Merge pull request #9581 from s-hadinger/zigbee_oct_19

Glowing led when permit join
This commit is contained in:
s-hadinger 2020-10-19 23:45:17 +02:00 committed by GitHub
commit 32648da9b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 69 additions and 16 deletions

View File

@ -34,6 +34,7 @@ public:
uint16_t manuf;
bool clusterSpecific;
bool needResponse;
bool direct; // true if direct, false if discover router
uint8_t transacId; // ZCL transaction number
const uint8_t *msg;
size_t len;
@ -86,6 +87,8 @@ struct ZigbeeStatus {
ZB_RecvMsgFunc recv_func = nullptr; // function to call when message is expected
ZB_RecvMsgFunc recv_unexpected = nullptr; // function called when unexpected message is received
uint32_t permit_end_time = 0; // timestamp when permit join ends
};
struct ZigbeeStatus zigbee;
SBuffer *zigbee_buffer = nullptr;

View File

@ -753,6 +753,8 @@ public:
void syntheticAqaraCubeOrButton(Z_attribute_list &attr_list, class Z_attribute &attr);
void syntheticAqaraVibration(Z_attribute_list &attr_list, class Z_attribute &attr);
// handle read attributes auto-responder
void autoResponder(const uint16_t *attr_list_ids, size_t attr_len);
inline void setGroupId(uint16_t groupid) {
_groupaddr = groupid;
@ -1182,6 +1184,7 @@ void ZCLFrame::parseReportAttributes(Z_attribute_list& attr_list) {
_manuf_code,
false /* not cluster specific */,
false /* noresponse */,
true /* direct no retry */,
_transact_seq, /* zcl transaction id */
buf.getBuffer(), buf.len()
}));
@ -1349,7 +1352,7 @@ void ZCLFrame::parseReadAttributes(Z_attribute_list& attr_list) {
attr_list.addAttribute(F("ReadNames")).setStrRaw(attr_names.toString(true).c_str());
// call auto-responder
Z_AutoResponder(_srcaddr, _cluster_id, _srcendpoint, read_attr_ids, len/2);
autoResponder(read_attr_ids, len/2);
}
// ZCL_CONFIGURE_REPORTING_RESPONSE

View File

@ -186,6 +186,7 @@ void Z_ReadAttrCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster
0, /* manuf */
false /* not cluster specific */,
true /* response */,
false /* discover route */,
seq, /* zcl transaction id */
attrs, attrs_len
}));

View File

@ -176,7 +176,7 @@ int32_t EZ_PermitJoinRsp(int32_t res, const class SBuffer &buf) {
//
// Special case: EZSP does not send an event for PermitJoin end, so we generate a synthetic one
//
void Z_PermitJoinDisable(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
void Z_PermitJoinDisable(void) {
Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{\"Status\":20,\"Message\":\"Pairing mode disabled\"}}"));
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE));
}
@ -1134,6 +1134,7 @@ void Z_SendDeviceInfoRequest(uint16_t shortaddr) {
0x0000, /* manuf */
false /* not cluster specific */,
true /* response */,
false /* discover route */,
transacid, /* zcl transaction id */
InfoReq, sizeof(InfoReq)
}));
@ -1155,6 +1156,7 @@ void Z_SendSingleAttributeRead(uint16_t shortaddr, uint16_t groupaddr, uint16_t
0x0000, /* manuf */
false /* not cluster specific */,
true /* response */,
false /* discover route */,
transacid, /* zcl transaction id */
InfoReq, sizeof(InfoReq)
}));
@ -1301,6 +1303,7 @@ void Z_AutoConfigReportingForCluster(uint16_t shortaddr, uint16_t groupaddr, uin
0x0000, /* manuf */
false /* not cluster specific */,
false /* no response */,
false /* discover route */,
zigbee_devices.getNextSeqNumber(shortaddr), /* zcl transaction id */
buf.buf(), buf.len()
}));
@ -1779,14 +1782,14 @@ int32_t Z_State_Ready(uint8_t value) {
//
// Mostly used for routers/end-devices
// json: holds the attributes in JSON format
void Z_AutoResponder(uint16_t srcaddr, uint16_t cluster, uint8_t endpoint, const uint16_t *attr_list_ids, size_t attr_len) {
void ZCLFrame::autoResponder(const uint16_t *attr_list_ids, size_t attr_len) {
Z_attribute_list attr_list;
for (uint32_t i=0; i<attr_len; i++) {
uint16_t attr_id = attr_list_ids[i];
uint32_t ccccaaaa = (cluster << 16) | attr_id;
uint32_t ccccaaaa = (_cluster_id << 16) | attr_id;
Z_attribute attr;
attr.setKeyId(cluster, attr_id);
attr.setKeyId(_cluster_id, attr_id);
switch (ccccaaaa) {
case 0x00000004: attr.setStr(PSTR(USE_ZIGBEE_MANUFACTURER)); break; // Manufacturer
@ -1837,7 +1840,7 @@ void Z_AutoResponder(uint16_t srcaddr, uint16_t cluster, uint8_t endpoint, const
}
if (!attr.isNone()) {
Z_parseAttributeKey(attr);
attr_list.addAttribute(cluster, attr_id) = attr;
attr_list.addAttribute(_cluster_id, attr_id) = attr;
}
}
@ -1857,22 +1860,22 @@ void Z_AutoResponder(uint16_t srcaddr, uint16_t cluster, uint8_t endpoint, const
",\"Endpoint\":%d"
",\"Response\":%s}"
),
srcaddr, cluster, endpoint,
_srcaddr, _cluster_id, _srcendpoint,
attr_list.toString().c_str());
// send
// all good, send the packet
uint8_t seq = zigbee_devices.getNextSeqNumber(srcaddr);
ZigbeeZCLSend_Raw(ZigbeeZCLSendMessage({
srcaddr,
_srcaddr,
0x0000,
cluster /*cluster*/,
endpoint,
_cluster_id /*cluster*/,
_srcendpoint,
ZCL_READ_ATTRIBUTES_RESPONSE,
0x0000, /* manuf */
false /* not cluster specific */,
false /* no response */,
seq, /* zcl transaction id */
true /* direct response */,
_transact_seq, /* zcl transaction id */
buf.getBuffer(), buf.len()
}));
}

View File

@ -819,7 +819,11 @@ void ZigbeeZCLSend_Raw(const ZigbeeZCLSendMessage &zcl) {
buf.add16(zcl.cluster); // cluster
buf.add8(0x01); // srcEp
buf.add8(zcl.endpoint); // dstEp
buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame
if (zcl.direct) {
buf.add16(0x0000); // APS frame
} else {
buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame
}
buf.add16(zcl.groupaddr); // groupId
buf.add8(zcl.transacId);
// end of ApsFrame
@ -843,7 +847,11 @@ void ZigbeeZCLSend_Raw(const ZigbeeZCLSendMessage &zcl) {
buf.add16(zcl.cluster); // cluster
buf.add8(0x01); // srcEp
buf.add8(zcl.endpoint); // broadcast endpoint for groupcast
buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame
if (zcl.direct) {
buf.add16(0x0000); // APS frame
} else {
buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame
}
buf.add16(zcl.groupaddr); // groupId
buf.add8(zcl.transacId);
// end of ApsFrame

View File

@ -192,6 +192,7 @@ void zigbeeZCLSendStr(uint16_t shortaddr, uint16_t groupaddr, uint8_t endpoint,
manuf, /* manuf */
clusterSpecific /* not cluster specific */,
true /* response */,
false /* discover route */,
seq, /* zcl transaction id */
buf.getBuffer(), buf.len()
}));
@ -739,6 +740,7 @@ void CmndZbSend(void) {
manuf, /* manuf */
false /* not cluster specific */,
false /* no response */,
false /* discover route */,
0, /* zcl transaction id */
nullptr, 0
});
@ -1219,9 +1221,11 @@ void CmndZbPermitJoin(void) {
// Log pairing mode enabled
Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{\"Status\":21,\"Message\":\"Pairing mode enabled\"}}"));
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE));
zigbee.permit_end_time = millis() + duration * 1000;
AddLog_P2(LOG_LEVEL_INFO, "zigbee.permit_end_time = %d", zigbee.permit_end_time);
} else {
zigbee.permit_end_time = millis();
}
// always register timer for disable, might happen at next tick
zigbee_devices.setTimer(0x0000 /* coordinator */, 0 /* group addr*/, duration * 1000, 0, 0 /* endpoint */, Z_CAT_PERMIT_JOIN, 0 /* value */, &Z_PermitJoinDisable);
#endif // USE_ZIGBEE_EZSP
ResponseCmndDone();
@ -1255,6 +1259,34 @@ void CmndZbEZSPListen(void) {
ResponseCmndDone();
}
void ZigbeeGlowPermitJoinLight(void) {
static const uint16_t cycle_time = 1000; // cycle up and down in 1000 ms
static const uint16_t half_cycle_time = cycle_time / 2; // cycle up and down in 1000 ms
if (zigbee.permit_end_time) {
uint16_t led_power = 0; // turn led off
// permit join is ongoing
if (TimeReached(zigbee.permit_end_time)) {
zigbee.permit_end_time = 0; // disable timer
Z_PermitJoinDisable();
} else {
uint32_t millis_to_go = millis() - zigbee.permit_end_time;
uint32_t sub_second = millis_to_go % cycle_time;
if (sub_second <= half_cycle_time) {
led_power = changeUIntScale(sub_second, 0, half_cycle_time, 0, 1023);
} else {
led_power = changeUIntScale(sub_second, half_cycle_time, cycle_time, 1023, 0);
}
led_power = ledGamma10_10(led_power);
}
// change the led state
uint32_t led_pin = Pin(GPIO_LEDLNK);
if (led_pin < 99) {
analogWrite(led_pin, ledlnk_inverted ? 1023 - led_power : led_power);
}
}
}
#endif // USE_ZIGBEE_EZSP
//
@ -1801,6 +1833,9 @@ bool Xdrv23(uint8_t function)
if (ZigbeeSerial) {
ZigbeeInputLoop();
ZigbeeOutputLoop(); // send any outstanding data
#ifdef USE_ZIGBEE_EZSP
ZigbeeGlowPermitJoinLight();
#endif // USE_ZIGBEE_EZSP
}
if (zigbee.state_machine) {
ZigbeeStateMachine_Run();