From 4243b934fe067bde94c8f139dff82a34a1958105 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 2 Dec 2020 19:25:17 +0100 Subject: [PATCH] Better support for PIR devices --- tasmota/xdrv_23_zigbee_2_devices.ino | 53 +++++++++++++++++++++++++ tasmota/xdrv_23_zigbee_5_converters.ino | 6 +++ tasmota/xdrv_23_zigbee_6_commands.ino | 8 +--- 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index 597c2d607..e5783eaed 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -427,6 +427,8 @@ public: } return false; } + + void convertZoneStatus(Z_attribute_list & attr_list, uint16_t val) const; // 4 bytes uint16_t zone_status; // last known state for sensor 1 & 2 @@ -447,6 +449,57 @@ public: // 0x0229 Security repeater* }; +void Z_Data_Alarm::convertZoneStatus(Z_attribute_list & attr_list, uint16_t val) const { + if (validConfig()) { + // indicator #1, published for false and true + if (isPIR()) { // set Occupancy + attr_list.addAttribute(0x0406, 0x0000).setUInt(val & 0x01 ? 1 : 0); + } else { // all other cases + attr_list.addAttribute(0x0500, 0xFFF0 + getConfig()).setUInt(val & 0x01 ? 1 : 0); + } + // indicator #2 published only if true + if (val & 0x02) { + if (isPIR()) { // set Occupancy + attr_list.addAttribute(0x0406, 0x0000, 2).setUInt(val & 0x02 ? 1 : 0); + } else { // all other cases + attr_list.addAttribute(0x0500, 0xFFF0 + getConfig(), 2).setUInt(val & 0x02 ? 1 : 0); + } + } + // Tamper + if (val & 0x04) { + attr_list.addAttributePMEM(PSTR("Tamper")).setUInt(1); + } + // BatteryLow + if (val & 0x08) { + attr_list.addAttributePMEM(PSTR("BatteryLow")).setUInt(1); + } + // // SupervisionReports + // if (val & 0x10) { + // attr_list.addAttributePMEM(PSTR("SupervisionReports")).setUInt(1); + // } + // // RestoreReports + // if (val & 0x20) { + // attr_list.addAttributePMEM(PSTR("RestoreReports")).setUInt(1); + // } + // Failure + if (val & 0x40) { + attr_list.addAttributePMEM(PSTR("Failure")).setUInt(1); + } + // MainsFault + if (val & 0x80) { + attr_list.addAttributePMEM(PSTR("MainsFault")).setUInt(1); + } + // Test + if (val & 0x100) { + attr_list.addAttributePMEM(PSTR("Test")).setUInt(1); + } + // BatteryDefect + if (val & 0x200) { + attr_list.addAttributePMEM(PSTR("BatteryDefect")).setUInt(1); + } + } +} + const uint8_t Z_Data_Type_len[] PROGMEM = { 0, // 0x00 Z_Data_Type::Z_Unknown sizeof(Z_Data_Light), // 0x01 Z_Data_Type::Z_Light diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index cdf64fbf5..cd388d16c 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -1312,6 +1312,12 @@ void ZCLFrame::computeSyntheticAttributes(Z_attribute_list& attr_list) { // We create a synthetic attribute 0403/FFF0 to indicate sea level } break; + case 0x05000002: // ZoneStatus + const Z_Data_Alarm & alarm = (const Z_Data_Alarm&) zigbee_devices.getShortAddr(_srcaddr).data.find(Z_Data_Type::Z_Alarm, _srcendpoint); + if (&alarm != nullptr) { + alarm.convertZoneStatus(attr_list, attr.getUInt()); + } + break; } } } diff --git a/tasmota/xdrv_23_zigbee_6_commands.ino b/tasmota/xdrv_23_zigbee_6_commands.ino index 3b37323ad..bf8bfdd6f 100644 --- a/tasmota/xdrv_23_zigbee_6_commands.ino +++ b/tasmota/xdrv_23_zigbee_6_commands.ino @@ -360,12 +360,8 @@ void convertClusterSpecific(class Z_attribute_list &attr_list, uint16_t cluster, } // Convert to "Occupancy" or to "Contact" if the device is PIR or Contact sensor const Z_Data_Alarm & alarm = (const Z_Data_Alarm&) zigbee_devices.getShortAddr(shortaddr).data.find(Z_Data_Type::Z_Alarm, srcendpoint); - if ((&alarm != nullptr) && (alarm.validConfig())) { - if (alarm.isPIR()) { // set Occupancy - attr_list.addAttribute(0x0406, 0x0000).setUInt((xyz.x) & 0x01 ? 1 : 0); - } else { // all other cases - attr_list.addAttribute(0x0500, 0xFFF0 + alarm.getConfig()).setUInt(xyz.x); - } + if (&alarm != nullptr) { + alarm.convertZoneStatus(attr_list, xyz.x); } } break;