diff --git a/config/aeotec/zw100.xml b/config/aeotec/zw100.xml index 03381caa11..5a04903762 100644 --- a/config/aeotec/zw100.xml +++ b/config/aeotec/zw100.xml @@ -1,8 +1,8 @@ - +--> http://www.openzwave.com/device-database/0086:0064:0102 images/aeotec/zw100.png @@ -25,6 +25,7 @@ V1.10 + V1.11 (12/14/2017) Updated Metadata Import from Z-Wave Alliance Database - https://products.z-wavealliance.org/products/2684/xml Updated Metadata Import from Z-Wave Alliance Database - https://products.z-wavealliance.org/products/2695/xml Updated Metadata Import from Z-Wave Alliance Database - https://products.z-wavealliance.org/products/2714/xml + Updated parameter 41 documentation based on https://help.aeotec.com/support/solutions/articles/6000219267-set-parameter-41-in-fibaro-home-center https://products.z-wavealliance.org/products/2714/ ZW100-C @@ -78,22 +79,23 @@ V1.10 + V1.11 (12/14/2017) Value=10 to 50. - Enable/disable the selective reporting only when measurements reach a certain threshold or percentage + Enable/disable the selective reporting only when measurements reach a certain threshold or percentage set in the threshold settings. This is used to reduce network traffic. - - Threshold change in temperature to induce an automatic report. - Note: - 1. The unit is Fahrenheit for US version, Celsius for EU/AU version. - 2. The value contains one decimal point. E.g. if the value is set to 20, the threshold value = 2.0 C (EU/AU) or 2.0 F (US). When the temperature has changed by 2.0 (of the appropriate unit), a temperature report will be sent. - + + Threshold change in temperature to induce an automatic report. In hexadecimal, the value should be in the form 0xAABBCCDD (firmware 1.10 and up) or 0xAABBCC (older firmware): + 1. AA should be 00 + 2. BB contains the temperature threshold with one decimal point. E.g. if the value is set to 0x14 (20 decimal), the threshold value is 2.0 degrees. So when the temperature has changed by 2.0 degrees, a temperature report will be sent. + 3. CC contains the unit: 01 for Celsius, 02 for Fahrenheit + 4. DD should be 00 + Example: decimal 1310976 is hexadecimal 0x140100, so 0x14 is 20 decimal, hence a change of 2.0 degree Celsius will trigger a notification report. - Threshold change in humidity to induce an automatic report. - Note: + Threshold change in humidity to induce an automatic report. + Note: 1. The unit is %. 2. The default value is 10, which means that a 10% change in humidity will trigger a report. @@ -102,8 +104,8 @@ V1.10 + V1.11 (12/14/2017) Threshold change in luminance to induce an automatic report. - Threshold change in battery level to induce an automatic report. - Note: + Threshold change in battery level to induce an automatic report. + Note: 1. The unit is %. 2. The default value is 10, which means that a 10% change in battery will trigger a report. @@ -121,8 +123,8 @@ V1.10 + V1.11 (12/14/2017) Enable/disable to send a report when the measurement is more than the upper limit value or less than the lower limit value. - Note: - If USB power, the Sensor will check the limit every 10 seconds. If battery power, the Sensor will check the limit when it is waken up. + Note: + If USB power, the Sensor will check the limit every 10 seconds. If battery power, the Sensor will check the limit when it is waken up. French Help @@ -175,26 +177,24 @@ V1.10 + V1.11 (12/14/2017) Upper Ultraviolet Threshold-fr - + When the measurement is more than this upper limit, which will trigger to sent out a sensor report. - High byte is the upper limit value. Low byte is the unit (0x01=Celsius, 0x02=Fahrenheit). - 1. When unit is Celsius. - Upper limit range: -40.0 to 100.0 C (0xFE70 to 0x03E8). + High two bytes is the upper limit value. Low two (firmware 1.10 and up) or single (older firmware) bytes is the unit (0x0100=Celsius, 0x0200=Fahrenheit). + 1. When unit is Celsius, upper limit rang is from: -40.0 to 100.0 C (0xFE70 to 0x03E8). E.g. The default upper limit of EU/AU version is 28.0 C (0x0118), when the measurement is more than 28.0C, it will be triggered to send out a temperature sensor report. - 2. When unit is Fahrenheit. - Upper limit range: -40.0 to 212.0 F (0xFE70 to 0x0848). + 2. When unit is Fahrenheit, upper limit range: -40.0 to 212.0 F (0xFE70 to 0x0848). E.g. The default upper limit of US version is 82.4F (0X0338), when the measurement is more than 82.4F, it will be triggered to send out a temperature sensor report. - + When the measurement is less than this lower limit, which will trigger to sent out a sensor report. - High byte is the lower limit value. Low byte is the unit (0x01=Celsius, 0x02=Fahrenheit). + High two bytes is the lower limit value. Low two (firmware 1.10 and up) or single (older firmware) bytes is the unit (0x0100=Celsius, 0x0200=Fahrenheit). 1. When unit is Celsius. Lower limit range: -40.0 to 100.0 C (0xFE70 to 0x03E8). E.g. The default lower limit of EU/AU version is 0 C (0x0000), when the measurement is less than 0C, it will be triggered to send out a temperature sensor report. - 2. When unit is Fahrenheit. + 2. When unit is Fahrenheit. Upper limit range: -40.0 to 212.0 F (0xFE70 to 0x0848). E.g. The default lower limit of US version is 32.0F (0x0140), when the measurement is less than 32.0F, it will be triggered to send out a temperature sensor report. @@ -203,35 +203,35 @@ V1.10 + V1.11 (12/14/2017) When the measurement is more than this upper limit, which will trigger to sent out a sensor report. Upper limit range: 0 to 100%. - E.g. The default upper limit is 60%, when the measurement is more than 60%, it will be triggered to send out a humidity sensor report. + E.g. The default upper limit is 60%, when the measurement is more than 60%, it will be triggered to send out a humidity sensor report. When the measurement is less than this lower limit, which will trigger to sent out a sensor report. Lower limit range: 0 to 100%. - E.g. The default lower limit is 50%, when the measurement is less than 50%, it will be triggered to send out a humidity sensor report. + E.g. The default lower limit is 50%, when the measurement is less than 50%, it will be triggered to send out a humidity sensor report. When the measurement is more than this upper limit, which will trigger to sent out a sensor report. Upper limit range: 0 to 30000 Lux. - E.g. The default upper limit is 1000Lux, when the measurement is more than 1000Lux, it will be triggered to send out a Lighting sensor report. + E.g. The default upper limit is 1000Lux, when the measurement is more than 1000Lux, it will be triggered to send out a Lighting sensor report. When the measurement is less than this lower limit, which will trigger to sent out a sensor report. Lower limit range: 0 to 30000 Lux. - E.g. The default lower limit is 100Lux, when the measurement is less than 100Lux, it will be triggered to send out a Lighting sensor report. + E.g. The default lower limit is 100Lux, when the measurement is less than 100Lux, it will be triggered to send out a Lighting sensor report. When the measurement is more than this upper limit, which will trigger to sent out a sensor report. Upper limit range: 1 to 11. - E.g. The default upper limit is 8, when the measurement is more than 8, it will be triggered to send out a ultraviolet sensor report. + E.g. The default upper limit is 8, when the measurement is more than 8, it will be triggered to send out a ultraviolet sensor report. @@ -244,9 +244,9 @@ V1.10 + V1.11 (12/14/2017) Note: - 1. When the current measurement lower or equal (Upper limit - Recover limit), the upper limit report is enabled and then it would send out a sensor report when the next measurement is more than the upper limit. + 1. When the current measurement lower or equal (Upper limit - Recover limit), the upper limit report is enabled and then it would send out a sensor report when the next measurement is more than the upper limit. After that, the upper limit report would be disabled again until the measurement lower or equal (Upper limit - Recover limit). - 2. When the current measurement greater or equal (Lower limit + Recover limit), the lower limit report is enabled and then it would send out a sensor report when the next measurement is less than the lower limit. + 2. When the current measurement greater or equal (Lower limit + Recover limit), the lower limit report is enabled and then it would send out a sensor report when the next measurement is less than the lower limit. After that, the lower limit report would be disabled again until the measurement greater or equal (Lower limit + Recover limit). 3. High byte is the recover limit value. Low byte is the unit (0x01=Celsius, 0x02=Fahrenheit). 4. Recover limit range: 1.0 to 25.5 C/ F (0x0101 to 0xFF01 or 0x0102 to 0xFF02). @@ -256,20 +256,20 @@ V1.10 + V1.11 (12/14/2017) Note: - 1. When the current measurement lower or equal (Upper limit - Recover limit), the upper limit report is enabled and then it would send out a sensor report when the next measurement is more than the upper limit. + 1. When the current measurement lower or equal (Upper limit - Recover limit), the upper limit report is enabled and then it would send out a sensor report when the next measurement is more than the upper limit. After that the upper limit report would be disabled again until the measurement lower or equal (Upper limit - Recover limit). - 2. When the current measurement greater or equal (Lower limit + Recover limit), the lower limit report is enabled and then it would send out a sensor report when the next measurement is less than the lower limit. + 2. When the current measurement greater or equal (Lower limit + Recover limit), the lower limit report is enabled and then it would send out a sensor report when the next measurement is less than the lower limit. After that the lower limit report would be disabled again until the measurement greater or equal(Lower limit + Recover limit). 3. Recover limit range: 1 to 50% (0x01 to 0x32). - E.g. The default recover limit value is 5%, when the measurement is less than (Upper limit - 5), the upper limit report would be enabled one time or when the measurement is more than (Lower limit + 5), the lower limit report would be enabled one time. + E.g. The default recover limit value is 5%, when the measurement is less than (Upper limit - 5), the upper limit report would be enabled one time or when the measurement is more than (Lower limit + 5), the lower limit report would be enabled one time. Note: - 1. When the current measurement lower or equal (Upper limit - Recover limit), the upper limit report is enabled and then it would send out a sensor report when the next measurement is more than the upper limit. + 1. When the current measurement lower or equal (Upper limit - Recover limit), the upper limit report is enabled and then it would send out a sensor report when the next measurement is more than the upper limit. After that the upper limit report would be disabled again until the measurement lower or equal (Upper limit - Recover limit). - 2. When the current measurement greater or equal (Lower limit + Recover limit), the lower limit report is enabled and then it would send out a sensor report when the next measurement is less than the lower limit. + 2. When the current measurement greater or equal (Lower limit + Recover limit), the lower limit report is enabled and then it would send out a sensor report when the next measurement is less than the lower limit. After that the lower limit report would be disabled again until the measurement greater or equal (Lower limit + Recover limit). 3. Unit = 10*Recover limit (Lux) 4. Recover limit range: 10 to 2550Lux (0x01 to 0xFF). @@ -279,12 +279,12 @@ V1.10 + V1.11 (12/14/2017) Note: - 1. When the current measurement lower or equal (Upper limit - Recover limit), the upper limit report is enabled and then it would send out a sensor report when the next measurement is more than the upper limit. + 1. When the current measurement lower or equal (Upper limit - Recover limit), the upper limit report is enabled and then it would send out a sensor report when the next measurement is more than the upper limit. After that the upper limit report would be disabled again until the measurement lower or equal (Upper limit - Recover limit). - 2. When the current measurement greater or equal (Lower limit + Recover limit), the lower limit report is enabled and then it would send out a sensor report when the next measurement is less than the lower limit. + 2. When the current measurement greater or equal (Lower limit + Recover limit), the lower limit report is enabled and then it would send out a sensor report when the next measurement is less than the lower limit. After that the lower limit report would be disabled again until the measurement greater or equal(Lower limit + Recover limit). 3. Recover limit range: 1 to 50% (0x01 to 0x32). - E.g. The default recover limit value is 5%, when the measurement is less than (Upper limit - 5), the upper limit report would be enabled one time or when the measurement is more than (Lower limit + 5), the lower limit report would be enabled one time. + E.g. The default recover limit value is 5%, when the measurement is less than (Upper limit - 5), the upper limit report would be enabled one time or when the measurement is more than (Lower limit + 5), the lower limit report would be enabled one time. @@ -398,10 +398,10 @@ V1.10 + V1.11 (12/14/2017) Temperature calibration (the available value range is [-128,127] or [-12.8C,12.7C]). Note: 1. High byte is the calibration value. Low byte is the unit (0x01=Celsius,0x02=Fahrenheit) - 2. The calibration value (high byte) contains one decimal point. + 2. The calibration value (high byte) contains one decimal point. E.g. if the value is set to 20 (0x1401), the calibration value is 2.0C (EU/AU version) or if the value is set to 20 (0x1402), the calibration value is 2.0F (US version) - 3. The calibration value (high byte) = standard value - measure value. - E.g. If measure value =25.3C and the standard value = 23.2C, so the calibration value= 23.2C - 25.3C= -2.1C (0xEB). + 3. The calibration value (high byte) = standard value - measure value. + E.g. If measure value =25.3C and the standard value = 23.2C, so the calibration value= 23.2C - 25.3C= -2.1C (0xEB). If the measure value =30.1C and the standard value = 33.2C, so the calibration value= 33.2C - 30.1C=3.1C (0x1F). Default value: 1 for EU/AU version, 2 for US version. @@ -410,21 +410,21 @@ V1.10 + V1.11 (12/14/2017) The calibration value = standard value - measure value. (the available value range is [-50, 50]). If measure value =80RH and the standard value = 75RH, so the calibration value= 75RH-80RH = -5RH (0xFB). - If the measure value =85RH and the standard value = 90RH, so the calibration value= 90RH-85RH = 5RH (0x05). + If the measure value =85RH and the standard value = 90RH, so the calibration value= 90RH-85RH = 5RH (0x05). - The calibration value = standard value - measure value. + The calibration value = standard value - measure value. (the available value range is [-1000, 1000]). - If measure value =800Lux and the standard value = 750Lux, so the calibration value= 750-800 = -50 (0xFFCE). - If the measure value =850Lux and the standard value = 900Lux, so the calibration value= 900-850 = 50 (0x0032). + If measure value =800Lux and the standard value = 750Lux, so the calibration value= 750-800 = -50 (0xFFCE). + If the measure value =850Lux and the standard value = 900Lux, so the calibration value= 900-850 = 50 (0x0032). - The calibration value = standard value measure value. + The calibration value = standard value measure value. (the available value range is [-10, 10]). - If measure value =9 and the standard value = 8, so the calibration value= 8-9 = -1 (0xFE). - If the measure value =7 and the standard value = 9, so the calibration value= 9-7 = 2 (0x02). + If measure value =9 and the standard value = 8, so the calibration value= 8-9 = -1 (0xFE). + If the measure value =7 and the standard value = 9, so the calibration value= 9-7 = 2 (0x02). diff --git a/config/aeotec/zw141.xml b/config/aeotec/zw141.xml index 969759470e..90c022bb26 100644 --- a/config/aeotec/zw141.xml +++ b/config/aeotec/zw141.xml @@ -3,7 +3,7 @@ Aeotec ZW141 Nano Shutter, based on Engineering Spec 8/22/2019 Product Type ID: EU=0x00, US=0x01, AU=0x02 CN=0x1D --> - + http://www.openzwave.com/device-database/0086:008D:0103 images/aeotec/zw141.png @@ -41,7 +41,8 @@ Product Type ID: EU=0x00, US=0x01, AU=0x02 CN=0x1D Updated Metadata Import from Z-Wave Alliance Database - https://products.z-wavealliance.org/products/2953/xml Updated Metadata Import from Z-Wave Alliance Database - https://products.z-wavealliance.org/products/3075/xml Updated Metadata Import from Z-Wave Alliance Database - https://products.z-wavealliance.org/Products/3693/XML - Fixed timing types, Fixed button list types + Fixed timing types, Fixed button list types + Add missing list item for param 22 U.S. / Canada / Mexico ZW141-A @@ -56,8 +57,12 @@ Product Type ID: EU=0x00, US=0x01, AU=0x02 CN=0x1D - + Set to toggle the motor running direction + + + + Set the blade turn time for Venetian mode. Details can be found in section 4.2 of Advanced information Product Manual. @@ -67,9 +72,9 @@ Product Type ID: EU=0x00, US=0x01, AU=0x02 CN=0x1D Set to enter/exit calibration mode - - - + + + Set user confirmation for calibration diff --git a/config/aeotec/zwa011.xml b/config/aeotec/zwa011.xml new file mode 100644 index 0000000000..cae441bd69 --- /dev/null +++ b/config/aeotec/zwa011.xml @@ -0,0 +1,157 @@ + + + + http://www.openzwave.com/device-database/0371:000B:0002 + images/aeotec/zwa011.png + https://products.z-wavealliance.org/products/3866/ + Door / Window Sensor 7 + CEPT (Europe) + ZWA011-C + Aeotec Door/ Window Sensor 7 is built on the 700 series Z-Wave technology. + Its a small window position sensor for your smart home, it monitors window and their exact opening position and lets your know when a window is tilted or completely opened. + It also supports connecting external binary sensors with a dry contact through the dry binary contact of the Door/ Window sensor. + Using the latest technology it supports the highest Z-Wave security level of S2 and SmartStart. + + Press the tamper once + 1. Open the housing. + 2. Remove the battery protection. + 3. Press the tamper on the side of the appliance three times quickly. + + 1. Open the housing. + 2. Press the tamper on the side of the appliance three times quickly. + + Reset to factory default + This device also allows to be reset without any involvement of a Z-Wave controller. This procedure should only be used when the primary controller is inoperable. + Once Cover is removed and the tamper switch is tripped, push the tamper for 5 seconds until the RED LED + blinks once. Then release tamper and push it again for 5 seconds while the RED LED is blinking until the + GREEN LED blinks once. + + https://aeotec.freshdesk.com/support/solutions/folders/6000237099 + https://aeotec.freshdesk.com/support/solutions/folders/6000237099 + + Initial Config File taken from ZWA012 + Initial Config File taken from https://help.aeotec.com/support/solutions/articles/6000218764-door-windows-sensor-7-user-guide + + + + + + true + + + + + + Parameter defines device operation mode. + + + + + + Parameter defines state of the sensor when the magnet is close. + If the alarm sensor is connected, it determines the output type. + Parameter inactive in external button mode (parameter Operation Mode set to 1). + + + + + + + This parameter defines events indicated by the visual LED indicator. Disabling events might extend battery life. + Values of parameters may be combined, e.g. 1+2=3 means opening/closing and wake up will be indicated by the visual indicator. + 0 - No indications. + 1 - Indication of opening/closing status change (input In). + 2 - Indication of wake up (1 x click or periodical). + 4 - Indication of device tampering. + + + + + Allows to enable activation of Z-Wave range test with double click of a Tamper Switch 2. + + + + + + + Parameter defines events which result in sending On/Off commands to devices added to the 2nd Association Group. + These commands are sent alternately to switch the devices On and Off. + Commands represent the values of BASIC SET command frames. + Parameter is inactive in external dry-contact mode (parameter Operation Mode set to 1). + + + + + + + + Command frames sent to devices added to the 2nd association group. + + + + + + + + The value of 0 turns OFF the device, 255 turns it On. + In case of associating the Dimmer or Roller Shutter module, values 1-99 allow to set an Associated device to a specified level. + + + + + The value of 0 turns OFF the device, 255 turns it On. + In case of associating the Dimmer or Roller Shutter module, values 1-99 allow to set an Associated device to a specified level. + + + + + Time period after which On command frame will be sent. + + + + + Time period after which Off command frame will be sent. + + + + + Time period after which a tamper alarm will be cancelled. + + + + + Reporting cancellation of tamper alarm to the controller and 5th Association Group. + + + + + + + The device can trigger scenes via Dry Input Terminal (external contact) using scene IDs assigned to different events. + + + + + + + The device can report Tilt Window events. + This functionality can be disabled if the device is mounted on a door or windows without tilt functionality.To disable tilt detection set the value to 0. + + + + + + You can use this parameter to adjust the tilt sensitivity if the tilt is too low or too high. + + + + + + + + + + + + + diff --git a/config/aeotec/zwa023.xml b/config/aeotec/zwa023.xml new file mode 100644 index 0000000000..d5213e1f00 --- /dev/null +++ b/config/aeotec/zwa023.xml @@ -0,0 +1,310 @@ + + + + ZWA023 Smart Switch 7 + + Aeotec Smart Switch 7 is a Z-Wave Switch plug-in module specifically used to enable Z-Wave command and control (on/off) of any plug-in tool. It can report immediate wattage consumption or kWh energy usage over a period of time. In the event of power failure, non-volatile memory retains all programmed information relating to the unit’s operating status. + The Plug is also a security S2 Z-Wave device, it supports Over The Air (OTA) feature for the products firmware upgrade and SmartStart network pairing feature. + + http://www.openzwave.com/device-database/0371:0017:0103 + https://products.z-wavealliance.org/products/3844 + https://products.z-wavealliance.org/products/3844 + images/aeotec/zwa023.png + https://products.z-wavealliance.org/products/3844 + N/A + + 1. Set your Z-Wave Controller into its 'Add Device' mode. Refer to the Controller's manual if you are unsure of how to perform this step. + 2. Power your Smart Switch to any outlet; its LED will slowly fade in and out slowly with a blue color to indicate it is ready to pair. + 3. Tap the action button once. The LED will turn solid yellow when it enters pair mode. + 4. If your Z-Wave Controller supports S2 encryption, enter the first 5 digits of DSK into your Controller's interface if it is requested. The DSK is printed on Smart Switch. + a. If pairing succeeds, it will flash white/green 4 times. + b. If pairing fails, it will light a solid bright red light for 2 seconds and then return to a breathing blue light; repeat steps 1 to 4 if this happens. + + + 1. Set your Z-Wave Controller into 'Remove Device' / 'Unpair Device' mode. Refer to the Controller's manual if you are unsure of how to perform this step. + 2. Make sure the product is powered. If not, plug it into a wall socket and power it on. + 3. Click Action Button 2 times quickly; it will bright violet light up to 2s. + a. If Removing fails, it will light a bright red color for 2 seconds and then turn back to Load Indicator Mode; repeat steps 1 to 3. Contact us for further support if needed. + b. If Removing succeeds, it will become breathing blue light. Smart Switch is removed from the Z-Wave network successfully and is ready to be paired again. + + + If the primary controller is missing or inoperable, you may need to reset the device to factory settings. + + Make sure the product is powered. If not, plug it into a wall socket and power on. To complete the reset process manually: + + 1. Press and hold the Action Button for at least 20 seconds and then release. + 2. The LED indicator will fade its blue light in and out slowly, which indicates the reset operation is successful. + + https://products.z-wavealliance.org/products/3844 + U.S. / Canada / Mexico + ZWA023-A + + Add ZWA023 Smart Switch 7 - Info from Aeotec's engineering sheet + Fixed missing config params 1-9 - Info from Aeotec's engineering sheet + + + + + + + This parameter is used to change the reaction of LED setting. + + 0 - Disable LED completely. LED will only be used for network operation indicator, such as inclusion, exclusion, factory reset. + 1 - Turn on between particular times only (act as night light). The default color is red, color can be changed by Color CC. + 2 - Display On/Off Status. The default color is white at 50% lightness. Color can be changed by Color CC. + + + + + + + + This parameter is used to configure the Night Light on time. User can use Color CC to change the Night Light color(default Red). Only useful when parameter 1 is set to 1. + + Value is of the pattern 0xRRHHMMSS. Where: + RR = Reserved + HH = Hours + MM = Minutes + SS = Seconds + Default = 0x00180000 means 6pm. + 0x00180000 = 1572864 dec + + + + + This parameter is used to configure the Night Light off time. Only useful when parameter 1 is set to 1. + + Value is of the pattern 0xRRHHMMSS. Where: + RR = Reserved + HH = Hours + MM = Minutes + SS = Seconds + Default = 0x00060000 means 6am. + 0x00060000 = 393216 dec + + + + + Set the duration of blink, unit second. + 0 - indicates that it is not blinking + 1~255 - set the duration + + + + + Set amount of blinks per second. + i.e. If set to 5, it should blink 5 times per second. + + + + + Send alert when in use. A Scene Activation Set command will be sent when energy draw is above this setting value. + 0 - disable + 1~3000 - enable, unit W + + + + + Prevents the plug from being turned off via its button. + + 0 - the plug will operate as normal and can be turned on or off. + 1 - the button on the plug will be disabled for on and off commands, but still work for network inclusion and exclusion. + 2 - the plug will ignore any commands to turn it off and it will ignore any use of the button (but still work for network inclusion and exclusion) + + + + + + + + Set the plug’s action in case of power out. + + 0 - last status + 1 - power on + 2 - power off + + + + + + + + Set the scene id when Scene Activation Set Command sent through group3. Refer parameter 6 for more information. + + + + + Turn off switch when current of load connected bypasses the maximum allowed power regardless of always on setting. + 0 - disable overload protection + 1~1800 - When watt detected above this setting value, the switch will be turned off immediately. And an over-load notification will be sent. + + + + + This parameter is used to set the over-voltage protect value, unit V. + 0 - disable over-voltage protection + 1~94 - The device will set value to 95 instead. + 95~255 - When voltage detected above this setting value, the switch will be turned off immediately. And an over-voltage notification will be sent. + + + + + Set the period of threshold check. Unit second. + 0 - disable all threshold settings + 1~255 - set in seconds on how fast device checks for threshold settings + + + + + Energy kWh threshold reporting enable/disable. Unit kWh. + + + + + Threshold setting for Watt for inducing automatic report. Unit W. + + + + + Threshold settings for current for inducing automatic report. Unit A. + + + + + Set the automatic report time of Watt. Unit second. + 0 - disable + 1~30 = 30s. + 31-65535 = 31-65535s. + + + + + Set the automatic report time of kWh. Unit second. + 0 - disable + 1~30 = 30s. + 31-65535 = 31-65535s. + + + + + Set the automatic report time of Voltage. Unit second. + 0 - disable + 1~30 = 30s. + 31-65535 = 31-65535s. + + + + + Set the automatic report time of Current. Unit second. + 0 - disable + 1~30 = 30s. + 31-65535 = 31-65535s. + + + + + Bitfield. Determines if alarms are enabled in Switch, and what Switch will react to which alarms. + + 0 - Disable all alarm settings + 1 - Smoke Alarm + 2 - CO Alarm + 4 - CO2 Alarm + 8 - Heat Alarm + 16 - Water Alarm + 32 - Access Control (DW Sensor open) + 64 - Home Security (intrusion) + 128 - Motion Sensor trigger + + + + Smoke Alarm + + + + CO Alarm + + + + CO2 Alarm + + + + Heat Alarm + + + + Water Alarm + + + + Access Control (DW Sensor open) + + + + Home Security (intrusion) + + + + Motion Sensor trigger + + + + + Enabled by Alarm Settings, and determines what the switch does in the case an alarm is triggered. + + 0 - disable, no reaction to alarm settings + 1 - Switch is ON + 2 - Switch is OFF + 3~255 - Sets rate at which Switch turns ON and OFF in seconds. (i.e. If set to 3, then Switch will turn ON in 0.3 seconds, and then turn OFF in 0.3 seconds in a cycle until user disables the alarm manually. If set to 255, then it will cycle every 25.5 seconds) + + + + + Determines the method of disabling the alarm of the device. + + 0 - Can be disabled by 1 tapping Switches action button once. + 1 - Can be disabled by 2 tapping Switches action button within 1 second. + 2 - Can be disabled by 4 tapping Switches action button within 2 seconds. + 4 - Can be disabled by pressing and holding Switches action button about 4 seconds. + 5~255 - Sets the duration of the alarm in seconds (i.e Sets this setting to 50, the alarm state of the switch will disable after 50 seconds) + Note: when the device receives the corresponding Notification State Idle Event, which can also dismiss the current alarm. + + + + + Acts as auto off after as soon as the switch turns ON, setting is set in seconds. + + 0 - no auto off with timer + 1~86400 - seconds + + + + + Acts as auto on after as soon as the switch turns OFF, setting is set in seconds. + + 0 - no auto on with timer + 1~86400 - seconds + + + + + Which report will be sent to lifeline group when the output state is changed. + + 0 - Send nothing + 1 - Send Basic Report + 2 - Send Switch Binary Report + + + + + + + + + + + + + + + diff --git a/config/hank/hkzw-so08-smartplug.xml b/config/hank/hkzw-so08-smartplug.xml new file mode 100644 index 0000000000..d6978cc5a5 --- /dev/null +++ b/config/hank/hkzw-so08-smartplug.xml @@ -0,0 +1,120 @@ + + + http://www.openzwave.com/device-database/0208:0019:0100 + images/hank/hkzw-so05-smartplug.png + https://products.z-wavealliance.org/products/3202/ + Smart Plug + https://products.z-wavealliance.org/ProductManual/File?filename=MarketCertificationFiles/3202/SmartPlug%20SO08P%20SpecificationEngineering.pdf + CEPT (Europe) + 1) Insert the Plug into a socket, +2) Press and hold the Z button for more than 20 seconds, +3) If holding time more than 20seconds, the RGB LED indicator will keep yellow for 2 seconds, which means resetting is completed. +Use this procedure only in the event that the network primary controller is missing or otherwise inoperable. + + 1) Connect the power supply. +2) Set the Z-Wave network main controller into inclusion mode (see Z-Wave network controller operating manual). +3) Triple click the Z-button or power up the device , RGB LED indicator should blink fast in blue. +4) Smart Plug should be recognized and included into the Z-Wave network. + + HKZW-SO08 + Smart plug is a Z-Wave Switch plugin module specifically used to enable Z-Wave command and control (on/off) of any plug-in tool. It can report wattage consumption or kWh energy usage, and can indicate the power level with a RGB LED. +Smart Plug is also a security Z-Wave device and supports the Over The Air (OTA) feature for the product’s firmware upgrade . + + 1) Insert the Plug into a socket. +2) Set the Z-Wave network controller into the exclusion mode (see Z-Wave controller operating manual). +3) Triple click the Z button. +4) RGB LED indicator will blink orange till the removing process is completed, than the indicator will keep orange for 3 seconds. + + + Initial Metadata Import from Z-Wave Alliance Database - https://products.z-wavealliance.org/products/3202/xml + + + + + + + Smart Plug keep detecting the load power, once the current exceeds 11.5A for more than 5s, smart plug's relay will turn off + + + + + Define how the plug reacts after the power supply is back on. + 0 - Smart Plug memorizes its state after a power failure. + 1 - Smart Plug does not memorize its state after a power failure. Connected device will be on after the power supply is reconnected. + 2 - Smart Plug does not memorize its state after a power failure. Connected device will be off after the power supply is reconnected. + + + + + + + + Smart Plug can send notifications to association device(Group Lifeline) when state of smart plug's load change + 0 - The function is disabled + 1 - Send Basic report. + 2 - Send Basic report only when Load condition is not changed by Z-WAVE Command + + + + + + + After smart plug being included into a Z-Wave network, the LED in the device will indicator the state of load. + 0 - The LED will follow the status(on/off) of its load + 1 - When the state of Switch's load changed, The LED will follow the status(on/off) of its load, but the red LED will turn off after 5 seconds if there is no any switch action. + + + + + + + Power threshold to be interpereted, when the change value of load power exceeds the setting threshold, the smart plug will send meter report to association device(Group Lifeline) + + + + + Power percentage threshold to be interpreted, when change value of the load power exceeds the setting threshold, the smart plug will send meter report to association device(Group Lifeline). + + + + + The interval of sending power report to association device(Group Lifeline). + 0 - The function is disabled. + + + + + The interval of sending power report to association device(Group Lifeline). + 0 - The function is disabled. + + + + + The interval of sending voltage report to association device(Group Lifeline). + 0 - The function is disabled. + + + + + The interval of sending electricity report to association device(Group Lifeline). + 0 - The function is disabled. + + + + + Lock/unlock all configuration parameters. + + + + + + + + + + + + diff --git a/config/images/aeotec/zwa011.png b/config/images/aeotec/zwa011.png new file mode 100644 index 0000000000..1ebf0c0241 Binary files /dev/null and b/config/images/aeotec/zwa011.png differ diff --git a/config/images/aeotec/zwa023.png b/config/images/aeotec/zwa023.png new file mode 100644 index 0000000000..4286c453ab Binary files /dev/null and b/config/images/aeotec/zwa023.png differ diff --git a/config/images/qubino/ZMNHHDx.png b/config/images/qubino/ZMNHHDx.png new file mode 100644 index 0000000000..1998a3039d Binary files /dev/null and b/config/images/qubino/ZMNHHDx.png differ diff --git a/config/manufacturer_specific.xml b/config/manufacturer_specific.xml index 9d32ec79c6..e8d94ae232 100644 --- a/config/manufacturer_specific.xml +++ b/config/manufacturer_specific.xml @@ -1,5 +1,5 @@ - + @@ -223,12 +223,14 @@ + + @@ -913,6 +915,7 @@ + @@ -1503,6 +1506,7 @@ + @@ -1680,6 +1684,7 @@ + diff --git a/config/qubino/ZMNHHDx.xml b/config/qubino/ZMNHHDx.xml index 9a136b32bd..315e3ea31d 100644 --- a/config/qubino/ZMNHHDx.xml +++ b/config/qubino/ZMNHHDx.xml @@ -1,8 +1,52 @@ - + + + Mini Dimmer + + The Qubino Mini Dimmer is smaller than any other zwave wireless dimmer in the world. Mini Dimmer is a + MOSFET-switching light device that also supports control of low-voltage halogen lamps with electronic + transformers, dimmable compact fluorescent lights, and dimmable LED bulbs. It can work with or + without the neutral line (3 or 2-wire installation). + + http://www.openzwave.com/device-database/0159:0055:0001 + https://qubino.com + https://support.qubino.com/support/home + images/qubino/ZMNHHDx.png + + Manual inclusion is triggered by the following procedure: + 1. Connect the device to the power supply + 2. Enable add/remove mode on your Z-Wave gateway (hub) + 3. Toggle the switch connected to the terminal I 3 times within 3 seconds (this procedure puts the + device in LEARN MODE). The device has to get On/Off signal 3 times, meaning 3 times push of the + momentary switch or with toggle switch 3 times On and 3 times Off. + + + Exclusion is triggered by the following procedure: + 1. Connect the device to the power supply. + 2. Make sure the device is within direct range of your Z-Wave gateway (hub) or use a hand-held Z-Wave + remote to perform exclusion. + 3. Enable add/remove mode on your Z-Wave gateway (hub). + 4. Toggle the switch connected to the terminal I 3 times within 3 seconds (this procedure put the device + in LEARN MODE). The device has to get On/Off signal 3 times, meaning 3 times push of the momentary + switch or with toggle switch 3 times On and 3 times Off. + + + Reset is triggered after the following procedure: + 1. Connect the device to the power supply. + 2. Within the first minute (60 seconds) the device is connected to the power supply, toggle the switch + connected to the terminal I 5 times within 3 seconds. The device has to get On/Off signal 5 times, meaning + 5 times push of the momentary switch or with toggle switch 5 times On and 5 times Off. + + + Initial Import + Fixed value type of config parameter 65 + Changed descriptions of parameters 5 and 6 and added some metadata + + + @@ -11,7 +55,27 @@ - With this parameter, you can change the device presentation on the user interface. + With this parameter, you can change the device presentation on the user interface. This parameter was removed in ZMNHHDx H1S3P2 (recertification) and was replaced with parameter no.6. + + + + + + With this parameter, you select the load type: dimmable or non dimmable. + Device operating in dimmable mode or non-dimmable load can lead to device or load malfunction. + For non dimmable loads no.6 must be set to 1. + + NOTE: When no.6 set to 1 (non dimmable load) values of the following parameters will be ingnored: + - par.60 min. dimming value, + - par.61 max. dimming value, + - par.65 Dimm. Time when key presed, + - par.66 dimm. Time when key hold, + - par.21 Double click function + + NOTE: If the bulb is dimmable or non dimmable (generally valid for LED) is shown on the bulb itself or on packaging. + + This parameter was added in ZMNHHDx H1S3P2 (recertification) and replaces parameter no.5, that required a reinclusion of the device. + diff --git a/config/qubino/ZMNHMDx.xml b/config/qubino/ZMNHMDx.xml new file mode 100644 index 0000000000..a4311a15d9 --- /dev/null +++ b/config/qubino/ZMNHMDx.xml @@ -0,0 +1,168 @@ + + + Smart leak protector + Qubino Smart leak protector can get the information about consumed water on one side, or have the complete protection of your home water system with water metering, flood detection and actuator for opening and closing the valve accordingly. + http://www.openzwave.com/device-database/0159:0051:0006 + https://qubino.com + https://support.qubino.com/support/home + images/qubino/ZMNHADx.png + + 1. Enable add/remove mode on your Z-Wave gateway. + 2. Connect the device to the power supply. + 3. Make sure the device is within direct range of your Z-Wave gateway. + 4. Push the switch connected to the I1 terminal 3 times within 5 seconds. + OR + Press and hold the S (Service) button between 2 and 6 seconds. + 4. A new device will appear on your dashboard. + 5. Inclusion with the switch connected to I1 terminal is not limited by time. + + + 1. Connect the device to the power supply. + 2. Make sure the device is within direct range of your Z-Wave gateway or use a hand-held Z-Wave remote to perform exclusion. + 3. Enable add/remove mode on your Z-Wave gateway. + 4. Toggle the switch connected to the I1 terminal 3 times within 5 seconds. The device must get ON/OFF signal 3 times. + OR + Press and hold the S (Service) button between 2 and 6 seconds. + 5. Exclusion with the switch connected to I1 terminal is not limited by time. + 6. The device will be removed from your network, but any custom configuration parameters will not be erased. + + + 1. Connect the device to the power supply. + 2. Within the first minute (60 seconds) of the device being connected to the power supply, push the momentary switch connected to the I1 terminal 5 times within 5 seconds. + OR + Press and hold the S (Service) button for more than 6 seconds. + The procedure is always available. + + + Initial Import + + + + + + + + Defines the output contact type for Q↑. + + + + + + Defines how the device reacts if a signal from I2 input is registered. + + + + + + Defines how the device reacts if a signal from I3 input is registered.. + + + + + + With this parameter, the user can select if the state of the device should be restored, after a power failure. + + + + + + + With this parameter we can set the current water consumption value in liters. + The value is represented with two's complement notation so that it can represent negative values also. + Span of the input value is from (-2147483648) to (+2147483647). + Its main usage is to set the same value on our device as on physical water meter. + If we get the PARAMETER_48 value with PARAMETER_GET command we get the last value that was set with this parameter and not the current water consumption value! + To get the current consumption value we must send the METER_GET command. + + + + + + This number defines how many litres represent 1 received pulse from the water meter connected to I2. + Default value = 10 (1 pulse = 10 liters) + 1 to 1000 => 1 litre – 1000 litres (step is 1 litre). + + + + + + This number defines how many minimum litres must be consumed each hour and constantly repeated for the defined time in parameter 52 to cause the leak alarm (depends on meter resolution). + Default value = 1 (1 litre) + 1 to 1000 => 1 litre – 1000 litres (step is 1 litre). + + + + + + Set value means time interval (0 – 24) in hours, during which the device checks, if water consumption defined in Parameter 51 was consumed to cause the leak alarm. + Default value = 24 (checking for a leak alarm in 24 hours) + 1 – 24 => 1 hour – 24 hours + + + + + + This number defines how many minimum litres must be consumed each hour and constantly repeated for the defined time in parameter 54 to cause the leak alarm. + Default value = 150 (150 litres) + 1 – 1000 => 1 litre – 1000 litres – step is 1 litre + + + + + + Set value means time interval (0 – 24) in hours, during which the device checks, if water consumption defined in Parameter 53 was consumed to cause the leak alarm. + Default value = 6 (checking for a leak alarm in 6 hours) + 1 – 24 => 1 hour – 24 hours + + + + + + This number defines how many minimum liters must be consumed each hour and constantly repeated for the defined time in parameter 56 to cause the leak alarm. + Default value 300 (300 liters) + 1 – 1000 = 1 litre – 1000 litres – step is 1 litre + + + + + + Set value means time interval (0 – 24) in hours, during which the device checks, if water consumption defined in Parameter 53 was consumed to cause the leak alarm. + Default value = 3 (checking for a leak alarm in 3 hours) + 1 – 24 => 1 hour – 24 hours + + + + + This parameter defines what happens with the valve if the leak alarm is triggered. + + + + + + This parameter defines what happens with the valve if the leak alarm is triggered. + + + + + + This parameter defines what happens with the valve if the leak alarm is triggered. + + + + + + This parameter defines what happens with the valve if the leak alarm is triggered. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cpp/build/testconfigversions.cfg b/cpp/build/testconfigversions.cfg index f1cc56e116..f9599db444 100644 --- a/cpp/build/testconfigversions.cfg +++ b/cpp/build/testconfigversions.cfg @@ -312,8 +312,8 @@ 'md5' => 'c4775cc1e44d3580cf6cadede3c1dca34dc94d9cb573888775ded7da5f224035853690d715ce8c7de0031d1e5df637d0da1ff7c1c86957755f09b65bcd4677f5' }, 'config/aeotec/zw100.xml' => { - 'Revision' => 24, - 'md5' => 'd7844707b29f8fe526d94aca4b1a47a26a3639e8d4a681199bb2775024d2f273c7be634cba65062d1ba2000803491af6aa654bcf33969e7ab870ffc80ce6f673' + 'Revision' => 25, + 'md5' => '3260a03fd6b6656d02ce4d70755e72cd7af35b0e1ed1c95efed230c8ee7d5bc13443092e031977d114efad81e43b35af53ba965b9c12b6a8e5c30b1e4fc59b02' }, 'config/aeotec/zw111.xml' => { 'Revision' => 8, @@ -364,8 +364,8 @@ 'md5' => 'b64f170b079ae1340bd4a74ef3a88f0cdf66281fa28d656b46f408b183d04c8e6a67f584f90dd6f8b2aa1fc2b2039e32b936f6f947394d28002b3d3a2a47cadb' }, 'config/aeotec/zw141.xml' => { - 'Revision' => 7, - 'md5' => '3707dc66d31c2b7b68d3067021825beb48e00aaf04802a8b5f69dbccb2e1228cb0fa10ea71e3fe1f4ce2f1ac92958504fe3200552f8daca10024da401d9bb7ea' + 'Revision' => 8, + 'md5' => '06b71d604f18c6a9a1dc5f7dd9ed31e561ad406814d96e2b2cf5d7242db12fc19ca5cea9d15901f8d22050fbdf9eb33c21099feacf53f692418d3f517fb27961' }, 'config/aeotec/zw162.xml' => { 'Revision' => 8, @@ -419,6 +419,10 @@ 'Revision' => 1, 'md5' => 'dea1ef33d8f6ee2abbe83a0aabd9c9e22e4a9d86e0715f1ee90c8851ed135ff27521ddd6cc308cd09648e2aca4a498903054fd5ee66f3338098f9ce81fcef2f3' }, + 'config/aeotec/zwa011.xml' => { + 'Revision' => 1, + 'md5' => 'a67f8c997e6813f1772b4e980ad1580327d4f993fe007442580b9a37163bf732ddecd431fdd944e8d1f5841f9a55ad8cd43e4a5b5471709748b5974e7171e55e' + }, 'config/aeotec/zwa012.xml' => { 'Revision' => 1, 'md5' => 'bcfcf5d1a552ab8a8ac6ab7586f3de4cd7189d72a11e60bbad6b0038eb33f1d4acba164b625e7d8343b712aa27752fbe9f17f5ee9294ce82599e7abdf6c675f9' @@ -431,6 +435,10 @@ 'Revision' => 2, 'md5' => '1337565d4bb52206d7c29f16a04957d09e9f800da716907a5190841f6b69901f5fde754d7e9713d0ac97f2ef6ab7b563edb3f3fda6981e58757e5f2202ab50e0' }, + 'config/aeotec/zwa023.xml' => { + 'Revision' => 2, + 'md5' => '55f789365f3b8a4f1c84a44dc93cac26f2afff40963a4ea6dee8a69f9ca5b40d71d0ca73e5b9f6dd6a420d9f38c75bec5bd2b7800256d9d1169035b88e114315' + }, 'config/airlinemechanical/zds-ud10.xml' => { 'Revision' => 1, 'md5' => '028c79db0efa85f50283cb57a22462dac7d2e7024851b5d715ddb7f715d0012b8f993829ad542639294ab266b3017fb31a62ed8fec929dde8f401dd276dde67f' @@ -1459,6 +1467,10 @@ 'Revision' => 3, 'md5' => '6dc4cc5e720bb5c534f25510f20c134baffb3d4b1f68704d397bab9775b6b14397471dee6469f230ecb81afd79363837589a531be926a7d3e789e82b4c1c5a83' }, + 'config/hank/hkzw-so08-smartplug.xml' => { + 'Revision' => 3, + 'md5' => '825fa7c75df29cad9ad3d2556e2b3c3eed5636ee0a4b2ca3af5eeb0542908373eac082b2db0839ec362d18332842add4fc09aca713629fed8c092e9dcf576fde' + }, 'config/hank/scenecontroller1.xml' => { 'Revision' => 3, 'md5' => 'e748ff7ae3bb3358e80b863cdea2103275dbf536edbd538963502c7629aaa623c49b562d092cfbf4db17f7fa2f4b191223ad1e9513c86b58b937eb6504145f7c' @@ -1952,8 +1964,8 @@ 'md5' => '4d34aeaaea917c229bedbb737e4de1550b2d7db5f9e61566a1c0a39966b6442d381d01f93714e12aae1404797d36854274cc4063dd7424b00d27da238b17a36a' }, 'config/manufacturer_specific.xml' => { - 'Revision' => 167, - 'md5' => '49cf25b11c0e08a228e10add2adfb48f6ea0a2196cf057a99cf54ea81f90505566e51d6a31760e59039c9903b57f53a36c6b3e7d48068fad8d8a55b2f667bf4c' + 'Revision' => 171, + 'md5' => 'ad06ce14f7a9a06a7ca99ce01632f0b95b580069c58a0ed0ec343594306603749799f00d27fa432a08582f9be08be339388bd3b854485e51e8cde086dd6c6e3d' }, 'config/mcohome/a8-9.xml' => { 'Revision' => 1, @@ -2384,8 +2396,8 @@ 'md5' => 'de18029a1539e10dd15fc85ede084182e1cfcbc78325602ca6e5b428884f6db6ce1bebdbea331a8ca0f4ba133828c09f13ce6c1f8486871a5ca9c17258358ba1' }, 'config/qubino/ZMNHHDx.xml' => { - 'Revision' => 2, - 'md5' => '190639b81177c88bd4a340e96d83578085f35ede860d7bc613bc879e4baff907c951d498696a52d84659936714855efae2a62e183d279957e3a8bda14d949a26' + 'Revision' => 3, + 'md5' => '1670fc7355688ae031018b28e6b3c184b3efa84a964b6d7b435175842e43a1ff445c5cdc7a336f71203fbd4d53ad9169a61968fac2b760db7339d9d5b58538b0' }, 'config/qubino/ZMNHIA2.xml' => { 'Revision' => 2, @@ -2419,6 +2431,10 @@ 'Revision' => 3, 'md5' => '5024808b8551691103b25c05fe37ae3b49499a38fe0491bcd492accab0eb346b7e810c3132cd67e1920ed0d971f07dd9303a3b774276aab38ac04610fe5dbd50' }, + 'config/qubino/ZMNHMDx.xml' => { + 'Revision' => 1, + 'md5' => '10bb3f3f11e86e4ec0e164e74e69f990864cd9fd76a4b407b1c26c54f5bcd5f16c3dc08482988b4f557f244da5cbb61b6555d5b1496d5ce3d7086868cd4ba3bc' + }, 'config/qubino/ZMNHNDx.xml' => { 'Revision' => 6, 'md5' => 'a10317520ca58616369d1d7782640ffeb84fb778c781f3bb39e7d6a0f22cfdad7aedb65b781f632e36c2c9837188019d00bb8b6509bc022719a64a77ea2c6277' diff --git a/cpp/src/Msg.cpp b/cpp/src/Msg.cpp index 9a4c9c3ff5..b11227d1e6 100644 --- a/cpp/src/Msg.cpp +++ b/cpp/src/Msg.cpp @@ -33,6 +33,7 @@ #include "ZWSecurity.h" #include "platform/Log.h" #include "command_classes/MultiInstance.h" +#include "command_classes/Supervision.h" #include "command_classes/Security.h" #include "aes/aescpp.h" @@ -50,7 +51,7 @@ namespace OpenZWave //----------------------------------------------------------------------------- Msg::Msg(string const& _logText, uint8 _targetNodeId, uint8 const _msgType, uint8 const _function, bool const _bCallbackRequired, bool const _bReplyRequired, // = true uint8 const _expectedReply, // = 0 - uint8 const _expectedCommandClassId // = 0 + uint8 const _expectedCommandClassId // = 0 ) : m_logText(_logText), m_bFinal(false), m_bCallbackRequired(_bCallbackRequired), m_callbackId(0), m_expectedReply(0), m_expectedCommandClassId(_expectedCommandClassId), m_length(4), m_targetNodeId(_targetNodeId), m_sendAttempts(0), m_maxSendAttempts( MAX_TRIES), m_instance(1), m_endPoint(0), m_flags(0), m_encrypted(false), m_noncerecvd(false), m_homeId(0), m_resendDuetoCANorNAK(false) { @@ -102,6 +103,19 @@ namespace OpenZWave } } +//----------------------------------------------------------------------------- +// +// Encapsulate the data inside a Supervision message +//----------------------------------------------------------------------------- + void Msg::SetSupervision(uint8 _supervision_session_id) + { + if (_supervision_session_id != Internal::CC::Supervision::StaticNoSessionId()) + { + m_supervision_session_id = _supervision_session_id; + m_flags |= m_Supervision; + } + } + //----------------------------------------------------------------------------- // // Add a byte to the message @@ -135,6 +149,12 @@ namespace OpenZWave return; } + // Deal with Supervision encapsulation + if ((m_flags & m_Supervision) != 0) + { + SupervisionEncap(); + } + // Deal with Multi-Channel/Instance encapsulation if ((m_flags & (m_MultiChannel | m_MultiInstance)) != 0) { @@ -280,6 +300,33 @@ namespace OpenZWave } } +//----------------------------------------------------------------------------- +// +// Encapsulate the data inside a Supervision message +//----------------------------------------------------------------------------- + void Msg::SupervisionEncap() + { + char str[256]; + if (m_buffer[3] != FUNC_ID_ZW_SEND_DATA) + { + return; + } + + for (uint32 i = m_length - 1; i >= 6; --i) + { + m_buffer[i + 4] = m_buffer[i]; + } + m_buffer[6] = Internal::CC::Supervision::StaticGetCommandClassId(); + m_buffer[7] = Internal::CC::Supervision::SupervisionCmd_Get; + m_buffer[8] = Internal::CC::Supervision::SupervisionMoreStatusUpdates_MoreReports | m_supervision_session_id; + m_buffer[9] = m_buffer[5]; + m_buffer[5] += 4; + m_length += 4; + + snprintf(str, sizeof(str), "Supervisioned (session=%d): %s", m_supervision_session_id, m_logText.c_str()); + m_logText = str; + } + //----------------------------------------------------------------------------- // // Get a pointer to our driver diff --git a/cpp/src/Msg.h b/cpp/src/Msg.h index 8a0bbb6c5f..dbaa127d9c 100644 --- a/cpp/src/Msg.h +++ b/cpp/src/Msg.h @@ -54,6 +54,7 @@ namespace OpenZWave { m_MultiChannel = 0x01, // Indicate MultiChannel encapsulation m_MultiInstance = 0x02, // Indicate MultiInstance encapsulation + m_Supervision = 0x04, // Indicate Supervision encapsulation }; Msg(string const& _logtext, uint8 _targetNodeId, uint8 const _msgType, uint8 const _function, bool const _bCallbackRequired, bool const _bReplyRequired = true, uint8 const _expectedReply = 0, uint8 const _expectedCommandClassId = 0); @@ -62,6 +63,7 @@ namespace OpenZWave } void SetInstance(OpenZWave::Internal::CC::CommandClass * _cc, uint8 const _instance); // Used to enable wrapping with MultiInstance/MultiChannel during finalize. + void SetSupervision(uint8 _session_id); void Append(uint8 const _data); void AppendArray(const uint8* const _data, const uint8 _length); @@ -215,7 +217,7 @@ namespace OpenZWave { m_homeId = homeId; } - void setResendDuetoCANorNAK() + void setResendDuetoCANorNAK() { m_resendDuetoCANorNAK = true; } @@ -231,6 +233,7 @@ namespace OpenZWave private: void MultiEncap(); // Encapsulate the data inside a MultiInstance/Multicommand message + void SupervisionEncap(); // Encapsulate the data inside a Supervision message string m_logText; bool m_bFinal; bool m_bCallbackRequired; @@ -249,6 +252,7 @@ namespace OpenZWave uint8 m_instance; uint8 m_endPoint; // Endpoint to use if the message must be wrapped in a multiInstance or multiChannel command class uint8 m_flags; + uint8 m_supervision_session_id; bool m_encrypted; bool m_noncerecvd; diff --git a/cpp/src/Node.cpp b/cpp/src/Node.cpp index 377a6b3738..0ecd05a092 100644 --- a/cpp/src/Node.cpp +++ b/cpp/src/Node.cpp @@ -58,6 +58,7 @@ #include "command_classes/NodeNaming.h" #include "command_classes/NoOperation.h" #include "command_classes/Version.h" +#include "command_classes/Supervision.h" #include "command_classes/SwitchAll.h" #include "command_classes/ZWavePlusInfo.h" #include "command_classes/DeviceResetLocally.h" @@ -4049,3 +4050,35 @@ void Node::WriteMetaDataXML(TiXmlElement *mdElement) mdElement->LinkEndChild(cl); } } + +//----------------------------------------------------------------------------- +// +// Generate a new session id for Supervision encapsulation, if supported +//----------------------------------------------------------------------------- +uint8 Node::CreateSupervisionSession(uint8 _command_class_id, uint8 _index) +{ + if (Internal::CC::CommandClass* cc = GetCommandClass(Internal::CC::Supervision::StaticGetCommandClassId())) + { + return cc->CreateSupervisionSession(_command_class_id, _index); + } + else + { + return Internal::CC::Supervision::StaticNoSessionId(); + } +} + +//----------------------------------------------------------------------------- +// +// Get the index used by a session +//----------------------------------------------------------------------------- +uint32 Node::GetSupervisionIndex(uint8 _session_id) +{ + if (Internal::CC::CommandClass* cc = GetCommandClass(Internal::CC::Supervision::StaticGetCommandClassId())) + { + return cc->GetSupervisionIndex(_session_id); + } + else + { + return Internal::CC::Supervision::StaticNoIndex(); + } +} diff --git a/cpp/src/Node.h b/cpp/src/Node.h index 9fbd0f42af..bae66efb07 100644 --- a/cpp/src/Node.h +++ b/cpp/src/Node.h @@ -911,6 +911,10 @@ namespace OpenZWave void WriteMetaDataXML(TiXmlElement*); map m_metadata; map m_changeLog; + + public: + uint8 CreateSupervisionSession(uint8 _command_class_id, uint8 _index); + uint32 GetSupervisionIndex(uint8 _session_id); }; } //namespace OpenZWave diff --git a/cpp/src/command_classes/CommandClass.h b/cpp/src/command_classes/CommandClass.h index 5120b6706c..4e7ddad03b 100644 --- a/cpp/src/command_classes/CommandClass.h +++ b/cpp/src/command_classes/CommandClass.h @@ -149,6 +149,13 @@ namespace OpenZWave virtual bool supportsMultiInstance() { return true; } + virtual uint8 CreateSupervisionSession(uint8 _command_class_id, uint8 _index) { + return 0; + } + virtual uint32 GetSupervisionIndex(uint8 _session_id) { + return 0; + } + virtual void SupervisionSessionSuccess(uint8 _session_id, uint32 const _instance) {}; void SetInstances(uint8 const _instances); void SetInstance(uint8 const _endPoint); diff --git a/cpp/src/command_classes/CommandClasses.cpp b/cpp/src/command_classes/CommandClasses.cpp index d8748caeec..41345ce783 100644 --- a/cpp/src/command_classes/CommandClasses.cpp +++ b/cpp/src/command_classes/CommandClasses.cpp @@ -70,6 +70,7 @@ #include "command_classes/SensorBinary.h" #include "command_classes/SensorMultilevel.h" #include "command_classes/SoundSwitch.h" +#include "command_classes/Supervision.h" #include "command_classes/SwitchAll.h" #include "command_classes/SwitchBinary.h" #include "command_classes/SwitchMultilevel.h" @@ -226,6 +227,7 @@ namespace OpenZWave cc.Register(SensorBinary::StaticGetCommandClassId(), SensorBinary::StaticGetCommandClassName(), SensorBinary::Create); cc.Register(SensorMultilevel::StaticGetCommandClassId(), SensorMultilevel::StaticGetCommandClassName(), SensorMultilevel::Create); cc.Register(SoundSwitch::StaticGetCommandClassId(), SoundSwitch::StaticGetCommandClassName(), SoundSwitch::Create); + cc.Register(Supervision::StaticGetCommandClassId(), Supervision::StaticGetCommandClassName(), Supervision::Create); cc.Register(SwitchAll::StaticGetCommandClassId(), SwitchAll::StaticGetCommandClassName(), SwitchAll::Create); cc.Register(SwitchBinary::StaticGetCommandClassId(), SwitchBinary::StaticGetCommandClassName(), SwitchBinary::Create); cc.Register(SwitchMultilevel::StaticGetCommandClassId(), SwitchMultilevel::StaticGetCommandClassName(), SwitchMultilevel::Create); diff --git a/cpp/src/command_classes/Supervision.cpp b/cpp/src/command_classes/Supervision.cpp new file mode 100644 index 0000000000..97908e081c --- /dev/null +++ b/cpp/src/command_classes/Supervision.cpp @@ -0,0 +1,174 @@ +//----------------------------------------------------------------------------- +// +// Supervision.h +// +// Implementation of the Z-Wave COMMAND_CLASS_SUPERVISION +// +// Copyright (c) 2020 Mark Ruys +// +// SOFTWARE NOTICE AND LICENSE +// +// This file is part of OpenZWave. +// +// OpenZWave is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// OpenZWave is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with OpenZWave. If not, see . +// +//----------------------------------------------------------------------------- + +#include "command_classes/CommandClasses.h" +#include "command_classes/Supervision.h" +#include "Defs.h" +#include "Msg.h" +#include "Node.h" +#include "Driver.h" +#include "platform/Log.h" + +#include "value_classes/Value.h" + +namespace OpenZWave +{ + namespace Internal + { + namespace CC + { + uint8 Supervision::CreateSupervisionSession(uint8 _command_class_id, uint8 _index) + { + m_last_session_id++; + m_last_session_id &= 0x3f; + + if (m_sessions.size() >= 6) + { + // Clean up oldest session, we support max 6 simultaneous sessions per node + m_sessions.pop_front(); + } + + m_sessions.push_back({ + .session_id = m_last_session_id, + .command_class_id = _command_class_id, + .index = _index + }); + + return m_last_session_id; + } + + uint32 Supervision::GetSupervisionIndex(uint8 _session_id) + { + for (auto it = m_sessions.cbegin(); it != m_sessions.cend(); ++it) + { + if (it->session_id == _session_id) + { + return it->index; + } + } + + return StaticNoIndex(); + } + +//----------------------------------------------------------------------------- +// +// Handle a supervision report message from the Z-Wave network +//----------------------------------------------------------------------------- + void Supervision::HandleSupervisionReport(uint8 const* _data, uint32 const _length, uint32 const _instance) + { + if (Node* node = GetNodeUnsafe()) + { + if (_length >= 4) + { + uint8 more_status_updates = _data[1] >> 7; + uint8 session_id = _data[1] & 0x3f; + uint8 status = _data[2]; + int duration = _data[3]; + + const char *status_identifier; + switch (status) { + case 0x00: status_identifier = "NO_SUPPORT"; break; + case 0x01: status_identifier = "WORKING"; break; + case 0x02: status_identifier = "FAIL"; break; + case 0xff: status_identifier = "SUCCESS"; break; + default: status_identifier = "UNKNOWN"; break; + } + + for (auto it = m_sessions.cbegin(); it != m_sessions.cend(); ++it) + { + if (it->session_id == session_id) + { + if (CommandClass* pCommandClass = node->GetCommandClass(it->command_class_id)) + { + Log::Write(LogLevel_Info, GetNodeId(), "Received SupervisionReport: session %d, %s index %d, status %s, duration %d sec, more status updates %d", + session_id, + pCommandClass->GetCommandClassName().c_str(), it->index, + status_identifier, decodeDuration(duration), more_status_updates); + + if (status == SupervisionStatus::SupervisionStatus_Success) + { + pCommandClass->SupervisionSessionSuccess(session_id, _instance); + } + } + else + { + Log::Write(LogLevel_Warning, GetNodeId(), "Received SupervisionReport for unknown CC %d", it->command_class_id); + } + + if (more_status_updates == 0) + { + m_sessions.erase(it); + } + + return; + } + } + + Log::Write(LogLevel_Warning, GetNodeId(), "Received SupervisionReport: unknown session %d, status %s, duration %d sec, more status updates %d", + session_id, + status_identifier, decodeDuration(duration), more_status_updates); + } + } + } + + bool Supervision::HandleIncomingMsg(uint8 const* _data, uint32 const _length, uint32 const _instance) + { + return HandleMsg(_data, _length, _instance); + } + +//----------------------------------------------------------------------------- +// +// Handle a message from the Z-Wave network +//----------------------------------------------------------------------------- + bool Supervision::HandleMsg(uint8 const* _data, uint32 const _length, uint32 const _instance) // = 1 + { + bool handled = false; + Node* node = GetNodeUnsafe(); + if (node != NULL) + { + handled = true; + switch ((SupervisionCmd) _data[0]) + { + case SupervisionCmd_Report: + { + HandleSupervisionReport(_data, _length, _instance); + break; + } + default: + { + handled = false; + break; + } + } + } + + return handled; + } + } // namespace CC + } // namespace Internal +} // namespace OpenZWave + diff --git a/cpp/src/command_classes/Supervision.h b/cpp/src/command_classes/Supervision.h new file mode 100644 index 0000000000..2484717055 --- /dev/null +++ b/cpp/src/command_classes/Supervision.h @@ -0,0 +1,127 @@ +//----------------------------------------------------------------------------- +// +// Supervision.h +// +// Implementation of the Z-Wave COMMAND_CLASS_SUPERVISION +// +// Copyright (c) 2020 Mark Ruys +// +// SOFTWARE NOTICE AND LICENSE +// +// This file is part of OpenZWave. +// +// OpenZWave is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// OpenZWave is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with OpenZWave. If not, see . +// +//----------------------------------------------------------------------------- + +#ifndef _Supervision_H +#define _Supervision_H + +#include + +#include "command_classes/CommandClass.h" + +namespace OpenZWave +{ + namespace Internal + { + namespace CC + { + /** \brief Implements COMMAND_CLASS_SUPERVISION (0x6c), a Z-Wave device command class. + * \ingroup CommandClass + */ + class Supervision: public CommandClass + { + public: + enum SupervisionCmd + { + SupervisionCmd_Get = 0x01, + SupervisionCmd_Report = 0x02, + }; + enum SupervisionMoreStatusUpdates + { + SupervisionMoreStatusUpdates_LastReport = 0x00, + SupervisionMoreStatusUpdates_MoreReports = 0x80, + }; + enum SupervisionStatus + { + SupervisionStatus_NoSupport = 0x00, + SupervisionStatus_Working = 0x01, + SupervisionStatus_Fail = 0x02, + SupervisionStatus_Success = 0xff + }; + + static CommandClass* Create(uint32 const _homeId, uint8 const _nodeId) + { + return new Supervision(_homeId, _nodeId); + } + virtual ~Supervision() + { + } + + static uint8 const StaticGetCommandClassId() + { + return 0x6c; + } + static string const StaticGetCommandClassName() + { + return "COMMAND_CLASS_SUPERVISION"; + } + + uint8 CreateSupervisionSession(uint8 _command_class_id, uint8 _index); + static uint8 const StaticNoSessionId() + { + return 0xff; // As sessions are only 5 bits, this value will never match + } + uint32 GetSupervisionIndex(uint8 _session_id); + static uint32 const StaticNoIndex() + { + return 0xffff; // As indices are max 16 bits, this value will never match + } + + // From CommandClass + virtual uint8 const GetCommandClassId() const override + { + return StaticGetCommandClassId(); + } + virtual string const GetCommandClassName() const override + { + return StaticGetCommandClassName(); + } + virtual bool HandleIncomingMsg(uint8 const* _data, uint32 const _length, uint32 const _instance = 1) override; + virtual bool HandleMsg(uint8 const* _data, uint32 const _length, uint32 const _instance = 1) override; + + private: + Supervision(uint32 const _homeId, uint8 const _nodeId) : + CommandClass(_homeId, _nodeId), + m_last_session_id{StaticNoSessionId()} + { + } + + struct s_Session { + uint8 session_id; + uint8 command_class_id; + uint8 index; + }; + std::deque m_sessions; + uint8 m_last_session_id; + + void HandleSupervisionReport(uint8 const* _data, uint32 const _length, uint32 const _instance); + }; + } // namespace CC + } // namespace Internal +} // namespace OpenZWave + +#endif + diff --git a/cpp/src/command_classes/SwitchBinary.cpp b/cpp/src/command_classes/SwitchBinary.cpp index df5d079d0d..0fa9cc1332 100644 --- a/cpp/src/command_classes/SwitchBinary.cpp +++ b/cpp/src/command_classes/SwitchBinary.cpp @@ -30,6 +30,7 @@ #include "command_classes/CommandClasses.h" #include "command_classes/SwitchBinary.h" #include "command_classes/WakeUp.h" +#include "command_classes/Supervision.h" #include "Defs.h" #include "Msg.h" #include "Driver.h" @@ -139,6 +140,29 @@ namespace OpenZWave return false; } + + void SwitchBinary::SupervisionSessionSuccess(uint8 _session_id, uint32 const _instance) + { + if (Node* node = GetNodeUnsafe()) + { + uint32 index = node->GetSupervisionIndex(_session_id); + + if (index != Internal::CC::Supervision::StaticNoIndex()) + { + if (Internal::VC::ValueBool* value = static_cast(GetValue(_instance, index))) + { + value->ConfirmNewValue(); + + Log::Write(LogLevel_Info, GetNodeId(), "Confirmed switch binary index %d to value=%s", + index, value->GetValue() ? "On" : "Off"); + } + } + else + { + Log::Write(LogLevel_Info, GetNodeId(), "Ignore unknown supervision session %d", _session_id); + } + } + } //----------------------------------------------------------------------------- // @@ -212,41 +236,54 @@ namespace OpenZWave { uint8 const nodeId = GetNodeId(); uint8 const targetValue = _state ? 0xff : 0; + + if (Node* node = GetNodeUnsafe()) + { + //add supervision encapsulation if supported + uint8 index = ValueID_Index_SwitchBinary::Level; + uint8 supervision_session_id = node->CreateSupervisionSession(StaticGetCommandClassId(), index); + if (supervision_session_id == Internal::CC::Supervision::StaticNoSessionId()) + { + Log::Write(LogLevel_Debug, GetNodeId(), "Supervision not supported, fall back to setpoint set/get"); + } - Log::Write(LogLevel_Info, nodeId, "SwitchBinary::Set - Setting to %s", _state ? "On" : "Off"); - Msg* msg = new Msg("SwitchBinaryCmd_Set", nodeId, REQUEST, FUNC_ID_ZW_SEND_DATA, true); - msg->SetInstance(this, _instance); - msg->Append(nodeId); + Log::Write(LogLevel_Info, nodeId, "SwitchBinary::Set - Setting to %s", _state ? "On" : "Off"); + Msg* msg = new Msg("SwitchBinaryCmd_Set", nodeId, REQUEST, FUNC_ID_ZW_SEND_DATA, true); + msg->SetInstance(this, _instance); + msg->SetSupervision(supervision_session_id); + msg->Append(nodeId); - if (GetVersion() >= 2) - { - Internal::VC::ValueInt* durationValue = static_cast(GetValue(_instance, ValueID_Index_SwitchBinary::Duration)); - uint32 duration = durationValue->GetValue(); - durationValue->Release(); - if (duration > 7620) - Log::Write(LogLevel_Info, GetNodeId(), " Duration: Device Default"); - else if (duration > 0x7F) - Log::Write(LogLevel_Info, GetNodeId(), " Rouding to %d Minutes (over 127 seconds)", encodeDuration(duration)-0x79); - else - Log::Write(LogLevel_Info, GetNodeId(), " Duration: %d seconds", duration); + if (GetVersion() >= 2) + { + Internal::VC::ValueInt* durationValue = static_cast(GetValue(_instance, ValueID_Index_SwitchBinary::Duration)); + uint32 duration = durationValue->GetValue(); + durationValue->Release(); + if (duration > 7620) + Log::Write(LogLevel_Info, GetNodeId(), " Duration: Device Default"); + else if (duration > 0x7F) + Log::Write(LogLevel_Info, GetNodeId(), " Rouding to %d Minutes (over 127 seconds)", encodeDuration(duration)-0x79); + else + Log::Write(LogLevel_Info, GetNodeId(), " Duration: %d seconds", duration); - msg->Append(4); - msg->Append(GetCommandClassId()); - msg->Append(SwitchBinaryCmd_Set); - msg->Append(targetValue); - msg->Append(encodeDuration(duration)); - } - else - { - msg->Append(3); - msg->Append(GetCommandClassId()); - msg->Append(SwitchBinaryCmd_Set); - msg->Append(targetValue); - } + msg->Append(4); + msg->Append(GetCommandClassId()); + msg->Append(SwitchBinaryCmd_Set); + msg->Append(targetValue); + msg->Append(encodeDuration(duration)); + } + else + { + msg->Append(3); + msg->Append(GetCommandClassId()); + msg->Append(SwitchBinaryCmd_Set); + msg->Append(targetValue); + } - msg->Append(GetDriver()->GetTransmitOptions()); - GetDriver()->SendMsg(msg, Driver::MsgQueue_Send); - return true; + msg->Append(GetDriver()->GetTransmitOptions()); + GetDriver()->SendMsg(msg, Driver::MsgQueue_Send); + return true; + } + return false; } //----------------------------------------------------------------------------- diff --git a/cpp/src/command_classes/SwitchBinary.h b/cpp/src/command_classes/SwitchBinary.h index ff4fdb0104..c301a73d67 100644 --- a/cpp/src/command_classes/SwitchBinary.h +++ b/cpp/src/command_classes/SwitchBinary.h @@ -80,6 +80,7 @@ namespace OpenZWave { return 2; } + virtual void SupervisionSessionSuccess(uint8 _session_id, uint32 const _instance); protected: virtual void CreateVars(uint8 const _instance) override; diff --git a/cpp/src/command_classes/SwitchMultilevel.cpp b/cpp/src/command_classes/SwitchMultilevel.cpp index 7685b81bbf..a20339e26c 100644 --- a/cpp/src/command_classes/SwitchMultilevel.cpp +++ b/cpp/src/command_classes/SwitchMultilevel.cpp @@ -28,6 +28,7 @@ #include "command_classes/CommandClasses.h" #include "command_classes/SwitchMultilevel.h" #include "command_classes/WakeUp.h" +#include "command_classes/Supervision.h" #include "Defs.h" #include "Msg.h" #include "Driver.h" @@ -226,6 +227,29 @@ namespace OpenZWave return false; } + void SwitchMultilevel::SupervisionSessionSuccess(uint8 _session_id, uint32 const _instance) + { + if (Node* node = GetNodeUnsafe()) + { + uint32 index = node->GetSupervisionIndex(_session_id); + + if (index != Internal::CC::Supervision::StaticNoIndex()) + { + if (Internal::VC::ValueByte* value = static_cast(GetValue(_instance, ValueID_Index_SwitchMultiLevel::Level))) + { + value->ConfirmNewValue(); + + Log::Write(LogLevel_Info, GetNodeId(), "Confirmed switch multi level index %d to value=%d", + index, value->GetValue()); + } + } + else + { + Log::Write(LogLevel_Info, GetNodeId(), "Ignore unknown supervision session %d", _session_id); + } + } + } + //----------------------------------------------------------------------------- // // Set the level on a device @@ -394,40 +418,54 @@ namespace OpenZWave //----------------------------------------------------------------------------- bool SwitchMultilevel::SetLevel(uint8 const _instance, uint8 const _level) { - Log::Write(LogLevel_Info, GetNodeId(), "SwitchMultilevel::Set - Setting to level %d", _level); - Msg* msg = new Msg("SwitchMultilevelCmd_Set", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true); - msg->SetInstance(this, _instance); - msg->Append(GetNodeId()); - if (GetVersion() >= 2) - { - Internal::VC::ValueInt* durationValue = static_cast(GetValue(_instance, ValueID_Index_SwitchMultiLevel::Duration)); - uint32 duration = durationValue->GetValue(); - durationValue->Release(); - if (duration > 7620) - Log::Write(LogLevel_Info, GetNodeId(), " Duration: Device Default"); - else if (duration > 0x7F) - Log::Write(LogLevel_Info, GetNodeId(), " Rouding to %d Minutes (over 127 seconds)", encodeDuration(duration)-0x79); - else - Log::Write(LogLevel_Info, GetNodeId(), " Duration: %d seconds", duration); - - msg->Append(4); - msg->Append(GetCommandClassId()); - msg->Append(SwitchMultilevelCmd_Set); - msg->Append(_level); - msg->Append(encodeDuration(duration)); - } - else + if (Node* node = GetNodeUnsafe()) { - msg->Append(3); - msg->Append(GetCommandClassId()); - msg->Append(SwitchMultilevelCmd_Set); - msg->Append(_level); - } + //add supervision encapsulation if supported + uint8 index = ValueID_Index_SwitchMultiLevel::Level; + uint8 supervision_session_id = node->CreateSupervisionSession(StaticGetCommandClassId(), index); + if (supervision_session_id == Internal::CC::Supervision::StaticNoSessionId()) + { + Log::Write(LogLevel_Debug, GetNodeId(), "Supervision not supported, fall back to setpoint set/get"); + } - msg->Append(GetDriver()->GetTransmitOptions()); - GetDriver()->SendMsg(msg, Driver::MsgQueue_Send); - return true; + Log::Write(LogLevel_Info, GetNodeId(), "SwitchMultilevel::Set - Setting to level %d", _level); + Msg* msg = new Msg("SwitchMultilevelCmd_Set", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true); + msg->SetInstance(this, _instance); + msg->SetSupervision(supervision_session_id); + msg->Append(GetNodeId()); + + if (GetVersion() >= 2) + { + Internal::VC::ValueInt* durationValue = static_cast(GetValue(_instance, ValueID_Index_SwitchMultiLevel::Duration)); + uint32 duration = durationValue->GetValue(); + durationValue->Release(); + if (duration > 7620) + Log::Write(LogLevel_Info, GetNodeId(), " Duration: Device Default"); + else if (duration > 0x7F) + Log::Write(LogLevel_Info, GetNodeId(), " Rouding to %d Minutes (over 127 seconds)", encodeDuration(duration)-0x79); + else + Log::Write(LogLevel_Info, GetNodeId(), " Duration: %d seconds", duration); + + msg->Append(4); + msg->Append(GetCommandClassId()); + msg->Append(SwitchMultilevelCmd_Set); + msg->Append(_level); + msg->Append(encodeDuration(duration)); + } + else + { + msg->Append(3); + msg->Append(GetCommandClassId()); + msg->Append(SwitchMultilevelCmd_Set); + msg->Append(_level); + } + + msg->Append(GetDriver()->GetTransmitOptions()); + GetDriver()->SendMsg(msg, Driver::MsgQueue_Send); + return true; + } + return false; } //----------------------------------------------------------------------------- diff --git a/cpp/src/command_classes/SwitchMultilevel.h b/cpp/src/command_classes/SwitchMultilevel.h index 72de24dd75..6c3aa7561a 100644 --- a/cpp/src/command_classes/SwitchMultilevel.h +++ b/cpp/src/command_classes/SwitchMultilevel.h @@ -79,6 +79,7 @@ namespace OpenZWave { return 4; } + virtual void SupervisionSessionSuccess(uint8 _session_id, uint32 const _instance); protected: virtual void CreateVars(uint8 const _instance) override; diff --git a/cpp/src/command_classes/ThermostatMode.cpp b/cpp/src/command_classes/ThermostatMode.cpp index 37c657f279..7f00a7e6e1 100644 --- a/cpp/src/command_classes/ThermostatMode.cpp +++ b/cpp/src/command_classes/ThermostatMode.cpp @@ -26,6 +26,7 @@ //----------------------------------------------------------------------------- #include "command_classes/CommandClasses.h" +#include "command_classes/Supervision.h" #include "command_classes/ThermostatMode.h" #include "Defs.h" #include "Msg.h" @@ -92,7 +93,7 @@ namespace OpenZWave static char const* c_modeName[] = { "Off", "Heat", "Cool", "Auto", "Aux Heat", "Resume", "Fan Only", "Furnace", "Dry Air", "Moist Air", "Auto Changeover", "Heat Econ", "Cool Econ", "Away", "Unknown", "Full Power", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Manufacturer Specific" }; - + ThermostatMode::ThermostatMode(uint32 const _homeId, uint8 const _nodeId) : CommandClass(_homeId, _nodeId), @@ -323,6 +324,7 @@ namespace OpenZWave } } } + /* at this stage, we don't know the Actual Mode of the Fan, so set it to the lowest * value... If not, set to 0, which possibly could be invalid... */ @@ -341,29 +343,70 @@ namespace OpenZWave return false; } + void ThermostatMode::SupervisionSessionSuccess(uint8 _session_id, uint32 const _instance) + { + if (Node* node = GetNodeUnsafe()) + { + uint32 index = node->GetSupervisionIndex(_session_id); + + if (index != Internal::CC::Supervision::StaticNoIndex()) + { + // We have received the confirmation for the thermostat mode from the Z-Wave device + if (Internal::VC::ValueList* valueList = static_cast(GetValue(_instance, ValueID_Index_ThermostatMode::Mode))) + { + valueList->ConfirmNewValue(); + if (valueList->GetItem()) + { + Log::Write(LogLevel_Info, GetNodeId(), "Confirmed thermostat mode: %s", valueList->GetItem()->m_label.c_str()); + m_currentMode = valueList->GetItem()->m_value; + } + else + Log::Write(LogLevel_Warning, GetNodeId(), "Confirmed thermostat mode (No Item)"); + valueList->Release(); + } + } + else + { + Log::Write(LogLevel_Info, GetNodeId(), "Ignore unknown supervision session %d", _session_id); + } + } + } + //----------------------------------------------------------------------------- // // Set the device's thermostat mode //----------------------------------------------------------------------------- bool ThermostatMode::SetValue(Internal::VC::Value const& _value) { - if (ValueID::ValueType_List == _value.GetID().GetType()) + + if (Node* node = GetNodeUnsafe()) { - Internal::VC::ValueList const* value = static_cast(&_value); - if (value->GetItem() == NULL) - return false; - uint8 state = (uint8) value->GetItem()->m_value; + if (ValueID::ValueType_List == _value.GetID().GetType()) + { + Internal::VC::ValueList const* value = static_cast(&_value); + if (value->GetItem() == NULL) + return false; + uint8 state = (uint8)value->GetItem()->m_value; + + uint8 index = value->GetID().GetIndex() & 0xFF; + uint8 supervision_session_id = node->CreateSupervisionSession(StaticGetCommandClassId(), index); + if (supervision_session_id == Internal::CC::Supervision::StaticNoSessionId()) + { + Log::Write(LogLevel_Debug, GetNodeId(), "Supervision not supported, fall back to setpoint set/get"); + } - Msg* msg = new Msg("ThermostatModeCmd_Set", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true); - msg->SetInstance(this, _value.GetID().GetInstance()); - msg->Append(GetNodeId()); - msg->Append(3); - msg->Append(GetCommandClassId()); - msg->Append(ThermostatModeCmd_Set); - msg->Append(state); - msg->Append(GetDriver()->GetTransmitOptions()); - GetDriver()->SendMsg(msg, Driver::MsgQueue_Send); - return true; + Msg* msg = new Msg("ThermostatModeCmd_Set", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true); + msg->SetInstance(this, _value.GetID().GetInstance()); + msg->SetSupervision(supervision_session_id); + msg->Append(GetNodeId()); + msg->Append(3); + msg->Append(GetCommandClassId()); + msg->Append(ThermostatModeCmd_Set); + msg->Append(state); + msg->Append(GetDriver()->GetTransmitOptions()); + GetDriver()->SendMsg(msg, Driver::MsgQueue_Send); + return true; + } } return false; diff --git a/cpp/src/command_classes/ThermostatMode.h b/cpp/src/command_classes/ThermostatMode.h index 0dc4d59254..efa6fae742 100644 --- a/cpp/src/command_classes/ThermostatMode.h +++ b/cpp/src/command_classes/ThermostatMode.h @@ -82,6 +82,7 @@ namespace OpenZWave { return 3; } + virtual void SupervisionSessionSuccess(uint8 _session_id, uint32 const _instance); protected: virtual void CreateVars(uint8 const _instance) override; diff --git a/cpp/src/command_classes/ThermostatSetpoint.cpp b/cpp/src/command_classes/ThermostatSetpoint.cpp index cef14b0a61..62eac4025b 100644 --- a/cpp/src/command_classes/ThermostatSetpoint.cpp +++ b/cpp/src/command_classes/ThermostatSetpoint.cpp @@ -26,6 +26,7 @@ //----------------------------------------------------------------------------- #include "command_classes/CommandClasses.h" +#include "command_classes/Supervision.h" #include "command_classes/ThermostatSetpoint.h" #include "Defs.h" #include "Msg.h" @@ -142,7 +143,7 @@ namespace OpenZWave // // Handle a message from the Z-Wave network //----------------------------------------------------------------------------- - bool ThermostatSetpoint::HandleMsg(uint8 const* _data, uint32 const _length, uint32 const _instance // = 1 + bool ThermostatSetpoint::HandleMsg(uint8 const* _data, uint32 const _length, uint32 const _instance // = 1 ) { if (ThermostatSetpointCmd_Report == (ThermostatSetpointCmd) _data[0]) @@ -261,28 +262,64 @@ namespace OpenZWave return false; } + void ThermostatSetpoint::SupervisionSessionSuccess(uint8 _session_id, uint32 const _instance) + { + if (Node* node = GetNodeUnsafe()) + { + uint32 index = node->GetSupervisionIndex(_session_id); + + if (index != Internal::CC::Supervision::StaticNoIndex()) + { + if (Internal::VC::ValueDecimal* value = static_cast(GetValue(_instance, index))) + { + value->ConfirmNewValue(); + + Log::Write(LogLevel_Info, GetNodeId(), "Confirmed thermostat setpoint index %d to %s%s", + index, value->GetValue().c_str(), value->GetUnits().c_str()); + } + } + else + { + Log::Write(LogLevel_Info, GetNodeId(), "Ignore unknown supervision session %d", _session_id); + } + } + } + //----------------------------------------------------------------------------- // // Set a thermostat setpoint temperature //----------------------------------------------------------------------------- bool ThermostatSetpoint::SetValue(Internal::VC::Value const& _value) { - if (ValueID::ValueType_Decimal == _value.GetID().GetType()) + if (Node* node = GetNodeUnsafe()) { - Internal::VC::ValueDecimal const* value = static_cast(&_value); - uint8 scale = strcmp("C", value->GetUnits().c_str()) ? 1 : 0; + if (ValueID::ValueType_Decimal == _value.GetID().GetType()) + { + Internal::VC::ValueDecimal const* value = static_cast(&_value); + + uint8 index = value->GetID().GetIndex() & 0xFF; + uint8 supervision_session_id = node->CreateSupervisionSession(StaticGetCommandClassId(), index); + if (supervision_session_id == Internal::CC::Supervision::StaticNoSessionId()) + { + Log::Write(LogLevel_Debug, GetNodeId(), "Supervision not supported, fall back to setpoint set/get"); + } - Msg* msg = new Msg("ThermostatSetpointCmd_Set", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true); - msg->SetInstance(this, _value.GetID().GetInstance()); - msg->Append(GetNodeId()); - msg->Append(4 + GetAppendValueSize(value->GetValue())); - msg->Append(GetCommandClassId()); - msg->Append(ThermostatSetpointCmd_Set); - msg->Append((uint8_t) (value->GetID().GetIndex() & 0xFF)); - AppendValue(msg, value->GetValue(), scale); - msg->Append(GetDriver()->GetTransmitOptions()); - GetDriver()->SendMsg(msg, Driver::MsgQueue_Send); - return true; + uint8 scale = strcmp("C", value->GetUnits().c_str()) ? 1 : 0; + + Msg* msg = new Msg("ThermostatSetpointCmd_Set", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true); + msg->SetInstance(this, _value.GetID().GetInstance()); + msg->SetSupervision(supervision_session_id); + msg->Append(GetNodeId()); + msg->Append(4 + GetAppendValueSize(value->GetValue())); + msg->Append(GetCommandClassId()); + msg->Append(ThermostatSetpointCmd_Set); + msg->Append(index); + AppendValue(msg, value->GetValue(), scale); + + msg->Append(GetDriver()->GetTransmitOptions()); + GetDriver()->SendMsg(msg, Driver::MsgQueue_Send); + return true; + } } return false; diff --git a/cpp/src/command_classes/ThermostatSetpoint.h b/cpp/src/command_classes/ThermostatSetpoint.h index fb12a54eaf..adaebc397d 100644 --- a/cpp/src/command_classes/ThermostatSetpoint.h +++ b/cpp/src/command_classes/ThermostatSetpoint.h @@ -31,6 +31,7 @@ #include #include #include "command_classes/CommandClass.h" +#include "value_classes/ValueDecimal.h" namespace OpenZWave { @@ -79,6 +80,7 @@ namespace OpenZWave { return 3; } + virtual void SupervisionSessionSuccess(uint8 _session_id, uint32 const _instance); protected: virtual void CreateVars(uint8 const _instance) override; diff --git a/cpp/src/value_classes/Value.cpp b/cpp/src/value_classes/Value.cpp index 5849a52a2f..cc5933a694 100644 --- a/cpp/src/value_classes/Value.cpp +++ b/cpp/src/value_classes/Value.cpp @@ -36,6 +36,7 @@ #include "value_classes/Value.h" #include "platform/Log.h" #include "command_classes/CommandClass.h" +#include "command_classes/Supervision.h" #include #include "Options.h" @@ -312,9 +313,13 @@ namespace OpenZWave { if (!IsWriteOnly()) { - // queue a "RequestValue" message to update the value - if (m_refreshAfterSet) { - cc->RequestValue( 0, m_id.GetIndex(), m_id.GetInstance(), Driver::MsgQueue_Send ); + if (m_refreshAfterSet) + { + if (!node->GetCommandClass(Internal::CC::Supervision::StaticGetCommandClassId())) + { + // queue a "RequestValue" message to update the value + cc->RequestValue( 0, m_id.GetIndex(), m_id.GetInstance(), Driver::MsgQueue_Send ); + } } } else @@ -483,11 +488,11 @@ namespace OpenZWave // Check a refreshed value //----------------------------------------------------------------------------- int Value::VerifyRefreshedValue( - void* _originalValue, - void* _checkValue, - void* _newValue, + void* _originalValue, + void* _checkValue, + void* _newValue, void* _targetValue, - ValueID::ValueType _type, + ValueID::ValueType _type, int _originalValueLength, // = 0, int _checkValueLength, // = 0, int _newValueLength, // = 0, @@ -607,9 +612,9 @@ namespace OpenZWave bOriginalEqual = (*((bool*) _originalValue) == *((bool*) _newValue)); break; case ValueID::ValueType_Raw: // raw - bOriginalEqual = (_originalValueLength == _newValueLength); // first check length of arrays + bOriginalEqual = (_originalValueLength == _newValueLength); // first check length of arrays if (bOriginalEqual) - bOriginalEqual = (memcmp(_originalValue, _newValue, _newValueLength) == 0); // if length is the same, then check content + bOriginalEqual = (memcmp(_originalValue, _newValue, _newValueLength) == 0); // if length is the same, then check content break; case ValueID::ValueType_Schedule: // Schedule /* Should not get here */ @@ -788,19 +793,19 @@ namespace OpenZWave * - Caveat here is that if the outgoing queue is large, then this will be additionally delayed */ int32 timeout; - if (m_duration <= 2) + if (m_duration <= 2) { timeout = 250; } - else if (m_duration <= 5) + else if (m_duration <= 5) { /* for Durations less than 5 seconds, lets refresh every 1/2 seconds */ timeout = 500; - } - else + } + else { - /* Everything else is 1 second + /* Everything else is 1 second */ timeout = 1000; } @@ -813,7 +818,7 @@ namespace OpenZWave //----------------------------------------------------------------------------- // -// Callback from the Timer to send a Get value to refresh a value from the +// Callback from the Timer to send a Get value to refresh a value from the // CheckTargetValue function //----------------------------------------------------------------------------- void Value::sendValueRefresh(uint32 _unused) diff --git a/cpp/src/value_classes/ValueBool.cpp b/cpp/src/value_classes/ValueBool.cpp index 9699f256f5..eea68b2b8e 100644 --- a/cpp/src/value_classes/ValueBool.cpp +++ b/cpp/src/value_classes/ValueBool.cpp @@ -100,6 +100,9 @@ namespace OpenZWave // create a temporary copy of this value to be submitted to the Set() call and set its value to the function param ValueBool* tempValue = new ValueBool(*this); tempValue->m_value = _value; + + // Save the new value to be stored when the device confirms the value was set successfully, + m_newValue = _value; // Set the value in the device. bool ret = ((Value*) tempValue)->Set(); diff --git a/cpp/src/value_classes/ValueBool.h b/cpp/src/value_classes/ValueBool.h index 1fa837dfbc..41fb23d8e7 100644 --- a/cpp/src/value_classes/ValueBool.h +++ b/cpp/src/value_classes/ValueBool.h @@ -57,6 +57,10 @@ namespace OpenZWave bool Set(bool const _value); void OnValueRefreshed(bool const _value); + void ConfirmNewValue() + { + OnValueRefreshed(m_newValue != 0); + }; void SetTargetValue(bool const _target, uint32 _duration = 0); @@ -78,6 +82,7 @@ namespace OpenZWave bool m_value; // the current index in the m_items vector bool m_valueCheck; // the previous value (used for double-checking spurious value reads) bool m_targetValue; // The Target Value + bool m_newValue; // a new value to be set on the appropriate device (used by Supervision CC) }; } // namespace VC } // namespace Internal diff --git a/cpp/src/value_classes/ValueByte.cpp b/cpp/src/value_classes/ValueByte.cpp index 19a7b83ba2..a36b06425e 100644 --- a/cpp/src/value_classes/ValueByte.cpp +++ b/cpp/src/value_classes/ValueByte.cpp @@ -120,6 +120,9 @@ namespace OpenZWave ValueByte* tempValue = new ValueByte(*this); tempValue->m_value = _value; + // Save the new value to be stored when the device confirms the value was set successfully, + m_newValue = _value; + // Set the value in the device. bool ret = ((Value*) tempValue)->Set(); diff --git a/cpp/src/value_classes/ValueByte.h b/cpp/src/value_classes/ValueByte.h index 617018ff1b..bc65807087 100644 --- a/cpp/src/value_classes/ValueByte.h +++ b/cpp/src/value_classes/ValueByte.h @@ -55,6 +55,10 @@ namespace OpenZWave bool Set(uint8 const _value); void OnValueRefreshed(uint8 const _value); + void ConfirmNewValue() + { + OnValueRefreshed(m_newValue); + }; void SetTargetValue(uint8 const _target, uint32 _duration = 0); // From Value @@ -72,6 +76,7 @@ namespace OpenZWave uint8 m_value; // the current value uint8 m_valueCheck; // the previous value (used for double-checking spurious value reads) uint8 m_targetValue; // the Target Value, if the CC support it + uint8 m_newValue; // a new value to be set on the device (used by Supervision CC) }; } // namespace VC } // namespace Internal diff --git a/cpp/src/value_classes/ValueDecimal.cpp b/cpp/src/value_classes/ValueDecimal.cpp index 81a85d4840..34920cc4d6 100644 --- a/cpp/src/value_classes/ValueDecimal.cpp +++ b/cpp/src/value_classes/ValueDecimal.cpp @@ -87,6 +87,9 @@ namespace OpenZWave ValueDecimal* tempValue = new ValueDecimal(*this); tempValue->m_value = _value; + // Save the new value to be stored when the device confirms the value was set successfully, + m_newValue = _value; + // Set the value in the device. bool ret = ((Value*) tempValue)->Set(); diff --git a/cpp/src/value_classes/ValueDecimal.h b/cpp/src/value_classes/ValueDecimal.h index 0e39a5c77d..5b2d402b0b 100644 --- a/cpp/src/value_classes/ValueDecimal.h +++ b/cpp/src/value_classes/ValueDecimal.h @@ -59,6 +59,10 @@ namespace OpenZWave bool Set(string const& _value); void OnValueRefreshed(string const& _value); + void ConfirmNewValue() + { + OnValueRefreshed(m_newValue); + }; void SetTargetValue(string const _target, uint32 _duration = 0); // From Value diff --git a/cpp/src/value_classes/ValueList.cpp b/cpp/src/value_classes/ValueList.cpp index e5b00cdbf2..a89629d163 100644 --- a/cpp/src/value_classes/ValueList.cpp +++ b/cpp/src/value_classes/ValueList.cpp @@ -229,6 +229,9 @@ namespace OpenZWave ValueList* tempValue = new ValueList(*this); tempValue->m_valueIdx = _value; + // Save the new value to be stored when the device confirms the value was set successfully, + m_newValue = _value; + // Set the value in the device. bool ret = ((Value*) tempValue)->Set(); diff --git a/cpp/src/value_classes/ValueList.h b/cpp/src/value_classes/ValueList.h index 78a69ba47b..6aa46b351d 100644 --- a/cpp/src/value_classes/ValueList.h +++ b/cpp/src/value_classes/ValueList.h @@ -66,6 +66,10 @@ namespace OpenZWave bool SetByValue(int32 const _value); void OnValueRefreshed(int32 const _valueIdx); + void ConfirmNewValue() + { + OnValueRefreshed(m_items[m_newValue].m_value); + }; // From Value virtual string const GetAsString() const @@ -98,6 +102,7 @@ namespace OpenZWave vector m_items; int32 m_valueIdx; // the current index in the m_items vector int32 m_valueIdxCheck; // the previous index in the m_items vector (used for double-checking spurious value reads) + int32 m_newValue; // a new index to be set on the appropriate device (used by Supervision CC) uint8 m_size; int32 m_targetValue; // the Target Value, if the CC support it diff --git a/distfiles.mk b/distfiles.mk index da3004e3e7..c10e18d68e 100644 --- a/distfiles.mk +++ b/distfiles.mk @@ -115,9 +115,11 @@ DISTFILES = .gitignore \ config/aeotec/zwa006.xml \ config/aeotec/zwa008.xml \ config/aeotec/zwa009.xml \ + config/aeotec/zwa011.xml \ config/aeotec/zwa012.xml \ config/aeotec/zwa019.xml \ config/aeotec/zwa021.xml \ + config/aeotec/zwa023.xml \ config/airlinemechanical/zds-ud10.xml \ config/alfred/DB2.xml \ config/assa_abloy/ConexisL1.xml \ @@ -380,6 +382,7 @@ DISTFILES = .gitignore \ config/hank/hkzw-so01-smartplug.xml \ config/hank/hkzw-so03.xml \ config/hank/hkzw-so05-smartplug.xml \ + config/hank/hkzw-so08-smartplug.xml \ config/hank/scenecontroller1.xml \ config/hank/scenecontroller4.xml \ config/heiman/HS1CA-Z.xml \ @@ -517,9 +520,11 @@ DISTFILES = .gitignore \ config/images/aeotec/zwa005.png \ config/images/aeotec/zwa006.png \ config/images/aeotec/zwa009.png \ + config/images/aeotec/zwa011.png \ config/images/aeotec/zwa012.png \ config/images/aeotec/zwa019.png \ config/images/aeotec/zwa021.png \ + config/images/aeotec/zwa023.png \ config/images/airlinemechanical/zds-ud10.png \ config/images/alfred/DB2.png \ config/images/assa_abloy/ConexisL1.png \ @@ -891,6 +896,7 @@ DISTFILES = .gitignore \ config/images/qubino/ZMNHCDx.png \ config/images/qubino/ZMNHDA2.png \ config/images/qubino/ZMNHDDx.png \ + config/images/qubino/ZMNHHDx.png \ config/images/qubino/ZMNHIDx.png \ config/images/qubino/ZMNHNDx.png \ config/images/qubino/ZMNHODx.png \ @@ -1030,6 +1036,7 @@ DISTFILES = .gitignore \ config/images/widom/WTED.png \ config/images/wink/wnk-mot1.png \ config/images/wink/wnk-sir1p.png \ + config/images/zen17.png \ config/images/zipato/HS1CA-Z.png \ config/images/zipato/HS1CG-Z.png \ config/images/zipato/HS1SA-Z.png \ @@ -1046,6 +1053,7 @@ DISTFILES = .gitignore \ config/images/zooz/zen06.png \ config/images/zooz/zen15.png \ config/images/zooz/zen16.png \ + config/images/zooz/zen17.png \ config/images/zooz/zen20.png \ config/images/zooz/zen20v2.png \ config/images/zooz/zen21.png \ @@ -1057,6 +1065,7 @@ DISTFILES = .gitignore \ config/images/zooz/zen27.png \ config/images/zooz/zen30.png \ config/images/zooz/zen31.png \ + config/images/zooz/zen32.png \ config/images/zooz/zen34.png \ config/images/zooz/zen71.png \ config/images/zooz/zen72.png \ @@ -1267,6 +1276,7 @@ DISTFILES = .gitignore \ config/qubino/ZMNHKDx.xml \ config/qubino/ZMNHLAx.xml \ config/qubino/ZMNHLDx.xml \ + config/qubino/ZMNHMDx.xml \ config/qubino/ZMNHNDx.xml \ config/qubino/ZMNHODx.xml \ config/qubino/ZMNHQDx.xml \ @@ -1446,6 +1456,7 @@ DISTFILES = .gitignore \ config/zooz/zen07.xml \ config/zooz/zen15.xml \ config/zooz/zen16.xml \ + config/zooz/zen17.xml \ config/zooz/zen20.xml \ config/zooz/zen20v2.xml \ config/zooz/zen21.xml \ @@ -1461,6 +1472,7 @@ DISTFILES = .gitignore \ config/zooz/zen27.xml \ config/zooz/zen30.xml \ config/zooz/zen31.xml \ + config/zooz/zen32.xml \ config/zooz/zen34.xml \ config/zooz/zen71.xml \ config/zooz/zen72.xml \