From 0b064961585435c1427a1296d2d969b7fc3263e2 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Thu, 24 Sep 2020 19:15:07 +0200 Subject: [PATCH] Zigbee send message when PermitJoin expires --- tasmota/xdrv_23_zigbee_2_devices.ino | 1 + tasmota/xdrv_23_zigbee_7_statemachine.ino | 1 + tasmota/xdrv_23_zigbee_8_parsers.ino | 23 ++++++++++++----------- tasmota/xdrv_23_zigbee_A_impl.ino | 9 +++++++++ 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index e68342da6..0067744d3 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -163,6 +163,7 @@ typedef enum Z_Def_Category { Z_CAT_READ_ATTR, // Attribute reporting, either READ_ATTRIBUTE or REPORT_ATTRIBUTE, we coalesce all attributes reported if we can Z_CAT_VIRTUAL_OCCUPANCY, // Creation of a virtual attribute, typically after a time-out. Ex: Aqara presence sensor Z_CAT_REACHABILITY, // timer set to measure reachability of device, i.e. if we don't get an answer after 1s, it is marked as unreachable (for Alexa) + Z_CAT_PERMIT_JOIN, // timer to signal the end of the PermitJoin period // Below will clear based on device + cluster pair. Z_CLEAR_DEVICE_CLUSTER, Z_CAT_READ_CLUSTER, diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index ee9bfd19a..8bfe785d0 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -28,6 +28,7 @@ const uint8_t ZIGBEE_STATUS_STARTING = 3; // Starting CC2530 as co const uint8_t ZIGBEE_STATUS_PERMITJOIN_CLOSE = 20; // Disable PermitJoin const uint8_t ZIGBEE_STATUS_PERMITJOIN_OPEN_60 = 21; // Enable PermitJoin for 60 seconds const uint8_t ZIGBEE_STATUS_PERMITJOIN_OPEN_XX = 22; // Enable PermitJoin until next boot +const uint8_t ZIGBEE_STATUS_PERMITJOIN_ERROR = 23; // Enable PermitJoin until next boot const uint8_t ZIGBEE_STATUS_DEVICE_ANNOUNCE = 30; // Device announces its address const uint8_t ZIGBEE_STATUS_NODE_DESC = 31; // Node descriptor const uint8_t ZIGBEE_STATUS_ACTIVE_EP = 32; // Endpoints descriptor diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 27eb14801..9952ac564 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -166,21 +166,22 @@ int32_t EZ_RouteError(int32_t res, const class SBuffer &buf) { int32_t EZ_PermitJoinRsp(int32_t res, const class SBuffer &buf) { uint8_t status = buf.get8(2); - Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" - "\"Status\":%d,\"Message\":\"%s"), - (0 == status) ? ZIGBEE_STATUS_PERMITJOIN_OPEN_60 : ZIGBEE_STATUS_PERMITJOIN_CLOSE, - (0 == status) ? PSTR("Pairing mode enabled") : PSTR("Pairing mode error") - ); - if (status) { - ResponseAppend_P("0x%02X", status); + if (status) { // only report if there is an error + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{\"Status\":23,\"Message\":\"Pairing mode error 0x%02X\"}}"), status); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); } - ResponseAppend_P(PSTR("\"}}")); - - MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); - return -1; } +// +// 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) { + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{\"Status\":20,\"Message\":\"Pairing mode disabled\"}}")); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); +} + + // // Received MessageSentHandler // diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 90cc4e28c..498e17c85 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -1152,6 +1152,15 @@ void CmndZbPermitJoin(void) { 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()); + + // Set Timer after the end of the period, and reset a non-expired previous timer + if (duration > 0) { + // 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)); + } + // 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();