Zigbee improved CIE handling

This commit is contained in:
Stephan Hadinger 2020-12-21 12:13:57 +01:00
parent 348a65ab4e
commit c9c948e567
3 changed files with 75 additions and 8 deletions

View File

@ -847,6 +847,8 @@ typedef enum Z_Def_Category {
Z_CAT_BIND, // send auto-binding to coordinator
Z_CAT_CONFIG_ATTR, // send a config attribute reporting request
Z_CAT_READ_ATTRIBUTE, // read a single attribute
Z_CAT_CIE_ATTRIBUTE, // write CIE address
Z_CAT_CIE_ENROLL, // enroll CIE zone
} Z_Def_Category;
const uint32_t Z_CAT_REACHABILITY_TIMEOUT = 2000; // 1000 ms or 1s

View File

@ -779,8 +779,9 @@ public:
void parseReadAttributesResponse(Z_attribute_list& attr_list);
void parseReadConfigAttributes(Z_attribute_list& attr_list);
void parseConfigAttributes(Z_attribute_list& attr_list);
void parseWriteAttributesResponse(Z_attribute_list& attr_list);
void parseResponse(void);
void parseResponseOld(void);
void parseResponse_inner(uint8_t cmd, bool cluster_specific, uint8_t status);
void parseClusterSpecificCommand(Z_attribute_list& attr_list);
// synthetic attributes converters
@ -1467,6 +1468,11 @@ void ZCLFrame::parseConfigAttributes(Z_attribute_list& attr_list) {
attr_1.setStrRaw(attr_config_list.toString(true).c_str());
}
// ZCL_WRITE_ATTRIBUTES_RESPONSE
void ZCLFrame::parseWriteAttributesResponse(Z_attribute_list& attr_list) {
parseResponse_inner(ZCL_WRITE_ATTRIBUTES_RESPONSE, false, _payload.get8(0));
}
// ZCL_READ_REPORTING_CONFIGURATION_RESPONSE
void ZCLFrame::parseReadConfigAttributes(Z_attribute_list& attr_list) {
uint32_t i = 0;
@ -1554,12 +1560,8 @@ void ZCLFrame::parseReadAttributesResponse(Z_attribute_list& attr_list) {
}
}
// ZCL_DEFAULT_RESPONSE
void ZCLFrame::parseResponse(void) {
if (_payload.len() < 2) { return; } // wrong format
uint8_t cmd = _payload.get8(0);
uint8_t status = _payload.get8(1);
void ZCLFrame::parseResponse_inner(uint8_t cmd, bool cluster_specific, uint8_t status) {
Z_attribute_list attr_list;
// "Device"
@ -1572,7 +1574,7 @@ void ZCLFrame::parseResponse(void) {
attr_list.addAttributePMEM(PSTR(D_JSON_ZIGBEE_NAME)).setStr(friendlyName);
}
// "Command"
snprintf_P(s, sizeof(s), PSTR("%04X!%02X"), _cluster_id, cmd);
snprintf_P(s, sizeof(s), PSTR("%04X%c%02X"), _cluster_id, cluster_specific ? '!' : '_', cmd);
attr_list.addAttributePMEM(PSTR(D_JSON_ZIGBEE_CMD)).setStr(s);
// "Status"
attr_list.addAttributePMEM(PSTR(D_JSON_ZIGBEE_STATUS)).setUInt(status);
@ -1591,6 +1593,15 @@ void ZCLFrame::parseResponse(void) {
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED));
}
// ZCL_DEFAULT_RESPONSE
void ZCLFrame::parseResponse(void) {
if (_payload.len() < 2) { return; } // wrong format
uint8_t cmd = _payload.get8(0);
uint8_t status = _payload.get8(1);
parseResponse_inner(cmd, true, status);
}
// Parse non-normalized attributes
void ZCLFrame::parseClusterSpecificCommand(Z_attribute_list& attr_list) {
convertClusterSpecific(attr_list, _cluster_id, _cmd_id, _frame_control.b.direction, _srcaddr, _srcendpoint, _payload);

View File

@ -652,6 +652,8 @@ void Z_AutoBindDefer(uint16_t shortaddr, uint8_t endpoint, const SBuffer &buf,
if (bitRead(cluster_map, Z_ClusterToCxBinding(0x0500))) {
// send a read command to cluster 0x0500, attribute 0x0001 (ZoneType) - to read the type of sensor
zigbee_devices.queueTimer(shortaddr, 0 /* groupaddr */, 2000, 0x0500, endpoint, Z_CAT_READ_ATTRIBUTE, 0x0001, &Z_SendSingleAttributeRead);
zigbee_devices.queueTimer(shortaddr, 0 /* groupaddr */, 2000, 0x0500, endpoint, Z_CAT_CIE_ATTRIBUTE, 0 /* value */, &Z_WriteCIEAddress);
zigbee_devices.queueTimer(shortaddr, 0 /* groupaddr */, 2000, 0x0500, endpoint, Z_CAT_CIE_ENROLL, 1 /* zone */, &Z_SendCIEZoneEnrollResponse);
}
// enqueue bind requests
@ -1346,7 +1348,7 @@ void Z_SendDeviceInfoRequest(uint16_t shortaddr) {
}
//
// Send sing attribute read request in Timer
// Send single attribute read request in Timer
//
void Z_SendSingleAttributeRead(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
uint8_t transacid = zigbee_devices.getNextSeqNumber(shortaddr);
@ -1367,6 +1369,56 @@ void Z_SendSingleAttributeRead(uint16_t shortaddr, uint16_t groupaddr, uint16_t
}));
}
//
// Write CIE address
//
void Z_WriteCIEAddress(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
uint8_t transacid = zigbee_devices.getNextSeqNumber(shortaddr);
SBuffer buf(12);
buf.add16(0x0010); // attribute 0x0010
buf.add8(ZEUI64);
buf.add64(localIEEEAddr);
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Writing CIE address"));
ZigbeeZCLSend_Raw(ZigbeeZCLSendMessage({
shortaddr,
0x0000, /* group */
0x0500 /*cluster*/,
endpoint,
ZCL_WRITE_ATTRIBUTES,
0x0000, /* manuf */
false /* not cluster specific */,
true /* response */,
false /* discover route */,
transacid, /* zcl transaction id */
buf.getBuffer(), buf.len()
}));
}
//
// Write CIE address
//
void Z_SendCIEZoneEnrollResponse(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
uint8_t transacid = zigbee_devices.getNextSeqNumber(shortaddr);
uint8_t EnrollRSP[2] = { 0x00 /* Sucess */, Z_B0(value) /* ZoneID */ };
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Sending Enroll Zone %d"), Z_B0(value));
ZigbeeZCLSend_Raw(ZigbeeZCLSendMessage({
shortaddr,
0x0000, /* group */
0x0500 /*cluster*/,
endpoint,
0x00, // Zone Enroll Response
0x0000, /* manuf */
true /* cluster specific */,
true /* response */,
false /* discover route */,
transacid, /* zcl transaction id */
EnrollRSP, sizeof(EnrollRSP)
}));
}
//
// Auto-bind some clusters to the coordinator's endpoint 0x01
//
@ -1600,6 +1652,8 @@ void Z_IncomingMessage(class ZCLFrame &zcl_received) {
zcl_received.parseReadConfigAttributes(attr_list);
} else if ( (!zcl_received.isClusterSpecificCommand()) && (ZCL_CONFIGURE_REPORTING_RESPONSE == zcl_received.getCmdId())) {
zcl_received.parseConfigAttributes(attr_list);
} else if ( (!zcl_received.isClusterSpecificCommand()) && (ZCL_WRITE_ATTRIBUTES_RESPONSE == zcl_received.getCmdId())) {
zcl_received.parseWriteAttributesResponse(attr_list);
} else if (zcl_received.isClusterSpecificCommand()) {
zcl_received.parseClusterSpecificCommand(attr_list);
}