diff --git a/package.json b/package.json index 150b34bd..49a27320 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zigbee-ota", - "version": "1.1.1", + "version": "1.2.0", "repository": { "type": "git", "url": "git+https://github.com/Koenkk/zigbee-OTA.git" diff --git a/src/autodl/hue.ts b/src/autodl/hue.ts new file mode 100644 index 00000000..4e3af6db --- /dev/null +++ b/src/autodl/hue.ts @@ -0,0 +1,105 @@ +import {getJson, getLatestImage, readCacheJson, writeCacheJson} from '../common.js'; +import {processFirmwareImage} from '../process_firmware_image.js'; + +type ImageJson = { + createdAt: string; + updatedAt: string; + fileSize: number; + md5: string; + binaryUrl: string; + version: number; + versionName: string; + releaseNotes: string; +}; +type PageJson = {updates: ImageJson[]}; + +const NAME = 'Hue'; +const BASE_URL = 'https://firmware.meethue.com/v1/checkupdate?version=0&deviceTypeId='; +const DEVICE_TYPE_IDS: string[] = [ + '100b-111', + '100b-112', + // '100b-113', + '100b-114', + '100b-115', + // '100b-116', + '100b-117', + '100b-118', + // '100b-119', + '100b-11a', + // '100b-11b', + // '100b-11c', + '100b-11d', + '100b-11e', + '100b-11f', + '100b-120', + // '100b-121', + // '100b-122', + '100b-123', + // '100b-124', + '100b-125', + // '100b-126', + '100b-127', + // '100b-128', + '100b-129', + // '100b-12a', + // '100b-12b', + // '100b-12c', + // '100b-12d', + // '100b-12e', + // '100b-12f', +]; + +function sortByVersion(a: ImageJson, b: ImageJson): number { + return a.version < b.version ? -1 : a.version > b.version ? 1 : 0; +} + +function isDifferent(newData: PageJson, cachedData?: PageJson): boolean { + return ( + Boolean(process.env.IGNORE_CACHE) || + !cachedData?.updates.length || + getLatestImage(cachedData.updates, sortByVersion)?.version !== getLatestImage(newData.updates, sortByVersion)?.version + ); +} + +export async function writeCache(): Promise { + for (const deviceTypeId of DEVICE_TYPE_IDS) { + const url = `${BASE_URL}${deviceTypeId}`; + const page = await getJson(NAME, url); + + if (page?.updates.length) { + writeCacheJson(`${NAME}_${deviceTypeId}`, page); + } + } +} + +export async function download(): Promise { + for (const deviceTypeId of DEVICE_TYPE_IDS) { + const logPrefix = `[${NAME}:${deviceTypeId}]`; + const url = `${BASE_URL}${deviceTypeId}`; + const page = await getJson(NAME, url); + + if (!page?.updates.length) { + console.error(`${logPrefix} No image data.`); + continue; + } + + const cacheFileName = `${NAME}_${deviceTypeId}`; + + if (!isDifferent(page, readCacheJson(cacheFileName))) { + console.log(`${logPrefix} No change from last run.`); + continue; + } + + writeCacheJson(cacheFileName, page); + + const image = getLatestImage(page.updates, sortByVersion); + + if (!image) { + continue; + } + + const firmwareFileName = image.binaryUrl.split('/').pop()!; + + await processFirmwareImage(NAME, firmwareFileName, image.binaryUrl, {releaseNotes: image.releaseNotes || undefined}); + } +} diff --git a/src/common.ts b/src/common.ts index 53f62853..a084d20d 100644 --- a/src/common.ts +++ b/src/common.ts @@ -31,6 +31,7 @@ export const PR_ARTIFACT_NUMBER_FILEPATH = path.join(PR_ARTIFACT_DIR, PR_NUMBER_ */ export const ALL_AUTODL_MANUFACTURERS = [ 'gammatroniques', + 'hue', 'ikea_new', 'ikea', 'inovelli',