Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zigbee support for Mi Door and Contact #9759

Merged
merged 1 commit into from
Nov 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion tasmota/xdrv_23_zigbee_2_devices.ino
Original file line number Diff line number Diff line change
Expand Up @@ -364,11 +364,14 @@ public:
inline bool validZoneType(void) const { return 0xFFFF != zone_type; }

inline uint16_t getZoneType(void) const { return zone_type; }
inline bool isPIR(void) const { return 0x000d == zone_type; }
inline bool isContact(void) const { return 0x0015 == zone_type; }

inline void setZoneType(uint16_t _zone_type) { zone_type = _zone_type; }

// 4 bytes
uint16_t zone_type; // mapped to the Zigbee standard
uint16_t zone_status; // last known state for sensor 1 & 2
uint16_t zone_type; // mapped to the Zigbee standard
// 0x0000 Standard CIE
// 0x000d Motion sensor
// 0x0015 Contact switch
Expand Down
266 changes: 134 additions & 132 deletions tasmota/xdrv_23_zigbee_5__constants.ino
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ const char Z_strings[] PROGMEM =
"ZoneState" "\x00"
"ZoneType" "\x00"
"ZoneStatus" "\x00"
"Contact" "\x00"
"CurrentSummDelivered" "\x00"
"CompanyName" "\x00"
"MeterTypeID" "\x00"
Expand Down Expand Up @@ -381,8 +382,8 @@ const char Z_strings[] PROGMEM =
"TuyaFanMode" "\x00"
"TuyaForceMode" "\x00"
"TuyaWeekSelect" "\x00"
"TerncyRotate" "\x00"
"TerncyDuration" "\x00"
"TerncyRotate" "\x00"
"Identify" "\x00"
"xxxx" "\x00"
"IdentifyQuery" "\x00"
Expand Down Expand Up @@ -742,137 +743,138 @@ enum Z_offsets {
Zo_ZoneState = 4540,
Zo_ZoneType = 4550,
Zo_ZoneStatus = 4559,
Zo_CurrentSummDelivered = 4570,
Zo_CompanyName = 4591,
Zo_MeterTypeID = 4603,
Zo_DataQualityID = 4615,
Zo_CustomerName = 4629,
Zo_Model = 4642,
Zo_PartNumber = 4648,
Zo_ProductRevision = 4659,
Zo_SoftwareRevision = 4675,
Zo_UtilityName = 4692,
Zo_POD = 4704,
Zo_AvailablePower = 4708,
Zo_PowerThreshold = 4723,
Zo_RMSVoltage = 4738,
Zo_RMSCurrent = 4749,
Zo_ActivePower = 4760,
Zo_NumberOfResets = 4772,
Zo_PersistentMemoryWrites = 4787,
Zo_LastMessageLQI = 4810,
Zo_LastMessageRSSI = 4825,
Zo_TuyaScheduleWorkdays = 4841,
Zo_TuyaScheduleHolidays = 4862,
Zo_TuyaChildLock = 4883,
Zo_TuyaWindowDetection = 4897,
Zo_TuyaValveDetection = 4917,
Zo_TuyaAutoLock = 4936,
Zo_TuyaTempTarget = 4949,
Zo_TuyaBattery = 4964,
Zo_TuyaMinTemp = 4976,
Zo_TuyaMaxTemp = 4988,
Zo_TuyaBoostTime = 5000,
Zo_TuyaComfortTemp = 5014,
Zo_TuyaEcoTemp = 5030,
Zo_TuyaValvePosition = 5042,
Zo_TuyaAwayTemp = 5060,
Zo_TuyaAwayDays = 5073,
Zo_TuyaPreset = 5086,
Zo_TuyaFanMode = 5097,
Zo_TuyaForceMode = 5109,
Zo_TuyaWeekSelect = 5123,
Zo_TerncyRotate = 5138,
Zo_TerncyDuration = 5151,
Zo_Identify = 5166,
Zo_xxxx = 5175,
Zo_IdentifyQuery = 5180,
Zo_AddGroup = 5194,
Zo_xxxx00 = 5203,
Zo_ViewGroup = 5210,
Zo_GetGroup = 5220,
Zo_01xxxx = 5229,
Zo_GetAllGroups = 5236,
Zo_00 = 5249,
Zo_RemoveGroup = 5252,
Zo_RemoveAllGroups = 5264,
Zo_ViewScene = 5280,
Zo_xxxxyy = 5290,
Zo_RemoveScene = 5297,
Zo_RemoveAllScenes = 5309,
Zo_RecallScene = 5325,
Zo_GetSceneMembership = 5337,
Zo_PowerOffEffect = 5356,
Zo_xxyy = 5371,
Zo_PowerOnRecall = 5376,
Zo_PowerOnTimer = 5390,
Zo_xxyyyyzzzz = 5403,
Zo_xx0A00 = 5414,
Zo_DimmerUp = 5421,
Zo_00190200 = 5430,
Zo_DimmerDown = 5439,
Zo_01190200 = 5450,
Zo_DimmerStop = 5459,
Zo_ResetAlarm = 5470,
Zo_xxyyyy = 5481,
Zo_ResetAllAlarms = 5488,
Zo_xx000A00 = 5503,
Zo_HueSat = 5512,
Zo_xxyy0A00 = 5519,
Zo_Color = 5528,
Zo_xxxxyyyy0A00 = 5534,
Zo_xxxx0A00 = 5547,
Zo_ShutterOpen = 5556,
Zo_ShutterClose = 5568,
Zo_ShutterStop = 5581,
Zo_ShutterLift = 5593,
Zo_xx = 5605,
Zo_ShutterTilt = 5608,
Zo_Shutter = 5620,
Zo_DimmerMove = 5628,
Zo_xx0A = 5639,
Zo_DimmerStepUp = 5644,
Zo_00xx0A00 = 5657,
Zo_DimmerStepDown = 5666,
Zo_01xx0A00 = 5681,
Zo_DimmerStep = 5690,
Zo_xx190A00 = 5701,
Zo_01 = 5710,
Zo_HueMove = 5713,
Zo_xx19 = 5721,
Zo_HueStepUp = 5726,
Zo_HueStepDown = 5736,
Zo_03xx0A00 = 5748,
Zo_HueStep = 5757,
Zo_SatMove = 5765,
Zo_SatStep = 5773,
Zo_xx190A = 5781,
Zo_ColorMove = 5788,
Zo_xxxxyyyy = 5798,
Zo_ColorStep = 5807,
Zo_ColorTempMoveUp = 5817,
Zo_01xxxx000000000000 = 5833,
Zo_ColorTempMoveDown = 5852,
Zo_03xxxx000000000000 = 5870,
Zo_ColorTempMoveStop = 5889,
Zo_00xxxx000000000000 = 5907,
Zo_ColorTempMove = 5926,
Zo_xxyyyy000000000000 = 5940,
Zo_ColorTempStepUp = 5959,
Zo_01xxxx0A0000000000 = 5975,
Zo_ColorTempStepDown = 5994,
Zo_03xxxx0A0000000000 = 6012,
Zo_ColorTempStep = 6031,
Zo_xxyyyy0A0000000000 = 6045,
Zo_ArrowClick = 6064,
Zo_ArrowHold = 6075,
Zo_ArrowRelease = 6085,
Zo_ZoneStatusChange = 6098,
Zo_xxxxyyzz = 6115,
Zo_xxyyzzzz = 6124,
Zo_AddScene = 6133,
Zo_xxyyyyzz = 6142,
Zo_StoreScene = 6151,
Zo_Contact = 4570,
Zo_CurrentSummDelivered = 4578,
Zo_CompanyName = 4599,
Zo_MeterTypeID = 4611,
Zo_DataQualityID = 4623,
Zo_CustomerName = 4637,
Zo_Model = 4650,
Zo_PartNumber = 4656,
Zo_ProductRevision = 4667,
Zo_SoftwareRevision = 4683,
Zo_UtilityName = 4700,
Zo_POD = 4712,
Zo_AvailablePower = 4716,
Zo_PowerThreshold = 4731,
Zo_RMSVoltage = 4746,
Zo_RMSCurrent = 4757,
Zo_ActivePower = 4768,
Zo_NumberOfResets = 4780,
Zo_PersistentMemoryWrites = 4795,
Zo_LastMessageLQI = 4818,
Zo_LastMessageRSSI = 4833,
Zo_TuyaScheduleWorkdays = 4849,
Zo_TuyaScheduleHolidays = 4870,
Zo_TuyaChildLock = 4891,
Zo_TuyaWindowDetection = 4905,
Zo_TuyaValveDetection = 4925,
Zo_TuyaAutoLock = 4944,
Zo_TuyaTempTarget = 4957,
Zo_TuyaBattery = 4972,
Zo_TuyaMinTemp = 4984,
Zo_TuyaMaxTemp = 4996,
Zo_TuyaBoostTime = 5008,
Zo_TuyaComfortTemp = 5022,
Zo_TuyaEcoTemp = 5038,
Zo_TuyaValvePosition = 5050,
Zo_TuyaAwayTemp = 5068,
Zo_TuyaAwayDays = 5081,
Zo_TuyaPreset = 5094,
Zo_TuyaFanMode = 5105,
Zo_TuyaForceMode = 5117,
Zo_TuyaWeekSelect = 5131,
Zo_TerncyDuration = 5146,
Zo_TerncyRotate = 5161,
Zo_Identify = 5174,
Zo_xxxx = 5183,
Zo_IdentifyQuery = 5188,
Zo_AddGroup = 5202,
Zo_xxxx00 = 5211,
Zo_ViewGroup = 5218,
Zo_GetGroup = 5228,
Zo_01xxxx = 5237,
Zo_GetAllGroups = 5244,
Zo_00 = 5257,
Zo_RemoveGroup = 5260,
Zo_RemoveAllGroups = 5272,
Zo_ViewScene = 5288,
Zo_xxxxyy = 5298,
Zo_RemoveScene = 5305,
Zo_RemoveAllScenes = 5317,
Zo_RecallScene = 5333,
Zo_GetSceneMembership = 5345,
Zo_PowerOffEffect = 5364,
Zo_xxyy = 5379,
Zo_PowerOnRecall = 5384,
Zo_PowerOnTimer = 5398,
Zo_xxyyyyzzzz = 5411,
Zo_xx0A00 = 5422,
Zo_DimmerUp = 5429,
Zo_00190200 = 5438,
Zo_DimmerDown = 5447,
Zo_01190200 = 5458,
Zo_DimmerStop = 5467,
Zo_ResetAlarm = 5478,
Zo_xxyyyy = 5489,
Zo_ResetAllAlarms = 5496,
Zo_xx000A00 = 5511,
Zo_HueSat = 5520,
Zo_xxyy0A00 = 5527,
Zo_Color = 5536,
Zo_xxxxyyyy0A00 = 5542,
Zo_xxxx0A00 = 5555,
Zo_ShutterOpen = 5564,
Zo_ShutterClose = 5576,
Zo_ShutterStop = 5589,
Zo_ShutterLift = 5601,
Zo_xx = 5613,
Zo_ShutterTilt = 5616,
Zo_Shutter = 5628,
Zo_DimmerMove = 5636,
Zo_xx0A = 5647,
Zo_DimmerStepUp = 5652,
Zo_00xx0A00 = 5665,
Zo_DimmerStepDown = 5674,
Zo_01xx0A00 = 5689,
Zo_DimmerStep = 5698,
Zo_xx190A00 = 5709,
Zo_01 = 5718,
Zo_HueMove = 5721,
Zo_xx19 = 5729,
Zo_HueStepUp = 5734,
Zo_HueStepDown = 5744,
Zo_03xx0A00 = 5756,
Zo_HueStep = 5765,
Zo_SatMove = 5773,
Zo_SatStep = 5781,
Zo_xx190A = 5789,
Zo_ColorMove = 5796,
Zo_xxxxyyyy = 5806,
Zo_ColorStep = 5815,
Zo_ColorTempMoveUp = 5825,
Zo_01xxxx000000000000 = 5841,
Zo_ColorTempMoveDown = 5860,
Zo_03xxxx000000000000 = 5878,
Zo_ColorTempMoveStop = 5897,
Zo_00xxxx000000000000 = 5915,
Zo_ColorTempMove = 5934,
Zo_xxyyyy000000000000 = 5948,
Zo_ColorTempStepUp = 5967,
Zo_01xxxx0A0000000000 = 5983,
Zo_ColorTempStepDown = 6002,
Zo_03xxxx0A0000000000 = 6020,
Zo_ColorTempStep = 6039,
Zo_xxyyyy0A0000000000 = 6053,
Zo_ArrowClick = 6072,
Zo_ArrowHold = 6083,
Zo_ArrowRelease = 6093,
Zo_ZoneStatusChange = 6106,
Zo_xxxxyyzz = 6123,
Zo_xxyyzzzz = 6132,
Zo_AddScene = 6141,
Zo_xxyyyyzz = 6150,
Zo_StoreScene = 6159,
};


Expand Down
45 changes: 26 additions & 19 deletions tasmota/xdrv_23_zigbee_5_converters.ino
Original file line number Diff line number Diff line change
Expand Up @@ -558,8 +558,9 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = {

// IAS Cluster (Intruder Alarm System)
{ Zenum8, Cx0500, 0x0000, Z_(ZoneState), Cm1, 0 }, // Occupancy (map8)
{ Zenum16, Cx0500, 0x0001, Z_(ZoneType), Cm1, 0 }, // Occupancy (map8)
{ Zmap16, Cx0500, 0x0002, Z_(ZoneStatus), Cm1 + Z_EXPORT_DATA, Z_MAPPING(Z_Data_Alarm, zone_type) }, // Occupancy (map8)
{ Zenum16, Cx0500, 0x0001, Z_(ZoneType), Cm1, Z_MAPPING(Z_Data_Alarm, zone_type) }, // Zone type for sensor
{ Zmap16, Cx0500, 0x0002, Z_(ZoneStatus), Cm1, 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

// Metering (Smart Energy) cluster
{ Zuint48, Cx0702, 0x0000, Z_(CurrentSummDelivered), Cm1, 0 },
Expand Down Expand Up @@ -1226,6 +1227,8 @@ void ZCLFrame::generateSyntheticAttributes(Z_attribute_list& attr_list) {
// Note: both function are now split to compute on extracted attributes
//
void ZCLFrame::computeSyntheticAttributes(Z_attribute_list& attr_list) {
const char * model_c = zigbee_devices.getModelId(_srcaddr); // null if unknown
String modelId((char*) model_c);
// scan through attributes and apply specific converters
for (auto &attr : attr_list) {
if (attr.key_is_str) { continue; } // pass if key is a name
Expand All @@ -1239,12 +1242,13 @@ void ZCLFrame::computeSyntheticAttributes(Z_attribute_list& attr_list) {
}
break;
case 0x00010021: // BatteryPercentage
{
const char * model_c = zigbee_devices.getModelId(_srcaddr); // null if unknown
String modelId((char*) model_c);
if (modelId.startsWith(F("TRADFRI"))) {
attr.setUInt(attr.getUInt() * 2); // bug in TRADFRI battery, need to double the value
}
if (modelId.startsWith(F("TRADFRI"))) {
attr.setUInt(attr.getUInt() * 2); // bug in TRADFRI battery, need to double the value
}
break;
case 0x00060000: // "Power" for lumi Door/Window is converted to "Contact"
if (modelId.startsWith(F("lumi.sensor_magnet"))) {
attr.setKeyId(0x0500, 0xFFF0); // change cluster and attribute to 0500/FFF0
}
break;
case 0x02010008: // Pi Heating Demand - solve Eutotronic bug
Expand Down Expand Up @@ -1558,9 +1562,21 @@ void ZCLFrame::syntheticAqaraSensor(Z_attribute_list &attr_list, class Z_attribu
attr_list.addAttribute(0x0001, 0x0020).setFloat(batteryvoltage);
uint8_t batterypercentage = toPercentageCR2032(uval32);
attr_list.addAttribute(0x0001, 0x0021).setUInt(batterypercentage * 2);
} else if ((nullptr != modelId) && (0 == getManufCode())) {
} else if ((nullptr != modelId) && ((0 == getManufCode()) || (0x115F == getManufCode()))) {
translated = true;
if (modelId.startsWith(F("lumi.sensor_ht")) ||
if (modelId.startsWith(F("lumi.sensor_magnet"))) { // door / window sensor
if (0x64 == attrid) {
attr_list.addAttribute(0x0500, 0xFFF0).copyVal(attr); // Contact
}
} else if (modelId.startsWith(F("lumi.sensor_smoke"))) { // gas leak
if (0x64 == attrid) {
attr_list.addAttribute(F("SmokeDensity")).copyVal(attr);
}
} else if (modelId.startsWith(F("lumi.sensor_natgas"))) { // gas leak
if (0x64 == attrid) {
attr_list.addAttribute(F("GasDensity")).copyVal(attr);
}
} else if (modelId.startsWith(F("lumi.sensor_ht")) ||
modelId.equals(F("lumi.sens")) ||
modelId.startsWith(F("lumi.weather"))) { // Temp sensor
// Filter according to prefix of model name
Expand All @@ -1572,18 +1588,9 @@ void ZCLFrame::syntheticAqaraSensor(Z_attribute_list &attr_list, class Z_attribu
} else if (0x66 == attrid) {
attr_list.addAttribute(0x0403, 0x0000).setUInt((ival32 + 50) / 100); // Pressure
}
} else if (modelId.startsWith(F("lumi.sensor_smoke"))) { // gas leak
if (0x64 == attrid) {
attr_list.addAttribute(F("SmokeDensity")).copyVal(attr);
}
} else if (modelId.startsWith(F("lumi.sensor_natgas"))) { // gas leak
if (0x64 == attrid) {
attr_list.addAttribute(F("GasDensity")).copyVal(attr);
}
} else {
translated = false; // we didn't find a match
}
// } else if (0x115F == zcl->getManufCode()) { // Aqara Motion Sensor, still unknown field
}
if (!translated) {
if (attrid >= 100) { // payload is always above 0x64 or 100
Expand Down
Loading