Skip to content

Commit

Permalink
SiliconLabsGH-35: Consistency between UCL and ZWave precision
Browse files Browse the repository at this point in the history
UCL precision is now always 2 whild Zwave is trying to adapt to the UCL precision.
  • Loading branch information
silabs-borisl committed Mar 21, 2024
1 parent f332df7 commit 436cc5f
Show file tree
Hide file tree
Showing 11 changed files with 1,243 additions and 316 deletions.
78 changes: 1 addition & 77 deletions applications/zpc/components/dotdot_mapper/rules/Thermostat.uam
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,6 @@ def zwSENSOR_MULTILEVEL_SCALE 0x3104
def zwSENSOR_MULTILEVEL_SENSOR_VALUE 0x3105
def zwMULTILEVEL_SUPPORTED_SENSOR_TYPES 0x3106

//Thermostat setpoint CC
def zwTHERMOSTAT_SETPOINT_VERSION 0x4301
def zwTHERMOSTAT_SUPPORTED_SETPOINT_TYPES 0x4302
def zwTHERMOSTAT_SETPOINT_TYPE 0x4303
def zwTHERMOSTAT_SETPOINT_VALUE 0x4304
def zwTHERMOSTAT_SETPOINT_VALUE_SCALE 0x4305
def zwTHERMOSTAT_SETPOINT_MIN_VALUE 0x4306
def zwTHERMOSTAT_SETPOINT_MIN_VALUE_SCALE 0x4307
def zwTHERMOSTAT_SETPOINT_MAX_VALUE 0x4308
def zwTHERMOSTAT_SETPOINT_MAX_VALUE_SCALE 0x4309

def zwTHERMOSTAT_MODE_VERSION 0x4001
def zwTHERMOSTAT_MODE 0x4002
def zwTHERMOSTAT_SUPPORTED_MODES 0x4003
Expand Down Expand Up @@ -54,75 +43,10 @@ def zb_ACLouverPosition 0x02010045
def zb_ACCoilTemperature 0x02010046
def zb_ACCapacityFormat 0x02010047

def thermostat_setpoint_supported (e'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_VALUE_SCALE | e'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_VALUE_SCALE)

scope 0 {
// We map Setpoint setpoint_type 0x01 (HEATING) and 0x02 (COOLING)
// The Z-Wave units are converted into milli units, in ZigBee is should be
// deci-celsius.
// A value scale of 1 means fahrenheit

// Heating
r'zb_OccupiedHeatingSetpoint =
if( r'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_VALUE_SCALE == 0 )
(r'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_VALUE / 10)
if( r'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_VALUE_SCALE == 1 )
(((r'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_VALUE - 32000) * 5) / 90)
undefined

d'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_VALUE =
if( r'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_VALUE_SCALE == 0 )
(d'zb_OccupiedHeatingSetpoint*10)
if( r'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_VALUE_SCALE == 1 )
(((d'zb_OccupiedHeatingSetpoint)*90) / 5 + 32000)
undefined

r'zb_MinHeatSetpointLimit =
if(r'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_MIN_VALUE_SCALE == 0)
(r'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_MIN_VALUE / 10)
if(r'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_MIN_VALUE_SCALE == 1)
(((r'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_MIN_VALUE - 32000) * 5) / 90)
undefined

r'zb_MaxHeatSetpointLimit =
if(r'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_MAX_VALUE_SCALE == 0)
(r'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_MAX_VALUE / 10)
if(r'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_MAX_VALUE_SCALE == 1)
(((r'zwTHERMOSTAT_SETPOINT_TYPE[1].zwTHERMOSTAT_SETPOINT_MAX_VALUE - 32000) * 5) / 90)
undefined

// Cooling
r'zb_OccupiedCoolingSetpoint =
if( r'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_VALUE_SCALE == 0)
(r'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_VALUE / 10 )
if( r'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_VALUE_SCALE == 1)
(((r'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_VALUE - 32000) * 5) / 90)
undefined

r'zb_MinCoolSetpointLimit =
if(r'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_MIN_VALUE_SCALE == 0)
(r'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_MIN_VALUE / 10)
if(r'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_MIN_VALUE_SCALE == 1)
(((r'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_MIN_VALUE - 32000) * 5) / 90)
undefined

r'zb_MaxCoolSetpointLimit =
if(r'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_MAX_VALUE_SCALE == 0)
(r'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_MAX_VALUE / 10)
if(r'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_MAX_VALUE_SCALE == 1)
(((r'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_MAX_VALUE - 32000) * 5) / 90)
undefined

d'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_VALUE =
if( r'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_VALUE_SCALE == 0)
(d'zb_OccupiedCoolingSetpoint*10)
if( r'zwTHERMOSTAT_SETPOINT_TYPE[2].zwTHERMOSTAT_SETPOINT_VALUE_SCALE == 1 )
(((d'zb_OccupiedCoolingSetpoint)*90) / 5 + 32000)
undefined

// Local Temperature
r'zb_LocalTemperature =
if(thermostat_setpoint_supported == 0) undefined
// if(thermostat_setpoint_supported == 0) undefined
if(r'zwSENSOR_MULTILEVEL_SENSOR_TYPE[1].zwSENSOR_MULTILEVEL_SCALE == 0)
(r'zwSENSOR_MULTILEVEL_SENSOR_TYPE[1].zwSENSOR_MULTILEVEL_SENSOR_VALUE / 10)
if(r'zwSENSOR_MULTILEVEL_SENSOR_TYPE[1].zwSENSOR_MULTILEVEL_SCALE == 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -673,26 +673,40 @@ DEFINE_ATTRIBUTE(
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_TYPE,
((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | 0x03))

// WARNING : applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_setpoint.cpp
// use the attributes ID to determine value scale and precision. (+1 for scale and +2 for precision)
// Be careful if you change the ID
#define SETPOINT_SCALE_ATTRIBUTE_ID_OFFSET 1
#define SETPOINT_PRECISION_ATTRIBUTE_ID_OFFSET 2

DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE,
((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | 0x04))

// 0x05
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE_SCALE,
((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | 0x05))
((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | (0x04 + SETPOINT_SCALE_ATTRIBUTE_ID_OFFSET)))
// 0x06
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE_PRECISION,
((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | (0x04 + SETPOINT_PRECISION_ATTRIBUTE_ID_OFFSET)))

DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MIN_VALUE,
((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | 0x06))

DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MIN_VALUE_SCALE,
((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | 0x07))
// 0x08
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MIN_VALUE_SCALE,
((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | (0x07 + SETPOINT_SCALE_ATTRIBUTE_ID_OFFSET)))
// 0x09
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MIN_VALUE_PRECISION,
((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | (0x07 + SETPOINT_PRECISION_ATTRIBUTE_ID_OFFSET)))

DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MAX_VALUE,
((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | 0x08))

DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MAX_VALUE_SCALE,
((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | 0x09))

DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE_PRECISION,
((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | 0x0A))
// 0x0B
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MAX_VALUE_SCALE,
((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | (0x0A + SETPOINT_SCALE_ATTRIBUTE_ID_OFFSET)))
// 0x0C
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MAX_VALUE_PRECISION,
((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | (0x0A + SETPOINT_PRECISION_ATTRIBUTE_ID_OFFSET)))


/////////////////////////////////////////////////
// Wakeup command class
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/******************************************************************************
* # License
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
******************************************************************************
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
*****************************************************************************/

/**
* @defgroup zpc_attribute_store_command_classes_types Type definitions for attribute storage of Command Classes
* @ingroup zpc_attribute_store
* @brief Type definitions for Command Classes, used for @ref attribute_store storage.
*
*/

/**
* @defgroup zwave_command_class_thermostat_setpoint_types Type definitions for attribute storage of the Thermostat SetPoint Command Class
* @ingroup zpc_attribute_store_command_classes_types
* @brief Type definitions for the Thermostat SetPoint Command Class.
*
* @{
*/

#ifndef ZWAVE_COMMAND_CLASS_THERMOSTAT_SETPOINT_TYPES_H
#define ZWAVE_COMMAND_CLASS_THERMOSTAT_SETPOINT_TYPES_H

#define SETPOINT_TYPE_HEATING 1
#define SETPOINT_TYPE_COOLING 2

// Should be uint8_t, but kept int8_t for legacy reasons
typedef int8_t thermostat_setpoint_type_t;
typedef int32_t thermostat_setpoint_value_t;
// Should be uint8_t, but kept uint32_t for legacy reasons
typedef uint32_t thermostat_setpoint_scale_t;
typedef uint8_t thermostat_setpoint_precision_t;


#endif //ZWAVE_COMMAND_CLASS_THERMOSTAT_SETPOINT_TYPES_H
/** @} end zwave_command_class_thermostat_setpoint_types */
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,12 @@ static const std::vector<attribute_schema_t> attribute_schema = {

{ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MIN_VALUE, "Min Value", ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_TYPE, I32_STORAGE_TYPE},
{ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MIN_VALUE_SCALE, "Min Value Scale", ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_TYPE, U32_STORAGE_TYPE},
{ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MIN_VALUE_PRECISION, "Min Value Precision", ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_TYPE, U8_STORAGE_TYPE},

{ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MAX_VALUE, "Max Value", ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_TYPE, I32_STORAGE_TYPE},
{ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MAX_VALUE_SCALE, "Max Value Scale", ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_TYPE, U32_STORAGE_TYPE},
{ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MAX_VALUE_PRECISION, "Max Value Precision", ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_TYPE, U8_STORAGE_TYPE},

/////////////////////////////////////////////////////////////////////
// Supervision Command Class attributes
/////////////////////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ add_library(
src/zwave_command_class_switch_color.c
src/zwave_command_class_switch_multilevel.c
src/zwave_command_class_thermostat_mode.c
src/zwave_command_class_thermostat_setpoint.c
src/zwave_command_class_thermostat_setpoint.cpp
src/zwave_command_class_time.c
src/zwave_command_class_user_code.c
src/zwave_command_class_version.c
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ typedef struct zwave_minimum_frame {
} zwave_minimum_frame_t;

// Helper macros
#define FAHRENHEIT_TO_DEGREES(value) ((value - 32.0F) * 5 / 9);
#define DEGREES_TO_FAHRENHEIT(value) (value * 9 / 5.0F) + 32;
#define FAHRENHEIT_TO_DEGREES(value) ((value - 32.0) * 5 / 9);
#define DEGREES_TO_FAHRENHEIT(value) (value * 9 / 5.0) + 32;

// Constants
/// Additional delay in ms to wait before issuing a Get Command
Expand Down Expand Up @@ -214,7 +214,33 @@ int32_t get_signed_value_from_frame_and_size(const uint8_t *frame,
*/
uint32_t get_unsigned_value_from_frame_and_size(const uint8_t *frame,
uint8_t size);

/**
* @brief Convert a value from the Z-Wave world (precision = [0..7] and C° + F) into a UCL (Zigbee) world (precision = 2 and C°)
*
* @param zwave_value Current Z-Wave value
* @param zwave_precision Reported Z-Wave precision
* @param zwave_scale Reported Z-Wave scale (0 : C°, 1 : F)
*
* @return int16_t UCL temperature. Rounded down if Z-Wave precision is too high.
*/
int16_t zwave_temperature_to_ucl_temperature(int32_t zwave_value,
uint8_t zwave_precision,
uint8_t zwave_scale);

/**
* @brief Convert a value from the UCL world (Zigbee) (precision = 2 and C°) to the ZWave world (precision = [0..7] and C° + F)
*
* @param ucl_value Current UCL value
* @param zwave_precision Expected Z-Wave precision
* @param zwave_scale Expected Z-Wave scale (0 : C°, 1 : F)
*
* @return int32_t Z-Wave temperature with given precision and scale.
*/
int32_t ucl_temperature_to_zwave_temperature(int16_t ucl_value,
uint8_t zwave_precision,
uint8_t zwave_scale);
/**
* @brief Converts a clock_time_t duration to a Z-Wave Command Class duration
* byte
*
Expand All @@ -224,7 +250,7 @@ uint32_t get_unsigned_value_from_frame_and_size(const uint8_t *frame,
* @param time The system time duration
* @returns uint8_t The corresponding Z-Wave duration encoding.
*/
uint8_t time_to_zwave_duration(clock_time_t time);
uint8_t time_to_zwave_duration(clock_time_t time);

/**
* @brief Converts a duration byte encoded for a Z-Wave command class and returns
Expand Down
Loading

0 comments on commit 436cc5f

Please sign in to comment.