Only attempt to configure end device when message is received from it. (#7242)

This commit is contained in:
Koen Kanters 2021-04-29 18:18:51 +02:00 committed by GitHub
parent 1d8b37eee0
commit d61d6e28f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 21 deletions

View File

@ -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);
}
}

View File

@ -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');

View File

@ -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}),

View File

@ -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});