@marcel2215/homebridge-supla-plugin 2.1.23 → 2.1.25

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.
@@ -0,0 +1,496 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FrontGateFsm = exports.DEFAULT_FRONT_GATE_TIMINGS = void 0;
4
+ exports.DEFAULT_FRONT_GATE_TIMINGS = {
5
+ fullTravelMs: 25000,
6
+ reversePauseMs: 3000,
7
+ wrongDirectionRunMs: 0,
8
+ minimumPulseGapMs: 3000,
9
+ closeRetryLimit: 1,
10
+ };
11
+ function delay(ms) {
12
+ return new Promise(resolve => setTimeout(resolve, ms));
13
+ }
14
+ function clampInt(value, min, max) {
15
+ if (!Number.isFinite(value)) {
16
+ return min;
17
+ }
18
+ return Math.min(max, Math.max(min, Math.round(value)));
19
+ }
20
+ class FrontGateFsm {
21
+ constructor(io, timings = exports.DEFAULT_FRONT_GATE_TIMINGS, _persisted = {}) {
22
+ this.io = io;
23
+ this.facts = {
24
+ controlConnected: null,
25
+ sensorConnected: null,
26
+ closedSensor: null,
27
+ };
28
+ this.sensorFreshSinceOnline = false;
29
+ this.requestedTarget = null;
30
+ this.plan = { kind: 'idle' };
31
+ this.lastPulseLikeActivityAt = 0;
32
+ this.movementTimerToken = 0;
33
+ this.phaseTimerToken = 0;
34
+ this.sequence = Promise.resolve(undefined);
35
+ this.disposed = false;
36
+ this.travelMs = clampInt(timings.fullTravelMs || exports.DEFAULT_FRONT_GATE_TIMINGS.fullTravelMs, 5000, 120000);
37
+ this.pulseGapMs = Math.max(3000, clampInt(timings.minimumPulseGapMs || exports.DEFAULT_FRONT_GATE_TIMINGS.minimumPulseGapMs, 0, 15000), clampInt(timings.reversePauseMs || exports.DEFAULT_FRONT_GATE_TIMINGS.reversePauseMs, 0, 15000));
38
+ this.closeRetryLimit = clampInt(timings.closeRetryLimit || exports.DEFAULT_FRONT_GATE_TIMINGS.closeRetryLimit, 0, 3);
39
+ this.emitSnapshot('fsm-initialized');
40
+ }
41
+ dispose() {
42
+ this.disposed = true;
43
+ this.clearTimers();
44
+ }
45
+ handleConnectedChange(connected) {
46
+ this.handleControlConnectedChange(connected);
47
+ }
48
+ handleControlConnectedChange(connected) {
49
+ void this.enqueue(`control-connected=${connected}`, () => {
50
+ this.applyControlConnectedChange(connected);
51
+ });
52
+ }
53
+ handleSensorConnectedChange(connected) {
54
+ void this.enqueue(`sensor-connected=${connected}`, () => {
55
+ this.applySensorConnectedChange(connected);
56
+ });
57
+ }
58
+ handleClosedSensorChange(closed) {
59
+ void this.enqueue(`closed-sensor=${closed}`, () => {
60
+ this.applyClosedSensorChange(closed);
61
+ });
62
+ }
63
+ async requestHomeKitTarget(target) {
64
+ return this.enqueue(`homekit-target=${target}`, async () => {
65
+ await this.applyHomeKitTarget(target);
66
+ });
67
+ }
68
+ getSnapshot() {
69
+ return this.buildSnapshot('snapshot-requested');
70
+ }
71
+ enqueue(label, task) {
72
+ if (this.disposed) {
73
+ return Promise.resolve();
74
+ }
75
+ const run = this.sequence.then(async () => {
76
+ if (this.disposed) {
77
+ return;
78
+ }
79
+ await task();
80
+ });
81
+ this.sequence = run.catch(error => {
82
+ const message = error instanceof Error ? error.message : String(error);
83
+ this.io.log.warn(`front-gate sequence '${label}' failed: ${message}`);
84
+ });
85
+ return run;
86
+ }
87
+ applyControlConnectedChange(connected) {
88
+ if (this.facts.controlConnected === connected) {
89
+ return;
90
+ }
91
+ this.facts.controlConnected = connected;
92
+ if (!connected) {
93
+ this.io.log.warn('front gate control channel went offline');
94
+ this.enterUnavailable('control-offline');
95
+ return;
96
+ }
97
+ this.io.log.info('front gate control channel connected');
98
+ this.clearTimers();
99
+ this.plan = { kind: 'idle' };
100
+ this.sensorFreshSinceOnline = false;
101
+ this.emitSnapshot('control-online-awaiting-fresh-sensor');
102
+ }
103
+ applySensorConnectedChange(connected) {
104
+ if (this.facts.sensorConnected === connected) {
105
+ return;
106
+ }
107
+ this.facts.sensorConnected = connected;
108
+ if (!connected) {
109
+ this.io.log.warn('front gate sensor channel went offline');
110
+ this.enterUnavailable('sensor-offline');
111
+ return;
112
+ }
113
+ this.io.log.info('front gate sensor channel connected');
114
+ this.clearTimers();
115
+ this.plan = { kind: 'idle' };
116
+ this.sensorFreshSinceOnline = false;
117
+ this.emitSnapshot('sensor-online-awaiting-fresh-state');
118
+ }
119
+ applyClosedSensorChange(closed) {
120
+ const previous = this.facts.closedSensor;
121
+ const wasFresh = this.sensorFreshSinceOnline;
122
+ this.facts.closedSensor = closed;
123
+ if (this.facts.controlConnected === true && this.facts.sensorConnected === true) {
124
+ this.sensorFreshSinceOnline = true;
125
+ }
126
+ const becameFresh = !wasFresh && this.sensorFreshSinceOnline;
127
+ if (previous === closed && !becameFresh) {
128
+ return;
129
+ }
130
+ if (closed) {
131
+ this.io.log.info('closed sensor is TRUE -> gate is fully closed');
132
+ this.clearTimers();
133
+ this.plan = { kind: 'idle' };
134
+ if (this.requestedTarget === 'open' && this.isAvailableForHomeKit()) {
135
+ this.emitSnapshot('closed-sensor-true-but-open-still-requested');
136
+ void this.enqueue('auto-open-after-closed', async () => {
137
+ await this.startOpeningFromClosed('auto-open-after-closed');
138
+ });
139
+ return;
140
+ }
141
+ this.requestedTarget = null;
142
+ this.emitSnapshot('closed-sensor-true');
143
+ return;
144
+ }
145
+ this.io.log.info('closed sensor is FALSE -> gate is not fully closed');
146
+ if (previous === true) {
147
+ // The gate just left the closed end-stop. This is the one fully reliable
148
+ // direction signal we have: motion is opening.
149
+ this.lastPulseLikeActivityAt = Date.now();
150
+ this.startOpeningMotion(this.requestedTarget === 'open' ? 'homekit' : 'external', 'closed-sensor-fell-from-true-to-false');
151
+ return;
152
+ }
153
+ if (this.requestedTarget === 'open'
154
+ && !(this.plan.kind === 'moving' && this.plan.direction === 'closing')
155
+ && !(this.plan.kind === 'waitingSecondPulse' && this.plan.finalDirection === 'closing')) {
156
+ this.requestedTarget = null;
157
+ }
158
+ this.emitSnapshot('closed-sensor-false');
159
+ }
160
+ async applyHomeKitTarget(target) {
161
+ if (!this.isAvailableForHomeKit()) {
162
+ throw new Error('front gate controller is not available');
163
+ }
164
+ this.requestedTarget = target;
165
+ if (target === 'open') {
166
+ await this.handleOpenRequest();
167
+ return;
168
+ }
169
+ await this.handleCloseRequest();
170
+ }
171
+ async handleOpenRequest() {
172
+ if (this.facts.closedSensor === true) {
173
+ if (this.plan.kind === 'moving' && this.plan.direction === 'opening') {
174
+ this.emitSnapshot('open-request-already-opening-from-closed');
175
+ return;
176
+ }
177
+ if (this.plan.kind === 'waitingSecondPulse' && this.plan.finalDirection === 'opening') {
178
+ this.emitSnapshot('open-request-already-reversing-to-open');
179
+ return;
180
+ }
181
+ await this.startOpeningFromClosed('homekit-open-from-closed');
182
+ return;
183
+ }
184
+ if (this.plan.kind === 'moving' && this.plan.direction === 'closing' && this.plan.certainty === 'known') {
185
+ await this.reverseKnownMotion('opening', 'homekit-reverse-known-closing-to-open');
186
+ return;
187
+ }
188
+ if (this.plan.kind === 'waitingSecondPulse' && this.plan.finalDirection === 'closing') {
189
+ this.io.log.info('open requested while waiting to restart towards close; cancelling close restart');
190
+ this.clearPhaseTimer();
191
+ this.plan = { kind: 'idle' };
192
+ this.emitSnapshot('cancelled-pending-close-restart');
193
+ return;
194
+ }
195
+ if (this.plan.kind === 'moving' && this.plan.direction === 'closing' && this.plan.certainty === 'goalOnly') {
196
+ // We do not actually know whether the gate is currently closing or whether a
197
+ // previous close-seek pulse accidentally caused opening. In this ambiguous
198
+ // state, the safest action is to cancel further close retries and hold the
199
+ // gate in the generic open-ish state.
200
+ this.io.log.warn('open requested during ambiguous close-seek; cancelling close retries instead of sending more pulses');
201
+ this.clearTimers();
202
+ this.plan = { kind: 'idle' };
203
+ this.requestedTarget = null;
204
+ this.emitSnapshot('cancelled-ambiguous-close-seek');
205
+ return;
206
+ }
207
+ this.requestedTarget = null;
208
+ this.emitSnapshot('open-request-already-satisfied-openish');
209
+ }
210
+ async handleCloseRequest() {
211
+ if (this.facts.closedSensor === true) {
212
+ if (this.plan.kind === 'moving' && this.plan.direction === 'opening') {
213
+ // A very early cancel while we are still on the closed end-stop can be
214
+ // satisfied by one pulse: stop the opening attempt and remain closed.
215
+ await this.pulseMotor('cancel-opening-while-still-closed');
216
+ this.clearTimers();
217
+ this.plan = { kind: 'idle' };
218
+ this.requestedTarget = null;
219
+ this.emitSnapshot('opening-cancelled-before-leaving-closed');
220
+ return;
221
+ }
222
+ this.requestedTarget = null;
223
+ this.emitSnapshot('close-request-already-satisfied');
224
+ return;
225
+ }
226
+ if (this.plan.kind === 'moving' && this.plan.direction === 'opening' && this.plan.certainty === 'known') {
227
+ await this.reverseKnownMotion('closing', 'homekit-reverse-known-opening-to-close');
228
+ return;
229
+ }
230
+ if (this.plan.kind === 'waitingSecondPulse' && this.plan.finalDirection === 'opening') {
231
+ this.io.log.info('close requested while waiting to restart towards open; cancelling open restart');
232
+ this.clearPhaseTimer();
233
+ this.plan = { kind: 'idle' };
234
+ await this.startCloseSeek(0, 'close-after-cancelled-open-restart');
235
+ return;
236
+ }
237
+ if (this.plan.kind === 'waitingSecondPulse' && this.plan.finalDirection === 'closing') {
238
+ this.emitSnapshot('close-request-already-reversing-to-close');
239
+ return;
240
+ }
241
+ if (this.plan.kind === 'moving' && this.plan.direction === 'closing') {
242
+ this.emitSnapshot('close-request-already-closing');
243
+ return;
244
+ }
245
+ await this.startCloseSeek(0, 'homekit-close-from-openish');
246
+ }
247
+ async startOpeningFromClosed(reason) {
248
+ if (this.facts.closedSensor !== true) {
249
+ this.requestedTarget = null;
250
+ this.emitSnapshot(`${reason}-already-openish`);
251
+ return;
252
+ }
253
+ await this.pulseMotor(reason);
254
+ this.startOpeningMotion('homekit', `${reason}-pulse-sent`);
255
+ }
256
+ async startCloseSeek(attempt, reason) {
257
+ if (this.facts.closedSensor === true) {
258
+ this.requestedTarget = null;
259
+ this.emitSnapshot(`${reason}-already-closed`);
260
+ return;
261
+ }
262
+ await this.pulseMotor(`${reason}-attempt-${attempt + 1}`);
263
+ this.startClosingMotion('goalOnly', attempt === 0 ? 'homekit' : 'recovery', attempt, `${reason}-pulse-sent`);
264
+ }
265
+ async reverseKnownMotion(finalDirection, reason) {
266
+ await this.pulseMotor(`${reason}-stop-current-motion`);
267
+ const deadlineAt = Date.now() + this.pulseGapMs + this.travelMs;
268
+ this.clearMovementTimer();
269
+ this.plan = {
270
+ kind: 'waitingSecondPulse',
271
+ finalDirection,
272
+ source: 'homekit',
273
+ attempt: 0,
274
+ dueAt: Date.now() + this.pulseGapMs,
275
+ deadlineAt,
276
+ reason: finalDirection === 'opening' ? 'reverseToOpen' : 'reverseToClose',
277
+ };
278
+ this.schedulePhaseTimer(this.plan.dueAt);
279
+ this.emitSnapshot(`${reason}-waiting-second-pulse`);
280
+ }
281
+ startOpeningMotion(source, note) {
282
+ this.clearPhaseTimer();
283
+ this.plan = {
284
+ kind: 'moving',
285
+ direction: 'opening',
286
+ certainty: 'known',
287
+ source,
288
+ attempt: 0,
289
+ startedAt: Date.now(),
290
+ deadlineAt: Date.now() + this.travelMs,
291
+ };
292
+ this.scheduleMovementTimer(this.plan.deadlineAt);
293
+ this.emitSnapshot(note);
294
+ }
295
+ startClosingMotion(certainty, source, attempt, note) {
296
+ this.clearPhaseTimer();
297
+ this.plan = {
298
+ kind: 'moving',
299
+ direction: 'closing',
300
+ certainty,
301
+ source,
302
+ attempt,
303
+ startedAt: Date.now(),
304
+ deadlineAt: Date.now() + this.travelMs,
305
+ };
306
+ this.scheduleMovementTimer(this.plan.deadlineAt);
307
+ this.emitSnapshot(note);
308
+ }
309
+ scheduleMovementTimer(deadlineAt) {
310
+ this.clearMovementTimer();
311
+ const delayMs = Math.max(0, deadlineAt - Date.now());
312
+ const token = ++this.movementTimerToken;
313
+ this.movementTimer = setTimeout(() => {
314
+ void this.enqueue(`movement-timeout-${token}`, async () => {
315
+ if (token !== this.movementTimerToken) {
316
+ return;
317
+ }
318
+ await this.handleMovementTimeout();
319
+ });
320
+ }, delayMs);
321
+ }
322
+ schedulePhaseTimer(dueAt) {
323
+ this.clearPhaseTimer();
324
+ const delayMs = Math.max(0, dueAt - Date.now());
325
+ const token = ++this.phaseTimerToken;
326
+ this.phaseTimer = setTimeout(() => {
327
+ void this.enqueue(`phase-timer-${token}`, async () => {
328
+ if (token !== this.phaseTimerToken) {
329
+ return;
330
+ }
331
+ await this.handlePhaseTimer();
332
+ });
333
+ }, delayMs);
334
+ }
335
+ clearMovementTimer() {
336
+ if (this.movementTimer) {
337
+ clearTimeout(this.movementTimer);
338
+ this.movementTimer = undefined;
339
+ }
340
+ this.movementTimerToken += 1;
341
+ }
342
+ clearPhaseTimer() {
343
+ if (this.phaseTimer) {
344
+ clearTimeout(this.phaseTimer);
345
+ this.phaseTimer = undefined;
346
+ }
347
+ this.phaseTimerToken += 1;
348
+ }
349
+ clearTimers() {
350
+ this.clearMovementTimer();
351
+ this.clearPhaseTimer();
352
+ }
353
+ async handlePhaseTimer() {
354
+ if (this.plan.kind !== 'waitingSecondPulse') {
355
+ return;
356
+ }
357
+ const finalDirection = this.plan.finalDirection;
358
+ const source = this.plan.source;
359
+ const attempt = this.plan.attempt;
360
+ const deadlineAt = this.plan.deadlineAt;
361
+ await this.pulseMotor(`second-pulse-${finalDirection}`);
362
+ this.clearPhaseTimer();
363
+ this.plan = {
364
+ kind: 'moving',
365
+ direction: finalDirection,
366
+ certainty: 'known',
367
+ source,
368
+ attempt,
369
+ startedAt: Date.now(),
370
+ deadlineAt,
371
+ };
372
+ this.scheduleMovementTimer(deadlineAt);
373
+ this.emitSnapshot(`second-pulse-fired-${finalDirection}`);
374
+ }
375
+ async handleMovementTimeout() {
376
+ if (this.plan.kind !== 'moving') {
377
+ return;
378
+ }
379
+ if (this.facts.closedSensor === true) {
380
+ this.clearTimers();
381
+ this.plan = { kind: 'idle' };
382
+ this.requestedTarget = null;
383
+ this.emitSnapshot('movement-timeout-but-already-closed');
384
+ return;
385
+ }
386
+ if (this.plan.direction === 'opening') {
387
+ // Fully-open and partially-open look the same to us. When the opening
388
+ // window expires we intentionally collapse to the generic open-ish state,
389
+ // which the Home app will still display as "Opening" per the requested UX.
390
+ this.clearTimers();
391
+ this.plan = { kind: 'idle' };
392
+ this.requestedTarget = null;
393
+ this.emitSnapshot('opening-window-elapsed-openish');
394
+ return;
395
+ }
396
+ if (this.requestedTarget === 'closed' && this.plan.attempt < this.closeRetryLimit) {
397
+ const nextAttempt = this.plan.attempt + 1;
398
+ this.io.log.warn('close window elapsed without a closed-sensor hit; retrying close seek from the generic open-ish state');
399
+ this.clearTimers();
400
+ this.plan = { kind: 'idle' };
401
+ await this.startCloseSeek(nextAttempt, 'close-timeout-retry');
402
+ return;
403
+ }
404
+ this.io.log.warn('close window elapsed without reaching the closed sensor; leaving gate in open-ish state');
405
+ this.clearTimers();
406
+ this.plan = { kind: 'idle' };
407
+ this.requestedTarget = null;
408
+ this.emitSnapshot('closing-window-elapsed-openish');
409
+ }
410
+ enterUnavailable(note) {
411
+ this.clearTimers();
412
+ this.plan = { kind: 'idle' };
413
+ this.requestedTarget = null;
414
+ this.sensorFreshSinceOnline = false;
415
+ this.emitSnapshot(note);
416
+ }
417
+ isAvailableForHomeKit() {
418
+ return this.facts.controlConnected === true
419
+ && this.facts.sensorConnected === true
420
+ && this.sensorFreshSinceOnline
421
+ && this.facts.closedSensor !== null;
422
+ }
423
+ async pulseMotor(reason) {
424
+ const elapsed = Date.now() - this.lastPulseLikeActivityAt;
425
+ if (elapsed < this.pulseGapMs) {
426
+ await delay(this.pulseGapMs - elapsed);
427
+ }
428
+ this.io.log.info(`motor pulse -> ${reason}`);
429
+ await this.io.pulseMotor(reason);
430
+ this.lastPulseLikeActivityAt = Date.now();
431
+ }
432
+ emitSnapshot(note) {
433
+ if (this.disposed) {
434
+ return;
435
+ }
436
+ this.io.publishSnapshot(this.buildSnapshot(note));
437
+ }
438
+ buildSnapshot(note) {
439
+ const available = this.isAvailableForHomeKit();
440
+ return {
441
+ available,
442
+ controlConnected: this.facts.controlConnected,
443
+ sensorConnected: this.facts.sensorConnected,
444
+ closedSensor: this.facts.closedSensor,
445
+ sensorFreshSinceOnline: this.sensorFreshSinceOnline,
446
+ currentDoorState: available ? this.computeCurrentDoorState() : undefined,
447
+ targetDoorState: available ? this.computeTargetDoorState() : undefined,
448
+ requestedTarget: this.requestedTarget,
449
+ motionDirection: this.getMotionDirection(),
450
+ motionCertainty: this.getMotionCertainty(),
451
+ planKind: this.plan.kind,
452
+ note,
453
+ };
454
+ }
455
+ getMotionDirection() {
456
+ if (this.plan.kind === 'moving') {
457
+ return this.plan.direction;
458
+ }
459
+ if (this.plan.kind === 'waitingSecondPulse') {
460
+ return this.plan.finalDirection;
461
+ }
462
+ return 'none';
463
+ }
464
+ getMotionCertainty() {
465
+ if (this.plan.kind === 'moving') {
466
+ return this.plan.certainty;
467
+ }
468
+ if (this.plan.kind === 'waitingSecondPulse') {
469
+ return 'known';
470
+ }
471
+ return 'none';
472
+ }
473
+ computeCurrentDoorState() {
474
+ if (this.plan.kind === 'moving') {
475
+ return this.plan.direction === 'closing' ? 3 /* DoorCurrentState.CLOSING */ : 2 /* DoorCurrentState.OPENING */;
476
+ }
477
+ if (this.plan.kind === 'waitingSecondPulse') {
478
+ return this.plan.finalDirection === 'closing' ? 3 /* DoorCurrentState.CLOSING */ : 2 /* DoorCurrentState.OPENING */;
479
+ }
480
+ return this.facts.closedSensor ? 1 /* DoorCurrentState.CLOSED */ : 2 /* DoorCurrentState.OPENING */;
481
+ }
482
+ computeTargetDoorState() {
483
+ if (this.requestedTarget) {
484
+ return this.requestedTarget === 'closed' ? 1 /* DoorTargetState.CLOSED */ : 0 /* DoorTargetState.OPEN */;
485
+ }
486
+ if (this.plan.kind === 'moving') {
487
+ return this.plan.direction === 'closing' ? 1 /* DoorTargetState.CLOSED */ : 0 /* DoorTargetState.OPEN */;
488
+ }
489
+ if (this.plan.kind === 'waitingSecondPulse') {
490
+ return this.plan.finalDirection === 'closing' ? 1 /* DoorTargetState.CLOSED */ : 0 /* DoorTargetState.OPEN */;
491
+ }
492
+ return this.facts.closedSensor ? 1 /* DoorTargetState.CLOSED */ : 0 /* DoorTargetState.OPEN */;
493
+ }
494
+ }
495
+ exports.FrontGateFsm = FrontGateFsm;
496
+ //# sourceMappingURL=FrontGateFsm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FrontGateFsm.js","sourceRoot":"","sources":["../../src/Accesories/FrontGateFsm.ts"],"names":[],"mappings":"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"}
@@ -5,64 +5,25 @@ export declare class GateAccessory {
5
5
  private readonly platform;
6
6
  private readonly accessory;
7
7
  private readonly context;
8
- private service;
9
- private currentState;
10
- private targetState;
11
- private connected;
12
- private obstructionDetected;
13
- private isClosedSensorActive;
14
- private isPartialSensorActive;
15
- private hasClosedSensorState;
16
- private hasPartialSensorState;
17
- private pendingTarget?;
18
- private transitionTimer?;
19
- private readonly transitionTimeoutMs;
20
- private readonly partialHiMode;
21
- private readonly baseTopic;
22
- private reverseToggleTimer?;
23
- private readonly reverseToggleDelayMs;
24
- private openArrivalDebounceTimer?;
25
- private readonly openArrivalDebounceMs;
26
- private lastCommandTarget?;
27
- private lastCommandAt;
28
- private readonly duplicateSetWindowMs;
29
- private sawPartialMotionDuringPending;
30
- private lastClosedReleaseAt;
31
- private readonly externalDirectionHintWindowMs;
8
+ private readonly service;
9
+ private readonly controlBaseTopic;
10
+ private readonly sensorBaseTopic;
11
+ private readonly fsm;
32
12
  constructor(platform: SuplaPlatform, accessory: PlatformAccessory, context: SuplaChannelContext);
33
13
  handleCurrentDoorStateGet(): Promise<CharacteristicValue>;
34
14
  handleTargetDoorStateGet(): Promise<CharacteristicValue>;
35
15
  handleTargetDoorStateSet(value: CharacteristicValue): Promise<void>;
36
16
  handleObstructionDetectedGet(): Promise<CharacteristicValue>;
37
- private updateStatesFromSensors;
38
- private isAtTarget;
39
- private applyDoorState;
40
- private setCurrentState;
41
- private setTargetState;
42
- private isKnownNotClosed;
43
- private updateStatusFault;
44
- private clearFaults;
45
- private armTransitionTimer;
46
- private clearTransitionTimer;
47
- private clearReverseToggleTimer;
48
- private clearOpenArrivalDebounceTimer;
49
- private touchTransitionTimer;
50
- private resolveMovingState;
51
- private getMotionTarget;
52
- private isOpenArrivalSignal;
53
- private shouldDebounceOpenArrival;
54
- private scheduleOpenArrivalDebounce;
55
- private resolveTerminalStateFromSensors;
56
- private oppositeTarget;
57
- private markCommand;
58
- private setPendingTarget;
59
- private isLikelyDuplicateSet;
60
- private publishGateAction;
61
- private scheduleReverseToggle;
62
- private shouldScheduleReverseFollowUp;
63
- private isOpenCloseExecuteActionPair;
64
- private shouldPublishExecuteActionReverseFollowUp;
65
- private resolveExternalMotionTarget;
66
- private wasClosedReleasedRecently;
17
+ private applySnapshot;
18
+ private createCommunicationError;
19
+ private publishPulse;
20
+ private resolveSensorBaseTopic;
21
+ private resolveSensorOverrideFromConfig;
22
+ private findSensorCandidates;
23
+ private scoreSensorCandidate;
24
+ private computeCaptionSimilarity;
25
+ private tokenizeCaption;
26
+ private normalizeOptionalId;
27
+ private collectKnownChannels;
67
28
  }
68
29
  //# sourceMappingURL=GateAccessory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GateAccessory.d.ts","sourceRoot":"","sources":["../../src/Accesories/GateAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAQrE,qBAAa,aAAa;IA2BtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IA5B1B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,YAAY,CAAwD;IAC5E,OAAO,CAAC,WAAW,CAAuD;IAC1E,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,qBAAqB,CAAS;IACtC,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,qBAAqB,CAAS;IACtC,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,eAAe,CAAC,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,kBAAkB,CAAC,CAAiB;IAC5C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,wBAAwB,CAAC,CAAiB;IAClD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAO;IAC7C,OAAO,CAAC,iBAAiB,CAAC,CAAS;IACnC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAO;IAC5C,OAAO,CAAC,6BAA6B,CAAS;IAC9C,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,QAAQ,CAAC,6BAA6B,CAAQ;gBAGnC,QAAQ,EAAE,aAAa,EACvB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,mBAAmB;IA6FzC,yBAAyB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAIzD,wBAAwB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAIxD,wBAAwB,CAAC,KAAK,EAAE,mBAAmB;IAyDnD,4BAA4B,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAIlE,OAAO,CAAC,uBAAuB;IAqE/B,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,kBAAkB;IA2B1B,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,uBAAuB;IAO/B,OAAO,CAAC,6BAA6B;IAOrC,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,mBAAmB;IAqB3B,OAAO,CAAC,yBAAyB;IAMjC,OAAO,CAAC,2BAA2B;IAyBnC,OAAO,CAAC,+BAA+B;IAiBvC,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,qBAAqB;IAqB7B,OAAO,CAAC,6BAA6B;IAOrC,OAAO,CAAC,4BAA4B;IAMpC,OAAO,CAAC,yCAAyC;IAUjD,OAAO,CAAC,2BAA2B;IAsCnC,OAAO,CAAC,yBAAyB;CAMlC"}
1
+ {"version":3,"file":"GateAccessory.d.ts","sourceRoot":"","sources":["../../src/Accesories/GateAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAqBrE,qBAAa,aAAa;IAOtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAR1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAGhB,QAAQ,EAAE,aAAa,EACvB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,mBAAmB;IA4EzC,yBAAyB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAQzD,wBAAwB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAQxD,wBAAwB,CAAC,KAAK,EAAE,mBAAmB;IAWnD,4BAA4B,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAIlE,OAAO,CAAC,aAAa;IA4BrB,OAAO,CAAC,wBAAwB;YAIlB,YAAY;IAmB1B,OAAO,CAAC,sBAAsB;IA0B9B,OAAO,CAAC,+BAA+B;IAiCvC,OAAO,CAAC,oBAAoB;IA0B5B,OAAO,CAAC,oBAAoB;IAwD5B,OAAO,CAAC,wBAAwB;IAuBhC,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,oBAAoB;CA+C7B"}