Implement scaffolding for making requests against OpenHAB

This commit is contained in:
2024-11-13 22:48:19 +01:00
parent e791bce02c
commit a95aae8c11
5 changed files with 132 additions and 6 deletions

91
package-lock.json generated
View File

@@ -9,6 +9,7 @@
"version": "0.0.1", "version": "0.0.1",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"axios": "^1.7.7",
"mqtt": "^5.10.1" "mqtt": "^5.10.1"
}, },
"devDependencies": { "devDependencies": {
@@ -448,6 +449,21 @@
"node": ">=6.5" "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": { "node_modules/base64-js": {
"version": "1.5.1", "version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "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", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" "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": { "node_modules/commist": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz", "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": { "node_modules/esbuild": {
"version": "0.23.1", "version": "0.23.1",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz",
@@ -621,6 +656,38 @@
"node": ">=16.1.0" "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": { "node_modules/fsevents": {
"version": "2.3.3", "version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "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", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" "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": { "node_modules/minimist": {
"version": "1.2.8", "version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "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", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" "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": { "node_modules/readable-stream": {
"version": "4.5.2", "version": "4.5.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz",

View File

@@ -15,6 +15,7 @@
"typescript": "^5.6.3" "typescript": "^5.6.3"
}, },
"dependencies": { "dependencies": {
"axios": "^1.7.7",
"mqtt": "^5.10.1" "mqtt": "^5.10.1"
} }
} }

View File

@@ -1,7 +1,33 @@
import axios from "axios";
import { Thing } from "../openhab/types"; import { Thing } from "../openhab/types";
import { Adapter } from "./types"; import { Adapter } from "./types";
export const importThings = async (adapter: Adapter): Promise<Thing[]> => { 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(); const things = await adapter.loadThings();
return things;
if (override) {
// things.forEach(t => openhab.delete(`/things/${t.UID}`));
}
const getThingsResponse = await openhab.get<Thing[]>('/things');
const existingThingsUIDs = getThingsResponse.data.map(t => t.UID);
const thingsToImport = things.filter(t => !existingThingsUIDs.includes(t.UID));
// openhab.post('/things', thingsToImport);
return thingsToImport;
} }

View File

@@ -10,10 +10,18 @@ const adapter = new Z2MAdapter({
idTransform: snakecase("-") idTransform: snakecase("-")
}); });
const baseURL = 'openhab.url';
const token = 'openhab-token';
async function run() { async function run() {
const things = await importThings(adapter); const config = {
console.log(things); baseURL,
token
};
const things = await importThings(config, adapter);
console.log(JSON.stringify(things, undefined, 2))
} }
run(); run();

View File

@@ -129,7 +129,7 @@ const parseAtomFeature = ({ idTransform }: Config, parentTopic: string, parentUI
channelTypeUID, channelTypeUID,
itemType: itemTypes[feature.type], itemType: itemTypes[feature.type],
uid: `${parentUID}:${id}`, uid: `${parentUID}:${id}`,
kind: "STATE", kind: isTrigger ? 'TRIGGER' : "STATE",
label: feature.label, label: feature.label,
description: `${prefix}${feature.description}`, description: `${prefix}${feature.description}`,
configuration: { configuration: {
@@ -153,7 +153,7 @@ const parseAtomFeature = ({ idTransform }: Config, parentTopic: string, parentUI
* @returns mapped thing * @returns mapped thing
*/ */
const toThing = (config: Config) => (device: Device): 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 thingTopic = `${config.prefix}/${device.friendly_name}`
const exposes = device.definition?.exposes?.flatMap(toChannels(config, thingTopic, UID)) ?? []; const exposes = device.definition?.exposes?.flatMap(toChannels(config, thingTopic, UID)) ?? [];
const options = device.definition?.options?.flatMap(toChannels(config, thingTopic, UID, "option")) ?? []; const options = device.definition?.options?.flatMap(toChannels(config, thingTopic, UID, "option")) ?? [];