├── .eslintignore ├── admin ├── favicon.ico ├── homekit-controller.png ├── manifest.json ├── static │ ├── media │ │ ├── Upstairs.441813e54e0daca0882d.svg │ │ ├── Outdoor Blinds.37b85a9c060a4af48da9.svg │ │ ├── Garage Doors.0c2a1cfca7ad1ea59625.svg │ │ ├── Doors.d59bf859f582d3488a04.svg │ │ ├── Window.421664f57c35e5109aa2.svg │ │ ├── Bedroom.2a16d8d98fafe965fd1b.svg │ │ ├── Floor Lamps.471e0bcf308d94963504.svg │ │ ├── Sockets.8320e1a99be9de004629.svg │ │ ├── Handle.3de1d1320fc3ce2f9712.svg │ │ ├── Hanging Lamps.0bd452fc843edd645c30.svg │ │ ├── Tv.4e9745a548e57bfac0c7.svg │ │ ├── Water Consumption.68891649591cc2434c5b.svg │ │ ├── Stairwell.0914feea948153a8637a.svg │ │ ├── Basement.fe636968eec9556bfd1f.svg │ │ ├── Shed.491a2ad372036118002c.svg │ │ ├── Shading.0577383dc227cd043b3d.svg │ │ ├── Printer.146d983be964b95745d2.svg │ │ ├── Carport.8337662544b9e95f4b27.svg │ │ ├── Water Heater.7e4bb4d99a5213f24d08.svg │ │ ├── Hall.9c2fa95419cb84ecda68.svg │ │ ├── Storeroom.7de4e6f3364554459b8a.svg │ │ ├── Power Consumption.4faab614c3c788f2d338.svg │ │ ├── Ceiling Spotlights.485822441b5df3b3384a.svg │ │ ├── Lock.2cbfe17ea8923e0f4e9e.svg │ │ ├── Swimming Pool.190b378cb0707edb9461.svg │ │ ├── Garage.f7fc0a9b326d582afee6.svg │ │ ├── Outdoors.da42e64a4b6ec2dd1e1c.svg │ │ ├── People.12a7e9127e72f3259186.svg │ │ ├── Laundry Room.58da550dff0173676e02.svg │ │ ├── Fan.8a29f85d6ca99c584603.svg │ │ ├── Awnings.78480df8796f09859b6a.svg │ │ ├── Washroom.bfb54196f381f36de9d6.svg │ │ ├── Computer.9558f6ee3941dba4e3c5.svg │ │ ├── Coffee Makers.9fb4d82f957a06f30dae.svg │ │ ├── Attic.bb5d690a160bb1d4edb2.svg │ │ ├── Table Lamps.bd92de33bf86b6cbaec9.svg │ │ ├── Nursery.9cecc0544bdb5c28500c.svg │ │ ├── Terrace.d71d07d9290674f2ca20.svg │ │ ├── Guest Bathroom.d07a9f1cf32a82d03267.svg │ │ ├── Receiver.26b5ae166395a6dcb83f.svg │ │ ├── Sleeping Area.828017602bfcc2dd7dce.svg │ │ ├── Dryer.5ea89bd6dc20a00fb442.svg │ │ ├── Consumption.fecd7a10a13fe4e5f69b.svg │ │ ├── Hairdryer.5960b514dac1f04f3c4d.svg │ │ ├── Weather.e91dae647698d48365e3.svg │ │ ├── Mowing Machine.9ead5b039f36cdc800e6.svg │ │ ├── Playroom.e64c9de43030c28d2f96.svg │ │ ├── Kitchen.deb7f976c1f43f9039a2.svg │ │ ├── Wc.83604dd2daafb67067dd.svg │ │ ├── Toilet.83604dd2daafb67067dd.svg │ │ ├── Temperature Sensors.75d805988a6b77b231d8.svg │ │ ├── Hoods.c177ddfec9fa9a6335db.svg │ │ ├── Ventilation.c31761d86d67e245ac92.svg │ │ ├── Led Strip.5cf2de461e29ffbaa5f0.svg │ │ ├── Amplifier.6f5d18048328386033f8.svg │ │ ├── Office.7e6a38218390b655e270.svg │ │ ├── Boiler Room.548e785e2f92b45f72b3.svg │ │ ├── Summer House.541a9fec69f01105e244.svg │ │ ├── SmokeDetector.8222f77cb07030a409ee.svg │ │ ├── Cold Water.937aad5fa21b0c20a856.svg │ │ ├── Hot Water.5c0a9e01741562e1fbab.svg │ │ ├── Stairway.9b007e08605296110003.svg │ │ ├── Living Room.3c380ab767be35f904e1.svg │ │ ├── Doorstep.10630b759b4867a10776.svg │ │ ├── Iron.b8a65a48503b6f3e0dc8.svg │ │ ├── Gates.5a8baf2c3d4832ca57e8.svg │ │ ├── Speaker.db548379676317470c4f.svg │ │ ├── Chamber.71daaa4d14262dae029b.svg │ │ ├── Guest Room.41c7cfa38806f5009f82.svg │ │ ├── Rear Wall.38843c33f1ea1f575500.svg │ │ ├── Battery Status.5951e2078ae1e573510e.svg │ │ ├── Barn.5d839e84c80918ce2ef0.svg │ │ ├── Workshop.7856e59fe4f164c90609.svg │ │ ├── Security.1ec78971bd34efa950f8.svg │ │ ├── Chandelier.8b9fbdbc73bc2e955ef7.svg │ │ └── Workspace.97d73e419d966bfb6428.svg │ └── css │ │ ├── main.96b3c861.css │ │ └── main.96b3c861.css.map └── index_m.html ├── .github ├── FUNDING.yml ├── dependabot.yml ├── auto-merge.yml ├── ISSUE_TEMPLATE │ └── bug_report.md ├── workflows │ └── dependabot-auto-merge.yml └── stale.yml ├── srcAdmin ├── public │ ├── favicon.ico │ ├── homekit-controller.png │ ├── manifest.json │ └── index.html ├── src │ ├── App.test.js │ ├── index.css │ ├── i18n │ │ ├── zh-cn.json │ │ ├── en.json │ │ ├── uk.json │ │ ├── it.json │ │ ├── es.json │ │ ├── de.json │ │ ├── pl.json │ │ ├── nl.json │ │ ├── ru.json │ │ ├── pt.json │ │ └── fr.json │ └── index.js └── package.json ├── .releaseconfig.json ├── test ├── package.js ├── tsconfig.json ├── mocharc.custom.json ├── unit.js ├── integration.js └── mocha.setup.js ├── src ├── lib │ ├── converter │ │ ├── base64.ts │ │ ├── number-to-boolean.ts │ │ ├── number-to-boolean-invert.ts │ │ └── index.ts │ ├── adapter-config.d.ts │ └── tools.ts └── main.test.ts ├── .babelrc ├── tsconfig.build.json ├── .gitignore ├── .npmignore ├── LICENSE ├── .create-adapter.json ├── tsconfig.json ├── .eslintrc.js └── package.json /.eslintignore: -------------------------------------------------------------------------------- 1 | **/.eslintrc.js 2 | **/build 3 | -------------------------------------------------------------------------------- /admin/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apollon77/ioBroker.homekit-controller/HEAD/admin/favicon.ico -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: Apollon77 4 | patreon: Apollon77 5 | -------------------------------------------------------------------------------- /srcAdmin/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apollon77/ioBroker.homekit-controller/HEAD/srcAdmin/public/favicon.ico -------------------------------------------------------------------------------- /admin/homekit-controller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apollon77/ioBroker.homekit-controller/HEAD/admin/homekit-controller.png -------------------------------------------------------------------------------- /.releaseconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["iobroker", "license"], 3 | "exec": { 4 | "before_commit": "npm run build" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /srcAdmin/public/homekit-controller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apollon77/ioBroker.homekit-controller/HEAD/srcAdmin/public/homekit-controller.png -------------------------------------------------------------------------------- /test/package.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { tests } = require('@iobroker/testing'); 3 | 4 | // Validate the package files 5 | tests.packageFiles(path.join(__dirname, '..')); 6 | -------------------------------------------------------------------------------- /test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "noImplicitAny": false 5 | }, 6 | "include": [ 7 | "./**/*.js" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /test/mocharc.custom.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": [ 3 | "test/mocha.setup.js", 4 | "ts-node/register", 5 | "source-map-support/register" 6 | ], 7 | "watch-files": [ 8 | "src/**/*.test.ts" 9 | ] 10 | } -------------------------------------------------------------------------------- /test/unit.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { tests } = require('@iobroker/testing'); 3 | 4 | // Run unit tests - See https://github.com/ioBroker/testing for a detailed explanation and further options 5 | tests.unit(path.join(__dirname, '..')); 6 | -------------------------------------------------------------------------------- /test/integration.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { tests } = require('@iobroker/testing'); 3 | 4 | // Run integration tests - See https://github.com/ioBroker/testing for a detailed explanation and further options 5 | tests.integration(path.join(__dirname, '..')); 6 | -------------------------------------------------------------------------------- /srcAdmin/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /src/lib/converter/base64.ts: -------------------------------------------------------------------------------- 1 | import { ConverterType } from './index'; 2 | 3 | export default { 4 | read: (value: ioBroker.StateValue): ioBroker.StateValue => { 5 | return value; 6 | }, 7 | write: (value: ioBroker.StateValue): ioBroker.StateValue => { 8 | return value; 9 | } 10 | } as ConverterType; 11 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-typescript", 4 | ["@babel/preset-env", { "targets": { "node": "current" } }] 5 | ], 6 | "plugins": [ 7 | ["@babel/plugin-transform-typescript", { "allowDeclareFields": true }], 8 | ["@babel/plugin-proposal-decorators", { "legacy": true }] 9 | ] 10 | } -------------------------------------------------------------------------------- /src/lib/converter/number-to-boolean.ts: -------------------------------------------------------------------------------- 1 | import { ConverterType } from './index'; 2 | 3 | export default { 4 | read: (value: ioBroker.StateValue): ioBroker.StateValue => { 5 | return !!value; 6 | }, 7 | write: (value: ioBroker.StateValue): ioBroker.StateValue => { 8 | return value ? 1 : 0; 9 | } 10 | } as ConverterType; 11 | -------------------------------------------------------------------------------- /src/lib/converter/number-to-boolean-invert.ts: -------------------------------------------------------------------------------- 1 | import { ConverterType } from './index'; 2 | 3 | export default { 4 | read: (value: ioBroker.StateValue): ioBroker.StateValue => { 5 | return !value; 6 | }, 7 | write: (value: ioBroker.StateValue): ioBroker.StateValue => { 8 | return value ? 0 : 1; 9 | } 10 | } as ConverterType; 11 | -------------------------------------------------------------------------------- /admin/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Homekit-Controller", 3 | "name": "ioBroker Homekit-Controller Settings", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /srcAdmin/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Homekit-Controller", 3 | "name": "ioBroker Homekit-Controller Settings", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | // Specialized tsconfig to only compile .ts-files in the src dir 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "allowJs": false, 6 | "checkJs": false, 7 | "noEmit": false, 8 | "declaration": false 9 | }, 10 | "include": [ 11 | "src/**/*.ts" 12 | ], 13 | "exclude": [ 14 | "src/**/*.test.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .git 2 | .idea 3 | *.code-workspace 4 | node_modules 5 | nbproject 6 | .cache 7 | 8 | # Sourcemaps 9 | maps/ 10 | 11 | # npm package files 12 | iobroker.*.tgz 13 | 14 | Thumbs.db 15 | 16 | # i18n intermediate files 17 | admin/i18n/flat.txt 18 | admin/i18n/*/flat.txt 19 | 20 | .dev-server 21 | /admin/src/package-lock.json 22 | /srcAdmin/package-lock.json 23 | /srcAdmin/build 24 | 25 | #ignore .commitinfo created by ioBroker release script 26 | .commitinfo 27 | -------------------------------------------------------------------------------- /admin/static/media/Upstairs.441813e54e0daca0882d.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .* 2 | node_modules/ 3 | nbproject/ 4 | *.code-workspace 5 | Thumbs.db 6 | gulpfile.js 7 | 8 | # CI test files 9 | test/ 10 | travis/ 11 | appveyor.yaml 12 | 13 | # React sources for the Admin UI 14 | srcAdmin/ 15 | 16 | # TypeScript sources and project configuration 17 | src/ 18 | tsconfig.json 19 | tsconfig.*.json 20 | 21 | # Sourcemaps 22 | *.map 23 | 24 | # npm package files 25 | iobroker.*.tgz 26 | package-lock.json 27 | 28 | # maintenance scripts 29 | maintenance/** 30 | 31 | .dev-server 32 | -------------------------------------------------------------------------------- /admin/static/css/main.96b3c861.css: -------------------------------------------------------------------------------- 1 | body,html{height:100%}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;margin:0;overflow:hidden;padding:0;width:100%}::-webkit-scrollbar,::-webkit-scrollbar-track{background-color:#ccc}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-thumb{background-color:#575757}#root,.App{height:100%} 2 | /*# sourceMappingURL=main.96b3c861.css.map*/ -------------------------------------------------------------------------------- /src/lib/converter/index.ts: -------------------------------------------------------------------------------- 1 | import Base64Converter from './base64'; 2 | import NumberToBooleanConverter from './number-to-boolean'; 3 | import NumberToBooleanInvertConverter from './number-to-boolean-invert'; 4 | 5 | export interface ConverterType { 6 | read: (value: ioBroker.StateValue) => ioBroker.StateValue, 7 | write: (value: ioBroker.StateValue) => ioBroker.StateValue, 8 | } 9 | 10 | export default { 11 | 'base64': Base64Converter, 12 | 'number-to-boolean': NumberToBooleanConverter, 13 | 'number-to-boolean-invert': NumberToBooleanInvertConverter 14 | }; 15 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Dependabot will run on day 20 of each month at 01:31 (Europe/Berlin timezone) 2 | version: 2 3 | updates: 4 | 5 | - package-ecosystem: "github-actions" 6 | directory: "/" 7 | schedule: 8 | interval: "cron" 9 | timezone: "Europe/Berlin" 10 | cronjob: "31 1 20 * *" 11 | open-pull-requests-limit: 15 12 | 13 | - package-ecosystem: "npm" 14 | schedule: 15 | interval: "cron" 16 | timezone: "Europe/Berlin" 17 | cronjob: "31 1 20 * *" 18 | open-pull-requests-limit: 20 19 | versioning-strategy: "increase" 20 | directories: 21 | - "**/*" 22 | -------------------------------------------------------------------------------- /admin/index_m.html: -------------------------------------------------------------------------------- 1 | Homekit-Controller Settings
-------------------------------------------------------------------------------- /src/lib/adapter-config.d.ts: -------------------------------------------------------------------------------- 1 | // This file extends the AdapterConfig type from "@types/iobroker" 2 | 3 | // Augment the globally declared type ioBroker.AdapterConfig 4 | declare global { 5 | namespace ioBroker { 6 | interface AdapterConfig { 7 | discoverIp: boolean; 8 | discoverBle: boolean; 9 | dataPollingIntervalIp: number; 10 | dataPollingIntervalBle: number; 11 | bleInterface: string; 12 | updateOnlyChangedValues: boolean; 13 | } 14 | } 15 | } 16 | 17 | // this is required so the above AdapterConfig is found by TypeScript / type checking 18 | export {}; 19 | -------------------------------------------------------------------------------- /admin/static/media/Outdoor Blinds.37b85a9c060a4af48da9.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.github/auto-merge.yml: -------------------------------------------------------------------------------- 1 | # Configure here which dependency updates should be merged automatically. 2 | # The recommended configuration is the following: 3 | - match: 4 | # Only merge patches for production dependencies 5 | dependency_type: production 6 | update_type: "semver:patch" 7 | - match: 8 | # Except for security fixes, here we allow minor patches 9 | dependency_type: production 10 | update_type: "security:minor" 11 | - match: 12 | # and development dependencies can have a minor update, too 13 | dependency_type: development 14 | update_type: "semver:minor" 15 | 16 | # The syntax is based on the legacy dependabot v1 automerged_updates syntax, see: 17 | # https://dependabot.com/docs/config-file/#automerged_updates 18 | -------------------------------------------------------------------------------- /srcAdmin/src/index.css: -------------------------------------------------------------------------------- 1 | html { 2 | height: 100%; 3 | } 4 | body { 5 | margin: 0; 6 | padding: 0; 7 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; 8 | -webkit-font-smoothing: antialiased; 9 | -moz-osx-font-smoothing: grayscale; 10 | width: 100%; 11 | height: 100%; 12 | overflow: hidden; 13 | } 14 | /* scrollbar */ 15 | *::-webkit-scrollbar-track { 16 | background-color: #ccc; 17 | } 18 | *::-webkit-scrollbar { 19 | width: 6px; 20 | background-color: #ccc; 21 | } 22 | *::-webkit-scrollbar-thumb { 23 | background-color: #575757; 24 | } 25 | 26 | 27 | #root { 28 | height: 100%; 29 | } 30 | .App { 31 | height: 100%; 32 | } -------------------------------------------------------------------------------- /admin/static/media/Garage Doors.0c2a1cfca7ad1ea59625.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /admin/static/media/Doors.d59bf859f582d3488a04.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /test/mocha.setup.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Makes ts-node ignore warnings, so mocha --watch does work 4 | process.env.TS_NODE_IGNORE_WARNINGS = 'TRUE'; 5 | // Sets the correct tsconfig for testing 6 | process.env.TS_NODE_PROJECT = 'tsconfig.json'; 7 | // Make ts-node respect the "include" key in tsconfig.json 8 | process.env.TS_NODE_FILES = 'TRUE'; 9 | 10 | // Don't silently swallow unhandled rejections 11 | process.on('unhandledRejection', (e) => { 12 | throw e; 13 | }); 14 | 15 | // enable the should interface with sinon 16 | // and load chai-as-promised and sinon-chai by default 17 | const sinonChai = require('sinon-chai'); 18 | const chaiAsPromised = require('chai-as-promised'); 19 | const { should, use } = require('chai'); 20 | 21 | should(); 22 | use(sinonChai); 23 | use(chaiAsPromised); -------------------------------------------------------------------------------- /admin/static/media/Window.421664f57c35e5109aa2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main.test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This is a dummy TypeScript test file using chai and mocha 3 | * 4 | * It's automatically excluded from npm and its build output is excluded from both git and npm. 5 | * It is advised to test all your modules with accompanying *.test.ts-files 6 | */ 7 | 8 | import { expect } from 'chai'; 9 | // import { functionToTest } from "./moduleToTest"; 10 | 11 | describe('module to test => function to test', () => { 12 | // initializing logic 13 | const expected = 5; 14 | 15 | it(`should return ${expected}`, () => { 16 | const result = 5; 17 | // assign result a value from functionToTest 18 | expect(result).to.equal(expected); 19 | // or using the should() syntax 20 | result.should.equal(expected); 21 | }); 22 | // ... more tests => it 23 | 24 | }); 25 | 26 | // ... more test suites => describe 27 | -------------------------------------------------------------------------------- /admin/static/css/main.96b3c861.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"static/css/main.96b3c861.css","mappings":"AAGA,UAFE,WAWF,CATA,KAIE,kCAAmC,CACnC,iCAAkC,CAFlC,mIAA8J,CAF9J,QAAS,CAOT,eAAgB,CANhB,SAAU,CAIV,UAGF,CAKA,8CAFE,qBAKF,CAHA,oBACE,SAEF,CACA,0BACE,wBACF,CAMA,WACE,WACF","sources":["index.css"],"sourcesContent":["html {\n height: 100%;\n}\nbody {\n margin: 0;\n padding: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n/* scrollbar */\n*::-webkit-scrollbar-track {\n background-color: #ccc;\n}\n*::-webkit-scrollbar {\n width: 6px;\n background-color: #ccc;\n}\n*::-webkit-scrollbar-thumb {\n background-color: #575757;\n}\n\n\n#root {\n height: 100%;\n}\n.App {\n height: 100%;\n}"],"names":[],"sourceRoot":""} -------------------------------------------------------------------------------- /srcAdmin/src/i18n/zh-cn.json: -------------------------------------------------------------------------------- 1 | { 2 | "Error": "错误", 3 | "Paired": "配对", 4 | "Unpaired": "未配对", 5 | "Identified": "已鉴定", 6 | "Connected": "连接的", 7 | "Discovered": "发现", 8 | "Identify": "确认", 9 | "Pair": "一对", 10 | "Unpair": "取消配对", 11 | "Refresh devices list": "刷新设备列表", 12 | "ID": "ID", 13 | "Type": "类型", 14 | "Name": "名称", 15 | "Category": "类别", 16 | "Please enter PIN": "请输入密码", 17 | "PIN": "别针", 18 | "Close": "关闭", 19 | "Instance must be started to set up the devices": "必须启动实例才能设置设备", 20 | "Start?": "开始?", 21 | "Discover over IP": "通过 IP 发现", 22 | "Discover over Bluetooth": "通过蓝牙发现", 23 | "Data polling interval for IP": "IP 的数据轮询间隔", 24 | "Data polling interval for Bluetooth": "蓝牙数据轮询间隔", 25 | "Update only changed values": "仅更新更改的值", 26 | "Options": "选项", 27 | "Devices": "设备", 28 | "seconds": "秒", 29 | "Are you sure?": "你确定吗?", 30 | "Please confirm": "请确认", 31 | "Cancel": "取消" 32 | } 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Something is not working as it should 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **To Reproduce** 13 | Steps to reproduce the behavior: 14 | 1. Go to '...' 15 | 2. Click on '...' 16 | 3. Scroll down to '....' 17 | 4. See error 18 | 19 | **Expected behavior** 20 | A clear and concise description of what you expected to happen. 21 | 22 | **Screenshots & Logfiles** 23 | If applicable, add screenshots and logfiles to help explain your problem. 24 | 25 | **Versions:** 26 | - Adapter version: 27 | - JS-Controller version: 28 | - Node version: 29 | - Operating system: 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /admin/static/media/Bedroom.2a16d8d98fafe965fd1b.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /admin/static/media/Floor Lamps.471e0bcf308d94963504.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /srcAdmin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "homekit-controller-admin", 3 | "version": "0.5.11", 4 | "private": true, 5 | "dependencies": { 6 | "@iobroker/adapter-react-v5": "^4.9.5", 7 | "@mui/material": "5.14.14", 8 | "@mui/styles": "5.14.14", 9 | "@mui/icons-material": "^5.15.6", 10 | "@sentry/browser": "^7.98.0", 11 | "@sentry/integrations": "^7.98.0", 12 | "babel-eslint": "^10.1.0", 13 | "react": "^18.2.0", 14 | "react-dom": "^18.2.0", 15 | "react-icons": "^5.0.1", 16 | "react-scripts": "^5.0.1" 17 | }, 18 | "scripts": { 19 | "start": "react-scripts start", 20 | "build": "react-scripts build", 21 | "test": "react-scripts test", 22 | "eject": "react-scripts eject" 23 | }, 24 | "eslintConfig": { 25 | "extends": "react-app" 26 | }, 27 | "homepage": ".", 28 | "browserslist": [ 29 | ">0.2%", 30 | "not dead", 31 | "not ie <= 11", 32 | "not op_mini all" 33 | ] 34 | } -------------------------------------------------------------------------------- /.github/workflows/dependabot-auto-merge.yml: -------------------------------------------------------------------------------- 1 | # Automatically merge Dependabot PRs when version comparison is within the range 2 | # that is configured in .github/auto-merge.yml 3 | 4 | name: Auto-Merge Dependabot PRs 5 | 6 | on: 7 | # WARNING: This needs to be run in the PR base, DO NOT build untrusted code in this action 8 | # details under https://github.blog/changelog/2021-02-19-github-actions-workflows-triggered-by-dependabot-prs-will-run-with-read-only-permissions/ 9 | pull_request_target: 10 | 11 | jobs: 12 | auto-merge: 13 | if: github.actor == 'dependabot[bot]' 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout code 17 | uses: actions/checkout@v4 18 | 19 | - name: Check if PR should be auto-merged 20 | uses: ahmadnassri/action-dependabot-auto-merge@v2 21 | with: 22 | # This must be a personal access token with push access 23 | github-token: ${{ secrets.AUTO_MERGE_TOKEN }} 24 | # By default, squash and merge, so Github chooses nice commit messages 25 | command: squash and merge 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2024 Ingo Fischer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /admin/static/media/Sockets.8320e1a99be9de004629.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 8 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /admin/static/media/Handle.3de1d1320fc3ce2f9712.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /srcAdmin/src/i18n/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "Error": "Error", 3 | "Paired": "Paired", 4 | "Unpaired": "Unpaired", 5 | "Identified": "Identified", 6 | "Connected": "Connected", 7 | "Discovered": "Discovered", 8 | "Identify": "Identify", 9 | "Pair": "Pair", 10 | "Unpair": "Unpair", 11 | "Refresh devices list": "Refresh the device list", 12 | "ID": "ID", 13 | "Type": "Type", 14 | "Name": "Name", 15 | "Category": "Category", 16 | "Please enter PIN": "Please enter PIN", 17 | "PIN": "PIN", 18 | "Close": "Close", 19 | "Instance must be started to set up the devices": "Instance must be started to set up the devices", 20 | "Start?": "Start?", 21 | "Discover over IP": "Discover over IP", 22 | "Discover over Bluetooth": "Discover over Bluetooth", 23 | "Data polling interval for IP": "Data polling interval for IP", 24 | "Data polling interval for Bluetooth": "Data polling interval for Bluetooth", 25 | "Update only changed values": "Update only changed values", 26 | "Options": "Options", 27 | "Devices": "Devices", 28 | "seconds": "seconds", 29 | "Are you sure?": "Are you sure?", 30 | "Please confirm": "Please confirm", 31 | "Cancel": "Cancel" 32 | } 33 | -------------------------------------------------------------------------------- /srcAdmin/src/i18n/uk.json: -------------------------------------------------------------------------------- 1 | { 2 | "Are you sure?": "Ти впевнений?", 3 | "Cancel": "Скасувати", 4 | "Category": "Категорія", 5 | "Close": "Закрити", 6 | "Connected": "Підключено", 7 | "Data polling interval for Bluetooth": "Інтервал опитування даних для Bluetooth", 8 | "Data polling interval for IP": "Інтервал опитування даних для IP", 9 | "Devices": "Пристрої", 10 | "Discover over Bluetooth": "Відкривайте через Bluetooth", 11 | "Discover over IP": "Відкривайте через IP", 12 | "Discovered": "Виявлено", 13 | "Error": "Помилка", 14 | "ID": "ID", 15 | "Identified": "Ідентифікований", 16 | "Identify": "Ідентифікувати", 17 | "Instance must be started to set up the devices": "Для налаштування пристроїв необхідно запустити екземпляр", 18 | "Name": "Ім'я", 19 | "Options": "Опції", 20 | "PIN": "PIN-код", 21 | "Pair": "Пара", 22 | "Paired": "Парні", 23 | "Please confirm": "Будь-ласка підтвердіть", 24 | "Please enter PIN": "Введіть PIN-код", 25 | "Refresh devices list": "Оновіть список пристроїв", 26 | "Start?": "почати?", 27 | "Type": "Тип", 28 | "Unpair": "Розірвати пару", 29 | "Unpaired": "Без пари", 30 | "Update only changed values": "Оновлювати лише змінені значення", 31 | "seconds": "секунд" 32 | } -------------------------------------------------------------------------------- /srcAdmin/src/i18n/it.json: -------------------------------------------------------------------------------- 1 | { 2 | "Error": "Errore", 3 | "Paired": "accoppiato", 4 | "Unpaired": "non abbinato", 5 | "Identified": "Identificato", 6 | "Connected": "Collegato", 7 | "Discovered": "Scoperto", 8 | "Identify": "Identificare", 9 | "Pair": "Coppia", 10 | "Unpair": "Disaccoppia", 11 | "Refresh devices list": "Aggiorna l'elenco dei dispositivi", 12 | "ID": "ID", 13 | "Type": "Tipo", 14 | "Name": "Nome", 15 | "Category": "Categoria", 16 | "Please enter PIN": "Si prega di inserire il PIN", 17 | "PIN": "SPILLO", 18 | "Close": "Chiudere", 19 | "Instance must be started to set up the devices": "L'istanza deve essere avviata per configurare i dispositivi", 20 | "Start?": "Cominciare?", 21 | "Discover over IP": "Scopri su IP", 22 | "Discover over Bluetooth": "Scopri tramite Bluetooth", 23 | "Data polling interval for IP": "Intervallo di polling dati per IP", 24 | "Data polling interval for Bluetooth": "Intervallo di polling dati per Bluetooth", 25 | "Update only changed values": "Aggiorna solo i valori modificati", 26 | "Options": "Opzioni", 27 | "Devices": "Dispositivi", 28 | "seconds": "secondi", 29 | "Are you sure?": "Sei sicuro?", 30 | "Please confirm": "Si prega di confermare", 31 | "Cancel": "Annulla" 32 | } -------------------------------------------------------------------------------- /srcAdmin/src/i18n/es.json: -------------------------------------------------------------------------------- 1 | { 2 | "Error": "Error", 3 | "Paired": "Emparejado", 4 | "Unpaired": "Desemparejado", 5 | "Identified": "Identificado", 6 | "Connected": "Conectado", 7 | "Discovered": "Descubierto", 8 | "Identify": "Identificar", 9 | "Pair": "Par", 10 | "Unpair": "Desemparejar", 11 | "Refresh devices list": "Actualizar la lista de dispositivos", 12 | "ID": "ID", 13 | "Type": "Escribe", 14 | "Name": "Nombre", 15 | "Category": "Categoría", 16 | "Please enter PIN": "Por favor ingrese su PIN", 17 | "PIN": "ALFILER", 18 | "Close": "Cerrar", 19 | "Instance must be started to set up the devices": "Se debe iniciar la instancia para configurar los dispositivos", 20 | "Start?": "¿Comienzo?", 21 | "Discover over IP": "Descubrir sobre IP", 22 | "Discover over Bluetooth": "Descubrir por Bluetooth", 23 | "Data polling interval for IP": "Intervalo de sondeo de datos para IP", 24 | "Data polling interval for Bluetooth": "Intervalo de sondeo de datos para Bluetooth", 25 | "Update only changed values": "Actualizar solo los valores modificados", 26 | "Options": "Opciones", 27 | "Devices": "Dispositivos", 28 | "seconds": "segundos", 29 | "Are you sure?": "¿Está seguro?", 30 | "Please confirm": "Por favor confirmar", 31 | "Cancel": "Cancelar" 32 | } -------------------------------------------------------------------------------- /admin/static/media/Hanging Lamps.0bd452fc843edd645c30.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /admin/static/media/Tv.4e9745a548e57bfac0c7.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /srcAdmin/src/i18n/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "Error": "Fehler", 3 | "Paired": "Gepaart", 4 | "Unpaired": "Nicht gekoppelt", 5 | "Identified": "Identifiziert", 6 | "Connected": "Verbunden", 7 | "Discovered": "Entdeckt", 8 | "Identify": "Identifizieren", 9 | "Pair": "Paaren", 10 | "Unpair": "Entkoppeln", 11 | "Refresh devices list": "Aktualisieren Sie die Geräteliste", 12 | "ID": "ID", 13 | "Type": "Typ", 14 | "Name": "Name", 15 | "Category": "Kategorie", 16 | "Please enter PIN": "Bitte PIN eingeben", 17 | "PIN": "PIN", 18 | "Close": "Schließen", 19 | "Instance must be started to set up the devices": "Instanz muss zum Einrichten der Geräte gestartet werden", 20 | "Start?": "Starten?", 21 | "Discover over IP": "Über IP entdecken", 22 | "Discover over Bluetooth": "Über Bluetooth entdecken", 23 | "Data polling interval for IP": "Datenabfrageintervall für IP", 24 | "Data polling interval for Bluetooth": "Datenabfrageintervall für Bluetooth", 25 | "Update only changed values": "Nur geänderte Werte aktualisieren", 26 | "Options": "Optionen", 27 | "Devices": "Geräte", 28 | "seconds": "Sekunden", 29 | "Are you sure?": "Wirklich sicher?", 30 | "Please confirm": "Bitte bestätigen", 31 | "Cancel": "Abbrechen" 32 | } 33 | -------------------------------------------------------------------------------- /srcAdmin/src/i18n/pl.json: -------------------------------------------------------------------------------- 1 | { 2 | "Error": "Błąd", 3 | "Paired": "Sparowane", 4 | "Unpaired": "Nieparzysty", 5 | "Identified": "Zidentyfikowane", 6 | "Connected": "Połączony", 7 | "Discovered": "Odkryty", 8 | "Identify": "Zidentyfikować", 9 | "Pair": "Para", 10 | "Unpair": "Usuń sparowanie", 11 | "Refresh devices list": "Odśwież listę urządzeń", 12 | "ID": "ID", 13 | "Type": "Typ", 14 | "Name": "Nazwa", 15 | "Category": "Kategoria", 16 | "Please enter PIN": "Wprowadź kod PIN", 17 | "PIN": "SZPILKA", 18 | "Close": "Zamknij", 19 | "Instance must be started to set up the devices": "Aby skonfigurować urządzenia, należy uruchomić instancję", 20 | "Start?": "Początek?", 21 | "Discover over IP": "Odkryj przez IP", 22 | "Discover over Bluetooth": "Odkryj przez Bluetooth", 23 | "Data polling interval for IP": "Interwał odpytywania danych dla IP", 24 | "Data polling interval for Bluetooth": "Interwał odpytywania danych dla Bluetooth", 25 | "Update only changed values": "Aktualizuj tylko zmienione wartości", 26 | "Options": "Opcje", 27 | "Devices": "Urządzenia", 28 | "seconds": "sekund", 29 | "Are you sure?": "Jesteś pewny?", 30 | "Please confirm": "Proszę potwierdzić", 31 | "Cancel": "Odwołaj" 32 | } 33 | -------------------------------------------------------------------------------- /srcAdmin/src/i18n/nl.json: -------------------------------------------------------------------------------- 1 | { 2 | "Error": "Fout", 3 | "Paired": "Gekoppeld", 4 | "Unpaired": "ongepaarde", 5 | "Identified": "geïdentificeerd", 6 | "Connected": "Verbonden", 7 | "Discovered": "ontdekt", 8 | "Identify": "Identificeren", 9 | "Pair": "Paar", 10 | "Unpair": "Ontkoppelen", 11 | "Refresh devices list": "Vernieuw de apparatenlijst", 12 | "ID": "ID", 13 | "Type": "Type", 14 | "Name": "Naam", 15 | "Category": "Categorie", 16 | "Please enter PIN": "Voer pincode in", 17 | "PIN": "PIN", 18 | "Close": "Dichtbij", 19 | "Instance must be started to set up the devices": "Instantie moet worden gestart om de apparaten in te stellen", 20 | "Start?": "Begin?", 21 | "Discover over IP": "Ontdek via IP", 22 | "Discover over Bluetooth": "Ontdek via Bluetooth", 23 | "Data polling interval for IP": "Interval voor gegevenspolling voor IP", 24 | "Data polling interval for Bluetooth": "Interval voor gegevenspolling voor Bluetooth", 25 | "Update only changed values": "Alleen gewijzigde waarden bijwerken", 26 | "Options": "Opties", 27 | "Devices": "Apparaten", 28 | "seconds": "seconden", 29 | "Are you sure?": "Weet je zeker dat?", 30 | "Please confirm": "Bevestig alstublieft", 31 | "Cancel": "Annuleren" 32 | } 33 | -------------------------------------------------------------------------------- /admin/static/media/Water Consumption.68891649591cc2434c5b.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /srcAdmin/src/i18n/ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "Error": "Ошибка", 3 | "Paired": "Связанный", 4 | "Unpaired": "Неспаренный", 5 | "Identified": "Выявлено", 6 | "Connected": "Связан", 7 | "Discovered": "Обнаруженный", 8 | "Identify": "Идентифицировать", 9 | "Pair": "Привязать", 10 | "Unpair": "Разорвать связь", 11 | "Refresh devices list": "Обновите список устройств", 12 | "ID": "ID", 13 | "Type": "Тип", 14 | "Name": "Имя", 15 | "Category": "Категория", 16 | "Please enter PIN": "Пожалуйста, введите PIN-код", 17 | "PIN": "PIN", 18 | "Close": "Закрыть", 19 | "Instance must be started to set up the devices": "Экземпляр должен быть запущен для настройки устройств", 20 | "Start?": "Начинать?", 21 | "Discover over IP": "Искать устройства через IP", 22 | "Discover over Bluetooth": "Искать устройства через Bluetooth", 23 | "Data polling interval for IP": "Интервал опроса данных по IP", 24 | "Data polling interval for Bluetooth": "Интервал опроса данных по Bluetooth", 25 | "Update only changed values": "Обновлять только измененные значения", 26 | "Options": "Параметры", 27 | "Devices": "Устройства", 28 | "seconds": "секунды", 29 | "Are you sure?": "Вы уверены?", 30 | "Please confirm": "Пожалуйста подтвердите", 31 | "Cancel": "Отмена" 32 | } 33 | -------------------------------------------------------------------------------- /srcAdmin/src/i18n/pt.json: -------------------------------------------------------------------------------- 1 | { 2 | "Error": "Erro", 3 | "Paired": "Emparelhados", 4 | "Unpaired": "Não emparelhado", 5 | "Identified": "Identificado", 6 | "Connected": "Conectado", 7 | "Discovered": "Descoberto", 8 | "Identify": "Identificar", 9 | "Pair": "Par", 10 | "Unpair": "Desemparelhar", 11 | "Refresh devices list": "Atualize a lista de dispositivos", 12 | "ID": "ID", 13 | "Type": "Tipo", 14 | "Name": "Nome", 15 | "Category": "Categoria", 16 | "Please enter PIN": "Por favor insira o PIN", 17 | "PIN": "ALFINETE", 18 | "Close": "Fechar", 19 | "Instance must be started to set up the devices": "A instância deve ser iniciada para configurar os dispositivos", 20 | "Start?": "Começar?", 21 | "Discover over IP": "Descubra por IP", 22 | "Discover over Bluetooth": "Descubra por Bluetooth", 23 | "Data polling interval for IP": "Intervalo de sondagem de dados para IP", 24 | "Data polling interval for Bluetooth": "Intervalo de sondagem de dados para Bluetooth", 25 | "Update only changed values": "Atualizar apenas os valores alterados", 26 | "Options": "Opções", 27 | "Devices": "Dispositivos", 28 | "seconds": "segundos", 29 | "Are you sure?": "Tem certeza?", 30 | "Please confirm": "Por favor confirme", 31 | "Cancel": "Cancelar" 32 | } 33 | -------------------------------------------------------------------------------- /srcAdmin/src/i18n/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Error": "Erreur", 3 | "Paired": "Jumelé", 4 | "Unpaired": "Non apparié", 5 | "Identified": "Identifié", 6 | "Connected": "Connecté", 7 | "Discovered": "Découvert", 8 | "Identify": "Identifier", 9 | "Pair": "Paire", 10 | "Unpair": "Dissocier", 11 | "Refresh devices list": "Actualiser la liste des appareils", 12 | "ID": "ID", 13 | "Type": "Taper", 14 | "Name": "Nom", 15 | "Category": "Catégorie", 16 | "Please enter PIN": "Veuillez saisir le code PIN", 17 | "PIN": "ÉPINGLER", 18 | "Close": "proche", 19 | "Instance must be started to set up the devices": "L'instance doit être démarrée pour configurer les appareils", 20 | "Start?": "Début?", 21 | "Discover over IP": "Découvrir sur IP", 22 | "Discover over Bluetooth": "Découvrir via Bluetooth", 23 | "Data polling interval for IP": "Intervalle d'interrogation des données pour IP", 24 | "Data polling interval for Bluetooth": "Intervalle d'interrogation des données pour Bluetooth", 25 | "Update only changed values": "Mettre à jour uniquement les valeurs modifiées", 26 | "Options": "Options", 27 | "Devices": "Dispositifs", 28 | "seconds": "secondes", 29 | "Are you sure?": "Es-tu sûr?", 30 | "Please confirm": "Veuillez confirmer", 31 | "Cancel": "Annuler" 32 | } 33 | -------------------------------------------------------------------------------- /admin/static/media/Stairwell.0914feea948153a8637a.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /admin/static/media/Basement.fe636968eec9556bfd1f.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /admin/static/media/Shed.491a2ad372036118002c.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.create-adapter.json: -------------------------------------------------------------------------------- 1 | { 2 | "expert": "yes", 3 | "cli": false, 4 | "adapterName": "homekit-controller", 5 | "title": "HomeKit Controller", 6 | "description": "Pair and control HomeKit devices directly", 7 | "keywords": [ 8 | "homekit", 9 | "hap" 10 | ], 11 | "authorName": "Ingo Fischer", 12 | "authorGithub": "Apollon77", 13 | "authorEmail": "github@fischer-ka.de", 14 | "features": [ 15 | "adapter" 16 | ], 17 | "adminFeatures": [], 18 | "type": "iot-systems", 19 | "startMode": "daemon", 20 | "connectionType": "local", 21 | "dataSource": "poll", 22 | "connectionIndicator": "yes", 23 | "adapterSettings": [ 24 | { 25 | "key": "discoverIp", 26 | "label": "Discover IP Devices", 27 | "inputType": "checkbox", 28 | "defaultValue": true 29 | }, 30 | { 31 | "key": "discoverBle", 32 | "label": "Discover Bluetooth Devices", 33 | "inputType": "checkbox", 34 | "defaultValue": false 35 | } 36 | ], 37 | "language": "TypeScript", 38 | "adminReact": "yes", 39 | "indentation": "Space (4)", 40 | "quotes": "single", 41 | "es6class": "yes", 42 | "tools": [ 43 | "ESLint" 44 | ], 45 | "gitRemoteProtocol": "HTTPS", 46 | "license": "MIT License", 47 | "ci": "gh-actions", 48 | "dependabot": "yes", 49 | "creatorVersion": "1.33.0" 50 | } -------------------------------------------------------------------------------- /admin/static/media/Shading.0577383dc227cd043b3d.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /admin/static/media/Printer.146d983be964b95745d2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /admin/static/media/Carport.8337662544b9e95f4b27.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /admin/static/media/Water Heater.7e4bb4d99a5213f24d08.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /admin/static/media/Hall.9c2fa95419cb84ecda68.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 11 | 13 | 14 | 16 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /admin/static/media/Storeroom.7de4e6f3364554459b8a.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /admin/static/media/Power Consumption.4faab614c3c788f2d338.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /admin/static/media/Ceiling Spotlights.485822441b5df3b3384a.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | // Root tsconfig to set the settings and power editor support for all TS files 2 | { 3 | "compileOnSave": true, 4 | "compilerOptions": { 5 | // do not compile anything, this file is just to configure type checking 6 | // the compilation is configured in tsconfig.build.json 7 | "noEmit": true, 8 | 9 | // check JS files, but do not compile them => tsconfig.build.json 10 | "allowJs": true, 11 | "checkJs": true, 12 | 13 | "skipLibCheck": true, // Don't report errors in 3rd party definitions 14 | "noEmitOnError": true, 15 | "outDir": "./build/", 16 | "removeComments": false, 17 | "module": "commonjs", 18 | "moduleResolution": "node", 19 | "esModuleInterop": true, 20 | // this is necessary for the automatic typing of the adapter config 21 | "resolveJsonModule": true, 22 | 23 | // Set this to false if you want to disable the very strict rules (not recommended) 24 | "strict": true, 25 | // Or enable some of those features for more fine-grained control 26 | // "strictNullChecks": true, 27 | // "strictPropertyInitialization": true, 28 | // "strictBindCallApply": true, 29 | // "noImplicitAny": true, 30 | // "noUnusedLocals": true, 31 | // "noUnusedParameters": true, 32 | 33 | // Consider targetting es2019 or higher if you only support Node.js 12+ 34 | "target": "es2019", 35 | 36 | "sourceMap": true, 37 | "inlineSourceMap": false, 38 | "useUnknownInCatchVariables": false, 39 | }, 40 | "include": [ 41 | "src/**/*.ts", 42 | "admin/**/*.ts", 43 | "admin/**/*.tsx" 44 | ], 45 | "exclude": [ 46 | "build/**", 47 | "node_modules/**" 48 | ] 49 | } 50 | -------------------------------------------------------------------------------- /admin/static/media/Lock.2cbfe17ea8923e0f4e9e.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 12 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /srcAdmin/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import { ThemeProvider, StyledEngineProvider } from '@mui/material/styles'; 4 | import { StylesProvider, createGenerateClassName } from '@mui/styles'; 5 | import './index.css'; 6 | import App from './App'; 7 | import * as serviceWorker from './serviceWorker'; 8 | import pack from '../package.json'; 9 | import theme from '@iobroker/adapter-react-v5/Theme'; 10 | import Utils from '@iobroker/adapter-react-v5/Components/Utils'; 11 | 12 | window.adapterName = 'homekit-controller'; 13 | // window.sentryDSN = 'https://5ad729dbed504d15aa8bde423cae9a8e@sentry.iobroker.net/57'; 14 | 15 | let themeName = Utils.getThemeName(); 16 | 17 | console.log(`iobroker.${window.adapterName}@${pack.version} using theme "${themeName}"`); 18 | const generateClassName = createGenerateClassName({ 19 | productionPrefix: 'iob', 20 | }); 21 | 22 | function build() { 23 | const container = document.getElementById('root'); 24 | const root = createRoot(container); 25 | return root.render( 26 | 27 | 28 | { 30 | themeName = _theme; 31 | build(); 32 | }} 33 | /> 34 | 35 | 36 | 37 | ); 38 | } 39 | 40 | build(); 41 | 42 | // If you want your app to work offline and load faster, you can change 43 | // unregister() to register() below. Note this comes with some pitfalls. 44 | // Learn more about service workers: http://bit.ly/CRA-PWA 45 | serviceWorker.unregister(); 46 | -------------------------------------------------------------------------------- /admin/static/media/Swimming Pool.190b378cb0707edb9461.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 9 | 11 | 13 | 15 | 17 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /admin/static/media/Garage.f7fc0a9b326d582afee6.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 13 | 15 | 17 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /admin/static/media/Outdoors.da42e64a4b6ec2dd1e1c.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /admin/static/media/People.12a7e9127e72f3259186.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /admin/static/media/Laundry Room.58da550dff0173676e02.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /admin/static/media/Fan.8a29f85d6ca99c584603.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /admin/static/media/Awnings.78480df8796f09859b6a.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /admin/static/media/Washroom.bfb54196f381f36de9d6.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /admin/static/media/Computer.9558f6ee3941dba4e3c5.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | 18 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /admin/static/media/Coffee Makers.9fb4d82f957a06f30dae.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /admin/static/media/Attic.bb5d690a160bb1d4edb2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /admin/static/media/Table Lamps.bd92de33bf86b6cbaec9.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /admin/static/media/Nursery.9cecc0544bdb5c28500c.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /admin/static/media/Terrace.d71d07d9290674f2ca20.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /admin/static/media/Guest Bathroom.d07a9f1cf32a82d03267.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /admin/static/media/Receiver.26b5ae166395a6dcb83f.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /admin/static/media/Sleeping Area.828017602bfcc2dd7dce.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | 17 | 19 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /admin/static/media/Dryer.5ea89bd6dc20a00fb442.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /admin/static/media/Consumption.fecd7a10a13fe4e5f69b.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /admin/static/media/Hairdryer.5960b514dac1f04f3c4d.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 14 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /admin/static/media/Weather.e91dae647698d48365e3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /admin/static/media/Mowing Machine.9ead5b039f36cdc800e6.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /admin/static/media/Playroom.e64c9de43030c28d2f96.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /admin/static/media/Kitchen.deb7f976c1f43f9039a2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /admin/static/media/Wc.83604dd2daafb67067dd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /admin/static/media/Toilet.83604dd2daafb67067dd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /srcAdmin/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 15 | 16 | 28 | 29 | 38 | Homekit-Controller Settings 39 | 40 | 41 | 42 |
43 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, // Don't look outside this project for inherited configs 3 | parser: '@typescript-eslint/parser', // Specifies the ESLint parser 4 | parserOptions: { 5 | ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features 6 | sourceType: 'module', // Allows for the use of imports 7 | project: './tsconfig.json', 8 | ecmaFeatures: { 9 | jsx: true, 10 | }, 11 | }, 12 | extends: [ 13 | 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin 14 | ], 15 | rules: { 16 | 'indent': 'off', 17 | '@typescript-eslint/indent': [ 18 | 'error', 19 | 4, 20 | { 21 | 'SwitchCase': 1 22 | } 23 | ], 24 | 'quotes': [ 25 | 'error', 26 | 'single', 27 | { 28 | 'avoidEscape': true, 29 | 'allowTemplateLiterals': true 30 | } 31 | ], 32 | '@typescript-eslint/no-parameter-properties': 'off', 33 | '@typescript-eslint/no-explicit-any': 'off', 34 | '@typescript-eslint/no-use-before-define': [ 35 | 'error', 36 | { 37 | functions: false, 38 | typedefs: false, 39 | classes: false, 40 | }, 41 | ], 42 | '@typescript-eslint/no-unused-vars': [ 43 | 'error', 44 | { 45 | ignoreRestSiblings: true, 46 | argsIgnorePattern: '^_', 47 | }, 48 | ], 49 | '@typescript-eslint/explicit-function-return-type': [ 50 | 'warn', 51 | { 52 | allowExpressions: true, 53 | allowTypedFunctionExpressions: true, 54 | }, 55 | ], 56 | '@typescript-eslint/no-object-literal-type-assertion': 'off', 57 | '@typescript-eslint/interface-name-prefix': 'off', 58 | '@typescript-eslint/no-non-null-assertion': 'off', // This is necessary for Map.has()/get()! 59 | 'no-var': 'error', 60 | 'prefer-const': 'error', 61 | 'no-trailing-spaces': 'error', 62 | }, 63 | overrides: [ 64 | { 65 | files: ['*.test.ts', '*.tsx'], 66 | rules: { 67 | '@typescript-eslint/explicit-function-return-type': 'off', 68 | }, 69 | }, 70 | ], 71 | }; 72 | -------------------------------------------------------------------------------- /admin/static/media/Temperature Sensors.75d805988a6b77b231d8.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /admin/static/media/Hoods.c177ddfec9fa9a6335db.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /admin/static/media/Ventilation.c31761d86d67e245ac92.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /admin/static/media/Led Strip.5cf2de461e29ffbaa5f0.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /admin/static/media/Amplifier.6f5d18048328386033f8.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /admin/static/media/Office.7e6a38218390b655e270.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /admin/static/media/Boiler Room.548e785e2f92b45f72b3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /admin/static/media/Summer House.541a9fec69f01105e244.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /admin/static/media/SmokeDetector.8222f77cb07030a409ee.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /admin/static/media/Cold Water.937aad5fa21b0c20a856.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 21 | 24 | 27 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /admin/static/media/Hot Water.5c0a9e01741562e1fbab.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "iobroker.homekit-controller", 3 | "version": "0.5.11", 4 | "description": "Pair and control HomeKit devices directly", 5 | "author": { 6 | "name": "Ingo Fischer", 7 | "email": "github@fischer-ka.de" 8 | }, 9 | "homepage": "https://github.com/Apollon77/ioBroker.homekit-controller", 10 | "license": "MIT", 11 | "keywords": [ 12 | "homekit", 13 | "hap" 14 | ], 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/Apollon77/ioBroker.homekit-controller" 18 | }, 19 | "dependencies": { 20 | "@iobroker/adapter-core": "^3.2.2", 21 | "bignumber.js": "^9.1.2", 22 | "debug": "^4.3.7", 23 | "hap-controller": "^0.10.2", 24 | "@esm2cjs/p-queue": "^7.3.0" 25 | }, 26 | "devDependencies": { 27 | "@alcalzone/release-script": "^3.8.0", 28 | "@alcalzone/release-script-plugin-iobroker": "^3.7.2", 29 | "@alcalzone/release-script-plugin-license": "^3.7.0", 30 | "@babel/cli": "^7.25.9", 31 | "@babel/core": "^7.26.0", 32 | "@babel/plugin-proposal-decorators": "^7.25.9", 33 | "@babel/preset-env": "^7.26.0", 34 | "@babel/preset-typescript": "^7.26.0", 35 | "@iobroker/adapter-dev": "^1.3.0", 36 | "@iobroker/dev-server": "^0.7.8", 37 | "@iobroker/testing": "^5.0.0", 38 | "@types/chai": "^4.3.20", 39 | "@types/chai-as-promised": "^7.1.8", 40 | "@types/debug": "^4.1.12", 41 | "@types/gulp": "^4.0.17", 42 | "@types/mocha": "^10.0.9", 43 | "@types/node": "^22.8.5", 44 | "@types/proxyquire": "^1.3.31", 45 | "@types/sinon": "^17.0.3", 46 | "@types/sinon-chai": "^3.2.12", 47 | "@typescript-eslint/eslint-plugin": "^7.18.0", 48 | "@typescript-eslint/parser": "^7.18.0", 49 | "chai": "^4.5.0", 50 | "chai-as-promised": "^7.1.2", 51 | "eslint": "^8.57.1", 52 | "gulp": "^4.0.2", 53 | "mocha": "^10.8.2", 54 | "parcel-bundler": "^1.12.5", 55 | "proxyquire": "^2.1.3", 56 | "rimraf": "^5.0.10", 57 | "sinon": "^17.0.2", 58 | "sinon-chai": "^3.7.0", 59 | "source-map-support": "^0.5.21", 60 | "ts-node": "^10.9.2", 61 | "typescript": "^5.6.3" 62 | }, 63 | "main": "build/main.js", 64 | "scripts": { 65 | "prebuild": "rimraf ./build", 66 | "build:ts": "tsc -p tsconfig.build.json", 67 | "build": "npm run build:ts && npm run buildGui", 68 | "buildGui": "gulp", 69 | "watch:ts": "tsc -p tsconfig.build.json --watch", 70 | "watch": "npm run watch:ts", 71 | "test:ts": "mocha --config test/mocharc.custom.json src/**/*.test.ts", 72 | "test:package": "mocha test/package --exit", 73 | "test:unit": "mocha test/unit --exit", 74 | "test:integration": "mocha test/integration --exit", 75 | "test": "npm run test:ts && npm run test:package", 76 | "check": "tsc --noEmit", 77 | "lint": "eslint --ext .ts,.tsx src/", 78 | "release": "release-script", 79 | "translate": "translate-adapter" 80 | }, 81 | "bugs": { 82 | "url": "https://github.com/Apollon77/ioBroker.homekit-controller/issues" 83 | }, 84 | "readmeFilename": "README.md" 85 | } 86 | -------------------------------------------------------------------------------- /admin/static/media/Stairway.9b007e08605296110003.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /admin/static/media/Living Room.3c380ab767be35f904e1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /admin/static/media/Doorstep.10630b759b4867a10776.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 11 | 14 | 17 | 20 | 23 | 25 | 28 | 30 | 32 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /admin/static/media/Iron.b8a65a48503b6f3e0dc8.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /admin/static/media/Gates.5a8baf2c3d4832ca57e8.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 23 | 25 | 27 | 29 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /admin/static/media/Speaker.db548379676317470c4f.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 13 | 16 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 27 | 29 | 30 | 32 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /admin/static/media/Chamber.71daaa4d14262dae029b.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /admin/static/media/Guest Room.41c7cfa38806f5009f82.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /admin/static/media/Rear Wall.38843c33f1ea1f575500.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 25 | 27 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /admin/static/media/Battery Status.5951e2078ae1e573510e.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /admin/static/media/Barn.5d839e84c80918ce2ef0.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | # Number of days of inactivity before an Issue or Pull Request becomes stale 4 | daysUntilStale: 90 5 | 6 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed. 7 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. 8 | daysUntilClose: 7 9 | 10 | # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) 11 | onlyLabels: [] 12 | 13 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable 14 | exemptLabels: 15 | - enhancement 16 | - security 17 | 18 | # Set to true to ignore issues in a project (defaults to false) 19 | exemptProjects: true 20 | 21 | # Set to true to ignore issues in a milestone (defaults to false) 22 | exemptMilestones: true 23 | 24 | # Set to true to ignore issues with an assignee (defaults to false) 25 | exemptAssignees: false 26 | 27 | # Label to use when marking as stale 28 | staleLabel: wontfix 29 | 30 | # Comment to post when marking as stale. Set to `false` to disable 31 | markComment: > 32 | This issue has been automatically marked as stale because it has not had 33 | recent activity. It will be closed if no further activity occurs within the next 7 days. 34 | Please check if the issue is still relevant in the most current version of the adapter 35 | and tell us. Also check that all relevant details, logs and reproduction steps 36 | are included and update them if needed. 37 | Thank you for your contributions. 38 | 39 | Dieses Problem wurde automatisch als veraltet markiert, da es in letzter Zeit keine Aktivitäten gab. 40 | Es wird geschlossen, wenn nicht innerhalb der nächsten 7 Tage weitere Aktivitäten stattfinden. 41 | Bitte überprüft, ob das Problem auch in der aktuellsten Version des Adapters noch relevant ist, 42 | und teilt uns dies mit. Überprüft auch, ob alle relevanten Details, Logs und Reproduktionsschritte 43 | enthalten sind bzw. aktualisiert diese. 44 | Vielen Dank für Eure Unterstützung. 45 | 46 | # Comment to post when removing the stale label. 47 | # unmarkComment: > 48 | # Your comment here. 49 | 50 | # Comment to post when closing a stale Issue or Pull Request. 51 | closeComment: > 52 | This issue has been automatically closed because of inactivity. Please open a new 53 | issue if still relevant and make sure to include all relevant details, logs and 54 | reproduction steps. 55 | Thank you for your contributions. 56 | 57 | Dieses Problem wurde aufgrund von Inaktivität automatisch geschlossen. Bitte öffnet ein 58 | neues Issue, falls dies noch relevant ist und stellt sicher das alle relevanten Details, 59 | Logs und Reproduktionsschritte enthalten sind. 60 | Vielen Dank für Eure Unterstützung. 61 | 62 | # Limit the number of actions per hour, from 1-30. Default is 30 63 | limitPerRun: 30 64 | 65 | # Limit to only `issues` or `pulls` 66 | only: issues 67 | 68 | # Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': 69 | # pulls: 70 | # daysUntilStale: 30 71 | # markComment: > 72 | # This pull request has been automatically marked as stale because it has not had 73 | # recent activity. It will be closed if no further activity occurs. Thank you 74 | # for your contributions. 75 | 76 | # issues: 77 | # exemptLabels: 78 | # - confirmed -------------------------------------------------------------------------------- /admin/static/media/Workshop.7856e59fe4f164c90609.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/lib/tools.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | /** 4 | * Tests whether the given variable is a real object and not an Array 5 | * @param it The variable to test 6 | */ 7 | export function isObject(it: unknown): it is Record { 8 | // This is necessary because: 9 | // typeof null === 'object' 10 | // typeof [] === 'object' 11 | // [] instanceof Object === true 12 | return Object.prototype.toString.call(it) === '[object Object]'; 13 | } 14 | 15 | /** 16 | * Tests whether the given variable is really an Array 17 | * @param it The variable to test 18 | */ 19 | export function isArray(it: unknown): it is any[] { 20 | if (Array.isArray != null) return Array.isArray(it); 21 | return Object.prototype.toString.call(it) === '[object Array]'; 22 | } 23 | 24 | /** 25 | * Translates text using the Google Translate API 26 | * @param text The text to translate 27 | * @param targetLang The target languate 28 | * @param yandexApiKey The yandex API key. You can create one for free at https://translate.yandex.com/developers 29 | */ 30 | export async function translateText(text: string, targetLang: string, yandexApiKey?: string): Promise { 31 | if (targetLang === 'en') { 32 | return text; 33 | } else if (!text) { 34 | return ''; 35 | } 36 | if (yandexApiKey) { 37 | return translateYandex(text, targetLang, yandexApiKey); 38 | } else { 39 | return translateGoogle(text, targetLang); 40 | } 41 | } 42 | 43 | /** 44 | * Translates text with Yandex API 45 | * @param text The text to translate 46 | * @param targetLang The target languate 47 | * @param apiKey The yandex API key. You can create one for free at https://translate.yandex.com/developers 48 | */ 49 | async function translateYandex(text: string, targetLang: string, apiKey: string): Promise { 50 | if (targetLang === 'zh-cn') { 51 | targetLang = 'zh'; 52 | } 53 | try { 54 | const url = `https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${encodeURIComponent(text)}&lang=en-${targetLang}`; 55 | const response = await axios.request({url, timeout: 15000}); 56 | if (isArray(response.data?.text)) { 57 | return response.data.text[0]; 58 | } 59 | throw new Error('Invalid response for translate request'); 60 | } catch (e) { 61 | throw new Error(`Could not translate to "${targetLang}": ${e}`); 62 | } 63 | } 64 | 65 | /** 66 | * Translates text with Google API 67 | * @param text The text to translate 68 | * @param targetLang The target languate 69 | */ 70 | async function translateGoogle(text: string, targetLang: string): Promise { 71 | try { 72 | const url = `http://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=${targetLang}&dt=t&q=${encodeURIComponent(text)}&ie=UTF-8&oe=UTF-8`; 73 | const response = await axios.request({url, timeout: 15000}); 74 | if (isArray(response.data)) { 75 | // we got a valid response 76 | return response.data[0][0][0]; 77 | } 78 | throw new Error('Invalid response for translate request'); 79 | } catch (e) { 80 | if (e.response?.status === 429) { 81 | throw new Error( 82 | `Could not translate to "${targetLang}": Rate-limited by Google Translate` 83 | ); 84 | } else { 85 | throw new Error(`Could not translate to "${targetLang}": ${e}`); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /admin/static/media/Security.1ec78971bd34efa950f8.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 20 | 22 | 25 | 31 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /admin/static/media/Chandelier.8b9fbdbc73bc2e955ef7.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /admin/static/media/Workspace.97d73e419d966bfb6428.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | --------------------------------------------------------------------------------