diff --git a/lib/extension/deviceReceive.js b/lib/extension/deviceReceive.js index 1bb6686bf..b819c1ae4 100644 --- a/lib/extension/deviceReceive.js +++ b/lib/extension/deviceReceive.js @@ -88,35 +88,40 @@ class DeviceReceive { // - If a payload is returned publish it to the MQTT broker // - 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. - converters.forEach((converter) => { - const publish = (payload) => { - // Don't cache messages with following properties: - let cache = true; - dontCacheProperties.forEach((property) => { - if (payload.hasOwnProperty(property)) { - cache = false; - } - }); - - // Add device linkquality. - if (message.hasOwnProperty('linkquality')) { - payload.linkquality = message.linkquality; + const publish = (payload) => { + // Don't cache messages with following properties: + let cache = true; + dontCacheProperties.forEach((property) => { + if (payload.hasOwnProperty(property)) { + cache = false; } + }); - // Add last seen timestamp - const now = new Date(); - payload.last_seen = now.toISOString(); + // Add device linkquality. + if (message.hasOwnProperty('linkquality')) { + payload.linkquality = message.linkquality; + } - this.publishDeviceState(device, payload, cache); - }; + // Add last seen timestamp + const now = new Date(); + payload.last_seen = now.toISOString(); + this.publishDeviceState(device, payload, cache); + }; + + let payload = {}; + converters.forEach((converter) => { const options = {...settings.get().device_options, ...settings.getDevice(device.ieeeAddr)}; - const payload = converter.convert(mappedDevice, message, publish, options); + const converted = converter.convert(mappedDevice, message, publish, options); - if (payload) { - publish(payload); + if (converted) { + payload = {...payload, ...converted}; } }); + + if (Object.keys(payload).length) { + publish(payload); + } } } diff --git a/test/deviceReceive.test.js b/test/deviceReceive.test.js index f33d40bdb..4a1eaa607 100644 --- a/test/deviceReceive.test.js +++ b/test/deviceReceive.test.js @@ -10,6 +10,7 @@ const sandbox = sinon.createSandbox(); const WXKG11LM = devices.find((d) => d.model === 'WXKG11LM'); const WXKG02LM = devices.find((d) => d.model === 'WXKG02LM'); const WSDCGQ11LM = devices.find((d) => d.model === 'WSDCGQ11LM'); +const RTCGQ11LM = devices.find((d) => d.model === 'RTCGQ11LM'); const mqtt = { log: () => {}, @@ -168,5 +169,25 @@ describe('DeviceReceive', () => { const expected = {battery: 0, voltage: 2000}; chai.assert.deepEqual(utils.withoutLastSeen(publishDeviceState.getCall(0).args[1]), expected); }); + + it('Should publish 1 message when converted twice', () => { + const device = {ieeeAddr: '0x12345678'}; + const payload = { + '65281': {'1': 3045, '3': 19, '4': 17320, '5': 35, '6': [0, 3], '10': 51107, '11': 381, '100': 0}, + }; + const message = utils.zigbeeMessage(device, 'genBasic', 'attReport', payload, 1); + deviceReceive.onZigbeeMessage(message, device, RTCGQ11LM); + chai.assert.isTrue(publishDeviceState.calledOnce); + const expected = {'battery': 100, 'illuminance': 381, 'voltage': 3045}; + chai.assert.deepEqual(utils.withoutLastSeen(publishDeviceState.getCall(0).args[1]), expected); + }); + + it('Should publish no message when converted without result', () => { + const device = {ieeeAddr: '0x12345678'}; + const payload = {'9999': {'1': 3045}}; + const message = utils.zigbeeMessage(device, 'genBasic', 'attReport', payload, 1); + deviceReceive.onZigbeeMessage(message, device, RTCGQ11LM); + chai.assert.isTrue(publishDeviceState.notCalled); + }); }); });