homebridge-tydom 0.23.4 → 0.23.6
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/README.md +32 -0
- package/lib/accessories/contactSensor.d.ts +3 -2
- package/lib/accessories/fan.d.ts +3 -2
- package/lib/accessories/garageDoorOpener.d.ts +17 -4
- package/lib/accessories/garageDoorOpener.js +33 -26
- package/lib/accessories/lightbulb.d.ts +11 -2
- package/lib/accessories/outlet.d.ts +3 -2
- package/lib/accessories/securitySystem.d.ts +14 -2
- package/lib/accessories/securitySystem.js +3 -3
- package/lib/accessories/securitySystemSensors.d.ts +3 -2
- package/lib/accessories/services/switchableService.d.ts +3 -2
- package/lib/accessories/switch.d.ts +3 -2
- package/lib/accessories/switch.js +3 -3
- package/lib/accessories/temperatureSensor.d.ts +3 -2
- package/lib/accessories/thermostat.d.ts +3 -2
- package/lib/accessories/triggerSwitch.d.ts +10 -0
- package/lib/accessories/{basicGarageDoorOpener.js → triggerSwitch.js} +11 -12
- package/lib/accessories/windowCovering.d.ts +13 -2
- package/lib/bin/cli.js +1 -1
- package/lib/helpers/accessory.d.ts +17 -5
- package/lib/helpers/accessory.js +12 -4
- package/lib/helpers/tydom.js +8 -7
- package/lib/platform.d.ts +4 -4
- package/lib/platform.js +4 -4
- package/lib/typings/tydom.d.ts +10 -8
- package/package.json +3 -2
- package/lib/accessories/basicGarageDoorOpener.d.ts +0 -3
- package/lib/utils/accessory.d.ts +0 -19
- package/lib/utils/accessory.js +0 -139
- package/lib/utils/array.d.ts +0 -2
- package/lib/utils/array.js +0 -8
- package/lib/utils/hap.d.ts +0 -6
- package/lib/utils/hap.js +0 -8
- package/lib/utils/tydom.d.ts +0 -27
- package/lib/utils/tydom.js +0 -126
- package/lib/utils/webhook.d.ts +0 -19
- package/lib/utils/webhook.js +0 -31
package/README.md
CHANGED
|
@@ -139,6 +139,38 @@ You can optionnaly rename zones (default is `Zone 1`, `Zone 2`, etc.),
|
|
|
139
139
|
}
|
|
140
140
|
```
|
|
141
141
|
|
|
142
|
+
#### GarageDoorOpener
|
|
143
|
+
|
|
144
|
+
You can customize the default GarageDoorOpener `delay` (defaults to 20 seconds)
|
|
145
|
+
|
|
146
|
+
Value is in milliseconds:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"platforms": [
|
|
151
|
+
{
|
|
152
|
+
"settings": {
|
|
153
|
+
"1529094720": {"delay": 10000} // 10 seconds
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
You can also configure an `autoCloseDelay`
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"platforms": [
|
|
165
|
+
{
|
|
166
|
+
"settings": {
|
|
167
|
+
"1529094720": {"autoCloseDelay": 300000} // 5 minutes
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
142
174
|
#### Webhooks
|
|
143
175
|
|
|
144
176
|
You can specify webhooks in your `config.json` to receive non homekit-dependent notifications.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PlatformAccessory } from 'homebridge';
|
|
2
2
|
import TydomController from '../controller';
|
|
3
|
-
|
|
4
|
-
export declare const
|
|
3
|
+
import { TydomAccessoryContext } from '../typings';
|
|
4
|
+
export declare const setupContactSensor: (accessory: PlatformAccessory<TydomAccessoryContext>, controller: TydomController) => void;
|
|
5
|
+
export declare const updateContactSensor: (accessory: PlatformAccessory<TydomAccessoryContext>, _controller: TydomController, updates: Record<string, unknown>[]) => void;
|
package/lib/accessories/fan.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PlatformAccessory } from 'homebridge';
|
|
2
2
|
import TydomController from '../controller';
|
|
3
|
-
|
|
4
|
-
export declare const
|
|
3
|
+
import type { TydomAccessoryContext } from '../typings';
|
|
4
|
+
export declare const setupFan: (accessory: PlatformAccessory<TydomAccessoryContext>, controller: TydomController) => void;
|
|
5
|
+
export declare const updateFan: (accessory: PlatformAccessory<TydomAccessoryContext>, controller: TydomController, updates: Record<string, unknown>[]) => void;
|
|
@@ -1,5 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { PlatformAccessory } from 'homebridge';
|
|
2
2
|
import TydomController from '../controller';
|
|
3
|
-
import { TydomAccessoryUpdateType } from '../helpers
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import { TydomAccessoryUpdateType } from '../helpers';
|
|
4
|
+
import { TydomAccessoryContext } from '../typings';
|
|
5
|
+
type GarageDoorOpenerSettings = {
|
|
6
|
+
delay?: number;
|
|
7
|
+
autoCloseDelay?: number;
|
|
8
|
+
};
|
|
9
|
+
type GarageDoorOpenerState = {
|
|
10
|
+
currentDoorState: number;
|
|
11
|
+
targetDoorState: number;
|
|
12
|
+
lastUpdatedAt: number;
|
|
13
|
+
computedPosition: number;
|
|
14
|
+
};
|
|
15
|
+
type GarageDoorOpenerContext = TydomAccessoryContext<GarageDoorOpenerSettings, GarageDoorOpenerState>;
|
|
16
|
+
export declare const setupGarageDoorOpener: (accessory: PlatformAccessory<GarageDoorOpenerContext>, controller: TydomController) => void;
|
|
17
|
+
export declare const updateGarageDoorOpener: (accessory: PlatformAccessory<GarageDoorOpenerContext>, _controller: TydomController, updates: Record<string, unknown>[], type: TydomAccessoryUpdateType) => void;
|
|
18
|
+
export {};
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.updateGarageDoorOpener = exports.setupGarageDoorOpener = void 0;
|
|
7
|
+
const debug_1 = __importDefault(require("debug"));
|
|
8
|
+
const helpers_1 = require("../helpers");
|
|
9
|
+
const utils_1 = require("../utils");
|
|
4
10
|
const hap_1 = require("../config/hap");
|
|
5
|
-
const
|
|
6
|
-
const basic_1 = require("../utils/basic");
|
|
7
|
-
const chalk_1 = require("../utils/chalk");
|
|
8
|
-
const debug_1 = require("../utils/debug");
|
|
11
|
+
const DEFAULT_GARAGE_DOOR_DELAY = 20 * 1000;
|
|
9
12
|
const setupGarageDoorOpener = (accessory, controller) => {
|
|
10
13
|
const { context } = accessory;
|
|
11
14
|
const { client } = controller;
|
|
12
15
|
const { CurrentDoorState, TargetDoorState } = hap_1.Characteristic;
|
|
13
|
-
const
|
|
14
|
-
const {
|
|
16
|
+
const { deviceId, endpointId, state, settings } = context;
|
|
17
|
+
const { delay: garageDoorDelay = DEFAULT_GARAGE_DOOR_DELAY, autoCloseDelay } = settings;
|
|
15
18
|
const assignState = (update) => {
|
|
16
19
|
Object.assign(state, update);
|
|
17
20
|
};
|
|
@@ -31,7 +34,7 @@ const setupGarageDoorOpener = (accessory, controller) => {
|
|
|
31
34
|
return 'UNKNOWN';
|
|
32
35
|
};
|
|
33
36
|
const assignCurrentDoorState = (currentDoorState) => {
|
|
34
|
-
(0, debug_1.
|
|
37
|
+
(0, debug_1.default)(`assignCurrentDoorState=${(0, utils_1.chalkString)(getDoorStateLabel(currentDoorState))}`);
|
|
35
38
|
Object.assign(state, { currentDoorState });
|
|
36
39
|
service.updateCharacteristic(CurrentDoorState, currentDoorState);
|
|
37
40
|
};
|
|
@@ -41,8 +44,8 @@ const setupGarageDoorOpener = (accessory, controller) => {
|
|
|
41
44
|
value: 'TOGGLE'
|
|
42
45
|
}
|
|
43
46
|
]);
|
|
44
|
-
(0,
|
|
45
|
-
(0,
|
|
47
|
+
(0, helpers_1.setupAccessoryInformationService)(accessory, controller);
|
|
48
|
+
(0, helpers_1.setupAccessoryIdentifyHandler)(accessory, controller);
|
|
46
49
|
assignState({
|
|
47
50
|
currentDoorState: CurrentDoorState.CLOSED,
|
|
48
51
|
targetDoorState: TargetDoorState.CLOSED,
|
|
@@ -99,10 +102,10 @@ const setupGarageDoorOpener = (accessory, controller) => {
|
|
|
99
102
|
return 0;
|
|
100
103
|
}
|
|
101
104
|
case CurrentDoorState.OPENING: {
|
|
102
|
-
return Math.min(100, lastComputedPosition + 100 * (elapsed /
|
|
105
|
+
return Math.min(100, lastComputedPosition + 100 * (elapsed / garageDoorDelay));
|
|
103
106
|
}
|
|
104
107
|
case CurrentDoorState.CLOSING: {
|
|
105
|
-
return Math.max(0, lastComputedPosition - 100 * (elapsed /
|
|
108
|
+
return Math.max(0, lastComputedPosition - 100 * (elapsed / garageDoorDelay));
|
|
106
109
|
}
|
|
107
110
|
}
|
|
108
111
|
return 0;
|
|
@@ -112,14 +115,14 @@ const setupGarageDoorOpener = (accessory, controller) => {
|
|
|
112
115
|
if (legacyService) {
|
|
113
116
|
accessory.removeService(legacyService);
|
|
114
117
|
}
|
|
115
|
-
const service = (0,
|
|
118
|
+
const service = (0, helpers_1.addAccessoryService)(accessory, hap_1.Service.GarageDoorOpener, `${accessory.displayName}`, true);
|
|
116
119
|
service
|
|
117
120
|
.getCharacteristic(CurrentDoorState)
|
|
118
121
|
.on("get" /* CharacteristicEventTypes.GET */, async (callback) => {
|
|
119
|
-
(0,
|
|
122
|
+
(0, utils_1.debugGet)(CurrentDoorState, service);
|
|
120
123
|
try {
|
|
121
124
|
const nextValue = state.currentDoorState;
|
|
122
|
-
(0,
|
|
125
|
+
(0, utils_1.debugGetResult)(CurrentDoorState, service, nextValue);
|
|
123
126
|
callback(null, nextValue);
|
|
124
127
|
}
|
|
125
128
|
catch (err) {
|
|
@@ -130,10 +133,10 @@ const setupGarageDoorOpener = (accessory, controller) => {
|
|
|
130
133
|
service
|
|
131
134
|
.getCharacteristic(TargetDoorState)
|
|
132
135
|
.on("get" /* CharacteristicEventTypes.GET */, async (callback) => {
|
|
133
|
-
(0,
|
|
136
|
+
(0, utils_1.debugGet)(TargetDoorState, service);
|
|
134
137
|
try {
|
|
135
138
|
const nextValue = state.targetDoorState;
|
|
136
|
-
(0,
|
|
139
|
+
(0, utils_1.debugGetResult)(TargetDoorState, service, nextValue);
|
|
137
140
|
callback(null, nextValue);
|
|
138
141
|
}
|
|
139
142
|
catch (err) {
|
|
@@ -141,10 +144,10 @@ const setupGarageDoorOpener = (accessory, controller) => {
|
|
|
141
144
|
}
|
|
142
145
|
})
|
|
143
146
|
.on("set" /* CharacteristicEventTypes.SET */, async (value, callback) => {
|
|
144
|
-
(0,
|
|
147
|
+
(0, utils_1.debugSet)(TargetDoorState, service, value);
|
|
145
148
|
try {
|
|
146
|
-
(0,
|
|
147
|
-
const targetDoorState = (0,
|
|
149
|
+
(0, utils_1.debugSetResult)(TargetDoorState, service, value);
|
|
150
|
+
const targetDoorState = (0, utils_1.asNumber)(value);
|
|
148
151
|
assignState({
|
|
149
152
|
targetDoorState: targetDoorState,
|
|
150
153
|
lastUpdatedAt: Date.now(),
|
|
@@ -154,7 +157,7 @@ const setupGarageDoorOpener = (accessory, controller) => {
|
|
|
154
157
|
let nextCurrentDoorState = getNextCurrentDoorState(targetDoorState);
|
|
155
158
|
// debug(`nextCurrentDoorState=${chalkString(getDoorStateLabel(nextCurrentDoorState))}`);
|
|
156
159
|
if (nextCurrentDoorState === state.currentDoorState) {
|
|
157
|
-
(0, debug_1.
|
|
160
|
+
(0, debug_1.default)(`nextCurrentDoorState=${(0, utils_1.chalkNumber)(nextCurrentDoorState)} === state.currentDoorState`);
|
|
158
161
|
callback();
|
|
159
162
|
return;
|
|
160
163
|
}
|
|
@@ -163,7 +166,7 @@ const setupGarageDoorOpener = (accessory, controller) => {
|
|
|
163
166
|
// Handle Stopped state, if we are stopped, wait one second and trigger again to reverse course
|
|
164
167
|
// eg. Stopped -> Closing if target is Closed
|
|
165
168
|
if (nextCurrentDoorState === CurrentDoorState.STOPPED) {
|
|
166
|
-
await (0,
|
|
169
|
+
await (0, utils_1.waitFor)('stopping', 1000);
|
|
167
170
|
assignState({
|
|
168
171
|
targetDoorState: targetDoorState,
|
|
169
172
|
lastUpdatedAt: Date.now(),
|
|
@@ -179,11 +182,15 @@ const setupGarageDoorOpener = (accessory, controller) => {
|
|
|
179
182
|
// Finally update pending states
|
|
180
183
|
switch (nextCurrentDoorState) {
|
|
181
184
|
case CurrentDoorState.OPENING: {
|
|
182
|
-
const delay = ((100 - state.computedPosition) *
|
|
185
|
+
const delay = ((100 - state.computedPosition) * garageDoorDelay) / 100;
|
|
183
186
|
// debug(`delay=${chalkNumber(delay)}`);
|
|
184
187
|
try {
|
|
185
|
-
await (0,
|
|
188
|
+
await (0, utils_1.waitFor)(`${deviceId}.pending`, delay);
|
|
186
189
|
assignCurrentDoorState(CurrentDoorState.OPEN);
|
|
190
|
+
if (autoCloseDelay) {
|
|
191
|
+
await (0, utils_1.waitFor)(`${deviceId}.pending`, autoCloseDelay);
|
|
192
|
+
assignCurrentDoorState(CurrentDoorState.CLOSED);
|
|
193
|
+
}
|
|
187
194
|
}
|
|
188
195
|
catch (err) {
|
|
189
196
|
// debug(`Aborted OPEN update with delay=${chalkNumber(delay)}`);
|
|
@@ -191,10 +198,10 @@ const setupGarageDoorOpener = (accessory, controller) => {
|
|
|
191
198
|
break;
|
|
192
199
|
}
|
|
193
200
|
case CurrentDoorState.CLOSING: {
|
|
194
|
-
const delay = (state.computedPosition *
|
|
201
|
+
const delay = (state.computedPosition * garageDoorDelay) / 100;
|
|
195
202
|
// debug(`delay=${chalkNumber(delay)}`);
|
|
196
203
|
try {
|
|
197
|
-
await (0,
|
|
204
|
+
await (0, utils_1.waitFor)(`${deviceId}.pending`, delay);
|
|
198
205
|
assignCurrentDoorState(CurrentDoorState.CLOSED);
|
|
199
206
|
}
|
|
200
207
|
catch (err) {
|
|
@@ -242,7 +249,7 @@ const updateGarageDoorOpener = (accessory, _controller, updates, type) => {
|
|
|
242
249
|
updates.forEach((update) => {
|
|
243
250
|
const { values } = update;
|
|
244
251
|
const { event } = values;
|
|
245
|
-
(0, debug_1.
|
|
252
|
+
(0, debug_1.default)(`New ${(0, utils_1.chalkKeyword)('GarageDoorOpener')} event=${(0, utils_1.chalkJson)(event)}`);
|
|
246
253
|
});
|
|
247
254
|
return;
|
|
248
255
|
}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import type { PlatformAccessory } from 'homebridge';
|
|
2
2
|
import TydomController from '../controller';
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import { TydomAccessoryContext } from '../typings/tydom';
|
|
4
|
+
type LightbulbSettings = Record<string, never>;
|
|
5
|
+
type LightbulbState = {
|
|
6
|
+
latestBrightness: number;
|
|
7
|
+
pendingUpdatedValues: number[];
|
|
8
|
+
lastUpdatedAt: number;
|
|
9
|
+
};
|
|
10
|
+
type LightbulbContext = TydomAccessoryContext<LightbulbSettings, LightbulbState>;
|
|
11
|
+
export declare const setupLightbulb: (accessory: PlatformAccessory<LightbulbContext>, controller: TydomController) => void;
|
|
12
|
+
export declare const updateLightbulb: (accessory: PlatformAccessory<LightbulbContext>, controller: TydomController, updates: Record<string, unknown>[]) => void;
|
|
13
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PlatformAccessory } from 'homebridge';
|
|
2
|
+
import { TydomAccessoryContext } from '../typings';
|
|
2
3
|
import TydomController from '../controller';
|
|
3
|
-
export declare const setupOutlet: (accessory: PlatformAccessory
|
|
4
|
-
export declare const updateOutlet: (accessory: PlatformAccessory
|
|
4
|
+
export declare const setupOutlet: (accessory: PlatformAccessory<TydomAccessoryContext>, controller: TydomController) => void;
|
|
5
|
+
export declare const updateOutlet: (accessory: PlatformAccessory<TydomAccessoryContext>, controller: TydomController, updates: Record<string, unknown>[]) => void;
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import type { PlatformAccessory } from 'homebridge';
|
|
2
2
|
import TydomController from '../controller';
|
|
3
3
|
import { TydomAccessoryUpdateType } from '../helpers/accessory';
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import type { TydomAccessoryContext } from '../typings/tydom';
|
|
5
|
+
type ZoneAliases = {
|
|
6
|
+
stay?: number[];
|
|
7
|
+
night?: number[];
|
|
8
|
+
};
|
|
9
|
+
type SecuritySystemSettings = {
|
|
10
|
+
aliases?: ZoneAliases;
|
|
11
|
+
sensors?: boolean;
|
|
12
|
+
pin?: string;
|
|
13
|
+
};
|
|
14
|
+
type SecuritySystemContext = TydomAccessoryContext<SecuritySystemSettings>;
|
|
15
|
+
export declare const setupSecuritySystem: (accessory: PlatformAccessory<SecuritySystemContext>, controller: TydomController) => Promise<void>;
|
|
16
|
+
export declare const updateSecuritySystem: (accessory: PlatformAccessory<SecuritySystemContext>, controller: TydomController, updates: Record<string, unknown>[], type: TydomAccessoryUpdateType) => void;
|
|
17
|
+
export {};
|
|
@@ -52,7 +52,7 @@ const setupSecuritySystem = async (accessory, controller) => {
|
|
|
52
52
|
const { deviceId, endpointId, settings } = context;
|
|
53
53
|
(0, accessory_1.setupAccessoryInformationService)(accessory, controller);
|
|
54
54
|
(0, accessory_1.setupAccessoryIdentifyHandler)(accessory, controller);
|
|
55
|
-
const aliases =
|
|
55
|
+
const { aliases = {}, pin: settingsPin } = settings;
|
|
56
56
|
// Create separate dedicated sensor extra accessory;
|
|
57
57
|
if (settings.sensors !== false) {
|
|
58
58
|
const { accessoryId } = context;
|
|
@@ -68,7 +68,7 @@ const setupSecuritySystem = async (accessory, controller) => {
|
|
|
68
68
|
const labelResults = await client.command(`/devices/${deviceId}/endpoints/${endpointId}/cdata?name=label`);
|
|
69
69
|
const { zones } = labelResults[0];
|
|
70
70
|
// Pin code check
|
|
71
|
-
const pin = env_1.HOMEBRIDGE_TYDOM_PIN ? (0, utils_1.decode)(env_1.HOMEBRIDGE_TYDOM_PIN) :
|
|
71
|
+
const pin = env_1.HOMEBRIDGE_TYDOM_PIN ? (0, utils_1.decode)(env_1.HOMEBRIDGE_TYDOM_PIN) : settingsPin;
|
|
72
72
|
if (!pin) {
|
|
73
73
|
controller.log.warn(`Missing pin for device securitySystem, add either {"settings": {"${deviceId}": {"pin": "123456"}}} or HOMEBRIDGE_TYDOM_PIN env var (base64 encoded)`);
|
|
74
74
|
}
|
|
@@ -258,7 +258,7 @@ exports.setupSecuritySystem = setupSecuritySystem;
|
|
|
258
258
|
const updateSecuritySystem = (accessory, controller, updates, type) => {
|
|
259
259
|
// Relay to separate dedicated sensor extra accessory;
|
|
260
260
|
const { deviceId, endpointId, accessoryId, settings } = accessory.context;
|
|
261
|
-
const aliases =
|
|
261
|
+
const { aliases = {} } = settings;
|
|
262
262
|
const { SecuritySystemCurrentState, ContactSensorState, On } = hap_1.Characteristic;
|
|
263
263
|
if (settings.sensors !== false) {
|
|
264
264
|
const extraUpdateContext = {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PlatformAccessory } from 'homebridge';
|
|
2
2
|
import TydomController from '../controller';
|
|
3
3
|
import { TydomAccessoryUpdateType } from '../helpers/accessory';
|
|
4
|
-
|
|
5
|
-
export declare const
|
|
4
|
+
import type { TydomAccessoryContext } from '../typings/tydom';
|
|
5
|
+
export declare const setupSecuritySystemSensors: (accessory: PlatformAccessory<TydomAccessoryContext>, controller: TydomController) => Promise<void>;
|
|
6
|
+
export declare const updateSecuritySystemSensors: (accessory: PlatformAccessory<TydomAccessoryContext>, controller: TydomController, updates: Record<string, unknown>[], type: TydomAccessoryUpdateType) => void;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PlatformAccessory, Service } from 'homebridge';
|
|
2
2
|
import TydomController from '../../controller';
|
|
3
3
|
import { ServiceClass } from '../../helpers/accessory';
|
|
4
|
-
|
|
5
|
-
export declare const
|
|
4
|
+
import type { TydomAccessoryContext } from '../../typings/tydom';
|
|
5
|
+
export declare const addAccessorySwitchableService: (accessory: PlatformAccessory<TydomAccessoryContext>, controller: TydomController, serviceClass: ServiceClass) => Service;
|
|
6
|
+
export declare const updateAccessorySwitchableService: (accessory: PlatformAccessory<TydomAccessoryContext>, _controller: TydomController, updates: Record<string, unknown>[], ServiceClass: ServiceClass) => void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PlatformAccessory } from 'homebridge';
|
|
2
2
|
import TydomController from '../controller';
|
|
3
|
-
|
|
4
|
-
export declare const
|
|
3
|
+
import { TydomAccessoryContext } from '../typings';
|
|
4
|
+
export declare const setupSwitch: (accessory: PlatformAccessory<TydomAccessoryContext>, controller: TydomController) => void;
|
|
5
|
+
export declare const updateSwitch: (accessory: PlatformAccessory<TydomAccessoryContext>, controller: TydomController, updates: Record<string, unknown>[]) => void;
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.updateSwitch = exports.setupSwitch = void 0;
|
|
4
4
|
const hap_1 = require("../config/hap");
|
|
5
|
-
const
|
|
5
|
+
const helpers_1 = require("../helpers");
|
|
6
6
|
const switchableService_1 = require("./services/switchableService");
|
|
7
7
|
const setupSwitch = (accessory, controller) => {
|
|
8
|
-
(0,
|
|
9
|
-
(0,
|
|
8
|
+
(0, helpers_1.setupAccessoryInformationService)(accessory, controller);
|
|
9
|
+
(0, helpers_1.setupAccessoryIdentifyHandler)(accessory, controller);
|
|
10
10
|
// Add the actual accessory Service
|
|
11
11
|
(0, switchableService_1.addAccessorySwitchableService)(accessory, controller, hap_1.Service.Switch);
|
|
12
12
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PlatformAccessory } from 'homebridge';
|
|
2
2
|
import TydomController from '../controller';
|
|
3
|
-
|
|
4
|
-
export declare const
|
|
3
|
+
import type { TydomAccessoryContext } from '../typings/tydom';
|
|
4
|
+
export declare const setupTemperatureSensor: (accessory: PlatformAccessory<TydomAccessoryContext>, controller: TydomController) => void;
|
|
5
|
+
export declare const updateTemperatureSensor: (accessory: PlatformAccessory<TydomAccessoryContext>, _controller: TydomController, updates: Record<string, unknown>[]) => void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PlatformAccessory } from 'homebridge';
|
|
2
2
|
import TydomController from '../controller';
|
|
3
|
-
|
|
4
|
-
export declare const
|
|
3
|
+
import type { TydomAccessoryContext } from '../typings/tydom';
|
|
4
|
+
export declare const setupThermostat: (accessory: PlatformAccessory<TydomAccessoryContext>, controller: TydomController) => void;
|
|
5
|
+
export declare const updateThermostat: (accessory: PlatformAccessory<TydomAccessoryContext>, _controller: TydomController, updates: Record<string, unknown>[]) => void;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PlatformAccessory } from 'homebridge';
|
|
2
|
+
import TydomController from '../controller';
|
|
3
|
+
import type { TydomAccessoryContext } from '../typings/tydom';
|
|
4
|
+
type TriggerSwitchSettings = {
|
|
5
|
+
delay?: number;
|
|
6
|
+
};
|
|
7
|
+
type TriggerSwitchContext = TydomAccessoryContext<TriggerSwitchSettings>;
|
|
8
|
+
export declare const setupTriggerSwitch: (accessory: PlatformAccessory<TriggerSwitchContext>, controller: TydomController) => void;
|
|
9
|
+
export declare const updateTriggerSwitch: (accessory: PlatformAccessory<TriggerSwitchContext>, controller: TydomController, updates: Record<string, unknown>[]) => void;
|
|
10
|
+
export {};
|
|
@@ -1,26 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.updateTriggerSwitch = exports.setupTriggerSwitch = void 0;
|
|
4
4
|
const hap_1 = require("../config/hap");
|
|
5
5
|
const accessory_1 = require("../helpers/accessory");
|
|
6
6
|
const debug_1 = require("../utils/debug");
|
|
7
|
-
const
|
|
7
|
+
const TRIGGER_SWITCH_DEFAULT_DELAY = 1000;
|
|
8
|
+
const setupTriggerSwitch = (accessory, controller) => {
|
|
8
9
|
const { context } = accessory;
|
|
9
10
|
const { client } = controller;
|
|
10
|
-
const { deviceId, endpointId } = context;
|
|
11
|
+
const { deviceId, endpointId, settings } = context;
|
|
12
|
+
const { delay = TRIGGER_SWITCH_DEFAULT_DELAY } = settings;
|
|
11
13
|
(0, accessory_1.setupAccessoryInformationService)(accessory, controller);
|
|
12
14
|
(0, accessory_1.setupAccessoryIdentifyHandler)(accessory, controller);
|
|
13
15
|
// Add the actual accessory Service
|
|
14
16
|
const service = (0, accessory_1.addAccessoryService)(accessory, hap_1.Service.Switch, `${accessory.displayName}`, true);
|
|
15
|
-
// State
|
|
16
|
-
// const state = {
|
|
17
|
-
// isOn: false
|
|
18
|
-
// };
|
|
19
17
|
service
|
|
20
18
|
.getCharacteristic(hap_1.Characteristic.On)
|
|
21
|
-
// .on(CharacteristicEventTypes.GET, async (callback: NodeCallback<CharacteristicValue>) => {
|
|
22
|
-
// callback(null, state.isOn);
|
|
23
|
-
// })
|
|
24
19
|
.on("set" /* CharacteristicEventTypes.SET */, async (value, callback) => {
|
|
25
20
|
(0, debug_1.debugSet)(hap_1.Characteristic.On, service, value);
|
|
26
21
|
if (!value) {
|
|
@@ -38,7 +33,7 @@ const setupBasicGarageDoorOpener = (accessory, controller) => {
|
|
|
38
33
|
callback();
|
|
39
34
|
setTimeout(() => {
|
|
40
35
|
service.updateCharacteristic(hap_1.Characteristic.On, false);
|
|
41
|
-
},
|
|
36
|
+
}, delay);
|
|
42
37
|
}
|
|
43
38
|
catch (err) {
|
|
44
39
|
callback(err);
|
|
@@ -46,4 +41,8 @@ const setupBasicGarageDoorOpener = (accessory, controller) => {
|
|
|
46
41
|
})
|
|
47
42
|
.updateValue(false);
|
|
48
43
|
};
|
|
49
|
-
exports.
|
|
44
|
+
exports.setupTriggerSwitch = setupTriggerSwitch;
|
|
45
|
+
const updateTriggerSwitch = (accessory, controller, updates) => {
|
|
46
|
+
// no-op
|
|
47
|
+
};
|
|
48
|
+
exports.updateTriggerSwitch = updateTriggerSwitch;
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import type { PlatformAccessory } from 'homebridge';
|
|
2
2
|
import TydomController from '../controller';
|
|
3
3
|
import { TydomAccessoryUpdateType } from '../helpers/accessory';
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import type { TydomAccessoryContext } from '../typings/tydom';
|
|
5
|
+
type WindowCoveringSettings = {
|
|
6
|
+
invertDirection?: boolean;
|
|
7
|
+
};
|
|
8
|
+
type WindowCoveringState = {
|
|
9
|
+
latestPosition: number;
|
|
10
|
+
pendingUpdatedValues: number[];
|
|
11
|
+
lastUpdatedAt: number;
|
|
12
|
+
};
|
|
13
|
+
type WindowCoveringContext = TydomAccessoryContext<WindowCoveringSettings, WindowCoveringState>;
|
|
14
|
+
export declare const setupWindowCovering: (accessory: PlatformAccessory<WindowCoveringContext>, controller: TydomController) => void;
|
|
15
|
+
export declare const updateWindowCovering: (accessory: PlatformAccessory<WindowCoveringContext>, _controller: TydomController, updates: Record<string, unknown>[], type: TydomAccessoryUpdateType) => void;
|
|
16
|
+
export {};
|
package/lib/bin/cli.js
CHANGED
|
@@ -17,7 +17,7 @@ const main = async () => {
|
|
|
17
17
|
const signature = (0, tydom_1.getEndpointSignatureFromMetadata)(deviceMeta.endpoints[0].metadata);
|
|
18
18
|
const config = allDevicesConfig.endpoints.find((item) => item.id_device === deviceMeta.id);
|
|
19
19
|
const hash = `${config === null || config === void 0 ? void 0 : config.first_usage}:${await (0, utils_1.sha256)(signature)}`;
|
|
20
|
-
console.dir({ name: config === null || config === void 0 ? void 0 : config.name, signature, hash });
|
|
20
|
+
console.dir({ id: config === null || config === void 0 ? void 0 : config.id_device, name: config === null || config === void 0 ? void 0 : config.name, signature, hash });
|
|
21
21
|
}
|
|
22
22
|
break;
|
|
23
23
|
}
|
|
@@ -7,12 +7,24 @@ export declare const getAccessoryService: (accessory: PlatformAccessory, Service
|
|
|
7
7
|
export declare const getAccessoryServiceWithSubtype: (accessory: PlatformAccessory, ServiceClass: ServiceClass, subtype: string) => Service;
|
|
8
8
|
export declare const addAccessoryService: (accessory: PlatformAccessory, service: ServiceClass, name: string, removeExisting?: boolean) => Service;
|
|
9
9
|
export declare const addAccessoryServiceWithSubtype: (accessory: PlatformAccessory, service: ServiceClass, name: string, subtype: string, removeExisting?: boolean) => Service;
|
|
10
|
-
type TydomAccessorySetup = (accessory: PlatformAccessory
|
|
11
|
-
export declare const getTydomAccessorySetup:
|
|
10
|
+
type TydomAccessorySetup<T extends TydomAccessoryContext> = (accessory: PlatformAccessory<T>, controller: TydomController) => void | Promise<void>;
|
|
11
|
+
export declare const getTydomAccessorySetup: <T extends TydomAccessoryContext<any, any> = TydomAccessoryContext<{
|
|
12
|
+
[x: string]: unknown;
|
|
13
|
+
}, {
|
|
14
|
+
[x: string]: unknown;
|
|
15
|
+
}>>(accessory: PlatformAccessory<T>, context: T) => TydomAccessorySetup<T>;
|
|
12
16
|
export type TydomAccessoryUpdateType = 'data' | 'cdata';
|
|
13
|
-
type TydomAccessoryUpdate = (accessory: PlatformAccessory
|
|
14
|
-
export declare const getTydomAccessoryDataUpdate:
|
|
17
|
+
type TydomAccessoryUpdate<T extends TydomAccessoryContext> = (accessory: PlatformAccessory<T>, controller: TydomController, updates: Record<string, unknown>[], type: TydomAccessoryUpdateType) => void | Promise<void>;
|
|
18
|
+
export declare const getTydomAccessoryDataUpdate: <T extends TydomAccessoryContext<any, any> = TydomAccessoryContext<{
|
|
19
|
+
[x: string]: unknown;
|
|
20
|
+
}, {
|
|
21
|
+
[x: string]: unknown;
|
|
22
|
+
}>>(accessory: PlatformAccessory<T>, context: T) => TydomAccessoryUpdate<T>;
|
|
15
23
|
export declare const setupAccessoryInformationService: (accessory: PlatformAccessory, _controller: TydomController) => void;
|
|
16
24
|
export declare const setupAccessoryIdentifyHandler: (accessory: PlatformAccessory, _controller: TydomController) => void;
|
|
17
|
-
export declare const assignTydomContext: (prev: PlatformAccessory['context'], next: TydomAccessoryContext) => prev is TydomAccessoryContext<
|
|
25
|
+
export declare const assignTydomContext: (prev: PlatformAccessory['context'], next: TydomAccessoryContext) => prev is TydomAccessoryContext<{
|
|
26
|
+
[x: string]: unknown;
|
|
27
|
+
}, {
|
|
28
|
+
[x: string]: unknown;
|
|
29
|
+
}>;
|
|
18
30
|
export {};
|
package/lib/helpers/accessory.js
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.assignTydomContext = exports.setupAccessoryIdentifyHandler = exports.setupAccessoryInformationService = exports.getTydomAccessoryDataUpdate = exports.getTydomAccessorySetup = exports.addAccessoryServiceWithSubtype = exports.addAccessoryService = exports.getAccessoryServiceWithSubtype = exports.getAccessoryService = exports.SECURITY_SYSTEM_SENSORS = void 0;
|
|
4
|
+
const switch_1 = require("../accessories/switch");
|
|
5
|
+
const triggerSwitch_1 = require("../accessories/triggerSwitch");
|
|
4
6
|
const contactSensor_1 = require("../accessories/contactSensor");
|
|
5
7
|
const fan_1 = require("../accessories/fan");
|
|
6
8
|
const garageDoorOpener_1 = require("../accessories/garageDoorOpener");
|
|
7
9
|
const lightbulb_1 = require("../accessories/lightbulb");
|
|
10
|
+
const outlet_1 = require("../accessories/outlet");
|
|
8
11
|
const securitySystem_1 = require("../accessories/securitySystem");
|
|
9
12
|
const securitySystemSensors_1 = require("../accessories/securitySystemSensors");
|
|
10
13
|
const temperatureSensor_1 = require("../accessories/temperatureSensor");
|
|
11
14
|
const thermostat_1 = require("../accessories/thermostat");
|
|
12
15
|
const windowCovering_1 = require("../accessories/windowCovering");
|
|
13
|
-
const utils_1 = require("../utils");
|
|
14
16
|
const hap_1 = require("../config/hap");
|
|
15
|
-
const
|
|
17
|
+
const utils_1 = require("../utils");
|
|
16
18
|
exports.SECURITY_SYSTEM_SENSORS = parseInt(`${11 /* Categories.SECURITY_SYSTEM */}0`);
|
|
17
19
|
const getAccessoryService = (accessory, ServiceClass) => {
|
|
18
20
|
const service = accessory.getService(ServiceClass);
|
|
@@ -48,7 +50,8 @@ const addAccessoryServiceWithSubtype = (accessory, service, name, subtype, remov
|
|
|
48
50
|
return accessory.addService(service, name, subtype);
|
|
49
51
|
};
|
|
50
52
|
exports.addAccessoryServiceWithSubtype = addAccessoryServiceWithSubtype;
|
|
51
|
-
const getTydomAccessorySetup = (accessory) => {
|
|
53
|
+
const getTydomAccessorySetup = (accessory, context) => {
|
|
54
|
+
var _a;
|
|
52
55
|
const { category } = accessory;
|
|
53
56
|
switch (category) {
|
|
54
57
|
case 5 /* Categories.LIGHTBULB */:
|
|
@@ -61,6 +64,8 @@ const getTydomAccessorySetup = (accessory) => {
|
|
|
61
64
|
return fan_1.setupFan;
|
|
62
65
|
case 4 /* Categories.GARAGE_DOOR_OPENER */:
|
|
63
66
|
return garageDoorOpener_1.setupGarageDoorOpener;
|
|
67
|
+
case 8 /* Categories.SWITCH */:
|
|
68
|
+
return ((_a = context.settings) === null || _a === void 0 ? void 0 : _a.trigger) ? switch_1.setupSwitch : triggerSwitch_1.setupTriggerSwitch;
|
|
64
69
|
case 14 /* Categories.WINDOW_COVERING */:
|
|
65
70
|
return windowCovering_1.setupWindowCovering;
|
|
66
71
|
case 11 /* Categories.SECURITY_SYSTEM */:
|
|
@@ -77,7 +82,8 @@ const getTydomAccessorySetup = (accessory) => {
|
|
|
77
82
|
}
|
|
78
83
|
};
|
|
79
84
|
exports.getTydomAccessorySetup = getTydomAccessorySetup;
|
|
80
|
-
const getTydomAccessoryDataUpdate = (accessory) => {
|
|
85
|
+
const getTydomAccessoryDataUpdate = (accessory, context) => {
|
|
86
|
+
var _a;
|
|
81
87
|
const { category } = accessory;
|
|
82
88
|
switch (category) {
|
|
83
89
|
case 5 /* Categories.LIGHTBULB */:
|
|
@@ -90,6 +96,8 @@ const getTydomAccessoryDataUpdate = (accessory) => {
|
|
|
90
96
|
return fan_1.updateFan;
|
|
91
97
|
case 4 /* Categories.GARAGE_DOOR_OPENER */:
|
|
92
98
|
return garageDoorOpener_1.updateGarageDoorOpener;
|
|
99
|
+
case 8 /* Categories.SWITCH */:
|
|
100
|
+
return ((_a = context.settings) === null || _a === void 0 ? void 0 : _a.trigger) ? switch_1.updateSwitch : triggerSwitch_1.updateTriggerSwitch;
|
|
93
101
|
case 14 /* Categories.WINDOW_COVERING */:
|
|
94
102
|
return windowCovering_1.updateWindowCovering;
|
|
95
103
|
case 11 /* Categories.SECURITY_SYSTEM */:
|
package/lib/helpers/tydom.js
CHANGED
|
@@ -86,22 +86,23 @@ const LEGACY_SUPPORTED_CATEGORIES_MAP = {
|
|
|
86
86
|
};
|
|
87
87
|
const ENDPOINTS_SIGNATURES_CATEGORIES = {
|
|
88
88
|
'alarm:0c6e1d33808fa50a0a921502f80d36430dfaeda5abfed2467f9f2b07821e4842': 11 /* Categories.SECURITY_SYSTEM */,
|
|
89
|
-
'alarm:aad768ee0367013a974276117fd5ed4834cc26e4d31acc88d35134731331b0e7': 11 /* Categories.SECURITY_SYSTEM */,
|
|
90
89
|
'alarm:6e33f7ee5e62b58f4e888c91a13fd9b9d868f3751cead5ea1252578ba86523a5': 11 /* Categories.SECURITY_SYSTEM */,
|
|
90
|
+
'alarm:aad768ee0367013a974276117fd5ed4834cc26e4d31acc88d35134731331b0e7': 11 /* Categories.SECURITY_SYSTEM */,
|
|
91
91
|
'awning:48f43ebab20eba438fa9cc2b6ce44311d3cfb01c5be84bf17599d9c152c348d3': 14 /* Categories.WINDOW_COVERING */,
|
|
92
92
|
'belmDoor:fb935867933d89b3058f09384f76fd63f3defb18cfb3172f60fa9f4f237f748b': 12 /* Categories.DOOR */,
|
|
93
93
|
'conso:16804a9994bce28275150db329a9c0b931ef7f20608c1a3d2ff248f58569f0d3': 10 /* Categories.SENSOR */,
|
|
94
|
-
'gate:83b0912c6fe14622219522922ea0347dcbf86bf9cfd3346a2eca8eac70ca8260': 4 /* Categories.GARAGE_DOOR_OPENER */,
|
|
95
94
|
'garage_door:83b0912c6fe14622219522922ea0347dcbf86bf9cfd3346a2eca8eac70ca8260': 4 /* Categories.GARAGE_DOOR_OPENER */,
|
|
96
|
-
'
|
|
95
|
+
'gate:83b0912c6fe14622219522922ea0347dcbf86bf9cfd3346a2eca8eac70ca8260': 4 /* Categories.GARAGE_DOOR_OPENER */,
|
|
96
|
+
'hvac:16804a9994bce28275150db329a9c0b931ef7f20608c1a3d2ff248f58569f0d3': 10 /* Categories.SENSOR */,
|
|
97
97
|
'hvac:17f933bec8ed29f9b2a2cd5280fb5b64806cf8a1c064c83950e350f491d7cb9f': 9 /* Categories.THERMOSTAT */,
|
|
98
|
+
'hvac:1bab47d1dd7e898b5dc2e9867b14dfb8bc9272c4cb0b5d1221da962d43a6ffb4': 9 /* Categories.THERMOSTAT */,
|
|
99
|
+
'hvac:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': 10 /* Categories.SENSOR */,
|
|
98
100
|
'light:449e2a60377094cde10224cee91d378fb0ae373ae6ceea0ac2cbc1ed011bffa7': 5 /* Categories.LIGHTBULB */,
|
|
99
101
|
'light:fce45085835f4f2790ea3b17d208b5ace34935444d2535e75ba3f0a2ce86de5f': 5 /* Categories.LIGHTBULB */,
|
|
100
|
-
'shutter:c3fe8e2afa864e1a7a5c6676b4287a7b2f2a886a466baec3df8a1ec4f898ad6c': 14 /* Categories.WINDOW_COVERING */,
|
|
101
|
-
'window:fb935867933d89b3058f09384f76fd63f3defb18cfb3172f60fa9f4f237f748b': 13 /* Categories.WINDOW */,
|
|
102
102
|
'others:449e2a60377094cde10224cee91d378fb0ae373ae6ceea0ac2cbc1ed011bffa7': 5 /* Categories.LIGHTBULB */,
|
|
103
|
-
'
|
|
104
|
-
'
|
|
103
|
+
'plug:2534c497ff8fb013a88da28d341adff5bc0ba77e1fc8ea8dcb8b8f1c9d62ce19': 7 /* Categories.OUTLET */,
|
|
104
|
+
'shutter:c3fe8e2afa864e1a7a5c6676b4287a7b2f2a886a466baec3df8a1ec4f898ad6c': 14 /* Categories.WINDOW_COVERING */,
|
|
105
|
+
'window:fb935867933d89b3058f09384f76fd63f3defb18cfb3172f60fa9f4f237f748b': 13 /* Categories.WINDOW */ // @mgcrea (MDO)
|
|
105
106
|
};
|
|
106
107
|
const resolveEndpointCategory = ({ firstUsage, metadata }) => {
|
|
107
108
|
// Compute device signature
|
package/lib/platform.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export type TydomPlatformConfig = PlatformConfig & {
|
|
|
21
21
|
};
|
|
22
22
|
export default class TydomPlatform implements DynamicPlatformPlugin {
|
|
23
23
|
cleanupAccessoriesIds: Set<string>;
|
|
24
|
-
accessories: Map<string, PlatformAccessory
|
|
24
|
+
accessories: Map<string, PlatformAccessory<TydomAccessoryContext>>;
|
|
25
25
|
controller?: TydomController;
|
|
26
26
|
api: Homebridge;
|
|
27
27
|
config: TydomPlatformConfig;
|
|
@@ -32,7 +32,7 @@ export default class TydomPlatform implements DynamicPlatformPlugin {
|
|
|
32
32
|
handleControllerDevice(context: ControllerDevicePayload): Promise<void>;
|
|
33
33
|
handleControllerDataUpdate({ type, updates, context }: ControllerUpdatePayload): void;
|
|
34
34
|
handleControllerNotification({ level, message }: ControllerNotificationPayload): void;
|
|
35
|
-
createAccessory(name: string, id: string, category: Categories, context: TydomAccessoryContext): Promise<PlatformAccessory
|
|
36
|
-
updateAccessory(accessory: PlatformAccessory
|
|
37
|
-
configureAccessory(accessory: PlatformAccessory): void;
|
|
35
|
+
createAccessory(name: string, id: string, category: Categories, context: TydomAccessoryContext): Promise<PlatformAccessory<TydomAccessoryContext>>;
|
|
36
|
+
updateAccessory(accessory: PlatformAccessory<TydomAccessoryContext>, context: TydomAccessoryContext): Promise<void>;
|
|
37
|
+
configureAccessory(accessory: PlatformAccessory<TydomAccessoryContext>): void;
|
|
38
38
|
}
|
package/lib/platform.js
CHANGED
|
@@ -70,7 +70,7 @@ class TydomPlatform {
|
|
|
70
70
|
}
|
|
71
71
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
72
72
|
const accessory = this.accessories.get(id);
|
|
73
|
-
const tydomAccessoryUpdate = (0, accessory_1.getTydomAccessoryDataUpdate)(accessory);
|
|
73
|
+
const tydomAccessoryUpdate = (0, accessory_1.getTydomAccessoryDataUpdate)(accessory, context);
|
|
74
74
|
if (tydomAccessoryUpdate) {
|
|
75
75
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
76
76
|
tydomAccessoryUpdate(accessory, this.controller, updates, type);
|
|
@@ -94,7 +94,7 @@ class TydomPlatform {
|
|
|
94
94
|
const { platformAccessory: PlatformAccessory } = this.api;
|
|
95
95
|
const { group } = context;
|
|
96
96
|
const accessoryName = category === 13 /* Categories.WINDOW */ && group ? group.name || name : name;
|
|
97
|
-
this.log.info(`Creating accessory named="${accessoryName}" with deviceId="${context.deviceId}"`);
|
|
97
|
+
this.log.info(`Creating accessory named="${accessoryName}" with id="${id}", deviceId="${context.deviceId}"`);
|
|
98
98
|
const accessory = new PlatformAccessory(accessoryName, id, category);
|
|
99
99
|
Object.assign(accessory.context, context);
|
|
100
100
|
await this.updateAccessory(accessory, context);
|
|
@@ -102,9 +102,9 @@ class TydomPlatform {
|
|
|
102
102
|
}
|
|
103
103
|
async updateAccessory(accessory, context) {
|
|
104
104
|
const { displayName: name, UUID: id } = accessory;
|
|
105
|
-
this.log.info(`Updating accessory named="${name}" with deviceId="${context.deviceId}"`);
|
|
105
|
+
this.log.info(`Updating accessory named="${name}" with id="${id}", deviceId="${context.deviceId}"`);
|
|
106
106
|
Object.assign(accessory.context, context);
|
|
107
|
-
const tydomAccessorySetup = (0, accessory_1.getTydomAccessorySetup)(accessory);
|
|
107
|
+
const tydomAccessorySetup = (0, accessory_1.getTydomAccessorySetup)(accessory, context);
|
|
108
108
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
109
109
|
await tydomAccessorySetup(accessory, this.controller);
|
|
110
110
|
this.api.updatePlatformAccessories([accessory]);
|
package/lib/typings/tydom.d.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { Categories } from '../config/hap';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
type UnknownObject = Record<string, unknown>;
|
|
3
|
+
export type TydomAccessoryContext<T extends UnknownObject = UnknownObject, U extends UnknownObject = UnknownObject> = {
|
|
4
|
+
accessoryId: string;
|
|
4
5
|
category: Categories;
|
|
5
|
-
metadata: TydomMetaElement[];
|
|
6
|
-
settings: Record<string, unknown>;
|
|
7
6
|
deviceId: number;
|
|
8
7
|
endpointId: number;
|
|
9
|
-
|
|
8
|
+
group?: TydomConfigGroup;
|
|
10
9
|
manufacturer?: string;
|
|
11
|
-
|
|
10
|
+
metadata: TydomMetaElement[];
|
|
12
11
|
model?: string;
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
name: string;
|
|
13
|
+
serialNumber?: string;
|
|
14
|
+
settings: T;
|
|
15
|
+
state: U;
|
|
15
16
|
};
|
|
16
17
|
export type TydomAccessoryUpdateContext = Pick<TydomAccessoryContext, 'category' | 'deviceId' | 'endpointId' | 'accessoryId'>;
|
|
17
18
|
export type TydomConfigEndpoint = {
|
|
@@ -184,3 +185,4 @@ export type SecuritySystemAlarmEvent = {
|
|
|
184
185
|
}>;
|
|
185
186
|
product?: SecuritySystemProduct;
|
|
186
187
|
};
|
|
188
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-tydom",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.6",
|
|
4
4
|
"description": "Homebridge plugin to manage Tydom devices by Delta Dore",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"start:node": "NODE_TLS_REJECT_UNAUTHORIZED=0 NODE_PATH=src/ ts-node .",
|
|
23
23
|
"start:watch": "nodemon --ext \"ts,tsx\" --watch \"lib/\" --exec \"yarn start\"",
|
|
24
24
|
"start:prod": "yarn spec:watch",
|
|
25
|
-
"build": "tsc --build",
|
|
25
|
+
"build": "tsc --build && tsc-alias --project tsconfig.json",
|
|
26
26
|
"clean": "rm -rf .homebridge/persist/* .homebridge/accessories/*",
|
|
27
27
|
"lint": "eslint src/",
|
|
28
28
|
"prettycheck": "prettier --check src/",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"nock": "^13.2.9",
|
|
57
57
|
"prettier": "^2.8.0",
|
|
58
58
|
"ts-node": "^10.9.1",
|
|
59
|
+
"tsc-alias": "^1.7.1",
|
|
59
60
|
"typescript": "^4.9.3"
|
|
60
61
|
}
|
|
61
62
|
}
|
package/lib/utils/accessory.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { PlatformAccessory, Service, WithUUID } from 'homebridge';
|
|
2
|
-
import TydomController from '../controller';
|
|
3
|
-
import { TydomAccessoryContext } from '../typings/tydom';
|
|
4
|
-
export declare const SECURITY_SYSTEM_SENSORS: number;
|
|
5
|
-
export declare const asNumber: (maybeNumber: unknown) => number;
|
|
6
|
-
export declare type ServiceClass = WithUUID<typeof Service>;
|
|
7
|
-
export declare const getAccessoryService: (accessory: PlatformAccessory, ServiceClass: ServiceClass) => Service;
|
|
8
|
-
export declare const getAccessoryServiceWithSubtype: (accessory: PlatformAccessory, ServiceClass: ServiceClass, subtype: string) => Service;
|
|
9
|
-
export declare const addAccessoryService: (accessory: PlatformAccessory, service: ServiceClass, name: string, removeExisting?: boolean) => Service;
|
|
10
|
-
export declare const addAccessoryServiceWithSubtype: (accessory: PlatformAccessory, service: ServiceClass, name: string, subtype: string, removeExisting?: boolean) => Service;
|
|
11
|
-
declare type TydomAccessorySetup = (accessory: PlatformAccessory, controller: TydomController) => void | Promise<void>;
|
|
12
|
-
export declare const getTydomAccessorySetup: (accessory: PlatformAccessory) => TydomAccessorySetup;
|
|
13
|
-
export declare type TydomAccessoryUpdateType = 'data' | 'cdata';
|
|
14
|
-
declare type TydomAccessoryUpdate = (accessory: PlatformAccessory, controller: TydomController, updates: Record<string, unknown>[], type: TydomAccessoryUpdateType) => void | Promise<void>;
|
|
15
|
-
export declare const getTydomAccessoryDataUpdate: (accessory: PlatformAccessory) => TydomAccessoryUpdate;
|
|
16
|
-
export declare const setupAccessoryInformationService: (accessory: PlatformAccessory, _controller: TydomController) => void;
|
|
17
|
-
export declare const setupAccessoryIdentifyHandler: (accessory: PlatformAccessory, _controller: TydomController) => void;
|
|
18
|
-
export declare const assignTydomContext: (prev: PlatformAccessory['context'], next: TydomAccessoryContext) => prev is TydomAccessoryContext<Record<string, any>>;
|
|
19
|
-
export {};
|
package/lib/utils/accessory.js
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.assignTydomContext = exports.setupAccessoryIdentifyHandler = exports.setupAccessoryInformationService = exports.getTydomAccessoryDataUpdate = exports.getTydomAccessorySetup = exports.addAccessoryServiceWithSubtype = exports.addAccessoryService = exports.getAccessoryServiceWithSubtype = exports.getAccessoryService = exports.asNumber = exports.SECURITY_SYSTEM_SENSORS = void 0;
|
|
7
|
-
const contactSensor_1 = require("../accessories/contactSensor");
|
|
8
|
-
const fan_1 = require("../accessories/fan");
|
|
9
|
-
const garageDoorOpener_1 = require("../accessories/garageDoorOpener");
|
|
10
|
-
const lightbulb_1 = require("../accessories/lightbulb");
|
|
11
|
-
const securitySystem_1 = require("../accessories/securitySystem");
|
|
12
|
-
const securitySystemSensors_1 = require("../accessories/securitySystemSensors");
|
|
13
|
-
const temperatureSensor_1 = require("../accessories/temperatureSensor");
|
|
14
|
-
const thermostat_1 = require("../accessories/thermostat");
|
|
15
|
-
const windowCovering_1 = require("../accessories/windowCovering");
|
|
16
|
-
const assert_1 = __importDefault(require("../utils/assert"));
|
|
17
|
-
const debug_1 = __importDefault(require("../utils/debug"));
|
|
18
|
-
const hap_1 = require("../utils/hap");
|
|
19
|
-
exports.SECURITY_SYSTEM_SENSORS = parseInt(`${11 /* SECURITY_SYSTEM */}0`);
|
|
20
|
-
const asNumber = (maybeNumber) => parseInt(`${maybeNumber}`, 10);
|
|
21
|
-
exports.asNumber = asNumber;
|
|
22
|
-
const getAccessoryService = (accessory, ServiceClass) => {
|
|
23
|
-
const service = accessory.getService(ServiceClass);
|
|
24
|
-
assert_1.default(service, `Unexpected missing service "${ServiceClass.name}" in accessory`);
|
|
25
|
-
return service;
|
|
26
|
-
};
|
|
27
|
-
exports.getAccessoryService = getAccessoryService;
|
|
28
|
-
const getAccessoryServiceWithSubtype = (accessory, ServiceClass, subtype) => {
|
|
29
|
-
const service = accessory.getServiceByUUIDAndSubType(ServiceClass, subtype);
|
|
30
|
-
assert_1.default(service, `Unexpected missing service "${ServiceClass.name}" with subtype="${subtype}" in accessory`);
|
|
31
|
-
return service;
|
|
32
|
-
};
|
|
33
|
-
exports.getAccessoryServiceWithSubtype = getAccessoryServiceWithSubtype;
|
|
34
|
-
const addAccessoryService = (accessory, service, name, removeExisting = false) => {
|
|
35
|
-
const existingService = accessory.getService(service);
|
|
36
|
-
if (existingService) {
|
|
37
|
-
if (!removeExisting) {
|
|
38
|
-
return existingService;
|
|
39
|
-
}
|
|
40
|
-
accessory.removeService(existingService);
|
|
41
|
-
}
|
|
42
|
-
return accessory.addService(service, name);
|
|
43
|
-
};
|
|
44
|
-
exports.addAccessoryService = addAccessoryService;
|
|
45
|
-
const addAccessoryServiceWithSubtype = (accessory, service, name, subtype, removeExisting = false) => {
|
|
46
|
-
const existingService = accessory.getServiceById(service, subtype);
|
|
47
|
-
if (existingService) {
|
|
48
|
-
if (!removeExisting) {
|
|
49
|
-
return existingService;
|
|
50
|
-
}
|
|
51
|
-
accessory.removeService(existingService);
|
|
52
|
-
}
|
|
53
|
-
return accessory.addService(service, name, subtype);
|
|
54
|
-
};
|
|
55
|
-
exports.addAccessoryServiceWithSubtype = addAccessoryServiceWithSubtype;
|
|
56
|
-
const getTydomAccessorySetup = (accessory) => {
|
|
57
|
-
const { category } = accessory;
|
|
58
|
-
switch (category) {
|
|
59
|
-
case 5 /* LIGHTBULB */:
|
|
60
|
-
return lightbulb_1.setupLightbulb;
|
|
61
|
-
case 9 /* THERMOSTAT */:
|
|
62
|
-
return thermostat_1.setupThermostat;
|
|
63
|
-
case 3 /* FAN */:
|
|
64
|
-
return fan_1.setupFan;
|
|
65
|
-
case 4 /* GARAGE_DOOR_OPENER */:
|
|
66
|
-
return garageDoorOpener_1.setupGarageDoorOpener;
|
|
67
|
-
case 14 /* WINDOW_COVERING */:
|
|
68
|
-
return windowCovering_1.setupWindowCovering;
|
|
69
|
-
case 11 /* SECURITY_SYSTEM */:
|
|
70
|
-
return securitySystem_1.setupSecuritySystem;
|
|
71
|
-
case 10 /* SENSOR */:
|
|
72
|
-
return temperatureSensor_1.setupTemperatureSensor;
|
|
73
|
-
case 13 /* WINDOW */:
|
|
74
|
-
case 12 /* DOOR */:
|
|
75
|
-
return contactSensor_1.setupContactSensor;
|
|
76
|
-
case exports.SECURITY_SYSTEM_SENSORS:
|
|
77
|
-
return securitySystemSensors_1.setupSecuritySystemSensors;
|
|
78
|
-
default:
|
|
79
|
-
throw new Error(`Unsupported accessory category=${category}`);
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
exports.getTydomAccessorySetup = getTydomAccessorySetup;
|
|
83
|
-
const getTydomAccessoryDataUpdate = (accessory) => {
|
|
84
|
-
const { category } = accessory;
|
|
85
|
-
switch (category) {
|
|
86
|
-
case 5 /* LIGHTBULB */:
|
|
87
|
-
return lightbulb_1.updateLightbulb;
|
|
88
|
-
case 9 /* THERMOSTAT */:
|
|
89
|
-
return thermostat_1.updateThermostat;
|
|
90
|
-
case 3 /* FAN */:
|
|
91
|
-
return fan_1.updateFan;
|
|
92
|
-
case 4 /* GARAGE_DOOR_OPENER */:
|
|
93
|
-
return () => {
|
|
94
|
-
// no-op
|
|
95
|
-
};
|
|
96
|
-
case 14 /* WINDOW_COVERING */:
|
|
97
|
-
return windowCovering_1.updateWindowCovering;
|
|
98
|
-
case 11 /* SECURITY_SYSTEM */:
|
|
99
|
-
return securitySystem_1.updateSecuritySystem;
|
|
100
|
-
case 10 /* SENSOR */:
|
|
101
|
-
return temperatureSensor_1.updateTemperatureSensor;
|
|
102
|
-
case 13 /* WINDOW */:
|
|
103
|
-
case 12 /* DOOR */:
|
|
104
|
-
return contactSensor_1.updateContactSensor;
|
|
105
|
-
case exports.SECURITY_SYSTEM_SENSORS:
|
|
106
|
-
return securitySystemSensors_1.updateSecuritySystemSensors;
|
|
107
|
-
default:
|
|
108
|
-
throw new Error(`Unsupported accessory category=${category}`);
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
exports.getTydomAccessoryDataUpdate = getTydomAccessoryDataUpdate;
|
|
112
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
113
|
-
const setupAccessoryInformationService = (accessory, _controller) => {
|
|
114
|
-
const { context } = accessory;
|
|
115
|
-
const { manufacturer = 'Delta Dore', serialNumber = 'N/A', model = 'N/A' } = context;
|
|
116
|
-
const informationService = accessory.getService(hap_1.Service.AccessoryInformation);
|
|
117
|
-
assert_1.default(informationService, `Did not found AccessoryInformation service`);
|
|
118
|
-
informationService
|
|
119
|
-
.setCharacteristic(hap_1.Characteristic.Manufacturer, manufacturer)
|
|
120
|
-
.setCharacteristic(hap_1.Characteristic.SerialNumber, serialNumber)
|
|
121
|
-
.setCharacteristic(hap_1.Characteristic.Model, model);
|
|
122
|
-
};
|
|
123
|
-
exports.setupAccessoryInformationService = setupAccessoryInformationService;
|
|
124
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
125
|
-
const setupAccessoryIdentifyHandler = (accessory, _controller) => {
|
|
126
|
-
const { displayName: name, UUID: id } = accessory;
|
|
127
|
-
// listen for the "identify" event for this Accessory
|
|
128
|
-
accessory.on("identify" /* IDENTIFY */, ( /* paired: boolean, callback: VoidCallback */) => {
|
|
129
|
-
// debug({id, type: 'AccessoryEventTypes.IDENTIFY', paired});
|
|
130
|
-
debug_1.default(`New identify request for device named="${name}" with id="${id}"`);
|
|
131
|
-
// callback();
|
|
132
|
-
});
|
|
133
|
-
};
|
|
134
|
-
exports.setupAccessoryIdentifyHandler = setupAccessoryIdentifyHandler;
|
|
135
|
-
const assignTydomContext = (prev, next) => {
|
|
136
|
-
Object.assign(prev, next);
|
|
137
|
-
return true;
|
|
138
|
-
};
|
|
139
|
-
exports.assignTydomContext = assignTydomContext;
|
package/lib/utils/array.d.ts
DELETED
package/lib/utils/array.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sameArrays = exports.stringIncludes = void 0;
|
|
4
|
-
const lodash_1 = require("lodash");
|
|
5
|
-
const stringIncludes = (array, value) => array.includes(value) || array.includes(`${value}`);
|
|
6
|
-
exports.stringIncludes = stringIncludes;
|
|
7
|
-
const sameArrays = (source, array) => source.length === array.length && lodash_1.xor(source, array).length === 0;
|
|
8
|
-
exports.sameArrays = sameArrays;
|
package/lib/utils/hap.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { API as Homebridge, HAP } from 'homebridge';
|
|
2
|
-
export { AccessoryEventTypes, Categories, CharacteristicEventTypes } from 'homebridge';
|
|
3
|
-
export type { CharacteristicProps, CharacteristicSetCallback, CharacteristicValue, NodeCallback, VoidCallback } from 'homebridge';
|
|
4
|
-
export declare let Characteristic: HAP['Characteristic'];
|
|
5
|
-
export declare let Service: HAP['Service'];
|
|
6
|
-
export declare const defineHAPGlobals: (homebridge: Homebridge) => void;
|
package/lib/utils/hap.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.defineHAPGlobals = exports.Service = exports.Characteristic = void 0;
|
|
4
|
-
const defineHAPGlobals = (homebridge) => {
|
|
5
|
-
exports.Characteristic = homebridge.hap.Characteristic;
|
|
6
|
-
exports.Service = homebridge.hap.Service;
|
|
7
|
-
};
|
|
8
|
-
exports.defineHAPGlobals = defineHAPGlobals;
|
package/lib/utils/tydom.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { Categories } from '../utils/hap';
|
|
2
|
-
import { TydomConfigEndpoint, TydomEndpointData, TydomMetaElement, TydomMetaResponse, AnyTydomDataValue, TydomGroupsResponse, TydomMetaEndpoint } from '../typings/tydom';
|
|
3
|
-
import TydomClient from 'tydom-client';
|
|
4
|
-
import type { PlatformAccessory } from 'homebridge';
|
|
5
|
-
export declare type GetTydomDeviceDataOptions = {
|
|
6
|
-
deviceId: number;
|
|
7
|
-
endpointId: number;
|
|
8
|
-
accessory?: PlatformAccessory;
|
|
9
|
-
};
|
|
10
|
-
export declare const getTydomDeviceData: <T extends TydomEndpointData = TydomEndpointData>(client: TydomClient, { deviceId, endpointId }: GetTydomDeviceDataOptions) => Promise<T>;
|
|
11
|
-
export declare type RunTydomDeviceCommandOptions = {
|
|
12
|
-
deviceId: number;
|
|
13
|
-
endpointId: number;
|
|
14
|
-
searchParams?: Record<string, string>;
|
|
15
|
-
};
|
|
16
|
-
export declare const runTydomDeviceCommand: <T extends Record<string, unknown> = Record<string, unknown>>(client: TydomClient, name: string, { deviceId, endpointId, searchParams }: RunTydomDeviceCommandOptions) => Promise<T[]>;
|
|
17
|
-
export declare const getTydomDataPropValue: <V extends AnyTydomDataValue = AnyTydomDataValue, T extends TydomEndpointData = TydomEndpointData>(data: T, name: string) => V;
|
|
18
|
-
export declare const getEndpointDetailsFromMeta: ({ id_endpoint: endpointId, id_device: deviceId }: TydomConfigEndpoint, meta: TydomMetaResponse) => TydomMetaEndpoint;
|
|
19
|
-
export declare const getEndpointGroupIdFromGroups: ({ id_endpoint: endpointId, id_device: deviceId }: TydomConfigEndpoint, groups: TydomGroupsResponse) => number | null;
|
|
20
|
-
export declare const getEndpointSignatureFromMetadata: (metadata: TydomMetaElement[]) => string;
|
|
21
|
-
declare type ResolveEndpointCategoryOptions = {
|
|
22
|
-
firstUsage: string;
|
|
23
|
-
metadata: TydomMetaElement[];
|
|
24
|
-
};
|
|
25
|
-
export declare const resolveEndpointCategory: ({ firstUsage, metadata }: ResolveEndpointCategoryOptions) => Categories | null;
|
|
26
|
-
export declare const asyncWait: (ms: number) => Promise<void>;
|
|
27
|
-
export {};
|
package/lib/utils/tydom.js
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.asyncWait = exports.resolveEndpointCategory = exports.getEndpointSignatureFromMetadata = exports.getEndpointGroupIdFromGroups = exports.getEndpointDetailsFromMeta = exports.getTydomDataPropValue = exports.runTydomDeviceCommand = exports.getTydomDeviceData = void 0;
|
|
7
|
-
const lodash_1 = require("lodash");
|
|
8
|
-
const assert_1 = __importDefault(require("../utils/assert"));
|
|
9
|
-
const debug_1 = __importDefault(require("./debug"));
|
|
10
|
-
const hash_1 = require("./hash");
|
|
11
|
-
const url_1 = require("url");
|
|
12
|
-
const chalk_1 = require("./chalk");
|
|
13
|
-
const cacheMap = new Map();
|
|
14
|
-
const DEBOUNCE_TIME = 1 * 1e3;
|
|
15
|
-
const getTydomDeviceData = async (client, { deviceId, endpointId }) => {
|
|
16
|
-
const now = Date.now();
|
|
17
|
-
const uri = `/devices/${deviceId}/endpoints/${endpointId}/data`;
|
|
18
|
-
if (cacheMap.has(uri)) {
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
20
|
-
const { time, promise } = cacheMap.get(uri);
|
|
21
|
-
if (now < time + DEBOUNCE_TIME) {
|
|
22
|
-
return promise;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
const promise = client.get(uri).then((res) => {
|
|
26
|
-
if (res.error > 0) {
|
|
27
|
-
debug_1.default(`Received non-zero error=${chalk_1.chalkNumber(res.error)} while querying uri=${chalk_1.chalkString(uri)}`);
|
|
28
|
-
if (res.error > 10) {
|
|
29
|
-
debug_1.default(`Accessory with uri=${chalk_1.chalkString(uri)} seems unreacheable (error=${chalk_1.chalkNumber(res.error)}).`);
|
|
30
|
-
throw new Error('UnreacheableAccessory');
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
debug_1.default(`Accessory with uri=${chalk_1.chalkString(uri)} is reporting unknown issues (error=${chalk_1.chalkNumber(res.error)}).`);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return res.data ? res.data : res;
|
|
37
|
-
});
|
|
38
|
-
cacheMap.set(uri, { time: now, promise });
|
|
39
|
-
return promise;
|
|
40
|
-
};
|
|
41
|
-
exports.getTydomDeviceData = getTydomDeviceData;
|
|
42
|
-
const runTydomDeviceCommand = async (client, name, { deviceId, endpointId, searchParams }) => {
|
|
43
|
-
const now = Date.now();
|
|
44
|
-
const uri = `/devices/${deviceId}/endpoints/${endpointId}/cdata?name=${name}${searchParams ? `&${new url_1.URLSearchParams(searchParams)}` : ''}`;
|
|
45
|
-
if (cacheMap.has(uri)) {
|
|
46
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
47
|
-
const { time, promise } = cacheMap.get(uri);
|
|
48
|
-
if (now < time + DEBOUNCE_TIME) {
|
|
49
|
-
return promise;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
const promise = client.command(uri);
|
|
53
|
-
cacheMap.set(uri, { time: now, promise });
|
|
54
|
-
return promise;
|
|
55
|
-
};
|
|
56
|
-
exports.runTydomDeviceCommand = runTydomDeviceCommand;
|
|
57
|
-
const getTydomDataPropValue = (data, name) => {
|
|
58
|
-
const item = data.find((prop) => prop.name === name);
|
|
59
|
-
assert_1.default(item, `Missing property with name="${name}" in endpoint data`);
|
|
60
|
-
return item.value;
|
|
61
|
-
};
|
|
62
|
-
exports.getTydomDataPropValue = getTydomDataPropValue;
|
|
63
|
-
const getEndpointDetailsFromMeta = ({ id_endpoint: endpointId, id_device: deviceId }, meta) => {
|
|
64
|
-
const device = lodash_1.find(meta, { id: deviceId });
|
|
65
|
-
assert_1.default(device, `Device with id="${deviceId}" not found in Tydom meta`);
|
|
66
|
-
const details = lodash_1.find(device.endpoints, { id: endpointId });
|
|
67
|
-
assert_1.default(details, `Endpoint with id="${endpointId}" not found in device with id="${deviceId}" meta`);
|
|
68
|
-
return details;
|
|
69
|
-
};
|
|
70
|
-
exports.getEndpointDetailsFromMeta = getEndpointDetailsFromMeta;
|
|
71
|
-
const getEndpointGroupIdFromGroups = ({ id_endpoint: endpointId, id_device: deviceId }, groups) => {
|
|
72
|
-
const group = groups.groups.find(({ devices }) => devices.some(({ id, endpoints }) => id === deviceId && endpoints.some(({ id }) => id === endpointId)));
|
|
73
|
-
return group ? group.id : null;
|
|
74
|
-
};
|
|
75
|
-
exports.getEndpointGroupIdFromGroups = getEndpointGroupIdFromGroups;
|
|
76
|
-
const getEndpointSignatureFromMetadata = (metadata) => metadata
|
|
77
|
-
.map((value) => value.name)
|
|
78
|
-
.sort()
|
|
79
|
-
.join('|');
|
|
80
|
-
exports.getEndpointSignatureFromMetadata = getEndpointSignatureFromMetadata;
|
|
81
|
-
const LEGACY_SUPPORTED_CATEGORIES_MAP = {
|
|
82
|
-
alarm: 11 /* SECURITY_SYSTEM */,
|
|
83
|
-
awning: 14 /* WINDOW_COVERING */,
|
|
84
|
-
belmDoor: 12 /* DOOR */,
|
|
85
|
-
gate: 4 /* GARAGE_DOOR_OPENER */,
|
|
86
|
-
garage_door: 4 /* GARAGE_DOOR_OPENER */,
|
|
87
|
-
hvac: 9 /* THERMOSTAT */,
|
|
88
|
-
light: 5 /* LIGHTBULB */,
|
|
89
|
-
shutter: 14 /* WINDOW_COVERING */,
|
|
90
|
-
window: 13 /* WINDOW */
|
|
91
|
-
};
|
|
92
|
-
const ENDPOINTS_SIGNATURES_CATEGORIES = {
|
|
93
|
-
'alarm:0c6e1d33808fa50a0a921502f80d36430dfaeda5abfed2467f9f2b07821e4842': 11 /* SECURITY_SYSTEM */,
|
|
94
|
-
'alarm:aad768ee0367013a974276117fd5ed4834cc26e4d31acc88d35134731331b0e7': 11 /* SECURITY_SYSTEM */,
|
|
95
|
-
'alarm:6e33f7ee5e62b58f4e888c91a13fd9b9d868f3751cead5ea1252578ba86523a5': 11 /* SECURITY_SYSTEM */,
|
|
96
|
-
'awning:48f43ebab20eba438fa9cc2b6ce44311d3cfb01c5be84bf17599d9c152c348d3': 14 /* WINDOW_COVERING */,
|
|
97
|
-
'belmDoor:fb935867933d89b3058f09384f76fd63f3defb18cfb3172f60fa9f4f237f748b': 12 /* DOOR */,
|
|
98
|
-
'conso:16804a9994bce28275150db329a9c0b931ef7f20608c1a3d2ff248f58569f0d3': 10 /* SENSOR */,
|
|
99
|
-
'gate:83b0912c6fe14622219522922ea0347dcbf86bf9cfd3346a2eca8eac70ca8260': 4 /* GARAGE_DOOR_OPENER */,
|
|
100
|
-
'garage_door:83b0912c6fe14622219522922ea0347dcbf86bf9cfd3346a2eca8eac70ca8260': 4 /* GARAGE_DOOR_OPENER */,
|
|
101
|
-
'hvac:1bab47d1dd7e898b5dc2e9867b14dfb8bc9272c4cb0b5d1221da962d43a6ffb4': 9 /* THERMOSTAT */,
|
|
102
|
-
'light:449e2a60377094cde10224cee91d378fb0ae373ae6ceea0ac2cbc1ed011bffa7': 5 /* LIGHTBULB */,
|
|
103
|
-
'light:fce45085835f4f2790ea3b17d208b5ace34935444d2535e75ba3f0a2ce86de5f': 5 /* LIGHTBULB */,
|
|
104
|
-
'shutter:c3fe8e2afa864e1a7a5c6676b4287a7b2f2a886a466baec3df8a1ec4f898ad6c': 14 /* WINDOW_COVERING */,
|
|
105
|
-
'window:fb935867933d89b3058f09384f76fd63f3defb18cfb3172f60fa9f4f237f748b': 13 /* WINDOW */ // @mgcrea (MDO)
|
|
106
|
-
};
|
|
107
|
-
const resolveEndpointCategory = ({ firstUsage, metadata }) => {
|
|
108
|
-
// Compute device signature
|
|
109
|
-
const metaSignature = exports.getEndpointSignatureFromMetadata(metadata);
|
|
110
|
-
const hash = `${firstUsage}:${hash_1.sha256Sync(metaSignature)}`;
|
|
111
|
-
// dir({metaSignature, hash});
|
|
112
|
-
if (ENDPOINTS_SIGNATURES_CATEGORIES[hash]) {
|
|
113
|
-
return ENDPOINTS_SIGNATURES_CATEGORIES[hash];
|
|
114
|
-
}
|
|
115
|
-
debug_1.default(`Unknown hash=${hash} with firstUsage="${firstUsage}"`);
|
|
116
|
-
// Fallback on legacy resolution
|
|
117
|
-
if (LEGACY_SUPPORTED_CATEGORIES_MAP[firstUsage]) {
|
|
118
|
-
return LEGACY_SUPPORTED_CATEGORIES_MAP[firstUsage];
|
|
119
|
-
}
|
|
120
|
-
return null;
|
|
121
|
-
};
|
|
122
|
-
exports.resolveEndpointCategory = resolveEndpointCategory;
|
|
123
|
-
const asyncWait = (ms) => new Promise((resolve) => {
|
|
124
|
-
setTimeout(resolve, ms);
|
|
125
|
-
});
|
|
126
|
-
exports.asyncWait = asyncWait;
|
package/lib/utils/webhook.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export declare type Webhook = {
|
|
2
|
-
url: string;
|
|
3
|
-
type: string;
|
|
4
|
-
};
|
|
5
|
-
export declare type WebhookPayload = {
|
|
6
|
-
message: string;
|
|
7
|
-
level?: string;
|
|
8
|
-
};
|
|
9
|
-
declare type DiscordPayload = {
|
|
10
|
-
content: string;
|
|
11
|
-
username?: string;
|
|
12
|
-
avatar_url?: string;
|
|
13
|
-
tts?: boolean;
|
|
14
|
-
payload_json?: string;
|
|
15
|
-
allowed_mentions?: boolean;
|
|
16
|
-
};
|
|
17
|
-
export declare const asDiscordPayload: ({ level, message }: WebhookPayload) => DiscordPayload;
|
|
18
|
-
export declare const triggerWebhook: (webhook: Webhook, { message, level }: WebhookPayload) => Promise<void>;
|
|
19
|
-
export {};
|
package/lib/utils/webhook.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.triggerWebhook = exports.asDiscordPayload = void 0;
|
|
4
|
-
const request_1 = require("./request");
|
|
5
|
-
const asDiscordPayload = ({ level, message }) => {
|
|
6
|
-
let prefix = '';
|
|
7
|
-
switch (level) {
|
|
8
|
-
case 'warn':
|
|
9
|
-
prefix = ':warning: ';
|
|
10
|
-
break;
|
|
11
|
-
default:
|
|
12
|
-
prefix = ':question: ';
|
|
13
|
-
break;
|
|
14
|
-
}
|
|
15
|
-
return {
|
|
16
|
-
content: `${prefix}${message}`
|
|
17
|
-
};
|
|
18
|
-
};
|
|
19
|
-
exports.asDiscordPayload = asDiscordPayload;
|
|
20
|
-
const triggerWebhook = async (webhook, { message, level = 'info' }) => {
|
|
21
|
-
const { url, type } = webhook;
|
|
22
|
-
switch (type) {
|
|
23
|
-
case 'discord':
|
|
24
|
-
const res = await request_1.postJson({ url, json: exports.asDiscordPayload({ message, level }) });
|
|
25
|
-
console.dir({ res });
|
|
26
|
-
break;
|
|
27
|
-
default:
|
|
28
|
-
break;
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
exports.triggerWebhook = triggerWebhook;
|