Respond with NO_IMAGE_AVAILABLE when device requests OTA. https://github.com/Koenkk/zigbee2mqtt/issues/13396

This commit is contained in:
Koen Kanters 2022-10-27 20:39:44 +02:00
parent 6c0430b6e2
commit 60de5b7676
2 changed files with 4 additions and 28 deletions

View File

@ -112,13 +112,11 @@ export default class OTAUpdate extends Extension {
}
}
// Respond to the OTA request:
// - In case we don't support OTA: respond with NO_IMAGE_AVAILABLE (0x98) (so the client stops requesting OTAs)
// - In case we do support OTA: respond with ABORT (0x95) as we don't want to update now.
// Respond to the OTA request: respond with NO_IMAGE_AVAILABLE (0x98) (so the client stops requesting OTAs)
const endpoint = data.device.zh.endpoints.find((e) => e.supportsOutputCluster('genOta'));
if (endpoint) {
// Some devices send OTA requests without defining OTA cluster as input cluster.
await endpoint.commandResponse('genOta', 'queryNextImageResponse', {status: supportsOTA ? 0x95 : 0x98});
await endpoint.commandResponse('genOta', 'queryNextImageResponse', {status: 0x98});
}
}

View File

@ -258,7 +258,7 @@ describe('OTA update', () => {
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledWith(device, logger, {"imageType": 12382});
expect(logger.info).toHaveBeenCalledWith(`Update available for 'bulb'`);
expect(device.endpoints[0].commandResponse).toHaveBeenCalledTimes(1);
expect(device.endpoints[0].commandResponse).toHaveBeenCalledWith("genOta", "queryNextImageResponse", {"status": 0x95});
expect(device.endpoints[0].commandResponse).toHaveBeenCalledWith("genOta", "queryNextImageResponse", {"status": 0x98});
// Should not request again when device asks again after a short time
await zigbeeHerdsman.events.message(payload);
@ -277,28 +277,6 @@ describe('OTA update', () => {
);
});
it('Should respond with NO_IMAGE_AVAILABLE when update available request fails', async () => {
const device = zigbeeHerdsman.devices.bulb;
device.endpoints[0].commandResponse.mockClear();
const data = {imageType: 12382};
const mapped = zigbeeHerdsmanConverters.findByDevice(device)
mockClear(mapped);
mapped.ota.isUpdateAvailable.mockImplementationOnce(() => {throw new Error('Nothing to find here')})
const payload = {data, cluster: 'genOta', device, endpoint: device.getEndpoint(1), type: 'commandQueryNextImageRequest', linkquality: 10};
logger.info.mockClear();
await zigbeeHerdsman.events.message(payload);
await flushPromises();
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledTimes(1);
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledWith(device, logger, {"imageType": 12382});
expect(device.endpoints[0].commandResponse).toHaveBeenCalledTimes(1);
expect(device.endpoints[0].commandResponse).toHaveBeenCalledWith("genOta", "queryNextImageResponse", {"status": 0x98});
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bulb',
stringify({"update_available":false,"update":{"state":"idle"}}),
{retain: true, qos: 0}, expect.any(Function)
);
});
it('Should check for update when device requests it and it is not available', async () => {
const device = zigbeeHerdsman.devices.bulb;
device.endpoints[0].commandResponse.mockClear();
@ -313,7 +291,7 @@ describe('OTA update', () => {
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledTimes(1);
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledWith(device, logger, {"imageType": 12382});
expect(device.endpoints[0].commandResponse).toHaveBeenCalledTimes(1);
expect(device.endpoints[0].commandResponse).toHaveBeenCalledWith("genOta", "queryNextImageResponse", {"status": 0x95});
expect(device.endpoints[0].commandResponse).toHaveBeenCalledWith("genOta", "queryNextImageResponse", {"status": 0x98});
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bulb',
stringify({"update_available":false,"update":{"state":"idle"}}),