Merge pull request #8945 from s-hadinger/zigbee_july_20

Added `SO101 1` to suffix commands with source endpoint
This commit is contained in:
Theo Arends 2020-07-20 22:03:55 +02:00 committed by GitHub
commit 1182895de7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 99 additions and 23 deletions

View File

@ -120,7 +120,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t rotary_uses_rules : 1; // bit 16 (v8.3.1.6) - SetOption98 - Use rules instead of light control
uint32_t zerocross_dimmer : 1; // bit 17 (v8.3.1.4) - SetOption99 - Enable zerocross dimmer on PWM DIMMER
uint32_t remove_zbreceived : 1; // bit 18 (v8.3.1.7) - SetOption100 - Remove ZbReceived form JSON message
uint32_t spare19 : 1;
uint32_t zb_index_ep : 1; // bit 19 (v8.3.1.7) - SetOption101 - Add the source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3
uint32_t spare20 : 1;
uint32_t spare21 : 1;
uint32_t spare22 : 1;

View File

@ -141,6 +141,7 @@ public:
// Add an endpoint to a device
void addEndpoint(uint16_t shortaddr, uint8_t endpoint);
void clearEndpoints(uint16_t shortaddr);
uint32_t countEndpoints(uint16_t shortaddr) const; // return the number of known endpoints (0 if unknown)
void setManufId(uint16_t shortaddr, const char * str);
void setModelId(uint16_t shortaddr, const char * str);
@ -533,6 +534,23 @@ void Z_Devices::addEndpoint(uint16_t shortaddr, uint8_t endpoint) {
}
}
//
// Count the number of known endpoints
//
uint32_t Z_Devices::countEndpoints(uint16_t shortaddr) const {
uint32_t count_ep = 0;
int32_t found = findShortAddr(shortaddr);
if (found < 0) return 0; // avoid creating an entry if the device was never seen
const Z_Device &device = devicesAt(found);
for (uint32_t i = 0; i < endpoints_max; i++) {
if (0 != device.endpoints[i]) {
count_ep++;
}
}
return count_ep;
}
// Find the first endpoint of the device
uint8_t Z_Devices::findFirstEndpoint(uint16_t shortaddr) const {
// When in router of end-device mode, the coordinator was not probed, in this case always talk to endpoint 1

View File

@ -1157,7 +1157,7 @@ void ZCLFrame::parseResponse(void) {
// Parse non-normalized attributes
void ZCLFrame::parseClusterSpecificCommand(JsonObject& json, uint8_t offset) {
convertClusterSpecific(json, _cluster_id, _cmd_id, _frame_control.b.direction, _payload);
convertClusterSpecific(json, _cluster_id, _cmd_id, _frame_control.b.direction, _srcaddr, _srcendpoint, _payload);
sendHueUpdate(_srcaddr, _groupaddr, _cluster_id, _cmd_id, _frame_control.b.direction);
}
@ -1423,6 +1423,8 @@ int32_t Z_ApplyConverter(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObje
}
void ZCLFrame::postProcessAttributes(uint16_t shortaddr, JsonObject& json) {
// source endpoint
uint8_t src_ep = _srcendpoint;
// iterate on json elements
for (auto kv : json) {
String key_string = kv.key;
@ -1490,6 +1492,11 @@ void ZCLFrame::postProcessAttributes(uint16_t shortaddr, JsonObject& json) {
((conv_attribute == attribute) || (conv_attribute == 0xFFFF)) ) {
String new_name_str = (const __FlashStringHelper*) converter->name;
if (suffix > 1) { new_name_str += suffix; } // append suffix number
// else if (Settings.flag4.zb_index_ep) {
// if (zigbee_devices.countEndpoints(shortaddr) > 0) {
// new_name_str += _srcendpoint;
// }
// }
// apply the transformation
int32_t drop = Z_ApplyConverter(this, shortaddr, json, key, value, new_name_str, conv_cluster, conv_attribute, conv_multiplier, conv_cb);
if (drop) {

View File

@ -341,7 +341,7 @@ void sendHueUpdate(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uin
// Parse a cluster specific command, and try to convert into human readable
void convertClusterSpecific(JsonObject& json, uint16_t cluster, uint8_t cmd, bool direction, const SBuffer &payload) {
void convertClusterSpecific(JsonObject& json, uint16_t cluster, uint8_t cmd, bool direction, uint16_t shortaddr, uint8_t srcendpoint, const SBuffer &payload) {
size_t hex_char_len = payload.len()*2+2;
char *hex_char = (char*) malloc(hex_char_len);
if (!hex_char) { return; }
@ -414,11 +414,11 @@ void convertClusterSpecific(JsonObject& json, uint16_t cluster, uint8_t cmd, boo
if (command_name) {
// Now try to transform into a human readable format
String command_name2 = String(command_name);
// if (direction & 0x80) then specific transform
if (conv_direction & 0x80) {
// TODO need to create a specific command
// IAS
String command_name2 = String(command_name);
if ((cluster == 0x0500) && (cmd == 0x00)) {
// "ZoneStatusChange"
json[command_name] = xyz.x;
@ -465,11 +465,21 @@ void convertClusterSpecific(JsonObject& json, uint16_t cluster, uint8_t cmd, boo
String scene_payload = json[attrid_str];
json[F("ScenePayload")] = scene_payload.substring(8); // remove first 8 characters
}
} else {
} else { // general case
bool extended_command = false; // do we send command with endpoint suffix
// if SO101 and multiple endpoints, append endpoint number
if (Settings.flag4.zb_index_ep) {
if (zigbee_devices.countEndpoints(shortaddr) > 0) {
command_name2 += srcendpoint;
extended_command = true;
}
}
if (0 == xyz.x_type) {
json[command_name] = true; // no parameter
if (extended_command) { json[command_name2] = true; }
} else if (0 == xyz.y_type) {
json[command_name] = xyz.x; // 1 parameter
if (extended_command) { json[command_name2] = xyz.x; }
} else {
// multiple answers, create an array
JsonArray &arr = json.createNestedArray(command_name);
@ -478,6 +488,14 @@ void convertClusterSpecific(JsonObject& json, uint16_t cluster, uint8_t cmd, boo
if (xyz.z_type) {
arr.add(xyz.z);
}
if (extended_command) {
JsonArray &arr = json.createNestedArray(command_name2);
arr.add(xyz.x);
arr.add(xyz.y);
if (xyz.z_type) {
arr.add(xyz.z);
}
}
}
}
}

View File

@ -966,23 +966,44 @@ void EZ_SendZDO(uint16_t shortaddr, uint16_t cmd, const unsigned char *payload,
SBuffer buf(payload_len + 22);
uint8_t seq = zigbee_devices.getNextSeqNumber(0x0000);
buf.add16(EZSP_sendUnicast);
if (shortaddr < 0xFFFC) {
// send unicast
buf.add16(EZSP_sendUnicast);
buf.add8(EMBER_OUTGOING_DIRECT); // 00
buf.add16(shortaddr); // dest addr
// ApsFrame
buf.add16(0x0000); // ZOD profile
buf.add16(cmd); // ZDO cmd in cluster
buf.add8(0); // srcEp
buf.add8(0); // dstEp
buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame
buf.add16(0x0000); // groupId
buf.add8(seq);
// end of ApsFrame
buf.add8(0x01); // tag TODO
buf.add8(payload_len + 1); // insert seq number
buf.add8(seq);
buf.addBuffer(payload, payload_len);
buf.add8(EMBER_OUTGOING_DIRECT); // 00
buf.add16(shortaddr); // dest addr
// ApsFrame
buf.add16(0x0000); // ZOD profile
buf.add16(cmd); // ZDO cmd in cluster
buf.add8(0); // srcEp
buf.add8(0); // dstEp
buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame
buf.add16(0x0000); // groupId
buf.add8(seq);
// end of ApsFrame
buf.add8(0x01); // tag TODO
buf.add8(payload_len + 1); // insert seq number
buf.add8(seq);
buf.addBuffer(payload, payload_len);
} else {
// send broadcast
buf.add16(EZSP_sendBroadcast);
buf.add16(shortaddr); // dest addr
// ApsFrame
buf.add16(0x0000); // ZOD profile
buf.add16(cmd); // ZDO cmd in cluster
buf.add8(0); // srcEp
buf.add8(0); // dstEp
buf.add16(0x00); // APS frame
buf.add16(0x0000); // groupId
buf.add8(seq);
// end of ApsFrame
buf.add8(0x1E); // radius
buf.add8(0x01); // tag TODO
buf.add8(payload_len + 1); // insert seq number
buf.add8(seq);
buf.addBuffer(payload, payload_len);
}
ZigbeeEZSPSendCmd(buf.buf(), buf.len(), true);
}

View File

@ -992,12 +992,14 @@ void CmndZbPermitJoin(void) {
if (payload <= 0) {
duration = 0;
} else if (99 == payload) {
duration = 0xFF; // unlimited time
}
// ZNP Version
#ifdef USE_ZIGBEE_ZNP
if (99 == payload) {
duration = 0xFF; // unlimited time
}
uint16_t dstAddr = 0xFFFC; // default addr
SBuffer buf(34);
@ -1014,10 +1016,20 @@ void CmndZbPermitJoin(void) {
// EZSP VERSION
#ifdef USE_ZIGBEE_EZSP
if (99 == payload) {
ResponseCmndChar_P(PSTR("Unlimited time not supported")); return;
}
SBuffer buf(3);
buf.add16(EZSP_permitJoining);
buf.add8(duration);
ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len(), true);
// send ZDO_Mgmt_Permit_Joining_req to all routers
buf.setLen(0);
buf.add8(duration);
buf.add8(0x01); // TC_Significance - This field shall always have a value of 1, indicating a request to change the Trust Center policy. If a frame is received with a value of 0, it shall be treated as having a value of 1.
// EZ_SendZDO(0xFFFC, ZDO_Mgmt_Permit_Joining_req, buf.buf(), buf.len()); TODO fix NAK/ACK first
#endif // USE_ZIGBEE_EZSP
ResponseCmndDone();