Zigbee support more alarms types (#9839)

* Zigbee support more alarms types

* Forgot Fire, and renamed Leak to Water

Co-authored-by: Stephan Hadinger <stephan.hadinger@gmail.com>
This commit is contained in:
s-hadinger 2020-11-13 18:55:06 +01:00 committed by GitHub
parent 0ac5dade2e
commit 121687088e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 200 additions and 155 deletions

View File

@ -308,6 +308,19 @@ void Z_Data_PIR::setTimeoutSeconds(int32_t value) {
/*********************************************************************************************\ /*********************************************************************************************\
* Device specific: Sensors: temp, humidity, pressure... * Device specific: Sensors: temp, humidity, pressure...
\*********************************************************************************************/ \*********************************************************************************************/
enum Z_Alarm_Type {
ZA_CIE = 0x0,
ZA_PIR = 0x1,
ZA_Contact = 0x2,
ZA_Fire = 0x3,
ZA_Water = 0x4,
ZA_CO = 0x5,
ZA_Personal = 0x6,
ZA_Movement = 0x7,
ZA_Panic = 0x8,
ZA_GlassBreak =0x9,
};
class Z_Data_Thermo : public Z_Data { class Z_Data_Thermo : public Z_Data {
public: public:
Z_Data_Thermo(uint8_t endpoint = 0) : Z_Data_Thermo(uint8_t endpoint = 0) :
@ -361,18 +374,18 @@ typedef union Z_Alarm_Types_t {
} Z_Alarm_Types_t; } Z_Alarm_Types_t;
static const Z_Alarm_Types_t Z_Alarm_Types[] PROGMEM = { static const Z_Alarm_Types_t Z_Alarm_Types[] PROGMEM = {
{ .t = { 0x000, 0x0 }}, // 0x0 : Standard CIE { .t = { 0x000, ZA_CIE }}, // 0x0 : Standard CIE
{ .t = { 0x00d, 0x1 }}, // 0x1 : PIR { .t = { 0x00d, ZA_PIR }}, // 0x1 : PIR
{ .t = { 0x015, 0x2 }}, // 0x2 : Contact { .t = { 0x015, ZA_Contact }}, // 0x2 : Contact
{ .t = { 0x028, 0x3 }}, // 0x3 : Fire { .t = { 0x028, ZA_Fire }}, // 0x3 : Fire
{ .t = { 0x02a, 0x4 }}, // 0x4 : Leak { .t = { 0x02a, ZA_Water }}, // 0x4 : Leak
{ .t = { 0x02b, 0x5 }}, // 0x5 : CO { .t = { 0x02b, ZA_CO }}, // 0x5 : CO
{ .t = { 0x02c, 0x6 }}, // 0x6 : Personal { .t = { 0x02c, ZA_Personal }}, // 0x6 : Personal
{ .t = { 0x02d, 0x7 }}, // 0x7 : Movement { .t = { 0x02d, ZA_Movement }}, // 0x7 : Movement
{ .t = { 0x10f, 0x8 }}, // 0x8 : Panic { .t = { 0x10f, ZA_Panic }}, // 0x8 : Panic
{ .t = { 0x115, 0x8 }}, // 0x8 : Panic { .t = { 0x115, ZA_Panic }}, // 0x8 : Panic
{ .t = { 0x21d, 0x8 }}, // 0x8 : Panic { .t = { 0x21d, ZA_Panic }}, // 0x8 : Panic
{ .t = { 0x226, 0x9 }}, // 0x9 : Glass break { .t = { 0x226, ZA_GlassBreak }}, // 0x9 : Glass break
}; };
class Z_Data_Alarm : public Z_Data { class Z_Data_Alarm : public Z_Data {
@ -387,8 +400,15 @@ public:
inline bool validZoneType(void) const { return 0xFFFF != zone_type; } inline bool validZoneType(void) const { return 0xFFFF != zone_type; }
inline uint16_t getZoneType(void) const { return zone_type; } inline uint16_t getZoneType(void) const { return zone_type; }
inline bool isPIR(void) const { return 0x1 == _config; } inline bool isPIR(void) const { return ZA_PIR == _config; }
inline bool isContact(void) const { return 0x2 == _config; } inline bool isContact(void) const { return ZA_Contact == _config; }
inline bool isFire(void) const { return ZA_Fire == _config; }
inline bool isWater(void) const { return ZA_Water == _config; }
inline bool isCO(void) const { return ZA_CO == _config; }
inline bool isPersonalAlarm(void) const { return ZA_Personal == _config; }
inline bool isMovement(void) const { return ZA_Movement == _config; }
inline bool isPanic(void) const { return ZA_Panic == _config; }
inline bool isGlassBreak(void) const { return ZA_GlassBreak == _config; }
inline void setZoneType(uint16_t _zone_type) { zone_type = _zone_type; } inline void setZoneType(uint16_t _zone_type) { zone_type = _zone_type; }

View File

@ -341,7 +341,15 @@ const char Z_strings[] PROGMEM =
"ZoneState" "\x00" "ZoneState" "\x00"
"ZoneType" "\x00" "ZoneType" "\x00"
"ZoneStatus" "\x00" "ZoneStatus" "\x00"
"CIE" "\x00"
"Contact" "\x00" "Contact" "\x00"
"Fire" "\x00"
"Water" "\x00"
"CO" "\x00"
"PersonalAlarm" "\x00"
"Movement" "\x00"
"Panic" "\x00"
"GlassBreak" "\x00"
"CurrentSummDelivered" "\x00" "CurrentSummDelivered" "\x00"
"CompanyName" "\x00" "CompanyName" "\x00"
"MeterTypeID" "\x00" "MeterTypeID" "\x00"
@ -743,138 +751,146 @@ enum Z_offsets {
Zo_ZoneState = 4540, Zo_ZoneState = 4540,
Zo_ZoneType = 4550, Zo_ZoneType = 4550,
Zo_ZoneStatus = 4559, Zo_ZoneStatus = 4559,
Zo_Contact = 4570, Zo_CIE = 4570,
Zo_CurrentSummDelivered = 4578, Zo_Contact = 4574,
Zo_CompanyName = 4599, Zo_Fire = 4582,
Zo_MeterTypeID = 4611, Zo_Water = 4587,
Zo_DataQualityID = 4623, Zo_CO = 4593,
Zo_CustomerName = 4637, Zo_PersonalAlarm = 4596,
Zo_Model = 4650, Zo_Movement = 4610,
Zo_PartNumber = 4656, Zo_Panic = 4619,
Zo_ProductRevision = 4667, Zo_GlassBreak = 4625,
Zo_SoftwareRevision = 4683, Zo_CurrentSummDelivered = 4636,
Zo_UtilityName = 4700, Zo_CompanyName = 4657,
Zo_POD = 4712, Zo_MeterTypeID = 4669,
Zo_AvailablePower = 4716, Zo_DataQualityID = 4681,
Zo_PowerThreshold = 4731, Zo_CustomerName = 4695,
Zo_RMSVoltage = 4746, Zo_Model = 4708,
Zo_RMSCurrent = 4757, Zo_PartNumber = 4714,
Zo_ActivePower = 4768, Zo_ProductRevision = 4725,
Zo_NumberOfResets = 4780, Zo_SoftwareRevision = 4741,
Zo_PersistentMemoryWrites = 4795, Zo_UtilityName = 4758,
Zo_LastMessageLQI = 4818, Zo_POD = 4770,
Zo_LastMessageRSSI = 4833, Zo_AvailablePower = 4774,
Zo_TuyaScheduleWorkdays = 4849, Zo_PowerThreshold = 4789,
Zo_TuyaScheduleHolidays = 4870, Zo_RMSVoltage = 4804,
Zo_TuyaChildLock = 4891, Zo_RMSCurrent = 4815,
Zo_TuyaWindowDetection = 4905, Zo_ActivePower = 4826,
Zo_TuyaValveDetection = 4925, Zo_NumberOfResets = 4838,
Zo_TuyaAutoLock = 4944, Zo_PersistentMemoryWrites = 4853,
Zo_TuyaTempTarget = 4957, Zo_LastMessageLQI = 4876,
Zo_TuyaBattery = 4972, Zo_LastMessageRSSI = 4891,
Zo_TuyaMinTemp = 4984, Zo_TuyaScheduleWorkdays = 4907,
Zo_TuyaMaxTemp = 4996, Zo_TuyaScheduleHolidays = 4928,
Zo_TuyaBoostTime = 5008, Zo_TuyaChildLock = 4949,
Zo_TuyaComfortTemp = 5022, Zo_TuyaWindowDetection = 4963,
Zo_TuyaEcoTemp = 5038, Zo_TuyaValveDetection = 4983,
Zo_TuyaValvePosition = 5050, Zo_TuyaAutoLock = 5002,
Zo_TuyaAwayTemp = 5068, Zo_TuyaTempTarget = 5015,
Zo_TuyaAwayDays = 5081, Zo_TuyaBattery = 5030,
Zo_TuyaPreset = 5094, Zo_TuyaMinTemp = 5042,
Zo_TuyaFanMode = 5105, Zo_TuyaMaxTemp = 5054,
Zo_TuyaForceMode = 5117, Zo_TuyaBoostTime = 5066,
Zo_TuyaWeekSelect = 5131, Zo_TuyaComfortTemp = 5080,
Zo_TerncyDuration = 5146, Zo_TuyaEcoTemp = 5096,
Zo_TerncyRotate = 5161, Zo_TuyaValvePosition = 5108,
Zo_Identify = 5174, Zo_TuyaAwayTemp = 5126,
Zo_xxxx = 5183, Zo_TuyaAwayDays = 5139,
Zo_IdentifyQuery = 5188, Zo_TuyaPreset = 5152,
Zo_AddGroup = 5202, Zo_TuyaFanMode = 5163,
Zo_xxxx00 = 5211, Zo_TuyaForceMode = 5175,
Zo_ViewGroup = 5218, Zo_TuyaWeekSelect = 5189,
Zo_GetGroup = 5228, Zo_TerncyDuration = 5204,
Zo_01xxxx = 5237, Zo_TerncyRotate = 5219,
Zo_GetAllGroups = 5244, Zo_Identify = 5232,
Zo_00 = 5257, Zo_xxxx = 5241,
Zo_RemoveGroup = 5260, Zo_IdentifyQuery = 5246,
Zo_RemoveAllGroups = 5272, Zo_AddGroup = 5260,
Zo_ViewScene = 5288, Zo_xxxx00 = 5269,
Zo_xxxxyy = 5298, Zo_ViewGroup = 5276,
Zo_RemoveScene = 5305, Zo_GetGroup = 5286,
Zo_RemoveAllScenes = 5317, Zo_01xxxx = 5295,
Zo_RecallScene = 5333, Zo_GetAllGroups = 5302,
Zo_GetSceneMembership = 5345, Zo_00 = 5315,
Zo_PowerOffEffect = 5364, Zo_RemoveGroup = 5318,
Zo_xxyy = 5379, Zo_RemoveAllGroups = 5330,
Zo_PowerOnRecall = 5384, Zo_ViewScene = 5346,
Zo_PowerOnTimer = 5398, Zo_xxxxyy = 5356,
Zo_xxyyyyzzzz = 5411, Zo_RemoveScene = 5363,
Zo_xx0A00 = 5422, Zo_RemoveAllScenes = 5375,
Zo_DimmerUp = 5429, Zo_RecallScene = 5391,
Zo_00190200 = 5438, Zo_GetSceneMembership = 5403,
Zo_DimmerDown = 5447, Zo_PowerOffEffect = 5422,
Zo_01190200 = 5458, Zo_xxyy = 5437,
Zo_DimmerStop = 5467, Zo_PowerOnRecall = 5442,
Zo_ResetAlarm = 5478, Zo_PowerOnTimer = 5456,
Zo_xxyyyy = 5489, Zo_xxyyyyzzzz = 5469,
Zo_ResetAllAlarms = 5496, Zo_xx0A00 = 5480,
Zo_xx000A00 = 5511, Zo_DimmerUp = 5487,
Zo_HueSat = 5520, Zo_00190200 = 5496,
Zo_xxyy0A00 = 5527, Zo_DimmerDown = 5505,
Zo_Color = 5536, Zo_01190200 = 5516,
Zo_xxxxyyyy0A00 = 5542, Zo_DimmerStop = 5525,
Zo_xxxx0A00 = 5555, Zo_ResetAlarm = 5536,
Zo_ShutterOpen = 5564, Zo_xxyyyy = 5547,
Zo_ShutterClose = 5576, Zo_ResetAllAlarms = 5554,
Zo_ShutterStop = 5589, Zo_xx000A00 = 5569,
Zo_ShutterLift = 5601, Zo_HueSat = 5578,
Zo_xx = 5613, Zo_xxyy0A00 = 5585,
Zo_ShutterTilt = 5616, Zo_Color = 5594,
Zo_Shutter = 5628, Zo_xxxxyyyy0A00 = 5600,
Zo_DimmerMove = 5636, Zo_xxxx0A00 = 5613,
Zo_xx0A = 5647, Zo_ShutterOpen = 5622,
Zo_DimmerStepUp = 5652, Zo_ShutterClose = 5634,
Zo_00xx0A00 = 5665, Zo_ShutterStop = 5647,
Zo_DimmerStepDown = 5674, Zo_ShutterLift = 5659,
Zo_01xx0A00 = 5689, Zo_xx = 5671,
Zo_DimmerStep = 5698, Zo_ShutterTilt = 5674,
Zo_xx190A00 = 5709, Zo_Shutter = 5686,
Zo_01 = 5718, Zo_DimmerMove = 5694,
Zo_HueMove = 5721, Zo_xx0A = 5705,
Zo_xx19 = 5729, Zo_DimmerStepUp = 5710,
Zo_HueStepUp = 5734, Zo_00xx0A00 = 5723,
Zo_HueStepDown = 5744, Zo_DimmerStepDown = 5732,
Zo_03xx0A00 = 5756, Zo_01xx0A00 = 5747,
Zo_HueStep = 5765, Zo_DimmerStep = 5756,
Zo_SatMove = 5773, Zo_xx190A00 = 5767,
Zo_SatStep = 5781, Zo_01 = 5776,
Zo_xx190A = 5789, Zo_HueMove = 5779,
Zo_ColorMove = 5796, Zo_xx19 = 5787,
Zo_xxxxyyyy = 5806, Zo_HueStepUp = 5792,
Zo_ColorStep = 5815, Zo_HueStepDown = 5802,
Zo_ColorTempMoveUp = 5825, Zo_03xx0A00 = 5814,
Zo_01xxxx000000000000 = 5841, Zo_HueStep = 5823,
Zo_ColorTempMoveDown = 5860, Zo_SatMove = 5831,
Zo_03xxxx000000000000 = 5878, Zo_SatStep = 5839,
Zo_ColorTempMoveStop = 5897, Zo_xx190A = 5847,
Zo_00xxxx000000000000 = 5915, Zo_ColorMove = 5854,
Zo_ColorTempMove = 5934, Zo_xxxxyyyy = 5864,
Zo_xxyyyy000000000000 = 5948, Zo_ColorStep = 5873,
Zo_ColorTempStepUp = 5967, Zo_ColorTempMoveUp = 5883,
Zo_01xxxx0A0000000000 = 5983, Zo_01xxxx000000000000 = 5899,
Zo_ColorTempStepDown = 6002, Zo_ColorTempMoveDown = 5918,
Zo_03xxxx0A0000000000 = 6020, Zo_03xxxx000000000000 = 5936,
Zo_ColorTempStep = 6039, Zo_ColorTempMoveStop = 5955,
Zo_xxyyyy0A0000000000 = 6053, Zo_00xxxx000000000000 = 5973,
Zo_ArrowClick = 6072, Zo_ColorTempMove = 5992,
Zo_ArrowHold = 6083, Zo_xxyyyy000000000000 = 6006,
Zo_ArrowRelease = 6093, Zo_ColorTempStepUp = 6025,
Zo_ZoneStatusChange = 6106, Zo_01xxxx0A0000000000 = 6041,
Zo_xxxxyyzz = 6123, Zo_ColorTempStepDown = 6060,
Zo_xxyyzzzz = 6132, Zo_03xxxx0A0000000000 = 6078,
Zo_AddScene = 6141, Zo_ColorTempStep = 6097,
Zo_xxyyyyzz = 6150, Zo_xxyyyy0A0000000000 = 6111,
Zo_StoreScene = 6159, Zo_ArrowClick = 6130,
Zo_ArrowHold = 6141,
Zo_ArrowRelease = 6151,
Zo_ZoneStatusChange = 6164,
Zo_xxxxyyzz = 6181,
Zo_xxyyzzzz = 6190,
Zo_AddScene = 6199,
Zo_xxyyyyzz = 6208,
Zo_StoreScene = 6217,
}; };

View File

@ -560,7 +560,16 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = {
{ Zenum8, Cx0500, 0x0000, Z_(ZoneState), Cm1, 0 }, // Occupancy (map8) { Zenum8, Cx0500, 0x0000, Z_(ZoneState), Cm1, 0 }, // Occupancy (map8)
{ Zenum16, Cx0500, 0x0001, Z_(ZoneType), Cm1 + Z_EXPORT_DATA, Z_MAPPING(Z_Data_Alarm, zone_type) }, // Zone type for sensor { Zenum16, Cx0500, 0x0001, Z_(ZoneType), Cm1 + Z_EXPORT_DATA, Z_MAPPING(Z_Data_Alarm, zone_type) }, // Zone type for sensor
{ Zmap16, Cx0500, 0x0002, Z_(ZoneStatus), Cm1 + Z_EXPORT_DATA, Z_MAPPING(Z_Data_Alarm, zone_status) }, // Zone status for sensor { Zmap16, Cx0500, 0x0002, Z_(ZoneStatus), Cm1 + Z_EXPORT_DATA, Z_MAPPING(Z_Data_Alarm, zone_status) }, // Zone status for sensor
{ Zbool, Cx0500, 0xFFF0, Z_(Contact), Cm1, Z_MAPPING(Z_Data_Alarm, zone_status) }, // We fit the first bit in the LSB { Zuint8, Cx0500, 0xFFF0 + ZA_CIE, Z_(CIE), Cm1, 0 },
{ Zuint8, Cx0500, 0xFFF0 + ZA_PIR, Z_(Occupancy), Cm1, 0 }, // normally converted to the actual Occupancy 0406/0000
{ Zuint8, Cx0500, 0xFFF0 + ZA_Contact, Z_(Contact), Cm1, Z_MAPPING(Z_Data_Alarm, zone_status) }, // We fit the first bit in the LSB
{ Zuint8, Cx0500, 0xFFF0 + ZA_Fire, Z_(Fire), Cm1, 0 },
{ Zuint8, Cx0500, 0xFFF0 + ZA_Water, Z_(Water), Cm1, 0 },
{ Zuint8, Cx0500, 0xFFF0 + ZA_CO, Z_(CO), Cm1, 0 },
{ Zuint8, Cx0500, 0xFFF0 + ZA_Personal, Z_(PersonalAlarm),Cm1, 0 },
{ Zuint8, Cx0500, 0xFFF0 + ZA_Movement, Z_(Movement), Cm1, 0 },
{ Zuint8, Cx0500, 0xFFF0 + ZA_Panic, Z_(Panic), Cm1, 0 },
{ Zuint8, Cx0500, 0xFFF0 + ZA_GlassBreak, Z_(GlassBreak),Cm1, 0 },
// Metering (Smart Energy) cluster // Metering (Smart Energy) cluster
{ Zuint48, Cx0702, 0x0000, Z_(CurrentSummDelivered), Cm1, 0 }, { Zuint48, Cx0702, 0x0000, Z_(CurrentSummDelivered), Cm1, 0 },
@ -1247,7 +1256,7 @@ void ZCLFrame::computeSyntheticAttributes(Z_attribute_list& attr_list) {
break; break;
case 0x00060000: // "Power" for lumi Door/Window is converted to "Contact" case 0x00060000: // "Power" for lumi Door/Window is converted to "Contact"
if (modelId.startsWith(F("lumi.sensor_magnet"))) { if (modelId.startsWith(F("lumi.sensor_magnet"))) {
attr.setKeyId(0x0500, 0xFFF0); // change cluster and attribute to 0500/FFF0 attr.setKeyId(0x0500, 0xFFF0 + ZA_Contact); // change cluster and attribute to 0500/FFF0
} }
break; break;
case 0x02010008: // Pi Heating Demand - solve Eutotronic bug case 0x02010008: // Pi Heating Demand - solve Eutotronic bug
@ -1567,7 +1576,7 @@ void ZCLFrame::syntheticAqaraSensor(Z_attribute_list &attr_list, class Z_attribu
translated = true; translated = true;
if (modelId.startsWith(F("lumi.sensor_magnet"))) { // door / window sensor if (modelId.startsWith(F("lumi.sensor_magnet"))) { // door / window sensor
if (0x64 == attrid) { if (0x64 == attrid) {
attr_list.addAttribute(0x0500, 0xFFF0).copyVal(attr); // Contact attr_list.addAttribute(0x0500, 0xFFF0 + ZA_Contact).copyVal(attr); // Contact
} }
} else if (modelId.startsWith(F("lumi.sensor_smoke"))) { // gas leak } else if (modelId.startsWith(F("lumi.sensor_smoke"))) { // gas leak
if (0x64 == attrid) { if (0x64 == attrid) {

View File

@ -356,11 +356,11 @@ 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 // 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); const Z_Data_Alarm & alarm = (const Z_Data_Alarm&) zigbee_devices.getShortAddr(shortaddr).data.find(Z_Data_Type::Z_Alarm, srcendpoint);
if (&alarm != nullptr) { if ((&alarm != nullptr) && (alarm.validConfig())) {
if (alarm.isPIR()) { // set Occupancy if (alarm.isPIR()) { // set Occupancy
attr_list.addAttribute(0x0406, 0x0000).setUInt((xyz.x) & 0x01 ? 1 : 0); attr_list.addAttribute(0x0406, 0x0000).setUInt((xyz.x) & 0x01 ? 1 : 0);
} else if (alarm.isContact()) { // set Contact } else { // all other cases
attr_list.addAttribute(0x0500, 0xFFF0).setUInt((xyz.x) & 0x01 ? 1 : 0); attr_list.addAttribute(0x0500, 0xFFF0 + alarm.getConfig()).setUInt(xyz.x);
} }
} }
} }