homebridge-tydom 0.23.2 → 0.23.4

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.
@@ -10,12 +10,28 @@ const setupGarageDoorOpener = (accessory, controller) => {
10
10
  const { context } = accessory;
11
11
  const { client } = controller;
12
12
  const { CurrentDoorState, TargetDoorState } = hap_1.Characteristic;
13
- const GARAGE_DOOR_DELAY = 15 * 1000;
13
+ const GARAGE_DOOR_DELAY = 20 * 1000;
14
14
  const { deviceId, endpointId, state } = context;
15
15
  const assignState = (update) => {
16
16
  Object.assign(state, update);
17
17
  };
18
+ const getDoorStateLabel = (currentDoorState) => {
19
+ switch (currentDoorState) {
20
+ case CurrentDoorState.OPEN:
21
+ return 'OPEN';
22
+ case CurrentDoorState.CLOSED:
23
+ return 'CLOSED';
24
+ case CurrentDoorState.OPENING:
25
+ return 'OPENING';
26
+ case CurrentDoorState.CLOSING:
27
+ return 'CLOSING';
28
+ case CurrentDoorState.STOPPED:
29
+ return 'STOPPED';
30
+ }
31
+ return 'UNKNOWN';
32
+ };
18
33
  const assignCurrentDoorState = (currentDoorState) => {
34
+ (0, debug_1.debug)(`assignCurrentDoorState=${(0, chalk_1.chalkString)(getDoorStateLabel(currentDoorState))}`);
19
35
  Object.assign(state, { currentDoorState });
20
36
  service.updateCharacteristic(CurrentDoorState, currentDoorState);
21
37
  };
@@ -31,14 +47,14 @@ const setupGarageDoorOpener = (accessory, controller) => {
31
47
  currentDoorState: CurrentDoorState.CLOSED,
32
48
  targetDoorState: TargetDoorState.CLOSED,
33
49
  lastUpdatedAt: 0,
34
- computedPosition: 0 // 0 <-> GARAGE_DOOR_DELAY
50
+ computedPosition: 0 // 0 <-> 100%
35
51
  });
36
52
  const getNextCurrentDoorState = (targetDoorState) => {
37
53
  switch (state.currentDoorState) {
38
54
  case CurrentDoorState.OPEN: {
39
55
  switch (targetDoorState) {
40
56
  case TargetDoorState.CLOSED:
41
- return CurrentDoorState.OPENING;
57
+ return CurrentDoorState.CLOSING;
42
58
  case TargetDoorState.OPEN:
43
59
  return CurrentDoorState.OPEN;
44
60
  }
@@ -49,7 +65,7 @@ const setupGarageDoorOpener = (accessory, controller) => {
49
65
  case TargetDoorState.CLOSED:
50
66
  return CurrentDoorState.CLOSED;
51
67
  case TargetDoorState.OPEN:
52
- return CurrentDoorState.CLOSING;
68
+ return CurrentDoorState.OPENING;
53
69
  }
54
70
  break;
55
71
  }
@@ -71,7 +87,7 @@ const setupGarageDoorOpener = (accessory, controller) => {
71
87
  };
72
88
  const computeCurrentPosition = () => {
73
89
  const { lastUpdatedAt, computedPosition: lastComputedPosition, currentDoorState } = state;
74
- const elapsed = lastUpdatedAt - Date.now();
90
+ const elapsed = Date.now() - lastUpdatedAt;
75
91
  switch (currentDoorState) {
76
92
  case CurrentDoorState.STOPPED: {
77
93
  return lastComputedPosition;
@@ -83,10 +99,10 @@ const setupGarageDoorOpener = (accessory, controller) => {
83
99
  return 0;
84
100
  }
85
101
  case CurrentDoorState.OPENING: {
86
- return Math.min(100, lastComputedPosition + elapsed / GARAGE_DOOR_DELAY);
102
+ return Math.min(100, lastComputedPosition + 100 * (elapsed / GARAGE_DOOR_DELAY));
87
103
  }
88
104
  case CurrentDoorState.CLOSING: {
89
- return Math.max(0, lastComputedPosition - elapsed / GARAGE_DOOR_DELAY);
105
+ return Math.max(0, lastComputedPosition - 100 * (elapsed / GARAGE_DOOR_DELAY));
90
106
  }
91
107
  }
92
108
  return 0;
@@ -126,10 +142,6 @@ const setupGarageDoorOpener = (accessory, controller) => {
126
142
  })
127
143
  .on("set" /* CharacteristicEventTypes.SET */, async (value, callback) => {
128
144
  (0, debug_1.debugSet)(TargetDoorState, service, value);
129
- if (!value) {
130
- callback();
131
- return;
132
- }
133
145
  try {
134
146
  (0, debug_1.debugSetResult)(TargetDoorState, service, value);
135
147
  const targetDoorState = (0, basic_1.asNumber)(value);
@@ -138,7 +150,9 @@ const setupGarageDoorOpener = (accessory, controller) => {
138
150
  lastUpdatedAt: Date.now(),
139
151
  computedPosition: computeCurrentPosition()
140
152
  });
153
+ // debug(`computedPosition=${chalkNumber(state.computedPosition)}`);
141
154
  let nextCurrentDoorState = getNextCurrentDoorState(targetDoorState);
155
+ // debug(`nextCurrentDoorState=${chalkString(getDoorStateLabel(nextCurrentDoorState))}`);
142
156
  if (nextCurrentDoorState === state.currentDoorState) {
143
157
  (0, debug_1.debug)(`nextCurrentDoorState=${(0, chalk_1.chalkNumber)(nextCurrentDoorState)} === state.currentDoorState`);
144
158
  callback();
@@ -146,30 +160,48 @@ const setupGarageDoorOpener = (accessory, controller) => {
146
160
  }
147
161
  await toggleGarageDoor();
148
162
  assignCurrentDoorState(nextCurrentDoorState);
149
- callback();
150
163
  // Handle Stopped state, if we are stopped, wait one second and trigger again to reverse course
151
164
  // eg. Stopped -> Closing if target is Closed
152
165
  if (nextCurrentDoorState === CurrentDoorState.STOPPED) {
153
- await (0, basic_1.waitFor)(1000);
166
+ await (0, basic_1.waitFor)('stopping', 1000);
154
167
  assignState({
155
168
  targetDoorState: targetDoorState,
156
169
  lastUpdatedAt: Date.now(),
157
170
  computedPosition: computeCurrentPosition()
158
171
  });
172
+ // debug(`computedPosition=${chalkNumber(state.computedPosition)}`);
159
173
  nextCurrentDoorState = getNextCurrentDoorState(targetDoorState);
174
+ // debug(`nextCurrentDoorState=${chalkString(getDoorStateLabel(nextCurrentDoorState))}`);
160
175
  await toggleGarageDoor();
161
176
  assignCurrentDoorState(nextCurrentDoorState);
162
177
  }
178
+ callback();
163
179
  // Finally update pending states
164
180
  switch (nextCurrentDoorState) {
165
- case CurrentDoorState.OPENING:
166
- await (0, basic_1.waitFor)((100 - state.computedPosition) * GARAGE_DOOR_DELAY);
167
- assignCurrentDoorState(CurrentDoorState.OPEN);
181
+ case CurrentDoorState.OPENING: {
182
+ const delay = ((100 - state.computedPosition) * GARAGE_DOOR_DELAY) / 100;
183
+ // debug(`delay=${chalkNumber(delay)}`);
184
+ try {
185
+ await (0, basic_1.waitFor)(`${deviceId}.pending`, delay);
186
+ assignCurrentDoorState(CurrentDoorState.OPEN);
187
+ }
188
+ catch (err) {
189
+ // debug(`Aborted OPEN update with delay=${chalkNumber(delay)}`);
190
+ }
168
191
  break;
169
- case CurrentDoorState.CLOSING:
170
- await (0, basic_1.waitFor)(state.computedPosition * GARAGE_DOOR_DELAY);
171
- assignCurrentDoorState(CurrentDoorState.CLOSED);
192
+ }
193
+ case CurrentDoorState.CLOSING: {
194
+ const delay = (state.computedPosition * GARAGE_DOOR_DELAY) / 100;
195
+ // debug(`delay=${chalkNumber(delay)}`);
196
+ try {
197
+ await (0, basic_1.waitFor)(`${deviceId}.pending`, delay);
198
+ assignCurrentDoorState(CurrentDoorState.CLOSED);
199
+ }
200
+ catch (err) {
201
+ // debug(`Aborted CLOSED update with delay=${chalkNumber(delay)}`);
202
+ }
172
203
  break;
204
+ }
173
205
  }
174
206
  }
175
207
  catch (err) {
@@ -177,6 +209,29 @@ const setupGarageDoorOpener = (accessory, controller) => {
177
209
  }
178
210
  })
179
211
  .getValue();
212
+ // const switchService = addAccessoryService(accessory, Service.Switch, `${accessory.displayName} Switch`, true);
213
+ // debugAddSubService(switchService, accessory);
214
+ // service.addLinkedService(switchService);
215
+ // switchService
216
+ // .getCharacteristic(Characteristic.On)
217
+ // .on(CharacteristicEventTypes.SET, async (value: CharacteristicValue, callback: CharacteristicSetCallback) => {
218
+ // debugSet(Characteristic.On, service, value);
219
+ // if (!value) {
220
+ // callback();
221
+ // return;
222
+ // }
223
+ // try {
224
+ // await toggleGarageDoor();
225
+ // debugSetResult(Characteristic.On, service, value);
226
+ // callback();
227
+ // setTimeout(() => {
228
+ // service.updateCharacteristic(Characteristic.On, false);
229
+ // }, 1000);
230
+ // } catch (err) {
231
+ // callback(err as Error);
232
+ // }
233
+ // })
234
+ // .updateValue(false);
180
235
  };
181
236
  exports.setupGarageDoorOpener = setupGarageDoorOpener;
182
237
  const updateGarageDoorOpener = (accessory, _controller, updates, type) => {
package/lib/controller.js CHANGED
@@ -110,7 +110,7 @@ class TydomController extends events_1.EventEmitter {
110
110
  }
111
111
  const category = categoryFromSettings || (0, tydom_1.resolveEndpointCategory)({ firstUsage, metadata });
112
112
  if (!category) {
113
- this.log.warn(`Unsupported firstUsage="${firstUsage}" for endpoint with id="${endpointId}"`);
113
+ this.log.warn(`Unsupported firstUsage="${firstUsage}" for endpoint with deviceId="${deviceId}"`);
114
114
  (0, utils_1.debug)({ endpoint });
115
115
  return;
116
116
  }
package/lib/platform.js CHANGED
@@ -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 id="${id}"`);
97
+ this.log.info(`Creating accessory named="${accessoryName}" with 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,7 +102,7 @@ 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 id="${id}"`);
105
+ this.log.info(`Updating accessory named="${name}" with deviceId="${context.deviceId}"`);
106
106
  Object.assign(accessory.context, context);
107
107
  const tydomAccessorySetup = (0, accessory_1.getTydomAccessorySetup)(accessory);
108
108
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
@@ -1,4 +1,4 @@
1
1
  export declare const stringIncludes: (array: unknown[], value: string | number) => boolean;
2
2
  export declare const sameArrays: (source: unknown[], array: unknown[]) => boolean;
3
3
  export declare const asNumber: (maybeNumber: unknown) => number;
4
- export declare const waitFor: (ms: number) => Promise<void>;
4
+ export declare const waitFor: (key: string, ms: number) => Promise<void>;
@@ -8,5 +8,18 @@ const sameArrays = (source, array) => source.length === array.length && (0, loda
8
8
  exports.sameArrays = sameArrays;
9
9
  const asNumber = (maybeNumber) => parseInt(`${maybeNumber}`, 10);
10
10
  exports.asNumber = asNumber;
11
- const waitFor = async (ms) => new Promise((resolve) => setTimeout(resolve, ms));
11
+ const timeouts = new Map();
12
+ const waitFor = async (key, ms) => {
13
+ if (timeouts.has(key)) {
14
+ const { timeout, reject } = timeouts.get(key);
15
+ clearTimeout(timeout);
16
+ timeouts.delete(key);
17
+ reject();
18
+ }
19
+ await new Promise((resolve, reject) => {
20
+ const timeout = setTimeout(resolve, ms);
21
+ timeouts.set(key, { timeout, reject });
22
+ });
23
+ timeouts.delete(key);
24
+ };
12
25
  exports.waitFor = waitFor;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "homebridge-tydom",
3
- "version": "0.23.2",
3
+ "version": "0.23.4",
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",