From efe195d6592d5c6cc64de71fc65f85522bc45dfa Mon Sep 17 00:00:00 2001 From: lonkaars Date: Tue, 10 Aug 2021 20:12:17 +0200 Subject: homebridge to homeassistant baby steps --- .gitignore | 2 - __pycache__/driver.cpython-39.pyc | Bin 0 -> 1832 bytes config.schema.json | 20 -- dprint.json | 19 -- driver.py | 58 ++++ hacs.json | 4 + index.ts | 7 - install.sh | 7 +- lamp.ts | 44 --- main.py | 48 --- package.json | 36 --- plugin.ts | 128 -------- readme.md | 13 +- tsconfig.json | 19 -- yarn.lock | 664 -------------------------------------- 15 files changed, 67 insertions(+), 1002 deletions(-) create mode 100644 __pycache__/driver.cpython-39.pyc delete mode 100644 config.schema.json delete mode 100644 dprint.json create mode 100644 driver.py create mode 100644 hacs.json delete mode 100644 index.ts delete mode 100644 lamp.ts delete mode 100644 main.py delete mode 100644 package.json delete mode 100644 plugin.ts delete mode 100644 tsconfig.json delete mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore index b3ada5d..928bcdc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,2 @@ -node_modules/ -**/*.js venv/ diff --git a/__pycache__/driver.cpython-39.pyc b/__pycache__/driver.cpython-39.pyc new file mode 100644 index 0000000..43ddd28 Binary files /dev/null and b/__pycache__/driver.cpython-39.pyc differ diff --git a/config.schema.json b/config.schema.json deleted file mode 100644 index 6a64a39..0000000 --- a/config.schema.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "pluginAlias": "BekenBridge", - "pluginType": "accessory", - "singular": false, - "schema": { - "type": "object", - "properties": { - "name": { - "title": "Name", - "type": "string", - "required": true - }, - "address": { - "title": "Bluetooth address of lamp", - "type": "string", - "required": true - } - } - } -} diff --git a/dprint.json b/dprint.json deleted file mode 100644 index b8a5173..0000000 --- a/dprint.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://dprint.dev/schemas/v0.json", - "projectType": "openSource", - "incremental": true, - "useTabs": true, - "typescript": { - "semiColons": "always", - "quoteStyle": "preferSingle", - "importDeclaration.spaceSurroundingNamedImports": true - }, - "includes": [ "**/*.{ts}" ], - "excludes": [ - "node_modules/**", - "**/*-lock.json" - ], - "plugins": [ - "https://plugins.dprint.dev/typescript-0.44.0.wasm" - ] -} diff --git a/driver.py b/driver.py new file mode 100644 index 0000000..91b537e --- /dev/null +++ b/driver.py @@ -0,0 +1,58 @@ +#!/bin/python3 +from bluepy.btle import Peripheral, ADDR_TYPE_PUBLIC, BTLEDisconnectError +import threading +import time +import sys + +def makemsg(r, g, b, l=0): + return bytes([ + int(g > 0), g, + 0x00, 0x00, + int(b > 0), b, + int(r > 0), r, + int(l > 0), l, + ]) + +class BekenConnection: + def __init__(self, mac): + self.mac = mac + self.dev = None + self.messages = [] + + def keep_alive(self): + while True: + self.send(0x0001, bytes(10)) + time.sleep(10) + + def send(self, characteristic, message): + self.messages.append((characteristic, message)) + + def verify_connection(self): + while self.dev == None or self.dev.getState() == 'disc': + try: + self.dev = Peripheral(self.mac, ADDR_TYPE_PUBLIC) + except BTLEDisconnectError as e: + continue + + def message_handler(self): + self.verify_connection() + while True: + if len(self.messages) < 1: continue + message = self.messages.pop(0) + self.verify_connection() + self.dev.writeCharacteristic(message[0], bytearray(message[1])) + + def start_threads(self): + threading.Thread(target=self.message_handler).start() + threading.Thread(target=self.keep_alive).start() + +if __name__ == "__main__": + mac = sys.argv[1] + con = BekenConnection(mac) + con.start_threads() + def user_input(): + for line in sys.stdin: + r, g, b, l = [ int(x, 16) for x in [ line.strip()[i:i+2] for i in range(0, 8, 2) ] ] + con.send(0x002a, makemsg(r, g, b, l)) + threading.Thread(target=user_input).start() + diff --git a/hacs.json b/hacs.json new file mode 100644 index 0000000..6da0dd7 --- /dev/null +++ b/hacs.json @@ -0,0 +1,4 @@ +{ + "name": "Beken", + "content_in_root": true +} diff --git a/index.ts b/index.ts deleted file mode 100644 index ece061d..0000000 --- a/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { API } from 'homebridge'; - -import BekenBridge from './plugin'; - -module.exports = (api: API) => { - api.registerAccessory('BekenBridge', BekenBridge); -}; diff --git a/install.sh b/install.sh index a7923bc..55650be 100644 --- a/install.sh +++ b/install.sh @@ -1,7 +1,4 @@ #!/bin/sh - -npm run build - rm -rf venv -npm run python -sudo npm run perms +python3 -m venv venv && venv/bin/pip3 install -r requirements.txt +sudo setcap 'cap_net_raw,cap_net_admin+eip' venv/lib/python3.9/site-packages/bluepy/bluepy-helper diff --git a/lamp.ts b/lamp.ts deleted file mode 100644 index b9a16a8..0000000 --- a/lamp.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { ChildProcess, spawn } from 'child_process'; -import { Logger } from 'homebridge'; -import { join } from 'path'; - -export type LampColor = [number, number, number, number]; - -export default class Lamp { - #color: LampColor; - private subpr: ChildProcess; - private last: string; - - constructor(public addr: string, public log: Logger) { - this.subpr = spawn(join(__dirname, '/venv/bin/python3'), [join(__dirname, './main.py'), addr]); - - // debug - this.subpr.stderr.on('data', this.log.error); - this.subpr.stdout.on('data', this.log.log); - } - - set color(newColor: LampColor) { - this.#color = newColor.map(c => Math.floor(c)) as LampColor; - var message = this.colorToString(); - if (this.last == message) return; // prevent duplicate messages - this.subpr.stdin.write(message + '\n'); - this.last = message; - } - - get color() { - return this.#color; - } - - private colorToString() { - return this.color.map(i => i.toString(16).padStart(2, '0')).join(''); - } -} - -// ! DEBUG -// if (typeof require !== 'undefined' && require.main === module) { -// var lamp = new Lamp("FC:58:FA:A1:CF:F1"); -// -// setInterval(() => { -// lamp.color = [0, 0, 0, Math.floor(Math.random() * 255)]; -// }, 100); -// } diff --git a/main.py b/main.py deleted file mode 100644 index d2debb7..0000000 --- a/main.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/python3 -from bluepy.btle import Peripheral, ADDR_TYPE_PUBLIC, BTLEDisconnectError -import threading -import time -import sys - -mac = sys.argv[1] -dev = None -messages = [] - -def verify_connection(): - global dev - while dev == None or dev.getState() == 'disc': - try: - dev = Peripheral(mac, ADDR_TYPE_PUBLIC) - except BTLEDisconnectError as e: - continue - -def makemsg(r, g, b, l=0): - return bytes([ - int(g > 0), g, - 0x00, 0x00, - int(b > 0), b, - int(r > 0), r, - int(l > 0), l, - ]) - -def keep_alive(): - while True: - global messages - messages.append((0x0001, bytes(10))) - time.sleep(10) - -def user_input(): - for line in sys.stdin: - r, g, b, l = [ int(x, 16) for x in [ line.strip()[i:i+2] for i in range(0, 8, 2) ] ] - messages.append((0x002a, makemsg(r, g, b, l))) - -threading.Thread(target=keep_alive).start() -threading.Thread(target=user_input).start() - -verify_connection() -while True: - if len(messages) < 1: continue - message = messages.pop(0) - verify_connection() - dev.writeCharacteristic(message[0], bytearray(message[1])) - diff --git a/package.json b/package.json deleted file mode 100644 index e73123a..0000000 --- a/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "displayName": "Beken LED Homebridge plugin", - "name": "homebridge-beken", - "version": "0.1.6", - "description": "homebridge beken led plugin", - "author": "lonkaars ", - "license": "MIT", - "private": false, - "main": "./index.js", - "repository": { - "type": "git", - "url": "https://github.com/lonkaars/homebridge-beken" - }, - "keywords": [ - "homebridge-plugin" - ], - "engines": { - "node": ">=16.0.0", - "homebridge": ">=1.3.0" - }, - "scripts": { - "build": "tsc", - "python": "python3 -m venv venv && venv/bin/pip3 install -r requirements.txt", - "perms": "sudo setcap 'cap_net_raw,cap_net_admin+eip' venv/lib/python3.9/site-packages/bluepy/bluepy-helper", - "postinstall": "sh ./install.sh" - }, - "dependencies": { - "color": "^4.0.0" - }, - "devDependencies": { - "@types/color": "^3.0.2", - "@types/node": "^16.4.10", - "homebridge": "^1.3.4", - "typescript": "^4.3.5" - } -} diff --git a/plugin.ts b/plugin.ts deleted file mode 100644 index 9b2fa10..0000000 --- a/plugin.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { AccessoryConfig, AccessoryPlugin, API, Logger, Service } from 'homebridge'; - -import Lamp from './lamp'; -const Color = require('color'); - -export default class BekenBridge implements AccessoryPlugin { - private lamp: Lamp; - private infoService: Service; - - private whiteBulbService: Service; - private RGBBulbService: Service; - - private state: { - on: boolean; - brightness: number; - lamp: 'white' | 'rgb'; - saturation: number; - hue: number; - }; - - public name: string; - - constructor( - public readonly log: Logger, - public readonly config: AccessoryConfig, - public readonly api: API, - ) { - this.name = config.name; - this.lamp = new Lamp(config.address, log); - - this.state = { - on: false, - brightness: 100, - lamp: 'white', - saturation: 0, - hue: 0, - }; - - this.infoService = new this.api.hap.Service.AccessoryInformation() - .setCharacteristic(this.api.hap.Characteristic.Manufacturer, 'Beken') - .setCharacteristic(this.api.hap.Characteristic.Model, 'Beken LED'); - - this.whiteBulbService = new this.api.hap.Service.Lightbulb('White', 'normal'); - this.RGBBulbService = new this.api.hap.Service.Lightbulb('RGB', 'rgb'); - - this.registerWhiteBulbServices(); - this.registerRGBBulbServices(); - } - - registerWhiteBulbServices() { - var done = () => { - this.RGBBulbService.getCharacteristic(this.api.hap.Characteristic.On).updateValue(false); - this.state.lamp = 'white'; - this.updateLamp(); - }; - this.whiteBulbService.getCharacteristic(this.api.hap.Characteristic.On) - .onGet(() => this.state.on && this.state.lamp == 'white') - .onSet((on: boolean) => { - this.state.on = on; - done(); - }); - this.whiteBulbService.getCharacteristic(this.api.hap.Characteristic.Brightness) - .onGet(() => this.state.brightness) - .onSet((brt: number) => { - this.state.brightness = brt; - done(); - }); - } - - registerRGBBulbServices() { - var done = () => { - this.whiteBulbService.getCharacteristic(this.api.hap.Characteristic.On).updateValue(false); - this.state.lamp = 'rgb'; - this.updateLamp(); - }; - this.RGBBulbService.getCharacteristic(this.api.hap.Characteristic.On) - .onGet(() => this.state.on && this.state.lamp == 'rgb') - .onSet((on: boolean) => { - this.state.on = on; - done(); - }); - this.RGBBulbService.getCharacteristic(this.api.hap.Characteristic.Brightness) - .onGet(() => this.state.brightness) - .onSet((brt: number) => { - this.state.brightness = brt; - done(); - }); - this.RGBBulbService.getCharacteristic(this.api.hap.Characteristic.Hue) - .onGet(() => this.state.hue) - .onSet((hue: number) => { - this.state.hue = hue; - done(); - }); - this.RGBBulbService.getCharacteristic(this.api.hap.Characteristic.Saturation) - .onGet(() => this.state.saturation) - .onSet((sat: number) => { - this.state.saturation = sat; - done(); - }); - } - - updateLamp() { - if (!this.state.on) { - this.lamp.color = [0, 0, 0, 0]; - return; - } - switch (this.state.lamp) { - case 'rgb': { - var rgb = Color({ h: this.state.hue, s: this.state.saturation, v: this.state.brightness }); - this.lamp.color = [rgb.red(), rgb.green(), rgb.blue(), 0]; - break; - } - case 'white': { - var value = Math.floor(this.state.brightness / 100 * 255); - this.lamp.color = [0, 0, 0, value]; - break; - } - } - } - - getServices() { - return [ - this.infoService, - this.whiteBulbService, - this.RGBBulbService, - ]; - } -} diff --git a/readme.md b/readme.md index ddfc71e..882ebd7 100644 --- a/readme.md +++ b/readme.md @@ -1,14 +1,7 @@ -# homebridge-beken +# homeassistant-beken -> NOTE: requires python3 -> -> This plugin uses child_process to spawn a python script that does the actual -> communication with the bulb using the bluepy library. Bluepy uses a binary -> called bluepy-helper which should be run as root or given permission to -> directly talk to the bluetooth stack. - -- a simple homebridge plugin that allows the control of a bulb that goes by - many names: +- a simple hacs plugin that allows the control of a bulb that goes by many + names: - Shada Led's light - iLedBulb - Beken LED diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 3267caa..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "compilerOptions": { - "moduleResolution": "node", - "pretty": false, - "target": "esnext", - "module": "commonjs", - "inlineSources": true, - "inlineSourceMap": true, - "allowSyntheticDefaultImports": true, - "skipLibCheck": true, - "rootDir": "." - }, - "exclude": [ "node_modules" ], - "files": [ - "./index.ts", - "./plugin.ts", - "./lamp.ts" - ] -} diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index fc834e5..0000000 --- a/yarn.lock +++ /dev/null @@ -1,664 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@homebridge/ciao@~1.1.2": - version "1.1.2" - resolved "https://registry.npmjs.org/@homebridge/ciao/-/ciao-1.1.2.tgz" - integrity sha512-31IfDKMqxfT+uVNXj0/TmYMou57gP8CUrh0vABzsc5QMsoCQ4Oo5uYQp0oJJyzxTBkF2pFvjR3XlWAapl0VyCg== - dependencies: - debug "^4.3.1" - fast-deep-equal "^3.1.3" - source-map-support "^0.5.19" - tslib "^2.0.3" - -"@leichtgewicht/ip-codec@^2.0.1": - version "2.0.3" - resolved "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz" - integrity sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg== - -"@types/color-convert@*": - version "2.0.0" - resolved "https://registry.npmjs.org/@types/color-convert/-/color-convert-2.0.0.tgz" - integrity sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ== - dependencies: - "@types/color-name" "*" - -"@types/color-name@*": - version "1.1.1" - resolved "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz" - integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== - -"@types/color@^3.0.2": - version "3.0.2" - resolved "https://registry.npmjs.org/@types/color/-/color-3.0.2.tgz" - integrity sha512-INiJl6sfNn8iyC5paxVzqiVUEj2boIlFki02uRTAkKwAj++7aAF+ZfEv/XrIeBa0XI/fTZuDHW8rEEcEVnON+Q== - dependencies: - "@types/color-convert" "*" - -"@types/node@^16.4.10": - version "16.4.10" - resolved "https://registry.npmjs.org/@types/node/-/node-16.4.10.tgz" - integrity sha512-TmVHsm43br64js9BqHWqiDZA+xMtbUpI1MBIA0EyiBmoV9pcEYFOSdj5fr6enZNfh4fChh+AGOLIzGwJnkshyQ== - -ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -array-flatten@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - -available-typed-arrays@^1.0.2: - version "1.0.4" - resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz" - integrity sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA== - -bonjour-hap@~3.6.2: - version "3.6.2" - resolved "https://registry.npmjs.org/bonjour-hap/-/bonjour-hap-3.6.2.tgz" - integrity sha512-uwMGUJ2Yql/sqvxAqR4nkE4qypo5JJk7EtGMkB/ikHMHa7/0djDjB8Ct0ES+8OK8SKZzthrLngDo+e2VjcfdXw== - dependencies: - array-flatten "^2.1.2" - deep-equal "^2.0.5" - ip "^1.1.5" - multicast-dns "^7.2.2" - multicast-dns-service-types "^1.1.0" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-string@^1.6.0: - version "1.6.0" - resolved "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz" - integrity sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/color/-/color-4.0.0.tgz" - integrity sha512-aVUOa5aYWJSimvei14J5rdxLeljG0EB/uXTovVaaSokW+D4MsAz3MrKsRNaKqPa2KL7Wfvh7PZyIIaaX4lYdzQ== - dependencies: - color-convert "^2.0.1" - color-string "^1.6.0" - -commander@5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz" - integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== - -debug@^4.3.1: - version "4.3.2" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - -deep-equal@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-2.0.5.tgz" - integrity sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw== - dependencies: - call-bind "^1.0.0" - es-get-iterator "^1.1.1" - get-intrinsic "^1.0.1" - is-arguments "^1.0.4" - is-date-object "^1.0.2" - is-regex "^1.1.1" - isarray "^2.0.5" - object-is "^1.1.4" - object-keys "^1.1.1" - object.assign "^4.1.2" - regexp.prototype.flags "^1.3.0" - side-channel "^1.0.3" - which-boxed-primitive "^1.0.1" - which-collection "^1.0.1" - which-typed-array "^1.1.2" - -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -dns-packet@^5.2.2: - version "5.3.0" - resolved "https://registry.npmjs.org/dns-packet/-/dns-packet-5.3.0.tgz" - integrity sha512-Nce7YLu6YCgWRvOmDBsJMo9M5/jV3lEZ5vUWnWXYmwURvPylHvq7nkDWhNmk1ZQoZZOP7oQh/S0lSxbisKOfHg== - dependencies: - "@leichtgewicht/ip-codec" "^2.0.1" - -es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: - version "1.18.5" - resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz" - integrity sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.2" - internal-slot "^1.0.3" - is-callable "^1.2.3" - is-negative-zero "^2.0.1" - is-regex "^1.1.3" - is-string "^1.0.6" - object-inspect "^1.11.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.1" - -es-get-iterator@^1.1.1: - version "1.1.2" - resolved "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz" - integrity sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.0" - has-symbols "^1.0.1" - is-arguments "^1.1.0" - is-map "^2.0.2" - is-set "^2.0.2" - is-string "^1.0.5" - isarray "^2.0.5" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-srp-hap@2.0.3: - version "2.0.3" - resolved "https://registry.npmjs.org/fast-srp-hap/-/fast-srp-hap-2.0.3.tgz" - integrity sha512-4P8TBD0all202L9FbeSsWc9qDlpaYp065VbUwbuNYZDYdOJ02UlWaDkai6d/+6/I8/sdtVYAVd17PEZDKbqopQ== - -foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz" - integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= - -fs-extra@^9.1.0: - version "9.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -futoin-hkdf@~1.3.2: - version "1.3.3" - resolved "https://registry.npmjs.org/futoin-hkdf/-/futoin-hkdf-1.3.3.tgz" - integrity sha512-oR75fYk3B3X9/B02Y6vusrBKucrpC6VjxhRL+C6B7FwUpuSRHbhBNG3AZbcE/xPyJmEQWsyqUFp3VeNNbA3S7A== - -get-intrinsic@^1.0.1, get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -graceful-fs@^4.1.6, graceful-fs@^4.2.0: - version "4.2.6" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz" - integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== - -hap-nodejs@0.9.4: - version "0.9.4" - resolved "https://registry.npmjs.org/hap-nodejs/-/hap-nodejs-0.9.4.tgz" - integrity sha512-wGYq6nQ8c5+V7iLr9Fa7XpOGAntmB0ejfOsjoIhXe/WHOXX9gGDwYgQTHg+dwmJZjW7RBoOyRRdB7/oa/NYovw== - dependencies: - "@homebridge/ciao" "~1.1.2" - bonjour-hap "~3.6.2" - debug "^4.3.1" - fast-srp-hap "2.0.3" - futoin-hkdf "~1.3.2" - ip "^1.1.3" - node-persist "^0.0.11" - source-map-support "^0.5.19" - tslib "^2.1.0" - tweetnacl "^1.0.3" - -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.1, has-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -homebridge@^1.3.4: - version "1.3.4" - resolved "https://registry.npmjs.org/homebridge/-/homebridge-1.3.4.tgz" - integrity sha512-I2vxabWpKHly3htXvOgnJbO79pXzrorz6/htRUCD3UTWXnzURqUFhevv9c/Mji3YeKxluIXCyXyiGAuDfx1m3A== - dependencies: - chalk "^4.1.0" - commander "5.1.0" - fs-extra "^9.1.0" - hap-nodejs "0.9.4" - qrcode-terminal "^0.12.0" - semver "^7.3.4" - source-map-support "^0.5.19" - -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" - -ip@^1.1.3, ip@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - -is-arguments@^1.0.4, is-arguments@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz" - integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== - dependencies: - call-bind "^1.0.0" - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - -is-bigint@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz" - integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== - -is-boolean-object@^1.1.0: - version "1.1.1" - resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz" - integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== - dependencies: - call-bind "^1.0.2" - -is-callable@^1.1.4, is-callable@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz" - integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== - -is-date-object@^1.0.1, is-date-object@^1.0.2: - version "1.0.4" - resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz" - integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A== - -is-map@^2.0.1, is-map@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz" - integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== - -is-negative-zero@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz" - integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== - -is-number-object@^1.0.4: - version "1.0.5" - resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz" - integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw== - -is-regex@^1.1.1, is-regex@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz" - integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== - dependencies: - call-bind "^1.0.2" - has-symbols "^1.0.2" - -is-set@^2.0.1, is-set@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz" - integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== - -is-string@^1.0.5, is-string@^1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz" - integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typed-array@^1.1.3: - version "1.1.5" - resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz" - integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug== - dependencies: - available-typed-arrays "^1.0.2" - call-bind "^1.0.2" - es-abstract "^1.18.0-next.2" - foreach "^2.0.5" - has-symbols "^1.0.1" - -is-weakmap@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz" - integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== - -is-weakset@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.1.tgz" - integrity sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw== - -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mkdirp@~0.5.1: - version "0.5.5" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -multicast-dns-service-types@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz" - integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= - -multicast-dns@^7.2.2: - version "7.2.3" - resolved "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.3.tgz" - integrity sha512-TzxgGSLRLB7tqAlzjgd2x2ZE0cDsGFq4rs9W4yE5xp+7hlRXeUQGtXZsTGfGw2FwWB45rfe8DtXMYBpZGMLUng== - dependencies: - dns-packet "^5.2.2" - thunky "^1.0.2" - -node-persist@^0.0.11: - version "0.0.11" - resolved "https://registry.npmjs.org/node-persist/-/node-persist-0.0.11.tgz" - integrity sha1-1m66Pr72IPB5Uw+nsTB2qQZmWHQ= - dependencies: - mkdirp "~0.5.1" - q "~1.1.1" - -object-inspect@^1.11.0, object-inspect@^1.9.0: - version "1.11.0" - resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz" - integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== - -object-is@^1.1.4: - version "1.1.5" - resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" - -q@~1.1.1: - version "1.1.2" - resolved "https://registry.npmjs.org/q/-/q-1.1.2.tgz" - integrity sha1-Y1fikSBnAdmfGXq4TlforRlvKok= - -qrcode-terminal@^0.12.0: - version "0.12.0" - resolved "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz" - integrity sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ== - -regexp.prototype.flags@^1.3.0: - version "1.3.1" - resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz" - integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -semver@^7.3.4: - version "7.3.5" - resolved "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -side-channel@^1.0.3, side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - dependencies: - is-arrayish "^0.3.1" - -source-map-support@^0.5.19: - version "0.5.19" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== - -tslib@^2.0.3, tslib@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz" - integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== - -tweetnacl@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - -typescript@^4.3.5: - version "4.3.5" - resolved "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz" - integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== - -unbox-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz" - integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== - dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.1" - has-symbols "^1.0.2" - which-boxed-primitive "^1.0.2" - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - -which-boxed-primitive@^1.0.1, which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-collection@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz" - integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== - dependencies: - is-map "^2.0.1" - is-set "^2.0.1" - is-weakmap "^2.0.1" - is-weakset "^2.0.1" - -which-typed-array@^1.1.2: - version "1.1.4" - resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz" - integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA== - dependencies: - available-typed-arrays "^1.0.2" - call-bind "^1.0.0" - es-abstract "^1.18.0-next.1" - foreach "^2.0.5" - function-bind "^1.1.1" - has-symbols "^1.0.1" - is-typed-array "^1.1.3" - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -- cgit v1.2.3 From 2319806262c0880c839f923c12cb995e26dbc2c3 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Wed, 11 Aug 2021 12:57:57 +0200 Subject: loading now? --- __init__.py | 5 +++++ light.py | 26 ++++++++++++++++++++++++++ manifest.json | 11 +++++++++++ 3 files changed, 42 insertions(+) create mode 100644 __init__.py create mode 100644 light.py create mode 100644 manifest.json diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..40b4d90 --- /dev/null +++ b/__init__.py @@ -0,0 +1,5 @@ +DOMAIN = "beken" + +def setup(hass, config): + hass.states.set("beken.loaded", "yes") + return True diff --git a/light.py b/light.py new file mode 100644 index 0000000..c443728 --- /dev/null +++ b/light.py @@ -0,0 +1,26 @@ +from homeassistant.components.light import LightEntity, ATTR_BRIGHTNESS, ATTR_COLOR_MODE +from driver import BekenConnection, makemsg + +class BekenLight(LightEntity): + def __init__(self): + self._state = { + "on": False, + "brightness": 100, + "lamp": "white", + "saturation": 0, + "hue": 0, + } + + @property + def name(self): + return "Beken LED" + + @property + def is_on(self): + return self._state['on'] + + def turn_on(self, **kwargs): + self._state['on'] = True + + def turn_off(self, **kwargs): + self._state['on'] = False diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..e104978 --- /dev/null +++ b/manifest.json @@ -0,0 +1,11 @@ +{ + "domain": "beken", + "name": "Beken", + "documentation": "https://github.com/lonkaars/homebridge-beken", + "issue_tracker": "https://github.com/lonkaars/homebridge-beken", + "codeowners": [ "@lonkaars" ], + "version": "0.2.0", + "requirements": [], + "iot_class": "cloud_polling" +} + -- cgit v1.2.3 From a1821bb663f834295d94acaf3a8c531fb30848a9 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Thu, 12 Aug 2021 19:04:39 +0200 Subject: loading now! --- .gitignore | 1 + __init__.py | 10 ++++- __pycache__/driver.cpython-39.pyc | Bin 1832 -> 0 bytes light.py | 78 +++++++++++++++++++++++++++++++------- 4 files changed, 73 insertions(+), 16 deletions(-) delete mode 100644 __pycache__/driver.cpython-39.pyc diff --git a/.gitignore b/.gitignore index 928bcdc..9d557af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ venv/ +__pycache__/ diff --git a/__init__.py b/__init__.py index 40b4d90..eb66857 100644 --- a/__init__.py +++ b/__init__.py @@ -1,5 +1,11 @@ +from homeassistant.core import HomeAssistant + DOMAIN = "beken" +PLATFORMS = ["light"] + +def setup(hass: HomeAssistant, config): + hass.data[DOMAIN] = {} + return True -def setup(hass, config): - hass.states.set("beken.loaded", "yes") +def setup_entry(hass, entry): return True diff --git a/__pycache__/driver.cpython-39.pyc b/__pycache__/driver.cpython-39.pyc deleted file mode 100644 index 43ddd28..0000000 Binary files a/__pycache__/driver.cpython-39.pyc and /dev/null differ diff --git a/light.py b/light.py index c443728..6b5961f 100644 --- a/light.py +++ b/light.py @@ -1,26 +1,76 @@ -from homeassistant.components.light import LightEntity, ATTR_BRIGHTNESS, ATTR_COLOR_MODE -from driver import BekenConnection, makemsg +import homeassistant.helpers.config_validation as cv +import voluptuous as vol +from homeassistant.const import CONF_MAC +from .driver import BekenConnection, makemsg +from homeassistant.components.light import ( + LightEntity, + + SUPPORT_BRIGHTNESS, + SUPPORT_COLOR, + SUPPORT_WHITE_VALUE, + + ATTR_BRIGHTNESS, + ATTR_RGBW_COLOR, + + COLOR_MODE_RGBW, + PLATFORM_SCHEMA +) + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required("name"): cv.string, + vol.Required("address"): cv.string +}) + +SUPPORT_FEATURES_RGB = SUPPORT_BRIGHTNESS | SUPPORT_COLOR +SUPPORT_FEATURES_WHITE = SUPPORT_BRIGHTNESS + +def setup_platform(hass, config, add_entities, discovery_info=None): + add_entities([ BekenLight(name=config["name"], address=config["address"]) ]) class BekenLight(LightEntity): - def __init__(self): - self._state = { - "on": False, - "brightness": 100, - "lamp": "white", - "saturation": 0, - "hue": 0, - } + def __init__(self, **kwargs): + self._name = kwargs["name"] + self._address = kwargs["address"] + self._on = False + self._brightness = 255 + self._rgbw = (255, 255, 255, 255) # r, g, b, w + + @property + def color_mode(self): + return COLOR_MODE_RGBW + + @property + def supported_color_modes(self): + return set([ COLOR_MODE_RGBW ]) + + @property + def supported_features(self): + return SUPPORT_BRIGHTNESS | SUPPORT_COLOR | SUPPORT_WHITE_VALUE + + @property + def unique_id(self): + return self._address @property def name(self): - return "Beken LED" + return self._name @property def is_on(self): - return self._state['on'] + return self._on + + @property + def brightness(self): + return self._brightness + + @property + def rgbw_color(self): + return self._rgbw def turn_on(self, **kwargs): - self._state['on'] = True + self._on = True + self._brightness = kwargs.get(ATTR_BRIGHTNESS) + self._rgbw = kwargs.get(ATTR_RGBW_COLOR) def turn_off(self, **kwargs): - self._state['on'] = False + self._on = False -- cgit v1.2.3 From 63102954fa115629d3fef84c0e251aa1a8269201 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Fri, 13 Aug 2021 13:58:12 +0200 Subject: working (still buggy) --- driver.py | 7 +++++-- light.py | 32 +++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/driver.py b/driver.py index 91b537e..5280d7d 100644 --- a/driver.py +++ b/driver.py @@ -4,6 +4,9 @@ import threading import time import sys +BEKEN_CHARACTERISTIC_NULL = 0x0001 +BEKEN_CHARACTERISTIC_LAMP = 0x002a + def makemsg(r, g, b, l=0): return bytes([ int(g > 0), g, @@ -21,7 +24,7 @@ class BekenConnection: def keep_alive(self): while True: - self.send(0x0001, bytes(10)) + self.send(BEKEN_CHARACTERISTIC_NULL, bytes(10)) time.sleep(10) def send(self, characteristic, message): @@ -53,6 +56,6 @@ if __name__ == "__main__": def user_input(): for line in sys.stdin: r, g, b, l = [ int(x, 16) for x in [ line.strip()[i:i+2] for i in range(0, 8, 2) ] ] - con.send(0x002a, makemsg(r, g, b, l)) + con.send(BEKEN_CHARACTERISTIC_LAMP, makemsg(r, g, b, l)) threading.Thread(target=user_input).start() diff --git a/light.py b/light.py index 6b5961f..f7cb243 100644 --- a/light.py +++ b/light.py @@ -1,7 +1,8 @@ import homeassistant.helpers.config_validation as cv import voluptuous as vol +from math import floor from homeassistant.const import CONF_MAC -from .driver import BekenConnection, makemsg +from .driver import BekenConnection, makemsg, BEKEN_CHARACTERISTIC_LAMP from homeassistant.components.light import ( LightEntity, @@ -33,7 +34,10 @@ class BekenLight(LightEntity): self._address = kwargs["address"] self._on = False self._brightness = 255 - self._rgbw = (255, 255, 255, 255) # r, g, b, w + self._rgb = (255, 255, 255) + self._w = 255 + self._connection = BekenConnection(self._address) + self._connection.start_threads() @property def color_mode(self): @@ -65,12 +69,30 @@ class BekenLight(LightEntity): @property def rgbw_color(self): - return self._rgbw + return self._rgb + (self._w,) def turn_on(self, **kwargs): self._on = True - self._brightness = kwargs.get(ATTR_BRIGHTNESS) - self._rgbw = kwargs.get(ATTR_RGBW_COLOR) + + brightness = kwargs.get(ATTR_BRIGHTNESS) + if brightness != None: + self._brightness = brightness + + rgbw = kwargs.get(ATTR_RGBW_COLOR) + if rgbw != None: + self._rgb = rgbw[0:3] + self._w = rgbw[3] + + self.update_beken_lamp() def turn_off(self, **kwargs): self._on = False + self.update_beken_lamp() + + def update_beken_lamp(self): + r = int(self._on) * self._rgb[0] + g = int(self._on) * self._rgb[1] + b = int(self._on) * self._rgb[2] + l = int(self._on) * self._w + self._connection.send(BEKEN_CHARACTERISTIC_LAMP, makemsg(r, g, b, l)) + -- cgit v1.2.3 From 886630c94bd76b5bec9aa5b2eeb8a6da7d6a0cc2 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Fri, 13 Aug 2021 14:01:59 +0200 Subject: updated readme --- readme.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 882ebd7..fa19d8a 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,17 @@ # homeassistant-beken -- a simple hacs plugin that allows the control of a bulb that goes by many - names: +this used to be a homebridge plugin, but i switched from using homebridge to +homeassistant because homeassistant has way more functionality. you can still +get the homebridge plugin from +[npm](https://www.npmjs.com/package/homebridge-beken) or by running `sudo npm i +-g homebridge-beken`, and the code for that plugin is in the releases section +on this repo, though i don't intend on updating it anymore. + +> installation *should* work with hacs, though i just `git clone` it into my +> `custom_components` directory because homeassistant is already janky. + +- a simple homeassistant plugin that allows the control of a bulb that goes by + many names: - Shada Led's light - iLedBulb - Beken LED -- cgit v1.2.3