From 734d700076ca5a967e7d175f5302374bda204095 Mon Sep 17 00:00:00 2001 From: sinedied Date: Tue, 11 Apr 2023 13:47:03 +0200 Subject: [PATCH] feat: update hue api --- index.js | 2 +- lib/hue.js | 134 +++++++++++++++++++++++++--------------------- package-lock.json | 122 ++++++++++++++--------------------------- package.json | 2 +- 4 files changed, 114 insertions(+), 146 deletions(-) diff --git a/index.js b/index.js index 912a49b..dcd5d7a 100644 --- a/index.js +++ b/index.js @@ -308,7 +308,7 @@ export class DmxHue { Util.exit(pkg.version, 0); } else if (this._args._[0] === 'setup') { return this._args.list - ? this._hue.listBridges() + ? this._hue.listBridges(true) : this.setup(this._args.ip, this._args.force); } diff --git a/lib/hue.js b/lib/hue.js index 8ffc667..35a3632 100644 --- a/lib/hue.js +++ b/lib/hue.js @@ -1,20 +1,22 @@ import Color from 'color'; -import hue from 'node-hue-api'; +import { v3 as hue } from 'node-hue-api'; import Util from './util.js'; -const HueApi = hue.api; +const LightState = hue.lightStates.LightState; const APP_DESCRIPTION = 'dmx-hue utility'; export default class Hue { - getLights() { - return this.api.lights().then( - (result) => result.lights, - () => Util.exit('No lights found') - ); + async getLights() { + try { + const api = await this.api(); + return api.lights.getAll(); + } catch { + Util.exit('No lights found'); + } } createLightState(r, g, b, temperature, brightness, options) { - const state = hue.lightState.create().transition(options.transition); + const state = new LightState().transition(options.transition); const mapRange = (value, low1, high1, low2, high2) => low2 + ((high2 - low2) * (value - low1)) / (high1 - low1); @@ -44,64 +46,82 @@ export default class Hue { return state; } - setLight(id, state) { - return this.api.setLightState(id, state); + async setLight(id, state) { + const api = await this.api(); + return api.lights.setLightState(id, state); } - listBridges(print) { - return hue.nupnpSearch().then( - (bridges) => { - if (print) { - for (const b of bridges) console.log(b.ipaddress); - } + async listBridges(print) { + try { + const bridges = await hue.discovery.nupnpSearch(); + if (bridges.length === 0) { + console.log('No bridges found, trying slower UPnP search...'); + bridges = await hue.discovery.upnpSearch(); + } - return bridges; - }, - () => Util.exit('No bridge found') - ); + console.log(`Found ${bridges.length} bridge(s)`); + + if (print) { + for (const b of bridges) { + console.log(`- ${b.ipaddress} (${b.name})`); + } + } + return bridges; + } catch { + Util.exit('No bridge found'); + } } - setupBridge(ip = null, force = false) { + async setupBridge(ip = null, force = false) { const bridge = Util.config.get('bridge'); if (bridge && Util.config.get('user') && !force) { console.log(`Bridge configured at ${bridge}`); return Promise.resolve(); } - return hue - .nupnpSearch() - .then((bridges) => { - const bridge = ip - ? bridges.find((b) => b.ipaddress === ip) - : bridges[0]; - if (bridge !== null) { - Util.config.set('bridge', bridge.ipaddress); - console.log(`Hue bridge found at ${bridge.ipaddress}`); - return this.bridge; - } + try { + const bridges = await this.listBridges(); + // TODO: if multiple bridges are found, ask the user to select one + const bridge = ip + ? bridges.find((b) => b.ipaddress === ip) + : bridges[0]; + + if (!bridge) { + throw new Error('No bridges found'); + } + + Util.config.set('bridge', bridge.ipaddress); + console.log(`Hue bridge found at ${bridge.ipaddress}`); + + } catch (error) { + if (ip) { + Util.config.set('bridge', ip); + console.log(`Forced Hue bridge at ${ip}`); + } else { + Util.exit('No bridges found'); + } + } - throw undefined; - }) - .catch(() => { - if (ip) { - Util.config.set('bridge', ip); - console.log(`Forced Hue bridge at ${ip}`); - return this.bridge; - } + try { + const user = await hue.api + .createLocal(this.bridge) + .connect() + .then((api) => api.users.createUser(APP_DESCRIPTION)) + .then((user) => user.username); + Util.config.set('user', user); + console.log('Linked bridge successfully'); + } catch { + Util.exit('Cannot link, press the button on bridge and try again.'); + } + } - Util.exit('No bridge found'); - }) - .then((bridge) => - new HueApi().registerUser(bridge, APP_DESCRIPTION).then( - (user) => { - Util.config.set('user', user); - console.log('Linked bridge successfully'); - return user; - }, - () => - Util.exit('Cannot link, press the button on bridge and try again.') - ) - ); + async api() { + if (!this._api) { + this._api = await hue.api + .createLocal(this.bridge) + .connect(this.user); + } + return this._api; } get bridge() { @@ -117,12 +137,4 @@ export default class Hue { Util.exit('Bridge not linked, run "dmx-hue setup"') ); } - - get api() { - if (!this._api) { - this._api = new HueApi(this.bridge, this.user); - } - - return this._api; - } } diff --git a/package-lock.json b/package-lock.json index eeaec69..41b5a23 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "conf": "^11.0.1", "inquirer": "^9.1.4", "minimist": "^1.2.8", - "node-hue-api": "^2.4.1" + "node-hue-api": "^4.0.11" }, "bin": { "dmx-hue": "bin/dmx-hue.js" @@ -1342,11 +1342,11 @@ } }, "node_modules/axios": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", - "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "dependencies": { - "follow-redirects": "1.5.10" + "follow-redirects": "^1.14.0" } }, "node_modules/balanced-match": { @@ -1406,8 +1406,7 @@ "node_modules/bottleneck": { "version": "2.19.5", "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", - "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", - "dev": true + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==" }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -2153,14 +2152,6 @@ "url": "/~https://github.com/sponsors/sindresorhus" } }, - "node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dependencies": { - "ms": "2.0.0" - } - }, "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -2196,6 +2187,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, "engines": { "node": ">=4.0.0" } @@ -3944,14 +3936,22 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "dependencies": { - "debug": "=3.1.0" - }, + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "/~https://github.com/sponsors/RubenVerborgh" + } + ], "engines": { "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, "node_modules/for-each": { @@ -4058,6 +4058,11 @@ "node": ">=0.10.0" } }, + "node_modules/get-ssl-certificate": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/get-ssl-certificate/-/get-ssl-certificate-2.3.3.tgz", + "integrity": "sha512-aKYXS1S5+2IYw4W5+lKC/M+lvaNYPe0PhnQ144NWARcBg35H3ZvyVZ6y0LNGtiAxggFBHeO7LaVGO4bgHK4g1Q==" + }, "node_modules/get-stdin": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", @@ -5879,11 +5884,6 @@ "node": ">=0.10.0" } }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, "node_modules/mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", @@ -5937,18 +5937,16 @@ } }, "node_modules/node-hue-api": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/node-hue-api/-/node-hue-api-2.4.6.tgz", - "integrity": "sha512-XeIejo9zJuyBo0c/0SjLz6yOqUEuUohEoiSEcwaXStzFVa/F001MeGg5idYK4gT3MBlXQ1tgdc/AfQB59djtVA==", + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/node-hue-api/-/node-hue-api-4.0.11.tgz", + "integrity": "sha512-lpnDdMjLTmm00JRsU70Mtm0Ix03cf7PRjKQAJbSg/Y0ChiIKQs+oDbSUpW2aDhEbor+wKpyfLYLGLTrjlG24pQ==", "dependencies": { - "axios": "^0.19.0", - "deep-extend": "^0.6.0", - "q": "~1.4", - "traits": "~0.4.0", - "xml2js": "~0.4" + "axios": "^0.21.1", + "bottleneck": "^2.19.5", + "get-ssl-certificate": "^2.3.3" }, "engines": { - "node": ">= 8.0.0" + "node": ">= 10.0.0" } }, "node_modules/node-releases": { @@ -9186,15 +9184,6 @@ "node": ">=6" } }, - "node_modules/q": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", - "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -9361,9 +9350,9 @@ } }, "node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "node_modules/read-pkg/node_modules/normalize-package-data": { @@ -9638,11 +9627,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, "node_modules/schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", @@ -10700,14 +10684,6 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, - "node_modules/traits": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/traits/-/traits-0.4.0.tgz", - "integrity": "sha1-QW7cq9yL9kvSkQKnRT3N3YVzcaE=", - "engines": { - "node": "*" - } - }, "node_modules/traverse": { "version": "0.6.6", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", @@ -10715,9 +10691,9 @@ "dev": true }, "node_modules/trim-newlines": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", - "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true, "engines": { "node": ">=8" @@ -11254,26 +11230,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } - }, "node_modules/xo": { "version": "0.53.1", "resolved": "https://registry.npmjs.org/xo/-/xo-0.53.1.tgz", diff --git a/package.json b/package.json index 61d839f..e2973ed 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "conf": "^11.0.1", "inquirer": "^9.1.4", "minimist": "^1.2.8", - "node-hue-api": "^2.4.1" + "node-hue-api": "^4.0.11" }, "devDependencies": { "semantic-release": "^20.1.0",