mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-25 11:46:31 +00:00
Merge pull request #9581 from s-hadinger/zigbee_oct_19
Glowing led when permit join
This commit is contained in:
commit
32648da9b6
@ -34,6 +34,7 @@ public:
|
|||||||
uint16_t manuf;
|
uint16_t manuf;
|
||||||
bool clusterSpecific;
|
bool clusterSpecific;
|
||||||
bool needResponse;
|
bool needResponse;
|
||||||
|
bool direct; // true if direct, false if discover router
|
||||||
uint8_t transacId; // ZCL transaction number
|
uint8_t transacId; // ZCL transaction number
|
||||||
const uint8_t *msg;
|
const uint8_t *msg;
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -86,6 +87,8 @@ struct ZigbeeStatus {
|
|||||||
|
|
||||||
ZB_RecvMsgFunc recv_func = nullptr; // function to call when message is expected
|
ZB_RecvMsgFunc recv_func = nullptr; // function to call when message is expected
|
||||||
ZB_RecvMsgFunc recv_unexpected = nullptr; // function called when unexpected message is received
|
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;
|
struct ZigbeeStatus zigbee;
|
||||||
SBuffer *zigbee_buffer = nullptr;
|
SBuffer *zigbee_buffer = nullptr;
|
||||||
|
@ -753,6 +753,8 @@ public:
|
|||||||
void syntheticAqaraCubeOrButton(Z_attribute_list &attr_list, class Z_attribute &attr);
|
void syntheticAqaraCubeOrButton(Z_attribute_list &attr_list, class Z_attribute &attr);
|
||||||
void syntheticAqaraVibration(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) {
|
inline void setGroupId(uint16_t groupid) {
|
||||||
_groupaddr = groupid;
|
_groupaddr = groupid;
|
||||||
@ -1182,6 +1184,7 @@ void ZCLFrame::parseReportAttributes(Z_attribute_list& attr_list) {
|
|||||||
_manuf_code,
|
_manuf_code,
|
||||||
false /* not cluster specific */,
|
false /* not cluster specific */,
|
||||||
false /* noresponse */,
|
false /* noresponse */,
|
||||||
|
true /* direct no retry */,
|
||||||
_transact_seq, /* zcl transaction id */
|
_transact_seq, /* zcl transaction id */
|
||||||
buf.getBuffer(), buf.len()
|
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());
|
attr_list.addAttribute(F("ReadNames")).setStrRaw(attr_names.toString(true).c_str());
|
||||||
|
|
||||||
// call auto-responder
|
// call auto-responder
|
||||||
Z_AutoResponder(_srcaddr, _cluster_id, _srcendpoint, read_attr_ids, len/2);
|
autoResponder(read_attr_ids, len/2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ZCL_CONFIGURE_REPORTING_RESPONSE
|
// ZCL_CONFIGURE_REPORTING_RESPONSE
|
||||||
|
@ -186,6 +186,7 @@ void Z_ReadAttrCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster
|
|||||||
0, /* manuf */
|
0, /* manuf */
|
||||||
false /* not cluster specific */,
|
false /* not cluster specific */,
|
||||||
true /* response */,
|
true /* response */,
|
||||||
|
false /* discover route */,
|
||||||
seq, /* zcl transaction id */
|
seq, /* zcl transaction id */
|
||||||
attrs, attrs_len
|
attrs, attrs_len
|
||||||
}));
|
}));
|
||||||
|
@ -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
|
// 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\"}}"));
|
Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{\"Status\":20,\"Message\":\"Pairing mode disabled\"}}"));
|
||||||
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE));
|
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE));
|
||||||
}
|
}
|
||||||
@ -1134,6 +1134,7 @@ void Z_SendDeviceInfoRequest(uint16_t shortaddr) {
|
|||||||
0x0000, /* manuf */
|
0x0000, /* manuf */
|
||||||
false /* not cluster specific */,
|
false /* not cluster specific */,
|
||||||
true /* response */,
|
true /* response */,
|
||||||
|
false /* discover route */,
|
||||||
transacid, /* zcl transaction id */
|
transacid, /* zcl transaction id */
|
||||||
InfoReq, sizeof(InfoReq)
|
InfoReq, sizeof(InfoReq)
|
||||||
}));
|
}));
|
||||||
@ -1155,6 +1156,7 @@ void Z_SendSingleAttributeRead(uint16_t shortaddr, uint16_t groupaddr, uint16_t
|
|||||||
0x0000, /* manuf */
|
0x0000, /* manuf */
|
||||||
false /* not cluster specific */,
|
false /* not cluster specific */,
|
||||||
true /* response */,
|
true /* response */,
|
||||||
|
false /* discover route */,
|
||||||
transacid, /* zcl transaction id */
|
transacid, /* zcl transaction id */
|
||||||
InfoReq, sizeof(InfoReq)
|
InfoReq, sizeof(InfoReq)
|
||||||
}));
|
}));
|
||||||
@ -1301,6 +1303,7 @@ void Z_AutoConfigReportingForCluster(uint16_t shortaddr, uint16_t groupaddr, uin
|
|||||||
0x0000, /* manuf */
|
0x0000, /* manuf */
|
||||||
false /* not cluster specific */,
|
false /* not cluster specific */,
|
||||||
false /* no response */,
|
false /* no response */,
|
||||||
|
false /* discover route */,
|
||||||
zigbee_devices.getNextSeqNumber(shortaddr), /* zcl transaction id */
|
zigbee_devices.getNextSeqNumber(shortaddr), /* zcl transaction id */
|
||||||
buf.buf(), buf.len()
|
buf.buf(), buf.len()
|
||||||
}));
|
}));
|
||||||
@ -1779,14 +1782,14 @@ int32_t Z_State_Ready(uint8_t value) {
|
|||||||
//
|
//
|
||||||
// Mostly used for routers/end-devices
|
// Mostly used for routers/end-devices
|
||||||
// json: holds the attributes in JSON format
|
// 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;
|
Z_attribute_list attr_list;
|
||||||
|
|
||||||
for (uint32_t i=0; i<attr_len; i++) {
|
for (uint32_t i=0; i<attr_len; i++) {
|
||||||
uint16_t attr_id = attr_list_ids[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;
|
Z_attribute attr;
|
||||||
attr.setKeyId(cluster, attr_id);
|
attr.setKeyId(_cluster_id, attr_id);
|
||||||
|
|
||||||
switch (ccccaaaa) {
|
switch (ccccaaaa) {
|
||||||
case 0x00000004: attr.setStr(PSTR(USE_ZIGBEE_MANUFACTURER)); break; // Manufacturer
|
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()) {
|
if (!attr.isNone()) {
|
||||||
Z_parseAttributeKey(attr);
|
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"
|
",\"Endpoint\":%d"
|
||||||
",\"Response\":%s}"
|
",\"Response\":%s}"
|
||||||
),
|
),
|
||||||
srcaddr, cluster, endpoint,
|
_srcaddr, _cluster_id, _srcendpoint,
|
||||||
attr_list.toString().c_str());
|
attr_list.toString().c_str());
|
||||||
|
|
||||||
// send
|
// send
|
||||||
// all good, send the packet
|
// all good, send the packet
|
||||||
uint8_t seq = zigbee_devices.getNextSeqNumber(srcaddr);
|
|
||||||
ZigbeeZCLSend_Raw(ZigbeeZCLSendMessage({
|
ZigbeeZCLSend_Raw(ZigbeeZCLSendMessage({
|
||||||
srcaddr,
|
_srcaddr,
|
||||||
0x0000,
|
0x0000,
|
||||||
cluster /*cluster*/,
|
_cluster_id /*cluster*/,
|
||||||
endpoint,
|
_srcendpoint,
|
||||||
ZCL_READ_ATTRIBUTES_RESPONSE,
|
ZCL_READ_ATTRIBUTES_RESPONSE,
|
||||||
0x0000, /* manuf */
|
0x0000, /* manuf */
|
||||||
false /* not cluster specific */,
|
false /* not cluster specific */,
|
||||||
false /* no response */,
|
false /* no response */,
|
||||||
seq, /* zcl transaction id */
|
true /* direct response */,
|
||||||
|
_transact_seq, /* zcl transaction id */
|
||||||
buf.getBuffer(), buf.len()
|
buf.getBuffer(), buf.len()
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -819,7 +819,11 @@ void ZigbeeZCLSend_Raw(const ZigbeeZCLSendMessage &zcl) {
|
|||||||
buf.add16(zcl.cluster); // cluster
|
buf.add16(zcl.cluster); // cluster
|
||||||
buf.add8(0x01); // srcEp
|
buf.add8(0x01); // srcEp
|
||||||
buf.add8(zcl.endpoint); // dstEp
|
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.add16(zcl.groupaddr); // groupId
|
||||||
buf.add8(zcl.transacId);
|
buf.add8(zcl.transacId);
|
||||||
// end of ApsFrame
|
// end of ApsFrame
|
||||||
@ -843,7 +847,11 @@ void ZigbeeZCLSend_Raw(const ZigbeeZCLSendMessage &zcl) {
|
|||||||
buf.add16(zcl.cluster); // cluster
|
buf.add16(zcl.cluster); // cluster
|
||||||
buf.add8(0x01); // srcEp
|
buf.add8(0x01); // srcEp
|
||||||
buf.add8(zcl.endpoint); // broadcast endpoint for groupcast
|
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.add16(zcl.groupaddr); // groupId
|
||||||
buf.add8(zcl.transacId);
|
buf.add8(zcl.transacId);
|
||||||
// end of ApsFrame
|
// end of ApsFrame
|
||||||
|
@ -192,6 +192,7 @@ void zigbeeZCLSendStr(uint16_t shortaddr, uint16_t groupaddr, uint8_t endpoint,
|
|||||||
manuf, /* manuf */
|
manuf, /* manuf */
|
||||||
clusterSpecific /* not cluster specific */,
|
clusterSpecific /* not cluster specific */,
|
||||||
true /* response */,
|
true /* response */,
|
||||||
|
false /* discover route */,
|
||||||
seq, /* zcl transaction id */
|
seq, /* zcl transaction id */
|
||||||
buf.getBuffer(), buf.len()
|
buf.getBuffer(), buf.len()
|
||||||
}));
|
}));
|
||||||
@ -739,6 +740,7 @@ void CmndZbSend(void) {
|
|||||||
manuf, /* manuf */
|
manuf, /* manuf */
|
||||||
false /* not cluster specific */,
|
false /* not cluster specific */,
|
||||||
false /* no response */,
|
false /* no response */,
|
||||||
|
false /* discover route */,
|
||||||
0, /* zcl transaction id */
|
0, /* zcl transaction id */
|
||||||
nullptr, 0
|
nullptr, 0
|
||||||
});
|
});
|
||||||
@ -1219,9 +1221,11 @@ void CmndZbPermitJoin(void) {
|
|||||||
// Log pairing mode enabled
|
// Log pairing mode enabled
|
||||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{\"Status\":21,\"Message\":\"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));
|
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
|
#endif // USE_ZIGBEE_EZSP
|
||||||
|
|
||||||
ResponseCmndDone();
|
ResponseCmndDone();
|
||||||
@ -1255,6 +1259,34 @@ void CmndZbEZSPListen(void) {
|
|||||||
|
|
||||||
ResponseCmndDone();
|
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
|
#endif // USE_ZIGBEE_EZSP
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -1801,6 +1833,9 @@ bool Xdrv23(uint8_t function)
|
|||||||
if (ZigbeeSerial) {
|
if (ZigbeeSerial) {
|
||||||
ZigbeeInputLoop();
|
ZigbeeInputLoop();
|
||||||
ZigbeeOutputLoop(); // send any outstanding data
|
ZigbeeOutputLoop(); // send any outstanding data
|
||||||
|
#ifdef USE_ZIGBEE_EZSP
|
||||||
|
ZigbeeGlowPermitJoinLight();
|
||||||
|
#endif // USE_ZIGBEE_EZSP
|
||||||
}
|
}
|
||||||
if (zigbee.state_machine) {
|
if (zigbee.state_machine) {
|
||||||
ZigbeeStateMachine_Run();
|
ZigbeeStateMachine_Run();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user