Skip to content

Commit 476efaa

Browse files
NerivecKoenkk
andcommitted
fix: OTA availability detection (#30815)
Co-authored-by: Koen Kanters <[email protected]>
1 parent 10478e7 commit 476efaa

File tree

3 files changed

+16
-17
lines changed

3 files changed

+16
-17
lines changed

lib/extension/otaUpdate.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ export default class OTAUpdate extends Extension {
218218
latest_release_notes: deviceUpdateState?.latest_release_notes,
219219
}
220220
: {
221-
state: state.available === 0 ? "idle" : "available",
221+
state: state.available ? "available" : "idle",
222222
installed_version: state.current.fileVersion,
223223
latest_version: state.availableMeta?.fileVersion ?? state.current.fileVersion,
224224
latest_source: state.availableMeta?.url || null,
@@ -303,13 +303,12 @@ export default class OTAUpdate extends Extension {
303303
await this.publishEntityState(device, this.#getEntityPublishPayload(device, availableResult));
304304
this.#lastChecked.set(device.ieeeAddr, Date.now());
305305

306-
const available = availableResult.available !== 0;
307306
const response = utils.getResponse<"bridge/response/device/ota_update/check">(message, {
308307
id: ID,
309-
update_available: available,
308+
update_available: availableResult.available,
309+
downgrade: source.downgrade,
310310
source: availableResult.availableMeta?.url,
311311
release_notes: availableResult.availableMeta?.releaseNotes,
312-
downgrade: available ? availableResult.available === 1 : undefined,
313312
});
314313

315314
await this.mqtt.publish("bridge/response/device/ota_update/check", stringify(response));
@@ -495,15 +494,15 @@ export default class OTAUpdate extends Extension {
495494

496495
if (to === undefined) {
497496
this.#removeProgressAndRemainingFromState(device);
498-
await this.publishEntityState(device, this.#getEntityPublishPayload(device, {available: 0, current: from}));
497+
await this.publishEntityState(device, this.#getEntityPublishPayload(device, {available: false, current: from}));
499498

500499
return [from.fileVersion, undefined];
501500
}
502501

503502
logger.info(`Finished update of '${device.name}'`);
504503

505504
this.#removeProgressAndRemainingFromState(device);
506-
await this.publishEntityState(device, this.#getEntityPublishPayload(device, {available: 0, current: to}));
505+
await this.publishEntityState(device, this.#getEntityPublishPayload(device, {available: false, current: to}));
507506

508507
logger.info(() => `Device '${device.name}' was OTA updated from '${from.fileVersion}' to '${to.fileVersion}'`);
509508

lib/types/api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,9 +614,9 @@ export interface Zigbee2MQTTAPI {
614614
"bridge/response/device/ota_update/check": {
615615
id: string;
616616
update_available: boolean;
617+
downgrade?: boolean;
617618
source?: string;
618619
release_notes?: string;
619-
downgrade?: boolean;
620620
};
621621

622622
"bridge/request/device/ota_update/update": {

test/extensions/otaUpdate.test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -585,21 +585,21 @@ describe("Extension: OTAUpdate", () => {
585585
});
586586

587587
it("is able to check if OTA update is available", async () => {
588-
devices.bulb.checkOta.mockResolvedValueOnce({available: 0, current: {...DEFAULT_CURRENT, fileVersion: 10}});
588+
devices.bulb.checkOta.mockResolvedValueOnce({available: false, current: {...DEFAULT_CURRENT, fileVersion: 10}});
589589
mockMQTTEvents.message("zigbee2mqtt/bridge/request/device/ota_update/check", stringify({id: "bulb"}));
590590
await flushPromises();
591591
expect(devices.bulb.checkOta).toHaveBeenCalledTimes(1);
592592
expect(devices.bulb.checkOta).toHaveBeenNthCalledWith(1, {downgrade: false}, undefined, {});
593593
expect(devices.bulb.updateOta).toHaveBeenCalledTimes(0);
594594
expect(mockMQTTPublishAsync).toHaveBeenCalledWith(
595595
"zigbee2mqtt/bridge/response/device/ota_update/check",
596-
stringify({data: {id: "bulb", update_available: false}, status: "ok"}),
596+
stringify({data: {id: "bulb", update_available: false, downgrade: false}, status: "ok"}),
597597
{},
598598
);
599599

600600
mockMQTTPublishAsync.mockClear();
601601
devices.bulb.checkOta.mockResolvedValueOnce({
602-
available: -1,
602+
available: true,
603603
current: {...DEFAULT_CURRENT, fileVersion: 10},
604604
availableMeta: {...DEFAULT_AVAILABLE_META, fileVersion: 12},
605605
});
@@ -613,15 +613,15 @@ describe("Extension: OTAUpdate", () => {
613613
stringify({data: {id: "bulb", update_available: true, downgrade: false, source: "https://example.com/my.ota"}, status: "ok"}),
614614
{},
615615
);
616-
devices.bulb.checkOta.mockResolvedValueOnce({available: 0, current: {...DEFAULT_CURRENT, fileVersion: 10}});
616+
devices.bulb.checkOta.mockResolvedValueOnce({available: false, current: {...DEFAULT_CURRENT, fileVersion: 10}});
617617
mockMQTTEvents.message("zigbee2mqtt/bridge/request/device/ota_update/check/downgrade", stringify({id: "bulb"}));
618618
await flushPromises();
619619
expect(devices.bulb.checkOta).toHaveBeenCalledTimes(3);
620620
expect(devices.bulb.checkOta).toHaveBeenNthCalledWith(3, {downgrade: true}, undefined, {});
621621
expect(devices.bulb.updateOta).toHaveBeenCalledTimes(0);
622622
expect(mockMQTTPublishAsync).toHaveBeenCalledWith(
623623
"zigbee2mqtt/bridge/response/device/ota_update/check",
624-
stringify({data: {id: "bulb", update_available: false}, status: "ok"}),
624+
stringify({data: {id: "bulb", update_available: false, downgrade: true}, status: "ok"}),
625625
{},
626626
);
627627

@@ -632,7 +632,7 @@ describe("Extension: OTAUpdate", () => {
632632

633633
mockMQTTPublishAsync.mockClear();
634634
devices.bulb.checkOta.mockResolvedValueOnce({
635-
available: 1,
635+
available: true,
636636
current: {...DEFAULT_CURRENT, fileVersion: 10},
637637
availableMeta: {...DEFAULT_AVAILABLE_META, fileVersion: 8},
638638
});
@@ -690,7 +690,7 @@ describe("Extension: OTAUpdate", () => {
690690

691691
it("allows check OTA with custom URL even when device does not support it", async () => {
692692
devices.HGZB04D.checkOta.mockResolvedValueOnce({
693-
available: -1,
693+
available: true,
694694
current: {...DEFAULT_CURRENT, fileVersion: 10},
695695
availableMeta: {...DEFAULT_AVAILABLE_META, fileVersion: 14, releaseNotes: "New features"},
696696
});
@@ -730,7 +730,7 @@ describe("Extension: OTAUpdate", () => {
730730
setTimeout(
731731
() =>
732732
resolve({
733-
available: 0,
733+
available: false,
734734
current: {...DEFAULT_CURRENT, fileVersion: 1},
735735
}),
736736
99999,
@@ -794,7 +794,7 @@ describe("Extension: OTAUpdate", () => {
794794
it("checks for update when device requests it", async () => {
795795
const data = {imageType: 12382, manufacturerCode: 2134, fileVersion: 33};
796796
devices.bulb.checkOta.mockResolvedValueOnce({
797-
available: -1,
797+
available: true,
798798
current: {...DEFAULT_CURRENT, ...data},
799799
availableMeta: {...DEFAULT_AVAILABLE_META, fileVersion: 34},
800800
});
@@ -864,7 +864,7 @@ describe("Extension: OTAUpdate", () => {
864864
it("checks for update when device requests it and it is not available", async () => {
865865
const data = {imageType: 12382, manufacturerCode: 2134, fileVersion: 33};
866866
devices.bulb.checkOta.mockResolvedValueOnce({
867-
available: 0,
867+
available: false,
868868
current: {...DEFAULT_CURRENT, ...data},
869869
availableMeta: {...DEFAULT_AVAILABLE_META, fileVersion: 33},
870870
});

0 commit comments

Comments
 (0)