mirror of
https://github.com/koush/scrypted.git
synced 2026-02-12 18:12:04 +00:00
lifx/owntracks: migrate
This commit is contained in:
4
plugins/lifx/.gitignore
vendored
4
plugins/lifx/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
.DS_Store
|
||||
out/
|
||||
node_modules/
|
||||
dist/
|
||||
@@ -1,4 +0,0 @@
|
||||
.DS_Store
|
||||
out/
|
||||
node_modules/
|
||||
dist/*.map
|
||||
22
plugins/lifx/.vscode/launch.json
vendored
22
plugins/lifx/.vscode/launch.json
vendored
@@ -1,22 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Scrypted Debugger",
|
||||
"address": "${config:scrypted.debugHost}",
|
||||
"port": 10081,
|
||||
"request": "attach",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"preLaunchTask": "scrypted: deploy+debug",
|
||||
"sourceMaps": true,
|
||||
"localRoot": "${workspaceFolder}/out",
|
||||
"remoteRoot": "/plugin/",
|
||||
"type": "pwa-node"
|
||||
}
|
||||
]
|
||||
}
|
||||
4
plugins/lifx/.vscode/settings.json
vendored
4
plugins/lifx/.vscode/settings.json
vendored
@@ -1,4 +0,0 @@
|
||||
|
||||
{
|
||||
"scrypted.debugHost": "127.0.0.1",
|
||||
}
|
||||
20
plugins/lifx/.vscode/tasks.json
vendored
20
plugins/lifx/.vscode/tasks.json
vendored
@@ -1,20 +0,0 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "scrypted: deploy+debug",
|
||||
"type": "shell",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "silent",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"command": "npm run scrypted-vscode-launch ${config:scrypted.debugHost}",
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
# A Lifx plugin
|
||||
|
||||
## npm commands
|
||||
* npm run scrypted-webpack
|
||||
* npm run scrypted-deploy <ipaddress>
|
||||
* npm run scrypted-debug <ipaddress>
|
||||
|
||||
## scrypted distribution via npm
|
||||
1. Ensure package.json is set up properly for publishing on npm.
|
||||
2. npm publish
|
||||
|
||||
## Visual Studio Code configuration
|
||||
|
||||
* If using a remote server, edit [.vscode/settings.json](blob/master/.vscode/settings.json) to specify the IP Address of the Scrypted server.
|
||||
* Launch Scrypted Debugger from the launch menu.
|
||||
324
plugins/lifx/package-lock.json
generated
324
plugins/lifx/package-lock.json
generated
@@ -1,324 +0,0 @@
|
||||
{
|
||||
"name": "@scrypted/lifx",
|
||||
"version": "0.2.23",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/lifx",
|
||||
"version": "0.2.23",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache",
|
||||
"dependencies": {
|
||||
"axios": "^0.18.0",
|
||||
"node-lifx": "github:koush/node-lifx",
|
||||
"terser": "^3.14.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/node": "^16.7.1"
|
||||
}
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.0.199",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/preset-typescript": "^7.16.7",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^0.21.4",
|
||||
"babel-loader": "^8.2.3",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.13.8",
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"tmp": "^0.2.1",
|
||||
"webpack": "^5.59.0"
|
||||
},
|
||||
"bin": {
|
||||
"scrypted-debug": "bin/scrypted-debug.js",
|
||||
"scrypted-deploy": "bin/scrypted-deploy.js",
|
||||
"scrypted-deploy-debug": "bin/scrypted-deploy-debug.js",
|
||||
"scrypted-package-json": "bin/scrypted-package-json.js",
|
||||
"scrypted-readme": "bin/scrypted-readme.js",
|
||||
"scrypted-setup-project": "bin/scrypted-setup-project.js",
|
||||
"scrypted-webpack": "bin/scrypted-webpack.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.1",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.22.8",
|
||||
"typescript-json-schema": "^0.50.1",
|
||||
"webpack-bundle-analyzer": "^4.5.0"
|
||||
}
|
||||
},
|
||||
"../sdk": {
|
||||
"extraneous": true
|
||||
},
|
||||
"node_modules/@scrypted/sdk": {
|
||||
"resolved": "../../sdk",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "16.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.1.tgz",
|
||||
"integrity": "sha512-ncRdc45SoYJ2H4eWU9ReDfp3vtFqDYhjOsKlFFUDEn8V1Bgr2RjYal8YT5byfadWIRluhPFU6JiDOl0H6Sl87A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "0.18.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz",
|
||||
"integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==",
|
||||
"deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410",
|
||||
"dependencies": {
|
||||
"follow-redirects": "1.5.10",
|
||||
"is-buffer": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "2.17.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
|
||||
"integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eventemitter3": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
|
||||
"integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo="
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||
"dependencies": {
|
||||
"debug": "=3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-buffer": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
|
||||
"integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"node_modules/node-lifx": {
|
||||
"resolved": "git+ssh://git@github.com/koush/node-lifx.git#ad85de6742168e867d4e54b8571dd3e8220ed9f2",
|
||||
"dependencies": {
|
||||
"eventemitter3": "^2.0.2",
|
||||
"lodash": "^4.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-support": {
|
||||
"version": "0.5.10",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz",
|
||||
"integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==",
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-support/node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/terser": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-3.14.1.tgz",
|
||||
"integrity": "sha512-NSo3E99QDbYSMeJaEk9YW2lTg3qS9V0aKGlb+PlOrei1X02r1wSBHCNX/O+yeTRFSWPKPIGj6MqvvdqV4rnVGw==",
|
||||
"dependencies": {
|
||||
"commander": "~2.17.1",
|
||||
"source-map": "~0.6.1",
|
||||
"source-map-support": "~0.5.6"
|
||||
},
|
||||
"bin": {
|
||||
"terser": "bin/uglifyjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/terser/node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@scrypted/sdk": {
|
||||
"version": "file:../../sdk",
|
||||
"requires": {
|
||||
"@babel/preset-typescript": "^7.16.7",
|
||||
"@types/node": "^16.11.1",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^0.21.4",
|
||||
"babel-loader": "^8.2.3",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.13.8",
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"stringify-object": "^3.3.0",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.22.8",
|
||||
"typescript-json-schema": "^0.50.1",
|
||||
"webpack": "^5.59.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "16.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.1.tgz",
|
||||
"integrity": "sha512-ncRdc45SoYJ2H4eWU9ReDfp3vtFqDYhjOsKlFFUDEn8V1Bgr2RjYal8YT5byfadWIRluhPFU6JiDOl0H6Sl87A==",
|
||||
"dev": true
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.18.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz",
|
||||
"integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==",
|
||||
"requires": {
|
||||
"follow-redirects": "1.5.10",
|
||||
"is-buffer": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.17.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
|
||||
"integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"eventemitter3": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
|
||||
"integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo="
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||
"requires": {
|
||||
"debug": "=3.1.0"
|
||||
}
|
||||
},
|
||||
"is-buffer": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
|
||||
"integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ=="
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"node-lifx": {
|
||||
"version": "git+ssh://git@github.com/koush/node-lifx.git#ad85de6742168e867d4e54b8571dd3e8220ed9f2",
|
||||
"from": "node-lifx@github:koush/node-lifx",
|
||||
"requires": {
|
||||
"eventemitter3": "^2.0.2",
|
||||
"lodash": "^4.5.0"
|
||||
}
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.10",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz",
|
||||
"integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==",
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"terser": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-3.14.1.tgz",
|
||||
"integrity": "sha512-NSo3E99QDbYSMeJaEk9YW2lTg3qS9V0aKGlb+PlOrei1X02r1wSBHCNX/O+yeTRFSWPKPIGj6MqvvdqV4rnVGw==",
|
||||
"requires": {
|
||||
"commander": "~2.17.1",
|
||||
"source-map": "~0.6.1",
|
||||
"source-map-support": "~0.5.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
{
|
||||
"name": "@scrypted/lifx",
|
||||
"version": "0.2.23",
|
||||
"description": "A Lifx plugin for Scrypted",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache",
|
||||
"scripts": {
|
||||
"scrypted-setup-project": "scrypted-setup-project",
|
||||
"prescrypted-setup-project": "scrypted-package-json",
|
||||
"build": "scrypted-webpack",
|
||||
"prepublishOnly": "NODE_ENV=production scrypted-webpack",
|
||||
"prescrypted-vscode-launch": "scrypted-webpack",
|
||||
"scrypted-vscode-launch": "scrypted-deploy-debug",
|
||||
"scrypted-deploy-debug": "scrypted-deploy-debug",
|
||||
"scrypted-debug": "scrypted-debug",
|
||||
"scrypted-deploy": "scrypted-deploy",
|
||||
"scrypted-readme": "scrypted-readme",
|
||||
"scrypted-package-json": "scrypted-package-json"
|
||||
},
|
||||
"keywords": [
|
||||
"lifx",
|
||||
"scrypted",
|
||||
"plugin"
|
||||
],
|
||||
"scrypted": {
|
||||
"name": "LIFX Controller",
|
||||
"type": "DeviceProvider",
|
||||
"interfaces": [
|
||||
"DeviceProvider"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/node": "^16.7.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.18.0",
|
||||
"node-lifx": "github:koush/node-lifx",
|
||||
"terser": "^3.14.1"
|
||||
}
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
import {Client as LifxClient} from 'node-lifx';
|
||||
var client = new LifxClient();
|
||||
import sdk, { Device, ScryptedDeviceBase, OnOff, Brightness, ColorSettingHsv, ColorSettingTemperature, Refresh, ScryptedDeviceType, DeviceProvider } from '@scrypted/sdk';
|
||||
const { deviceManager, log } = sdk;
|
||||
|
||||
|
||||
const StateSetters = {
|
||||
OnOff: function (s, state) {
|
||||
state.on = !!(s && s.power);
|
||||
},
|
||||
Brightness: function (s, state) {
|
||||
state.brightness = (s && s.color && s.color.brightness) || 0;
|
||||
},
|
||||
ColorSettingTemperature: function (s, state) {
|
||||
state.colorTemperature = (s && s.color && s.color.kelvin) || 0;
|
||||
},
|
||||
ColorSettingHsv: function (st, state) {
|
||||
var h = (st && st.color && st.color.hue) || 0;
|
||||
var s = ((st && st.color && st.color.saturation) || 0) / 100;
|
||||
var v = ((st && st.color && st.color.brightness) || 0) / 100;
|
||||
state.hsv = { h, s, v };
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class LifxDevice extends ScryptedDeviceBase implements OnOff, Brightness, ColorSettingHsv, ColorSettingTemperature, Refresh {
|
||||
light: any;
|
||||
device: Device;
|
||||
refresher: Function;
|
||||
|
||||
constructor(light: any, device: Device) {
|
||||
super(device.nativeId);
|
||||
this.light = light;
|
||||
this.device = device;
|
||||
|
||||
this.refresher = (err) => this.refresh();
|
||||
|
||||
// schedule a refresh. not doing it immediately, to allow the device to be reported
|
||||
// by sync first.
|
||||
setImmediate(() => this.refresh());
|
||||
}
|
||||
|
||||
|
||||
async refresh() {
|
||||
this._refresh();
|
||||
}
|
||||
|
||||
async getRefreshFrequency() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
async _refresh(cb?) {
|
||||
this.light.getState((err, state) => {
|
||||
if (state) {
|
||||
for (var iface of this.device.interfaces) {
|
||||
var setter = StateSetters[iface];
|
||||
if (setter) {
|
||||
setter(state, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cb) {
|
||||
cb(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// setters
|
||||
|
||||
async turnOn() {
|
||||
this.light.on(0, this.refresher);
|
||||
}
|
||||
|
||||
async turnOff() {
|
||||
this.light.off(0, this.refresher);
|
||||
}
|
||||
|
||||
async setBrightness(level: number) {
|
||||
this.light.getState((err, state) => {
|
||||
var color = state.color;
|
||||
this.light.color(color.hue, color.saturation, level, color.kelvin, undefined, this.refresher);
|
||||
})
|
||||
}
|
||||
|
||||
async setColorTemperature(kelvin: number) {
|
||||
this.light.color(0, 0, 100, kelvin, undefined, this.refresher);
|
||||
}
|
||||
|
||||
async setHsv(h: number, s: number, v: number) {
|
||||
this.light.color(h, Math.round(s * 100), Math.round(v * 100), undefined, undefined, this.refresher);
|
||||
}
|
||||
|
||||
async getTemperatureMinK() {
|
||||
return 2500;
|
||||
}
|
||||
|
||||
async getTemperatureMaxK() {
|
||||
return 9000;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class LifxController implements DeviceProvider {
|
||||
lights: any = {};
|
||||
|
||||
constructor() {
|
||||
this.discoverDevices(30);
|
||||
}
|
||||
|
||||
getDevice(id) {
|
||||
return this.lights[id];
|
||||
}
|
||||
|
||||
newLight(light) {
|
||||
light.getHardwareVersion((err, data) => {
|
||||
if (err) {
|
||||
log.e(`unable to get product version: ${err}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// these are the interfaces (capabilities) provided by this bulb
|
||||
var interfaces = ['OnOff', 'Brightness'];
|
||||
if (data.productFeatures && data.productFeatures.color) {
|
||||
interfaces.push('ColorSettingHsv');
|
||||
interfaces.push('ColorSettingTemperature');
|
||||
}
|
||||
// lifx bulbs require polling to get their state. it is not
|
||||
// actively pushed to the controller. implementing the Refresh interface allows
|
||||
// Scrypted to poll the device intelligently: such as when the UI is visible,
|
||||
// or HomeKit/Google requests a sync and needs updated state.
|
||||
interfaces.push('Refresh');
|
||||
|
||||
var info = {
|
||||
name: data.productName,
|
||||
nativeId: light.id,
|
||||
interfaces: interfaces,
|
||||
type: ScryptedDeviceType.Light,
|
||||
};
|
||||
log.i(`light found: ${JSON.stringify(info)}`);
|
||||
|
||||
deviceManager.onDeviceDiscovered(info);
|
||||
this.lights[light.id] = new LifxDevice(light, info);
|
||||
});
|
||||
}
|
||||
|
||||
async discoverDevices(duration: number) {
|
||||
client.on('light-new', this.newLight.bind(this));
|
||||
client.init();
|
||||
setTimeout(() => {
|
||||
client.stopDiscovery();
|
||||
}, duration * 1000);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export default new LifxController();
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "ES2021",
|
||||
"resolveJsonModule": true,
|
||||
"moduleResolution": "Node16",
|
||||
"esModuleInterop": true,
|
||||
"sourceMap": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
||||
4
plugins/owntracks/.gitignore
vendored
4
plugins/owntracks/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
.DS_Store
|
||||
out/
|
||||
node_modules/
|
||||
dist/
|
||||
@@ -1,4 +0,0 @@
|
||||
.DS_Store
|
||||
out/
|
||||
node_modules/
|
||||
dist/*.map
|
||||
22
plugins/owntracks/.vscode/launch.json
vendored
22
plugins/owntracks/.vscode/launch.json
vendored
@@ -1,22 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Scrypted Debugger",
|
||||
"address": "${config:scrypted.debugHost}",
|
||||
"port": 10081,
|
||||
"request": "attach",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"preLaunchTask": "scrypted: deploy+debug",
|
||||
"sourceMaps": true,
|
||||
"localRoot": "${workspaceFolder}/out",
|
||||
"remoteRoot": "/plugin/",
|
||||
"type": "pwa-node"
|
||||
}
|
||||
]
|
||||
}
|
||||
4
plugins/owntracks/.vscode/settings.json
vendored
4
plugins/owntracks/.vscode/settings.json
vendored
@@ -1,4 +0,0 @@
|
||||
|
||||
{
|
||||
"scrypted.debugHost": "127.0.0.1",
|
||||
}
|
||||
20
plugins/owntracks/.vscode/tasks.json
vendored
20
plugins/owntracks/.vscode/tasks.json
vendored
@@ -1,20 +0,0 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "scrypted: deploy+debug",
|
||||
"type": "shell",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "silent",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"command": "npm run scrypted-vscode-launch ${config:scrypted.debugHost}",
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
# Owntracks Plugin
|
||||
|
||||
## npm commands
|
||||
* npm run scrypted-webpack
|
||||
* npm run scrypted-deploy <ipaddress>
|
||||
* npm run scrypted-debug <ipaddress>
|
||||
|
||||
## scrypted distribution via npm
|
||||
1. Ensure package.json is set up properly for publishing on npm.
|
||||
2. npm publish
|
||||
|
||||
## Visual Studio Code configuration
|
||||
|
||||
* If using a remote server, edit [.vscode/settings.json](blob/master/.vscode/settings.json) to specify the IP Address of the Scrypted server.
|
||||
* Launch Scrypted Debugger from the launch menu.
|
||||
118
plugins/owntracks/package-lock.json
generated
118
plugins/owntracks/package-lock.json
generated
@@ -1,118 +0,0 @@
|
||||
{
|
||||
"name": "@scrypted/owntracks",
|
||||
"version": "0.0.24",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/owntracks",
|
||||
"version": "0.0.24",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache",
|
||||
"dependencies": {
|
||||
"basic-auth": "^2.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
}
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.0.199",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/preset-typescript": "^7.16.7",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^0.21.4",
|
||||
"babel-loader": "^8.2.3",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.13.8",
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"tmp": "^0.2.1",
|
||||
"webpack": "^5.59.0"
|
||||
},
|
||||
"bin": {
|
||||
"scrypted-debug": "bin/scrypted-debug.js",
|
||||
"scrypted-deploy": "bin/scrypted-deploy.js",
|
||||
"scrypted-deploy-debug": "bin/scrypted-deploy-debug.js",
|
||||
"scrypted-package-json": "bin/scrypted-package-json.js",
|
||||
"scrypted-readme": "bin/scrypted-readme.js",
|
||||
"scrypted-setup-project": "bin/scrypted-setup-project.js",
|
||||
"scrypted-webpack": "bin/scrypted-webpack.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.1",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.22.8",
|
||||
"typescript-json-schema": "^0.50.1",
|
||||
"webpack-bundle-analyzer": "^4.5.0"
|
||||
}
|
||||
},
|
||||
"../sdk": {
|
||||
"extraneous": true
|
||||
},
|
||||
"node_modules/@scrypted/sdk": {
|
||||
"resolved": "../../sdk",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/basic-auth": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
|
||||
"integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
|
||||
"dependencies": {
|
||||
"safe-buffer": "5.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@scrypted/sdk": {
|
||||
"version": "file:../../sdk",
|
||||
"requires": {
|
||||
"@babel/preset-typescript": "^7.16.7",
|
||||
"@types/node": "^16.11.1",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^0.21.4",
|
||||
"babel-loader": "^8.2.3",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.13.8",
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"stringify-object": "^3.3.0",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.22.8",
|
||||
"typescript-json-schema": "^0.50.1",
|
||||
"webpack": "^5.59.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0"
|
||||
}
|
||||
},
|
||||
"basic-auth": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
|
||||
"integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.2"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"name": "@scrypted/owntracks",
|
||||
"version": "0.0.24",
|
||||
"description": "Owntracks Plugin for Scrypted",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache",
|
||||
"scripts": {
|
||||
"scrypted-setup-project": "scrypted-setup-project",
|
||||
"prescrypted-setup-project": "scrypted-package-json",
|
||||
"build": "scrypted-webpack",
|
||||
"prepublishOnly": "NODE_ENV=production scrypted-webpack",
|
||||
"prescrypted-vscode-launch": "scrypted-webpack",
|
||||
"scrypted-vscode-launch": "scrypted-deploy-debug",
|
||||
"scrypted-deploy-debug": "scrypted-deploy-debug",
|
||||
"scrypted-debug": "scrypted-debug",
|
||||
"scrypted-deploy": "scrypted-deploy",
|
||||
"scrypted-readme": "scrypted-readme",
|
||||
"scrypted-package-json": "scrypted-package-json"
|
||||
},
|
||||
"keywords": [
|
||||
"scrypted",
|
||||
"plugin"
|
||||
],
|
||||
"scrypted": {
|
||||
"name": "Owntracks Plugin",
|
||||
"type": "DeviceProvider",
|
||||
"interfaces": [
|
||||
"PushHandler",
|
||||
"Settings",
|
||||
"DeviceProvider",
|
||||
"PasswordStore"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
},
|
||||
"dependencies": {
|
||||
"basic-auth": "^2.0.1"
|
||||
}
|
||||
}
|
||||
@@ -1,193 +0,0 @@
|
||||
// https://developer.scrypted.app/#getting-started
|
||||
import sdk, { Settings, DeviceProvider, ScryptedDeviceType, OccupancySensor, Setting, HttpRequest, PasswordStore, PushHandler, PositionSensor, ScryptedInterface } from "@scrypted/sdk";
|
||||
import { ScryptedDeviceBase } from "@scrypted/sdk";
|
||||
const { log, deviceManager, endpointManager } = sdk;
|
||||
import auth from 'basic-auth';
|
||||
|
||||
class OwntracksUser extends ScryptedDeviceBase implements PositionSensor {
|
||||
constructor(nativeId: string) {
|
||||
super(nativeId);
|
||||
}
|
||||
}
|
||||
|
||||
class OwntracksRegion extends ScryptedDeviceBase implements OccupancySensor, Settings {
|
||||
getSetting(key: string): string | number | boolean {
|
||||
return null;
|
||||
}
|
||||
// create settings that correspond to allowed usernames in this region
|
||||
async getSettings(): Promise<Setting[]> {
|
||||
const ret: Setting[] = [];
|
||||
for (let i = 0; i < this.storage.length; i++) {
|
||||
const key = this.storage.key(i);
|
||||
ret.push({
|
||||
key,
|
||||
value: key,
|
||||
title: 'Owntracks Username',
|
||||
description: 'This sensor will be marked as occupied if this user is in this Owntracks region.',
|
||||
})
|
||||
}
|
||||
ret.push({
|
||||
title: 'Add User',
|
||||
placeholder: 'username',
|
||||
description: 'Owntracks Username',
|
||||
key: 'new-user',
|
||||
})
|
||||
return ret;
|
||||
}
|
||||
// create/rename users
|
||||
async putSetting(key: string, value: string | number | boolean) {
|
||||
if (key == 'new-user') {
|
||||
this.storage.setItem(value as string, false.toString());
|
||||
return;
|
||||
}
|
||||
this.storage.removeItem(key);
|
||||
if ((value as string).length) {
|
||||
this.storage.setItem(value as string, false.toString());
|
||||
}
|
||||
this.sendOccupancyEvent();
|
||||
}
|
||||
// look at the user status for every user, and send the correct event.
|
||||
// todo: timestamp? purge old users?
|
||||
sendOccupancyEvent() {
|
||||
for (let i = 0; i < this.storage.length; i++) {
|
||||
const key = this.storage.key(i);
|
||||
if (this.storage.getItem(key) === 'true') {
|
||||
this.occupied = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.occupied = false;
|
||||
}
|
||||
constructor(nativeId: string) {
|
||||
super(nativeId);
|
||||
}
|
||||
}
|
||||
|
||||
class Owntracks extends ScryptedDeviceBase implements PushHandler, Settings, DeviceProvider, PasswordStore {
|
||||
constructor() {
|
||||
super();
|
||||
if (!localStorage.getItem('private_http')) {
|
||||
endpointManager.getPublicPushEndpoint().then(endpoint => {
|
||||
localStorage.setItem('private_http', endpoint);
|
||||
log.a('The Owntracks Private HTTP endpoint is available in Settings.');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// owntracks will call the endpoint with a password, so set up a simple password store
|
||||
// that can be accessed via the scrypted web ui. this allows revocation of passwords,
|
||||
// and denial of unauthorized users that may have the owntracks private http endpoint.
|
||||
async getPasswords(): Promise<string[]> {
|
||||
try {
|
||||
return JSON.parse(localStorage.getItem('passwords')) || [];
|
||||
}
|
||||
catch (e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
get passwords(): string[] {
|
||||
try {
|
||||
return JSON.parse(localStorage.getItem('passwords')) || [];
|
||||
}
|
||||
catch (e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
savePasswords(passwords: string[]) {
|
||||
const uniques = {};
|
||||
passwords.map(password => uniques[password] = true);
|
||||
passwords = Object.keys(uniques);
|
||||
localStorage.setItem('passwords', JSON.stringify(passwords));
|
||||
}
|
||||
async addPassword(password: string) {
|
||||
const passwords = this.passwords;
|
||||
passwords.push(password)
|
||||
this.savePasswords(passwords);
|
||||
}
|
||||
async removePassword(password: string) {
|
||||
const passwords = this.passwords;
|
||||
passwords.filter(entry => entry != password);
|
||||
this.savePasswords(passwords);
|
||||
}
|
||||
async checkPassword(password: string): Promise<boolean> {
|
||||
return this.passwords.includes(password);
|
||||
}
|
||||
|
||||
async discoverDevices(duration: number) {
|
||||
}
|
||||
getDevice(nativeId: string) {
|
||||
return new OwntracksRegion(nativeId);
|
||||
}
|
||||
getSetting(key: string): string | number | boolean {
|
||||
return null;
|
||||
}
|
||||
async getSettings(): Promise<Setting[]> {
|
||||
// create a settings menu that shows the private http endpoint, and allows creation of new regions.
|
||||
return [
|
||||
{
|
||||
key: 'private_http',
|
||||
title: 'Private HTTP',
|
||||
description: 'The Private HTTP endpoint that is configured within the Owntracks mobile application. Owntracks users will need to authenticate with one of the passcodes set up by this Plugin.',
|
||||
readonly: true,
|
||||
value: localStorage.getItem('private_http') || 'Error creating Private HTTP. Try reloading the plugin',
|
||||
},
|
||||
{
|
||||
key: 'region',
|
||||
description: 'The name of the Region within Owntracks. Multiple users may specifiy the same Region. The OccupancySensor will be marked as occupied when any of them are within that Region.',
|
||||
title: 'Add Owntracks Region',
|
||||
},
|
||||
];
|
||||
}
|
||||
async putSetting(key: string, value: string | number | boolean) {
|
||||
// creat the named region from the setting.
|
||||
deviceManager.onDeviceDiscovered({
|
||||
name: value.toString(),
|
||||
interfaces: ['OccupancySensor', 'Settings'],
|
||||
nativeId: value.toString(),
|
||||
type: ScryptedDeviceType.Sensor,
|
||||
});
|
||||
}
|
||||
getEndpoint(): string {
|
||||
return "@scrypted/owntracks";
|
||||
}
|
||||
async onPush(request: HttpRequest) {
|
||||
const user = auth.parse(request.headers['authorization']);
|
||||
if (!this.passwords.includes(user.pass)) {
|
||||
return;
|
||||
}
|
||||
const body = JSON.parse(request.body);
|
||||
this.console.log(body);
|
||||
|
||||
const userNativeId = `user-${user.name}`;
|
||||
if (!deviceManager.getNativeIds().includes(userNativeId)) {
|
||||
deviceManager.onDeviceDiscovered({
|
||||
name: `Owntracks User - ${user.name}`,
|
||||
nativeId: userNativeId,
|
||||
type: ScryptedDeviceType.Sensor,
|
||||
interfaces: [ScryptedInterface.PositionSensor],
|
||||
})
|
||||
}
|
||||
const owntracksUser = new OwntracksUser(userNativeId);
|
||||
owntracksUser.position = {
|
||||
latitude: body.lat,
|
||||
longitude: body.lon,
|
||||
accuracyRadius: body.acc,
|
||||
}
|
||||
|
||||
// find all regions this user belongs to, and update them.
|
||||
for (const nativeId of deviceManager.getNativeIds()) {
|
||||
if (!nativeId || nativeId.startsWith('user-'))
|
||||
continue;
|
||||
let region = new OwntracksRegion(nativeId);
|
||||
let value = region.storage.getItem(user.name);
|
||||
if (value !== null) {
|
||||
region.storage.setItem(user.name, body.inregions && body.inregions.includes(nativeId) ? 'true': 'false');
|
||||
region.sendOccupancyEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new Owntracks();
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "ES2021",
|
||||
"resolveJsonModule": true,
|
||||
"moduleResolution": "Node16",
|
||||
"esModuleInterop": true,
|
||||
"sourceMap": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user