@@ -229,14 +229,14 @@ static attribute_store_node_t
229229// Attribute resolution functions
230230///////////////////////////////////////////////////////////////////////////////
231231sl_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 )
233233{
234234 // Check that we have the right type of attribute.
235235 assert (ATTRIBUTE (SUPPORTED_SETPOINT_TYPES )
236236 == attribute_store_get_node_type (node ));
237237
238238 // Default frame length in case of error
239- * frame_len = 0 ;
239+ * frame_length = 0 ;
240240
241241 // Supported Get is the same for all versions.
242242 ZW_THERMOSTAT_SETPOINT_SUPPORTED_GET_V3_FRAME * supported_get_frame
@@ -245,18 +245,18 @@ sl_status_t zwave_command_class_thermostat_setpoint_supported_get(
245245 supported_get_frame -> cmdClass = COMMAND_CLASS_THERMOSTAT_SETPOINT_V3 ;
246246 supported_get_frame -> cmd = THERMOSTAT_SETPOINT_SUPPORTED_GET_V3 ;
247247
248- * frame_len = sizeof (ZW_THERMOSTAT_SETPOINT_SUPPORTED_GET_V3_FRAME );
248+ * frame_length = sizeof (ZW_THERMOSTAT_SETPOINT_SUPPORTED_GET_V3_FRAME );
249249 return SL_STATUS_OK ;
250250}
251251
252252// FIXME: This will be failing CL:0043.01.21.02.1
253253sl_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 )
255255{
256256 // Check that we have the right type of attribute.
257257 assert (ATTRIBUTE (MIN_VALUE ) == attribute_store_get_node_type (node ));
258258 // Default frame length in case of error
259- * frame_len = 0 ;
259+ * frame_length = 0 ;
260260
261261 attribute_store_node_t type_node = attribute_store_get_node_parent (node );
262262 attribute_store_node_t endpoint_node
@@ -297,20 +297,20 @@ sl_status_t zwave_command_class_thermostat_setpoint_capabilities_get(
297297 & capabilities_get_frame -> properties1 ,
298298 sizeof (capabilities_get_frame -> properties1 ));
299299
300- * frame_len = sizeof (ZW_THERMOSTAT_SETPOINT_CAPABILITIES_GET_V3_FRAME );
300+ * frame_length = sizeof (ZW_THERMOSTAT_SETPOINT_CAPABILITIES_GET_V3_FRAME );
301301 return SL_STATUS_OK ;
302302 }
303303}
304304
305305sl_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 )
307307{
308308 // Check that we have the right type of attribute.
309309 assert (ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE
310310 == attribute_store_get_node_type (node ));
311311
312312 // Default frame length in case of error
313- * frame_len = 0 ;
313+ * frame_length = 0 ;
314314
315315 attribute_store_node_t type_node = attribute_store_get_node_parent (node );
316316
@@ -325,57 +325,94 @@ sl_status_t zwave_command_class_thermostat_setpoint_get(
325325 & get_frame -> level ,
326326 sizeof (get_frame -> level ));
327327
328- * frame_len = sizeof (ZW_THERMOSTAT_SETPOINT_GET_V3_FRAME );
328+ * frame_length = sizeof (ZW_THERMOSTAT_SETPOINT_GET_V3_FRAME );
329329 return SL_STATUS_OK ;
330330}
331331
332332sl_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 )
334334{
335335 // Check that we have the right type of attribute.
336336 assert (ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE
337337 == attribute_store_get_node_type (node ));
338338
339339 // Default frame length in case of error
340- * frame_len = 0 ;
340+ * frame_length = 0 ;
341341
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 );
350343
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 ;
355346 attribute_store_get_reported (type_node ,
356- & set_frame -> level ,
357- sizeof (set_frame -> level ));
347+ & setpoint_type ,
348+ sizeof (setpoint_type ));
358349
359- // set_frame->level2 ? This is Precision (3 bits) / Scale (2 bits) / size (3 bits)
360- uint32_t setpoint_value_scale = 0 ;
361350 // 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 ));
365357
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 ));
369365
366+ uint8_t level2_properties_field
367+ = (setpoint_value_precision << 5 ) | (setpoint_value_scale << 3 );
370368 int32_t setpoint_value_integer
371369 = thermostat_setpoint_get_valid_desired_setpoint_value (node );
372370
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+ }
377415
378- * frame_len = sizeof (ZW_THERMOSTAT_SETPOINT_SET_4BYTE_V3_FRAME );
379416 return SL_STATUS_OK ;
380417}
381418
@@ -389,7 +426,7 @@ static sl_status_t zwave_command_class_thermostat_setpoint_handle_report(
389426{
390427 // We expect to have at least 1 byte of value
391428 if (frame_length <= REPORT_VALUE_INDEX ) {
392- return SL_STATUS_FAIL ;
429+ return SL_STATUS_NOT_SUPPORTED ;
393430 }
394431
395432 attribute_store_node_t endpoint_node
@@ -406,6 +443,12 @@ static sl_status_t zwave_command_class_thermostat_setpoint_handle_report(
406443 sizeof (uint8_t ),
407444 0 );
408445
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+
409452 uint8_t size = frame_data [REPORT_PRECISION_SCALE_SIZE_INDEX ] & SIZE_MASK ;
410453 int32_t scale
411454 = (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(
419462 attribute_store_node_t scale_node = attribute_store_get_first_child_by_type (
420463 type_node ,
421464 ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE_SCALE );
422-
423465 attribute_store_set_reported (scale_node , & scale , sizeof (scale ));
424466
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+
425474 int32_t setpoint_value
426475 = command_class_get_int32_value (size ,
427476 precision ,
@@ -688,9 +737,7 @@ sl_status_t zwave_command_class_thermostat_setpoint_init()
688737 handler .command_class_name = "Thermostat Setpoint" ;
689738 handler .comments = "Partial Control: <br>"
690739 "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>" ;
694741
695742 zwave_command_handler_register_handler (handler );
696743
0 commit comments