diff --git a/lib/extension/deviceReport.js b/lib/extension/deviceReport.js index d724939f7..89edb2c38 100644 --- a/lib/extension/deviceReport.js +++ b/lib/extension/deviceReport.js @@ -1,6 +1,7 @@ const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters'); const logger = require('../util/logger'); const CC2530Router = zigbeeHerdsmanConverters.devices.find((d) => d.model === 'CC2530.ROUTER'); +const ZNLDP12LM = zigbeeHerdsmanConverters.devices.find((d) => d.model === 'ZNLDP12LM'); const utils = require('../util/utils'); const BaseExtension = require('./baseExtension'); const debounce = require('debounce'); @@ -64,19 +65,29 @@ class DeviceReport extends BaseExtension { this.pollDebouncers = {}; } - async setupReporting(device) { + shouldIgnoreClusterForDevice(cluster, mappedDevice) { + if (mappedDevice === ZNLDP12LM && cluster === 'closuresWindowCovering') { + // Device announces it but doesn't support it + // https://github.com/Koenkk/zigbee2mqtt/issues/2611 + return true; + } + + return false; + } + + async setupReporting(device, mappedDevice) { if (this.configuring.has(device.ieeeAddr) || this.failed.has(device.ieeeAddr)) return; this.configuring.add(device.ieeeAddr); try { - for (const endpoint of device.endpoints) { + for (const ep of device.endpoints) { for (const [cluster, configuration] of Object.entries(clusters)) { - if (endpoint.supportsInputCluster(cluster)) { - logger.debug(`Setup reporting for '${device.ieeeAddr}' - ${endpoint.ID} - ${cluster}`); - await endpoint.bind(cluster, this.coordinatorEndpoint); - await endpoint.configureReporting(cluster, configuration); + if (ep.supportsInputCluster(cluster) && !this.shouldIgnoreClusterForDevice(cluster, mappedDevice)) { + logger.debug(`Setup reporting for '${device.ieeeAddr}' - ${ep.ID} - ${cluster}`); + await ep.bind(cluster, this.coordinatorEndpoint); + await ep.configureReporting(cluster, configuration); logger.info( - `Succesfully setup reporting for '${device.ieeeAddr}' - ${endpoint.ID} - ${cluster}`, + `Succesfully setup reporting for '${device.ieeeAddr}' - ${ep.ID} - ${cluster}`, ); } } @@ -119,14 +130,14 @@ class DeviceReport extends BaseExtension { for (const device of this.zigbee.getClients()) { const mappedDevice = zigbeeHerdsmanConverters.findByZigbeeModel(device.modelID); if (this.shouldSetupReporting(mappedDevice, device, null)) { - this.setupReporting(device); + this.setupReporting(device, mappedDevice); } } } onZigbeeEvent(type, data, mappedDevice, settingsDevice) { if (this.shouldSetupReporting(mappedDevice, data.device, type)) { - this.setupReporting(data.device); + this.setupReporting(data.device, mappedDevice); } if (type === 'message') { diff --git a/test/deviceReport.test.js b/test/deviceReport.test.js index 6f43389c2..d0322c9ca 100644 --- a/test/deviceReport.test.js +++ b/test/deviceReport.test.js @@ -8,6 +8,7 @@ zigbeeHerdsman.returnDevices.push('0x0017880104e45553'); zigbeeHerdsman.returnDevices.push('0x0017880104e45559'); zigbeeHerdsman.returnDevices.push('0x000b57fffec6a5b4'); zigbeeHerdsman.returnDevices.push('0x000b57fffec6a5b7'); +zigbeeHerdsman.returnDevices.push('0x90fd9ffffe4b64ax'); const MQTT = require('./stub/mqtt'); const settings = require('../lib/util/settings'); const Controller = require('../lib/controller'); @@ -197,4 +198,17 @@ describe('Device report', () => { // Should only call Hue bulb, not e.g. tradfri expect(zigbeeHerdsman.devices.bulb.getEndpoint(1).read).toHaveBeenCalledTimes(0); }); + + it('Should not configure reporting for the ZNLDP12LM closuresWindowCovering as it is ignored', async () => { + const device = zigbeeHerdsman.devices.ZNLDP12LM; + const coordinatorEndpoint = zigbeeHerdsman.devices.coordinator.getEndpoint(1); + const endpoint = device.getEndpoint(1); + delete device.meta.reporting; + await flushPromises(); + expect(endpoint.bind).toHaveBeenCalledTimes(3); + expect(endpoint.bind).toHaveBeenCalledWith('genOnOff', coordinatorEndpoint); + expect(endpoint.bind).toHaveBeenCalledWith('genLevelCtrl', coordinatorEndpoint); + expect(endpoint.bind).toHaveBeenCalledWith('lightingColorCtrl', coordinatorEndpoint); + expect(endpoint.configureReporting).toHaveBeenCalledTimes(3); + }); }); diff --git a/test/stub/data.js b/test/stub/data.js index fa6722ff8..7e3e1269a 100644 --- a/test/stub/data.js +++ b/test/stub/data.js @@ -132,7 +132,10 @@ function writeDefaultConfiguration() { }, '0x90fd9ffffe4b64af': { friendly_name: 'roller_shutter', - } + }, + '0x90fd9ffffe4b64ax': { + friendly_name: 'ZNLDP12LM', + }, }, groups: { '1': { diff --git a/test/stub/zigbeeHerdsman.js b/test/stub/zigbeeHerdsman.js index ba0f73d23..c59049181 100644 --- a/test/stub/zigbeeHerdsman.js +++ b/test/stub/zigbeeHerdsman.js @@ -129,6 +129,7 @@ const devices = { 'LIVOLO': new Device('Router', '0x0017880104e45560', 6541,4152, [new Endpoint(6, [0, 6], [])], true, "Mains (single phase)", 'TI0001 '), 'tradfri_remote': new Device('EndDevice', '0x90fd9ffffe4b64ae', 33906, 4476, [new Endpoint(1, [0], [0,3,4,6,8,5], '0x90fd9ffffe4b64ae')], true, "Battery", "TRADFRI remote control"), 'roller_shutter': new Device('EndDevice', '0x90fd9ffffe4b64af', 33906, 4476, [new Endpoint(1, [0], [0,3,4,6,8,5], '0x90fd9ffffe4b64af')], true, "Battery", "SCM-R_00.00.03.15TC"), + 'ZNLDP12LM': new Device('Router', '0x90fd9ffffe4b64ax', 33901, 4476, [new Endpoint(1, [0,4,3,5,10,258,13,19,6,1,1030,8,768,1027,1029,1026], [0,3,4,6,8,5], '0x90fd9ffffe4b64ax')], true, "Mains (single phase)", "lumi.light.aqcn02"), } const groups = {