diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 93e94a6c9..97de5b63f 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -15,6 +15,7 @@ - Add command ``SetOption41 `` to force sending gratuitous ARP every seconds - Add quick wifi reconnect using saved AP parameters when ``SetOption56 0`` (#3189) - Fix PWM flickering during wifi connection (#8046) +- Fix Zigbee crash with Occupancy sensor (#8089) ### 8.2.0.2 20200328 diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index d8cb1d5bc..9f5ef60a9 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -706,6 +706,7 @@ void Z_Devices::setTimer(uint16_t shortaddr, uint16_t groupaddr, uint32_t wait_m } // Run timer at each tick +// WARNING: don't set a new timer within a running timer, this causes memory corruption void Z_Devices::runTimer(void) { // visit all timers for (auto it = _deferred.begin(); it != _deferred.end(); it++) { diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 7de0d56f4..aa9505bd7 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -526,10 +526,10 @@ void Z_SendAFInfoRequest(uint16_t shortaddr) { // Aqara Occupancy behavior: the Aqara device only sends Occupancy: true events every 60 seconds. // Here we add a timer so if we don't receive a Occupancy event for 90 seconds, we send Occupancy:false -void Z_AqaraOccupancy(uint16_t shortaddr, uint16_t cluster, uint8_t endpoint, const JsonObject *json) { +void Z_AqaraOccupancy(uint16_t shortaddr, uint16_t cluster, uint8_t endpoint, const JsonObject &json) { static const uint32_t OCCUPANCY_TIMEOUT = 90 * 1000; // 90 s // Read OCCUPANCY value if any - const JsonVariant &val_endpoint = getCaseInsensitive(*json, PSTR(OCCUPANCY)); + const JsonVariant &val_endpoint = getCaseInsensitive(json, PSTR(OCCUPANCY)); if (nullptr != &val_endpoint) { uint32_t occupancy = strToUInt(val_endpoint); @@ -544,8 +544,6 @@ void Z_AqaraOccupancy(uint16_t shortaddr, uint16_t cluster, uint8_t endpoint, co int32_t Z_PublishAttributes(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) { const JsonObject *json = zigbee_devices.jsonGet(shortaddr); if (json == nullptr) { return 0; } // don't crash if not found - // Post-provess for Aqara Presence Senson - Z_AqaraOccupancy(shortaddr, cluster, endpoint, json); zigbee_devices.jsonPublishFlush(shortaddr); return 1; @@ -613,6 +611,9 @@ int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { zigbee_devices.resetTimersForDevice(srcaddr, 0 /* groupaddr */, Z_CAT_REACHABILITY); // remove any reachability timer already there zigbee_devices.setReachable(srcaddr, true); // mark device as reachable + // Post-provess for Aqara Presence Senson + Z_AqaraOccupancy(srcaddr, clusterid, srcendpoint, json); + if (defer_attributes) { // Prepare for publish if (zigbee_devices.jsonIsConflict(srcaddr, json)) {