From a95aae8c11c090551bc5e41bbcb1b3210e2cea08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Pluta?= Date: Wed, 13 Nov 2024 22:48:19 +0100 Subject: [PATCH] Implement scaffolding for making requests against OpenHAB --- package-lock.json | 91 +++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + src/importer/index.ts | 30 +++++++++++++- src/index.ts | 12 +++++- src/z2m/index.ts | 4 +- 5 files changed, 132 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0f5a6a3..4d3cf87 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.1", "license": "ISC", "dependencies": { + "axios": "^1.7.7", "mqtt": "^5.10.1" }, "devDependencies": { @@ -448,6 +449,21 @@ "node": ">=6.5" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -506,6 +522,17 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commist": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz", @@ -554,6 +581,14 @@ } } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/esbuild": { "version": "0.23.1", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", @@ -621,6 +656,38 @@ "node": ">=16.1.0" } }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -690,6 +757,25 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", @@ -766,6 +852,11 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/readable-stream": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", diff --git a/package.json b/package.json index 51e8f39..d905ded 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "typescript": "^5.6.3" }, "dependencies": { + "axios": "^1.7.7", "mqtt": "^5.10.1" } } diff --git a/src/importer/index.ts b/src/importer/index.ts index 89c1ba0..4745528 100644 --- a/src/importer/index.ts +++ b/src/importer/index.ts @@ -1,7 +1,33 @@ +import axios from "axios"; import { Thing } from "../openhab/types"; import { Adapter } from "./types"; -export const importThings = async (adapter: Adapter): Promise => { +export type Config = { + baseURL: string; + token: string; + override?: boolean; +}; + +export const importThings = async ({baseURL, token, override}: Config, adapter: Adapter) => { + const openhab = axios.create({ + baseURL, + headers: { + Authorization: `Bearer ${token}` + } + }); + const things = await adapter.loadThings(); - return things; + + if (override) { + // things.forEach(t => openhab.delete(`/things/${t.UID}`)); + } + + const getThingsResponse = await openhab.get('/things'); + const existingThingsUIDs = getThingsResponse.data.map(t => t.UID); + + const thingsToImport = things.filter(t => !existingThingsUIDs.includes(t.UID)); + + // openhab.post('/things', thingsToImport); + + return thingsToImport; } \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index a3b160a..02e0bad 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,10 +10,18 @@ const adapter = new Z2MAdapter({ idTransform: snakecase("-") }); +const baseURL = 'openhab.url'; +const token = 'openhab-token'; + async function run() { - const things = await importThings(adapter); - console.log(things); + const config = { + baseURL, + token + }; + + const things = await importThings(config, adapter); + console.log(JSON.stringify(things, undefined, 2)) } run(); \ No newline at end of file diff --git a/src/z2m/index.ts b/src/z2m/index.ts index e49644b..1384fea 100644 --- a/src/z2m/index.ts +++ b/src/z2m/index.ts @@ -129,7 +129,7 @@ const parseAtomFeature = ({ idTransform }: Config, parentTopic: string, parentUI channelTypeUID, itemType: itemTypes[feature.type], uid: `${parentUID}:${id}`, - kind: "STATE", + kind: isTrigger ? 'TRIGGER' : "STATE", label: feature.label, description: `${prefix}${feature.description}`, configuration: { @@ -153,7 +153,7 @@ const parseAtomFeature = ({ idTransform }: Config, parentTopic: string, parentUI * @returns mapped thing */ const toThing = (config: Config) => (device: Device): Thing => { - const UID = `mqtt:topic:${config.bridgeID}:${device.friendly_name}`; + const UID = `mqtt:topic:${config.bridgeID}:${config.idTransform?.(device.friendly_name) || device.friendly_name}`; const thingTopic = `${config.prefix}/${device.friendly_name}` const exposes = device.definition?.exposes?.flatMap(toChannels(config, thingTopic, UID)) ?? []; const options = device.definition?.options?.flatMap(toChannels(config, thingTopic, UID, "option")) ?? [];