diff --git a/README.md b/README.md index c8dfa20..0889546 100644 --- a/README.md +++ b/README.md @@ -1,150 +1,22 @@

- - - +Home Bridge logotype

+# Homebridge Platform Aqua Temp Plugin +This is a plugin for Aqua Temp pool heater. -# Homebridge Platform Plugin Template - -This is a template Homebridge platform plugin and can be used as a base to help you get started developing your own plugin. - -This template should be used in conjunction with the [developer documentation](https://developers.homebridge.io/). A full list of all supported service types, and their characteristics is available on this site. - -## Clone As Template - -Click the link below to create a new GitHub Repository using this template, or click the *Use This Template* button above. - - - -### [Create New Repository From Template](https://github.com/homebridge/homebridge-plugin-template/generate) - - - -## Setup Development Environment - -To develop Homebridge plugins you must have Node.js 12 or later installed, and a modern code editor such as [VS Code](https://code.visualstudio.com/). This plugin template uses [TypeScript](https://www.typescriptlang.org/) to make development easier and comes with pre-configured settings for [VS Code](https://code.visualstudio.com/) and ESLint. If you are using VS Code install these extensions: - -* [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) - -## Install Development Dependencies - -Using a terminal, navigate to the project folder and run this command to install the development dependencies: - -``` -npm install -``` - -## Update package.json - -Open the [`package.json`](./package.json) and change the following attributes: - -* `name` - this should be prefixed with `homebridge-` or `@username/homebridge-` and contain no spaces or special characters apart from a dashes -* `displayName` - this is the "nice" name displayed in the Homebridge UI -* `repository.url` - Link to your GitHub repo -* `bugs.url` - Link to your GitHub repo issues page - -When you are ready to publish the plugin you should set `private` to false, or remove the attribute entirely. - -## Update Plugin Defaults - -Open the [`src/settings.ts`](./src/settings.ts) file and change the default values: - -* `PLATFORM_NAME` - Set this to be the name of your platform. This is the name of the platform that users will use to register the plugin in the Homebridge `config.json`. -* `PLUGIN_NAME` - Set this to be the same name you set in the [`package.json`](./package.json) file. - -Open the [`config.schema.json`](./config.schema.json) file and change the following attribute: - -* `pluginAlias` - set this to match the `PLATFORM_NAME` you defined in the previous step. - -## Build Plugin - -TypeScript needs to be compiled into JavaScript before it can run. The following command will compile the contents of your [`src`](./src) directory and put the resulting code into the `dist` folder. - -``` -npm run build -``` - -## Link To Homebridge - -Run this command so your global install of Homebridge can discover the plugin in your development environment: - -``` -npm link -``` +# Support for +1.0.0 Temperature -You can now start Homebridge, use the `-D` flag so you can see debug log messages in your plugin: +# Default config +```json +"platforms": [ + { + "name": "Nexa Bridge X", + "Token": "[TOKEN] (get this by debuging iOS trafic)", + "UpdateTime": 60, + } +] ``` -homebridge -D -``` - -## Watch For Changes and Build Automatically - -If you want to have your code compile automatically as you make changes, and restart Homebridge automatically between changes you can run: - -``` -npm run watch -``` - -This will launch an instance of Homebridge in debug mode which will restart every time you make a change to the source code. It will load the config stored in the default location under `~/.homebridge`. You may need to stop other running instances of Homebridge while using this command to prevent conflicts. You can adjust the Homebridge startup command in the [`nodemon.json`](./nodemon.json) file. - -## Customise Plugin - -You can now start customising the plugin template to suit your requirements. - -* [`src/platform.ts`](./src/platform.ts) - this is where your device setup and discovery should go. -* [`src/platformAccessory.ts`](./src/platformAccessory.ts) - this is where your accessory control logic should go, you can rename or create multiple instances of this file for each accessory type you need to implement as part of your platform plugin. You can refer to the [developer documentation](https://developers.homebridge.io/) to see what characteristics you need to implement for each service type. -* [`config.schema.json`](./config.schema.json) - update the config schema to match the config you expect from the user. See the [Plugin Config Schema Documentation](https://developers.homebridge.io/#/config-schema). - -## Versioning Your Plugin - -Given a version number `MAJOR`.`MINOR`.`PATCH`, such as `1.4.3`, increment the: - -1. **MAJOR** version when you make breaking changes to your plugin, -2. **MINOR** version when you add functionality in a backwards compatible manner, and -3. **PATCH** version when you make backwards compatible bug fixes. - -You can use the `npm version` command to help you with this: - -```bash -# major update / breaking changes -npm version major - -# minor update / new features -npm version update - -# patch / bugfixes -npm version patch -``` - -## Publish Package - -When you are ready to publish your plugin to [npm](https://www.npmjs.com/), make sure you have removed the `private` attribute from the [`package.json`](./package.json) file then run: - -``` -npm publish -``` - -If you are publishing a scoped plugin, i.e. `@username/homebridge-xxx` you will need to add `--access=public` to command the first time you publish. - -#### Publishing Beta Versions - -You can publish *beta* versions of your plugin for other users to test before you release it to everyone. - -```bash -# create a new pre-release version (eg. 2.1.0-beta.1) -npm version prepatch --preid beta - -# publsh to @beta -npm publish --tag=beta -``` - -Users can then install the *beta* version by appending `@beta` to the install command, for example: - -``` -sudo npm install -g homebridge-example-plugin@beta -``` - - diff --git a/config.schema.json b/config.schema.json index 21bd99a..e8e1316 100644 --- a/config.schema.json +++ b/config.schema.json @@ -1,5 +1,5 @@ { - "pluginAlias": "ExampleHomebridgePlugin", + "pluginAlias": "AquaTemp", "pluginType": "platform", "singular": true, "schema": { @@ -9,8 +9,20 @@ "title": "Name", "type": "string", "required": true, - "default": "Example Dynamic Platform" - } + "default": "Aqua Temp" + }, + "Token": { + "title": "Token (get this by debuging iOS trafic)", + "type": "string", + "required": true, + "default": "" + }, + "UpdateTime": { + "title": "Time in secondes between updates", + "type": "number", + "required": true, + "default": 60 + } } } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8364029..73e23b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "homebridge-plugin-name", + "name": "homebridge-aqua-temp", "version": "1.0.0", "lockfileVersion": 1, "requires": true, @@ -246,7 +246,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -367,12 +366,30 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, "at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", @@ -388,12 +405,37 @@ "array-filter": "^1.0.0" } }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + } + } + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -559,6 +601,11 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -662,6 +709,14 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, "commander": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", @@ -688,6 +743,11 @@ "xdg-basedir": "^4.0.0" } }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -711,6 +771,14 @@ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "dev": true }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -779,6 +847,11 @@ "object-keys": "^1.0.12" } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -828,6 +901,15 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -1072,11 +1154,20 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-glob": { "version": "3.2.5", @@ -1095,8 +1186,7 @@ "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "fast-levenshtein": { "version": "2.0.6", @@ -1159,6 +1249,21 @@ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", "dev": true }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, "fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -1222,6 +1327,14 @@ "pump": "^3.0.0" } }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -1336,6 +1449,20 @@ } } }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -1390,6 +1517,16 @@ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", "dev": true }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, "ignore": { "version": "5.1.8", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", @@ -1626,8 +1763,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-weakmap": { "version": "2.0.1", @@ -1659,6 +1795,11 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -1675,17 +1816,26 @@ "esprima": "^4.0.0" } }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", "dev": true }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -1693,6 +1843,11 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -1703,6 +1858,17 @@ "universalify": "^2.0.0" } }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, "keyv": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", @@ -1791,6 +1957,19 @@ "picomatch": "^2.0.5" } }, + "mime-db": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" + }, + "mime-types": { + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "requires": { + "mime-db": "1.47.0" + } + }, "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", @@ -1915,6 +2094,11 @@ "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", "dev": true }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, "object-inspect": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", @@ -2025,6 +2209,11 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", @@ -2049,6 +2238,11 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, "pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", @@ -2068,8 +2262,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "pupa": { "version": "2.1.1", @@ -2092,6 +2285,11 @@ "integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==", "dev": true }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, "queue-microtask": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.2.tgz", @@ -2161,6 +2359,33 @@ "rc": "^1.2.8" } }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -2209,8 +2434,12 @@ "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "semver": { "version": "7.3.4", @@ -2335,6 +2564,29 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + } + } + }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -2464,6 +2716,15 @@ "nopt": "~1.0.10" } }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, "ts-node": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", @@ -2493,6 +2754,14 @@ "tslib": "^1.8.1" } }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "tweetnacl": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", @@ -2658,7 +2927,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "requires": { "punycode": "^2.1.0" } @@ -2672,12 +2940,27 @@ "prepend-http": "^2.0.0" } }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, "v8-compile-cache": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", "dev": true }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 30751dd..e35f48e 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,16 @@ { - "private": true, - "displayName": "Plugin Name", - "name": "homebridge-plugin-name", + "private": false, + "displayName": "Aqua Temp Plugin", + "name": "homebridge-aqua-temp", "version": "1.0.0", - "description": "A short description about what your plugin does.", + "description": "This is a plugin for Aqua Temp pool heater.", "license": "Apache-2.0", "repository": { "type": "git", - "url": "git://github.com/USERNAME/GITHUB_PROJECT_NAME.git" + "url": "git://https://github.com/hjuhlin/homebridge-aqua-temp.git" }, "bugs": { - "url": "https://github.com/USERNAME/GITHUB_PROJECT_NAME/issues" + "url": "https://github.com/hjuhlin/homebridge-aqua-temp/issues" }, "engines": { "node": ">=10.17.0", @@ -26,7 +26,9 @@ "keywords": [ "homebridge-plugin" ], - "dependencies": {}, + "dependencies": { + "request": "^2.88.0" + }, "devDependencies": { "@types/node": "^14.14.31", "@typescript-eslint/eslint-plugin": "^4.16.1", diff --git a/src/accessories/ThermometerAccessory.ts b/src/accessories/ThermometerAccessory.ts new file mode 100644 index 0000000..1a80a6e --- /dev/null +++ b/src/accessories/ThermometerAccessory.ts @@ -0,0 +1,43 @@ +import { Service, PlatformAccessory, Logger, PlatformConfig } from 'homebridge'; + +import { AquaTempHomebridgePlatform } from '../platform'; +import { AquaTempObject } from '../types/AquaTempObject'; +import { ObjectResult } from '../types/ObjectResult'; +import { HttpRequest } from '../utils/httprequest'; + +export class ThermometerAccessory { + private service: Service; + + constructor( + private readonly platform: AquaTempHomebridgePlatform, + private readonly accessory: PlatformAccessory, + private readonly jsonItem: ObjectResult, + public readonly config: PlatformConfig, + public readonly log: Logger, + ) { + this.accessory.getService(this.platform.Service.AccessoryInformation)! + .setCharacteristic(this.platform.Characteristic.Manufacturer, 'AquaTemp') + .setCharacteristic(this.platform.Characteristic.Model, 'AquaTempThermometerSensor') + .setCharacteristic(this.platform.Characteristic.SerialNumber, accessory.context.device.device_id); + + this.service = this.accessory.getService(this.platform.Service.TemperatureSensor) || + this.accessory.addService(this.platform.Service.TemperatureSensor); + + this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device.device_nick_name); + + const httpRequest = new HttpRequest(this.config, log); + + httpRequest.GetDeviceStatus(accessory.context.device.device_code).then((deviceResults)=> { + + const deviceResult = deviceResults; + + for (const codeData of deviceResult.object_result) { + if (codeData.code ==='T02') { + this.service.getCharacteristic(this.platform.Characteristic.CurrentTemperature).setProps({minValue: -100, maxValue: 100}); + this.service.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, codeData.value); + + } + } + }); + } +} diff --git a/src/index.ts b/src/index.ts index 7ec4c7a..6ac16eb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,11 @@ import { API } from 'homebridge'; import { PLATFORM_NAME } from './settings'; -import { ExampleHomebridgePlatform } from './platform'; +import { AquaTempHomebridgePlatform } from './platform'; /** * This method registers the platform with Homebridge */ export = (api: API) => { - api.registerPlatform(PLATFORM_NAME, ExampleHomebridgePlatform); + api.registerPlatform(PLATFORM_NAME, AquaTempHomebridgePlatform); }; diff --git a/src/platform.ts b/src/platform.ts index 536024f..e4b307d 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -1,116 +1,131 @@ import { API, DynamicPlatformPlugin, Logger, PlatformAccessory, PlatformConfig, Service, Characteristic } from 'homebridge'; - import { PLATFORM_NAME, PLUGIN_NAME } from './settings'; -import { ExamplePlatformAccessory } from './platformAccessory'; - -/** - * HomebridgePlatform - * This class is the main constructor for your plugin, this is where you should - * parse the user config and discover/register accessories with Homebridge. - */ -export class ExampleHomebridgePlatform implements DynamicPlatformPlugin { +import { HttpRequest } from './utils/httprequest'; + +import { AquaTempObject } from './types/AquaTempObject'; +import { ObjectResult } from './types/ObjectResult'; + +import { ThermometerAccessory } from './accessories/ThermometerAccessory'; + +export class AquaTempHomebridgePlatform implements DynamicPlatformPlugin { public readonly Service: typeof Service = this.api.hap.Service; public readonly Characteristic: typeof Characteristic = this.api.hap.Characteristic; - // this is used to track restored cached accessories public readonly accessories: PlatformAccessory[] = []; constructor( public readonly log: Logger, public readonly config: PlatformConfig, public readonly api: API, - ) { - this.log.debug('Finished initializing platform:', this.config.name); - // When this event is fired it means Homebridge has restored all cached accessories from disk. - // Dynamic Platform plugins should only register new accessories after this event was fired, - // in order to ensure they weren't added to homebridge already. This event can also be used - // to start discovery of new accessories. + ) { this.api.on('didFinishLaunching', () => { log.debug('Executed didFinishLaunching callback'); - // run the method to discover / register your devices as accessories + this.discoverDevices(); }); + + + this.log.debug('Finished initializing platform:', this.config.name); + + setInterval(() => { + const httpRequest = new HttpRequest(this.config, log); + + httpRequest.GetDeviceList().then((results)=> { + const aquaTempObject = results; + + if (aquaTempObject.is_reuslt_suc) { + for (const device of aquaTempObject.object_result) { + if (device.is_fault===false) { + + httpRequest.GetDeviceStatus(device.device_code).then((deviceResults)=> { + + const deviceResult = deviceResults; + + if (deviceResult.is_reuslt_suc) { + for (const codeData of deviceResult.object_result) { + if (codeData.code ==='T02') { + + const accessoryObject = this.getAccessory(device, 'temperature'); + const service = accessoryObject.accessory.getService(this.Service.TemperatureSensor); + + if (service!==undefined) { + service.updateCharacteristic(this.Characteristic.CurrentTemperature, codeData.value); + } + } + } + } else { + this.log.error(deviceResult.error_msg); + this.log.error(deviceResult.error_code); + this.log.error(deviceResult.error_msg_code); + } + }); + } + } + } else { + this.log.error(aquaTempObject.error_msg); + this.log.error(aquaTempObject.error_code); + this.log.error(aquaTempObject.error_msg_code); + } + }); + }, (this.config['UpdateTime'] as number) * 1000); + } - /** - * This function is invoked when homebridge restores cached accessories from disk at startup. - * It should be used to setup event handlers for characteristics and update respective values. - */ configureAccessory(accessory: PlatformAccessory) { this.log.info('Loading accessory from cache:', accessory.displayName); - // add the restored accessory to the accessories cache so we can track if it has already been registered this.accessories.push(accessory); } - /** - * This is an example method showing how to register discovered accessories. - * Accessories must only be registered once, previously created accessories - * must not be registered again to prevent "duplicate UUID" errors. - */ discoverDevices() { - - // EXAMPLE ONLY - // A real plugin you would discover accessories from the local network, cloud services - // or a user-defined array in the platform config. - const exampleDevices = [ - { - exampleUniqueId: 'ABCD', - exampleDisplayName: 'Bedroom', - }, - { - exampleUniqueId: 'EFGH', - exampleDisplayName: 'Kitchen', - }, - ]; - - // loop over the discovered devices and register each one if it has not already been registered - for (const device of exampleDevices) { - - // generate a unique id for the accessory this should be generated from - // something globally unique, but constant, for example, the device serial - // number or MAC address - const uuid = this.api.hap.uuid.generate(device.exampleUniqueId); - - // see if an accessory with the same uuid has already been registered and restored from - // the cached devices we stored in the `configureAccessory` method above - const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid); - - if (existingAccessory) { - // the accessory already exists - this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName); - - // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.: - // existingAccessory.context.device = device; - // this.api.updatePlatformAccessories([existingAccessory]); - - // create the accessory handler for the restored accessory - // this is imported from `platformAccessory.ts` - new ExamplePlatformAccessory(this, existingAccessory); - - // it is possible to remove platform accessories at any time using `api.unregisterPlatformAccessories`, eg.: - // remove platform accessories when no longer present - // this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [existingAccessory]); - // this.log.info('Removing existing accessory from cache:', existingAccessory.displayName); + const httpRequest = new HttpRequest(this.config, this.log); + + httpRequest.GetDeviceList().then((results)=> { + const aquaTempObject = results; + + if (aquaTempObject.is_reuslt_suc) { + for (const device of aquaTempObject.object_result) { + if (device.is_fault===false) { + const accessoryObject = this.getAccessory(device, 'temperature'); + new ThermometerAccessory(this, accessoryObject.accessory, device, this.config, this.log); + this.addOrRestorAccessory(accessoryObject.accessory, device.device_nick_name, 'temperature', accessoryObject.exists); + } + } } else { - // the accessory does not yet exist, so we need to create it - this.log.info('Adding new accessory:', device.exampleDisplayName); + this.log.error(aquaTempObject.error_msg); + this.log.error(aquaTempObject.error_code); + this.log.error(aquaTempObject.error_msg_code); + } + }); + } + + public getAccessory(device: ObjectResult, type: string) { + const existingAccessory = this.accessories.find(accessory => accessory.UUID === this.localIdForType(device, type)); - // create a new accessory - const accessory = new this.api.platformAccessory(device.exampleDisplayName, uuid); + if (existingAccessory!==undefined) { + existingAccessory.displayName = device.device_nick_name; - // store a copy of the device object in the `accessory.context` - // the `context` property can be used to store any data about the accessory you may need - accessory.context.device = device; + return {accessory : existingAccessory, exists : true}; + } - // create the accessory handler for the newly create accessory - // this is imported from `platformAccessory.ts` - new ExamplePlatformAccessory(this, accessory); + const accessory = new this.api.platformAccessory(device.device_nick_name, this.localIdForType(device, type)); + accessory.context.device = device; - // link the accessory to your platform - this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]); - } + return {accessory : accessory, exists : false}; + } + + public addOrRestorAccessory(accessory: PlatformAccessory>, name: string, type: string, exists: boolean ) { + if (exists) { + this.log.info('Restoring existing accessory:', name +' ('+type+')'); + this.api.updatePlatformAccessories([accessory]); + } else { + this.log.info('Adding new accessory:', name +' ('+type+')'); + this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]); } } -} + + localIdForType(device:ObjectResult, type:string):string { + return this.api.hap.uuid.generate(device.device_id.toString()+'_'+type); + } +} \ No newline at end of file diff --git a/src/platformAccessory.ts b/src/platformAccessory.ts deleted file mode 100644 index d885377..0000000 --- a/src/platformAccessory.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge'; - -import { ExampleHomebridgePlatform } from './platform'; - -/** - * Platform Accessory - * An instance of this class is created for each accessory your platform registers - * Each accessory may expose multiple services of different service types. - */ -export class ExamplePlatformAccessory { - private service: Service; - - /** - * These are just used to create a working example - * You should implement your own code to track the state of your accessory - */ - private exampleStates = { - On: false, - Brightness: 100, - }; - - constructor( - private readonly platform: ExampleHomebridgePlatform, - private readonly accessory: PlatformAccessory, - ) { - - // set accessory information - this.accessory.getService(this.platform.Service.AccessoryInformation)! - .setCharacteristic(this.platform.Characteristic.Manufacturer, 'Default-Manufacturer') - .setCharacteristic(this.platform.Characteristic.Model, 'Default-Model') - .setCharacteristic(this.platform.Characteristic.SerialNumber, 'Default-Serial'); - - // get the LightBulb service if it exists, otherwise create a new LightBulb service - // you can create multiple services for each accessory - this.service = this.accessory.getService(this.platform.Service.Lightbulb) || this.accessory.addService(this.platform.Service.Lightbulb); - - // set the service name, this is what is displayed as the default name on the Home app - // in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method. - this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device.exampleDisplayName); - - // each service must implement at-minimum the "required characteristics" for the given service type - // see https://developers.homebridge.io/#/service/Lightbulb - - // register handlers for the On/Off Characteristic - this.service.getCharacteristic(this.platform.Characteristic.On) - .onSet(this.setOn.bind(this)) // SET - bind to the `setOn` method below - .onGet(this.getOn.bind(this)); // GET - bind to the `getOn` method below - - // register handlers for the Brightness Characteristic - this.service.getCharacteristic(this.platform.Characteristic.Brightness) - .onSet(this.setBrightness.bind(this)); // SET - bind to the 'setBrightness` method below - - /** - * Creating multiple services of the same type. - * - * To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error, - * when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id: - * this.accessory.getService('NAME') || this.accessory.addService(this.platform.Service.Lightbulb, 'NAME', 'USER_DEFINED_SUBTYPE_ID'); - * - * The USER_DEFINED_SUBTYPE must be unique to the platform accessory (if you platform exposes multiple accessories, each accessory - * can use the same sub type id.) - */ - - // Example: add two "motion sensor" services to the accessory - const motionSensorOneService = this.accessory.getService('Motion Sensor One Name') || - this.accessory.addService(this.platform.Service.MotionSensor, 'Motion Sensor One Name', 'YourUniqueIdentifier-1'); - - const motionSensorTwoService = this.accessory.getService('Motion Sensor Two Name') || - this.accessory.addService(this.platform.Service.MotionSensor, 'Motion Sensor Two Name', 'YourUniqueIdentifier-2'); - - /** - * Updating characteristics values asynchronously. - * - * Example showing how to update the state of a Characteristic asynchronously instead - * of using the `on('get')` handlers. - * Here we change update the motion sensor trigger states on and off every 10 seconds - * the `updateCharacteristic` method. - * - */ - let motionDetected = false; - setInterval(() => { - // EXAMPLE - inverse the trigger - motionDetected = !motionDetected; - - // push the new value to HomeKit - motionSensorOneService.updateCharacteristic(this.platform.Characteristic.MotionDetected, motionDetected); - motionSensorTwoService.updateCharacteristic(this.platform.Characteristic.MotionDetected, !motionDetected); - - this.platform.log.debug('Triggering motionSensorOneService:', motionDetected); - this.platform.log.debug('Triggering motionSensorTwoService:', !motionDetected); - }, 10000); - } - - /** - * Handle "SET" requests from HomeKit - * These are sent when the user changes the state of an accessory, for example, turning on a Light bulb. - */ - async setOn(value: CharacteristicValue) { - // implement your own code to turn your device on/off - this.exampleStates.On = value as boolean; - - this.platform.log.debug('Set Characteristic On ->', value); - } - - /** - * Handle the "GET" requests from HomeKit - * These are sent when HomeKit wants to know the current state of the accessory, for example, checking if a Light bulb is on. - * - * GET requests should return as fast as possbile. A long delay here will result in - * HomeKit being unresponsive and a bad user experience in general. - * - * If your device takes time to respond you should update the status of your device - * asynchronously instead using the `updateCharacteristic` method instead. - - * @example - * this.service.updateCharacteristic(this.platform.Characteristic.On, true) - */ - async getOn(): Promise { - // implement your own code to check if the device is on - const isOn = this.exampleStates.On; - - this.platform.log.debug('Get Characteristic On ->', isOn); - - // if you need to return an error to show the device as "Not Responding" in the Home app: - // throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE); - - return isOn; - } - - /** - * Handle "SET" requests from HomeKit - * These are sent when the user changes the state of an accessory, for example, changing the Brightness - */ - async setBrightness(value: CharacteristicValue) { - // implement your own code to set the brightness - this.exampleStates.Brightness = value as number; - - this.platform.log.debug('Set Characteristic Brightness -> ', value); - } - -} diff --git a/src/settings.ts b/src/settings.ts index 8684475..2502f99 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,9 +1,2 @@ -/** - * This is the name of the platform that users will use to register the plugin in the Homebridge config.json - */ -export const PLATFORM_NAME = 'ExampleHomebridgePlugin'; - -/** - * This must match the name of your plugin as defined the package.json - */ -export const PLUGIN_NAME = 'homebridge-plugin-name'; \ No newline at end of file +export const PLATFORM_NAME = 'AquaTemp'; +export const PLUGIN_NAME = 'homebridge-aqua-temp'; \ No newline at end of file diff --git a/src/types/AquaTempObject.ts b/src/types/AquaTempObject.ts new file mode 100644 index 0000000..148e7fb --- /dev/null +++ b/src/types/AquaTempObject.ts @@ -0,0 +1,9 @@ +import { ObjectResult } from './ObjectResult'; + +export interface AquaTempObject { + error_code: string; + error_msg: string; + error_msg_code: string; + object_result: ObjectResult[]; + is_reuslt_suc: boolean; +} diff --git a/src/types/ObjectResult.ts b/src/types/ObjectResult.ts new file mode 100644 index 0000000..c0c8074 --- /dev/null +++ b/src/types/ObjectResult.ts @@ -0,0 +1,10 @@ +export interface ObjectResult { + device_status: string; + is_fault: boolean; + device_id: string; + device_code: string; + product_id: string; + device_nick_name: string; + code: string; + value: string; +} \ No newline at end of file diff --git a/src/utils/httprequest.ts b/src/utils/httprequest.ts new file mode 100644 index 0000000..0977498 --- /dev/null +++ b/src/utils/httprequest.ts @@ -0,0 +1,89 @@ +const request = require('request'); + +import { PlatformConfig, Logger } from 'homebridge'; + +export class HttpRequest { + + readonly urlDevicesList = 'http://cloud.linked-go.com:84/cloudservice/api/app/device/deviceList.json'; + readonly urlDevicesData = 'http://cloud.linked-go.com:84/cloudservice/api/app/device/getDataByCode.json'; + //readonly urlUpdateDevice = `http://${this.config['ip']}/v1/nodes/{id}/call?timeout=500`; + + constructor( + public readonly config: PlatformConfig, + public readonly log: Logger, + ) {} + + createInstance() { + return {}; + } + + GetDeviceList() { + return new Promise((resolve, reject) => { + request( + { + url: this.urlDevicesList, + method: 'POST', + headers: { + 'x-token': this.config['Token'], + }, + json: true, + }, (error, response, body) => { + if (error) { + reject(error); + } else { + resolve(body); + } + }); + }); + } + + GetDeviceStatus(deviceCode: string) { + return new Promise((resolve, reject) => { + request( + { + url: this.urlDevicesData, + method: 'POST', + headers: { + 'x-token': this.config['Token'], + }, + body: { + device_code: deviceCode, + protocal_codes: ['power', 'T02'], + }, + json: true, + }, (error, response, body) => { + if (error) { + reject(error); + } else { + resolve(body); + } + }); + }); + } + + // Update(id: number, body) { + // return new Promise((resolve, reject) => { + +// request( +// { +// url: this.urlUpdateDevice.replace('{id}', id.toString()), +// method: 'POST', +// body: body, +// auth: { +// user: 'nexa', +// pass: 'nexa', +// sendImmediately: false, +// }, +// json: true, +// }, +// (error, response, body) => { +// if (error) { +// reject(error); +// } else { +// resolve(body); +// } +// }, +// ); +// }); +// } +} \ No newline at end of file