From 0826db07d048b9bccbcbb717399e705f518568e8 Mon Sep 17 00:00:00 2001 From: Koen Kanters Date: Tue, 5 Feb 2019 17:41:47 +0100 Subject: [PATCH] =?UTF-8?q?Set=20state=20of=20stateless=20properties=20to?= =?UTF-8?q?=20=E2=80=98idle=E2=80=99=20after=20publish.=20#959?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/extension/deviceReceive.js | 16 +++++++++++++--- test/deviceReceive.test.js | 13 ++++++++----- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/lib/extension/deviceReceive.js b/lib/extension/deviceReceive.js index 58ee23bb..25598dcd 100644 --- a/lib/extension/deviceReceive.js +++ b/lib/extension/deviceReceive.js @@ -1,7 +1,7 @@ const settings = require('../util/settings'); const logger = require('../util/logger'); -const dontCacheProperties = ['action', 'button', 'button_left', 'button_right', 'click', 'forgotten', 'keyerror']; +const statelessProperties = ['action', 'button', 'button_left', 'button_right', 'click', 'forgotten', 'keyerror']; /** * This extensions handles messages received from devices. @@ -100,11 +100,18 @@ class DeviceReceive { // - If NO payload is returned do nothing. This is for non-standard behaviour // for e.g. click switches where we need to count number of clicks and detect long presses. const publish = (payload) => { - // Don't cache messages with following properties: + // Don't cache messages with stateless properties. + // After a stateless property is send we need to clear it. + // Otherwise the state of the device is incorrect. + // E.g. when a button is pressed a payload like {"click": "single"} + // is produced, afterwards we want to clear this with {"click": "idle"} + // https://github.com/Koenkk/zigbee2mqtt/issues/959 let cache = true; - dontCacheProperties.forEach((property) => { + const clearStatePayload = {}; + statelessProperties.forEach((property) => { if (payload.hasOwnProperty(property)) { cache = false; + clearStatePayload[property] = 'idle'; } }); @@ -133,6 +140,9 @@ class DeviceReceive { } this.publishEntityState(device.ieeeAddr, payload, cache); + if (Object.keys(clearStatePayload).length > 0) { + this.publishEntityState(device.ieeeAddr, clearStatePayload, false); + } }; let payload = {}; diff --git a/test/deviceReceive.test.js b/test/deviceReceive.test.js index 1d2e9ef8..b90cee79 100644 --- a/test/deviceReceive.test.js +++ b/test/deviceReceive.test.js @@ -36,24 +36,27 @@ describe('DeviceReceive', () => { const device = {ieeeAddr: '0x12345678'}; const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 1); deviceReceive.onZigbeeMessage(message, device, WXKG11LM); - chai.assert.isTrue(publishEntityState.calledOnce); + chai.assert.isTrue(publishEntityState.calledTwice); chai.assert.deepEqual(publishEntityState.getCall(0).args[1], {click: 'single'}); + chai.assert.deepEqual(publishEntityState.getCall(1).args[1], {click: 'idle'}); }); it('Should handle a zigbee message which uses ep (left)', () => { const device = {ieeeAddr: '0x12345678'}; const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 1); deviceReceive.onZigbeeMessage(message, device, WXKG02LM); - chai.assert.isTrue(publishEntityState.calledOnce); + chai.assert.isTrue(publishEntityState.calledTwice); chai.assert.deepEqual(publishEntityState.getCall(0).args[1], {click: 'left'}); + chai.assert.deepEqual(publishEntityState.getCall(1).args[1], {click: 'idle'}); }); it('Should handle a zigbee message which uses ep (right)', () => { const device = {ieeeAddr: '0x12345678'}; const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 2); deviceReceive.onZigbeeMessage(message, device, WXKG02LM); - chai.assert.isTrue(publishEntityState.calledOnce); + chai.assert.isTrue(publishEntityState.calledTwice); chai.assert.deepEqual(publishEntityState.getCall(0).args[1], {click: 'right'}); + chai.assert.deepEqual(publishEntityState.getCall(1).args[1], {click: 'idle'}); }); it('Should handle a zigbee message with default precision', () => { @@ -207,7 +210,7 @@ describe('DeviceReceive', () => { }; }); deviceReceive.onZigbeeMessage(message, device, WXKG02LM); - chai.assert.isTrue(publishEntityState.calledOnce); + chai.assert.isTrue(publishEntityState.calledTwice); chai.assert.equal(typeof publishEntityState.getCall(0).args[1].last_seen, 'number'); }); @@ -222,7 +225,7 @@ describe('DeviceReceive', () => { }; }); deviceReceive.onZigbeeMessage(message, device, WXKG02LM); - chai.assert.isTrue(publishEntityState.calledOnce); + chai.assert.isTrue(publishEntityState.calledTwice); chai.assert.equal(typeof publishEntityState.getCall(0).args[1].last_seen, 'string'); }); });