mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-24 11:16:34 +00:00
Zigbee debounce duplicate commands (#10477)
* Zigbee debounce duplicate commands received from the same device within ``USE_ZIGBEE_DEBOUNCE_COMMANDS`` milliseconds * Zigbee debounce duplicate commands received from the same device within ``USE_ZIGBEE_DEBOUNCE_COMMANDS`` milliseconds Co-authored-by: Stephan Hadinger <stephan.hadinger@gmail.com>
This commit is contained in:
parent
4217880946
commit
6a6454d8ab
@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
|
||||
- Support for time proportioned (``#define USE_TIMEPROP``) and optional PID (``#define USE_PID``) relay control (#10412)
|
||||
- Support rotary encoder on Shelly Dimmer (#10407)
|
||||
- Command ``SetOption43 1..100`` to control Rotary step (#10407)
|
||||
- Zigbee debounce duplicate commands received from the same device within ``USE_ZIGBEE_DEBOUNCE_COMMANDS`` milliseconds
|
||||
|
||||
### Breaking Changed
|
||||
- ESP32 switch from default SPIFFS to default LittleFS file system loosing current (zigbee) files
|
||||
|
@ -746,6 +746,7 @@
|
||||
#define USE_ZIGBEE_TXRADIO_DBM 20 // Tx Radio power in dBm (only for EZSP, EFR32 can go up to 20 dBm)
|
||||
|
||||
#define USE_ZIGBEE_COALESCE_ATTR_TIMER 350 // timer to coalesce attribute values (in ms)
|
||||
#define USE_ZIGBEE_DEBOUNCE_COMMANDS 200 // if commands are received from the same device/endpoint with same ZCL transaction number, discard packet in this time window (ms)
|
||||
#define USE_ZIGBEE_MODELID "Tasmota Z2T" // reported "ModelId" (cluster 0000 / attribute 0005)
|
||||
#define USE_ZIGBEE_MANUFACTURER "Tasmota" // reported "Manufacturer" (cluster 0000 / attribute 0004)
|
||||
#define USE_ZBBRIDGE_TLS // TLS support for zbbridge
|
||||
|
@ -730,6 +730,11 @@ public:
|
||||
uint8_t lqi; // lqi from last message, 0xFF means unknown
|
||||
uint8_t batterypercent; // battery percentage (0..100), 0xFF means unknwon
|
||||
uint16_t reserved_for_alignment;
|
||||
// Debounce informmation when receiving commands
|
||||
// If we receive the same ZCL transaction number from the same device and the same endpoint within 300ms
|
||||
// then discard the second packet
|
||||
uint8_t debounce_endpoint; // endpoint of the last received packet, or 0 if not active (expired)
|
||||
uint8_t debounce_transact; // ZCL transaction number of the last packet
|
||||
// END OF DEVICE WIDE DATA
|
||||
|
||||
// Constructor with all defaults
|
||||
@ -750,7 +755,9 @@ public:
|
||||
last_seen(0),
|
||||
lqi(0xFF),
|
||||
batterypercent(0xFF),
|
||||
reserved_for_alignment(0xFFFF)
|
||||
reserved_for_alignment(0xFFFF),
|
||||
debounce_endpoint(0),
|
||||
debounce_transact(0)
|
||||
{ };
|
||||
|
||||
inline bool valid(void) const { return BAD_SHORTADDR != shortaddr; } // is the device known, valid and found?
|
||||
@ -847,6 +854,7 @@ typedef enum Z_Def_Category {
|
||||
Z_CAT_BIND, // send auto-binding to coordinator
|
||||
Z_CAT_CONFIG_ATTR, // send a config attribute reporting request
|
||||
Z_CAT_READ_ATTRIBUTE, // read a single attribute
|
||||
Z_CAT_DEBOUNCE_CMD, // debounce incoming commands
|
||||
Z_CAT_CIE_ATTRIBUTE, // write CIE address
|
||||
Z_CAT_CIE_ENROLL, // enroll CIE zone
|
||||
} Z_Def_Category;
|
||||
|
@ -1606,14 +1606,34 @@ void ZCLFrame::parseResponse(void) {
|
||||
parseResponse_inner(cmd, true, status);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Callbacks
|
||||
\*********************************************************************************************/
|
||||
// Reset the debounce marker
|
||||
void Z_ResetDebounce(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
|
||||
zigbee_devices.getShortAddr(shortaddr).debounce_endpoint = 0;
|
||||
}
|
||||
|
||||
// Parse non-normalized attributes
|
||||
void ZCLFrame::parseClusterSpecificCommand(Z_attribute_list& attr_list) {
|
||||
convertClusterSpecific(attr_list, _cluster_id, _cmd_id, _frame_control.b.direction, _srcaddr, _srcendpoint, _payload);
|
||||
if (!Settings.flag5.zb_disable_autoquery) {
|
||||
// read attributes unless disabled
|
||||
if (!_frame_control.b.direction) { // only handle server->client (i.e. device->coordinator)
|
||||
if (_wasbroadcast) { // only update for broadcast messages since we don't see unicast from device to device and we wouldn't know the target
|
||||
sendHueUpdate(BAD_SHORTADDR, _groupaddr, _cluster_id);
|
||||
// Check if debounce is active and if the packet is a duplicate
|
||||
Z_Device & device = zigbee_devices.getShortAddr(_srcaddr);
|
||||
if ((device.debounce_endpoint != 0) && (device.debounce_endpoint == _srcendpoint) && (device.debounce_transact == _transact_seq)) {
|
||||
// this is a duplicate, drop the packet
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "Discarding duplicate command from 0x%04X, endpoint %d"), _srcaddr, _srcendpoint);
|
||||
} else {
|
||||
// reset the duplicate marker, parse the packet normally, and set a timer to reset the marker later (which will discard any existing timer for the same device/endpoint)
|
||||
device.debounce_endpoint = _srcendpoint;
|
||||
device.debounce_transact = _transact_seq;
|
||||
zigbee_devices.setTimer(_srcaddr, 0 /* groupaddr */, USE_ZIGBEE_DEBOUNCE_COMMANDS, 0 /*clusterid*/, _srcendpoint, Z_CAT_DEBOUNCE_CMD, 0, &Z_ResetDebounce);
|
||||
|
||||
convertClusterSpecific(attr_list, _cluster_id, _cmd_id, _frame_control.b.direction, _srcaddr, _srcendpoint, _payload);
|
||||
if (!Settings.flag5.zb_disable_autoquery) {
|
||||
// read attributes unless disabled
|
||||
if (!_frame_control.b.direction) { // only handle server->client (i.e. device->coordinator)
|
||||
if (_wasbroadcast) { // only update for broadcast messages since we don't see unicast from device to device and we wouldn't know the target
|
||||
sendHueUpdate(BAD_SHORTADDR, _groupaddr, _cluster_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user