diff --git a/package-lock.json b/package-lock.json index f8e5ad5..c9bd165 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,20 +1,20 @@ { "name": "scrypted-dyson", - "version": "0.2.0", + "version": "0.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "scrypted-dyson", - "version": "0.2.0", + "version": "0.4.0", "license": "MIT", "dependencies": { - "@types/node": "^16.11.7", "crypto-js": "^4.1.1" }, "devDependencies": { "@scrypted/mqtt": "^0.0.56", - "@scrypted/sdk": "^0.1.18", + "@scrypted/sdk": "^0.2.70", + "@types/node": "^18.4.2", "webpack-bundle-analyzer": "^4.5.0" } }, @@ -596,31 +596,39 @@ "websocket-stream": "^5.5.2" } }, + "node_modules/@scrypted/mqtt/node_modules/@types/node": { + "version": "16.18.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.14.tgz", + "integrity": "sha512-wvzClDGQXOCVNU4APPopC2KtMYukaF1MN/W3xAmslx22Z4/IF1/izDMekuyoUlwfnDHYCIZGaj7jMwnJKBTxKw==", + "dev": true + }, "node_modules/@scrypted/sdk": { - "version": "0.1.21", - "resolved": "https://registry.npmjs.org/@scrypted/sdk/-/sdk-0.1.21.tgz", - "integrity": "sha512-6o6LvhOCOIpxopbxRFSvBfiFd5/fqT3By/4KCQ7iIWziYZIqMVllNjHUy2nAs4+rB6uT0m70vUZp3zFZktBaCg==", + "version": "0.2.80", + "resolved": "https://registry.npmjs.org/@scrypted/sdk/-/sdk-0.2.80.tgz", + "integrity": "sha512-Ngj1SqRFSVgZog9EudpDiCnWzepeDCnBvg2NYbwQRECe5USYqqM3imZWUp/5FPvLe3VmmHhxnNB866dh9w1QUg==", "dev": true, "dependencies": { - "@babel/preset-typescript": "^7.16.7", + "@babel/preset-typescript": "^7.18.6", "adm-zip": "^0.4.13", "axios": "^0.21.4", - "babel-loader": "^8.2.3", + "babel-loader": "^9.1.0", "babel-plugin-const-enum": "^1.1.0", "esbuild": "^0.15.9", "ncp": "^2.0.0", "raw-loader": "^4.0.2", "rimraf": "^3.0.2", "tmp": "^0.2.1", - "webpack": "^5.74.0", + "ts-loader": "^9.4.2", + "typescript": "^4.9.4", + "webpack": "^5.75.0", "webpack-bundle-analyzer": "^4.5.0" }, "bin": { + "scrypted-changelog": "bin/scrypted-changelog.js", "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" } @@ -667,9 +675,10 @@ "dev": true }, "node_modules/@types/node": { - "version": "16.18.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.4.tgz", - "integrity": "sha512-9qGjJ5GyShZjUfx2ArBIGM+xExdfLvvaCyQR0t6yRXKPcWCVYF/WemtX/uIU3r7FYECXRXkIiw2Vnhn6y8d+pw==" + "version": "18.14.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.6.tgz", + "integrity": "sha512-93+VvleD3mXwlLI/xASjw0FzKcwzl3OdTCzm1LaRfqgS21gfFtK3zDXM5Op9TeeMsJVOaJ2VRDpT9q4Y3d0AvA==", + "dev": true }, "node_modules/@webassemblyjs/ast": { "version": "1.11.1", @@ -952,6 +961,45 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -995,22 +1043,20 @@ } }, "node_modules/babel-loader": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", - "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz", + "integrity": "sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA==", "dev": true, "dependencies": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" + "find-cache-dir": "^3.3.2", + "schema-utils": "^4.0.0" }, "engines": { - "node": ">= 8.9" + "node": ">= 14.15.0" }, "peerDependencies": { - "@babel/core": "^7.0.0", - "webpack": ">=2" + "@babel/core": "^7.12.0", + "webpack": ">=5" } }, "node_modules/babel-plugin-const-enum": { @@ -1083,6 +1129,18 @@ "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/browserslist": { "version": "4.21.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", @@ -1814,6 +1872,18 @@ "integrity": "sha512-XBU9RXeoYc2/VnvMhplAxEmZLfIk7cvTBu+xwoBuTI8pL19E03cmca17QQycKIdxgwCeFA/a4u27gv1h3ya5LQ==", "dev": true }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", @@ -2041,6 +2111,15 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -2216,6 +2295,19 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -2475,6 +2567,18 @@ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -2588,6 +2692,15 @@ "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==", "dev": true }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/retimer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/retimer/-/retimer-3.0.0.tgz", @@ -2646,23 +2759,58 @@ ] }, "node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" }, "engines": { - "node": ">= 8.9.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" } }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -2856,6 +3004,18 @@ "node": ">=4" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/totalist": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", @@ -2865,12 +3025,129 @@ "node": ">=6" } }, + "node_modules/ts-loader": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz", + "integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ts-loader/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ts-loader/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ts-loader/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/ts-loader/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-loader/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-loader/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", diff --git a/package.json b/package.json index 63f1162..9290f54 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "scrypted-dyson", - "version": "0.3.0", + "version": "0.4.0", "description": "Scrypted plugin for Dyson", "author": "nberardi", "license": "MIT", @@ -43,12 +43,12 @@ ] }, "dependencies": { - "@types/node": "^16.11.7", "crypto-js": "^4.1.1" }, "devDependencies": { "@scrypted/mqtt": "^0.0.56", - "@scrypted/sdk": "^0.1.18", + "@types/node": "^18.4.2", + "@scrypted/sdk": "^0.2.70", "webpack-bundle-analyzer": "^4.5.0" } } diff --git a/src/DysonBase.ts b/src/DysonBase.ts index d0255de..e11672c 100644 --- a/src/DysonBase.ts +++ b/src/DysonBase.ts @@ -33,10 +33,10 @@ export class DysonBase extends ScryptedDeviceBase implements Online, Settings, R }, productType: { title: "Product Type", + group: 'Credentials', type: "string", description: "The numberical product type provided by Dyson.", - readonly: true, - hide: true + readonly: true }, temperatureUnit: { title: 'Temperature Unit', diff --git a/src/DysonFanWithHeater.ts b/src/DysonFanWithHeater.ts index fbc2892..90d97ed 100644 --- a/src/DysonFanWithHeater.ts +++ b/src/DysonFanWithHeater.ts @@ -1,4 +1,4 @@ -import { TemperatureSetting, TemperatureUnit, ThermostatMode } from '@scrypted/sdk'; +import { TemperatureCommand, TemperatureSetting, TemperatureSettingStatus, TemperatureUnit, ThermostatMode } from '@scrypted/sdk'; import { DysonFanWithAdvancedAirQuality } from './DysonFanWithAdvancedAirQuality'; export class DysonFanWithHeater extends DysonFanWithAdvancedAirQuality implements TemperatureSetting { @@ -6,7 +6,30 @@ export class DysonFanWithHeater extends DysonFanWithAdvancedAirQuality implement super(nativeId); this.thermostatAvailableModes = [ThermostatMode.Heat, ThermostatMode.On, ThermostatMode.Auto, ThermostatMode.Off]; + + this.temperatureSetting = { + availableModes: [ThermostatMode.Heat, ThermostatMode.On, ThermostatMode.Auto, ThermostatMode.Off] + } as TemperatureSettingStatus; } + + async setTemperature(command: TemperatureCommand): Promise { + let settings = this.temperatureSetting; + + if (command.mode) { + settings.mode = command.mode; + await this.setThermostatMode(command.mode); + } + + if (command.setpoint) { + settings.setpoint = command.setpoint; + + const setpoint = typeof command.setpoint === "number" ? command.setpoint : command.setpoint[0]; + await this.setThermostatSetpoint(setpoint); + } + + this.temperatureSetting = settings; + } + async setThermostatMode(mode: ThermostatMode): Promise { let commandData = { hmod: mode === ThermostatMode.On || mode == ThermostatMode.Heat || mode == ThermostatMode.Auto ? 'HEAT' : 'OFF' @@ -15,6 +38,7 @@ export class DysonFanWithHeater extends DysonFanWithAdvancedAirQuality implement this.console.log(`setThermostatMode(${mode}): ${JSON.stringify(commandData)}`); this.setState(commandData); } + async setThermostatSetpoint(degrees: number): Promise { this.thermostatSetpoint = degrees; @@ -45,33 +69,49 @@ export class DysonFanWithHeater extends DysonFanWithAdvancedAirQuality implement processCurrentState(content: any) { super.processCurrentState(content); + let settings = this.temperatureSetting; // Sets the heating mode and target temperature if (content['product-state']['hmod']) { let mode = (!super.on || content['product-state']['hmod'] === 'OFF') ? ThermostatMode.Off : ThermostatMode.Heat; this.thermostatActiveMode = mode; this.thermostatMode = mode; + + settings.activeMode = mode; + settings.mode = mode; } if (content['product-state']['hmax']) { let targetTemp = super.convertKelvin(Number.parseInt(content['product-state']['hmax']) / 10.0, TemperatureUnit.C); this.thermostatSetpoint = targetTemp; + + settings.setpoint = targetTemp; } + + this.temperatureSetting = settings; } processStateChange(content: any): void { super.processStateChange(content); + let settings = this.temperatureSetting; // Sets the heating mode and target temperature if (content['product-state']['hmod']) { let mode = (!super.on || content['product-state']['hmod'][1] === 'OFF') ? ThermostatMode.Off : ThermostatMode.Heat; this.thermostatActiveMode = mode; this.thermostatMode = mode; + + settings.activeMode = mode; + settings.mode = mode; } if (content['product-state']['hmax']) { let targetTemp = super.convertKelvin(Number.parseInt(content['product-state']['hmax'][1]) / 10.0, TemperatureUnit.C); this.thermostatSetpoint = targetTemp; + + settings.setpoint = targetTemp; } + + this.temperatureSetting = settings; } } diff --git a/src/DysonPlugin.ts b/src/DysonPlugin.ts index be71d86..9f7e383 100644 --- a/src/DysonPlugin.ts +++ b/src/DysonPlugin.ts @@ -1,4 +1,4 @@ -import sdk, { DeviceCreator, DeviceCreatorSettings } from '@scrypted/sdk' +import sdk, { AdoptDevice, DeviceCreator, DeviceCreatorSettings, DiscoveredDevice } from '@scrypted/sdk' import axios, { AxiosError, AxiosResponse } from 'axios'; import { Device, DeviceDiscovery, DeviceProvider, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, Setting, Settings, SettingValue } from '@scrypted/sdk'; import { StorageSettings } from "@scrypted/sdk/storage-settings" @@ -50,6 +50,14 @@ export class DysonPlugin extends ScryptedDeviceBase implements DeviceDiscovery, this.discoverDevices(); } + async releaseDevice(id: string, nativeId: string): Promise { + this.fans.delete(nativeId); + } + + async adoptDevice(device: AdoptDevice): Promise { + throw new Error('Method not implemented.'); + } + async getCreateDeviceSettings(): Promise { return [ { @@ -219,7 +227,7 @@ export class DysonPlugin extends ScryptedDeviceBase implements DeviceDiscovery, return undefined; } - async discoverDevices(duration?: number): Promise { + async discoverDevices(scan?: boolean): Promise { if (!this.storageSettings.values.countryCode || !this.storageSettings.values.email || !this.storageSettings.values.password) { this.log.a('Enter your Country Code, Email and Password to discover your Dyson Fans.'); @@ -240,7 +248,7 @@ export class DysonPlugin extends ScryptedDeviceBase implements DeviceDiscovery, if (this.storageSettings.values.authorizationHeader) { const client = axios.create(); - let fans: AxiosResponse; + let fans: any; let self = this; await client("https://appapi.cp.dyson.com/v2/provisioningservice/manifest", { @@ -336,6 +344,22 @@ export class DysonPlugin extends ScryptedDeviceBase implements DeviceDiscovery, s.setItem("productType", d.info.metadata.productType); s.setItem("localPassword", d.info.metadata.localPasswordHash); } + + return devices.map(d => { + return { + name: d.name, + description: d.nativeId, + nativeId: d.nativeId, + type: d.type, + interfaces: d.interfaces, + info: d.info, + settings: [ + { key: "serialNumber", value: d.info.serialNumber }, + { key: "productType", value: d.info.metadata.productType }, + { key: "localPassword", value: d.info.metadata.localPasswordHash } + ] + } as DiscoveredDevice; + }); } } @@ -347,7 +371,7 @@ export class DysonPlugin extends ScryptedDeviceBase implements DeviceDiscovery, const client = axios.create(); const self = this; - const catchError = function (error: AxiosError) { + const catchError = function (error: any) { let msg = `[Status ${error.response.status} ${error.response.statusText}] ${error.response.data?.Message}`; self.console.error(msg); self.log.e(msg); @@ -369,7 +393,7 @@ export class DysonPlugin extends ScryptedDeviceBase implements DeviceDiscovery, data: { email: this.storageSettings.values.email } - }); + }) as any; if (step1Response.status === 200) { self.console.log("login step 1", step1Response.data); @@ -394,7 +418,7 @@ export class DysonPlugin extends ScryptedDeviceBase implements DeviceDiscovery, data: { email: this.storageSettings.values.email } - }); + }) as any; if (step2Response.status === 200) { self.console.log("login step 2", step2Response.data); @@ -428,7 +452,7 @@ export class DysonPlugin extends ScryptedDeviceBase implements DeviceDiscovery, challengeId: this.challengeId, otpCode: this.storageSettings.values.otpCode } - }); + }) as any; if (step3mfaResponse.status === 200) { self.console.log("login step 3 (2FA)", step3mfaResponse.data);