@@ -229,14 +229,14 @@ static attribute_store_node_t
229
229
// Attribute resolution functions
230
230
///////////////////////////////////////////////////////////////////////////////
231
231
sl_status_t zwave_command_class_thermostat_setpoint_supported_get (
232
- attribute_store_node_t node , uint8_t * frame , uint16_t * frame_len )
232
+ attribute_store_node_t node , uint8_t * frame , uint16_t * frame_length )
233
233
{
234
234
// Check that we have the right type of attribute.
235
235
assert (ATTRIBUTE (SUPPORTED_SETPOINT_TYPES )
236
236
== attribute_store_get_node_type (node ));
237
237
238
238
// Default frame length in case of error
239
- * frame_len = 0 ;
239
+ * frame_length = 0 ;
240
240
241
241
// Supported Get is the same for all versions.
242
242
ZW_THERMOSTAT_SETPOINT_SUPPORTED_GET_V3_FRAME * supported_get_frame
@@ -245,18 +245,18 @@ sl_status_t zwave_command_class_thermostat_setpoint_supported_get(
245
245
supported_get_frame -> cmdClass = COMMAND_CLASS_THERMOSTAT_SETPOINT_V3 ;
246
246
supported_get_frame -> cmd = THERMOSTAT_SETPOINT_SUPPORTED_GET_V3 ;
247
247
248
- * frame_len = sizeof (ZW_THERMOSTAT_SETPOINT_SUPPORTED_GET_V3_FRAME );
248
+ * frame_length = sizeof (ZW_THERMOSTAT_SETPOINT_SUPPORTED_GET_V3_FRAME );
249
249
return SL_STATUS_OK ;
250
250
}
251
251
252
252
// FIXME: This will be failing CL:0043.01.21.02.1
253
253
sl_status_t zwave_command_class_thermostat_setpoint_capabilities_get (
254
- attribute_store_node_t node , uint8_t * frame , uint16_t * frame_len )
254
+ attribute_store_node_t node , uint8_t * frame , uint16_t * frame_length )
255
255
{
256
256
// Check that we have the right type of attribute.
257
257
assert (ATTRIBUTE (MIN_VALUE ) == attribute_store_get_node_type (node ));
258
258
// Default frame length in case of error
259
- * frame_len = 0 ;
259
+ * frame_length = 0 ;
260
260
261
261
attribute_store_node_t type_node = attribute_store_get_node_parent (node );
262
262
attribute_store_node_t endpoint_node
@@ -297,20 +297,20 @@ sl_status_t zwave_command_class_thermostat_setpoint_capabilities_get(
297
297
& capabilities_get_frame -> properties1 ,
298
298
sizeof (capabilities_get_frame -> properties1 ));
299
299
300
- * frame_len = sizeof (ZW_THERMOSTAT_SETPOINT_CAPABILITIES_GET_V3_FRAME );
300
+ * frame_length = sizeof (ZW_THERMOSTAT_SETPOINT_CAPABILITIES_GET_V3_FRAME );
301
301
return SL_STATUS_OK ;
302
302
}
303
303
}
304
304
305
305
sl_status_t zwave_command_class_thermostat_setpoint_get (
306
- attribute_store_node_t node , uint8_t * frame , uint16_t * frame_len )
306
+ attribute_store_node_t node , uint8_t * frame , uint16_t * frame_length )
307
307
{
308
308
// Check that we have the right type of attribute.
309
309
assert (ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE
310
310
== attribute_store_get_node_type (node ));
311
311
312
312
// Default frame length in case of error
313
- * frame_len = 0 ;
313
+ * frame_length = 0 ;
314
314
315
315
attribute_store_node_t type_node = attribute_store_get_node_parent (node );
316
316
@@ -325,57 +325,94 @@ sl_status_t zwave_command_class_thermostat_setpoint_get(
325
325
& get_frame -> level ,
326
326
sizeof (get_frame -> level ));
327
327
328
- * frame_len = sizeof (ZW_THERMOSTAT_SETPOINT_GET_V3_FRAME );
328
+ * frame_length = sizeof (ZW_THERMOSTAT_SETPOINT_GET_V3_FRAME );
329
329
return SL_STATUS_OK ;
330
330
}
331
331
332
332
sl_status_t zwave_command_class_thermostat_setpoint_set (
333
- attribute_store_node_t node , uint8_t * frame , uint16_t * frame_len )
333
+ attribute_store_node_t node , uint8_t * frame , uint16_t * frame_length )
334
334
{
335
335
// Check that we have the right type of attribute.
336
336
assert (ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE
337
337
== attribute_store_get_node_type (node ));
338
338
339
339
// Default frame length in case of error
340
- * frame_len = 0 ;
340
+ * frame_length = 0 ;
341
341
342
- attribute_store_node_t type_node = attribute_store_get_node_parent (node );
343
- attribute_store_node_t scale_node = attribute_store_get_first_child_by_type (
344
- type_node ,
345
- ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE_SCALE );
346
-
347
- // We will just always use 4 bytes, precision 2.
348
- ZW_THERMOSTAT_SETPOINT_SET_4BYTE_V3_FRAME * set_frame
349
- = (ZW_THERMOSTAT_SETPOINT_SET_4BYTE_V3_FRAME * )frame ;
342
+ attribute_store_node_t type_node = attribute_store_get_node_parent (node );
350
343
351
- set_frame -> cmdClass = COMMAND_CLASS_THERMOSTAT_SETPOINT_V3 ;
352
- set_frame -> cmd = THERMOSTAT_SETPOINT_SET_V3 ;
353
- // set_frame->level ? This is 4 bits reserved / 4 bits setpoint type.
354
- set_frame -> level = 0 ;
344
+ // Get setpoint type
345
+ uint8_t setpoint_type = 0 ;
355
346
attribute_store_get_reported (type_node ,
356
- & set_frame -> level ,
357
- sizeof (set_frame -> level ));
347
+ & setpoint_type ,
348
+ sizeof (setpoint_type ));
358
349
359
- // set_frame->level2 ? This is Precision (3 bits) / Scale (2 bits) / size (3 bits)
360
- uint32_t setpoint_value_scale = 0 ;
361
350
// Reuse the same scale as current value.
362
- attribute_store_get_reported (scale_node ,
363
- & setpoint_value_scale ,
364
- sizeof (setpoint_value_scale ));
351
+ uint32_t setpoint_value_scale = 0 ;
352
+ attribute_store_get_child_reported (
353
+ type_node ,
354
+ ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE_SCALE ,
355
+ & setpoint_value_scale ,
356
+ sizeof (setpoint_value_scale ));
365
357
366
- set_frame -> level2 = SET_DEFAULT_PRECISION ;
367
- set_frame -> level2 |= SET_DEFAULT_SIZE ;
368
- set_frame -> level2 |= ((setpoint_value_scale << 3 ) & SCALE_MASK );
358
+ // Reuse the same precision as current value.
359
+ uint8_t setpoint_value_precision = 0 ;
360
+ attribute_store_get_child_reported (
361
+ type_node ,
362
+ ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE_PRECISION ,
363
+ & setpoint_value_precision ,
364
+ sizeof (setpoint_value_precision ));
369
365
366
+ uint8_t level2_properties_field
367
+ = (setpoint_value_precision << 5 ) | (setpoint_value_scale << 3 );
370
368
int32_t setpoint_value_integer
371
369
= thermostat_setpoint_get_valid_desired_setpoint_value (node );
372
370
373
- set_frame -> value1 = (setpoint_value_integer & 0xFF000000 ) >> 24 ; // MSB
374
- set_frame -> value2 = (setpoint_value_integer & 0x00FF0000 ) >> 16 ;
375
- set_frame -> value3 = (setpoint_value_integer & 0x0000FF00 ) >> 8 ;
376
- set_frame -> value4 = (setpoint_value_integer & 0x000000FF ); // LSB
371
+ if (setpoint_value_integer >= INT8_MIN
372
+ && setpoint_value_integer <= INT8_MAX ) {
373
+ ZW_THERMOSTAT_SETPOINT_SET_1BYTE_V3_FRAME * set_frame
374
+ = (ZW_THERMOSTAT_SETPOINT_SET_1BYTE_V3_FRAME * )frame ;
375
+ * frame_length = sizeof (ZW_THERMOSTAT_SETPOINT_SET_1BYTE_V3_FRAME );
376
+
377
+ set_frame -> cmdClass = COMMAND_CLASS_THERMOSTAT_SETPOINT_V3 ;
378
+ set_frame -> cmd = THERMOSTAT_SETPOINT_SET_V3 ;
379
+ set_frame -> level = setpoint_type ;
380
+ set_frame -> level2 = level2_properties_field | 1 ;
381
+ set_frame -> value1 = (uint8_t )(setpoint_value_integer & 0x000000FF );
382
+ } else if (setpoint_value_integer >= INT16_MIN
383
+ && setpoint_value_integer <= INT16_MAX ) {
384
+ ZW_THERMOSTAT_SETPOINT_SET_2BYTE_V3_FRAME * set_frame
385
+ = (ZW_THERMOSTAT_SETPOINT_SET_2BYTE_V3_FRAME * )frame ;
386
+ * frame_length = sizeof (ZW_THERMOSTAT_SETPOINT_SET_2BYTE_V3_FRAME );
387
+
388
+ set_frame -> cmdClass = COMMAND_CLASS_THERMOSTAT_SETPOINT_V3 ;
389
+ set_frame -> cmd = THERMOSTAT_SETPOINT_SET_V3 ;
390
+ set_frame -> level = setpoint_type ;
391
+ set_frame -> level2 = level2_properties_field | 2 ;
392
+
393
+ set_frame -> value1 = (setpoint_value_integer & 0x0000FF00 ) >> 8 ; // MSB
394
+ set_frame -> value2 = (setpoint_value_integer & 0x000000FF ); // LSB
395
+
396
+ } else if (setpoint_value_integer >= INT32_MIN
397
+ && setpoint_value_integer <= INT32_MAX ) {
398
+ ZW_THERMOSTAT_SETPOINT_SET_4BYTE_V3_FRAME * set_frame
399
+ = (ZW_THERMOSTAT_SETPOINT_SET_4BYTE_V3_FRAME * )frame ;
400
+ * frame_length = sizeof (ZW_THERMOSTAT_SETPOINT_SET_4BYTE_V3_FRAME );
401
+
402
+ set_frame -> cmdClass = COMMAND_CLASS_THERMOSTAT_SETPOINT_V3 ;
403
+ set_frame -> cmd = THERMOSTAT_SETPOINT_SET_V3 ;
404
+ set_frame -> level = setpoint_type ;
405
+ set_frame -> level2 = level2_properties_field | 4 ;
406
+
407
+ set_frame -> value1 = (setpoint_value_integer & 0xFF000000 ) >> 24 ; // MSB
408
+ set_frame -> value2 = (setpoint_value_integer & 0x00FF0000 ) >> 16 ;
409
+ set_frame -> value3 = (setpoint_value_integer & 0x0000FF00 ) >> 8 ;
410
+ set_frame -> value4 = (setpoint_value_integer & 0x000000FF ); // LSB
411
+ } else {
412
+ sl_log_error (LOG_TAG , "Invalid desired value size" );
413
+ return SL_STATUS_NOT_SUPPORTED ;
414
+ }
377
415
378
- * frame_len = sizeof (ZW_THERMOSTAT_SETPOINT_SET_4BYTE_V3_FRAME );
379
416
return SL_STATUS_OK ;
380
417
}
381
418
@@ -389,7 +426,7 @@ static sl_status_t zwave_command_class_thermostat_setpoint_handle_report(
389
426
{
390
427
// We expect to have at least 1 byte of value
391
428
if (frame_length <= REPORT_VALUE_INDEX ) {
392
- return SL_STATUS_FAIL ;
429
+ return SL_STATUS_NOT_SUPPORTED ;
393
430
}
394
431
395
432
attribute_store_node_t endpoint_node
@@ -406,6 +443,12 @@ static sl_status_t zwave_command_class_thermostat_setpoint_handle_report(
406
443
sizeof (uint8_t ),
407
444
0 );
408
445
446
+ // Add guard in case we don't find it
447
+ if (type_node == ATTRIBUTE_STORE_INVALID_NODE ) {
448
+ sl_log_warning (LOG_TAG , "Can't find setpoint type %d" , received_type );
449
+ return SL_STATUS_NOT_SUPPORTED ;
450
+ }
451
+
409
452
uint8_t size = frame_data [REPORT_PRECISION_SCALE_SIZE_INDEX ] & SIZE_MASK ;
410
453
int32_t scale
411
454
= (frame_data [REPORT_PRECISION_SCALE_SIZE_INDEX ] & SCALE_MASK ) >> 3 ;
@@ -419,9 +462,15 @@ static sl_status_t zwave_command_class_thermostat_setpoint_handle_report(
419
462
attribute_store_node_t scale_node = attribute_store_get_first_child_by_type (
420
463
type_node ,
421
464
ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE_SCALE );
422
-
423
465
attribute_store_set_reported (scale_node , & scale , sizeof (scale ));
424
466
467
+ // Save precision
468
+ attribute_store_set_child_reported (
469
+ type_node ,
470
+ ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE_PRECISION ,
471
+ & precision ,
472
+ sizeof (precision ));
473
+
425
474
int32_t setpoint_value
426
475
= command_class_get_int32_value (size ,
427
476
precision ,
@@ -688,9 +737,7 @@ sl_status_t zwave_command_class_thermostat_setpoint_init()
688
737
handler .command_class_name = "Thermostat Setpoint" ;
689
738
handler .comments = "Partial Control: <br>"
690
739
"1. No discovery of ambiguous types in v1-v2 <br>"
691
- "2. Only a few setpoints can be configured. <br>"
692
- "3. Precision/size fields in the set are determined <br>"
693
- "automatically by the controller. " ;
740
+ "2. Only a few setpoints can be configured. <br>" ;
694
741
695
742
zwave_command_handler_register_handler (handler );
696
743
0 commit comments