mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2026-08-05 02:09:37 +00:00
fix: OTA availability detection (#30815)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
This commit is contained in:
committed by
Koen Kanters
co-authored by
Koen Kanters
parent
10478e797e
commit
476efaa6e1
@@ -218,7 +218,7 @@ export default class OTAUpdate extends Extension {
|
||||
latest_release_notes: deviceUpdateState?.latest_release_notes,
|
||||
}
|
||||
: {
|
||||
state: state.available === 0 ? "idle" : "available",
|
||||
state: state.available ? "available" : "idle",
|
||||
installed_version: state.current.fileVersion,
|
||||
latest_version: state.availableMeta?.fileVersion ?? state.current.fileVersion,
|
||||
latest_source: state.availableMeta?.url || null,
|
||||
@@ -303,13 +303,12 @@ export default class OTAUpdate extends Extension {
|
||||
await this.publishEntityState(device, this.#getEntityPublishPayload(device, availableResult));
|
||||
this.#lastChecked.set(device.ieeeAddr, Date.now());
|
||||
|
||||
const available = availableResult.available !== 0;
|
||||
const response = utils.getResponse<"bridge/response/device/ota_update/check">(message, {
|
||||
id: ID,
|
||||
update_available: available,
|
||||
update_available: availableResult.available,
|
||||
downgrade: source.downgrade,
|
||||
source: availableResult.availableMeta?.url,
|
||||
release_notes: availableResult.availableMeta?.releaseNotes,
|
||||
downgrade: available ? availableResult.available === 1 : undefined,
|
||||
});
|
||||
|
||||
await this.mqtt.publish("bridge/response/device/ota_update/check", stringify(response));
|
||||
@@ -495,7 +494,7 @@ export default class OTAUpdate extends Extension {
|
||||
|
||||
if (to === undefined) {
|
||||
this.#removeProgressAndRemainingFromState(device);
|
||||
await this.publishEntityState(device, this.#getEntityPublishPayload(device, {available: 0, current: from}));
|
||||
await this.publishEntityState(device, this.#getEntityPublishPayload(device, {available: false, current: from}));
|
||||
|
||||
return [from.fileVersion, undefined];
|
||||
}
|
||||
@@ -503,7 +502,7 @@ export default class OTAUpdate extends Extension {
|
||||
logger.info(`Finished update of '${device.name}'`);
|
||||
|
||||
this.#removeProgressAndRemainingFromState(device);
|
||||
await this.publishEntityState(device, this.#getEntityPublishPayload(device, {available: 0, current: to}));
|
||||
await this.publishEntityState(device, this.#getEntityPublishPayload(device, {available: false, current: to}));
|
||||
|
||||
logger.info(() => `Device '${device.name}' was OTA updated from '${from.fileVersion}' to '${to.fileVersion}'`);
|
||||
|
||||
|
||||
+1
-1
@@ -614,9 +614,9 @@ export interface Zigbee2MQTTAPI {
|
||||
"bridge/response/device/ota_update/check": {
|
||||
id: string;
|
||||
update_available: boolean;
|
||||
downgrade?: boolean;
|
||||
source?: string;
|
||||
release_notes?: string;
|
||||
downgrade?: boolean;
|
||||
};
|
||||
|
||||
"bridge/request/device/ota_update/update": {
|
||||
|
||||
@@ -585,7 +585,7 @@ describe("Extension: OTAUpdate", () => {
|
||||
});
|
||||
|
||||
it("is able to check if OTA update is available", async () => {
|
||||
devices.bulb.checkOta.mockResolvedValueOnce({available: 0, current: {...DEFAULT_CURRENT, fileVersion: 10}});
|
||||
devices.bulb.checkOta.mockResolvedValueOnce({available: false, current: {...DEFAULT_CURRENT, fileVersion: 10}});
|
||||
mockMQTTEvents.message("zigbee2mqtt/bridge/request/device/ota_update/check", stringify({id: "bulb"}));
|
||||
await flushPromises();
|
||||
expect(devices.bulb.checkOta).toHaveBeenCalledTimes(1);
|
||||
@@ -593,13 +593,13 @@ describe("Extension: OTAUpdate", () => {
|
||||
expect(devices.bulb.updateOta).toHaveBeenCalledTimes(0);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith(
|
||||
"zigbee2mqtt/bridge/response/device/ota_update/check",
|
||||
stringify({data: {id: "bulb", update_available: false}, status: "ok"}),
|
||||
stringify({data: {id: "bulb", update_available: false, downgrade: false}, status: "ok"}),
|
||||
{},
|
||||
);
|
||||
|
||||
mockMQTTPublishAsync.mockClear();
|
||||
devices.bulb.checkOta.mockResolvedValueOnce({
|
||||
available: -1,
|
||||
available: true,
|
||||
current: {...DEFAULT_CURRENT, fileVersion: 10},
|
||||
availableMeta: {...DEFAULT_AVAILABLE_META, fileVersion: 12},
|
||||
});
|
||||
@@ -613,7 +613,7 @@ describe("Extension: OTAUpdate", () => {
|
||||
stringify({data: {id: "bulb", update_available: true, downgrade: false, source: "https://example.com/my.ota"}, status: "ok"}),
|
||||
{},
|
||||
);
|
||||
devices.bulb.checkOta.mockResolvedValueOnce({available: 0, current: {...DEFAULT_CURRENT, fileVersion: 10}});
|
||||
devices.bulb.checkOta.mockResolvedValueOnce({available: false, current: {...DEFAULT_CURRENT, fileVersion: 10}});
|
||||
mockMQTTEvents.message("zigbee2mqtt/bridge/request/device/ota_update/check/downgrade", stringify({id: "bulb"}));
|
||||
await flushPromises();
|
||||
expect(devices.bulb.checkOta).toHaveBeenCalledTimes(3);
|
||||
@@ -621,7 +621,7 @@ describe("Extension: OTAUpdate", () => {
|
||||
expect(devices.bulb.updateOta).toHaveBeenCalledTimes(0);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith(
|
||||
"zigbee2mqtt/bridge/response/device/ota_update/check",
|
||||
stringify({data: {id: "bulb", update_available: false}, status: "ok"}),
|
||||
stringify({data: {id: "bulb", update_available: false, downgrade: true}, status: "ok"}),
|
||||
{},
|
||||
);
|
||||
|
||||
@@ -632,7 +632,7 @@ describe("Extension: OTAUpdate", () => {
|
||||
|
||||
mockMQTTPublishAsync.mockClear();
|
||||
devices.bulb.checkOta.mockResolvedValueOnce({
|
||||
available: 1,
|
||||
available: true,
|
||||
current: {...DEFAULT_CURRENT, fileVersion: 10},
|
||||
availableMeta: {...DEFAULT_AVAILABLE_META, fileVersion: 8},
|
||||
});
|
||||
@@ -690,7 +690,7 @@ describe("Extension: OTAUpdate", () => {
|
||||
|
||||
it("allows check OTA with custom URL even when device does not support it", async () => {
|
||||
devices.HGZB04D.checkOta.mockResolvedValueOnce({
|
||||
available: -1,
|
||||
available: true,
|
||||
current: {...DEFAULT_CURRENT, fileVersion: 10},
|
||||
availableMeta: {...DEFAULT_AVAILABLE_META, fileVersion: 14, releaseNotes: "New features"},
|
||||
});
|
||||
@@ -730,7 +730,7 @@ describe("Extension: OTAUpdate", () => {
|
||||
setTimeout(
|
||||
() =>
|
||||
resolve({
|
||||
available: 0,
|
||||
available: false,
|
||||
current: {...DEFAULT_CURRENT, fileVersion: 1},
|
||||
}),
|
||||
99999,
|
||||
@@ -794,7 +794,7 @@ describe("Extension: OTAUpdate", () => {
|
||||
it("checks for update when device requests it", async () => {
|
||||
const data = {imageType: 12382, manufacturerCode: 2134, fileVersion: 33};
|
||||
devices.bulb.checkOta.mockResolvedValueOnce({
|
||||
available: -1,
|
||||
available: true,
|
||||
current: {...DEFAULT_CURRENT, ...data},
|
||||
availableMeta: {...DEFAULT_AVAILABLE_META, fileVersion: 34},
|
||||
});
|
||||
@@ -864,7 +864,7 @@ describe("Extension: OTAUpdate", () => {
|
||||
it("checks for update when device requests it and it is not available", async () => {
|
||||
const data = {imageType: 12382, manufacturerCode: 2134, fileVersion: 33};
|
||||
devices.bulb.checkOta.mockResolvedValueOnce({
|
||||
available: 0,
|
||||
available: false,
|
||||
current: {...DEFAULT_CURRENT, ...data},
|
||||
availableMeta: {...DEFAULT_AVAILABLE_META, fileVersion: 33},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user