From 4b85e9b83a30ffa15e1d0d08bd9870589cce244e Mon Sep 17 00:00:00 2001 From: Ingo Fischer Date: Sat, 20 Jul 2024 17:55:37 +0200 Subject: [PATCH 1/4] Add Prettier --- .eslintrc.js | 16 +- .prettierignore | 2 + .prettierrc.json | 15 + package-lock.json | 439 +++++++---- package.json | 29 +- src/lib/DeviceFactory.ts | 21 +- src/lib/DeviceManagement.ts | 60 +- src/lib/devices/AirCondition.ts | 78 +- src/lib/devices/Blind.ts | 28 +- src/lib/devices/BlindButtons.ts | 76 +- src/lib/devices/Button.ts | 18 +- src/lib/devices/ButtonSensor.ts | 26 +- src/lib/devices/Camera.ts | 58 +- src/lib/devices/Chart.ts | 6 +- src/lib/devices/Cie.ts | 19 +- src/lib/devices/Ct.ts | 60 +- src/lib/devices/Dimmer.ts | 48 +- src/lib/devices/Door.ts | 18 +- src/lib/devices/FireAlarm.ts | 18 +- src/lib/devices/FloodAlarm.ts | 18 +- src/lib/devices/Gate.ts | 38 +- src/lib/devices/GenericDevice.ts | 207 ++++-- src/lib/devices/Hue.ts | 20 +- src/lib/devices/Humidity.ts | 20 +- src/lib/devices/Image.ts | 20 +- src/lib/devices/Info.ts | 20 +- src/lib/devices/Light.ts | 75 +- src/lib/devices/Location.ts | 52 +- src/lib/devices/LocationOne.ts | 44 +- src/lib/devices/Lock.ts | 38 +- src/lib/devices/Media.ts | 194 ++++- src/lib/devices/Motion.ts | 28 +- src/lib/devices/Rgb.ts | 44 +- src/lib/devices/RgbSingle.ts | 20 +- src/lib/devices/RgbwSingle.ts | 21 +- src/lib/devices/Slider.ts | 30 +- src/lib/devices/Socket.ts | 2 +- src/lib/devices/Temperature.ts | 28 +- src/lib/devices/Thermostat.ts | 68 +- src/lib/devices/VacuumCleaner.ts | 140 +++- src/lib/devices/Volume.ts | 38 +- src/lib/devices/VolumeGroup.ts | 2 +- src/lib/devices/Warning.ts | 68 +- src/lib/devices/WeatherCurrent.ts | 116 ++- src/lib/devices/WeatherForecast.ts | 180 ++++- src/lib/devices/Window.ts | 20 +- src/lib/devices/WindowTilt.ts | 20 +- src/lib/i18n.ts | 10 +- src/lib/index.ts | 10 +- src/main.ts | 173 +++-- src/matter/BaseServerNode.ts | 7 +- src/matter/BridgedDevicesNode.ts | 52 +- src/matter/ControllerNode.ts | 165 +++-- src/matter/DeviceNode.ts | 35 +- src/matter/GeneralNode.ts | 3 +- src/matter/IoBrokerNodeStorage.ts | 23 +- src/matter/clusters/Base.ts | 39 +- src/matter/clusters/BooleanState.ts | 13 +- src/matter/clusters/Identify.ts | 17 +- src/matter/clusters/LevelControl.ts | 19 +- src/matter/clusters/OnOff.ts | 15 +- src/matter/clusters/factories.ts | 13 +- src/matter/devices/MappingDimmer.ts | 19 +- src/matter/devices/MappingGenericDevice.ts | 8 +- src/matter/devices/MappingLight.ts | 10 +- src/matter/devices/MappingSocket.ts | 13 +- src/matter/matterFactory.ts | 10 +- src/matter/vendorIds.ts | 824 ++++++++++----------- 68 files changed, 2764 insertions(+), 1320 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc.json diff --git a/.eslintrc.js b/.eslintrc.js index 20a6a12..8cb3e88 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -13,20 +13,10 @@ module.exports = { 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin ], rules: { - 'indent': 'off', - '@typescript-eslint/indent': [ - 'error', - 4, - { - 'SwitchCase': 1 - } - ], 'semi': 'off', '@typescript-eslint/semi': 'error', - 'object-curly-spacing': 'off', - '@typescript-eslint/object-curly-spacing': ['error', 'always'], - 'space-before-function-paren': 'off', - '@typescript-eslint/space-before-function-paren': ['error', 'never'], + '@typescript-eslint/object-curly-spacing': 'off', + '@typescript-eslint/space-before-function-paren': 'off', 'quotes': [ 'error', 'single', @@ -74,4 +64,4 @@ module.exports = { }, }, ], -}; \ No newline at end of file +}; diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..abfd7a9 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +/build/** +/admin/** diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..aef2b56 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,15 @@ +{ + "printWidth": 120, + "semi": true, + "tabWidth": 4, + "useTabs": false, + "trailingComma": "all", + "singleQuote": true, + "endOfLine": "lf", + "bracketSpacing": true, + "arrowParens": "avoid", + "quoteProps": "as-needed", + "plugins": [ + "prettier-plugin-organize-imports" + ] +} diff --git a/package-lock.json b/package-lock.json index d777b1d..f18fd74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,39 +10,41 @@ "license": "Apache-2.0", "dependencies": { "@iobroker/adapter-core": "^3.1.6", - "@iobroker/dm-utils": "^0.2.2", + "@iobroker/dm-utils": "^0.3.1", "@iobroker/type-detector": "^3.0.5", - "@project-chip/matter-node.js": "0.10.0-alpha.0-20240707-ccb2eb3c", - "@project-chip/matter.js": "0.10.0-alpha.0-20240707-ccb2eb3c", + "@project-chip/matter-node.js": "0.10.0-alpha.0-20240720-471dea8c", + "@project-chip/matter.js": "0.10.0-alpha.0-20240720-471dea8c", "axios": "^1.7.2", "jsonwebtoken": "^9.0.2" }, "devDependencies": { - "@alcalzone/release-script": "^3.7.0", + "@alcalzone/release-script": "^3.7.3", "@alcalzone/release-script-plugin-iobroker": "^3.7.2", "@alcalzone/release-script-plugin-license": "^3.7.0", "@iobroker/dev-server": "^0.7.3", "@iobroker/legacy-testing": "^1.0.12", - "@iobroker/types": "^6.0.5", + "@iobroker/types": "^6.0.9", "@types/jsonwebtoken": "^9.0.6", - "@types/node": "^20.14.9", - "@typescript-eslint/eslint-plugin": "^7.14.1", + "@types/node": "^20.14.11", + "@typescript-eslint/eslint-plugin": "^7.16.1", "chai": "^4.4.1", "colorette": "^2.0.20", "eslint": "^8.57.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-n": "^17.9.0", - "eslint-plugin-promise": "^6.2.0", + "eslint-plugin-promise": "^6.5.1", "gulp": "^4.0.2", - "mocha": "^10.5.1", - "puppeteer": "^22.12.1", - "typescript": "~5.5.2" + "mocha": "^10.6.0", + "prettier": "^3.3.3", + "prettier-plugin-organize-imports": "^4.0.0", + "puppeteer": "^22.13.1", + "typescript": "~5.5.3" }, "engines": { "node": ">=16" }, "optionalDependencies": { - "@project-chip/matter-node-ble.js": "0.10.0-alpha.0-20240707-ccb2eb3c" + "@project-chip/matter-node-ble.js": "0.10.0-alpha.0-20240720-471dea8c" } }, "node_modules/@alcalzone/pak": { @@ -534,9 +536,9 @@ } }, "node_modules/@iobroker/dm-utils": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@iobroker/dm-utils/-/dm-utils-0.2.2.tgz", - "integrity": "sha512-DV8Br0nxA7ZhfTUWCyCINVp/7EcrlAJQ+YvN7Mabll71YEWlxXBj7aEq8qIHqz0Zhp3L5wS680QiedtCRVEsWQ==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@iobroker/dm-utils/-/dm-utils-0.3.1.tgz", + "integrity": "sha512-9zlBAtJfIEMdZKySfIutKBIKpxWoCzmZMaFyIDejob0E2u0scV/f20JKLeSBLDzv3XBJDfes3Icmtvevi3HHog==", "dependencies": { "@iobroker/adapter-core": "^3.1.6" } @@ -573,9 +575,9 @@ "integrity": "sha512-2tGGFXBcM+IH4ChUZWDIYESpf5ZkS0SY8po9pT2Ng8Y2n4lJT7U/mA7p72wS//D1GWERnaseH3RNVBwlWXSdQw==" }, "node_modules/@iobroker/types": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/@iobroker/types/-/types-6.0.6.tgz", - "integrity": "sha512-h7blSGvRR0pZp5XmmC2n74xlY5W9wnugbb9vi+cv9wrCdGdN+MORiEDgwZ2o5ex6cRsitCd8EtqgpTYUc8bBIA==", + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@iobroker/types/-/types-6.0.9.tgz", + "integrity": "sha512-8+u5c/cawj5cmnQaW95TJv1vBMs68GaepPko7urvylGfixPE/vJ0nwNq392v67B52PwHPi41kctmR9gNt9M+tw==", "engines": { "node": ">=12.0.0" } @@ -830,27 +832,27 @@ } }, "node_modules/@project-chip/matter-node-ble.js": { - "version": "0.10.0-alpha.0-20240707-ccb2eb3c", - "resolved": "https://registry.npmjs.org/@project-chip/matter-node-ble.js/-/matter-node-ble.js-0.10.0-alpha.0-20240707-ccb2eb3c.tgz", - "integrity": "sha512-9FievRgY8/9XKb+aBldIb8A0P9MWdb4LOF/uYgTBrwbGAup/yIFhXwTd/eo9jLkmEWhAPo+eGgi2mowmAKSX3g==", + "version": "0.10.0-alpha.0-20240720-471dea8c", + "resolved": "https://registry.npmjs.org/@project-chip/matter-node-ble.js/-/matter-node-ble.js-0.10.0-alpha.0-20240720-471dea8c.tgz", + "integrity": "sha512-ojJJgLMvGpOaWHqcg5UGRuXxtd2tnRhATcPQDFi7qNCj3rXDEGg+tdpa592npRGY6+cxMOQZtdC17E3qNrCGOQ==", "optional": true, "dependencies": { - "@project-chip/matter.js": "0.10.0-alpha.0-20240707-ccb2eb3c" + "@project-chip/matter.js": "0.10.0-alpha.0-20240720-471dea8c" }, "engines": { "node": ">=16.0.0" }, "optionalDependencies": { "@stoprocent/bleno": "^0.7.6", - "@stoprocent/noble": "^1.13.6" + "@stoprocent/noble": "^1.14.1" } }, "node_modules/@project-chip/matter-node.js": { - "version": "0.10.0-alpha.0-20240707-ccb2eb3c", - "resolved": "https://registry.npmjs.org/@project-chip/matter-node.js/-/matter-node.js-0.10.0-alpha.0-20240707-ccb2eb3c.tgz", - "integrity": "sha512-Iv+TmDkyZc437N5Df4tE1CaKiH888fPMOvpIyh3RrfpQwxJcmCUvcp2lWnSHZx5hwjIenO2pcin1xfYvMHShgQ==", + "version": "0.10.0-alpha.0-20240720-471dea8c", + "resolved": "https://registry.npmjs.org/@project-chip/matter-node.js/-/matter-node.js-0.10.0-alpha.0-20240720-471dea8c.tgz", + "integrity": "sha512-jYDlhAXxH01nOkoRY7wPqbqymx2vtw/5fBvPvCNK0dr5d70H1jm1pbGtXdG1/E1xexv0aPkX+lxBImkk08J/nw==", "dependencies": { - "@project-chip/matter.js": "0.10.0-alpha.0-20240707-ccb2eb3c", + "@project-chip/matter.js": "0.10.0-alpha.0-20240720-471dea8c", "node-localstorage": "^3.0.5" }, "engines": { @@ -859,27 +861,27 @@ } }, "node_modules/@project-chip/matter.js": { - "version": "0.10.0-alpha.0-20240707-ccb2eb3c", - "resolved": "https://registry.npmjs.org/@project-chip/matter.js/-/matter.js-0.10.0-alpha.0-20240707-ccb2eb3c.tgz", - "integrity": "sha512-fXvkxNGyPtft5d8/2HivB52l77ldzmEuR+bFZVz/+3e8cSKWaUDl2yOY0iCb3GJAob/Lu7+f/UNuf8tVbRa3dw==", + "version": "0.10.0-alpha.0-20240720-471dea8c", + "resolved": "https://registry.npmjs.org/@project-chip/matter.js/-/matter.js-0.10.0-alpha.0-20240720-471dea8c.tgz", + "integrity": "sha512-6HrSsoR4CbjfPxvJNsPDH+lG3tgUJouFDZ7F2OrQwn5NCDm/AaJZbfLi89FX9XdK/vqB3YWE6yNQjUmKfEjMCQ==", "dependencies": { - "@noble/curves": "^1.4.0" + "@noble/curves": "^1.4.2" } }, "node_modules/@puppeteer/browsers": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.3.tgz", - "integrity": "sha512-bJ0UBsk0ESOs6RFcLXOt99a3yTDcOKlzfjad+rhFwdaG1Lu/Wzq58GHYCDTlZ9z6mldf4g+NTb+TXEfe0PpnsQ==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.4.tgz", + "integrity": "sha512-BdG2qiI1dn89OTUUsx2GZSpUzW+DRffR1wlMJyKxVHYrhnKoELSDxDd+2XImUkuWPEKk76H5FcM/gPFrEK1Tfw==", "dev": true, "dependencies": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "progress": "2.0.3", - "proxy-agent": "6.4.0", - "semver": "7.6.0", - "tar-fs": "3.0.5", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.2" + "debug": "^4.3.5", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.4.0", + "semver": "^7.6.2", + "tar-fs": "^3.0.6", + "unbzip2-stream": "^1.4.3", + "yargs": "^17.7.2" }, "bin": { "browsers": "lib/cjs/main-cli.js" @@ -888,50 +890,6 @@ "node": ">=18" } }, - "node_modules/@puppeteer/browsers/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@puppeteer/browsers/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@puppeteer/browsers/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@serialport/binding-mock": { "version": "10.2.2", "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz", @@ -1365,9 +1323,9 @@ } }, "node_modules/@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "version": "20.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", + "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -1384,16 +1342,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz", - "integrity": "sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", + "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/type-utils": "7.15.0", - "@typescript-eslint/utils": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/type-utils": "7.16.1", + "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -1416,6 +1374,53 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "7.15.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.15.0.tgz", @@ -1450,6 +1455,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz", "integrity": "sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/types": "7.15.0", "@typescript-eslint/visitor-keys": "7.15.0" @@ -1463,13 +1469,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.15.0.tgz", - "integrity": "sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", + "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.15.0", - "@typescript-eslint/utils": "7.15.0", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/utils": "7.16.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -1489,11 +1495,70 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { "version": "7.15.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.15.0.tgz", "integrity": "sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==", "dev": true, + "peer": true, "engines": { "node": "^18.18.0 || >=20.0.0" }, @@ -1507,6 +1572,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.15.0.tgz", "integrity": "sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/types": "7.15.0", "@typescript-eslint/visitor-keys": "7.15.0", @@ -1531,15 +1597,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.15.0.tgz", - "integrity": "sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/typescript-estree": "7.15.0" + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1552,11 +1618,87 @@ "eslint": "^8.56.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "7.15.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.15.0.tgz", "integrity": "sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/types": "7.15.0", "eslint-visitor-keys": "^3.4.3" @@ -3012,9 +3154,9 @@ } }, "node_modules/chromium-bidi": { - "version": "0.5.24", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.24.tgz", - "integrity": "sha512-5xQNN2SVBdZv4TxeMLaI+PelrnZsHDhn8h2JtyriLr+0qHcZS8BMuo93qN6J1VmtmrgYP+rmcLHcbpnA8QJh+w==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.1.tgz", + "integrity": "sha512-kSxJRj0VgtUKz6nmzc2JPfyfJGzwzt65u7PqhPHtgGQUZLF5oG+ST6l6e5ONfStUMAlhSutFCjaGKllXZa16jA==", "dev": true, "dependencies": { "mitt": "3.0.1", @@ -4723,9 +4865,9 @@ } }, "node_modules/eslint-plugin-promise": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.4.0.tgz", - "integrity": "sha512-/KWWRaD3fGkVCZsdR0RU53PSthFmoHVhZl+y9+6DqeDLSikLdlUVpVEAmI6iCRR5QyOjBYBqHZV/bdv4DJ4Gtw==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.5.1.tgz", + "integrity": "sha512-KEYBjj9nCynXAquwKrYEnIJ1zK+e+O5jqwn/9Aln/FhdOXm6WwsmCVatDM6OAxkEzbigsyD79Fi3DUWWqulTEA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -10247,6 +10389,41 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-organize-imports": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-4.0.0.tgz", + "integrity": "sha512-vnKSdgv9aOlqKeEFGhf9SCBsTyzDSyScy1k7E0R1Uo4L0cTcOV7c1XQaT7jfXIOc/p08WLBfN2QUQA9zDSZMxA==", + "dev": true, + "peerDependencies": { + "@vue/language-plugin-pug": "^2.0.24", + "prettier": ">=2.0", + "typescript": ">=2.9", + "vue-tsc": "^2.0.24" + }, + "peerDependenciesMeta": { + "@vue/language-plugin-pug": { + "optional": true + }, + "vue-tsc": { + "optional": true + } + } + }, "node_modules/pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", @@ -10395,16 +10572,16 @@ } }, "node_modules/puppeteer": { - "version": "22.12.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.12.1.tgz", - "integrity": "sha512-1GxY8dnEnHr1SLzdSDr0FCjM6JQfAh2E2I/EqzeF8a58DbGVk9oVjj4lFdqNoVbpgFSpAbz7VER9St7S1wDpNg==", + "version": "22.13.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.13.1.tgz", + "integrity": "sha512-PwXLDQK5u83Fm5A7TGMq+9BR7iHDJ8a3h21PSsh/E6VfhxiKYkU7+tvGZNSCap6k3pCNDd9oNteVBEctcBalmQ==", "dev": true, "hasInstallScript": true, "dependencies": { - "@puppeteer/browsers": "2.2.3", + "@puppeteer/browsers": "2.2.4", "cosmiconfig": "^9.0.0", "devtools-protocol": "0.0.1299070", - "puppeteer-core": "22.12.1" + "puppeteer-core": "22.13.1" }, "bin": { "puppeteer": "lib/esm/puppeteer/node/cli.js" @@ -10414,16 +10591,16 @@ } }, "node_modules/puppeteer-core": { - "version": "22.12.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.12.1.tgz", - "integrity": "sha512-XmqeDPVdC5/3nGJys1jbgeoZ02wP0WV1GBlPtr/ULRbGXJFuqgXMcKQ3eeNtFpBzGRbpeoCGWHge1ZWKWl0Exw==", + "version": "22.13.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.13.1.tgz", + "integrity": "sha512-NmhnASYp51QPRCAf9n0OPxuPMmzkKd8+2sB9Q+BjwwCG25gz6iuNc3LQDWa+cH2tyivmJppLhNNFt6Q3HmoOpw==", "dev": true, "dependencies": { - "@puppeteer/browsers": "2.2.3", - "chromium-bidi": "0.5.24", + "@puppeteer/browsers": "2.2.4", + "chromium-bidi": "0.6.1", "debug": "^4.3.5", "devtools-protocol": "0.0.1299070", - "ws": "^8.17.1" + "ws": "^8.18.0" }, "engines": { "node": ">=18" @@ -12362,9 +12539,9 @@ } }, "node_modules/tar-fs": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.5.tgz", - "integrity": "sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", "dev": true, "dependencies": { "pump": "^3.0.0", @@ -12396,9 +12573,9 @@ } }, "node_modules/text-decoder": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", - "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.1.tgz", + "integrity": "sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==", "dev": true, "dependencies": { "b4a": "^1.6.4" @@ -13464,7 +13641,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true + "optional": true }, "node_modules/yargs": { "version": "17.7.2", diff --git a/package.json b/package.json index 9721cf2..05df4ed 100644 --- a/package.json +++ b/package.json @@ -19,37 +19,39 @@ "url": "https://github.com/ioBroker/ioBroker.matter" }, "optionalDependencies": { - "@project-chip/matter-node-ble.js": "0.10.0-alpha.0-20240707-ccb2eb3c" + "@project-chip/matter-node-ble.js": "0.10.0-alpha.0-20240720-471dea8c" }, "dependencies": { "@iobroker/adapter-core": "^3.1.6", - "@project-chip/matter.js": "0.10.0-alpha.0-20240707-ccb2eb3c", - "@project-chip/matter-node.js": "0.10.0-alpha.0-20240707-ccb2eb3c", + "@project-chip/matter.js": "0.10.0-alpha.0-20240720-471dea8c", + "@project-chip/matter-node.js": "0.10.0-alpha.0-20240720-471dea8c", "@iobroker/type-detector": "^3.0.5", - "@iobroker/dm-utils": "^0.2.2", + "@iobroker/dm-utils": "^0.3.1", "axios": "^1.7.2", "jsonwebtoken": "^9.0.2" }, "devDependencies": { - "@alcalzone/release-script": "^3.7.0", + "@alcalzone/release-script": "^3.7.3", "@alcalzone/release-script-plugin-iobroker": "^3.7.2", "@alcalzone/release-script-plugin-license": "^3.7.0", - "@iobroker/types": "^6.0.5", + "@iobroker/types": "^6.0.9", "@iobroker/dev-server": "^0.7.3", "@iobroker/legacy-testing": "^1.0.12", "@types/jsonwebtoken": "^9.0.6", - "@types/node": "^20.14.9", + "@types/node": "^20.14.11", "colorette": "^2.0.20", - "puppeteer": "^22.12.1", - "@typescript-eslint/eslint-plugin": "^7.14.1", + "puppeteer": "^22.13.1", + "@typescript-eslint/eslint-plugin": "^7.16.1", "chai": "^4.4.1", "eslint": "^8.57.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-n": "^17.9.0", - "eslint-plugin-promise": "^6.2.0", + "eslint-plugin-promise": "^6.5.1", "gulp": "^4.0.2", - "mocha": "^10.5.1", - "typescript": "~5.5.2" + "mocha": "^10.6.0", + "prettier": "^3.3.3", + "prettier-plugin-organize-imports": "^4.0.0", + "typescript": "~5.5.3" }, "bugs": { "url": "https://github.com/ioBroker/ioBroker.matter/issues" @@ -76,7 +78,8 @@ "release-major": "release-script major --yes", "update-packages": "ncu --upgrade && cd src-admin && ncu --upgrade", "npm": "npm i && cd src-admin && npm i", - "dev-server": "dev-server" + "dev-server": "dev-server", + "format": "prettier --write 'src/**/*.ts'" }, "license": "Apache-2.0", "readmeFilename": "README.md" diff --git a/src/lib/DeviceFactory.ts b/src/lib/DeviceFactory.ts index 51eed5e..c99581e 100644 --- a/src/lib/DeviceFactory.ts +++ b/src/lib/DeviceFactory.ts @@ -1,5 +1,5 @@ -import GenericDevice, { DetectedDevice, DeviceOptions } from './devices/GenericDevice'; import { Types } from '@iobroker/type-detector'; +import GenericDevice, { DetectedDevice, DeviceOptions } from './devices/GenericDevice'; import AirCondition from './devices/AirCondition'; import Blind from './devices/Blind'; @@ -7,39 +7,38 @@ import BlindButtons from './devices/BlindButtons'; import Button from './devices/Button'; import ButtonSensor from './devices/ButtonSensor'; import Camera from './devices/Camera'; -import Image from './devices/Image'; import Chart from './devices/Chart'; +import Cie from './devices/Cie'; +import Ct from './devices/Ct'; import Dimmer from './devices/Dimmer'; import Door from './devices/Door'; import FireAlarm from './devices/FireAlarm'; import FloodAlarm from './devices/FloodAlarm'; import Gate from './devices/Gate'; +import Hue from './devices/Hue'; import Humidity from './devices/Humidity'; +import Image from './devices/Image'; import Info from './devices/Info'; import Light from './devices/Light'; -import Lock from './devices/Lock'; import Location from './devices/Location'; +import Lock from './devices/Lock'; import Media from './devices/Media'; import Motion from './devices/Motion'; import Rgb from './devices/Rgb'; -import Ct from './devices/Ct'; import RgbSingle from './devices/RgbSingle'; import RgbwSingle from './devices/RgbwSingle'; -import Hue from './devices/Hue'; -import Cie from './devices/Cie'; import Slider from './devices/Slider'; import Socket from './devices/Socket'; import Temperature from './devices/Temperature'; import Thermostat from './devices/Thermostat'; -import Volume from './devices/Volume'; import VacuumCleaner from './devices/VacuumCleaner'; +import Volume from './devices/Volume'; import VolumeGroup from './devices/VolumeGroup'; -import Window from './devices/Window'; -import WindowTilt from './devices/WindowTilt'; +import Warning from './devices/Warning'; import WeatherCurrent from './devices/WeatherCurrent'; import WeatherForecast from './devices/WeatherForecast'; -import Warning from './devices/Warning'; - +import Window from './devices/Window'; +import WindowTilt from './devices/WindowTilt'; const types: { [key in Types]: any } = { [Types.airCondition]: AirCondition, diff --git a/src/lib/DeviceManagement.ts b/src/lib/DeviceManagement.ts index ef74107..0acf267 100644 --- a/src/lib/DeviceManagement.ts +++ b/src/lib/DeviceManagement.ts @@ -1,15 +1,16 @@ import { MatterAdapter } from '../main'; import { - DeviceManagement, - DeviceInfo, - DeviceStatus, ActionContext, + ControlState, DeviceDetails, - DeviceRefresh, ErrorResponse, + DeviceInfo, + DeviceManagement, + DeviceRefresh, + DeviceStatus, + ErrorResponse, } from '@iobroker/dm-utils'; -import { ControlState } from '@iobroker/dm-utils'; -import { t, getText } from './i18n'; +import { getText, t } from './i18n'; const demoDevice = { id: 'my ID', @@ -45,7 +46,7 @@ class MatterAdapterDeviceManagement extends DeviceManagement { id: device._id, name: device.common.name, icon: device.common.icon || undefined, - manufacturer: manufacturer?.val as string || undefined, + manufacturer: (manufacturer?.val as string) || undefined, model: model || undefined, status, hasDetails: true, @@ -54,21 +55,21 @@ class MatterAdapterDeviceManagement extends DeviceManagement { id: 'delete', icon: 'fa-solid fa-trash-can', description: t('Delete this device'), - handler: this.handleDeleteDevice.bind(this) + handler: this.handleDeleteDevice.bind(this), }, { id: 'rename', icon: 'fa-solid fa-pen', description: t('Rename this device'), - handler: this.handleRenameDevice.bind(this) + handler: this.handleRenameDevice.bind(this), }, { id: 'pairingCode', icon: 'fa-solid fa-qrcode', description: t('Generate new pairing code'), - handler: this.handlePairingCode.bind(this) - } - ] + handler: this.handlePairingCode.bind(this), + }, + ], }; // if id contains gateway remove res.actions if (device._id.includes('localhost')) { @@ -153,24 +154,29 @@ class MatterAdapterDeviceManagement extends DeviceManagement { async handleRenameDevice(id: string, context: ActionContext): Promise<{ refresh: DeviceRefresh }> { this.adapter.log.info(`Rename device ${id}`); const devices = await this.adapter.getDevicesAsync(); - const device = devices.find((dev) => dev._id === id); + const device = devices.find(dev => dev._id === id); if (device || id === demoDevice.id) { - const result = await context.showForm({ - type: 'panel', - items: { - name: { - type: 'text', - label: t('Name'), - sm: 12, + const result = await context.showForm( + { + type: 'panel', + items: { + name: { + type: 'text', + label: t('Name'), + sm: 12, + }, }, }, - }, - { - data: { - name: id === demoDevice.id ? 'My Name' : getText(device?.common.name || '', this.adapter.sysLanguage), + { + data: { + name: + id === demoDevice.id + ? 'My Name' + : getText(device?.common.name || '', this.adapter.sysLanguage), + }, + title: t('Rename device'), }, - title: t('Rename device') - }); + ); if (result?.name !== undefined) { if (id === demoDevice.id) { @@ -192,7 +198,7 @@ class MatterAdapterDeviceManagement extends DeviceManagement { async handleDeleteDevice(id: string, context: ActionContext): Promise<{ refresh: DeviceRefresh }> { this.adapter.log.info(`Delete device ${id}`); - if (!await context.showConfirmation(t('Are you sure?'))) { + if (!(await context.showConfirmation(t('Are you sure?')))) { return { refresh: false }; } diff --git a/src/lib/devices/AirCondition.ts b/src/lib/devices/AirCondition.ts index 8e9de78..393878f 100644 --- a/src/lib/devices/AirCondition.ts +++ b/src/lib/devices/AirCondition.ts @@ -1,10 +1,10 @@ import GenericDevice, { DetectedDevice, + DeviceOptions, DeviceStateObject, PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; enum AirConditionerMode { @@ -46,17 +46,67 @@ class AirCondition extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'SET', valueType: ValueType.NumberMinMax, accessType: StateAccessType.ReadWrite, type: PropertyType.Level, callback: state => this._levelState = state }, - - { name: 'ACTUAL', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Temperature, callback: state => this._getTemperatureState = state }, - { name: 'POWER', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Power, callback: state => this._powerState = state }, - { name: 'HUMIDITY', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Humidity, callback: state => this._getHumidityState = state }, - { name: 'SPEED', valueType: ValueType.Enum, accessType: StateAccessType.ReadWrite, type: PropertyType.Speed, callback: state => this._speedState = state }, - { name: 'BOOST', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Boost, callback: state => this._boostState = state }, - { name: 'SWING', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Swing, callback: state => this._SwingState = state }, - { name: 'MODE', valueType: ValueType.Enum, accessType: StateAccessType.ReadWrite, type: PropertyType.Mode, callback: state => this._modeState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'SET', + valueType: ValueType.NumberMinMax, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Level, + callback: state => (this._levelState = state), + }, + + { + name: 'ACTUAL', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Temperature, + callback: state => (this._getTemperatureState = state), + }, + { + name: 'POWER', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Power, + callback: state => (this._powerState = state), + }, + { + name: 'HUMIDITY', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Humidity, + callback: state => (this._getHumidityState = state), + }, + { + name: 'SPEED', + valueType: ValueType.Enum, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Speed, + callback: state => (this._speedState = state), + }, + { + name: 'BOOST', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Boost, + callback: state => (this._boostState = state), + }, + { + name: 'SWING', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Swing, + callback: state => (this._SwingState = state), + }, + { + name: 'MODE', + valueType: ValueType.Enum, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Mode, + callback: state => (this._modeState = state), + }, + ]), + ); } getLevel(): number | undefined { @@ -122,7 +172,7 @@ class AirCondition extends GenericDevice { return this._speedState.value; } - async setSpeed(value: AirConditionerSpeed):Promise { + async setSpeed(value: AirConditionerSpeed): Promise { if (!this._speedState) { throw new Error('Speed state not found'); } @@ -179,4 +229,4 @@ class AirCondition extends GenericDevice { } } -export default AirCondition; \ No newline at end of file +export default AirCondition; diff --git a/src/lib/devices/Blind.ts b/src/lib/devices/Blind.ts index 443c1a8..175bd1d 100644 --- a/src/lib/devices/Blind.ts +++ b/src/lib/devices/Blind.ts @@ -1,11 +1,11 @@ import BlindButtons from './BlindButtons'; import { DetectedDevice, + DeviceOptions, DeviceStateObject, PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Blind extends BlindButtons { @@ -15,11 +15,25 @@ class Blind extends BlindButtons { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - // actual value first, as it will be read first - { name: 'ACTUAL', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Level, callback: state => this._getLevelState = state }, - { name: 'SET', valueType: ValueType.NumberPercent, accessType: StateAccessType.ReadWrite, type: PropertyType.Level, callback: state => this._setLevelState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + // actual value first, as it will be read first + { + name: 'ACTUAL', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Level, + callback: state => (this._getLevelState = state), + }, + { + name: 'SET', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Level, + callback: state => (this._setLevelState = state), + }, + ]), + ); } getLevel(): number | undefined { @@ -37,4 +51,4 @@ class Blind extends BlindButtons { } } -export default Blind; \ No newline at end of file +export default Blind; diff --git a/src/lib/devices/BlindButtons.ts b/src/lib/devices/BlindButtons.ts index 74b406c..4f74b9d 100644 --- a/src/lib/devices/BlindButtons.ts +++ b/src/lib/devices/BlindButtons.ts @@ -1,10 +1,10 @@ import GenericDevice, { DetectedDevice, + DeviceOptions, DeviceStateObject, PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; /* @@ -39,17 +39,67 @@ class BlindButtons extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'STOP', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.Stop, callback: state => this._setStopState = state }, - { name: 'OPEN', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.Open, callback: state => this._setOpenState = state }, - { name: 'CLOSE', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.Close, callback: state => this._setCloseState = state }, - // actual value first, as it will be read first - { name: 'TILT_ACTUAL', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.TiltLevel, callback: state => this._getTiltState = state }, - { name: 'TILT_SET', valueType: ValueType.NumberPercent, accessType: StateAccessType.ReadWrite, type: PropertyType.TiltLevel, callback: state => this._setTiltState = state }, - { name: 'TILT_STOP', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.TiltStop, callback: state => this._setTiltStopState = state }, - { name: 'TILT_OPEN', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.TiltOpen, callback: state => this._setTiltOpenState = state }, - { name: 'TILT_CLOSE', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.TiltClose, callback: state => this._setTiltCloseState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'STOP', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.Stop, + callback: state => (this._setStopState = state), + }, + { + name: 'OPEN', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.Open, + callback: state => (this._setOpenState = state), + }, + { + name: 'CLOSE', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.Close, + callback: state => (this._setCloseState = state), + }, + // actual value first, as it will be read first + { + name: 'TILT_ACTUAL', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.TiltLevel, + callback: state => (this._getTiltState = state), + }, + { + name: 'TILT_SET', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.ReadWrite, + type: PropertyType.TiltLevel, + callback: state => (this._setTiltState = state), + }, + { + name: 'TILT_STOP', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.TiltStop, + callback: state => (this._setTiltStopState = state), + }, + { + name: 'TILT_OPEN', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.TiltOpen, + callback: state => (this._setTiltOpenState = state), + }, + { + name: 'TILT_CLOSE', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.TiltClose, + callback: state => (this._setTiltCloseState = state), + }, + ]), + ); } async setStop(): Promise { @@ -109,4 +159,4 @@ class BlindButtons extends GenericDevice { } } -export default BlindButtons; \ No newline at end of file +export default BlindButtons; diff --git a/src/lib/devices/Button.ts b/src/lib/devices/Button.ts index 20f2057..b212888 100644 --- a/src/lib/devices/Button.ts +++ b/src/lib/devices/Button.ts @@ -1,10 +1,10 @@ import GenericDevice, { DetectedDevice, + DeviceOptions, DeviceStateObject, PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Button extends GenericDevice { @@ -13,9 +13,17 @@ class Button extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'SET', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.Press, callback: state => this._setPressState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'SET', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.Press, + callback: state => (this._setPressState = state), + }, + ]), + ); } async setPress(): Promise { @@ -26,4 +34,4 @@ class Button extends GenericDevice { } } -export default Button; \ No newline at end of file +export default Button; diff --git a/src/lib/devices/ButtonSensor.ts b/src/lib/devices/ButtonSensor.ts index a4a89c5..8d7329e 100644 --- a/src/lib/devices/ButtonSensor.ts +++ b/src/lib/devices/ButtonSensor.ts @@ -1,10 +1,10 @@ import GenericDevice, { DetectedDevice, + DeviceOptions, DeviceStateObject, PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class ButtonSensor extends GenericDevice { @@ -14,10 +14,24 @@ class ButtonSensor extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'PRESS', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.Press, callback: state => this._setPressState = state }, - { name: 'PRESS_LONG', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.PressLong, callback: state => this._setPressLongState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'PRESS', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.Press, + callback: state => (this._setPressState = state), + }, + { + name: 'PRESS_LONG', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.PressLong, + callback: state => (this._setPressLongState = state), + }, + ]), + ); } async setPress(): Promise { @@ -35,4 +49,4 @@ class ButtonSensor extends GenericDevice { } } -export default ButtonSensor; \ No newline at end of file +export default ButtonSensor; diff --git a/src/lib/devices/Camera.ts b/src/lib/devices/Camera.ts index 145b710..7ab6378 100644 --- a/src/lib/devices/Camera.ts +++ b/src/lib/devices/Camera.ts @@ -1,10 +1,10 @@ import GenericDevice, { DetectedDevice, + DeviceOptions, DeviceStateObject, PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; /* @@ -27,14 +27,52 @@ class Camera extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'FILE', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.File, callback: state => this._getFileState = state }, - { name: 'AUTOFOCUS', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.AutoFocus, callback: state => this._autoFocusState = state }, - { name: 'AUTOWHITEBALANCE', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.AutoWhiteBalance, callback: state => this._autoWhiteBalanceState = state }, - { name: 'BRIGHTNESS', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Brightness, callback: state => this._brightnessState = state }, - { name: 'NIGHTMODE', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.NightMode, callback: state => this._nightModeState = state }, - { name: 'PTZ', valueType: ValueType.Number, accessType: StateAccessType.ReadWrite, type: PropertyType.PTZ, callback: state => this._ptzState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'FILE', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.File, + callback: state => (this._getFileState = state), + }, + { + name: 'AUTOFOCUS', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.AutoFocus, + callback: state => (this._autoFocusState = state), + }, + { + name: 'AUTOWHITEBALANCE', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.AutoWhiteBalance, + callback: state => (this._autoWhiteBalanceState = state), + }, + { + name: 'BRIGHTNESS', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Brightness, + callback: state => (this._brightnessState = state), + }, + { + name: 'NIGHTMODE', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.NightMode, + callback: state => (this._nightModeState = state), + }, + { + name: 'PTZ', + valueType: ValueType.Number, + accessType: StateAccessType.ReadWrite, + type: PropertyType.PTZ, + callback: state => (this._ptzState = state), + }, + ]), + ); } getFile(): string | undefined { @@ -115,4 +153,4 @@ class Camera extends GenericDevice { } } -export default Camera; \ No newline at end of file +export default Camera; diff --git a/src/lib/devices/Chart.ts b/src/lib/devices/Chart.ts index e13e0c7..c0fb2ae 100644 --- a/src/lib/devices/Chart.ts +++ b/src/lib/devices/Chart.ts @@ -1,7 +1,5 @@ import GenericDevice from './GenericDevice'; -class Chart extends GenericDevice { +class Chart extends GenericDevice {} -} - -export default Chart; \ No newline at end of file +export default Chart; diff --git a/src/lib/devices/Cie.ts b/src/lib/devices/Cie.ts index bcd0c1b..2aba4c5 100644 --- a/src/lib/devices/Cie.ts +++ b/src/lib/devices/Cie.ts @@ -1,11 +1,11 @@ import Ct from './Ct'; import { DetectedDevice, + DeviceOptions, DeviceStateObject, PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Cie extends Ct { @@ -15,9 +15,17 @@ class Cie extends Ct { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'CIE', valueType: ValueType.String, accessType: StateAccessType.ReadWrite, type: PropertyType.Cie, callback: state => this._cie = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'CIE', + valueType: ValueType.String, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Cie, + callback: state => (this._cie = state), + }, + ]), + ); } getCie(): string | undefined { @@ -33,7 +41,6 @@ class Cie extends Ct { } return this._cie.setValue(value); } - } -export default Cie; \ No newline at end of file +export default Cie; diff --git a/src/lib/devices/Ct.ts b/src/lib/devices/Ct.ts index 45a735b..f7ad646 100644 --- a/src/lib/devices/Ct.ts +++ b/src/lib/devices/Ct.ts @@ -1,10 +1,10 @@ import GenericDevice, { DetectedDevice, + DeviceOptions, DeviceStateObject, PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Ct extends GenericDevice { @@ -18,15 +18,53 @@ class Ct extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'DIMMER', valueType: ValueType.NumberPercent, accessType: StateAccessType.ReadWrite, type: PropertyType.Dimmer, callback: state => this._dimmer = state }, - { name: 'BRIGHTNESS', valueType: ValueType.NumberPercent, accessType: StateAccessType.ReadWrite, type: PropertyType.Brightness, callback: state => this._brightness = state }, - { name: 'SATURATION', valueType: ValueType.NumberPercent, accessType: StateAccessType.ReadWrite, type: PropertyType.Saturation, callback: state => this._saturation = state }, - { name: 'TEMPERATURE', valueType: ValueType.NumberMinMax, accessType: StateAccessType.ReadWrite, type: PropertyType.Temperature, callback: state => this._temperature = state }, - // actual value first, as it will be read first - { name: 'ON_ACTUAL', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.Power, callback: state => this._getPower = state }, - { name: 'ON', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Power, callback: state => this._setPower = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'DIMMER', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Dimmer, + callback: state => (this._dimmer = state), + }, + { + name: 'BRIGHTNESS', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Brightness, + callback: state => (this._brightness = state), + }, + { + name: 'SATURATION', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Saturation, + callback: state => (this._saturation = state), + }, + { + name: 'TEMPERATURE', + valueType: ValueType.NumberMinMax, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Temperature, + callback: state => (this._temperature = state), + }, + // actual value first, as it will be read first + { + name: 'ON_ACTUAL', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.Power, + callback: state => (this._getPower = state), + }, + { + name: 'ON', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Power, + callback: state => (this._setPower = state), + }, + ]), + ); } getDimmer(): number | undefined { @@ -100,4 +138,4 @@ class Ct extends GenericDevice { } } -export default Ct; \ No newline at end of file +export default Ct; diff --git a/src/lib/devices/Dimmer.ts b/src/lib/devices/Dimmer.ts index 525710a..7413755 100644 --- a/src/lib/devices/Dimmer.ts +++ b/src/lib/devices/Dimmer.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Dimmer extends GenericDevice { @@ -17,14 +17,40 @@ class Dimmer extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - // actual value first, as it will be read first - { name: 'ACTUAL', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Level, callback: state => this._getLevelState = state }, - { name: 'SET', valueType: ValueType.NumberPercent, accessType: StateAccessType.ReadWrite, type: PropertyType.Level, callback: state => this._setLevelState = state }, - // actual value first, as it will be read first - { name: 'ON_ACTUAL', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.Power, callback: state => this._getPowerState = state }, - { name: 'ON_SET', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Power, callback: state => this._setPowerState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + // actual value first, as it will be read first + { + name: 'ACTUAL', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Level, + callback: state => (this._getLevelState = state), + }, + { + name: 'SET', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Level, + callback: state => (this._setLevelState = state), + }, + // actual value first, as it will be read first + { + name: 'ON_ACTUAL', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.Power, + callback: state => (this._getPowerState = state), + }, + { + name: 'ON_SET', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Power, + callback: state => (this._setPowerState = state), + }, + ]), + ); } getLevel(): number | undefined { @@ -83,4 +109,4 @@ class Dimmer extends GenericDevice { } } -export default Dimmer; \ No newline at end of file +export default Dimmer; diff --git a/src/lib/devices/Door.ts b/src/lib/devices/Door.ts index 5929b5c..7e6543c 100644 --- a/src/lib/devices/Door.ts +++ b/src/lib/devices/Door.ts @@ -1,10 +1,10 @@ import GenericDevice, { DetectedDevice, + DeviceOptions, DeviceStateObject, PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Door extends GenericDevice { @@ -13,9 +13,17 @@ class Door extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'ACTUAL', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.Value, callback: state => this._getValueState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'ACTUAL', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.Value, + callback: state => (this._getValueState = state), + }, + ]), + ); } getValue(): boolean | undefined { @@ -26,4 +34,4 @@ class Door extends GenericDevice { } } -export default Door; \ No newline at end of file +export default Door; diff --git a/src/lib/devices/FireAlarm.ts b/src/lib/devices/FireAlarm.ts index ce2bc52..2d31760 100644 --- a/src/lib/devices/FireAlarm.ts +++ b/src/lib/devices/FireAlarm.ts @@ -1,10 +1,10 @@ import GenericDevice, { DetectedDevice, + DeviceOptions, DeviceStateObject, PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class FireAlarm extends GenericDevice { @@ -13,9 +13,17 @@ class FireAlarm extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'ACTUAL', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.Value, callback: state => this._getValueState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'ACTUAL', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.Value, + callback: state => (this._getValueState = state), + }, + ]), + ); } getValue(): boolean | undefined { @@ -26,4 +34,4 @@ class FireAlarm extends GenericDevice { } } -export default FireAlarm; \ No newline at end of file +export default FireAlarm; diff --git a/src/lib/devices/FloodAlarm.ts b/src/lib/devices/FloodAlarm.ts index 2f35b55..65cd5b0 100644 --- a/src/lib/devices/FloodAlarm.ts +++ b/src/lib/devices/FloodAlarm.ts @@ -1,10 +1,10 @@ import GenericDevice, { DetectedDevice, + DeviceOptions, DeviceStateObject, PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class FloodAlarm extends GenericDevice { @@ -13,9 +13,17 @@ class FloodAlarm extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'ACTUAL', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.Value, callback: state => this._getValueState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'ACTUAL', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.Value, + callback: state => (this._getValueState = state), + }, + ]), + ); } getValue(): boolean | undefined { @@ -26,4 +34,4 @@ class FloodAlarm extends GenericDevice { } } -export default FloodAlarm; \ No newline at end of file +export default FloodAlarm; diff --git a/src/lib/devices/Gate.ts b/src/lib/devices/Gate.ts index fceefed..43518ff 100644 --- a/src/lib/devices/Gate.ts +++ b/src/lib/devices/Gate.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Gate extends GenericDevice { @@ -15,12 +15,32 @@ class Gate extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - // actual value first, as it will be read first - { name: 'ACTUAL', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Level, callback: state => this._getLevelState = state }, - { name: 'SET', valueType: ValueType.NumberPercent, accessType: StateAccessType.ReadWrite, type: PropertyType.Level, callback: state => this._setLevelState = state }, - { name: 'STOP', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.Stop, callback: state => this._setStopState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + // actual value first, as it will be read first + { + name: 'ACTUAL', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Level, + callback: state => (this._getLevelState = state), + }, + { + name: 'SET', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Level, + callback: state => (this._setLevelState = state), + }, + { + name: 'STOP', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.Stop, + callback: state => (this._setStopState = state), + }, + ]), + ); } getLevel(): number | undefined { @@ -45,4 +65,4 @@ class Gate extends GenericDevice { } } -export default Gate; \ No newline at end of file +export default Gate; diff --git a/src/lib/devices/GenericDevice.ts b/src/lib/devices/GenericDevice.ts index 4804657..ff76fa0 100644 --- a/src/lib/devices/GenericDevice.ts +++ b/src/lib/devices/GenericDevice.ts @@ -215,7 +215,7 @@ export class DeviceStateObject { await this.object; } - getMinMax(): { min: number, max: number } | null { + getMinMax(): { min: number; max: number } | null { if (this.min === undefined || this.max === undefined) { return null; } @@ -230,50 +230,48 @@ export class DeviceStateObject { if (!this.object) { return; } - this.object - .then(obj => { - if (percent) { - this.min = 0; + this.object.then(obj => { + if (percent) { + this.min = 0; + this.max = 100; + this.realMin = obj?.common?.min || 0; + this.realMax = obj?.common?.max === undefined || obj?.common?.max === null ? 100 : obj?.common?.max; + this.unit = '%'; + if (obj.common.type !== 'number') { + throw new Error(`State ${this.state.id} is not a number`); + } + } else { + this.min = obj?.common?.min; + this.max = obj?.common?.max; + if (this.min !== undefined && this.max === undefined) { this.max = 100; - this.realMin = obj?.common?.min || 0; - this.realMax = obj?.common?.max === undefined || obj?.common?.max === null ? 100 : obj?.common?.max; - this.unit = '%'; - if (obj.common.type !== 'number') { - throw new Error(`State ${this.state.id} is not a number`); - } - } else { - this.min = obj?.common?.min; - this.max = obj?.common?.max; - if (this.min !== undefined && this.max === undefined) { - this.max = 100; - } else if (this.min === undefined && this.max !== undefined) { - this.max = 0; - } - this.unit = obj?.common?.unit; + } else if (this.min === undefined && this.max !== undefined) { + this.max = 0; } - }); + this.unit = obj?.common?.unit; + } + }); } protected parseMode(): void { if (!this.object) { return; } - this.modes = this.object - .then(obj => { - // {'MODE_VALUE': 'MODE_TEXT'} - let modes: { [key: string]: T } = obj?.common?.states; - if (modes) { - // convert ['Auto'] => {'Auto': 'AUTO'} - if (Array.isArray(modes)) { - const _m: { [key: string]: T } = {}; - modes.forEach((mode: T) => _m[mode as string] = ((mode as string).toUpperCase()) as T); - modes = _m; - } - return modes; - } else { - return {}; + this.modes = this.object.then(obj => { + // {'MODE_VALUE': 'MODE_TEXT'} + let modes: { [key: string]: T } = obj?.common?.states; + if (modes) { + // convert ['Auto'] => {'Auto': 'AUTO'} + if (Array.isArray(modes)) { + const _m: { [key: string]: T } = {}; + modes.forEach((mode: T) => (_m[mode as string] = (mode as string).toUpperCase() as T)); + modes = _m; } - }); + return modes; + } else { + return {}; + } + }); } async getModes(): Promise { @@ -295,7 +293,7 @@ export class DeviceStateObject { if (this.realMin !== undefined && this.realMax !== undefined) { // convert values let realValue: number = parseFloat(value as string); - realValue = ((realValue / 100) * (this.realMax - this.realMin) + this.realMin); + realValue = (realValue / 100) * (this.realMax - this.realMin) + this.realMin; if (object.common.min !== undefined && realValue < object.common.min) { throw new Error(`Value ${realValue} is less than min ${object.common.min}`); @@ -309,7 +307,13 @@ export class DeviceStateObject { // convert value if (typeof value !== valueType) { if (valueType === 'boolean') { - const realValue: boolean = value === 'true' || value === '1' || value === 1 || value === true || value === 'on' || value === 'ON'; + const realValue: boolean = + value === 'true' || + value === '1' || + value === 1 || + value === true || + value === 'on' || + value === 'ON'; await this.adapter.setForeignStateAsync(this.state.id, realValue as ioBroker.StateValue); } else if (valueType === 'number') { const realValue: number = parseFloat(value as string); @@ -352,7 +356,7 @@ export class DeviceStateObject { if (this.realMin !== undefined && this.realMax !== undefined) { // convert values const _value = parseFloat(state.val as string); - this.value = ((_value - this.realMin) / (this.realMax - this.realMin) * 100) as T; + this.value = (((_value - this.realMin) / (this.realMax - this.realMin)) * 100) as T; } else { this.value = state.val as T; } @@ -394,7 +398,7 @@ export interface DeviceStateDescription { type: PropertyType; valueType: ValueType; unit?: string; - callback: (state: DeviceStateObject | undefined) => void, + callback: (state: DeviceStateObject | undefined) => void; accessType: StateAccessType; } @@ -422,11 +426,7 @@ abstract class GenericDevice { protected _subscribeObjects: DeviceStateObject[] = []; protected _deviceType: Types; protected _detectedDevice: DetectedDevice; - protected handlers: ((event: { - property: PropertyType - value: any, - device: GenericDevice, - }) => void)[] = []; + protected handlers: ((event: { property: PropertyType; value: any; device: GenericDevice }) => void)[] = []; protected _errorState: DeviceStateObject | undefined; protected _maintenanceState: DeviceStateObject | undefined; @@ -445,14 +445,52 @@ abstract class GenericDevice { this._deviceType = detectedDevice.type; this._detectedDevice = detectedDevice; - this._ready.push(this.addDeviceStates([ - { name: 'ERROR', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.Error, callback: state => this._errorState = state }, - { name: 'MAINTAIN', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.Maintenance, callback: state => this._maintenanceState = state }, - { name: 'UNREACH', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.Unreachable, callback: state => this._unreachState = state }, - { name: 'LOWBAT', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.LowBattery, callback: state => this._lowbatState = state }, - { name: 'WORKING', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.Working, callback: state => this._workingState = state }, - { name: 'DIRECTION', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.Direction, callback: state => this._directionState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'ERROR', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.Error, + callback: state => (this._errorState = state), + }, + { + name: 'MAINTAIN', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.Maintenance, + callback: state => (this._maintenanceState = state), + }, + { + name: 'UNREACH', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.Unreachable, + callback: state => (this._unreachState = state), + }, + { + name: 'LOWBAT', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.LowBattery, + callback: state => (this._lowbatState = state), + }, + { + name: 'WORKING', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.Working, + callback: state => (this._workingState = state), + }, + { + name: 'DIRECTION', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.Direction, + callback: state => (this._directionState = state), + }, + ]), + ); } isActionAllowedByIdentify(): boolean { @@ -487,14 +525,22 @@ abstract class GenericDevice { } } else { if (this._properties[type].valueType !== valueType) { - throw new Error(`Property ${type} has already a different value type: ${this._properties[type].valueType} !== ${valueType}`); + throw new Error( + `Property ${type} has already a different value type: ${this._properties[type].valueType} !== ${valueType}`, + ); } if (accessType === StateAccessType.ReadWrite) { this._properties[type].accessType = accessType; - } else if (accessType === StateAccessType.Write && this._properties[type].accessType === StateAccessType.Read) { + } else if ( + accessType === StateAccessType.Write && + this._properties[type].accessType === StateAccessType.Read + ) { this._properties[type].accessType = StateAccessType.ReadWrite; - } else if (accessType === StateAccessType.Read && this._properties[type].accessType === StateAccessType.Write) { + } else if ( + accessType === StateAccessType.Read && + this._properties[type].accessType === StateAccessType.Write + ) { this._properties[type].accessType = StateAccessType.ReadWrite; } if (accessType === StateAccessType.Read) { @@ -509,7 +555,10 @@ abstract class GenericDevice { if (this._possibleProperties[type]) { delete this._possibleProperties[type]; } - if (this._properties[type].accessType === StateAccessType.ReadWrite || this._properties[type].accessType === StateAccessType.Read) { + if ( + this._properties[type].accessType === StateAccessType.ReadWrite || + this._properties[type].accessType === StateAccessType.Read + ) { const stateId = object?.getIoBrokerState().id; // subscribe and read only if not already subscribed if (stateId && !this._subscribeObjects.find(obj => obj.state.id === stateId)) { @@ -532,9 +581,15 @@ abstract class GenericDevice { } else { if (accessType === StateAccessType.ReadWrite) { this._possibleProperties[type].accessType = accessType; - } else if (accessType === StateAccessType.Write && this._possibleProperties[type].accessType === StateAccessType.Read) { + } else if ( + accessType === StateAccessType.Write && + this._possibleProperties[type].accessType === StateAccessType.Read + ) { this._possibleProperties[type].accessType = StateAccessType.ReadWrite; - } else if (accessType === StateAccessType.Read && this._possibleProperties[type].accessType === StateAccessType.Write) { + } else if ( + accessType === StateAccessType.Read && + this._possibleProperties[type].accessType === StateAccessType.Write + ) { this._possibleProperties[type].accessType = StateAccessType.ReadWrite; } } @@ -549,7 +604,13 @@ abstract class GenericDevice { async addDeviceStates(states: DeviceStateDescription[]): Promise { for (let i = 0; i < states.length; i++) { // we cannot give the whole object as it must be cast to T - await this.addDeviceState(states[i].name, states[i].type, states[i].callback, states[i].accessType, states[i].valueType); + await this.addDeviceState( + states[i].name, + states[i].type, + states[i].callback, + states[i].accessType, + states[i].valueType, + ); } } @@ -578,7 +639,9 @@ abstract class GenericDevice { // @ts-expect-error How to fix it? await this[method](value); } else { - throw new Error(`Method _setPropertyValue for ${property} and ${value} is not implemented in ${this.constructor.name}`); + throw new Error( + `Method _setPropertyValue for ${property} and ${value} is not implemented in ${this.constructor.name}`, + ); } } @@ -587,11 +650,13 @@ abstract class GenericDevice { } protected updateState = (object: DeviceStateObject): void => { - this.handlers.forEach(handler => handler({ - property: object.propertyType, - value: object.value, - device: this, - })); + this.handlers.forEach(handler => + handler({ + property: object.propertyType, + value: object.value, + device: this, + }), + ); }; protected async _doUnsubscribe(): Promise { @@ -672,17 +737,11 @@ abstract class GenericDevice { return this._directionState.value; } - onChange(handler: (event: { - property: PropertyType - value: T - }) => void): void { + onChange(handler: (event: { property: PropertyType; value: T }) => void): void { this.handlers.push(handler); } - offChange(handler: (event: { - property: PropertyType - value: T - }) => void): void { + offChange(handler: (event: { property: PropertyType; value: T }) => void): void { if (!handler) { this.handlers = []; } else { diff --git a/src/lib/devices/Hue.ts b/src/lib/devices/Hue.ts index 3d8e840..6b885b3 100644 --- a/src/lib/devices/Hue.ts +++ b/src/lib/devices/Hue.ts @@ -1,11 +1,11 @@ import Ct from './Ct'; import { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Cie extends Ct { protected _hue: DeviceStateObject | undefined; @@ -13,9 +13,17 @@ class Cie extends Ct { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'HUE', valueType: ValueType.String, accessType: StateAccessType.ReadWrite, type: PropertyType.Hue, callback: state => this._hue = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'HUE', + valueType: ValueType.String, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Hue, + callback: state => (this._hue = state), + }, + ]), + ); } getHue(): number | undefined { @@ -33,4 +41,4 @@ class Cie extends Ct { } } -export default Cie; \ No newline at end of file +export default Cie; diff --git a/src/lib/devices/Humidity.ts b/src/lib/devices/Humidity.ts index 3a4ba9b..b78df68 100644 --- a/src/lib/devices/Humidity.ts +++ b/src/lib/devices/Humidity.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Humidity extends GenericDevice { @@ -13,9 +13,17 @@ class Humidity extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'ACTUAL', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Value, callback: state => this._getValueState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'ACTUAL', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Value, + callback: state => (this._getValueState = state), + }, + ]), + ); } getValue(): number | undefined { @@ -26,4 +34,4 @@ class Humidity extends GenericDevice { } } -export default Humidity; \ No newline at end of file +export default Humidity; diff --git a/src/lib/devices/Image.ts b/src/lib/devices/Image.ts index 50a55e5..8e94513 100644 --- a/src/lib/devices/Image.ts +++ b/src/lib/devices/Image.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Image extends GenericDevice { @@ -13,9 +13,17 @@ class Image extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'URL', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Url, callback: state => this._getUrlState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'URL', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Url, + callback: state => (this._getUrlState = state), + }, + ]), + ); } getUrl(): string | undefined { @@ -26,4 +34,4 @@ class Image extends GenericDevice { } } -export default Image; \ No newline at end of file +export default Image; diff --git a/src/lib/devices/Info.ts b/src/lib/devices/Info.ts index 7b2d18f..4b1df26 100644 --- a/src/lib/devices/Info.ts +++ b/src/lib/devices/Info.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Info extends GenericDevice { @@ -13,9 +13,17 @@ class Info extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'ACTUAL', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Value, callback: state => this._getValueState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'ACTUAL', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Value, + callback: state => (this._getValueState = state), + }, + ]), + ); } getValue(): string | undefined { @@ -29,4 +37,4 @@ class Info extends GenericDevice { } } -export default Info; \ No newline at end of file +export default Info; diff --git a/src/lib/devices/Light.ts b/src/lib/devices/Light.ts index f4ad9db..2e519ae 100644 --- a/src/lib/devices/Light.ts +++ b/src/lib/devices/Light.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Light extends GenericDevice { @@ -20,17 +20,66 @@ class Light extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - // actual value first, as it will be read first - { name: 'ON_ACTUAL', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.Power, callback: state => this._getPowerState = state }, - { name: 'SET', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Power, callback: state => this._setPowerState = state }, + this._ready.push( + this.addDeviceStates([ + // actual value first, as it will be read first + { + name: 'ON_ACTUAL', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.Power, + callback: state => (this._getPowerState = state), + }, + { + name: 'SET', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Power, + callback: state => (this._setPowerState = state), + }, - { name: 'ELECTRIC_POWER', valueType: ValueType.Number, unit: 'W', accessType: StateAccessType.Read, type: PropertyType.ElectricPower, callback: state => this._getElectricPowerState = state }, - { name: 'CURRENT', valueType: ValueType.Number, unit: 'A', accessType: StateAccessType.Read, type: PropertyType.Current, callback: state => this._getCurrentState = state }, - { name: 'VOLTAGE', valueType: ValueType.Number, unit: 'V', accessType: StateAccessType.Read, type: PropertyType.Voltage, callback: state => this._getVoltageState = state }, - { name: 'CONSUMPTION', valueType: ValueType.Number, unit: 'Wh', accessType: StateAccessType.Read, type: PropertyType.Consumption, callback: state => this._getConsumptionState = state }, - { name: 'FREQUENCY', valueType: ValueType.Number, unit: 'Hz', accessType: StateAccessType.Read, type: PropertyType.Frequency, callback: state => this._getFrequencyState = state }, - ])); + { + name: 'ELECTRIC_POWER', + valueType: ValueType.Number, + unit: 'W', + accessType: StateAccessType.Read, + type: PropertyType.ElectricPower, + callback: state => (this._getElectricPowerState = state), + }, + { + name: 'CURRENT', + valueType: ValueType.Number, + unit: 'A', + accessType: StateAccessType.Read, + type: PropertyType.Current, + callback: state => (this._getCurrentState = state), + }, + { + name: 'VOLTAGE', + valueType: ValueType.Number, + unit: 'V', + accessType: StateAccessType.Read, + type: PropertyType.Voltage, + callback: state => (this._getVoltageState = state), + }, + { + name: 'CONSUMPTION', + valueType: ValueType.Number, + unit: 'Wh', + accessType: StateAccessType.Read, + type: PropertyType.Consumption, + callback: state => (this._getConsumptionState = state), + }, + { + name: 'FREQUENCY', + valueType: ValueType.Number, + unit: 'Hz', + accessType: StateAccessType.Read, + type: PropertyType.Frequency, + callback: state => (this._getFrequencyState = state), + }, + ]), + ); } getPower(): boolean | undefined { @@ -83,4 +132,4 @@ class Light extends GenericDevice { } } -export default Light; \ No newline at end of file +export default Light; diff --git a/src/lib/devices/Location.ts b/src/lib/devices/Location.ts index 0a04f10..bf9b9ee 100644 --- a/src/lib/devices/Location.ts +++ b/src/lib/devices/Location.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Location extends GenericDevice { @@ -17,13 +17,45 @@ class Location extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'LONGITUDE', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Longitude, callback: state => this._getLongitudeState = state }, - { name: 'LATITUDE', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Latitude, callback: state => this._getLatitudeState = state }, - { name: 'ELEVATION', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Elevation, callback: state => this._getElevationState = state }, - { name: 'RADIUS', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Radius, callback: state => this._getRadiusState = state }, - { name: 'ACCURACY', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Accuracy, callback: state => this._getAccuracyState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'LONGITUDE', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Longitude, + callback: state => (this._getLongitudeState = state), + }, + { + name: 'LATITUDE', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Latitude, + callback: state => (this._getLatitudeState = state), + }, + { + name: 'ELEVATION', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Elevation, + callback: state => (this._getElevationState = state), + }, + { + name: 'RADIUS', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Radius, + callback: state => (this._getRadiusState = state), + }, + { + name: 'ACCURACY', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Accuracy, + callback: state => (this._getAccuracyState = state), + }, + ]), + ); } getLongitude(): number | undefined { @@ -62,4 +94,4 @@ class Location extends GenericDevice { } } -export default Location; \ No newline at end of file +export default Location; diff --git a/src/lib/devices/LocationOne.ts b/src/lib/devices/LocationOne.ts index 1274187..4383c09 100644 --- a/src/lib/devices/LocationOne.ts +++ b/src/lib/devices/LocationOne.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class LocationOne extends GenericDevice { @@ -16,12 +16,38 @@ class LocationOne extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'GPS', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.GPS, callback: state => this._getGPSState = state }, - { name: 'ELEVATION', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Elevation, callback: state => this._getElevationState = state }, - { name: 'RADIUS', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Radius, callback: state => this._getRadiusState = state }, - { name: 'ACCURACY', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Accuracy, callback: state => this._getAccuracyState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'GPS', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.GPS, + callback: state => (this._getGPSState = state), + }, + { + name: 'ELEVATION', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Elevation, + callback: state => (this._getElevationState = state), + }, + { + name: 'RADIUS', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Radius, + callback: state => (this._getRadiusState = state), + }, + { + name: 'ACCURACY', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Accuracy, + callback: state => (this._getAccuracyState = state), + }, + ]), + ); } getGPS(): string | undefined { @@ -53,4 +79,4 @@ class LocationOne extends GenericDevice { } } -export default LocationOne; \ No newline at end of file +export default LocationOne; diff --git a/src/lib/devices/Lock.ts b/src/lib/devices/Lock.ts index cfa9fcf..c9b9902 100644 --- a/src/lib/devices/Lock.ts +++ b/src/lib/devices/Lock.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Lock extends GenericDevice { @@ -15,12 +15,32 @@ class Lock extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - // actual value first, as it will be read first - { name: 'ACTUAL', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.Power, callback: state => this._getPowerState = state }, - { name: 'SET', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Power, callback: state => this._setPowerState = state }, - { name: 'OPEN', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.Open, callback: state => this._setOpenState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + // actual value first, as it will be read first + { + name: 'ACTUAL', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.Power, + callback: state => (this._getPowerState = state), + }, + { + name: 'SET', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Power, + callback: state => (this._setPowerState = state), + }, + { + name: 'OPEN', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.Open, + callback: state => (this._setOpenState = state), + }, + ]), + ); } getPower(): boolean | undefined { @@ -45,4 +65,4 @@ class Lock extends GenericDevice { } } -export default Lock; \ No newline at end of file +export default Lock; diff --git a/src/lib/devices/Media.ts b/src/lib/devices/Media.ts index b529f21..c29f633 100644 --- a/src/lib/devices/Media.ts +++ b/src/lib/devices/Media.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Media extends GenericDevice { @@ -34,32 +34,168 @@ class Media extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'STATE', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.State, callback: state => this._getStateState = state }, - { name: 'PLAY', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.Play, callback: state => this._setPlayState = state }, - { name: 'PAUSE', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.Pause, callback: state => this._setPauseState = state }, - { name: 'STOP', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.Stop, callback: state => this._setStopState = state }, - { name: 'NEXT', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.Next, callback: state => this._setNextState = state }, - { name: 'PREV', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.Previous, callback: state => this._setPrevState = state }, - { name: 'SHUFFLE', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Shuffle, callback: state => this._shuffleState = state }, - { name: 'REPEAT', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Repeat, callback: state => this._repeatState = state }, - { name: 'ARTIST', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Artist, callback: state => this._getArtistState = state }, - { name: 'ALBUM', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Album, callback: state => this._getAlbumState = state }, - { name: 'TITLE', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Title, callback: state => this._getTitleState = state }, - { name: 'COVER', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Cover, callback: state => this._getCoverState = state }, - { name: 'DURATION', valueType: ValueType.Number, accessType: StateAccessType.Read, unit: 'seconds', type: PropertyType.Duration, callback: state => this._getDurationState = state }, - { name: 'ELAPSED', valueType: ValueType.Number, unit: 'seconds', accessType: StateAccessType.Read, type: PropertyType.Elapsed, callback: state => this._getElapsedState = state }, - { name: 'SEEK', valueType: ValueType.NumberPercent, accessType: StateAccessType.Write, type: PropertyType.Seek, callback: state => this._setSeekState = state }, - { name: 'TRACK', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Track, callback: state => this._getTrackState = state }, - { name: 'EPISODE', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Episode, callback: state => this._getEpisodeState = state }, - { name: 'SEASON', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Season, callback: state => this._getSeasonState = state }, - // actual value first, as it will be read first - { name: 'VOLUME_ACTUAL', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Volume, callback: state => this._getVolumeState = state || this._setVolumeState }, - { name: 'VOLUME', valueType: ValueType.NumberPercent, accessType: StateAccessType.ReadWrite, type: PropertyType.Volume, callback: state => this._setVolumeState = state }, - { name: 'MUTE', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Mute, callback: state => this._muteState = state }, - // TODO: This must be mapped to reachable - { name: 'CONNECTED', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.Connected, callback: state => this._getConnectedState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'STATE', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.State, + callback: state => (this._getStateState = state), + }, + { + name: 'PLAY', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.Play, + callback: state => (this._setPlayState = state), + }, + { + name: 'PAUSE', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.Pause, + callback: state => (this._setPauseState = state), + }, + { + name: 'STOP', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.Stop, + callback: state => (this._setStopState = state), + }, + { + name: 'NEXT', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.Next, + callback: state => (this._setNextState = state), + }, + { + name: 'PREV', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.Previous, + callback: state => (this._setPrevState = state), + }, + { + name: 'SHUFFLE', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Shuffle, + callback: state => (this._shuffleState = state), + }, + { + name: 'REPEAT', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Repeat, + callback: state => (this._repeatState = state), + }, + { + name: 'ARTIST', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Artist, + callback: state => (this._getArtistState = state), + }, + { + name: 'ALBUM', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Album, + callback: state => (this._getAlbumState = state), + }, + { + name: 'TITLE', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Title, + callback: state => (this._getTitleState = state), + }, + { + name: 'COVER', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Cover, + callback: state => (this._getCoverState = state), + }, + { + name: 'DURATION', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + unit: 'seconds', + type: PropertyType.Duration, + callback: state => (this._getDurationState = state), + }, + { + name: 'ELAPSED', + valueType: ValueType.Number, + unit: 'seconds', + accessType: StateAccessType.Read, + type: PropertyType.Elapsed, + callback: state => (this._getElapsedState = state), + }, + { + name: 'SEEK', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Write, + type: PropertyType.Seek, + callback: state => (this._setSeekState = state), + }, + { + name: 'TRACK', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Track, + callback: state => (this._getTrackState = state), + }, + { + name: 'EPISODE', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Episode, + callback: state => (this._getEpisodeState = state), + }, + { + name: 'SEASON', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Season, + callback: state => (this._getSeasonState = state), + }, + // actual value first, as it will be read first + { + name: 'VOLUME_ACTUAL', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Volume, + callback: state => (this._getVolumeState = state || this._setVolumeState), + }, + { + name: 'VOLUME', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Volume, + callback: state => (this._setVolumeState = state), + }, + { + name: 'MUTE', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Mute, + callback: state => (this._muteState = state), + }, + // TODO: This must be mapped to reachable + { + name: 'CONNECTED', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.Connected, + callback: state => (this._getConnectedState = state), + }, + ]), + ); } getState(): boolean | number | undefined { @@ -238,4 +374,4 @@ class Media extends GenericDevice { } } -export default Media; \ No newline at end of file +export default Media; diff --git a/src/lib/devices/Motion.ts b/src/lib/devices/Motion.ts index c0dd3ae..0232807 100644 --- a/src/lib/devices/Motion.ts +++ b/src/lib/devices/Motion.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Motion extends GenericDevice { @@ -14,10 +14,24 @@ class Motion extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'ACTUAL', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.Value, callback: state => this._getValueState = state }, - { name: 'SECOND', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Brightness, callback: state => this._getBrightnessState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'ACTUAL', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.Value, + callback: state => (this._getValueState = state), + }, + { + name: 'SECOND', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Brightness, + callback: state => (this._getBrightnessState = state), + }, + ]), + ); } getValue(): boolean | undefined { @@ -35,4 +49,4 @@ class Motion extends GenericDevice { } } -export default Motion; \ No newline at end of file +export default Motion; diff --git a/src/lib/devices/Rgb.ts b/src/lib/devices/Rgb.ts index 4ab8c69..dcb156f 100644 --- a/src/lib/devices/Rgb.ts +++ b/src/lib/devices/Rgb.ts @@ -1,11 +1,11 @@ import Ct from './Ct'; import { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Rgb extends Ct { @@ -17,12 +17,38 @@ class Rgb extends Ct { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'RED', valueType: ValueType.NumberPercent, accessType: StateAccessType.ReadWrite, type: PropertyType.Red, callback: state => this._red = state }, - { name: 'GREEN', valueType: ValueType.NumberPercent, accessType: StateAccessType.ReadWrite, type: PropertyType.Green, callback: state => this._green = state }, - { name: 'BLUE', valueType: ValueType.NumberPercent, accessType: StateAccessType.ReadWrite, type: PropertyType.Blue, callback: state => this._blue = state }, - { name: 'WHITE', valueType: ValueType.NumberPercent, accessType: StateAccessType.ReadWrite, type: PropertyType.White, callback: state => this._white = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'RED', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Red, + callback: state => (this._red = state), + }, + { + name: 'GREEN', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Green, + callback: state => (this._green = state), + }, + { + name: 'BLUE', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Blue, + callback: state => (this._blue = state), + }, + { + name: 'WHITE', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.ReadWrite, + type: PropertyType.White, + callback: state => (this._white = state), + }, + ]), + ); } getRed(): number | undefined { @@ -82,4 +108,4 @@ class Rgb extends Ct { } } -export default Rgb; \ No newline at end of file +export default Rgb; diff --git a/src/lib/devices/RgbSingle.ts b/src/lib/devices/RgbSingle.ts index 62ae205..1dae785 100644 --- a/src/lib/devices/RgbSingle.ts +++ b/src/lib/devices/RgbSingle.ts @@ -1,11 +1,11 @@ import Ct from './Ct'; import { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class RgbSingle extends Ct { @@ -14,9 +14,17 @@ class RgbSingle extends Ct { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'RGB', valueType: ValueType.String, accessType: StateAccessType.ReadWrite, type: PropertyType.Rgb, callback: state => this._rgb = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'RGB', + valueType: ValueType.String, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Rgb, + callback: state => (this._rgb = state), + }, + ]), + ); } getRgb(): string | undefined { @@ -34,4 +42,4 @@ class RgbSingle extends Ct { } } -export default RgbSingle; \ No newline at end of file +export default RgbSingle; diff --git a/src/lib/devices/RgbwSingle.ts b/src/lib/devices/RgbwSingle.ts index cb733ba..0b2b315 100644 --- a/src/lib/devices/RgbwSingle.ts +++ b/src/lib/devices/RgbwSingle.ts @@ -1,11 +1,11 @@ import Ct from './Ct'; import { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class RgbwSingle extends Ct { @@ -14,9 +14,17 @@ class RgbwSingle extends Ct { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'RGBW', valueType: ValueType.String, accessType: StateAccessType.ReadWrite, type: PropertyType.Rgbw, callback: state => this._rgbw = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'RGBW', + valueType: ValueType.String, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Rgbw, + callback: state => (this._rgbw = state), + }, + ]), + ); } getRgbw(): string | undefined { @@ -32,7 +40,6 @@ class RgbwSingle extends Ct { } return this._rgbw.setValue(value); } - } -export default RgbwSingle; \ No newline at end of file +export default RgbwSingle; diff --git a/src/lib/devices/Slider.ts b/src/lib/devices/Slider.ts index eb057f3..5eea0ef 100644 --- a/src/lib/devices/Slider.ts +++ b/src/lib/devices/Slider.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Slider extends GenericDevice { @@ -14,11 +14,25 @@ class Slider extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - // actual value first, as it will be read first - { name: 'ACTUAL', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Level, callback: state => this._getLevelState = state }, - { name: 'SET', valueType: ValueType.NumberPercent, accessType: StateAccessType.ReadWrite, type: PropertyType.Level, callback: state => this._setLevelState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + // actual value first, as it will be read first + { + name: 'ACTUAL', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Level, + callback: state => (this._getLevelState = state), + }, + { + name: 'SET', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Level, + callback: state => (this._setLevelState = state), + }, + ]), + ); } getLevel(): number | undefined { @@ -36,4 +50,4 @@ class Slider extends GenericDevice { } } -export default Slider; \ No newline at end of file +export default Slider; diff --git a/src/lib/devices/Socket.ts b/src/lib/devices/Socket.ts index 880d733..a5879b5 100644 --- a/src/lib/devices/Socket.ts +++ b/src/lib/devices/Socket.ts @@ -1,2 +1,2 @@ import Light from './Light'; -export default Light; \ No newline at end of file +export default Light; diff --git a/src/lib/devices/Temperature.ts b/src/lib/devices/Temperature.ts index 65e84a9..992ffbf 100644 --- a/src/lib/devices/Temperature.ts +++ b/src/lib/devices/Temperature.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Temperature extends GenericDevice { @@ -14,10 +14,24 @@ class Temperature extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'ACTUAL', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Value, callback: state => this._getValueState = state }, - { name: 'SECOND', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Humidity, callback: state => this._getHumidityState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'ACTUAL', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Value, + callback: state => (this._getValueState = state), + }, + { + name: 'SECOND', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Humidity, + callback: state => (this._getHumidityState = state), + }, + ]), + ); } getValue(): boolean | undefined { @@ -35,4 +49,4 @@ class Temperature extends GenericDevice { } } -export default Temperature; \ No newline at end of file +export default Temperature; diff --git a/src/lib/devices/Thermostat.ts b/src/lib/devices/Thermostat.ts index ce74e19..95429fe 100644 --- a/src/lib/devices/Thermostat.ts +++ b/src/lib/devices/Thermostat.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; enum ThermostatMode { @@ -33,15 +33,59 @@ class Thermostat extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'SET', valueType: ValueType.NumberMinMax, accessType: StateAccessType.ReadWrite, type: PropertyType.Level, callback: state => this._levelState = state }, - { name: 'ACTUAL', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Temperature, callback: state => this._getTemperatureState = state }, - { name: 'POWER', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Power, callback: state => this._powerState = state }, - { name: 'HUMIDITY', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Humidity, callback: state => this._getHumidityState = state }, - { name: 'BOOST', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Boost, callback: state => this._boostState = state }, - { name: 'PARTY', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Party, callback: state => this._partyState = state }, - { name: 'MODE', valueType: ValueType.Enum, accessType: StateAccessType.ReadWrite, type: PropertyType.Mode, callback: state => this._modeState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'SET', + valueType: ValueType.NumberMinMax, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Level, + callback: state => (this._levelState = state), + }, + { + name: 'ACTUAL', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Temperature, + callback: state => (this._getTemperatureState = state), + }, + { + name: 'POWER', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Power, + callback: state => (this._powerState = state), + }, + { + name: 'HUMIDITY', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Humidity, + callback: state => (this._getHumidityState = state), + }, + { + name: 'BOOST', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Boost, + callback: state => (this._boostState = state), + }, + { + name: 'PARTY', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Party, + callback: state => (this._partyState = state), + }, + { + name: 'MODE', + valueType: ValueType.Enum, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Mode, + callback: state => (this._modeState = state), + }, + ]), + ); } getModes(): Promise { @@ -136,4 +180,4 @@ class Thermostat extends GenericDevice { } } -export default Thermostat; \ No newline at end of file +export default Thermostat; diff --git a/src/lib/devices/VacuumCleaner.ts b/src/lib/devices/VacuumCleaner.ts index 3d502d0..8e0b671 100644 --- a/src/lib/devices/VacuumCleaner.ts +++ b/src/lib/devices/VacuumCleaner.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; enum VacuumCleanerMode { @@ -50,24 +50,122 @@ class VacuumCleaner extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'POWER', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Power, callback: state => this._powerState = state }, - { name: 'MODE', valueType: ValueType.Enum, accessType: StateAccessType.ReadWrite, type: PropertyType.Mode, callback: state => this._modeState = state }, - { name: 'MAP_BASE64', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.MapBase64, callback: state => this._getMapBase64State = state }, - { name: 'MAP_URL', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.MapUrl, callback: state => this._getMapUrlState = state }, - { name: 'WORK_MODE', valueType: ValueType.Enum, accessType: StateAccessType.ReadWrite, type: PropertyType.WorkMode, callback: state => this._workModeState = state }, - { name: 'WATER', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Water, callback: state => this._getWaterState = state }, - { name: 'WASTE', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Waste, callback: state => this._getWasteState = state }, - { name: 'BATTERY', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Battery, callback: state => this._getBatteryState = state }, - { name: 'STATE', valueType: ValueType.Enum, accessType: StateAccessType.Read, type: PropertyType.State, callback: state => this._getStateState = state }, - { name: 'PAUSE', valueType: ValueType.Button, accessType: StateAccessType.Write, type: PropertyType.Pause, callback: state => this._pauseState = state }, - { name: 'WASTE_ALARM', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.WasteAlarm, callback: state => this._getWasteAlarmState = state }, - { name: 'WATER_ALARM', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.WaterAlarm, callback: state => this._getWaterAlarmState = state }, - { name: 'FILTER', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Filter, callback: state => this._getFilterState = state }, - { name: 'BRUSH', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Brush, callback: state => this._getBrushState = state }, - { name: 'SENSORS', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Sensors, callback: state => this._getSensorsState = state }, - { name: 'SIDE_BRUSH', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.SideBrush, callback: state => this._getSideBrushState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'POWER', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Power, + callback: state => (this._powerState = state), + }, + { + name: 'MODE', + valueType: ValueType.Enum, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Mode, + callback: state => (this._modeState = state), + }, + { + name: 'MAP_BASE64', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.MapBase64, + callback: state => (this._getMapBase64State = state), + }, + { + name: 'MAP_URL', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.MapUrl, + callback: state => (this._getMapUrlState = state), + }, + { + name: 'WORK_MODE', + valueType: ValueType.Enum, + accessType: StateAccessType.ReadWrite, + type: PropertyType.WorkMode, + callback: state => (this._workModeState = state), + }, + { + name: 'WATER', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Water, + callback: state => (this._getWaterState = state), + }, + { + name: 'WASTE', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Waste, + callback: state => (this._getWasteState = state), + }, + { + name: 'BATTERY', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Battery, + callback: state => (this._getBatteryState = state), + }, + { + name: 'STATE', + valueType: ValueType.Enum, + accessType: StateAccessType.Read, + type: PropertyType.State, + callback: state => (this._getStateState = state), + }, + { + name: 'PAUSE', + valueType: ValueType.Button, + accessType: StateAccessType.Write, + type: PropertyType.Pause, + callback: state => (this._pauseState = state), + }, + { + name: 'WASTE_ALARM', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.WasteAlarm, + callback: state => (this._getWasteAlarmState = state), + }, + { + name: 'WATER_ALARM', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.WaterAlarm, + callback: state => (this._getWaterAlarmState = state), + }, + { + name: 'FILTER', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Filter, + callback: state => (this._getFilterState = state), + }, + { + name: 'BRUSH', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Brush, + callback: state => (this._getBrushState = state), + }, + { + name: 'SENSORS', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Sensors, + callback: state => (this._getSensorsState = state), + }, + { + name: 'SIDE_BRUSH', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.SideBrush, + callback: state => (this._getSideBrushState = state), + }, + ]), + ); } getPower(): boolean | undefined { @@ -225,4 +323,4 @@ class VacuumCleaner extends GenericDevice { } } -export default VacuumCleaner; \ No newline at end of file +export default VacuumCleaner; diff --git a/src/lib/devices/Volume.ts b/src/lib/devices/Volume.ts index df88bc7..74bba58 100644 --- a/src/lib/devices/Volume.ts +++ b/src/lib/devices/Volume.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Volume extends GenericDevice { @@ -15,12 +15,32 @@ class Volume extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - // actual value first, as it will be read first - { name: 'ACTUAL', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Level, callback: state => this._getLevelState = state }, - { name: 'SET', valueType: ValueType.NumberPercent, accessType: StateAccessType.ReadWrite, type: PropertyType.Level, callback: state => this._setLevelState = state }, - { name: 'MUTE', valueType: ValueType.Boolean, accessType: StateAccessType.ReadWrite, type: PropertyType.Mute, callback: state => this._MuteState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + // actual value first, as it will be read first + { + name: 'ACTUAL', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Level, + callback: state => (this._getLevelState = state), + }, + { + name: 'SET', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Level, + callback: state => (this._setLevelState = state), + }, + { + name: 'MUTE', + valueType: ValueType.Boolean, + accessType: StateAccessType.ReadWrite, + type: PropertyType.Mute, + callback: state => (this._MuteState = state), + }, + ]), + ); } getLevel(): number | undefined { @@ -52,4 +72,4 @@ class Volume extends GenericDevice { } } -export default Volume; \ No newline at end of file +export default Volume; diff --git a/src/lib/devices/VolumeGroup.ts b/src/lib/devices/VolumeGroup.ts index 89957ea..d82b377 100644 --- a/src/lib/devices/VolumeGroup.ts +++ b/src/lib/devices/VolumeGroup.ts @@ -1,2 +1,2 @@ import Volume from './Volume'; -export default Volume; \ No newline at end of file +export default Volume; diff --git a/src/lib/devices/Warning.ts b/src/lib/devices/Warning.ts index 2327be7..66a3a32 100644 --- a/src/lib/devices/Warning.ts +++ b/src/lib/devices/Warning.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Warning extends GenericDevice { @@ -19,15 +19,59 @@ class Warning extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'LEVEL', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Warning, callback: state => this._getWarningState = state }, - { name: 'TITLE', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Title, callback: state => this._getTitleState = state }, - { name: 'INFO', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Info, callback: state => this._getInfoState = state }, - { name: 'START', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.StartTime, callback: state => this._getStartState = state }, - { name: 'END', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.EndTime, callback: state => this._getEndState = state }, - { name: 'ICON', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Icon, callback: state => this._getIconState = state }, - { name: 'DESC', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Description, callback: state => this._getDescState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'LEVEL', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Warning, + callback: state => (this._getWarningState = state), + }, + { + name: 'TITLE', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Title, + callback: state => (this._getTitleState = state), + }, + { + name: 'INFO', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Info, + callback: state => (this._getInfoState = state), + }, + { + name: 'START', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.StartTime, + callback: state => (this._getStartState = state), + }, + { + name: 'END', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.EndTime, + callback: state => (this._getEndState = state), + }, + { + name: 'ICON', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Icon, + callback: state => (this._getIconState = state), + }, + { + name: 'DESC', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Description, + callback: state => (this._getDescState = state), + }, + ]), + ); } getWarning(): number | undefined { @@ -80,4 +124,4 @@ class Warning extends GenericDevice { } } -export default Warning; \ No newline at end of file +export default Warning; diff --git a/src/lib/devices/WeatherCurrent.ts b/src/lib/devices/WeatherCurrent.ts index f870779..7036ed3 100644 --- a/src/lib/devices/WeatherCurrent.ts +++ b/src/lib/devices/WeatherCurrent.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class WeatherCurrent extends GenericDevice { @@ -25,21 +25,101 @@ class WeatherCurrent extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'ACTUAL', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Value, callback: state => this._getValueState = state }, - { name: 'ICON', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Icon, callback: state => this._getIconState = state }, - { name: 'PRECIPITATION_CHANCE', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.PrecipitationChance, callback: state => this._getPrecipitationChanceState = state }, - { name: 'PRECIPITATION_TYPE', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.PrecipitationType, callback: state => this._getPrecipitationTypeState = state }, - { name: 'PRESSURE', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Pressure, callback: state => this._getPressureState = state }, - { name: 'PRESSURE_TENDENCY', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.PressureTendency, callback: state => this._getPressureTendencyState = state }, - { name: 'REAL_FEEL_TEMPERATURE', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.RealFeelTemperature, callback: state => this._getRealFeelTemperatureState = state }, - { name: 'HUMIDITY', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Humidity, callback: state => this._getHumidityState = state }, - { name: 'UV', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Uv, callback: state => this._getUVState = state }, - { name: 'WEATHER', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Weather, callback: state => this._getWeatherState = state }, - { name: 'WIND_DIRECTION', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.WindDirectionString, callback: state => this._getWindDirectionState = state }, - { name: 'WIND_GUST', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.WindGust, callback: state => this._getWindGustState = state }, - { name: 'WIND_SPEED', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.WindSpeed, callback: state => this._getWindSpeedState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'ACTUAL', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Value, + callback: state => (this._getValueState = state), + }, + { + name: 'ICON', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Icon, + callback: state => (this._getIconState = state), + }, + { + name: 'PRECIPITATION_CHANCE', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.PrecipitationChance, + callback: state => (this._getPrecipitationChanceState = state), + }, + { + name: 'PRECIPITATION_TYPE', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.PrecipitationType, + callback: state => (this._getPrecipitationTypeState = state), + }, + { + name: 'PRESSURE', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Pressure, + callback: state => (this._getPressureState = state), + }, + { + name: 'PRESSURE_TENDENCY', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.PressureTendency, + callback: state => (this._getPressureTendencyState = state), + }, + { + name: 'REAL_FEEL_TEMPERATURE', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.RealFeelTemperature, + callback: state => (this._getRealFeelTemperatureState = state), + }, + { + name: 'HUMIDITY', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Humidity, + callback: state => (this._getHumidityState = state), + }, + { + name: 'UV', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Uv, + callback: state => (this._getUVState = state), + }, + { + name: 'WEATHER', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Weather, + callback: state => (this._getWeatherState = state), + }, + { + name: 'WIND_DIRECTION', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.WindDirectionString, + callback: state => (this._getWindDirectionState = state), + }, + { + name: 'WIND_GUST', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.WindGust, + callback: state => (this._getWindGustState = state), + }, + { + name: 'WIND_SPEED', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.WindSpeed, + callback: state => (this._getWindSpeedState = state), + }, + ]), + ); } getValue(): number | undefined { @@ -134,4 +214,4 @@ class WeatherCurrent extends GenericDevice { } } -export default WeatherCurrent; \ No newline at end of file +export default WeatherCurrent; diff --git a/src/lib/devices/WeatherForecast.ts b/src/lib/devices/WeatherForecast.ts index 948aa9f..ff8842a 100644 --- a/src/lib/devices/WeatherForecast.ts +++ b/src/lib/devices/WeatherForecast.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class WeatherForecast extends GenericDevice { @@ -33,29 +33,157 @@ class WeatherForecast extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'ICON', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Icon, callback: state => this._getIconState = state }, - { name: 'TEMP_MIN', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.TemperatureMin, callback: state => this._getTempMinState = state }, - { name: 'TEMP_MAX', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.TemperatureMax, callback: state => this._getTempMaxState = state }, - { name: 'PRECIPITATION_CHANCE', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.PrecipitationChance, callback: state => this._getPrecipitationChanceState = state }, - { name: 'PRECIPITATION', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Precipitation, callback: state => this._getPrecipitationState = state }, - { name: 'DATE', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.Date, callback: state => this._getDateState = state }, - { name: 'DOW', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.DayOfWeek, callback: state => this._getDowState = state }, - { name: 'STATE', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.State, callback: state => this._getStateState = state }, - { name: 'TEMP', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Temperature, callback: state => this._getTempState = state }, - { name: 'PRESSURE', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.Pressure, callback: state => this._getPressureState = state }, - { name: 'HUMIDITY', valueType: ValueType.NumberPercent, accessType: StateAccessType.Read, type: PropertyType.Humidity, callback: state => this._getHumidityState = state }, - { name: 'TIME_SUNRISE', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.TimeSunrise, callback: state => this._getTimeSunriseState = state }, - { name: 'TIME_SUNSET', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.TimeSunset, callback: state => this._getTimeSunsetState = state }, - { name: 'WIND_CHILL', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.WindChill, callback: state => this._getWindChillState = state }, - { name: 'FEELS_LIKE', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.FeelsLike, callback: state => this._getFeelsLikeState = state }, - { name: 'WIND_SPEED', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.WindSpeed, callback: state => this._getWindSpeedState = state }, - { name: 'WIND_DIRECTION', valueType: ValueType.Number, accessType: StateAccessType.Read, type: PropertyType.WindDirectionNumber, callback: state => this._getWindDirectionState = state }, - { name: 'WIND_DIRECTION_STR', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.WindDirectionString, callback: state => this._getWindDirectionStrState = state }, - { name: 'WIND_ICON', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.WindIcon, callback: state => this._getWindIconState = state }, - { name: 'HISTORY_CHART', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.HistoryChart, callback: state => this._getHistoryChartState = state }, - { name: 'FORECAST_CHART', valueType: ValueType.String, accessType: StateAccessType.Read, type: PropertyType.ForecastChart, callback: state => this._getForecastChartState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'ICON', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Icon, + callback: state => (this._getIconState = state), + }, + { + name: 'TEMP_MIN', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.TemperatureMin, + callback: state => (this._getTempMinState = state), + }, + { + name: 'TEMP_MAX', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.TemperatureMax, + callback: state => (this._getTempMaxState = state), + }, + { + name: 'PRECIPITATION_CHANCE', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.PrecipitationChance, + callback: state => (this._getPrecipitationChanceState = state), + }, + { + name: 'PRECIPITATION', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Precipitation, + callback: state => (this._getPrecipitationState = state), + }, + { + name: 'DATE', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.Date, + callback: state => (this._getDateState = state), + }, + { + name: 'DOW', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.DayOfWeek, + callback: state => (this._getDowState = state), + }, + { + name: 'STATE', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.State, + callback: state => (this._getStateState = state), + }, + { + name: 'TEMP', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Temperature, + callback: state => (this._getTempState = state), + }, + { + name: 'PRESSURE', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.Pressure, + callback: state => (this._getPressureState = state), + }, + { + name: 'HUMIDITY', + valueType: ValueType.NumberPercent, + accessType: StateAccessType.Read, + type: PropertyType.Humidity, + callback: state => (this._getHumidityState = state), + }, + { + name: 'TIME_SUNRISE', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.TimeSunrise, + callback: state => (this._getTimeSunriseState = state), + }, + { + name: 'TIME_SUNSET', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.TimeSunset, + callback: state => (this._getTimeSunsetState = state), + }, + { + name: 'WIND_CHILL', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.WindChill, + callback: state => (this._getWindChillState = state), + }, + { + name: 'FEELS_LIKE', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.FeelsLike, + callback: state => (this._getFeelsLikeState = state), + }, + { + name: 'WIND_SPEED', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.WindSpeed, + callback: state => (this._getWindSpeedState = state), + }, + { + name: 'WIND_DIRECTION', + valueType: ValueType.Number, + accessType: StateAccessType.Read, + type: PropertyType.WindDirectionNumber, + callback: state => (this._getWindDirectionState = state), + }, + { + name: 'WIND_DIRECTION_STR', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.WindDirectionString, + callback: state => (this._getWindDirectionStrState = state), + }, + { + name: 'WIND_ICON', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.WindIcon, + callback: state => (this._getWindIconState = state), + }, + { + name: 'HISTORY_CHART', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.HistoryChart, + callback: state => (this._getHistoryChartState = state), + }, + { + name: 'FORECAST_CHART', + valueType: ValueType.String, + accessType: StateAccessType.Read, + type: PropertyType.ForecastChart, + callback: state => (this._getForecastChartState = state), + }, + ]), + ); } getIcon(): string | undefined { @@ -206,4 +334,4 @@ class WeatherForecast extends GenericDevice { } } -export default WeatherForecast; \ No newline at end of file +export default WeatherForecast; diff --git a/src/lib/devices/Window.ts b/src/lib/devices/Window.ts index d8403ec..4a4d5ed 100644 --- a/src/lib/devices/Window.ts +++ b/src/lib/devices/Window.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class Window extends GenericDevice { @@ -13,9 +13,17 @@ class Window extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'ACTUAL', valueType: ValueType.Boolean, accessType: StateAccessType.Read, type: PropertyType.Value, callback: state => this._getValueState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'ACTUAL', + valueType: ValueType.Boolean, + accessType: StateAccessType.Read, + type: PropertyType.Value, + callback: state => (this._getValueState = state), + }, + ]), + ); } getValue(): boolean | undefined { @@ -26,4 +34,4 @@ class Window extends GenericDevice { } } -export default Window; \ No newline at end of file +export default Window; diff --git a/src/lib/devices/WindowTilt.ts b/src/lib/devices/WindowTilt.ts index 4632cd1..c0f6c7b 100644 --- a/src/lib/devices/WindowTilt.ts +++ b/src/lib/devices/WindowTilt.ts @@ -1,10 +1,10 @@ import GenericDevice, { - PropertyType, DetectedDevice, + DeviceOptions, DeviceStateObject, + PropertyType, StateAccessType, ValueType, - DeviceOptions, } from './GenericDevice'; class WindowTilt extends GenericDevice { @@ -13,9 +13,17 @@ class WindowTilt extends GenericDevice { constructor(detectedDevice: DetectedDevice, adapter: ioBroker.Adapter, options?: DeviceOptions) { super(detectedDevice, adapter, options); - this._ready.push(this.addDeviceStates([ - { name: 'ACTUAL', valueType: ValueType.Enum, accessType: StateAccessType.Read, type: PropertyType.Value, callback: state => this._getValueState = state }, - ])); + this._ready.push( + this.addDeviceStates([ + { + name: 'ACTUAL', + valueType: ValueType.Enum, + accessType: StateAccessType.Read, + type: PropertyType.Value, + callback: state => (this._getValueState = state), + }, + ]), + ); } getValue(): number | undefined { @@ -26,4 +34,4 @@ class WindowTilt extends GenericDevice { } } -export default WindowTilt; \ No newline at end of file +export default WindowTilt; diff --git a/src/lib/i18n.ts b/src/lib/i18n.ts index c406541..295eaef 100644 --- a/src/lib/i18n.ts +++ b/src/lib/i18n.ts @@ -1,11 +1,11 @@ -import en from './i18n/en.json'; import de from './i18n/de.json'; -import it from './i18n/it.json'; -import fr from './i18n/fr.json'; +import en from './i18n/en.json'; import es from './i18n/es.json'; +import fr from './i18n/fr.json'; +import it from './i18n/it.json'; import nl from './i18n/nl.json'; -import pt from './i18n/pt.json'; import pl from './i18n/pl.json'; +import pt from './i18n/pt.json'; import ru from './i18n/ru.json'; import uk from './i18n/uk.json'; import zhCN from './i18n/zh-cn.json'; @@ -40,7 +40,7 @@ function init(): void { init(); -export function t(word: string, lang?: ioBroker.Languages): ioBroker.StringOrTranslated { +export function t(word: string, lang?: ioBroker.Languages): ioBroker.StringOrTranslated { if (!lang) { return words[word] || word; } diff --git a/src/lib/index.ts b/src/lib/index.ts index 6583235..fe340d3 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -1,3 +1,4 @@ +import DeviceFactory from './DeviceFactory'; import AirCondition from './devices/AirCondition'; import Blind from './devices/Blind'; import BlindButtons from './devices/BlindButtons'; @@ -7,7 +8,6 @@ import Camera from './devices/Camera'; import Chart from './devices/Chart'; import Cie from './devices/Cie'; import Ct from './devices/Ct'; -import DeviceFactory from './DeviceFactory'; import Dimmer from './devices/Dimmer'; import Door from './devices/Door'; import FireAlarm from './devices/FireAlarm'; @@ -18,7 +18,6 @@ import Hue from './devices/Hue'; import Humidity from './devices/Humidity'; import Image from './devices/Image'; import Info from './devices/Info'; -import Slider from './devices/Slider'; import Light from './devices/Light'; import Location from './devices/Location'; import LocationOne from './devices/LocationOne'; @@ -28,8 +27,8 @@ import Motion from './devices/Motion'; import Rgb from './devices/Rgb'; import RgbSingle from './devices/RgbSingle'; import RgbwSingle from './devices/RgbwSingle'; +import Slider from './devices/Slider'; import Socket from './devices/Socket'; -import SubscribeManager from './SubscribeManager'; import Temperature from './devices/Temperature'; import Thermostat from './devices/Thermostat'; import VacuumCleaner from './devices/VacuumCleaner'; @@ -40,6 +39,7 @@ import WeatherCurrent from './devices/WeatherCurrent'; import WeatherForecast from './devices/WeatherForecast'; import Window from './devices/Window'; import WindowTilt from './devices/WindowTilt'; +import SubscribeManager from './SubscribeManager'; export { AirCondition, @@ -62,7 +62,6 @@ export { Humidity, Image, Info, - Slider, Light, Location, LocationOne, @@ -72,6 +71,7 @@ export { Rgb, RgbSingle, RgbwSingle, + Slider, Socket, SubscribeManager, Temperature, @@ -84,4 +84,4 @@ export { WeatherForecast, Window, WindowTilt, -}; \ No newline at end of file +}; diff --git a/src/main.ts b/src/main.ts index f97cd65..c8fec71 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,28 +1,28 @@ +import '@project-chip/matter-node.js'; import axios from 'axios'; import jwt from 'jsonwebtoken'; import fs from 'node:fs'; -import '@project-chip/matter-node.js'; import * as utils from '@iobroker/adapter-core'; import ChannelDetector, { DetectorState, PatternControl, Types } from '@iobroker/type-detector'; import { Level, Logger } from '@project-chip/matter.js/log'; -import { IoBrokerNodeStorage } from './matter/IoBrokerNodeStorage'; -import { DeviceFactory, SubscribeManager } from './lib'; -import { DetectedDevice, DeviceOptions } from './lib/devices/GenericDevice'; -import BridgedDevice, { BridgeCreateOptions } from './matter/BridgedDevicesNode'; -import MatterDevice, { DeviceCreateOptions } from './matter/DeviceNode'; import { BridgeDescription, BridgeDeviceDescription, DeviceDescription, - MatterAdapterConfig + MatterAdapterConfig, } from './ioBrokerStorageTypes'; +import { DeviceFactory, SubscribeManager } from './lib'; +import { DetectedDevice, DeviceOptions } from './lib/devices/GenericDevice'; +import BridgedDevice, { BridgeCreateOptions } from './matter/BridgedDevicesNode'; import MatterController from './matter/ControllerNode'; +import MatterDevice, { DeviceCreateOptions } from './matter/DeviceNode'; +import { IoBrokerNodeStorage } from './matter/IoBrokerNodeStorage'; -import MatterAdapterDeviceManagement from './lib/DeviceManagement'; import { Environment, StorageService } from '@project-chip/matter.js/environment'; import { MatterControllerConfig } from '../src-admin/src/types'; +import MatterAdapterDeviceManagement from './lib/DeviceManagement'; import { NodeStateResponse } from './matter/BaseServerNode'; import { MessageResponse } from './matter/GeneralNode'; @@ -102,11 +102,11 @@ export class MatterAdapter extends utils.Adapter { this.log.debug(`Client "${clientId}: ${reason}`); } this.onClientUnsubscribe(clientId); - } + }, }); this.on('ready', () => this.onReady()); this.on('stateChange', (id, state) => this.onStateChange(id, state)); - this.on('objectChange', (id , object) => this.onObjectChange(id, object)); + this.on('objectChange', (id, object) => this.onObjectChange(id, object)); this.on('unload', callback => this.onUnload(callback)); this.on('message', this.onMessage.bind(this)); this.deviceManagement = new MatterAdapterDeviceManagement(this); @@ -182,7 +182,9 @@ export class MatterAdapter extends utils.Adapter { this.sendTo(obj.from, obj.command, result, obj.callback); } } catch (error) { - this.log.warn(`Error while handling command "${obj.command}" for device ${uuid}: ${error.stack}`); + this.log.warn( + `Error while handling command "${obj.command}" for device ${uuid}: ${error.stack}`, + ); if (obj.callback) { this.sendTo(obj.from, obj.command, { error: error.message }, obj.callback); } @@ -199,7 +201,9 @@ export class MatterAdapter extends utils.Adapter { this.sendTo(obj.from, obj.command, result, obj.callback); } } catch (error) { - this.log.warn(`Error while handling command "${obj.command}" for device ${uuid}: ${error.stack}`); + this.log.warn( + `Error while handling command "${obj.command}" for device ${uuid}: ${error.stack}`, + ); if (obj.callback) { this.sendTo(obj.from, obj.command, { error: error.message }, obj.callback); } @@ -234,7 +238,8 @@ export class MatterAdapter extends utils.Adapter { const newControllerConfig: MatterControllerConfig = JSON.parse(obj.message); this.log.info(JSON.stringify(newControllerConfig)); const result = await this.applyControllerConfiguration(newControllerConfig); - if (result && 'result' in result) { // was successful + if (result && 'result' in result) { + // was successful await this.extendObject(`${this.namespace}.controller`, { native: newControllerConfig }); } this.sendTo(obj.from, obj.command, result, obj.callback); @@ -247,10 +252,10 @@ export class MatterAdapter extends utils.Adapter { } } - async onClientSubscribe(clientId: string): Promise<{ error?: string, accepted: boolean, heartbeat?: number }> { + async onClientSubscribe(clientId: string): Promise<{ error?: string; accepted: boolean; heartbeat?: number }> { this.log.debug(`Subscribe from ${clientId}`); if (!this._guiSubscribes) { - return { error: `Adapter is still initializing`,accepted: false }; + return { error: `Adapter is still initializing`, accepted: false }; } // start camera with obj.message.data if (!this._guiSubscribes.find(s => s.clientId === clientId)) { @@ -263,7 +268,7 @@ export class MatterAdapter extends utils.Adapter { if (!sub) { this._guiSubscribes.push({ clientId, ts: Date.now() }); this.stateTimeout && clearTimeout(this.stateTimeout); - this.stateTimeout = setTimeout(async() => { + this.stateTimeout = setTimeout(async () => { this.stateTimeout = null; const states = await this.requestNodeStates(); await this.sendToGui({ command: 'bridgeStates', states }); @@ -288,10 +293,10 @@ export class MatterAdapter extends utils.Adapter { deleted = true; this._guiSubscribes.splice(pos, 1); } - } while(deleted); + } while (deleted); } - sendToGui = async(data: any): Promise => { + sendToGui = async (data: any): Promise => { if (!this._guiSubscribes) { return; } @@ -332,13 +337,13 @@ export class MatterAdapter extends utils.Adapter { * The storage manager is then also used by the Matter server, so this code block in general is required, * but you can choose a different storage backend as long as it implements the required API. */ - await this.extendObject('storage',{ + await this.extendObject('storage', { type: 'folder', common: { expert: true, name: 'Matter storage', }, - native: {} + native: {}, }); const storageService = this.matterEnvironment.get(StorageService); @@ -355,7 +360,9 @@ export class MatterAdapter extends utils.Adapter { SubscribeManager.setAdapter(this); await this.prepareMatterEnvironment(); - const systemConfig: ioBroker.SystemConfigObject = await this.getForeignObjectAsync('system.config') as ioBroker.SystemConfigObject; + const systemConfig: ioBroker.SystemConfigObject = (await this.getForeignObjectAsync( + 'system.config', + )) as ioBroker.SystemConfigObject; this.sysLanguage = systemConfig?.common?.language || 'en'; await this.syncDevices(); @@ -434,7 +441,7 @@ export class MatterAdapter extends utils.Adapter { if (obj && obj.type === 'state') { // we can go maximal three levels up: state => channel => device parts.pop(); - const channelId= parts.join('.'); + const channelId = parts.join('.'); obj = await this.getForeignObjectAsync(channelId); if (obj && (obj.type === 'device' || obj.type === 'channel')) { return channelId; @@ -470,7 +477,10 @@ export class MatterAdapter extends utils.Adapter { if (!obj) { return null; } - const states = await this.getObjectViewAsync('system', 'state', { startkey: `${deviceId}.`, endkey: `${deviceId}.\u9999` }); + const states = await this.getObjectViewAsync('system', 'state', { + startkey: `${deviceId}.`, + endkey: `${deviceId}.\u9999`, + }); const objects = { [obj._id]: obj }; for (const state of states.rows) { if (state.value) { @@ -478,15 +488,15 @@ export class MatterAdapter extends utils.Adapter { } } - const keys = Object.keys(objects); // For optimization - const usedIds: string[] = []; // To not allow using of same ID in more than one device - const ignoreIndicators = ['UNREACH_STICKY']; // Ignore indicators by name + const keys = Object.keys(objects); // For optimization + const usedIds: string[] = []; // To not allow using of same ID in more than one device + const ignoreIndicators = ['UNREACH_STICKY']; // Ignore indicators by name const options = { objects, - id: deviceId, // Channel, device or state, that must be detected - _keysOptional: keys, - _usedIdsOptional: usedIds, - ignoreIndicators + id: deviceId, // Channel, device or state, that must be detected + _keysOptional: keys, + _usedIdsOptional: usedIds, + ignoreIndicators, }; const controls = this.detector.detect(options); if (controls) { @@ -525,8 +535,8 @@ export class MatterAdapter extends utils.Adapter { response = await axios(`${IOBROKER_USER_API}/api/v1/subscriptions`, { headers: { 'Content-Type': 'application/json', - 'Authorization': `Basic ${Buffer.from(`${login}:${pass}`).toString('base64')}` - } + Authorization: `Basic ${Buffer.from(`${login}:${pass}`).toString('base64')}`, + }, }); } catch (e) { if (e.response.status === 401) { @@ -539,18 +549,20 @@ export class MatterAdapter extends utils.Adapter { } const subscriptions = response.data; const cert = fs.readFileSync(`${__dirname}/../data/cloudCert.crt`); - if (subscriptions.find((it: any) => { - try { - const decoded: any = jwt.verify(it.json, cert); - if (decoded.name?.startsWith('remote.') || decoded.name?.startsWith('assistant.')) { - return new Date(decoded.expires * 1000) > new Date(); + if ( + subscriptions.find((it: any) => { + try { + const decoded: any = jwt.verify(it.json, cert); + if (decoded.name?.startsWith('remote.') || decoded.name?.startsWith('assistant.')) { + return new Date(decoded.expires * 1000) > new Date(); + } + } catch (e) { + this.log.warn(`Cannot verify license: ${e}`); + this.license[key] = false; + return this.license[key]; } - } catch (e) { - this.log.warn(`Cannot verify license: ${e}`); - this.license[key] = false; - return this.license[key]; - } - })) { + }) + ) { this.license[key] = true; return this.license[key]; } @@ -560,8 +572,8 @@ export class MatterAdapter extends utils.Adapter { userResponse = await axios(`${IOBROKER_USER_API}/api/v1/user`, { headers: { 'Content-Type': 'application/json', - 'Authorization': `Basic ${Buffer.from(`${login}:${pass}`).toString('base64')}` - } + Authorization: `Basic ${Buffer.from(`${login}:${pass}`).toString('base64')}`, + }, }); } catch (e) { this.license[key] = false; @@ -586,7 +598,7 @@ export class MatterAdapter extends utils.Adapter { const optionsList = (options.list || []).filter(item => item.enabled !== false); for (let l = 0; l < optionsList.length; l++) { const device = optionsList[l]; - let detectedDevice = await this.getDeviceStates(device.oid) as DetectedDevice; + let detectedDevice = (await this.getDeviceStates(device.oid)) as DetectedDevice; if (!device.auto && (!detectedDevice || detectedDevice.type !== device.type)) { // ignore all detected states and let only one detectedDevice = { @@ -608,7 +620,9 @@ export class MatterAdapter extends utils.Adapter { if (deviceObject) { if (devices.length >= 5) { if (!(await this.checkLicense())) { - this.log.error('You cannot use more than 5 devices without ioBroker.pro subscription. Only first 5 devices will be created.}'); + this.log.error( + 'You cannot use more than 5 devices without ioBroker.pro subscription. Only first 5 devices will be created.}', + ); await deviceObject.destroy(); break; } @@ -649,12 +663,15 @@ export class MatterAdapter extends utils.Adapter { return null; } - async prepareMatterDeviceConfiguration(deviceName: string, options: DeviceDescription): Promise { + async prepareMatterDeviceConfiguration( + deviceName: string, + options: DeviceDescription, + ): Promise { if (options.enabled === false) { return null; // Not startup } let device; - let detectedDevice = await this.getDeviceStates(options.oid) as DetectedDevice; + let detectedDevice = (await this.getDeviceStates(options.oid)) as DetectedDevice; if (!options.auto && (!detectedDevice || detectedDevice.type !== options.type)) { // ignore all detected states and let only one detectedDevice = { @@ -710,7 +727,7 @@ export class MatterAdapter extends utils.Adapter { const matterController = new MatterController({ adapter: this, controllerOptions, - matterEnvironment: this.matterEnvironment + matterEnvironment: this.matterEnvironment, }); await matterController.init(); // add bridge to server @@ -729,21 +746,15 @@ export class MatterAdapter extends utils.Adapter { if (obj) { objects.push(obj); } else { - const devicesObjects = await this.getObjectViewAsync( - 'system', 'channel', - { - startkey: `${this.namespace}.devices.`, - endkey: `${this.namespace}.devices.\u9999`, - }, - ); + const devicesObjects = await this.getObjectViewAsync('system', 'channel', { + startkey: `${this.namespace}.devices.`, + endkey: `${this.namespace}.devices.\u9999`, + }); devicesObjects.rows.forEach(row => objects.push(row.value)); - const bridgesObjects = await this.getObjectViewAsync( - 'system', 'channel', - { - startkey: `${this.namespace}.bridges.`, - endkey: `${this.namespace}.bridges.\u9999`, - }, - ); + const bridgesObjects = await this.getObjectViewAsync('system', 'channel', { + startkey: `${this.namespace}.bridges.`, + endkey: `${this.namespace}.bridges.\u9999`, + }); bridgesObjects.rows.forEach(row => objects.push(row.value)); } @@ -803,7 +814,9 @@ export class MatterAdapter extends utils.Adapter { if (Object.keys(this.bridges).length) { // check license if (!(await this.checkLicense())) { - this.log.error(`You cannot use more than one bridge without ioBroker.pro subscription. Bridge "${bridge._id}" will be ignored.}`); + this.log.error( + `You cannot use more than one bridge without ioBroker.pro subscription. Bridge "${bridge._id}" will be ignored.}`, + ); await matterBridge.stop(); break; } @@ -817,7 +830,9 @@ export class MatterAdapter extends utils.Adapter { this.log.info(`Apply configuration update for bridge "${bridge._id}".`); await existingBridge.applyConfiguration(config); } else { - this.log.info(`Configuration for bridge "${bridge._id}" is no longer valid or bridge disabled. Stopping it now.`); + this.log.info( + `Configuration for bridge "${bridge._id}" is no longer valid or bridge disabled. Stopping it now.`, + ); await existingBridge.stop(); } } @@ -825,18 +840,21 @@ export class MatterAdapter extends utils.Adapter { // Objects exist and enabled: Sync devices for (const device of devices) { - const deviceName = typeof device.common.name === 'object' ? - (device.common.name[this.sysLanguage] ? device.common.name[this.sysLanguage] as string : device.common.name.en) : device.common.name; + const deviceName = + typeof device.common.name === 'object' + ? device.common.name[this.sysLanguage] + ? (device.common.name[this.sysLanguage] as string) + : device.common.name.en + : device.common.name; const existingDevice = this.devices.get(device._id); if (existingDevice === undefined) { - const matterDevice = await this.createMatterDevice( - deviceName, - device.native as DeviceDescription - ); + const matterDevice = await this.createMatterDevice(deviceName, device.native as DeviceDescription); if (matterDevice) { if (Object.keys(this.devices).length >= 2) { if (!(await this.checkLicense())) { - this.log.error('You cannot use more than 2 devices without ioBroker.pro subscription. Only first 2 devices will be created.}'); + this.log.error( + 'You cannot use more than 2 devices without ioBroker.pro subscription. Only first 2 devices will be created.}', + ); await matterDevice.stop(); break; } @@ -844,12 +862,17 @@ export class MatterAdapter extends utils.Adapter { this.devices.set(device._id, matterDevice); } } else { - const config = await this.prepareMatterDeviceConfiguration(deviceName, device.native as DeviceDescription); + const config = await this.prepareMatterDeviceConfiguration( + deviceName, + device.native as DeviceDescription, + ); if (config) { this.log.info(`Apply configuration update for device "${device._id}".`); await existingDevice.applyConfiguration(config); } else { - this.log.info(`Configuration for device "${device._id}" is no longer valid or bridge disabled. Stopping it now.`); + this.log.info( + `Configuration for device "${device._id}" is no longer valid or bridge disabled. Stopping it now.`, + ); await existingDevice.stop(); } } diff --git a/src/matter/BaseServerNode.ts b/src/matter/BaseServerNode.ts index cd63277..94dd88a 100644 --- a/src/matter/BaseServerNode.ts +++ b/src/matter/BaseServerNode.ts @@ -1,6 +1,6 @@ -import { GeneralNode, MessageResponse } from './GeneralNode'; -import type { MatterAdapter } from '../main'; import { ServerNode } from '@project-chip/matter.js/node'; +import type { MatterAdapter } from '../main'; +import { GeneralNode, MessageResponse } from './GeneralNode'; export enum NodeStates { Creating = 'creating', @@ -27,8 +27,7 @@ export abstract class BaseServerNode implements GeneralNode { abstract uuid: string; - protected constructor(protected adapter: MatterAdapter) { - } + protected constructor(protected adapter: MatterAdapter) {} async advertise(): Promise { await this.serverNode?.advertiseNow(); diff --git a/src/matter/BridgedDevicesNode.ts b/src/matter/BridgedDevicesNode.ts index 199700f..e02517d 100644 --- a/src/matter/BridgedDevicesNode.ts +++ b/src/matter/BridgedDevicesNode.ts @@ -1,24 +1,22 @@ import { VendorId } from '@project-chip/matter.js/datatype'; import { DeviceTypes } from '@project-chip/matter.js/device'; -import { GenericDevice } from '../lib'; -import { BridgeDeviceDescription } from '../ioBrokerStorageTypes'; import { Logger } from '@project-chip/matter.js/log'; +import { BridgeDeviceDescription } from '../ioBrokerStorageTypes'; +import { GenericDevice } from '../lib'; -import matterDeviceFactory from './matterFactory'; -import VENDOR_IDS from './vendorIds'; -import type { MatterAdapter } from '../main'; -import { ServerNode } from '@project-chip/matter.js/node'; +import { BridgedDeviceBasicInformationServer } from '@project-chip/matter.js/behavior/definitions/bridged-device-basic-information'; import { SessionsBehavior } from '@project-chip/matter.js/behavior/system/sessions'; import { Endpoint } from '@project-chip/matter.js/endpoint'; import { AggregatorEndpoint } from '@project-chip/matter.js/endpoint/definitions'; -import { - BridgedDeviceBasicInformationServer -} from '@project-chip/matter.js/behavior/definitions/bridged-device-basic-information'; +import { ServerNode } from '@project-chip/matter.js/node'; +import type { MatterAdapter } from '../main'; import { BaseServerNode, ConnectionInfo, NodeStateResponse, NodeStates } from './BaseServerNode'; +import matterDeviceFactory from './matterFactory'; +import VENDOR_IDS from './vendorIds'; export interface BridgeCreateOptions { - parameters: BridgeOptions, + parameters: BridgeOptions; devices: GenericDevice[]; devicesOptions: BridgeDeviceDescription[]; } @@ -77,7 +75,7 @@ class BridgedDevices extends BaseServerNode { const vendorName = 'ioBroker'; // product name / id and vendor id should match what is in the device certificate - const vendorId = this.parameters.vendorId;// 0xfff1; + const vendorId = this.parameters.vendorId; // 0xfff1; const productName = `ioBroker Bridge`; const productId = this.parameters.productId; // 0x8000; @@ -98,7 +96,7 @@ class BridgedDevices extends BaseServerNode { this.serverNode = await ServerNode.create({ id: this.parameters.uuid, network: { - port: this.parameters.port + port: this.parameters.port, }, productDescription: { name: deviceName, @@ -134,7 +132,11 @@ class BridgedDevices extends BaseServerNode { for (let i = 0; i < this.devices.length; i++) { const ioBrokerDevice = this.devices[i]; - const mappingDevice = await matterDeviceFactory(ioBrokerDevice, this.devicesOptions[i].name, this.devicesOptions[i].uuid); + const mappingDevice = await matterDeviceFactory( + ioBrokerDevice, + this.devicesOptions[i].name, + this.devicesOptions[i].uuid, + ); if (mappingDevice) { const name = mappingDevice.getName(); const bridgedDevice = mappingDevice.getMatterDevice(); @@ -148,22 +150,32 @@ class BridgedDevices extends BaseServerNode { await aggregator.add(bridgedDevice); await mappingDevice.init(); } else { - this.adapter.log.error(`ioBroker Device in Bridge "${this.devices[i].getDeviceType()}" is not supported`); + this.adapter.log.error( + `ioBroker Device in Bridge "${this.devices[i].getDeviceType()}" is not supported`, + ); } } - this.serverNode.events.commissioning.fabricsChanged.on(async(fabricIndex) => { + this.serverNode.events.commissioning.fabricsChanged.on(async fabricIndex => { this.adapter.log.debug( - `commissioningChangedCallback: Commissioning changed on Fabric ${fabricIndex}: ${this.serverNode?.state.operationalCredentials.fabrics.find(fabric => fabric.fabricIndex === fabricIndex)}`); + `commissioningChangedCallback: Commissioning changed on Fabric ${fabricIndex}: ${this.serverNode?.state.operationalCredentials.fabrics.find(fabric => fabric.fabricIndex === fabricIndex)}`, + ); // TODO find replacement for ${Logger.toJSON(this.serverNode?.getCommissionedFabricInformation(fabricIndex)[0])} - await this.adapter.sendToGui({ command: 'updateStates', states: { [this.parameters.uuid]: await this.getState() } }); + await this.adapter.sendToGui({ + command: 'updateStates', + states: { [this.parameters.uuid]: await this.getState() }, + }); }); - const sessionChange = async(session: SessionsBehavior.Session): Promise => { + const sessionChange = async (session: SessionsBehavior.Session): Promise => { this.adapter.log.debug( `activeSessionsChangedCallback: Active sessions changed on Fabric ${session.fabric?.fabricIndex}` + - Logger.toJSON(session)); - await this.adapter.sendToGui({ command: 'updateStates', states: { [this.parameters.uuid]: await this.getState() } }); + Logger.toJSON(session), + ); + await this.adapter.sendToGui({ + command: 'updateStates', + states: { [this.parameters.uuid]: await this.getState() }, + }); }; this.serverNode.events.sessions.opened.on(sessionChange); this.serverNode.events.sessions.closed.on(sessionChange); diff --git a/src/matter/ControllerNode.ts b/src/matter/ControllerNode.ts index 1bbe302..c99b959 100644 --- a/src/matter/ControllerNode.ts +++ b/src/matter/ControllerNode.ts @@ -1,40 +1,33 @@ +import { CommissioningController, NodeCommissioningOptions } from '@project-chip/matter.js'; import { - CommissioningController, - NodeCommissioningOptions, -} from '@project-chip/matter.js'; -import { NodeId /* , ClusterId */ } from '@project-chip/matter.js/datatype'; -import { - Endpoint, CommissioningControllerNodeOptions, - PairedNode, -} from '@project-chip/matter.js/device'; -import { toHex, singleton } from '@project-chip/matter.js/util'; -import { + AnyAttributeServer, asClusterServerInternal, + BasicInformationCluster, ClusterServerObj, + FabricScopeError, GlobalAttributes, - AnyAttributeServer, FabricScopeError, - BasicInformationCluster, } from '@project-chip/matter.js/cluster'; import { CommissionableDevice, DiscoveryData } from '@project-chip/matter.js/common'; +import { NodeId /* , ClusterId */ } from '@project-chip/matter.js/datatype'; +import { CommissioningControllerNodeOptions, Endpoint, PairedNode } from '@project-chip/matter.js/device'; +import { singleton, toHex } from '@project-chip/matter.js/util'; -import { ManualPairingCodeCodec, QrPairingCodeCodec } from '@project-chip/matter.js/schema'; import { NodeStateInformation } from '@project-chip/matter.js/device'; import { Logger } from '@project-chip/matter.js/log'; +import { ManualPairingCodeCodec, QrPairingCodeCodec } from '@project-chip/matter.js/schema'; +import { GeneralCommissioning } from '@project-chip/matter.js/cluster'; import { CommissioningOptions } from '@project-chip/matter.js/protocol'; -import { - GeneralCommissioning, -} from '@project-chip/matter.js/cluster'; import { BleNode } from '@project-chip/matter-node-ble.js/ble'; import { Ble } from '@project-chip/matter.js/ble'; +import { Environment } from '@project-chip/matter.js/environment'; +import { MatterControllerConfig } from '../../src-admin/src/types'; import type { MatterAdapter } from '../main'; -import Factories from './clusters/factories'; import Base from './clusters/Base'; -import { Environment } from '@project-chip/matter.js/environment'; +import Factories from './clusters/factories'; import { GeneralNode, MessageResponse } from './GeneralNode'; -import { MatterControllerConfig } from '../../src-admin/src/types'; export interface ControllerCreateOptions { adapter: MatterAdapter; @@ -93,7 +86,7 @@ class Controller implements GeneralNode { private readonly adapter: MatterAdapter; private readonly matterEnvironment: Environment; private commissioningController?: CommissioningController; - private devices= new Map(); + private devices = new Map(); private delayedStates: { [nodeId: string]: NodeStateInformation } = {}; private connected: { [nodeId: string]: boolean } = {}; private discovering = false; @@ -112,8 +105,8 @@ class Controller implements GeneralNode { // TODO add listeningAddressIpv4 and listeningAddressIpv6 to limit controller to one network interface environment: { environment: this.matterEnvironment, - id: 'controller' - } + id: 'controller', + }, }); } @@ -122,10 +115,11 @@ class Controller implements GeneralNode { this.useBle = false; if (config.ble !== currentConfig.ble || config.hciId !== currentConfig.hciId) { - if (config.ble && ( - (config.wifiSSID && config.wifiPassword) || - (config.threadNetworkName !== undefined && config.threadOperationalDataSet !== undefined) - )) { + if ( + config.ble && + ((config.wifiSSID && config.wifiPassword) || + (config.threadNetworkName !== undefined && config.threadOperationalDataSet !== undefined)) + ) { try { const hciId = config.hciId === undefined ? undefined : parseInt(config.hciId); Ble.get = singleton(() => new BleNode({ hciId })); @@ -170,7 +164,9 @@ class Controller implements GeneralNode { return { result: this.commissioningController.paseCommissionerData }; case 'controllerCompletePaseCommissioning': // Completes a commissioning process that was started by the mobile app in the main controller - return { result: await this.completeCommissioningForNode(message.peerNodeId, message.discoveryData) }; + return { + result: await this.completeCommissioningForNode(message.peerNodeId, message.discoveryData), + }; } } catch (error) { this.adapter.log.warn(`Error while executing command "${command}": ${error.stack}`); @@ -182,7 +178,10 @@ class Controller implements GeneralNode { initEventHandlers(originalNodeId: NodeId | null, options?: any): any { return Object.assign(options || {}, { - attributeChangedCallback: (peerNodeId: NodeId, { path: { nodeId, clusterId, endpointId, attributeName }, value }: any) => { + attributeChangedCallback: ( + peerNodeId: NodeId, + { path: { nodeId, clusterId, endpointId, attributeName }, value }: any, + ) => { this.adapter.log.debug( `attributeChangedCallback ${peerNodeId}: Attribute ${nodeId}/${endpointId}/${clusterId}/${attributeName} changed to ${Logger.toJSON( value, @@ -190,7 +189,10 @@ class Controller implements GeneralNode { ); }, - eventTriggeredCallback: (peerNodeId: NodeId, { path: { nodeId, clusterId, endpointId, eventName }, events }: any) => { + eventTriggeredCallback: ( + peerNodeId: NodeId, + { path: { nodeId, clusterId, endpointId, eventName }, events }: any, + ) => { this.adapter.log.debug( `eventTriggeredCallback ${peerNodeId}: Event ${nodeId}/${endpointId}/${clusterId}/${eventName} triggered with ${Logger.toJSON( events, @@ -198,7 +200,7 @@ class Controller implements GeneralNode { ); }, - stateInformationCallback: async(peerNodeId: NodeId, info: NodeStateInformation) => { + stateInformationCallback: async (peerNodeId: NodeId, info: NodeStateInformation) => { const jsonNodeId = peerNodeId.toString(); const node = this.commissioningController?.getConnectedNode(peerNodeId); const device: Device | undefined = this.devices.get(jsonNodeId); @@ -213,8 +215,14 @@ class Controller implements GeneralNode { } if (device) { - device.connectionStateId && (await this.adapter.setStateAsync(device.connectionStateId, info === NodeStateInformation.Connected, true)); - device.connectionStatusId && (await this.adapter.setStateAsync(device.connectionStatusId, info, true)); + device.connectionStateId && + (await this.adapter.setStateAsync( + device.connectionStateId, + info === NodeStateInformation.Connected, + true, + )); + device.connectionStatusId && + (await this.adapter.setStateAsync(device.connectionStatusId, info, true)); } else { this.adapter.log.warn(`Device ${jsonNodeId} not found`); // delayed state @@ -223,13 +231,19 @@ class Controller implements GeneralNode { switch (info) { case NodeStateInformation.Connected: - this.adapter.log.debug(`stateInformationCallback ${peerNodeId}: Node ${originalNodeId} connected`); + this.adapter.log.debug( + `stateInformationCallback ${peerNodeId}: Node ${originalNodeId} connected`, + ); break; case NodeStateInformation.Disconnected: - this.adapter.log.debug(`stateInformationCallback ${peerNodeId}: Node ${originalNodeId} disconnected`); + this.adapter.log.debug( + `stateInformationCallback ${peerNodeId}: Node ${originalNodeId} disconnected`, + ); break; case NodeStateInformation.Reconnecting: - this.adapter.log.debug(`stateInformationCallback ${peerNodeId}: Node ${originalNodeId} reconnecting`); + this.adapter.log.debug( + `stateInformationCallback ${peerNodeId}: Node ${originalNodeId} reconnecting`, + ); break; case NodeStateInformation.WaitingForDeviceDiscovery: this.adapter.log.debug( @@ -237,7 +251,9 @@ class Controller implements GeneralNode { ); break; case NodeStateInformation.StructureChanged: - this.adapter.log.debug(`stateInformationCallback ${peerNodeId}: Node ${originalNodeId} structure changed`); + this.adapter.log.debug( + `stateInformationCallback ${peerNodeId}: Node ${originalNodeId} structure changed`, + ); break; } }, @@ -254,9 +270,7 @@ class Controller implements GeneralNode { common: { name: 'Information', }, - native: { - - }, + native: {}, }); await this.adapter.extendObject('controller.info.discovering', { @@ -267,10 +281,9 @@ class Controller implements GeneralNode { type: 'boolean', read: true, write: false, - def: false - }, - native: { + def: false, }, + native: {}, }); await this.adapter.setState('controller.info.discovering', false, true); @@ -284,7 +297,10 @@ class Controller implements GeneralNode { // attach all nodes to the controller for (const nodeId of nodes) { try { - const node = await this.commissioningController.connectNode(nodeId, this.initEventHandlers(nodeId) as CommissioningControllerNodeOptions); + const node = await this.commissioningController.connectNode( + nodeId, + this.initEventHandlers(nodeId) as CommissioningControllerNodeOptions, + ); await this.nodeToIoBrokerStructure(node); } catch (error) { this.adapter.log.info(`Failed to connect to node ${nodeId}: ${error.stack}`); @@ -324,7 +340,8 @@ class Controller implements GeneralNode { this.adapter.log.debug( `${''.padStart(level * 2)}Cluster-Server "${clusterServer.name}" (${toHex(clusterServer.id)}) ${ supportedFeatures.length ? `(Features: ${supportedFeatures.join(', ')})` : '' - }`); + }`, + ); this.adapter.log.debug(`${''.padStart(level * 2 + 2)}Global-Attributes:`); for (const attributeName in globalAttributes) { const attribute = clusterServer.attributes[attributeName]; @@ -359,7 +376,9 @@ class Controller implements GeneralNode { for (const commandName in commands) { const command = commands[commandName]; if (command === undefined) continue; - this.adapter.log.debug(`${''.padStart(level * 2 + 4)}"${command.name}" (${toHex(command.invokeId)}/${command.responseId})`); + this.adapter.log.debug( + `${''.padStart(level * 2 + 4)}"${command.name}" (${toHex(command.invokeId)}/${command.responseId})`, + ); } this.adapter.log.debug(`${''.padStart(level * 2 + 2)}Events:`); @@ -398,7 +417,7 @@ class Controller implements GeneralNode { // } this.adapter.log.debug( - `${''.padStart(level * 2)}Cluster-Client "${clusterClient.name}" (${toHex(clusterClient.id)}) ${supportedFeatures.length ? `(Features: ${supportedFeatures.join(', ')})` : ''}` + `${''.padStart(level * 2)}Cluster-Client "${clusterClient.name}" (${toHex(clusterClient.id)}) ${supportedFeatures.length ? `(Features: ${supportedFeatures.join(', ')})` : ''}`, ); this.adapter.log.debug(`${''.padStart(level * 2 + 2)}Global-Attributes:`); for (const attributeName in globalAttributes) { @@ -407,7 +426,9 @@ class Controller implements GeneralNode { continue; } - this.adapter.log.debug(`${''.padStart(level * 2 + 4)}"${attribute.name}" (${toHex(attribute.id)}) = ${this.getAttributeServerValue(attribute)}`); + this.adapter.log.debug( + `${''.padStart(level * 2 + 4)}"${attribute.name}" (${toHex(attribute.id)}) = ${this.getAttributeServerValue(attribute)}`, + ); } this.adapter.log.debug(`${''.padStart(level * 2 + 2)}Attributes:`); @@ -428,7 +449,9 @@ class Controller implements GeneralNode { // if (unknown) { // info += " (Unknown)"; // } - this.adapter.log.debug(`${''.padStart(level * 2 + 4)}"${attribute.name}" (${toHex(attribute.id)}) = ${this.getAttributeServerValue(attribute)}`); + this.adapter.log.debug( + `${''.padStart(level * 2 + 4)}"${attribute.name}" (${toHex(attribute.id)}) = ${this.getAttributeServerValue(attribute)}`, + ); } this.adapter.log.debug(`${''.padStart(level * 2 + 2)}Commands:`); @@ -485,11 +508,7 @@ class Controller implements GeneralNode { const id = `controller.${nodeIdString}`; let deviceObj = await this.adapter.getObjectAsync(id); let changed = false; - if ( - !deviceObj || - (deviceObj.type === 'folder' && !bridge) || - (deviceObj.type === 'device' && bridge) - ) { + if (!deviceObj || (deviceObj.type === 'folder' && !bridge) || (deviceObj.type === 'device' && bridge)) { changed = true; const oldCommon = deviceObj?.common || undefined; @@ -517,7 +536,7 @@ class Controller implements GeneralNode { deviceObj.common.desc = oldCommon.desc; } - deviceObj && await this.adapter.setObjectAsync(deviceObj._id, deviceObj); + deviceObj && (await this.adapter.setObjectAsync(deviceObj._id, deviceObj)); } const device: Device = { @@ -536,7 +555,7 @@ class Controller implements GeneralNode { }); device.connectionStateId = `controller.${nodeIdString}.info.connection`; - await this.adapter.getObjectAsync(device.connectionStateId,{ + await this.adapter.getObjectAsync(device.connectionStateId, { type: 'state', common: { name: 'Connected', @@ -569,7 +588,11 @@ class Controller implements GeneralNode { }); if (this.delayedStates[nodeIdString] !== undefined) { - await this.adapter.setState(device.connectionStateId, this.delayedStates[nodeIdString] === NodeStateInformation.Connected, true); + await this.adapter.setState( + device.connectionStateId, + this.delayedStates[nodeIdString] === NodeStateInformation.Connected, + true, + ); await this.adapter.setState(device.connectionStatusId, this.delayedStates[nodeIdString], true); delete this.delayedStates[nodeIdString]; } @@ -635,7 +658,13 @@ class Controller implements GeneralNode { } } - async endPointToIoBrokerStructure(nodeId: NodeId, endpoint: Endpoint, level: number, path: number[], device: Device): Promise { + async endPointToIoBrokerStructure( + nodeId: NodeId, + endpoint: Endpoint, + level: number, + path: number[], + device: Device, + ): Promise { this.adapter.log.info(`${''.padStart(level * 2)}Endpoint ${endpoint.number} (${endpoint.name}):`); if (level) { for (let f = 0; f < Factories.length; f++) { @@ -689,8 +718,13 @@ class Controller implements GeneralNode { wifiCredentials: this.parameters.wifiPassword, }; } - if (this.parameters.threadNetworkName !== undefined && this.parameters.threadOperationalDataSet !== undefined) { - this.adapter.log.debug(`Registering Commissioning over BLE with Thread: ${this.parameters.threadNetworkName}`); + if ( + this.parameters.threadNetworkName !== undefined && + this.parameters.threadOperationalDataSet !== undefined + ) { + this.adapter.log.debug( + `Registering Commissioning over BLE with Thread: ${this.parameters.threadNetworkName}`, + ); commissioningOptions.threadNetwork = { networkName: this.parameters.threadNetworkName, operationalDataset: this.parameters.threadOperationalDataSet, @@ -722,11 +756,12 @@ class Controller implements GeneralNode { commissioning: commissioningOptions, discovery: { commissionableDevice: device || undefined, - identifierData: longDiscriminator !== undefined - ? { longDiscriminator } - : shortDiscriminator !== undefined - ? { shortDiscriminator } - : undefined, + identifierData: + longDiscriminator !== undefined + ? { longDiscriminator } + : shortDiscriminator !== undefined + ? { shortDiscriminator } + : undefined, }, passcode, }) as NodeCommissioningOptions; @@ -776,7 +811,7 @@ class Controller implements GeneralNode { if (!this.commissioningController) { return null; } - await this.adapter.setState('controller.info.discovering', true, true ); + await this.adapter.setState('controller.info.discovering', true, true); this.discovering = true; this.adapter.log.info(`Start the discovering...`); const result = await this.commissioningController.discoverCommissionableDevices( diff --git a/src/matter/DeviceNode.ts b/src/matter/DeviceNode.ts index 8278e94..1e00b76 100644 --- a/src/matter/DeviceNode.ts +++ b/src/matter/DeviceNode.ts @@ -2,18 +2,18 @@ import { VendorId } from '@project-chip/matter.js/datatype'; import { DeviceTypes } from '@project-chip/matter.js/device'; import { Logger } from '@project-chip/matter.js/log'; -import { GenericDevice } from '../lib'; import { DeviceDescription } from '../ioBrokerStorageTypes'; +import { GenericDevice } from '../lib'; -import matterDeviceFactory from './matterFactory'; -import VENDOR_IDS from './vendorIds'; -import { ServerNode } from '@project-chip/matter.js/node'; import { SessionsBehavior } from '@project-chip/matter.js/behavior/system/sessions'; -import { BaseServerNode, NodeStateResponse, NodeStates } from './BaseServerNode'; +import { ServerNode } from '@project-chip/matter.js/node'; import type { MatterAdapter } from '../main'; +import { BaseServerNode, NodeStateResponse, NodeStates } from './BaseServerNode'; +import matterDeviceFactory from './matterFactory'; +import VENDOR_IDS from './vendorIds'; export interface DeviceCreateOptions { - parameters: DeviceOptions, + parameters: DeviceOptions; device: GenericDevice; deviceOptions: DeviceDescription; } @@ -93,7 +93,7 @@ class Device extends BaseServerNode { this.serverNode = await ServerNode.create({ id: this.parameters.uuid, network: { - port: this.parameters.port + port: this.parameters.port, }, productDescription: { name: deviceName, @@ -133,23 +133,30 @@ class Device extends BaseServerNode { return; } - this.serverNode.events.commissioning.fabricsChanged.on(async(fabricIndex) => { + this.serverNode.events.commissioning.fabricsChanged.on(async fabricIndex => { this.adapter.log.debug( - `commissioningChangedCallback: Commissioning changed on Fabric ${fabricIndex}: ${this.serverNode?.state.operationalCredentials.fabrics.find(fabric => fabric.fabricIndex === fabricIndex)}`); + `commissioningChangedCallback: Commissioning changed on Fabric ${fabricIndex}: ${this.serverNode?.state.operationalCredentials.fabrics.find(fabric => fabric.fabricIndex === fabricIndex)}`, + ); // TODO find replacement for ${Logger.toJSON(this.serverNode?.getCommissionedFabricInformation(fabricIndex)[0])} - await this.adapter.sendToGui({ command: 'updateStates', states: { [this.parameters.uuid]: await this.getState() } }); + await this.adapter.sendToGui({ + command: 'updateStates', + states: { [this.parameters.uuid]: await this.getState() }, + }); }); - const sessionChange = async(session: SessionsBehavior.Session): Promise => { + const sessionChange = async (session: SessionsBehavior.Session): Promise => { this.adapter.log.debug( `activeSessionsChangedCallback: Active sessions changed on Fabric ${session.fabric?.fabricIndex}` + - Logger.toJSON(session)); - await this.adapter.sendToGui({ command: 'updateStates', states: { [this.parameters.uuid]: await this.getState() } }); + Logger.toJSON(session), + ); + await this.adapter.sendToGui({ + command: 'updateStates', + states: { [this.parameters.uuid]: await this.getState() }, + }); }; this.serverNode.events.sessions.opened.on(sessionChange); this.serverNode.events.sessions.closed.on(sessionChange); this.serverNode.events.sessions.subscriptionsChanged.on(sessionChange); - } async applyConfiguration(_options: DeviceCreateOptions): Promise { diff --git a/src/matter/GeneralNode.ts b/src/matter/GeneralNode.ts index bd8d7ea..d12e82c 100644 --- a/src/matter/GeneralNode.ts +++ b/src/matter/GeneralNode.ts @@ -1,5 +1,4 @@ - -export type MessageResponse = void | { result: any } | { error: string }; +export type MessageResponse = void | { result: any } | { error: string }; export interface GeneralNode { handleCommand(command: string, message: ioBroker.MessagePayload): Promise; diff --git a/src/matter/IoBrokerNodeStorage.ts b/src/matter/IoBrokerNodeStorage.ts index 27a55b6..0e4f8db 100644 --- a/src/matter/IoBrokerNodeStorage.ts +++ b/src/matter/IoBrokerNodeStorage.ts @@ -1,8 +1,9 @@ import { - fromJson, MaybeAsyncStorage, + fromJson, + MaybeAsyncStorage, StorageError, SupportedStorageTypes, - toJson + toJson, } from '@project-chip/matter.js/storage'; /** @@ -16,7 +17,7 @@ export class IoBrokerNodeStorage implements MaybeAsyncStorage { constructor( private readonly adapter: ioBroker.Adapter, private namespace: string, - private clear = false + private clear = false, ) { this.storageRootOid = `storage.${this.namespace}`; } @@ -30,7 +31,7 @@ export class IoBrokerNodeStorage implements MaybeAsyncStorage { expert: true, name: 'Matter storage', }, - native: {} + native: {}, }); if (this.clear) { @@ -77,7 +78,9 @@ export class IoBrokerNodeStorage implements MaybeAsyncStorage { return undefined; } if (typeof valueState.val !== 'string') { - this.adapter.log.error(`[STORAGE] Invalid value for key "${key}" in context "${contexts.join('$$')}": ${toJson(valueState.val)}`); + this.adapter.log.error( + `[STORAGE] Invalid value for key "${key}" in context "${contexts.join('$$')}": ${toJson(valueState.val)}`, + ); return undefined; } return fromJson(valueState.val) as T; @@ -115,7 +118,7 @@ export class IoBrokerNodeStorage implements MaybeAsyncStorage { const values = {} as Record; const keys = await this.keys(contexts); for (const key in keys) { - values[key] = await this.get(contexts,key); + values[key] = await this.get(contexts, key); } return values; } @@ -139,7 +142,7 @@ export class IoBrokerNodeStorage implements MaybeAsyncStorage { read: true, write: false, }, - native: {} + native: {}, }); this.existingObjectIds.add(oid); } @@ -149,7 +152,11 @@ export class IoBrokerNodeStorage implements MaybeAsyncStorage { } } - async set(contexts: string[], keyOrValue: string | Record, value?: SupportedStorageTypes): Promise { + async set( + contexts: string[], + keyOrValue: string | Record, + value?: SupportedStorageTypes, + ): Promise { if (typeof keyOrValue === 'string') { await this.#setKey(contexts, keyOrValue, value); } else { diff --git a/src/matter/clusters/Base.ts b/src/matter/clusters/Base.ts index 811b878..4aac759 100644 --- a/src/matter/clusters/Base.ts +++ b/src/matter/clusters/Base.ts @@ -1,11 +1,9 @@ -import { Logger } from '@project-chip/matter-node.js/log'; -import { MatterAdapter } from '../../main'; import { NodeId } from '@project-chip/matter-node.js/datatype'; +import { DeviceTypeDefinition, Endpoint } from '@project-chip/matter-node.js/device'; +import { Logger } from '@project-chip/matter-node.js/log'; import { AtLeastOne } from '@project-chip/matter-node.js/util'; -import { - Endpoint, DeviceTypeDefinition, -} from '@project-chip/matter-node.js/device'; import { SubscribeManager } from '../../lib'; +import { MatterAdapter } from '../../main'; class Base { protected adapter: MatterAdapter; @@ -25,19 +23,17 @@ class Base { this.prefix = `${newPath.join('.')}.`; // create folder const id = `controller.${this.jsonNodeId.replace(/"/g, '')}.${this.prefix.substring(0, this.prefix.length - 1)}`; - this.adapter.getObjectAsync(id) - .then(obj => { - if (!obj) { - this.adapter.setObjectAsync(id, { - type: 'device', - common: { - name: `Device ${this.prefix.substring(0, this.prefix.length - 1)}`, - }, - native: { - }, - }); - } - }); + this.adapter.getObjectAsync(id).then(obj => { + if (!obj) { + this.adapter.setObjectAsync(id, { + type: 'device', + common: { + name: `Device ${this.prefix.substring(0, this.prefix.length - 1)}`, + }, + native: {}, + }); + } + }); } else { this.prefix = ''; } @@ -79,8 +75,11 @@ class Base { _id: id, type: 'channel', common: { - name: deviceType ? deviceType.name.replace(/^MA-/, '') : - (deviceTypes[0] ? deviceTypes[0].name.replace(/^MA-/, '') :'Unknown'), + name: deviceType + ? deviceType.name.replace(/^MA-/, '') + : deviceTypes[0] + ? deviceTypes[0].name.replace(/^MA-/, '') + : 'Unknown', }, native: { nodeId: this.jsonNodeId, diff --git a/src/matter/clusters/BooleanState.ts b/src/matter/clusters/BooleanState.ts index 471e494..0a17758 100644 --- a/src/matter/clusters/BooleanState.ts +++ b/src/matter/clusters/BooleanState.ts @@ -1,9 +1,9 @@ -import { Endpoint } from '@project-chip/matter-node.js/device'; import { BooleanStateCluster } from '@project-chip/matter-node.js/cluster'; import { NodeId } from '@project-chip/matter-node.js/datatype'; +import { Endpoint } from '@project-chip/matter-node.js/device'; -import Base from './Base'; import { MatterAdapter } from '../../main'; +import Base from './Base'; class BooleanState extends Base { private handler: ((value: boolean) => void) | undefined = undefined; @@ -29,7 +29,7 @@ class BooleanState extends Base { await cluster.getStateValueAttribute(), ); - this.handler = async(value: boolean) => { + this.handler = async (value: boolean) => { await this.adapter.setStateAsync(id, value, true); }; @@ -45,7 +45,12 @@ class BooleanState extends Base { } } - static async factory(adapter: MatterAdapter, nodeId: NodeId, endpoint: Endpoint, path: number[]): Promise { + static async factory( + adapter: MatterAdapter, + nodeId: NodeId, + endpoint: Endpoint, + path: number[], + ): Promise { const cluster = endpoint.getClusterClient(BooleanStateCluster); if (!cluster) { return; diff --git a/src/matter/clusters/Identify.ts b/src/matter/clusters/Identify.ts index 01feb38..29d3d57 100644 --- a/src/matter/clusters/Identify.ts +++ b/src/matter/clusters/Identify.ts @@ -1,9 +1,9 @@ -import { Endpoint } from '@project-chip/matter-node.js/device'; import { IdentifyCluster } from '@project-chip/matter-node.js/cluster'; import { NodeId } from '@project-chip/matter-node.js/datatype'; +import { Endpoint } from '@project-chip/matter-node.js/device'; -import Base from './Base'; import { MatterAdapter } from '../../main'; +import Base from './Base'; class Identify extends Base { private handlerType: ((value: number) => void) | undefined = undefined; @@ -70,10 +70,10 @@ class Identify extends Base { await cluster.getIdentifyTimeAttribute(), ); - this.handlerType = async(value: number) => { + this.handlerType = async (value: number) => { await this.adapter.setStateAsync(typeId, value, true); }; - this.handlerTime = async(value: number) => { + this.handlerTime = async (value: number) => { await this.adapter.setStateAsync(timeId, value, true); }; @@ -94,7 +94,7 @@ class Identify extends Base { false, ); - const triggerIdentifyHandler = async(state: ioBroker.State): Promise => { + const triggerIdentifyHandler = async (state: ioBroker.State): Promise => { if (!state || state.ack) { return; } @@ -123,7 +123,12 @@ class Identify extends Base { } } - static async factory(adapter: MatterAdapter, nodeId: NodeId, endpoint: Endpoint, path: number[]): Promise { + static async factory( + adapter: MatterAdapter, + nodeId: NodeId, + endpoint: Endpoint, + path: number[], + ): Promise { const cluster = endpoint.getClusterClient(IdentifyCluster); if (!cluster) { return; diff --git a/src/matter/clusters/LevelControl.ts b/src/matter/clusters/LevelControl.ts index 25ec049..477cc97 100644 --- a/src/matter/clusters/LevelControl.ts +++ b/src/matter/clusters/LevelControl.ts @@ -1,9 +1,9 @@ -import { Endpoint } from '@project-chip/matter-node.js/device'; import { LevelControlCluster } from '@project-chip/matter-node.js/cluster'; import { NodeId } from '@project-chip/matter-node.js/datatype'; +import { Endpoint } from '@project-chip/matter-node.js/device'; -import Base from './Base'; import { MatterAdapter } from '../../main'; +import Base from './Base'; class LevelControl extends Base { private handler: ((value: number | null) => void) | undefined = undefined; @@ -31,17 +31,17 @@ class LevelControl extends Base { max, }, cluster.id, - await cluster.getCurrentLevelAttribute() + await cluster.getCurrentLevelAttribute(), ); - this.handler = async(value: number | null) => { + this.handler = async (value: number | null) => { await this.adapter.setStateAsync(id, value, true); }; // subscribe on matter changes cluster.addCurrentLevelAttributeListener(this.handler); - const levelHandler = async(state: ioBroker.State): Promise => { + const levelHandler = async (state: ioBroker.State): Promise => { if (!state || state.ack) { return; } @@ -56,7 +56,7 @@ class LevelControl extends Base { optionsOverride: { executeIfOff: false, coupleColorTempToLevel: false, - } + }, }); } catch (e) { this.adapter.log.error(`Cannot set ${id}: ${e.message}, stack: ${e.stack}`); @@ -73,7 +73,12 @@ class LevelControl extends Base { } } - static async factory(adapter: MatterAdapter, nodeId: NodeId, endpoint: Endpoint, path: number[]): Promise { + static async factory( + adapter: MatterAdapter, + nodeId: NodeId, + endpoint: Endpoint, + path: number[], + ): Promise { const cluster = endpoint.getClusterClient(LevelControlCluster); if (!cluster) { return; diff --git a/src/matter/clusters/OnOff.ts b/src/matter/clusters/OnOff.ts index 7f32c13..f7c625e 100644 --- a/src/matter/clusters/OnOff.ts +++ b/src/matter/clusters/OnOff.ts @@ -1,9 +1,9 @@ -import { Endpoint } from '@project-chip/matter-node.js/device'; import { OnOffCluster } from '@project-chip/matter-node.js/cluster'; import { NodeId } from '@project-chip/matter-node.js/datatype'; +import { Endpoint } from '@project-chip/matter-node.js/device'; -import Base from './Base'; import { MatterAdapter } from '../../main'; +import Base from './Base'; class OnOff extends Base { private handler: ((value: boolean) => void) | undefined = undefined; @@ -29,14 +29,14 @@ class OnOff extends Base { await cluster.getOnOffAttribute(), ); - this.handler = async(value: boolean) => { + this.handler = async (value: boolean) => { await this.adapter.setStateAsync(id, value, true); }; // subscribe on matter changes cluster.addOnOffAttributeListener(this.handler); - const onOffHandler = async(state: ioBroker.State): Promise => { + const onOffHandler = async (state: ioBroker.State): Promise => { if (!state || state.ack) { return; } @@ -61,7 +61,12 @@ class OnOff extends Base { } } - static async factory(adapter: MatterAdapter, nodeId: NodeId, endpoint: Endpoint, path: number[]): Promise { + static async factory( + adapter: MatterAdapter, + nodeId: NodeId, + endpoint: Endpoint, + path: number[], + ): Promise { const cluster = endpoint.getClusterClient(OnOffCluster); if (!cluster) { return; diff --git a/src/matter/clusters/factories.ts b/src/matter/clusters/factories.ts index 87a01d7..8f5f2d0 100644 --- a/src/matter/clusters/factories.ts +++ b/src/matter/clusters/factories.ts @@ -1,13 +1,8 @@ +import BooleanState from './BooleanState'; import Identify from './Identify'; -import OnOff from './OnOff'; import LevelControl from './LevelControl'; -import BooleanState from './BooleanState'; +import OnOff from './OnOff'; -const Factories = [ - Identify.factory, - OnOff.factory, - LevelControl.factory, - BooleanState.factory, -]; +const Factories = [Identify.factory, OnOff.factory, LevelControl.factory, BooleanState.factory]; -export default Factories; \ No newline at end of file +export default Factories; diff --git a/src/matter/devices/MappingDimmer.ts b/src/matter/devices/MappingDimmer.ts index cd3db6b..bac8b77 100644 --- a/src/matter/devices/MappingDimmer.ts +++ b/src/matter/devices/MappingDimmer.ts @@ -4,8 +4,8 @@ import { Endpoint } from '@project-chip/matter.js/endpoint'; import { GenericDevice } from '../../lib'; import { PropertyType } from '../../lib/devices/GenericDevice'; -import { IdentifyOptions, MappingGenericDevice } from './MappingGenericDevice'; import Dimmer from '../../lib/devices/Dimmer'; +import { IdentifyOptions, MappingGenericDevice } from './MappingGenericDevice'; export class MappingDimmer extends MappingGenericDevice { private readonly ioBrokerDevice: Dimmer; @@ -46,14 +46,13 @@ export class MappingDimmer extends MappingGenericDevice { } }); // here we can react on changes from the matter side for the current lamp level - this.matterDevice.events.levelControl.currentLevel$Changed.on(async(level: number | null) => { + this.matterDevice.events.levelControl.currentLevel$Changed.on(async (level: number | null) => { const currentValue = this.ioBrokerDevice.getLevel(); if (level !== currentValue && level !== null) { await this.ioBrokerDevice.setLevel(level); } }); - let isIdentifying = false; const identifyOptions: IdentifyOptions = {}; this.matterDevice.events.identify.identifyTime$Changed.on(value => { @@ -83,14 +82,14 @@ export class MappingDimmer extends MappingGenericDevice { if (event.property === PropertyType.Power) { await this.matterDevice.set({ onOff: { - onOff: !!event.value - } + onOff: !!event.value, + }, }); } else if (event.property === PropertyType.Dimmer) { await this.matterDevice.set({ levelControl: { - currentLevel: event.value as number - } + currentLevel: event.value as number, + }, }); } }); @@ -98,11 +97,11 @@ export class MappingDimmer extends MappingGenericDevice { // init current state from ioBroker side await this.matterDevice.set({ onOff: { - onOff: !!this.ioBrokerDevice.getPower() + onOff: !!this.ioBrokerDevice.getPower(), }, levelControl: { - currentLevel: this.ioBrokerDevice.getLevel() || 0 - } + currentLevel: this.ioBrokerDevice.getLevel() || 0, + }, }); } } diff --git a/src/matter/devices/MappingGenericDevice.ts b/src/matter/devices/MappingGenericDevice.ts index 08498bf..8ee2262 100644 --- a/src/matter/devices/MappingGenericDevice.ts +++ b/src/matter/devices/MappingGenericDevice.ts @@ -1,5 +1,5 @@ -import { GenericDevice } from '../../lib'; import { Endpoint } from '@project-chip/matter.js/endpoint'; +import { GenericDevice } from '../../lib'; export interface IdentifyOptions { currentState?: any; @@ -10,13 +10,11 @@ export abstract class MappingGenericDevice { private identifyTimeout?: NodeJS.Timeout; private identifyHighlightState = false; - constructor(private name: string) { - - } + constructor(private name: string) {} handleIdentify(identifyOptions: IdentifyOptions): void { clearTimeout(this.identifyTimeout); - this.identifyTimeout = setTimeout(async() => { + this.identifyTimeout = setTimeout(async () => { this.identifyTimeout = undefined; const highlightState = !this.identifyHighlightState; if (highlightState) { diff --git a/src/matter/devices/MappingLight.ts b/src/matter/devices/MappingLight.ts index 52a683d..734e26d 100644 --- a/src/matter/devices/MappingLight.ts +++ b/src/matter/devices/MappingLight.ts @@ -4,8 +4,8 @@ import { Endpoint } from '@project-chip/matter.js/endpoint'; import { GenericDevice } from '../../lib'; import { PropertyType } from '../../lib/devices/GenericDevice'; -import { IdentifyOptions, MappingGenericDevice } from './MappingGenericDevice'; import Light from '../../lib/devices/Light'; +import { IdentifyOptions, MappingGenericDevice } from './MappingGenericDevice'; export class MappingLight extends MappingGenericDevice { private readonly ioBrokerDevice: Light; @@ -76,8 +76,8 @@ export class MappingLight extends MappingGenericDevice { if (event.property === PropertyType.Power) { await this.matterDevice.set({ onOff: { - onOff: !!event.value - } + onOff: !!event.value, + }, }); } }); @@ -85,8 +85,8 @@ export class MappingLight extends MappingGenericDevice { // init current state from ioBroker side await this.matterDevice.set({ onOff: { - onOff: !!this.ioBrokerDevice.getPower() - } + onOff: !!this.ioBrokerDevice.getPower(), + }, }); } } diff --git a/src/matter/devices/MappingSocket.ts b/src/matter/devices/MappingSocket.ts index 5928a3a..8b2db07 100644 --- a/src/matter/devices/MappingSocket.ts +++ b/src/matter/devices/MappingSocket.ts @@ -4,8 +4,8 @@ import { Endpoint } from '@project-chip/matter.js/endpoint'; import { GenericDevice } from '../../lib'; import { PropertyType } from '../../lib/devices/GenericDevice'; -import { IdentifyOptions, MappingGenericDevice } from './MappingGenericDevice'; import Socket from '../../lib/devices/Socket'; +import { IdentifyOptions, MappingGenericDevice } from './MappingGenericDevice'; export class MappingSocket extends MappingGenericDevice { private readonly ioBrokerDevice: Socket; @@ -76,16 +76,17 @@ export class MappingSocket extends MappingGenericDevice { if (event.property === PropertyType.Power) { await this.matterDevice.set({ onOff: { - onOff: !!event.value - } - }); } + onOff: !!event.value, + }, + }); + } }); // init current state from ioBroker side await this.matterDevice.set({ onOff: { - onOff: !!this.ioBrokerDevice.getPower() - } + onOff: !!this.ioBrokerDevice.getPower(), + }, }); } } diff --git a/src/matter/matterFactory.ts b/src/matter/matterFactory.ts index 4141415..baedfc6 100644 --- a/src/matter/matterFactory.ts +++ b/src/matter/matterFactory.ts @@ -1,12 +1,16 @@ +import { Types } from '@iobroker/type-detector'; import { GenericDevice } from '../lib'; import { MappingGenericDevice } from './devices/MappingGenericDevice'; -import { Types } from '@iobroker/type-detector'; +import { MappingDimmer } from './devices/MappingDimmer'; import { MappingLight } from './devices/MappingLight'; import { MappingSocket } from './devices/MappingSocket'; -import { MappingDimmer } from './devices/MappingDimmer'; -async function matterDeviceFabric(ioBrokerDevice: GenericDevice, name: string, uuid?: string): Promise { +async function matterDeviceFabric( + ioBrokerDevice: GenericDevice, + name: string, + uuid?: string, +): Promise { const ioBrokerDeviceType = ioBrokerDevice.getDeviceType(); switch (ioBrokerDeviceType) { diff --git a/src/matter/vendorIds.ts b/src/matter/vendorIds.ts index 91bef64..ef8ee74 100644 --- a/src/matter/vendorIds.ts +++ b/src/matter/vendorIds.ts @@ -17,12 +17,12 @@ const VENDOR_IDS: Record = { 0x1007: 'TUV', 0x1008: 'Integration', 0x1009: 'BM SpA', - 0x100A: 'AwarePoint', - 0x100B: 'Signify Netherlands B.V.', - 0x100C: 'Luxoft', - 0x100D: 'Korwin', - 0x100E: 'One RF Technology', - 0x100F: 'Software Technologies Group', + 0x100a: 'AwarePoint', + 0x100b: 'Signify Netherlands B.V.', + 0x100c: 'Luxoft', + 0x100d: 'Korwin', + 0x100e: 'One RF Technology', + 0x100f: 'Software Technologies Group', 0x1010: 'Telegesis', 0x1011: 'Visonic', 0x1012: 'Insta', @@ -33,12 +33,12 @@ const VENDOR_IDS: Record = { 0x1017: 'RadioPulse', 0x1018: 'Renesas', 0x1019: 'Xanadu Wireless', - 0x101A: 'NEC Engineering', - 0x101B: 'Yamatake Corporation', - 0x101C: 'Tendril Networks', - 0x101D: 'Assa Abloy', - 0x101E: 'MaxStream', - 0x101F: 'Neurocom', + 0x101a: 'NEC Engineering', + 0x101b: 'Yamatake Corporation', + 0x101c: 'Tendril Networks', + 0x101d: 'Assa Abloy', + 0x101e: 'MaxStream', + 0x101f: 'Neurocom', 0x1020: 'Institute for Information Industry', 0x1021: 'Legrand Group', 0x1022: 'iControl', @@ -49,12 +49,12 @@ const VENDOR_IDS: Record = { 0x1027: 'RF Technologies', 0x1028: 'Itron', 0x1029: 'Tritech', - 0x102A: 'Embedit A/S', - 0x102B: 'S3C', - 0x102C: 'Siemens', - 0x102D: 'Mindtech', - 0x102E: 'LG Electronics', - 0x102F: 'Mitsubishi Electric Corp.', + 0x102a: 'Embedit A/S', + 0x102b: 'S3C', + 0x102c: 'Siemens', + 0x102d: 'Mindtech', + 0x102e: 'LG Electronics', + 0x102f: 'Mitsubishi Electric Corp.', 0x1030: 'Johnson Controls', 0x1031: 'Secure Meters (UK) Ltd', 0x1032: 'Knick', @@ -65,12 +65,12 @@ const VENDOR_IDS: Record = { 0x1037: 'NXP Semiconductors', 0x1038: 'Living Independently Group', 0x1039: 'AlertMe.com', - 0x103A: 'Daintree', - 0x103B: 'Aiji System', - 0x103C: 'Telecom Italia', - 0x103D: 'Mikrokrets AS', - 0x103E: 'Oki Semiconductor', - 0x103F: 'Newport Electonics', + 0x103a: 'Daintree', + 0x103b: 'Aiji System', + 0x103c: 'Telecom Italia', + 0x103d: 'Mikrokrets AS', + 0x103e: 'Oki Semiconductor', + 0x103f: 'Newport Electonics', 0x1040: 'Control 4', 0x1041: 'STMicroelectronics', 0x1042: 'Ad-Sol Nissin Corp', @@ -81,12 +81,12 @@ const VENDOR_IDS: Record = { 0x1047: 'Colorado vNet', 0x1048: 'Aerocomm, Inc.', 0x1049: 'Silicon Laboratories', - 0x104A: 'Inncom International Inc.', - 0x104B: 'Cooper Power Systems', - 0x104C: 'Synapse', - 0x104D: 'Fisher Pierce/Sunrise', - 0x104E: 'CentraLite Systems, Inc.', - 0x104F: 'Crane Wireless Monitoring Solutions', + 0x104a: 'Inncom International Inc.', + 0x104b: 'Cooper Power Systems', + 0x104c: 'Synapse', + 0x104d: 'Fisher Pierce/Sunrise', + 0x104e: 'CentraLite Systems, Inc.', + 0x104f: 'Crane Wireless Monitoring Solutions', 0x1050: 'Mobilarm Limited', 0x1051: 'iMonitor Research Ltd.', 0x1052: 'Bartech', @@ -97,12 +97,12 @@ const VENDOR_IDS: Record = { 0x1057: 'Elster', 0x1058: 'SMS Tecnologia Eletrônica', 0x1059: 'Onset Computer Corporation', - 0x105A: 'Riga Development', - 0x105B: 'Energate', - 0x105C: 'ConMed Linvatec', - 0x105D: 'PowerMand', - 0x105E: 'Schneider Electric', - 0x105F: 'Eaton Corporation', + 0x105a: 'Riga Development', + 0x105b: 'Energate', + 0x105c: 'ConMed Linvatec', + 0x105d: 'PowerMand', + 0x105e: 'Schneider Electric', + 0x105f: 'Eaton Corporation', 0x1060: 'Telular Corporation', 0x1061: 'Delphi Medical Systems', 0x1062: 'EpiSensor Limited', @@ -113,12 +113,12 @@ const VENDOR_IDS: Record = { 0x1067: 'DBS Lodging Technologies, LLC.', 0x1068: 'Energy Aware Technology Inc.', 0x1069: 'Hidalgo Limited', - 0x106A: 'Air2App', - 0x106B: 'AMX', - 0x106C: 'EDMI Pty Ltd', - 0x106D: 'Cyan Ltd', - 0x106E: 'System SPA', - 0x106F: 'Telit', + 0x106a: 'Air2App', + 0x106b: 'AMX', + 0x106c: 'EDMI Pty Ltd', + 0x106d: 'Cyan Ltd', + 0x106e: 'System SPA', + 0x106f: 'Telit', 0x1070: 'Kaga Electronics', 0x1071: 'Astrel Group SRL', 0x1072: 'Certicom', @@ -129,12 +129,12 @@ const VENDOR_IDS: Record = { 0x1077: 'Alektrona', 0x1078: 'Computime', 0x1079: 'Remote Technologies, Inc.', - 0x107A: 'Wavecom S.A.', - 0x107B: 'Energy Optimizers Ltd.', - 0x107C: 'GE', - 0x107D: 'Jetlun', - 0x107E: 'Cipher Systems', - 0x107F: 'Corporate Systems Engineering', + 0x107a: 'Wavecom S.A.', + 0x107b: 'Energy Optimizers Ltd.', + 0x107c: 'GE', + 0x107d: 'Jetlun', + 0x107e: 'Cipher Systems', + 0x107f: 'Corporate Systems Engineering', 0x1080: 'ecobee', 0x1081: 'SMK', 0x1082: 'Meshworks Wireless Oy', @@ -155,108 +155,108 @@ const VENDOR_IDS: Record = { 0x1097: 'SyChip/Murata', 0x1098: 'OpenPeak', 0x1099: 'PassiveSystems', - 0x109A: 'MMB Research', - 0x109B: 'Leviton Manufacturing Company', - 0x109C: 'Korea Electric Power Data Network Co., Ltd.', - 0x109D: 'Comcast', - 0x109E: 'NEC Electronics', - 0x109F: 'Netvox', - 0x10A0: 'U-Control', - 0x10A1: 'Embedia Technologies Corp', - 0x10A2: 'Sensus', - 0x10A3: 'Sunrise Technologies', - 0x10A4: 'Memtech Corp', - 0x10A5: 'Freebox', - 0x10A6: 'M2 Labs Ltd.', - 0x10A7: 'British Gas', - 0x10A8: 'Sentec Ltd.', - 0x10A9: 'Navetas', - 0x10AA: 'Lightspeed Technologies', - 0x10AB: 'Oki Electric Industry Co., Ltd.', - 0x10AC: 'S I - Sistemas Inteligentes Eletrônicos Ltda', - 0x10AD: 'Dometic', - 0x10AE: 'Alps', - 0x10AF: 'EnergyHub', - 0x10B0: 'Kamstrup', - 0x10B1: 'EchoStar', - 0x10B2: 'EnerNOC', - 0x10B3: 'Eltav', - 0x10B4: 'Belkin', - 0x10B5: 'XStreamHD - Wireless Ventures', - 0x10B6: 'Saturn South Pty Ltd', - 0x10B7: 'GreenTrapOnline A/S', - 0x10B8: 'SmartSynch, Inc.', - 0x10B9: 'Nyce Control, Inc.', - 0x10BA: 'ICM Controls Corp', - 0x10BB: 'Millennium Electronics, PTY Ltd.', - 0x10BC: 'Motorola, Inc', - 0x10BD: 'Emerson White-Rodgers', - 0x10BE: 'Radio Thermostat Company of America', - 0x10BF: 'OMRON Corporation', - 0x10C0: 'GiiNii Global Limited', - 0x10C1: 'Fujitsu General Limited', - 0x10C2: 'Peel Technologies, Inc.', - 0x10C3: 'Accent S.p.A.', - 0x10C4: 'ByteSnap Design Ltd.', - 0x10C5: 'NEC TOKIN Corporation', - 0x10C6: 'G4S Justice Services', - 0x10C7: 'Trilliant Networks, Inc.', - 0x10C8: 'Electrolux Italia S.p.A', - 0x10C9: 'Onzo Ltd', - 0x10CA: 'EnTek Systems', - 0x10CB: 'Philips', - 0x10CC: 'Mainstream Engineering', - 0x10CD: 'Indesit Company', - 0x10CE: 'THINKECO, INC.', - 0x10CF: '2D2C, Inc.', - 0x10D0: 'Qorvo', - 0x10D1: 'InterCEL', - 0x10D2: 'LG Electronics', - 0x10D3: 'Mitsumi Electric Co.,Ltd.', - 0x10D4: 'Mitsumi Electric Co.,Ltd.', - 0x10D5: 'Zentrum Mikroelektronik Dresden AG (ZMDI)', - 0x10D6: 'Nest Labs, Inc.', - 0x10D7: 'Exegin Technologies, Ltd.', - 0x10D8: 'Honeywell', - 0x10D9: 'Takahata Precision Co. Ltd.', - 0x10DA: 'SUMITOMO ELECTRIC NETWORKS, INC.', - 0x10DB: 'GE Energy', - 0x10DC: 'GE Appliances', - 0x10DD: 'Radiocrafts AS', - 0x10DE: 'Ceiva', - 0x10DF: 'TEC&CO Co., Ltd', - 0x10E0: 'Chameleon Technology (UK) Ltd', - 0x10E1: 'Samsung', - 0x10E2: 'ruwido austria gmbh', - 0x10E3: 'Huawei Technologies Co., Ltd.', - 0x10E4: 'Huawei Technologies Co., Ltd.', - 0x10E5: 'Greenwave Reality', - 0x10E6: 'BGlobal Metering Ltd', - 0x10E7: 'Mindteck', - 0x10E8: 'Ingersoll-Rand', - 0x10E9: 'Dius Computing Pty Ltd', - 0x10EA: 'Embedded Automation, Inc.', - 0x10EB: 'ABB', - 0x10EC: 'Sony', - 0x10ED: 'Genus Power Infrastructures Limited', - 0x10EE: 'Universal Electronics, Inc.', - 0x10EF: 'Universal Electronics, Inc.', - 0x10F0: 'Metrum Technologies, LLC', - 0x10F1: 'Cisco', - 0x10F2: 'Ubisys technologies GmbH', - 0x10F3: 'Consert', - 0x10F4: 'Crestron Electronics', - 0x10F5: 'Enphase Energy', - 0x10F6: 'Invensys Controls', - 0x10F7: 'Mueller Systems, LLC', - 0x10F8: 'AAC Technologies Holding', - 0x10F9: 'U-NEXT Co., Ltd', - 0x10FA: 'Steelcase Inc.', - 0x10FB: 'Telematics Wireless', - 0x10FC: 'Samil Power Co., Ltd', - 0x10FD: 'Pace Plc', - 0x10FE: 'Osborne Coinage Co.', - 0x10FF: 'Powerwatch', + 0x109a: 'MMB Research', + 0x109b: 'Leviton Manufacturing Company', + 0x109c: 'Korea Electric Power Data Network Co., Ltd.', + 0x109d: 'Comcast', + 0x109e: 'NEC Electronics', + 0x109f: 'Netvox', + 0x10a0: 'U-Control', + 0x10a1: 'Embedia Technologies Corp', + 0x10a2: 'Sensus', + 0x10a3: 'Sunrise Technologies', + 0x10a4: 'Memtech Corp', + 0x10a5: 'Freebox', + 0x10a6: 'M2 Labs Ltd.', + 0x10a7: 'British Gas', + 0x10a8: 'Sentec Ltd.', + 0x10a9: 'Navetas', + 0x10aa: 'Lightspeed Technologies', + 0x10ab: 'Oki Electric Industry Co., Ltd.', + 0x10ac: 'S I - Sistemas Inteligentes Eletrônicos Ltda', + 0x10ad: 'Dometic', + 0x10ae: 'Alps', + 0x10af: 'EnergyHub', + 0x10b0: 'Kamstrup', + 0x10b1: 'EchoStar', + 0x10b2: 'EnerNOC', + 0x10b3: 'Eltav', + 0x10b4: 'Belkin', + 0x10b5: 'XStreamHD - Wireless Ventures', + 0x10b6: 'Saturn South Pty Ltd', + 0x10b7: 'GreenTrapOnline A/S', + 0x10b8: 'SmartSynch, Inc.', + 0x10b9: 'Nyce Control, Inc.', + 0x10ba: 'ICM Controls Corp', + 0x10bb: 'Millennium Electronics, PTY Ltd.', + 0x10bc: 'Motorola, Inc', + 0x10bd: 'Emerson White-Rodgers', + 0x10be: 'Radio Thermostat Company of America', + 0x10bf: 'OMRON Corporation', + 0x10c0: 'GiiNii Global Limited', + 0x10c1: 'Fujitsu General Limited', + 0x10c2: 'Peel Technologies, Inc.', + 0x10c3: 'Accent S.p.A.', + 0x10c4: 'ByteSnap Design Ltd.', + 0x10c5: 'NEC TOKIN Corporation', + 0x10c6: 'G4S Justice Services', + 0x10c7: 'Trilliant Networks, Inc.', + 0x10c8: 'Electrolux Italia S.p.A', + 0x10c9: 'Onzo Ltd', + 0x10ca: 'EnTek Systems', + 0x10cb: 'Philips', + 0x10cc: 'Mainstream Engineering', + 0x10cd: 'Indesit Company', + 0x10ce: 'THINKECO, INC.', + 0x10cf: '2D2C, Inc.', + 0x10d0: 'Qorvo', + 0x10d1: 'InterCEL', + 0x10d2: 'LG Electronics', + 0x10d3: 'Mitsumi Electric Co.,Ltd.', + 0x10d4: 'Mitsumi Electric Co.,Ltd.', + 0x10d5: 'Zentrum Mikroelektronik Dresden AG (ZMDI)', + 0x10d6: 'Nest Labs, Inc.', + 0x10d7: 'Exegin Technologies, Ltd.', + 0x10d8: 'Honeywell', + 0x10d9: 'Takahata Precision Co. Ltd.', + 0x10da: 'SUMITOMO ELECTRIC NETWORKS, INC.', + 0x10db: 'GE Energy', + 0x10dc: 'GE Appliances', + 0x10dd: 'Radiocrafts AS', + 0x10de: 'Ceiva', + 0x10df: 'TEC&CO Co., Ltd', + 0x10e0: 'Chameleon Technology (UK) Ltd', + 0x10e1: 'Samsung', + 0x10e2: 'ruwido austria gmbh', + 0x10e3: 'Huawei Technologies Co., Ltd.', + 0x10e4: 'Huawei Technologies Co., Ltd.', + 0x10e5: 'Greenwave Reality', + 0x10e6: 'BGlobal Metering Ltd', + 0x10e7: 'Mindteck', + 0x10e8: 'Ingersoll-Rand', + 0x10e9: 'Dius Computing Pty Ltd', + 0x10ea: 'Embedded Automation, Inc.', + 0x10eb: 'ABB', + 0x10ec: 'Sony', + 0x10ed: 'Genus Power Infrastructures Limited', + 0x10ee: 'Universal Electronics, Inc.', + 0x10ef: 'Universal Electronics, Inc.', + 0x10f0: 'Metrum Technologies, LLC', + 0x10f1: 'Cisco', + 0x10f2: 'Ubisys technologies GmbH', + 0x10f3: 'Consert', + 0x10f4: 'Crestron Electronics', + 0x10f5: 'Enphase Energy', + 0x10f6: 'Invensys Controls', + 0x10f7: 'Mueller Systems, LLC', + 0x10f8: 'AAC Technologies Holding', + 0x10f9: 'U-NEXT Co., Ltd', + 0x10fa: 'Steelcase Inc.', + 0x10fb: 'Telematics Wireless', + 0x10fc: 'Samil Power Co., Ltd', + 0x10fd: 'Pace Plc', + 0x10fe: 'Osborne Coinage Co.', + 0x10ff: 'Powerwatch', 0x1100: 'CANDELED GmbH', 0x1101: 'FlexGrid S.R.L', 0x1102: 'Humax', @@ -267,12 +267,12 @@ const VENDOR_IDS: Record = { 0x1107: 'Panasonic R&D Center Singapore', 0x1108: 'eSystems Research', 0x1109: 'Panamax', - 0x110A: 'SmartThings, Inc.', - 0x110B: 'EM-Lite Ltd.', - 0x110C: 'Osram Sylvania', - 0x110D: '2 Save Energy Ltd.', - 0x110E: 'Planet Innovation Products Pty Ltd', - 0x110F: 'Ambient Devices, Inc.', + 0x110a: 'SmartThings, Inc.', + 0x110b: 'EM-Lite Ltd.', + 0x110c: 'Osram Sylvania', + 0x110d: '2 Save Energy Ltd.', + 0x110e: 'Planet Innovation Products Pty Ltd', + 0x110f: 'Ambient Devices, Inc.', 0x1110: 'Profalux', 0x1111: 'Billion Electric Company (BEC)', 0x1112: 'Embertec Pty Ltd', @@ -283,12 +283,12 @@ const VENDOR_IDS: Record = { 0x1117: 'Moxa', 0x1118: 'QEES', 0x1119: 'SAYME Wireless Sensor Networks', - 0x111A: 'Pentair Aquatic Systems', - 0x111B: 'Orbit Irrigation', - 0x111C: 'California Eastern Laboratories', - 0x111D: 'Comcast', - 0x111E: 'IDT Technology Limited', - 0x111F: 'Pixela Corporation', + 0x111a: 'Pentair Aquatic Systems', + 0x111b: 'Orbit Irrigation', + 0x111c: 'California Eastern Laboratories', + 0x111d: 'Comcast', + 0x111e: 'IDT Technology Limited', + 0x111f: 'Pixela Corporation', 0x1120: 'TiVo, Inc.', 0x1121: 'Fidure Corp.', 0x1122: 'Marvell Semiconductor, Inc.', @@ -299,12 +299,12 @@ const VENDOR_IDS: Record = { 0x1127: 'Define Instruments Limited', 0x1128: 'In Home Displays Ltd.', 0x1129: 'Miele & Cie. KG', - 0x112A: 'Televes S.A.', - 0x112B: 'Labelec', - 0x112C: 'China Electronics Standardization Institute', - 0x112D: 'Vectorform, LLC', - 0x112E: 'Busch-Jaeger Elektro', - 0x112F: 'Redpine Signals, Inc.', + 0x112a: 'Televes S.A.', + 0x112b: 'Labelec', + 0x112c: 'China Electronics Standardization Institute', + 0x112d: 'Vectorform, LLC', + 0x112e: 'Busch-Jaeger Elektro', + 0x112f: 'Redpine Signals, Inc.', 0x1130: 'Bridges Electronic Technology Pty Ltd.', 0x1131: 'Sercomm', 0x1132: 'WSH GmbH wirsindheller', @@ -315,12 +315,12 @@ const VENDOR_IDS: Record = { 0x1137: 'Crow Electronic Engineering Ltd.', 0x1138: 'Harvard Engineering Plc', 0x1139: 'Andson(Beijing) Technology CO.,Ltd', - 0x113A: 'Adhoco AG', - 0x113B: 'Waxman Consumer Products Group, Inc.', - 0x113C: 'Owon Technology, Inc.', - 0x113D: 'Hitron Technologies, Inc.', - 0x113E: 'Scemtec Hard - und Software für Mess - und Steuerungstechnik GmbH', - 0x113F: 'Webee LLC', + 0x113a: 'Adhoco AG', + 0x113b: 'Waxman Consumer Products Group, Inc.', + 0x113c: 'Owon Technology, Inc.', + 0x113d: 'Hitron Technologies, Inc.', + 0x113e: 'Scemtec Hard - und Software für Mess - und Steuerungstechnik GmbH', + 0x113f: 'Webee LLC', 0x1140: 'Grid2Home Inc', 0x1141: 'Telink Micro', 0x1142: 'Jasmine Systems, Inc.', @@ -331,12 +331,12 @@ const VENDOR_IDS: Record = { 0x1147: 'TCP, Inc.', 0x1148: 'Rogers Communications Partnership', 0x1149: 'Cree, Inc.', - 0x114A: 'Robert Bosch LLC', - 0x114B: 'Ibis Networks, Inc.', - 0x114C: 'Quirky, Inc.', - 0x114D: 'Efergy Technologies Limited', - 0x114E: 'SmartLabs, Inc.', - 0x114F: 'Everspring Industry Co., Ltd.', + 0x114a: 'Robert Bosch LLC', + 0x114b: 'Ibis Networks, Inc.', + 0x114c: 'Quirky, Inc.', + 0x114d: 'Efergy Technologies Limited', + 0x114e: 'SmartLabs, Inc.', + 0x114f: 'Everspring Industry Co., Ltd.', 0x1150: 'Swann Communications Ptl Ltd.', 0x1151: 'Soneter', 0x1152: 'Samsung SDS', @@ -347,12 +347,12 @@ const VENDOR_IDS: Record = { 0x1157: 'Ohsung Electronics', 0x1158: 'Zen Within, Inc.', 0x1159: 'Tech4home, Lda.', - 0x115A: 'Nanoleaf', - 0x115B: 'Keen Home, Inc.', - 0x115C: 'Poly-Control APS', - 0x115D: 'Eastfield Lighting Co., Ltd Shenzhen', - 0x115E: 'IP Datatel, Inc.', - 0x115F: 'Lumi United Techology, Ltd Shenzhen', + 0x115a: 'Nanoleaf', + 0x115b: 'Keen Home, Inc.', + 0x115c: 'Poly-Control APS', + 0x115d: 'Eastfield Lighting Co., Ltd Shenzhen', + 0x115e: 'IP Datatel, Inc.', + 0x115f: 'Lumi United Techology, Ltd Shenzhen', 0x1160: 'Sengled Co., Ltd.', 0x1161: 'Remote Solution Co., Ltd.', 0x1162: 'ABB Genway Xiamen Electrical Equipment Co., Ltd.', @@ -363,12 +363,12 @@ const VENDOR_IDS: Record = { 0x1167: 'Techworld Industries', 0x1168: 'Leedarson Lighting Co., Ltd.', 0x1169: 'Arzel Zoning', - 0x116A: 'Holley Technology', - 0x116B: 'Beldon Technologies', - 0x116C: 'Flextronics', - 0x116D: 'Shenzhen Meian', - 0x116E: 'Lowe’s', - 0x116F: 'Sigma Connectivity', + 0x116a: 'Holley Technology', + 0x116b: 'Beldon Technologies', + 0x116c: 'Flextronics', + 0x116d: 'Shenzhen Meian', + 0x116e: 'Lowe’s', + 0x116f: 'Sigma Connectivity', 0x1171: 'Wulian', 0x1172: 'Plugwise B.V.', 0x1173: 'Titan Products', @@ -378,12 +378,12 @@ const VENDOR_IDS: Record = { 0x1177: 'Opple Lighting', 0x1178: 'Wistron NeWeb Corp.', 0x1179: 'QMotion Shades', - 0x117A: 'Insta GmbH', - 0x117B: 'Shanghai Vancount', - 0x117C: 'Ikea of Sweden', - 0x117D: 'RT-RK', - 0x117E: 'Shenzhen Feibit', - 0x117F: 'EuControls', + 0x117a: 'Insta GmbH', + 0x117b: 'Shanghai Vancount', + 0x117c: 'Ikea of Sweden', + 0x117d: 'RT-RK', + 0x117e: 'Shenzhen Feibit', + 0x117f: 'EuControls', 0x1180: 'Telkonet', 0x1181: 'Thermal Solution Resources', 0x1182: 'PomCube', @@ -394,12 +394,12 @@ const VENDOR_IDS: Record = { 0x1187: 'Semiconductor Components', 0x1188: 'TP-Link', 0x1189: 'Ledvance GmbH', - 0x118A: 'Nortek', - 0x118B: 'iRevo/Assa Abbloy Korea', - 0x118C: 'Midea', - 0x118D: 'ZF Friedrichshafen', - 0x118E: 'Checkit', - 0x118F: 'Aclara', + 0x118a: 'Nortek', + 0x118b: 'iRevo/Assa Abbloy Korea', + 0x118c: 'Midea', + 0x118d: 'ZF Friedrichshafen', + 0x118e: 'Checkit', + 0x118f: 'Aclara', 0x1190: 'Nokia', 0x1191: 'Goldcard High-tech Co., Ltd.', 0x1192: 'George Wilson Industries Ltd.', @@ -410,12 +410,12 @@ const VENDOR_IDS: Record = { 0x1197: 'Insight Energy Ventures/Powerley', 0x1198: 'Thomas Research Products (Hubbell Lighting Inc.)', 0x1199: 'Li Seng Technology', - 0x119A: 'System Level Solutions Inc.', - 0x119B: 'Matrix Labs', - 0x119C: 'Sinope Technologies', - 0x119D: 'Jiuzhou Greeble', - 0x119E: 'Guangzhou Lanvee Tech. Co. Ltd.', - 0x119F: 'Venstar', + 0x119a: 'System Level Solutions Inc.', + 0x119b: 'Matrix Labs', + 0x119c: 'Sinope Technologies', + 0x119d: 'Jiuzhou Greeble', + 0x119e: 'Guangzhou Lanvee Tech. Co. Ltd.', + 0x119f: 'Venstar', 0x1200: 'SLV', 0x1201: 'Halo Smart Labs', 0x1202: 'Scout Security Inc.', @@ -426,12 +426,12 @@ const VENDOR_IDS: Record = { 0x1207: 'Vimar SpA', 0x1208: 'Universal Lighting Technologies', 0x1209: 'Robert Bosch, GmbH', - 0x120A: 'Accenture', - 0x120B: 'Heiman Technology Co., Ltd.', - 0x120C: 'Shenzhen HOMA Technology Co., Ltd.', - 0x120D: 'Vision-Electronics Technology', - 0x120E: 'Lenovo', - 0x120F: 'Presciense R&D', + 0x120a: 'Accenture', + 0x120b: 'Heiman Technology Co., Ltd.', + 0x120c: 'Shenzhen HOMA Technology Co., Ltd.', + 0x120d: 'Vision-Electronics Technology', + 0x120e: 'Lenovo', + 0x120f: 'Presciense R&D', 0x1210: 'Shenzhen Seastar Intelligence Co., Ltd.', 0x1211: 'Sensative AB', 0x1212: 'SolarEdge', @@ -442,12 +442,12 @@ const VENDOR_IDS: Record = { 0x1217: 'Amazon Lab126', 0x1218: 'Paulmann Licht GmbH', 0x1219: 'Shenzhen Orvibo Electronics Co. Ltd.', - 0x121A: 'TCI Telecommunications', - 0x121B: 'Mueller-Licht International Inc.', - 0x121C: 'Aurora Limited', - 0x121D: 'SmartDCC', - 0x121E: 'Shanghai UMEinfo Co. Ltd.', - 0x121F: 'carbonTRACK', + 0x121a: 'TCI Telecommunications', + 0x121b: 'Mueller-Licht International Inc.', + 0x121c: 'Aurora Limited', + 0x121d: 'SmartDCC', + 0x121e: 'Shanghai UMEinfo Co. Ltd.', + 0x121f: 'carbonTRACK', 0x1220: 'Somfy', 0x1221: 'Viessmann Elektronik GmbH', 0x1222: 'Hildebrand Technology Ltd', @@ -458,12 +458,12 @@ const VENDOR_IDS: Record = { 0x1227: 'Shenzhen Kaadas Intelligent Technology Co. Ltd', 0x1228: 'Shanghai Xiaoyan Technology Co. Ltd', 0x1229: 'Cypress Semiconductor', - 0x122A: 'XAL GmbH', - 0x122B: 'Inergy Systems LLC', - 0x122C: 'Alfred Karcher GmbH & Co KG', - 0x122D: 'Adurolight Manufacturing', - 0x122E: 'Groupe Muller', - 0x122F: 'V-Mark Enterprises Inc.', + 0x122a: 'XAL GmbH', + 0x122b: 'Inergy Systems LLC', + 0x122c: 'Alfred Karcher GmbH & Co KG', + 0x122d: 'Adurolight Manufacturing', + 0x122e: 'Groupe Muller', + 0x122f: 'V-Mark Enterprises Inc.', 0x1230: 'Lead Energy AG', 0x1231: 'Ultimate IOT (Henan) Technology Ltd.', 0x1232: 'Axxess Industries Inc.', @@ -474,12 +474,12 @@ const VENDOR_IDS: Record = { 0x1237: 'Net2Grid', 0x1238: 'Airam Electric Oy Ab', 0x1239: 'IMMAX WPB CZ', - 0x123A: 'ZIV Automation', - 0x123B: 'HangZhou iMagicTechnology Co., Ltd', - 0x123C: 'Xiamen Leelen Technology Co. Ltd.', - 0x123D: 'Overkiz SAS', - 0x123E: 'Flonidan A/S', - 0x123F: 'HDL Automation Co., Ltd.', + 0x123a: 'ZIV Automation', + 0x123b: 'HangZhou iMagicTechnology Co., Ltd', + 0x123c: 'Xiamen Leelen Technology Co. Ltd.', + 0x123d: 'Overkiz SAS', + 0x123e: 'Flonidan A/S', + 0x123f: 'HDL Automation Co., Ltd.', 0x1240: 'Ardomus Networks Corporation', 0x1241: 'Samjin Co., Ltd.', 0x1242: 'FireAngel Safety Technology plc', @@ -490,12 +490,12 @@ const VENDOR_IDS: Record = { 0x1247: 'NIVISS PHP Sp. z o.o. Sp.k.', 0x1248: 'Shenzhen Fengliyuan Energy Conservating Technology Co. Ltd', 0x1249: 'NEXELEC', - 0x124A: 'Sichuan Behome Prominent Technology Co., Ltd', - 0x124B: 'Fujian Star-net Communication Co., Ltd.', - 0x124C: 'Toshiba Visual Solutions Corporation', - 0x124D: 'Latchable, Inc.', - 0x124E: 'L&S Deutschland GmbH', - 0x124F: 'Gledopto Co., Ltd.', + 0x124a: 'Sichuan Behome Prominent Technology Co., Ltd', + 0x124b: 'Fujian Star-net Communication Co., Ltd.', + 0x124c: 'Toshiba Visual Solutions Corporation', + 0x124d: 'Latchable, Inc.', + 0x124e: 'L&S Deutschland GmbH', + 0x124f: 'Gledopto Co., Ltd.', 0x1250: 'The Home Depot', 0x1251: 'Neonlite Distribution Limited', 0x1252: 'Arlo Technologies, Inc.', @@ -506,12 +506,12 @@ const VENDOR_IDS: Record = { 0x1257: 'Solum Co., Ltd.', 0x1258: 'Eaglerise Electric & Electronic (China) Co., Ltd.', 0x1259: 'Fantem Technologies (Shenzhen) Co., Ltd.', - 0x125A: 'Yunding Network Technology (Beijing) Co., Ltd.', - 0x125B: 'Atlantic Group', - 0x125C: 'Xiamen Intretech, Inc.', - 0x125D: 'Tuya Global Inc.', - 0x125E: 'Dnake (Xiamen) Intelligent Technology Co., Ltd.', - 0x125F: 'Niko nv', + 0x125a: 'Yunding Network Technology (Beijing) Co., Ltd.', + 0x125b: 'Atlantic Group', + 0x125c: 'Xiamen Intretech, Inc.', + 0x125d: 'Tuya Global Inc.', + 0x125e: 'Dnake (Xiamen) Intelligent Technology Co., Ltd.', + 0x125f: 'Niko nv', 0x1260: 'Emporia Energy', 0x1261: 'Sikom AS', 0x1262: 'AXIS Labs, Inc.', @@ -522,12 +522,12 @@ const VENDOR_IDS: Record = { 0x1267: 'ARC Technology Co., Ltd', 0x1268: 'Hangzhou Konke Information Technology Co., Ltd.', 0x1269: 'SALTO Systems S.L.', - 0x126A: 'Shenzhen Shyugj Technology Co., Ltd', - 0x126B: 'Brayden Automation Corporation', - 0x126C: 'Environexus Pty. Ltd.', - 0x126D: 'Eltra nv/sa', - 0x126E: 'Xiaomi Communications Co., Ltd.', - 0x126F: 'Shanghai Shuncom Electronic Technology Co., Ltd.', + 0x126a: 'Shenzhen Shyugj Technology Co., Ltd', + 0x126b: 'Brayden Automation Corporation', + 0x126c: 'Environexus Pty. Ltd.', + 0x126d: 'Eltra nv/sa', + 0x126e: 'Xiaomi Communications Co., Ltd.', + 0x126f: 'Shanghai Shuncom Electronic Technology Co., Ltd.', 0x1270: 'Voltalis S.A', 0x1271: 'FEELUX Co., Ltd.', 0x1272: 'SmartPlus Inc.', @@ -538,12 +538,12 @@ const VENDOR_IDS: Record = { 0x1277: 'ADEO', 0x1278: 'Connected Response Limited', 0x1279: 'StroyEnergoKom, Ltd.', - 0x127A: 'Lumitech Lighting Solution GmbH', - 0x127B: 'Verdant Environmental Technologies', - 0x127C: 'Alfred International Inc.', - 0x127D: 'Sansi LED Lighting co., LTD.', - 0x127E: 'Mindtree Limited', - 0x127F: 'Nordic Semiconductor ASA', + 0x127a: 'Lumitech Lighting Solution GmbH', + 0x127b: 'Verdant Environmental Technologies', + 0x127c: 'Alfred International Inc.', + 0x127d: 'Sansi LED Lighting co., LTD.', + 0x127e: 'Mindtree Limited', + 0x127f: 'Nordic Semiconductor ASA', 0x1280: 'Siterwell Electronics Co., Limited', 0x1281: 'Briloner Leuchten GmbH & Co. KG', 0x1282: 'Shenzhen SEI Technology Co., Ltd.', @@ -554,12 +554,12 @@ const VENDOR_IDS: Record = { 0x1287: 'Hangzhou Sky-Lighting Co., Ltd.', 0x1288: 'E.ON SE', 0x1289: 'Lidl Stiftung & Co. KG', - 0x128A: 'Sichuan Changhong Network Technologies Co., Ltd.', - 0x128B: 'NodOn', - 0x128C: 'Jiangxi Innotech Technology Co., Ltd.', - 0x128D: 'Mercator Pty Ltd', - 0x128E: 'Beijing Ruying Tech Limited', - 0x128F: 'EGLO Leuchten GmbH', + 0x128a: 'Sichuan Changhong Network Technologies Co., Ltd.', + 0x128b: 'NodOn', + 0x128c: 'Jiangxi Innotech Technology Co., Ltd.', + 0x128d: 'Mercator Pty Ltd', + 0x128e: 'Beijing Ruying Tech Limited', + 0x128f: 'EGLO Leuchten GmbH', 0x1290: 'Pietro Fiorentini S.p.A', 0x1291: 'Zehnder Group Vaux-Andigny', 0x1292: 'BRK Brands, Inc.', @@ -570,12 +570,12 @@ const VENDOR_IDS: Record = { 0x1297: 'Société en Commandite Stello', 0x1298: 'Vivint Smart Home', 0x1299: 'Namron AS', - 0x129A: 'RADEMACHER Geraete-Elektronik GmbH', - 0x129B: 'OMO Systems LTD', - 0x129C: 'Siglis AG', - 0x129D: 'IMHOTEP CREATION', - 0x129E: 'icasa', - 0x129F: 'Level Home, Inc.', + 0x129a: 'RADEMACHER Geraete-Elektronik GmbH', + 0x129b: 'OMO Systems LTD', + 0x129c: 'Siglis AG', + 0x129d: 'IMHOTEP CREATION', + 0x129e: 'icasa', + 0x129f: 'Level Home, Inc.', 0x1300: 'TIS Control Limited', 0x1301: 'Radisys India Pvt. Ltd.', 0x1302: 'Veea Inc.', @@ -586,12 +586,12 @@ const VENDOR_IDS: Record = { 0x1307: 'GRUNDFOS Holding A/S', 0x1308: 'SOURCING & CREATION', 0x1309: 'Kraken Technologies Ltd', - 0x130A: 'EVE SYSTEMS', - 0x130B: 'LITE-ON TECHNOLOGY CORPORATION', - 0x130C: 'Focalcrest Limited', - 0x130D: 'Bouffalo Lab (Nanjing) Co., Ltd.', - 0x130E: 'Wyze Labs, Inc.', - 0x130F: 'Z-Wave Europe GmbH', + 0x130a: 'EVE SYSTEMS', + 0x130b: 'LITE-ON TECHNOLOGY CORPORATION', + 0x130c: 'Focalcrest Limited', + 0x130d: 'Bouffalo Lab (Nanjing) Co., Ltd.', + 0x130e: 'Wyze Labs, Inc.', + 0x130f: 'Z-Wave Europe GmbH', 0x1310: 'AEOTEC LIMITED', 0x1311: 'NGSTB Company Limited', 0x1312: 'Qingdao Yeelink Information Technology Co., Ltd.', @@ -602,12 +602,12 @@ const VENDOR_IDS: Record = { 0x1317: 'Logitech', 0x1318: 'Piaro, Inc.', 0x1319: 'Mitsubishi Electric US, Inc.', - 0x131A: 'Resideo Technologies, Inc.', - 0x131B: 'Espressif Systems (Shanghai) Co., Ltd.', - 0x131C: 'HELLA Sonnen- und Wetterschutztechnik GmbH', - 0x131D: 'Geberit International AG', - 0x131E: 'CAME S.p.A.', - 0x131F: 'Guangzhou Elite Education & Technology Co., Ltd.', + 0x131a: 'Resideo Technologies, Inc.', + 0x131b: 'Espressif Systems (Shanghai) Co., Ltd.', + 0x131c: 'HELLA Sonnen- und Wetterschutztechnik GmbH', + 0x131d: 'Geberit International AG', + 0x131e: 'CAME S.p.A.', + 0x131f: 'Guangzhou Elite Education & Technology Co., Ltd.', 0x1320: 'Phyplus Microelectronics Limited', 0x1321: 'Shenzhen Sonoff Technologies Co., Ltd.', 0x1322: 'Safe4 Security Group', @@ -618,12 +618,12 @@ const VENDOR_IDS: Record = { 0x1327: 'Mill International AS', 0x1328: 'HomeWizard BV', 0x1329: 'Shenzhen Topband Co., Ltd', - 0x132A: 'Pressac Communications Ltd', - 0x132B: 'Origin Wireless, Inc.', - 0x132C: 'Connecte AS', - 0x132D: 'YOKIS', - 0x132E: 'Xiamen Yankon Energetic Lighting Co., Ltd.', - 0x132F: 'Yandex LLC', + 0x132a: 'Pressac Communications Ltd', + 0x132b: 'Origin Wireless, Inc.', + 0x132c: 'Connecte AS', + 0x132d: 'YOKIS', + 0x132e: 'Xiamen Yankon Energetic Lighting Co., Ltd.', + 0x132f: 'Yandex LLC', 0x1330: 'Critical Software S.A.', 0x1331: 'Nortek Control', 0x1332: 'BrightAI', @@ -634,12 +634,12 @@ const VENDOR_IDS: Record = { 0x1337: 'Datek Wireless AS', 0x1338: 'ALDES', 0x1339: 'Savant Company', - 0x133A: 'Ariston Thermo Group', - 0x133B: 'WAREMA Renkhoff SE', - 0x133C: 'VTech Holdings Limited', - 0x133D: 'Futurehome AS', - 0x133E: 'Cognitive Systems Corp.', - 0x133F: 'ASR Microelectronics (Shenzhen) Co., Ltd.', + 0x133a: 'Ariston Thermo Group', + 0x133b: 'WAREMA Renkhoff SE', + 0x133c: 'VTech Holdings Limited', + 0x133d: 'Futurehome AS', + 0x133e: 'Cognitive Systems Corp.', + 0x133f: 'ASR Microelectronics (Shenzhen) Co., Ltd.', 0x1340: 'Airios', 0x1341: 'Guangdong OPPO Mobile Telecommunications Corp., Ltd.', 0x1342: 'Beken Corporation', @@ -650,12 +650,12 @@ const VENDOR_IDS: Record = { 0x1347: 'Aug. Winkhuas GmbH & Co. KG', 0x1348: 'Qingdao Haier Technology Co., Ltd.', 0x1349: 'Apple Inc.', - 0x134A: 'Rollease Acmeda', - 0x134B: 'Nabu Casa, Inc.', - 0x134C: 'Simon Holding', - 0x134D: 'KD Navien', - 0x134E: 'tado GmbH', - 0x134F: 'Mediola Connected Living AG', + 0x134a: 'Rollease Acmeda', + 0x134b: 'Nabu Casa, Inc.', + 0x134c: 'Simon Holding', + 0x134d: 'KD Navien', + 0x134e: 'tado GmbH', + 0x134f: 'Mediola Connected Living AG', 0x1350: 'Polynhome', 0x1351: 'HooRii Technology Co., Ltd.', 0x1352: 'Häfele SE & Co KG', @@ -666,12 +666,12 @@ const VENDOR_IDS: Record = { 0x1357: 'Teledatics Incorporated', 0x1358: 'Top Victory Investments Limited', 0x1359: 'GOQUAL Inc.', - 0x135A: 'Siegenia Aubi KG', - 0x135B: 'Virtual Connected Controlling System (Singapore) Pte. Ltd.', - 0x135C: 'Gigaset Communications GmbH', - 0x135D: 'Nuki Home Solutions GmbH', - 0x135E: 'Devicebook, Inc.', - 0x135F: 'Consumer 2.0 Inc. (Rently)', + 0x135a: 'Siegenia Aubi KG', + 0x135b: 'Virtual Connected Controlling System (Singapore) Pte. Ltd.', + 0x135c: 'Gigaset Communications GmbH', + 0x135d: 'Nuki Home Solutions GmbH', + 0x135e: 'Devicebook, Inc.', + 0x135f: 'Consumer 2.0 Inc. (Rently)', 0x1360: 'Edison Labs, Inc. (dba Orro)', 0x1361: 'Inovelli', 0x1362: 'deveritec GmbH', @@ -682,12 +682,12 @@ const VENDOR_IDS: Record = { 0x1367: 'HP Inc.', 0x1368: 'mui Lab, Inc.', 0x1369: 'BHtronics S.r.l.', - 0x136A: 'Akuvox (Xiamen) Networks Co., Ltd.', - 0x136B: 'nami', - 0x136C: 'Kee Tat Manufactory Holdings Limited', - 0x136D: 'Iton Technology Corp.', - 0x136E: 'Ambi Labs Limited', - 0x136F: 'Corporación Empresarial Altra S.L.', + 0x136a: 'Akuvox (Xiamen) Networks Co., Ltd.', + 0x136b: 'nami', + 0x136c: 'Kee Tat Manufactory Holdings Limited', + 0x136d: 'Iton Technology Corp.', + 0x136e: 'Ambi Labs Limited', + 0x136f: 'Corporación Empresarial Altra S.L.', 0x1370: 'Coway Co., Ltd.', 0x1371: 'Tridonic GmbH & Co KG', 0x1372: 'innovation matters iot GmbH', @@ -698,12 +698,12 @@ const VENDOR_IDS: Record = { 0x1377: 'Night Owl SP, LLC', 0x1378: 'Je Woo Corporation Ltd.', 0x1379: 'Earda Technologies Co., Ltd.', - 0x137A: 'Alexa Connect Kit (ACK)', - 0x137B: 'Amazon Basics', - 0x137C: 'Morse Micro Inc.', - 0x137D: 'Shanghai Xiaodu Technology Limited', - 0x137E: 'Nubert electronic GmbH', - 0x137F: 'Shenzhen NEO Electronics Co. Ltd.', + 0x137a: 'Alexa Connect Kit (ACK)', + 0x137b: 'Amazon Basics', + 0x137c: 'Morse Micro Inc.', + 0x137d: 'Shanghai Xiaodu Technology Limited', + 0x137e: 'Nubert electronic GmbH', + 0x137f: 'Shenzhen NEO Electronics Co. Ltd.', 0x1380: 'Grimsholm Products AB', 0x1381: 'Amazon Prime Video', 0x1382: 'ION INDUSTRIES B.V.', @@ -714,12 +714,12 @@ const VENDOR_IDS: Record = { 0x1387: 'Shenzhen Qianyan Technology Ltd.', 0x1388: 'Infineon Technologies AG', 0x1389: 'Shenzhen Jingxun Technology Co., Ltd.', - 0x138A: 'Nature Inc.', - 0x138B: 'WiFigarden Inc.', - 0x138C: 'Hisense Group Co. Ltd., USA', - 0x138D: 'Nanjing Easthouse Electrical Co., Ltd.', - 0x138E: 'Ledworks SRL', - 0x138F: 'Shina System Co., Ltd.', + 0x138a: 'Nature Inc.', + 0x138b: 'WiFigarden Inc.', + 0x138c: 'Hisense Group Co. Ltd., USA', + 0x138d: 'Nanjing Easthouse Electrical Co., Ltd.', + 0x138e: 'Ledworks SRL', + 0x138f: 'Shina System Co., Ltd.', 0x1390: 'Qualcomm Technologies Inc.', 0x1391: 'Kasa (Big Field Global PTE. Ltd.)', 0x1392: 'Tapo (Big Field Global PTE. Ltd.)', @@ -730,12 +730,12 @@ const VENDOR_IDS: Record = { 0x1397: 'Woan Technology (Shenzhen) Co., Ltd.', 0x1398: 'Meizu Technology Co., Ltd.', 0x1399: 'Yukai Engineering Inc.', - 0x139A: 'Qrio, Inc.', - 0x139B: 'ITIUS GmbH', - 0x139C: 'Zemismart Technology Limited', - 0x139D: 'LED Linear GmbH', - 0x139E: 'Dyson Technology Limited', - 0x139F: 'Razer Inc.', + 0x139a: 'Qrio, Inc.', + 0x139b: 'ITIUS GmbH', + 0x139c: 'Zemismart Technology Limited', + 0x139d: 'LED Linear GmbH', + 0x139e: 'Dyson Technology Limited', + 0x139f: 'Razer Inc.', 0x1400: 'Uascent Technology Company Limited', 0x1401: 'Bose Corporation', 0x1402: 'GOLDTek Technology Co., Ltd.', @@ -746,12 +746,12 @@ const VENDOR_IDS: Record = { 0x1407: 'Jiangshu Shushi Technology Co., Ltd.', 0x1408: 'Velux A/S', 0x1409: 'Shenzhen Hidin Technology Co., Ltd.', - 0x140A: 'Intertech Services AG', - 0x140B: '70mai Co., Ltd.', - 0x140C: 'Beijing ESWIN Computing Technology CO.,Ltd.', - 0x140D: 'Photon Sail Technologies Pte. Ltd.', - 0x140E: 'WiDom SRL', - 0x140F: 'Sagemcom SAS', + 0x140a: 'Intertech Services AG', + 0x140b: '70mai Co., Ltd.', + 0x140c: 'Beijing ESWIN Computing Technology CO.,Ltd.', + 0x140d: 'Photon Sail Technologies Pte. Ltd.', + 0x140e: 'WiDom SRL', + 0x140f: 'Sagemcom SAS', 0x1410: 'Quectel Wireless Solutions Co., Ltd.', 0x1411: 'Freedompro S.r.l.', 0x1412: 'Disign Incorporated', @@ -762,12 +762,12 @@ const VENDOR_IDS: Record = { 0x1417: 'Konnected Inc.', 0x1418: 'KLite (Signify)', 0x1419: 'Lorex Technology Inc.', - 0x141A: 'RATOC Systems, Inc', - 0x141B: 'Rang Dong Light Source & VacuumFlask Joint Stock Company', - 0x141C: 'Shenzhen Sibo Zhilian Technology Co., Ltd.', - 0x141D: 'Secuyou APS', - 0x141E: 'TUO Accessories LLC', - 0x141F: 'DUCTECH Co., Ltd', + 0x141a: 'RATOC Systems, Inc', + 0x141b: 'Rang Dong Light Source & VacuumFlask Joint Stock Company', + 0x141c: 'Shenzhen Sibo Zhilian Technology Co., Ltd.', + 0x141d: 'Secuyou APS', + 0x141e: 'TUO Accessories LLC', + 0x141f: 'DUCTECH Co., Ltd', 0x1420: 'EcoFlow Inc.', 0x1421: 'Kwikset', 0x1422: 'Zhuhai HiVi Technology Co., Ltd.', @@ -778,12 +778,12 @@ const VENDOR_IDS: Record = { 0x1427: 'Hama GmbH & Co. KG', 0x1428: 'Shenzhen Aimore .Co .,Ltd', 0x1429: 'Albrecht Jung GmbH & Co. KG', - 0x142A: 'Hitachi Global Life Solutions, Inc.', - 0x142B: 'Beijing Renhejia Technology Co., Ltd', - 0x142C: 'vivo Mobile Communication Co., Ltd.', - 0x142D: 'Zhongshan QIHANG Electronic Technology Co.', - 0x142E: 'Shenzhen Sowye Technology CO.,Ltd', - 0x142F: 'Shenzhen QIACHIP Wireless Ecommerce Co.', + 0x142a: 'Hitachi Global Life Solutions, Inc.', + 0x142b: 'Beijing Renhejia Technology Co., Ltd', + 0x142c: 'vivo Mobile Communication Co., Ltd.', + 0x142d: 'Zhongshan QIHANG Electronic Technology Co.', + 0x142e: 'Shenzhen Sowye Technology CO.,Ltd', + 0x142f: 'Shenzhen QIACHIP Wireless Ecommerce Co.', 0x1430: 'L-TRADE GROUP SP z.o.o.', 0x1431: 'Daikin Industries, Ltd.', 0x1432: 'ELKO EP, s.r.o.', @@ -794,12 +794,12 @@ const VENDOR_IDS: Record = { 0x1437: 'ACCEL LAB Ltd.', 0x1438: 'Xiamen Topstar Lighting Co.,Ltd', 0x1439: 'Vaillant Group', - 0x143A: 'YoSmart Inc.', - 0x143B: 'Amina Charging AS', - 0x143C: 'Athom B.V.', - 0x143D: 'Shenzhen Champon Technology Co., Ltd', - 0x143E: 'Acer Inc.', - 0x143F: 'Vestel Elektronik Sanayi ve Ticaret A.S.', + 0x143a: 'YoSmart Inc.', + 0x143b: 'Amina Charging AS', + 0x143c: 'Athom B.V.', + 0x143d: 'Shenzhen Champon Technology Co., Ltd', + 0x143e: 'Acer Inc.', + 0x143f: 'Vestel Elektronik Sanayi ve Ticaret A.S.', 0x1440: 'VerLuce', 0x1441: 'Shenzhen Snowball Technology Co., Ltd.', 0x1442: 'REHAU Group', @@ -810,12 +810,12 @@ const VENDOR_IDS: Record = { 0x1447: 'Honor Device Co., Ltd.', 0x1448: 'LivingStyle Enterprises Limited', 0x1449: 'ZUTTO TECHNOLOGIES', - 0x144A: 'Sensibo Ltd.', - 0x144B: 'Kohler Company', - 0x144C: 'TrustAsia Technologies, Inc.', - 0x144D: 'Atios AG', - 0x144E: 'Sense Labs, Inc.', - 0x144F: 'Assa Abloy AB', + 0x144a: 'Sensibo Ltd.', + 0x144b: 'Kohler Company', + 0x144c: 'TrustAsia Technologies, Inc.', + 0x144d: 'Atios AG', + 0x144e: 'Sense Labs, Inc.', + 0x144f: 'Assa Abloy AB', 0x1450: 'GM Global Technology Operations LLC', 0x1451: 'JetHome', 0x1452: 'Big Ass Fans', @@ -826,12 +826,12 @@ const VENDOR_IDS: Record = { 0x1457: 'Hangzhou Wistar Mechanical & Electric Technology Co., Ltd', 0x1458: 'Wilhelm Koch GmbH ', 0x1459: 'Shenzhen iComm Semiconductor Co., Ltd.', - 0x145A: 'British Telecommunications plc', - 0x145B: 'Remotec Technology Ltd.', - 0x145C: 'Pin Genie, Inc. DBA Lockly', - 0x145D: 'Hosiden Corporation', - 0x145E: 'Deako, Inc.', - 0x145F: 'Good Way Technology Co., Ltd.', + 0x145a: 'British Telecommunications plc', + 0x145b: 'Remotec Technology Ltd.', + 0x145c: 'Pin Genie, Inc. DBA Lockly', + 0x145d: 'Hosiden Corporation', + 0x145e: 'Deako, Inc.', + 0x145f: 'Good Way Technology Co., Ltd.', 0x1460: 'Zhuhai Ruran Intelligent Technology Co., LTD (Meizu)', 0x1461: 'Xinda Asset Management (Shenzhen) Co.,Ltd.', 0x1462: 'Chengdu Energy Magic Cube Technology Co., Ltd', @@ -842,12 +842,12 @@ const VENDOR_IDS: Record = { 0x1467: 'OTODO SAS', 0x1468: 'Anona Security Technology Limited', 0x1469: 'Loxone Electronics GmbH', - 0x146A: 'Intecular LLC', - 0x146B: 'Aixlink Ltd.', - 0x146C: 'Shenzhen Jinjie Technology Co.,Ltd.', - 0x146D: 'Polyaire Pty Ltd', - 0x146E: 'Shenzhen PINXUAN Trading Co.', - 0x146F: 'SmartWing Home LLC', + 0x146a: 'Intecular LLC', + 0x146b: 'Aixlink Ltd.', + 0x146c: 'Shenzhen Jinjie Technology Co.,Ltd.', + 0x146d: 'Polyaire Pty Ltd', + 0x146e: 'Shenzhen PINXUAN Trading Co.', + 0x146f: 'SmartWing Home LLC', 0x1470: 'Shenzhen Hope Microelectronics Co., Ltd.', 0x1471: 'Commax', 0x1472: 'Zhejiang Jiecang Linear Motion Technology Co.,Ltd', @@ -858,12 +858,12 @@ const VENDOR_IDS: Record = { 0x1477: 'Shenzhen Multi IR Technology Co.,Ltd', 0x1478: 'APYNOV', 0x1479: 'Browan Communications Inc.', - 0x147A: 'Shenzhen Realwe Innovation Technology Co., Ltd.', - 0x147B: 'Lumiflow INC', - 0x147C: 'SHENZHEN SHENAN YANGGUANG ELECTRONICS CO., LTD.', - 0x147D: 'Wenzhou Morning Electronics Co., Ltd.', - 0x147E: 'MIWA Lock Co., Ltd.', - 0x147F: 'U-tec Group Inc.', + 0x147a: 'Shenzhen Realwe Innovation Technology Co., Ltd.', + 0x147b: 'Lumiflow INC', + 0x147c: 'SHENZHEN SHENAN YANGGUANG ELECTRONICS CO., LTD.', + 0x147d: 'Wenzhou Morning Electronics Co., Ltd.', + 0x147e: 'MIWA Lock Co., Ltd.', + 0x147f: 'U-tec Group Inc.', 0x1480: 'Beijing Roborock Technology Co., Ltd.', 0x1481: 'Shenzhen Xenon Industrial Ltd', 0x1482: 'Guangzhou Lingqu Electronic Technology Co., Ltd', @@ -874,42 +874,42 @@ const VENDOR_IDS: Record = { 0x1487: 'Whirlpool Corp.', 0x1488: 'Shortcut Labs (Flic)', 0x1489: 'INTEREL BUILDING AUTOMATION', - 0x148A: 'Occhio GmbH', - 0x148B: 'Samraj Technologies Limited', + 0x148a: 'Occhio GmbH', + 0x148b: 'Samraj Technologies Limited', 0x1994: 'Gewiss S.p.A.', 0x2794: 'Climax Technology Co., Ltd.', 0x6006: 'Google LLC', - 0xC5A0: 'Connectivity Standards Alliance', - 0xC5A1: 'Connectivity Standards Alliance', - 0xC5A2: 'Connectivity Standards Alliance', - 0xC5A3: 'Connectivity Standards Alliance', - 0xC5A4: 'Connectivity Standards Alliance', - 0xC5A5: 'Connectivity Standards Alliance', - 0xC5A6: 'Connectivity Standards Alliance', - 0xC5A7: 'Connectivity Standards Alliance', - 0xC5A8: 'Connectivity Standards Alliance', - 0xC5A9: 'Connectivity Standards Alliance', - 0xC5AA: 'Connectivity Standards Alliance', - 0xC5AB: 'Connectivity Standards Alliance', - 0xC5AC: 'Connectivity Standards Alliance', - 0xC5AD: 'Connectivity Standards Alliance', - 0xC5AE: 'Connectivity Standards Alliance', - 0xC5AF: 'Connectivity Standards Alliance', - 0xFFF1: '[Test vendor #1]', - 0xFFF2: '[Test vendor #2]', - 0xFFF3: '[Test vendor #3]', - 0xFFF4: '[Test vendor #4]', - 0xFFF5: '[Reserved]', - 0xFFF6: '[Reserved]', - 0xFFF7: '[Reserved]', - 0xFFF8: '[Reserved]', - 0xFFF9: '[Reserved]', - 0xFFFA: '[Reserved]', - 0xFFFB: '[Reserved]', - 0xFFFC: '[Reserved]', - 0xFFFD: '[Reserved]', - 0xFFFE: '[Reserved]', - 0xFFFF: '[Reserved]', + 0xc5a0: 'Connectivity Standards Alliance', + 0xc5a1: 'Connectivity Standards Alliance', + 0xc5a2: 'Connectivity Standards Alliance', + 0xc5a3: 'Connectivity Standards Alliance', + 0xc5a4: 'Connectivity Standards Alliance', + 0xc5a5: 'Connectivity Standards Alliance', + 0xc5a6: 'Connectivity Standards Alliance', + 0xc5a7: 'Connectivity Standards Alliance', + 0xc5a8: 'Connectivity Standards Alliance', + 0xc5a9: 'Connectivity Standards Alliance', + 0xc5aa: 'Connectivity Standards Alliance', + 0xc5ab: 'Connectivity Standards Alliance', + 0xc5ac: 'Connectivity Standards Alliance', + 0xc5ad: 'Connectivity Standards Alliance', + 0xc5ae: 'Connectivity Standards Alliance', + 0xc5af: 'Connectivity Standards Alliance', + 0xfff1: '[Test vendor #1]', + 0xfff2: '[Test vendor #2]', + 0xfff3: '[Test vendor #3]', + 0xfff4: '[Test vendor #4]', + 0xfff5: '[Reserved]', + 0xfff6: '[Reserved]', + 0xfff7: '[Reserved]', + 0xfff8: '[Reserved]', + 0xfff9: '[Reserved]', + 0xfffa: '[Reserved]', + 0xfffb: '[Reserved]', + 0xfffc: '[Reserved]', + 0xfffd: '[Reserved]', + 0xfffe: '[Reserved]', + 0xffff: '[Reserved]', }; -export default VENDOR_IDS; \ No newline at end of file +export default VENDOR_IDS; From 500af20bb264135e762239eab6dfedd45c333f2f Mon Sep 17 00:00:00 2001 From: Ingo Fischer Date: Sat, 20 Jul 2024 18:05:18 +0200 Subject: [PATCH 2/4] see https://github.com/npm/cli/issues/7672 --- .github/workflows/test-and-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-and-release.yml b/.github/workflows/test-and-release.yml index 7206be9..84b36fd 100644 --- a/.github/workflows/test-and-release.yml +++ b/.github/workflows/test-and-release.yml @@ -55,7 +55,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - node-version: [18.x, 20.x, 22.x] + node-version: [18.x, 20.x, 22.4.1] os: [ubuntu-latest, windows-latest, macos-latest] steps: From 5586a2a7868f712b147af3a8e7ef71a13b380ba5 Mon Sep 17 00:00:00 2001 From: Ingo Fischer Date: Sun, 21 Jul 2024 10:50:04 +0200 Subject: [PATCH 3/4] review feedback --- .eslintrc.js | 14 ++++---- package-lock.json | 90 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 ++ 3 files changed, 98 insertions(+), 8 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 8cb3e88..3afb862 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -9,21 +9,19 @@ module.exports = { jsx: true, }, }, - extends: [ - 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin - ], + extends: ['plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'], rules: { - 'semi': 'off', + semi: 'off', '@typescript-eslint/semi': 'error', '@typescript-eslint/object-curly-spacing': 'off', '@typescript-eslint/space-before-function-paren': 'off', - 'quotes': [ + quotes: [ 'error', 'single', { - 'avoidEscape': true, - 'allowTemplateLiterals': true - } + avoidEscape: true, + allowTemplateLiterals: true, + }, ], '@typescript-eslint/no-parameter-properties': 'off', '@typescript-eslint/no-explicit-any': 'off', diff --git a/package-lock.json b/package-lock.json index f18fd74..7765a6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,8 +30,10 @@ "chai": "^4.4.1", "colorette": "^2.0.20", "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-n": "^17.9.0", + "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-promise": "^6.5.1", "gulp": "^4.0.2", "mocha": "^10.6.0", @@ -831,6 +833,18 @@ "node": ">=14" } }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@project-chip/matter-node-ble.js": { "version": "0.10.0-alpha.0-20240720-471dea8c", "resolved": "https://registry.npmjs.org/@project-chip/matter-node-ble.js/-/matter-node-ble.js-0.10.0-alpha.0-20240720-471dea8c.tgz", @@ -4677,6 +4691,18 @@ "eslint": ">=6.0.0" } }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", @@ -4864,6 +4890,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint-plugin-prettier": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, "node_modules/eslint-plugin-promise": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.5.1.tgz", @@ -5465,6 +5521,12 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", @@ -10404,6 +10466,18 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/prettier-plugin-organize-imports": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-4.0.0.tgz", @@ -12474,6 +12548,22 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "node_modules/synckit": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", + "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/table": { "version": "6.8.2", "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", diff --git a/package.json b/package.json index 05df4ed..56934f4 100644 --- a/package.json +++ b/package.json @@ -44,9 +44,11 @@ "@typescript-eslint/eslint-plugin": "^7.16.1", "chai": "^4.4.1", "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-n": "^17.9.0", "eslint-plugin-promise": "^6.5.1", + "eslint-plugin-prettier": "^5.2.1", "gulp": "^4.0.2", "mocha": "^10.6.0", "prettier": "^3.3.3", From a7a87b9af8d353b3ecedc4abe9b5144625b4c012 Mon Sep 17 00:00:00 2001 From: Ingo Fischer Date: Sun, 21 Jul 2024 10:57:51 +0200 Subject: [PATCH 4/4] review feedback --- .../components/InstanceManager/i18n/i18n.d.ts | 12 ++++++------ src/main.ts | 18 ++++++++---------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src-admin/src/components/InstanceManager/i18n/i18n.d.ts b/src-admin/src/components/InstanceManager/i18n/i18n.d.ts index 7b4c729..3cccefd 100644 --- a/src-admin/src/components/InstanceManager/i18n/i18n.d.ts +++ b/src-admin/src/components/InstanceManager/i18n/i18n.d.ts @@ -17,10 +17,10 @@ declare type AdminWord = keyof typeof import('./en.json'); declare module '@iobroker/adapter-react/i18n' { - /** - * Translate the given string to the selected language. - * @param word The (key) word to look up the string. Has to be defined at least in `i18n/en.json`. - * @param args Optional arguments which will replace the first (second, third, ...) occurence of %s - */ - function t(word: AdminWord, ...args: string[]): string; + /** + * Translate the given string to the selected language. + * @param word The (key) word to look up the string. Has to be defined at least in `i18n/en.json`. + * @param args Optional arguments which will replace the first (second, third, ...) occurence of %s + */ + function t(word: AdminWord, ...args: string[]): string; } diff --git a/src/main.ts b/src/main.ts index c8fec71..b420c8e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,12 +1,13 @@ import '@project-chip/matter-node.js'; -import axios from 'axios'; -import jwt from 'jsonwebtoken'; -import fs from 'node:fs'; import * as utils from '@iobroker/adapter-core'; import ChannelDetector, { DetectorState, PatternControl, Types } from '@iobroker/type-detector'; +import { Environment, StorageService } from '@project-chip/matter.js/environment'; import { Level, Logger } from '@project-chip/matter.js/log'; - +import axios from 'axios'; +import jwt from 'jsonwebtoken'; +import fs from 'node:fs'; +import { MatterControllerConfig } from '../src-admin/src/types'; import { BridgeDescription, BridgeDeviceDescription, @@ -14,17 +15,14 @@ import { MatterAdapterConfig, } from './ioBrokerStorageTypes'; import { DeviceFactory, SubscribeManager } from './lib'; +import MatterAdapterDeviceManagement from './lib/DeviceManagement'; import { DetectedDevice, DeviceOptions } from './lib/devices/GenericDevice'; +import { NodeStateResponse } from './matter/BaseServerNode'; import BridgedDevice, { BridgeCreateOptions } from './matter/BridgedDevicesNode'; import MatterController from './matter/ControllerNode'; import MatterDevice, { DeviceCreateOptions } from './matter/DeviceNode'; -import { IoBrokerNodeStorage } from './matter/IoBrokerNodeStorage'; - -import { Environment, StorageService } from '@project-chip/matter.js/environment'; -import { MatterControllerConfig } from '../src-admin/src/types'; -import MatterAdapterDeviceManagement from './lib/DeviceManagement'; -import { NodeStateResponse } from './matter/BaseServerNode'; import { MessageResponse } from './matter/GeneralNode'; +import { IoBrokerNodeStorage } from './matter/IoBrokerNodeStorage'; const IOBROKER_USER_API = 'https://iobroker.pro:3001';