diff --git a/lib/extension/configure.js b/lib/extension/configure.js index c7618095..595df95a 100644 --- a/lib/extension/configure.js +++ b/lib/extension/configure.js @@ -31,11 +31,11 @@ class Configure extends Extension { } if (this.shouldConfigure(resolvedEntity)) { - this.configure(resolvedEntity); + this.configure(resolvedEntity, 'reporting_disabled'); } } - shouldConfigure(resolvedEntity) { + shouldConfigure(resolvedEntity, event) { if (!resolvedEntity || !resolvedEntity.definition || !resolvedEntity.definition.configure) { return false; } @@ -50,6 +50,11 @@ class Configure extends Extension { return false; } + // Only configure end devices when a message is received, otherwise it will likely fails as they are sleeping. + if (resolvedEntity.device.type === 'EndDevice' && event !== 'message_received') { + return false; + } + return true; } @@ -95,7 +100,7 @@ class Configure extends Extension { for (const device of this.zigbee.getClients()) { const resolvedEntity = this.zigbee.resolveEntity(device); - if (this.shouldConfigure(resolvedEntity)) { + if (this.shouldConfigure(resolvedEntity, 'started')) { await this.configure(resolvedEntity); } } @@ -109,7 +114,7 @@ class Configure extends Extension { device.save(); } - if (this.shouldConfigure(resolvedEntity)) { + if (this.shouldConfigure(resolvedEntity, 'message_received')) { this.configure(resolvedEntity); } } diff --git a/test/configure.test.js b/test/configure.test.js index 038c0295..389337c1 100644 --- a/test/configure.test.js +++ b/test/configure.test.js @@ -26,6 +26,22 @@ describe('Configure', () => { expect(device.meta.configured).toBe(1); } + expectBulbConfigured = () => { + const device = zigbeeHerdsman.devices.bulb; + const endpoint1 = device.getEndpoint(1); + console.log(endpoint1.read.mock.calls); + expect(endpoint1.read).toHaveBeenCalledTimes(2); + expect(endpoint1.read).toHaveBeenCalledWith('lightingColorCtrl', ['colorCapabilities']); + expect(endpoint1.read).toHaveBeenCalledWith('lightingColorCtrl', [ 'colorTempPhysicalMin', 'colorTempPhysicalMax' ]); + } + + expectBulbNotConfigured = () => { + const device = zigbeeHerdsman.devices.bulb; + const endpoint1 = device.getEndpoint(1); + console.log(endpoint1.read.mock.calls); + expect(endpoint1.read).toHaveBeenCalledTimes(0); + } + expectRemoteNotConfigured = () => { const device = zigbeeHerdsman.devices.remote; const endpoint1 = device.getEndpoint(1); @@ -53,56 +69,59 @@ describe('Configure', () => { this.coordinatorEndoint = zigbeeHerdsman.devices.coordinator.getEndpoint(1); }); - it('Should configure on startup', async () => { - expectRemoteConfigured(); + it('Should configure Router on startup', async () => { + expectBulbConfigured(); + }); + + it('Should not configure EndDevice on startup', async () => { + expectRemoteNotConfigured(); }); it('Should re-configure when device rejoins', async () => { - expectRemoteConfigured(); - const device = zigbeeHerdsman.devices.remote; + expectBulbConfigured(); + const device = zigbeeHerdsman.devices.bulb; const endpoint = device.getEndpoint(1); await flushPromises(); mockClear(device); const payload = {device}; zigbeeHerdsman.events.deviceJoined(payload); await flushPromises(); - expectRemoteConfigured(); + expectBulbConfigured(); }); it('Should reconfigure reporting on reportingDisabled event', async () => { - expectRemoteConfigured(); - const device = zigbeeHerdsman.devices.remote; + expectBulbConfigured(); + const device = zigbeeHerdsman.devices.bulb; mockClear(device); - expectRemoteNotConfigured(); + expectBulbNotConfigured(); controller.eventBus.emit('reportingDisabled', {device}) await flushPromises(); - expectRemoteConfigured(); + expectBulbConfigured(); }); it('Should not configure twice', async () => { - expectRemoteConfigured(); - const device = zigbeeHerdsman.devices.remote; + expectBulbConfigured(); + const device = zigbeeHerdsman.devices.bulb; const endpoint = device.getEndpoint(1); mockClear(device); const payload = {data: {zclVersion: 1}, cluster: 'genBasic', device, endpoint, type: 'attributeReport', linkquality: 10}; await zigbeeHerdsman.events.message(payload); await flushPromises(); - expect(endpoint.bind).toHaveBeenCalledTimes(0); + expectBulbNotConfigured(); }); it('Should configure on zigbee message when not configured yet', async () => { - const device = zigbeeHerdsman.devices.remote; + const device = zigbeeHerdsman.devices.bulb; delete device.meta.configured; const endpoint = device.getEndpoint(1); mockClear(device); const payload = {data: {zclVersion: 1}, cluster: 'genBasic', device, endpoint, type: 'attributeReport', linkquality: 10}; await zigbeeHerdsman.events.message(payload); await flushPromises(); - expectRemoteConfigured(); + expectBulbConfigured(); }); it('Should allow to configure via MQTT', async () => { - expectRemoteConfigured(); mockClear(zigbeeHerdsman.devices.remote); expectRemoteNotConfigured(); await MQTT.events.message('zigbee2mqtt/bridge/request/device/configure', 'remote'); diff --git a/test/homeassistant.test.js b/test/homeassistant.test.js index 318a7879..b2eb8650 100644 --- a/test/homeassistant.test.js +++ b/test/homeassistant.test.js @@ -750,7 +750,7 @@ describe('HomeAssistant extension', () => { MQTT.publish.mockClear(); await zigbeeHerdsman.events.message(payload); await flushPromises(); - expect(MQTT.publish).toHaveBeenCalledTimes(1); + expect(MQTT.publish).toHaveBeenCalledTimes(3); expect(MQTT.publish).toHaveBeenCalledWith( 'zigbee2mqtt/weather_sensor', stringify({"battery":null,"humidity":null,"linkquality":null,"pressure":null,"temperature":-0.85,"voltage":null}), diff --git a/test/receive.test.js b/test/receive.test.js index b157a2df..7d5dc49b 100755 --- a/test/receive.test.js +++ b/test/receive.test.js @@ -64,7 +64,7 @@ describe('Receive', () => { const payload = {data, cluster: 'msTemperatureMeasurement', device, endpoint: device.getEndpoint(1), type: 'attributeReport', linkquality: 10}; await zigbeeHerdsman.events.message(payload); await flushPromises(); - expect(MQTT.publish).toHaveBeenCalledTimes(1); + expect(MQTT.publish).toHaveBeenCalledTimes(3); expect(MQTT.publish.mock.calls[0][0]).toStrictEqual('zigbee2mqtt/weather_sensor'); expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({temperature: -0.85}); expect(MQTT.publish.mock.calls[0][2]).toStrictEqual({"qos": 1, "retain": false});