homebridge-tydom 0.21.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/README.md +287 -0
- package/config.schema.json +38 -0
- package/lib/accessories/contactSensor.d.ts +4 -0
- package/lib/accessories/contactSensor.js +49 -0
- package/lib/accessories/fan.d.ts +4 -0
- package/lib/accessories/fan.js +17 -0
- package/lib/accessories/garageDoorOpener.d.ts +3 -0
- package/lib/accessories/garageDoorOpener.js +49 -0
- package/lib/accessories/lightbulb.d.ts +4 -0
- package/lib/accessories/lightbulb.js +147 -0
- package/lib/accessories/securitySystem.d.ts +5 -0
- package/lib/accessories/securitySystem.js +422 -0
- package/lib/accessories/securitySystemSensors.d.ts +5 -0
- package/lib/accessories/securitySystemSensors.js +160 -0
- package/lib/accessories/services/switchableService.d.ts +5 -0
- package/lib/accessories/services/switchableService.js +66 -0
- package/lib/accessories/switch.d.ts +4 -0
- package/lib/accessories/switch.js +17 -0
- package/lib/accessories/temperatureSensor.d.ts +4 -0
- package/lib/accessories/temperatureSensor.js +52 -0
- package/lib/accessories/thermostat.d.ts +4 -0
- package/lib/accessories/thermostat.js +340 -0
- package/lib/accessories/windowCovering.d.ts +5 -0
- package/lib/accessories/windowCovering.js +167 -0
- package/lib/config/env.d.ts +3 -0
- package/lib/config/env.js +7 -0
- package/lib/config/i18n/en.d.ts +1021 -0
- package/lib/config/i18n/en.js +1022 -0
- package/lib/config/i18n/fr.d.ts +1035 -0
- package/lib/config/i18n/fr.js +1036 -0
- package/lib/config/locale.d.ts +4110 -0
- package/lib/config/locale.js +12 -0
- package/lib/controller.d.ts +40 -0
- package/lib/controller.js +199 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.js +13 -0
- package/lib/platform.d.ts +37 -0
- package/lib/platform.js +114 -0
- package/lib/typings/tydom.d.ts +186 -0
- package/lib/typings/tydom.js +2 -0
- package/lib/utils/accessory.d.ts +19 -0
- package/lib/utils/accessory.js +139 -0
- package/lib/utils/array.d.ts +2 -0
- package/lib/utils/array.js +8 -0
- package/lib/utils/assert.d.ts +2 -0
- package/lib/utils/assert.js +9 -0
- package/lib/utils/chalk.d.ts +7 -0
- package/lib/utils/chalk.js +21 -0
- package/lib/utils/debug.d.ts +14 -0
- package/lib/utils/debug.js +44 -0
- package/lib/utils/hap.d.ts +6 -0
- package/lib/utils/hap.js +8 -0
- package/lib/utils/hash.d.ts +4 -0
- package/lib/utils/hash.js +28 -0
- package/lib/utils/request.d.ts +10 -0
- package/lib/utils/request.js +43 -0
- package/lib/utils/tydom.d.ts +27 -0
- package/lib/utils/tydom.js +126 -0
- package/lib/utils/webhook.d.ts +19 -0
- package/lib/utils/webhook.js +31 -0
- package/package.json +62 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
|
+
|
|
5
|
+
### [0.18.6](https://github.com/mgcrea/homebridge-tydom/compare/v0.18.5...v0.18.6) (2020-05-21)
|
|
6
|
+
|
|
7
|
+
### [0.18.5](https://github.com/mgcrea/homebridge-tydom/compare/v0.18.4...v0.18.5) (2020-05-19)
|
|
8
|
+
|
|
9
|
+
### [0.18.4](https://github.com/mgcrea/homebridge-tydom/compare/v0.18.3...v0.18.4) (2020-05-19)
|
package/README.md
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://github.com/mgcrea/homebridge-tydom">
|
|
3
|
+
<img src="https://raw.githubusercontent.com/mgcrea/homebridge-tydom/master/docs/homebridge-tydom_small.png" height="320" alt="Homebridge Tydom Logo" />
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/homebridge-tydom">
|
|
9
|
+
<img src="https://img.shields.io/npm/v/homebridge-tydom.svg" alt="Homebridge Tydom NPM Package" />
|
|
10
|
+
</a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/homebridge-tydom">
|
|
12
|
+
<img src="https://img.shields.io/npm/dm/homebridge-tydom.svg" alt="Homebridge Tydom NPM Download Count" />
|
|
13
|
+
</a>
|
|
14
|
+
<a href="https://travis-ci.com/mgcrea/homebridge-tydom">
|
|
15
|
+
<img src="https://travis-ci.com/mgcrea/homebridge-tydom.svg?branch=master" alt="Homebridge Tydom Travis Builds" />
|
|
16
|
+
</a>
|
|
17
|
+
<a href="https://david-dm.org/mgcrea/homebridge-tydom">
|
|
18
|
+
<img src="https://david-dm.org/mgcrea/homebridge-tydom/status.svg" alt="Homebridge Tydom Dependencies" />
|
|
19
|
+
</a>
|
|
20
|
+
<a href="https://codecov.io/gh/mgcrea/homebridge-tydom">
|
|
21
|
+
<img src="https://codecov.io/gh/mgcrea/homebridge-tydom/branch/master/graph/badge.svg" alt="Homebridge Tydom Code Coverage" />
|
|
22
|
+
</a>
|
|
23
|
+
</p>
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
[Homebridge](https://homebridge.io/) plugin to easily manage [Tydom hardware](https://www.deltadore.fr/domotique/pilotage-maison-connectee) by [Delta Dore](https://www.deltadore.fr/) from [Apple HomeKit](https://www.apple.com/ios/home/).
|
|
28
|
+
|
|
29
|
+
- Rely on [node-tydom-client](https://github.com/mgcrea/node-tydom-client) to communicate with an existing [Tydom bridge](https://www.deltadore.fr/domotique/pilotage-maison-connectee/box-domotique/tydom-2-0-ref-6414118) (required).
|
|
30
|
+
|
|
31
|
+
- Properly propagates external events into [Apple HomeKit](https://www.apple.com/ios/home/).
|
|
32
|
+
|
|
33
|
+
- Built with [TypeScript](https://www.typescriptlang.org/) for static type checking with exported types along the library.
|
|
34
|
+
|
|
35
|
+
- Supports Webhooks to trigger non-homekit dependent actions or notifications.
|
|
36
|
+
|
|
37
|
+
## Documentation
|
|
38
|
+
|
|
39
|
+
### Installation
|
|
40
|
+
|
|
41
|
+
1. Add `homebridge-tydom` plugin to your homebridge install:
|
|
42
|
+
|
|
43
|
+
- eg. using [oznu/docker-homebridge](https://github.com/oznu/docker-homebridge), update `./volumes/homebridge/package.json`
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"private": true,
|
|
48
|
+
"description": "This file keeps track of which plugins should be installed.",
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"homebridge-tydom": "^0.15.1"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
2. Configure the `homebridge-tydom` platform, providing your Tydom identifiers:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"bridge": {
|
|
60
|
+
"name": "Homebridge 27C9",
|
|
61
|
+
"username": "0E:21:1B:E7:27:C9",
|
|
62
|
+
"port": 53619,
|
|
63
|
+
"pin": "031-45-154"
|
|
64
|
+
},
|
|
65
|
+
"accessories": [],
|
|
66
|
+
"platforms": [
|
|
67
|
+
{
|
|
68
|
+
"platform": "Tydom",
|
|
69
|
+
"hostname": "mediation.tydom.com",
|
|
70
|
+
"username": "001A25123456",
|
|
71
|
+
"password": "YourPassw0rd"
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Your username is the MAC Address of your local Tydom hardware, it should be `001A25` + your 6-character home ID that you can find in the mobile app.
|
|
78
|
+
|
|
79
|
+
For your password, you can also use an environment variable `HOMEBRIDGE_TYDOM_PASSWORD` with the base64 encoded value of your password (might be safer than having it inside your `config.json`).
|
|
80
|
+
|
|
81
|
+
> Example: `HOMEBRIDGE_TYDOM_PASSWORD=Zm9vYmFyYmF6` for a `foobarbaz` password (`echo -n "foobarbaz" | base64`)
|
|
82
|
+
|
|
83
|
+
3. Configure the locale used for the labels (supported languages: `French` (default) & `English`) using the `HOMEBRIDGE_TYDOM_LOCALE` environment variable with value `fr` or `en`.
|
|
84
|
+
|
|
85
|
+
#### SecuritySystem
|
|
86
|
+
|
|
87
|
+
You can also manage your TYXAL+ security system from HomeKit, but it requires your alarm pin code:
|
|
88
|
+
|
|
89
|
+
As HomeKit security system has 3 active levels: `stay`, `night`, `away` you can configure which zones are linked to these active levels (`away` is by default every zones).
|
|
90
|
+
|
|
91
|
+
1. You need to add the following to the config `settings` field (check the logs for your actual device id).
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"platforms": [
|
|
96
|
+
{
|
|
97
|
+
"settings": {
|
|
98
|
+
"1521931577": {"aliases": {"stay": [3], "night": [2, 3]}}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
2. For the pin,
|
|
106
|
+
|
|
107
|
+
You can either add a `pin` field:
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"platforms": [
|
|
112
|
+
{
|
|
113
|
+
"settings": {
|
|
114
|
+
"1521931577": {"pin": "123456", "aliases": {"stay": [3], "night": [2, 3]}}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Or you can also use an environment variable `HOMEBRIDGE_TYDOM_PIN` with the base64 encoded value of your pin (might be safer than having it inside your `config.json`).
|
|
122
|
+
|
|
123
|
+
You can optionnaly rename zones (default is `Zone 1`, `Zone 2`, etc.),
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"platforms": [
|
|
128
|
+
{
|
|
129
|
+
"settings": {
|
|
130
|
+
"1521931577": {"zones": ["1st Floor", "Ground Floor", "Garden"]}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
#### Webhooks
|
|
138
|
+
|
|
139
|
+
You can specify webhooks in your `config.json` to receive non homekit-dependent notifications.
|
|
140
|
+
|
|
141
|
+
For now all `SecuritySystem` events are relayed and we only support [discord](https://ptb.discord.com/developers/docs/resources/webhook).
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"platforms": [
|
|
146
|
+
{
|
|
147
|
+
"webhooks": [
|
|
148
|
+
{
|
|
149
|
+
"url": "https://discord.com/api/webhooks/123456/abdcdef",
|
|
150
|
+
"type": "discord",
|
|
151
|
+
"level": "debug"
|
|
152
|
+
}
|
|
153
|
+
]
|
|
154
|
+
}
|
|
155
|
+
]
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
#### Category overrides (eg. Fan)
|
|
160
|
+
|
|
161
|
+
You can override categories of devices (eg. some light switch used to manage a fan)
|
|
162
|
+
|
|
163
|
+
1. You need to add the following to the config `settings` field (check the logs for your actual device id).
|
|
164
|
+
|
|
165
|
+
```json
|
|
166
|
+
{
|
|
167
|
+
"platforms": [
|
|
168
|
+
{
|
|
169
|
+
"settings": {
|
|
170
|
+
"1528565701": {"category": 3}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
> `3` being the `Categories.FAN` number.
|
|
178
|
+
|
|
179
|
+
### Supported hardware
|
|
180
|
+
|
|
181
|
+
It is currently supporting the following devices (have them at home).
|
|
182
|
+
|
|
183
|
+
- Lightbulb ([TYXIA 5610](https://www.deltadore.co.uk/home-automation/lighting-control/receiver-micromodule/tyxia-5610-ref-6351400), [TYXIA 6610](https://www.deltadore.co.uk/home-automation/lighting-control/receiver-switch/tyxia-6610-ref-6351376))
|
|
184
|
+
- Dimmable Lightbulb ([TYXIA 5650](https://www.deltadore.co.uk/home-automation/lighting-control/receiver-micromodule/tyxia-5650-ref-6351414-ref-6351414)
|
|
185
|
+
- Fan ([TYXIA 6610](https://www.deltadore.co.uk/home-automation/lighting-control/receiver-switch/tyxia-6610-ref-6351376))
|
|
186
|
+
- Thermostat ([RF4890](https://www.deltadore.co.uk/home-automation/heating-control/receiver-micromodule/rf-4890-ref-6050615))
|
|
187
|
+
- Switch ([TYXIA 4620](https://www.deltadore.co.uk/home-automation/control-shutters-blinds-gate-garage/receiver-micromodule/tyxia-4620-ref-6351104))
|
|
188
|
+
- Security System ([TYXAL+](https://www.deltadore.co.uk/home-automation/alarm/siren/si-tyxal-plus-ref-6415220))
|
|
189
|
+
- Contact Sensor (Door / Window) ([TYXAL+ MDO BL](https://www.deltadore.co.uk/home-automation/alarm/detector/mdo-bl-tyxal-plus-ref-6412305))
|
|
190
|
+
|
|
191
|
+
But should support many more similar devices out of the box.
|
|
192
|
+
|
|
193
|
+
Some other hardware that should work thanks to the community feedback:
|
|
194
|
+
|
|
195
|
+
- WindowCoverings ([TYXIA 5630](https://www.deltadore.co.uk/home-automation/control-shutters-blinds-gate-garage/receiver-micromodule/tyxia-5630-ref-6351401), [TYXIA 5730](https://www.deltadore.co.uk/home-automation/control-shutters-blinds-gate-garage/receiver-micromodule/tyxia-5730-ref-6351402), [TYXIA 5731](https://www.deltadore.co.uk/home-automation/control-shutters-blinds-gate-garage/receiver-micromodule/tyxia-5731-ref-6351412))
|
|
196
|
+
|
|
197
|
+
It is relatively easy to add new hardware so don't hesitate to create a new issue.
|
|
198
|
+
|
|
199
|
+
### Notes
|
|
200
|
+
|
|
201
|
+
You can also use your local tydom IP (eg `192.168.0.X`) for `hostname`, however:
|
|
202
|
+
|
|
203
|
+
- You must set environment var `NODE_TLS_REJECT_UNAUTHORIZED=0` to interact with the self-signed certificate.
|
|
204
|
+
- Tydom 2.0 current firmware does not seem to support multiple local clients, so you would end up locking you away from the mobile app.
|
|
205
|
+
|
|
206
|
+
### Configurations
|
|
207
|
+
|
|
208
|
+
| **Field** | **Type** | **Description** | |
|
|
209
|
+
| ------------------ | ------------------- | --------------------------- | ------------------------------------------ |
|
|
210
|
+
| hostname | `string` | Tydom hostname | |
|
|
211
|
+
| username | `string` | Tydom username | |
|
|
212
|
+
| password | `string` | Tydom password | |
|
|
213
|
+
| settings | `Record<string, ?>` | Device settings (overrides) | |
|
|
214
|
+
| includedDevices | `Array<string>` | number> | Include only devices with following ids |
|
|
215
|
+
| excludedDevices | `Array<string>` | number> | Exclude all devices with following ids |
|
|
216
|
+
| includedCategories | `Array<string>` | number> | Include only categories with following ids |
|
|
217
|
+
| excludedCategories | `Array<string>` | number> | Exclude all categories with following ids |
|
|
218
|
+
|
|
219
|
+
- The `settings` field enables you to override the name or homekit category of your Tydom device (check homebridge log for the device ids).
|
|
220
|
+
|
|
221
|
+
You can also use the following environment variables (base64 encoded values)
|
|
222
|
+
|
|
223
|
+
| **Env** | **Description** |
|
|
224
|
+
| ------------------------- | --------------- |
|
|
225
|
+
| HOMEBRIDGE_TYDOM_PASSWORD | Tydom password |
|
|
226
|
+
| HOMEBRIDGE_TYDOM_PIN | Tyxal+ pin |
|
|
227
|
+
|
|
228
|
+
### Debug
|
|
229
|
+
|
|
230
|
+
This library uses [debug](https://www.npmjs.com/package/debug) to provide high verbosity logs, just pass the following environment:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
DEBUG=homebridge-tydom
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
You might also want to debug [node-tydom-client](https://github.com/mgcrea/node-tydom-client)
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
DEBUG=homebridge-tydom,tydom-client
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Available scripts
|
|
243
|
+
|
|
244
|
+
| **Script** | **Description** |
|
|
245
|
+
| ------------- | ---------------------------- |
|
|
246
|
+
| start | alias to `spec:watch` |
|
|
247
|
+
| test | Run all tests |
|
|
248
|
+
| spec | Run unit tests |
|
|
249
|
+
| spec:coverage | Run unit tests with coverage |
|
|
250
|
+
| spec:watch | Watch unit tests |
|
|
251
|
+
| lint | Run eslint static tests |
|
|
252
|
+
| pretty | Run prettier static tests |
|
|
253
|
+
| build | Compile the library |
|
|
254
|
+
| build:watch | Watch compilation |
|
|
255
|
+
|
|
256
|
+
## Authors
|
|
257
|
+
|
|
258
|
+
**Olivier Louvignes**
|
|
259
|
+
|
|
260
|
+
- http://olouv.com
|
|
261
|
+
- http://github.com/mgcrea
|
|
262
|
+
|
|
263
|
+
## License
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
The MIT License
|
|
267
|
+
|
|
268
|
+
Copyright (c) 2020 Olivier Louvignes <olivier@mgcrea.io>
|
|
269
|
+
|
|
270
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
271
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
272
|
+
in the Software without restriction, including without limitation the rights
|
|
273
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
274
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
275
|
+
furnished to do so, subject to the following conditions:
|
|
276
|
+
|
|
277
|
+
The above copyright notice and this permission notice shall be included in
|
|
278
|
+
all copies or substantial portions of the Software.
|
|
279
|
+
|
|
280
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
281
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
282
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
283
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
284
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
285
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
286
|
+
THE SOFTWARE.
|
|
287
|
+
```
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"pluginAlias": "Tydom",
|
|
3
|
+
"pluginType": "platform",
|
|
4
|
+
"singular": true,
|
|
5
|
+
"headerDisplay": "Homebridge plugin to manage Tydom devices by Delta Dore",
|
|
6
|
+
"footerDisplay": "For a detailed description, see the [wiki](https://github.com/mgcrea/homebridge-tydom/wiki/Configuration)",
|
|
7
|
+
"schema": {
|
|
8
|
+
"type": "object",
|
|
9
|
+
"properties": {
|
|
10
|
+
"hostname": {
|
|
11
|
+
"title": "Tydom hostname",
|
|
12
|
+
"type": "string",
|
|
13
|
+
"required": true,
|
|
14
|
+
"default": "mediation.tydom.com"
|
|
15
|
+
},
|
|
16
|
+
"username": {
|
|
17
|
+
"title": "Tydom username",
|
|
18
|
+
"type": "string",
|
|
19
|
+
"required": true,
|
|
20
|
+
"default": ""
|
|
21
|
+
},
|
|
22
|
+
"password": {
|
|
23
|
+
"title": "Tydom password",
|
|
24
|
+
"type": "string",
|
|
25
|
+
"required": true,
|
|
26
|
+
"default": ""
|
|
27
|
+
},
|
|
28
|
+
"settings": {
|
|
29
|
+
"description": "Device settings",
|
|
30
|
+
"type": "object",
|
|
31
|
+
"patternProperties": {
|
|
32
|
+
"^[0-9]+$": {"type": "object"}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"form": ["hostname", "username", "password", "settings"]
|
|
38
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { PlatformAccessory } from 'homebridge';
|
|
2
|
+
import TydomController from '../controller';
|
|
3
|
+
export declare const setupContactSensor: (accessory: PlatformAccessory, controller: TydomController) => void;
|
|
4
|
+
export declare const updateContactSensor: (accessory: PlatformAccessory, _controller: TydomController, updates: Record<string, unknown>[]) => void;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateContactSensor = exports.setupContactSensor = void 0;
|
|
4
|
+
const accessory_1 = require("../utils/accessory");
|
|
5
|
+
const debug_1 = require("../utils/debug");
|
|
6
|
+
const hap_1 = require("../utils/hap");
|
|
7
|
+
const tydom_1 = require("../utils/tydom");
|
|
8
|
+
const setupContactSensor = (accessory, controller) => {
|
|
9
|
+
const { context } = accessory;
|
|
10
|
+
const { client } = controller;
|
|
11
|
+
const { ContactSensorState } = hap_1.Characteristic;
|
|
12
|
+
const { deviceId, endpointId } = context;
|
|
13
|
+
accessory_1.setupAccessoryInformationService(accessory, controller);
|
|
14
|
+
accessory_1.setupAccessoryIdentifyHandler(accessory, controller);
|
|
15
|
+
// Add the actual accessory Service
|
|
16
|
+
const service = accessory_1.addAccessoryService(accessory, hap_1.Service.ContactSensor, `${accessory.displayName}`, true);
|
|
17
|
+
service
|
|
18
|
+
.getCharacteristic(ContactSensorState)
|
|
19
|
+
.on("get" /* GET */, async (callback) => {
|
|
20
|
+
debug_1.debugGet(ContactSensorState, service);
|
|
21
|
+
try {
|
|
22
|
+
const data = await tydom_1.getTydomDeviceData(client, { deviceId, endpointId });
|
|
23
|
+
const intrusionDetect = tydom_1.getTydomDataPropValue(data, 'intrusionDetect');
|
|
24
|
+
debug_1.debugGetResult(ContactSensorState, service, intrusionDetect);
|
|
25
|
+
callback(null, intrusionDetect);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
callback(err);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
exports.setupContactSensor = setupContactSensor;
|
|
33
|
+
const updateContactSensor = (accessory, _controller, updates) => {
|
|
34
|
+
updates.forEach((update) => {
|
|
35
|
+
const { name, value } = update;
|
|
36
|
+
const { ContactSensorState } = hap_1.Characteristic;
|
|
37
|
+
switch (name) {
|
|
38
|
+
case 'intrusionDetect': {
|
|
39
|
+
const service = accessory_1.getAccessoryService(accessory, hap_1.Service.ContactSensor);
|
|
40
|
+
debug_1.debugSetUpdate(ContactSensorState, service, value);
|
|
41
|
+
service.updateCharacteristic(ContactSensorState, value);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
default:
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
exports.updateContactSensor = updateContactSensor;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { PlatformAccessory } from 'homebridge';
|
|
2
|
+
import TydomController from '../controller';
|
|
3
|
+
export declare const setupFan: (accessory: PlatformAccessory, controller: TydomController) => void;
|
|
4
|
+
export declare const updateFan: (accessory: PlatformAccessory, controller: TydomController, updates: Record<string, unknown>[]) => void;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateFan = exports.setupFan = void 0;
|
|
4
|
+
const accessory_1 = require("../utils/accessory");
|
|
5
|
+
const hap_1 = require("../utils/hap");
|
|
6
|
+
const switchableService_1 = require("./services/switchableService");
|
|
7
|
+
const setupFan = (accessory, controller) => {
|
|
8
|
+
accessory_1.setupAccessoryInformationService(accessory, controller);
|
|
9
|
+
accessory_1.setupAccessoryIdentifyHandler(accessory, controller);
|
|
10
|
+
// Add the actual accessory Service
|
|
11
|
+
switchableService_1.addAccessorySwitchableService(accessory, controller, hap_1.Service.Fan);
|
|
12
|
+
};
|
|
13
|
+
exports.setupFan = setupFan;
|
|
14
|
+
const updateFan = (accessory, controller, updates) => {
|
|
15
|
+
switchableService_1.updateAccessorySwitchableService(accessory, controller, updates, hap_1.Service.Fan);
|
|
16
|
+
};
|
|
17
|
+
exports.updateFan = updateFan;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setupGarageDoorOpener = void 0;
|
|
4
|
+
const accessory_1 = require("../utils/accessory");
|
|
5
|
+
const debug_1 = require("../utils/debug");
|
|
6
|
+
const hap_1 = require("../utils/hap");
|
|
7
|
+
const setupGarageDoorOpener = (accessory, controller) => {
|
|
8
|
+
const { context } = accessory;
|
|
9
|
+
const { client } = controller;
|
|
10
|
+
const { deviceId, endpointId } = context;
|
|
11
|
+
accessory_1.setupAccessoryInformationService(accessory, controller);
|
|
12
|
+
accessory_1.setupAccessoryIdentifyHandler(accessory, controller);
|
|
13
|
+
// Add the actual accessory Service
|
|
14
|
+
const service = accessory_1.addAccessoryService(accessory, hap_1.Service.Switch, `${accessory.displayName}`, true);
|
|
15
|
+
// State
|
|
16
|
+
// const state = {
|
|
17
|
+
// isOn: false
|
|
18
|
+
// };
|
|
19
|
+
service
|
|
20
|
+
.getCharacteristic(hap_1.Characteristic.On)
|
|
21
|
+
// .on(CharacteristicEventTypes.GET, async (callback: NodeCallback<CharacteristicValue>) => {
|
|
22
|
+
// callback(null, state.isOn);
|
|
23
|
+
// })
|
|
24
|
+
.on("set" /* SET */, async (value, callback) => {
|
|
25
|
+
debug_1.debugSet(hap_1.Characteristic.On, service, value);
|
|
26
|
+
if (!value) {
|
|
27
|
+
callback();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
await client.put(`/devices/${deviceId}/endpoints/${endpointId}/data`, [
|
|
32
|
+
{
|
|
33
|
+
name: 'levelCmd',
|
|
34
|
+
value: 'TOGGLE'
|
|
35
|
+
}
|
|
36
|
+
]);
|
|
37
|
+
debug_1.debugSetResult(hap_1.Characteristic.On, service, value);
|
|
38
|
+
callback();
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
service.updateCharacteristic(hap_1.Characteristic.On, false);
|
|
41
|
+
}, 1000);
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
callback(err);
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
.updateValue(false);
|
|
48
|
+
};
|
|
49
|
+
exports.setupGarageDoorOpener = setupGarageDoorOpener;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { PlatformAccessory } from 'homebridge';
|
|
2
|
+
import TydomController from '../controller';
|
|
3
|
+
export declare const setupLightbulb: (accessory: PlatformAccessory, controller: TydomController) => void;
|
|
4
|
+
export declare const updateLightbulb: (accessory: PlatformAccessory, controller: TydomController, updates: Record<string, unknown>[]) => void;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateLightbulb = exports.setupLightbulb = void 0;
|
|
4
|
+
const lodash_1 = require("lodash");
|
|
5
|
+
const accessory_1 = require("../utils/accessory");
|
|
6
|
+
const chalk_1 = require("../utils/chalk");
|
|
7
|
+
const debug_1 = require("../utils/debug");
|
|
8
|
+
const hap_1 = require("../utils/hap");
|
|
9
|
+
const tydom_1 = require("../utils/tydom");
|
|
10
|
+
const switchableService_1 = require("./services/switchableService");
|
|
11
|
+
const setupLightbulb = (accessory, controller) => {
|
|
12
|
+
const { context } = accessory;
|
|
13
|
+
const { client } = controller;
|
|
14
|
+
const { On, Brightness } = hap_1.Characteristic;
|
|
15
|
+
const { deviceId, endpointId, metadata, state } = context;
|
|
16
|
+
accessory_1.setupAccessoryInformationService(accessory, controller);
|
|
17
|
+
accessory_1.setupAccessoryIdentifyHandler(accessory, controller);
|
|
18
|
+
Object.assign(state, {
|
|
19
|
+
latestBrightness: 100,
|
|
20
|
+
pendingUpdatedValues: [],
|
|
21
|
+
lastUpdatedAt: 0
|
|
22
|
+
});
|
|
23
|
+
const levelMeta = lodash_1.find(metadata, { name: 'level' });
|
|
24
|
+
// Not dimmable
|
|
25
|
+
if ((levelMeta === null || levelMeta === void 0 ? void 0 : levelMeta.step) === 100) {
|
|
26
|
+
switchableService_1.addAccessorySwitchableService(accessory, controller, hap_1.Service.Lightbulb);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
// Dimmable
|
|
30
|
+
const service = accessory_1.addAccessoryService(accessory, hap_1.Service.Lightbulb, `${accessory.displayName}`, true);
|
|
31
|
+
const debouncedSetLevel = lodash_1.debounce(async (value) => {
|
|
32
|
+
debug_1.debugTydomPut('level', accessory, value);
|
|
33
|
+
await client.put(`/devices/${deviceId}/endpoints/${endpointId}/data`, [
|
|
34
|
+
{
|
|
35
|
+
name: 'level',
|
|
36
|
+
value
|
|
37
|
+
}
|
|
38
|
+
]);
|
|
39
|
+
Object.assign(state, {
|
|
40
|
+
pendingUpdatedValues: state.pendingUpdatedValues.concat([value])
|
|
41
|
+
});
|
|
42
|
+
}, 15, { leading: true, trailing: false });
|
|
43
|
+
service
|
|
44
|
+
.getCharacteristic(hap_1.Characteristic.On)
|
|
45
|
+
.on("get" /* GET */, async (callback) => {
|
|
46
|
+
debug_1.debugGet(On, service);
|
|
47
|
+
try {
|
|
48
|
+
const data = (await tydom_1.getTydomDeviceData(client, { deviceId, endpointId }));
|
|
49
|
+
const level = tydom_1.getTydomDataPropValue(data, 'level');
|
|
50
|
+
const nextValue = level > 0;
|
|
51
|
+
debug_1.debugGetResult(On, service, nextValue);
|
|
52
|
+
callback(null, nextValue);
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
callback(err);
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
.on("set" /* SET */, async (value, callback) => {
|
|
59
|
+
debug_1.debugSet(On, service, value);
|
|
60
|
+
try {
|
|
61
|
+
const nextLevel = value ? state.latestBrightness || 100 : 0;
|
|
62
|
+
await debouncedSetLevel(nextLevel);
|
|
63
|
+
service.updateCharacteristic(Brightness, nextLevel);
|
|
64
|
+
debug_1.debugSetResult(On, service, value);
|
|
65
|
+
callback();
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
callback(err);
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
.getValue();
|
|
72
|
+
service
|
|
73
|
+
.getCharacteristic(hap_1.Characteristic.Brightness)
|
|
74
|
+
.on("get" /* GET */, async (callback) => {
|
|
75
|
+
debug_1.debugGet(Brightness, service);
|
|
76
|
+
try {
|
|
77
|
+
const data = await tydom_1.getTydomDeviceData(client, { deviceId, endpointId });
|
|
78
|
+
const level = tydom_1.getTydomDataPropValue(data, 'level');
|
|
79
|
+
debug_1.debugGetResult(Brightness, service, level);
|
|
80
|
+
callback(null, level);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
callback(err);
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
.on("set" /* SET */, async (value, callback) => {
|
|
87
|
+
debug_1.debugSet(Brightness, service, value);
|
|
88
|
+
try {
|
|
89
|
+
const nextValue = value;
|
|
90
|
+
Object.assign(state, {
|
|
91
|
+
latestBrightness: nextValue,
|
|
92
|
+
lastUpdatedAt: Date.now()
|
|
93
|
+
});
|
|
94
|
+
await debouncedSetLevel(nextValue);
|
|
95
|
+
debug_1.debugSetResult(Brightness, service, value);
|
|
96
|
+
callback();
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
callback(err);
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
.getValue();
|
|
103
|
+
};
|
|
104
|
+
exports.setupLightbulb = setupLightbulb;
|
|
105
|
+
const updateLightbulb = (accessory, controller, updates) => {
|
|
106
|
+
const { context } = accessory;
|
|
107
|
+
const { metadata, state } = context;
|
|
108
|
+
const { On, Brightness } = hap_1.Characteristic;
|
|
109
|
+
const levelMeta = lodash_1.find(metadata, { name: 'level' });
|
|
110
|
+
// Not dimmable
|
|
111
|
+
if ((levelMeta === null || levelMeta === void 0 ? void 0 : levelMeta.step) === 100) {
|
|
112
|
+
switchableService_1.updateAccessorySwitchableService(accessory, controller, updates, hap_1.Service.Lightbulb);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
// Dimmable
|
|
116
|
+
updates.forEach((update) => {
|
|
117
|
+
const { name, value } = update;
|
|
118
|
+
switch (name) {
|
|
119
|
+
case 'level': {
|
|
120
|
+
const service = accessory_1.getAccessoryService(accessory, hap_1.Service.Lightbulb);
|
|
121
|
+
const level = value;
|
|
122
|
+
if (level === null) {
|
|
123
|
+
debug_1.debug(`Encountered a ${chalk_1.chalkString('level')} update with a null value!`);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
// @NOTE ignore pending updates
|
|
127
|
+
if (state.pendingUpdatedValues.includes(level)) {
|
|
128
|
+
debug_1.debug(`Ignoring a delayed ${chalk_1.chalkString('level')} update with value=${chalk_1.chalkNumber(level)}`);
|
|
129
|
+
// Reset pending updates stack
|
|
130
|
+
state.pendingUpdatedValues = [];
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
debug_1.debugSetUpdate(On, service, level > 0);
|
|
134
|
+
service.updateCharacteristic(On, level > 0);
|
|
135
|
+
// @NOTE Only update brightness for non-null values
|
|
136
|
+
if (level > 0) {
|
|
137
|
+
debug_1.debugSetUpdate(Brightness, service, level);
|
|
138
|
+
service.updateCharacteristic(Brightness, level);
|
|
139
|
+
}
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
default:
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
};
|
|
147
|
+
exports.updateLightbulb = updateLightbulb;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { PlatformAccessory } from 'homebridge';
|
|
2
|
+
import TydomController from '../controller';
|
|
3
|
+
import { TydomAccessoryUpdateType } from '../utils/accessory';
|
|
4
|
+
export declare const setupSecuritySystem: (accessory: PlatformAccessory, controller: TydomController) => Promise<void>;
|
|
5
|
+
export declare const updateSecuritySystem: (accessory: PlatformAccessory, controller: TydomController, updates: Record<string, unknown>[], type: TydomAccessoryUpdateType) => void;
|