homebridge-valor-fireplace 2.0.4 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.1.0] - 2026-05-17
4
+
5
+ ### Added
6
+ - **Ignition lockout circuit breaker with auto-retry.** When `igniteFireplace()` runs, it now sends the Ignite command and observes the receiver's own ignition cycle to completion. Three outcome classes are distinguished:
7
+ - **success**: `guardFlameOn` confirmed → exit, clear failure history.
8
+ - **soft-fail**: `igniting` cleared back to 0 but no flame caught (cold pilot, air in line — common cold-start case) → retry after delay.
9
+ - **hard-fail**: `igniting` bit stuck past timeout → Mertik GV60 safety lockout → stop the sequence, require manual reset (paperclip, cycle gas, or service).
10
+
11
+ Default: 4 attempts, 90s timeout per attempt, 3 min between retries. Each attempt logs as `[ignite] Attempt N of M` with explicit outcomes — makes postmortem of "did the fireplace try and fail?" trivial. Off requests mid-sequence abort the loop cleanly.
12
+ - **Persistent ignition history** at `<storagePath>/valor-ignition-history.json` via new `IgnitionTracker` class. Records every attempt with timestamps, outcomes, durations, and final status bits. Survives plugin restarts and homebridge log rotations — the previous all-in-memory state lost every diagnostic the moment the log rotated.
13
+ - **Six newly-decoded status packet fields** on `FireplaceStatus`, in parity with `valor-fireplace-cli` 1.1.0:
14
+ - `burnerOutput` (chars 14-15) — current burner output 0-255, continuous.
15
+ - `lightBrightness` (chars 20-21) — decorative light dimmer setpoint 0-255 (persists across off).
16
+ - `fanSpeed` (chars 22-23) — circulating fan speed 0-4.
17
+ - `scheduleActive` (status bit 9) — schedule/timer overlay flag.
18
+ - `lightOn` (status bit 13) — decorative light power.
19
+ - `statusBitsHex` — raw 4-char hex of the status bit field.
20
+ - **Derived signals** on `FireplaceStatus`:
21
+ - `lockoutSuspected` — heuristic candidate for hard lockout.
22
+ - `pilotOnly` — `guardFlameOn && burnerOutput === 0`.
23
+ - **`isLockoutActive()` on `IFireplaceController`.** Public method exposing whether the controller is in a confirmed hard-lockout state, for future code wiring up a HomeKit `StatusFault` characteristic.
24
+ - **`'lockout'` event** emitted on the controller for fault-state subscribers. Fires `true` when a hard lockout is detected, `false` when it clears.
25
+
26
+ ### Changed
27
+ - **Lockout state gates non-Off commands** but lets shutdowns through. When a hard lockout is in effect from a prior session, `request()` blocks ignite/mode/temp requests with a clear warning. An Off request is always allowed (does no harm, may help reconcile state).
28
+ - **`processStatusResponse`** no longer auto-shuts-off during the `lostConnection` recovery path while a hard lockout is active — the gas is already off and the receiver is in fault state, so a shutdown command would just generate log noise.
29
+
3
30
  ## [2.0.1] - 2026-01-11
4
31
 
5
32
  ### Fixed
@@ -11,10 +11,25 @@ export interface IFireplaceController extends EventEmitter {
11
11
  getFlameHeight(): FlameHeight;
12
12
  reachable(): boolean;
13
13
  setTemperature(temperature: number): void;
14
+ /**
15
+ * True when a confirmed Mertik GV60 hard-lockout state is in effect
16
+ * (last terminated attempt was a hard-fail with no subsequent success).
17
+ * Future code can wire this to a HomeKit `StatusFault` characteristic.
18
+ */
19
+ isLockoutActive(): boolean;
14
20
  }
15
21
  export interface IFireplaceEvents {
16
22
  on(event: 'status', listener: (status: FireplaceStatus) => void): this;
17
23
  on(event: 'reachable', listener: (reachable: boolean) => void): this;
24
+ on(event: 'lockout', listener: (active: boolean) => void): this;
25
+ /**
26
+ * Fired when `guardFlameOff()` hits its ceiling without seeing
27
+ * `guardFlameOn` clear. The `elapsedMs` argument is the actual wall time
28
+ * spent waiting. Subscribers (HomeKit fault surface, log audit) can use
29
+ * this to flag a partial shutdown rather than blindly trusting the
30
+ * fixed delay that the older implementation used.
31
+ */
32
+ on(event: 'shutdownTimeout', listener: (elapsedMs: number) => void): this;
18
33
  }
19
34
  export declare class FireplaceController extends EventEmitter implements IFireplaceController, IFireplaceEvents {
20
35
  readonly log: Logger;
@@ -29,17 +44,128 @@ export declare class FireplaceController extends EventEmitter implements IFirepl
29
44
  private igniting;
30
45
  private shuttingDown;
31
46
  private lostConnection;
47
+ /**
48
+ * Set when a user request (typically Off) wants to interrupt the auto-retry
49
+ * loop. The loop polls this between attempts and bails out gracefully.
50
+ */
51
+ private ignitionAbortRequested;
52
+ /**
53
+ * Tracks attempt outcomes and persists history across plugin restarts.
54
+ * Provides the `consecutiveFailures` / `hasRecentHardLockout` signals
55
+ * used by the circuit breaker below.
56
+ */
57
+ private readonly ignitionTracker;
32
58
  private static UNREACHABLE_TIMEOUT;
33
59
  private static REFRESH_TIMEOUT;
34
60
  private static STATUS_PACKET_LENGTH;
61
+ /**
62
+ * How often we poll status while waiting for an Ignite to resolve.
63
+ * Tighter than the normal 15s subscription because we want to catch
64
+ * the igniting=1 → 0 transition quickly.
65
+ */
66
+ private static IGNITE_POLL_INTERVAL_MS;
67
+ /**
68
+ * How long to wait for a status response after issuing a poll command
69
+ * inside a transition wait. Must be longer than the normal round-trip
70
+ * but short enough that a missed response just causes the next poll to
71
+ * retry. 5s mirrors the CLI's `STATUS_RESPONSE_TIMEOUT`.
72
+ */
73
+ private static STATUS_RESPONSE_TIMEOUT_MS;
74
+ /**
75
+ * Shutdown ceiling. Empirically a real shutdown observed at the cabin
76
+ * (2026-05-17) took 26s — comfortably under this ceiling, but the
77
+ * previous 30s blind delay was only 4s of headroom. 45s gives the gas
78
+ * valve, pilot millivolts decay, and thermopile latch release plenty of
79
+ * room without leaving HomeKit hanging.
80
+ */
81
+ private static SHUTDOWN_CEILING_MS;
82
+ /**
83
+ * Poll cadence inside the shutdown wait. 2s is fine-grained enough to
84
+ * catch the `guardFlameOn` clear within ~2s of the actual event.
85
+ */
86
+ private static SHUTDOWN_POLL_INTERVAL_MS;
87
+ /**
88
+ * Hard safety cap on the thermostat setpoint, in Celsius. Mirrors the
89
+ * HomeKit `setProps` cap in `serviceController` — duplicated here as a
90
+ * defense against any code path (cached HomeKit state, restored
91
+ * accessory state, future internal callers) that bypasses the slider's
92
+ * advertised maxValue. 26.5°C ≈ 79.7°F.
93
+ */
94
+ private static MAX_SAFE_TARGET_C;
35
95
  constructor(log: Logger, accessory: PlatformAccessory, platform?: ValorPlatform | undefined);
36
96
  private startStatusSubscription;
37
97
  private stopStatusSubscription;
38
98
  private refreshStatus;
39
99
  private processStatusResponse;
100
+ /**
101
+ * True when the most recent terminated attempt was a hard lockout
102
+ * (igniting bit stuck past timeout). External callers (HomeKit fault
103
+ * surface, status reporting) can use this to render fault state.
104
+ */
105
+ isLockoutActive(): boolean;
106
+ /**
107
+ * Ignite the fireplace, retrying up to `IgnitionTracker.MAX_ATTEMPTS`
108
+ * times. Each attempt sends the Ignite command, waits for the receiver's
109
+ * own ignition cycle to resolve, and either declares success
110
+ * (`guardFlameOn` confirmed), a soft failure (receiver cleanly gave up —
111
+ * `igniting` cleared but no flame), or a hard lockout (`igniting` bit
112
+ * stuck past `IGNITION_TIMEOUT_MS` — receiver is in safety fault and
113
+ * needs manual reset).
114
+ *
115
+ * Logs each attempt as `[ignite] Attempt N of M` so the failure pattern
116
+ * is visible in `homebridge.log` after the fact. Persists every outcome
117
+ * to `<storagePath>/valor-ignition-history.json` for postmortem use even
118
+ * if the homebridge log rotates.
119
+ */
40
120
  private igniteFireplace;
121
+ /**
122
+ * Poll status during an Ignite attempt and decide its outcome.
123
+ *
124
+ * Returns:
125
+ * - `'success'`: `guardFlameOn` came up — pilot caught.
126
+ * - `'soft-fail'`: `igniting` cleared back to 0 but no flame. Receiver
127
+ * gave up cleanly. Worth retrying.
128
+ * - `'hard-fail'`: `IGNITION_TIMEOUT_MS` elapsed with `igniting` still
129
+ * set. Receiver is locked out; only manual reset clears this.
130
+ */
131
+ private waitForIgnitionOutcome;
132
+ /**
133
+ * Like `delay()` but bails out early if `ignitionAbortRequested` becomes
134
+ * true. Returns true if it was interrupted, false on normal completion.
135
+ */
136
+ private delayWithAbort;
41
137
  private standBy;
138
+ /**
139
+ * Send the GuardFlame Off command and wait — by polling status, not a
140
+ * blind delay — until the receiver confirms `guardFlameOn` is clear.
141
+ *
142
+ * Returns `true` on confirmed shutdown, `false` if we hit the
143
+ * `SHUTDOWN_CEILING_MS` ceiling without confirmation. On timeout,
144
+ * emits `'shutdownTimeout'` with the elapsed wall time so HomeKit and
145
+ * log subscribers can react instead of trusting a stale assumption.
146
+ *
147
+ * Ported from `valor-fireplace-cli` v1.1.1 (`waitForTransition`). The
148
+ * older 30s blind delay observed only ~4s of headroom on a real 26s
149
+ * shutdown — slightly slower cycles would miss without anyone noticing.
150
+ */
42
151
  private guardFlameOff;
152
+ /**
153
+ * Wait for the next `status` event with a timeout. Subscribes
154
+ * synchronously (via `this.once`) before returning, so callers can do
155
+ *
156
+ * const responsePromise = this.waitForNextStatus(timeoutMs);
157
+ * this.sendCommand('303303');
158
+ * const s = await responsePromise;
159
+ *
160
+ * without racing the response. If no event arrives in `timeoutMs`,
161
+ * resolves with the current `lastStatus` (which may be stale or
162
+ * undefined) — the caller decides what to do with stale data.
163
+ *
164
+ * Ported from `valor-fireplace-cli` v1.1.0 — replaces a fixed 500ms
165
+ * delay that risked reading stale `lastStatus` under slow network
166
+ * conditions.
167
+ */
168
+ private waitForNextStatus;
43
169
  private setEcoMode;
44
170
  private setManualMode;
45
171
  private setTemperatureMode;
@@ -1 +1 @@
1
- {"version":3,"file":"fireplaceController.d.ts","sourceRoot":"","sources":["../../src/controllers/fireplaceController.ts"],"names":[],"mappings":";AACA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAoB,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD,OAAO,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,IAAI,eAAe,GAAG,SAAS,CAAC;IACtC,cAAc,IAAI,WAAW,CAAC;IAC9B,SAAS,IAAI,OAAO,CAAC;IACrB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI,CAAC;IACvE,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;CACtE;AAED,qBAAa,mBAAoB,SAAQ,YAAa,YAAW,oBAAoB,EAAE,gBAAgB;aAenF,GAAG,EAAE,MAAM;aACX,SAAS,EAAE,iBAAiB;aAC5B,QAAQ,CAAC;IAhB3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAiB;IACnD,OAAO,CAAC,MAAM,CAAC,eAAe,CAAa;IAC3C,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAO;gBAGxB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,iBAAiB,EAC5B,QAAQ,CAAC,2BAAe;IAO1C,OAAO,CAAC,uBAAuB;IAO/B,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,qBAAqB;YAaf,eAAe;YAWf,OAAO;YAOP,aAAa;IAW3B,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,YAAY;IAyBpB,OAAO,CAAC,WAAW;IAOnB,SAAS,IAAI,OAAO;IAMpB,MAAM,IAAI,eAAe,GAAG,SAAS;IAIrC,KAAK,gCAAiD;IAEtD,gBAAgB,IAAI,IAAI;IAKlB,cAAc,CAAC,WAAW,EAAE,MAAM;IAajC,cAAc,IAAI,WAAW;IAIvB,cAAc,CAAC,WAAW,EAAE,MAAM;YAsBjC,mBAAmB;IAO3B,OAAO,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAqClD,MAAM,CAAC,EAAE,EAAE,OAAO;IAKZ,OAAO,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;CAgCnD"}
1
+ {"version":3,"file":"fireplaceController.d.ts","sourceRoot":"","sources":["../../src/controllers/fireplaceController.ts"],"names":[],"mappings":"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"}
@@ -10,8 +10,10 @@ const fireplaceStatus_1 = require("../models/fireplaceStatus");
10
10
  const operationMode_1 = require("../models/operationMode");
11
11
  const flameHeight_1 = require("../models/flameHeight");
12
12
  const temperatureRange_1 = require("../models/temperatureRange");
13
+ const ignitionTracker_1 = require("./ignitionTracker");
13
14
  class FireplaceController extends events_1.default {
14
15
  constructor(log, accessory, platform) {
16
+ var _a, _b, _c, _d;
15
17
  super();
16
18
  this.log = log;
17
19
  this.accessory = accessory;
@@ -22,8 +24,15 @@ class FireplaceController extends events_1.default {
22
24
  this.igniting = false;
23
25
  this.shuttingDown = false;
24
26
  this.lostConnection = false;
27
+ /**
28
+ * Set when a user request (typically Off) wants to interrupt the auto-retry
29
+ * loop. The loop polls this between attempts and bails out gracefully.
30
+ */
31
+ this.ignitionAbortRequested = false;
25
32
  this.delay = ms => new Promise(res => setTimeout(res, ms));
26
33
  this.config = this.accessory.context.device;
34
+ const storagePath = (_d = (_c = (_b = (_a = this.platform) === null || _a === void 0 ? void 0 : _a.api) === null || _b === void 0 ? void 0 : _b.user) === null || _c === void 0 ? void 0 : _c.storagePath) === null || _d === void 0 ? void 0 : _d.call(_c);
35
+ this.ignitionTracker = new ignitionTracker_1.IgnitionTracker(this.log, storagePath);
27
36
  this.startStatusSubscription();
28
37
  }
29
38
  startStatusSubscription() {
@@ -68,15 +77,150 @@ class FireplaceController extends events_1.default {
68
77
  this.guardFlameOff();
69
78
  }
70
79
  }
80
+ /**
81
+ * True when the most recent terminated attempt was a hard lockout
82
+ * (igniting bit stuck past timeout). External callers (HomeKit fault
83
+ * surface, status reporting) can use this to render fault state.
84
+ */
85
+ isLockoutActive() {
86
+ return this.ignitionTracker.hasRecentHardLockout();
87
+ }
88
+ /**
89
+ * Ignite the fireplace, retrying up to `IgnitionTracker.MAX_ATTEMPTS`
90
+ * times. Each attempt sends the Ignite command, waits for the receiver's
91
+ * own ignition cycle to resolve, and either declares success
92
+ * (`guardFlameOn` confirmed), a soft failure (receiver cleanly gave up —
93
+ * `igniting` cleared but no flame), or a hard lockout (`igniting` bit
94
+ * stuck past `IGNITION_TIMEOUT_MS` — receiver is in safety fault and
95
+ * needs manual reset).
96
+ *
97
+ * Logs each attempt as `[ignite] Attempt N of M` so the failure pattern
98
+ * is visible in `homebridge.log` after the fact. Persists every outcome
99
+ * to `<storagePath>/valor-ignition-history.json` for postmortem use even
100
+ * if the homebridge log rotates.
101
+ */
71
102
  async igniteFireplace() {
103
+ var _a, _b;
72
104
  if (this.igniting) {
73
105
  this.log.debug('Ignore already igniting!');
74
- return;
106
+ return false;
75
107
  }
108
+ if (this.ignitionTracker.hasRecentHardLockout()) {
109
+ this.log.error('[ignite] Refusing to attempt — prior session ended in hard lockout. ' +
110
+ 'Manual intervention required (cycle gas at the wall, paperclip-reset the WiFi module, ' +
111
+ 'or retry ignition from the handheld). Restart homebridge after recovery to clear this state.');
112
+ return false;
113
+ }
114
+ this.ignitionAbortRequested = false;
76
115
  this.igniting = true;
77
- this.sendCommand('314103');
78
- await this.delay(40000);
79
- this.refreshStatus();
116
+ const max = ignitionTracker_1.IgnitionTracker.MAX_ATTEMPTS;
117
+ try {
118
+ for (let attempt = 1; attempt <= max; attempt++) {
119
+ if (this.ignitionAbortRequested) {
120
+ this.log.info(`[ignite] Attempt sequence aborted by user request before attempt ${attempt} of ${max}`);
121
+ return false;
122
+ }
123
+ this.log.info(`[ignite] Attempt ${attempt} of ${max}: sending Ignite command`);
124
+ const record = this.ignitionTracker.recordAttemptStart(attempt, max, 'auto-retry');
125
+ const startedAt = Date.now();
126
+ this.sendCommand('314103');
127
+ const outcome = await this.waitForIgnitionOutcome(attempt, max);
128
+ const elapsedMs = Date.now() - startedAt;
129
+ const bits = (_b = (_a = this.lastStatus) === null || _a === void 0 ? void 0 : _a.statusBitsHex) !== null && _b !== void 0 ? _b : '????';
130
+ if (outcome === 'success') {
131
+ this.ignitionTracker.recordSuccess(elapsedMs, bits);
132
+ this.log.info(`[ignite] Attempt ${attempt} of ${max}: ✓ success after ${Math.round(elapsedMs / 1000)}s ` +
133
+ `(attempt id=${record.id}, bits=0x${bits})`);
134
+ this.emit('lockout', false);
135
+ return true;
136
+ }
137
+ if (outcome === 'soft-fail') {
138
+ this.ignitionTracker.recordSoftFailure(elapsedMs, bits);
139
+ this.log.warn(`[ignite] Attempt ${attempt} of ${max}: ✗ soft-fail after ${Math.round(elapsedMs / 1000)}s — ` +
140
+ `receiver gave up cleanly (bits=0x${bits}). Common on cold starts.`);
141
+ }
142
+ else {
143
+ this.ignitionTracker.recordHardLockout(elapsedMs, bits);
144
+ this.log.error(`[ignite] Attempt ${attempt} of ${max}: ✗ HARD LOCKOUT — igniting bit stuck after ` +
145
+ `${Math.round(elapsedMs / 1000)}s (bits=0x${bits}). Stopping retry sequence; manual reset required.`);
146
+ this.emit('lockout', true);
147
+ return false;
148
+ }
149
+ if (attempt < max) {
150
+ const delaySec = Math.round(ignitionTracker_1.IgnitionTracker.RETRY_DELAY_MS / 1000);
151
+ this.log.info(`[ignite] Waiting ${delaySec}s before attempt ${attempt + 1} of ${max}`);
152
+ const aborted = await this.delayWithAbort(ignitionTracker_1.IgnitionTracker.RETRY_DELAY_MS);
153
+ if (aborted) {
154
+ this.log.info('[ignite] Retry wait interrupted by user request — aborting sequence');
155
+ return false;
156
+ }
157
+ }
158
+ }
159
+ this.log.error(`[ignite] All ${max} attempts failed (no hard lockout but pilot never caught). ` +
160
+ 'Likely needs manual intervention: check gas pressure, pilot orifice, thermopile, or spark electrode.');
161
+ this.emit('lockout', true);
162
+ return false;
163
+ }
164
+ finally {
165
+ this.igniting = false;
166
+ }
167
+ }
168
+ /**
169
+ * Poll status during an Ignite attempt and decide its outcome.
170
+ *
171
+ * Returns:
172
+ * - `'success'`: `guardFlameOn` came up — pilot caught.
173
+ * - `'soft-fail'`: `igniting` cleared back to 0 but no flame. Receiver
174
+ * gave up cleanly. Worth retrying.
175
+ * - `'hard-fail'`: `IGNITION_TIMEOUT_MS` elapsed with `igniting` still
176
+ * set. Receiver is locked out; only manual reset clears this.
177
+ */
178
+ async waitForIgnitionOutcome(attempt, max) {
179
+ const start = Date.now();
180
+ const timeoutMs = ignitionTracker_1.IgnitionTracker.IGNITION_TIMEOUT_MS;
181
+ while (Date.now() - start < timeoutMs) {
182
+ await this.delay(FireplaceController.IGNITE_POLL_INTERVAL_MS);
183
+ // Subscribe to the next status event before sending the poll, so we
184
+ // can't race the response. Replaces a fixed 500ms wait that risked
185
+ // reading stale `lastStatus` under slow network conditions.
186
+ const responsePromise = this.waitForNextStatus(FireplaceController.STATUS_RESPONSE_TIMEOUT_MS);
187
+ try {
188
+ this.sendCommand('303303');
189
+ }
190
+ catch (_a) {
191
+ this.log.debug('[ignite] Status request during ignite wait failed (will retry)');
192
+ }
193
+ const s = await responsePromise;
194
+ if (!s)
195
+ continue;
196
+ if (s.guardFlameOn) {
197
+ return 'success';
198
+ }
199
+ if (!s.igniting) {
200
+ // Receiver cleared the igniting bit but never confirmed flame.
201
+ // Classic soft failure — the most common cold-start outcome.
202
+ return 'soft-fail';
203
+ }
204
+ // Promote progress ticks to info so the homebridge log shows the
205
+ // attempt is alive during the 90s ignition window. Otherwise users
206
+ // see an Ignite send and then silence until the outcome lands.
207
+ this.log.info(`[ignite] Attempt ${attempt}/${max}: still igniting at ${Math.round((Date.now() - start) / 1000)}s (bits=0x${s.statusBitsHex})`);
208
+ }
209
+ return 'hard-fail';
210
+ }
211
+ /**
212
+ * Like `delay()` but bails out early if `ignitionAbortRequested` becomes
213
+ * true. Returns true if it was interrupted, false on normal completion.
214
+ */
215
+ async delayWithAbort(ms) {
216
+ const step = 1000;
217
+ const end = Date.now() + ms;
218
+ while (Date.now() < end) {
219
+ if (this.ignitionAbortRequested)
220
+ return true;
221
+ await this.delay(Math.min(step, end - Date.now()));
222
+ }
223
+ return false;
80
224
  }
81
225
  async standBy() {
82
226
  this.log.info('Standby');
@@ -84,15 +228,111 @@ class FireplaceController extends events_1.default {
84
228
  const msg = '3136303003';
85
229
  return this.sendCommand(msg);
86
230
  }
231
+ /**
232
+ * Send the GuardFlame Off command and wait — by polling status, not a
233
+ * blind delay — until the receiver confirms `guardFlameOn` is clear.
234
+ *
235
+ * Returns `true` on confirmed shutdown, `false` if we hit the
236
+ * `SHUTDOWN_CEILING_MS` ceiling without confirmation. On timeout,
237
+ * emits `'shutdownTimeout'` with the elapsed wall time so HomeKit and
238
+ * log subscribers can react instead of trusting a stale assumption.
239
+ *
240
+ * Ported from `valor-fireplace-cli` v1.1.1 (`waitForTransition`). The
241
+ * older 30s blind delay observed only ~4s of headroom on a real 26s
242
+ * shutdown — slightly slower cycles would miss without anyone noticing.
243
+ */
87
244
  async guardFlameOff() {
88
245
  if (this.shuttingDown) {
89
246
  this.log.debug('Ignore already shutting down!');
90
- return;
247
+ return true;
91
248
  }
92
249
  this.log.info('GuardFlame Off');
93
250
  this.shuttingDown = true;
94
- this.sendCommand('313003');
95
- await this.delay(30000);
251
+ let offSent = false;
252
+ try {
253
+ this.sendCommand('313003');
254
+ offSent = true;
255
+ }
256
+ catch (_a) {
257
+ this.log.warn('[shutdown] Initial GuardFlame Off send failed — will retry inside poll loop');
258
+ }
259
+ const start = Date.now();
260
+ const ceilingMs = FireplaceController.SHUTDOWN_CEILING_MS;
261
+ const pollMs = FireplaceController.SHUTDOWN_POLL_INTERVAL_MS;
262
+ // A single poll iteration consumes up to `pollMs + STATUS_RESPONSE_TIMEOUT_MS`
263
+ // of wall time. Refuse to start a new iteration unless we have that much
264
+ // budget remaining — otherwise the stated ceiling is soft by up to 7s
265
+ // and we'd block HomeKit past what the docstring promises.
266
+ const stepBudgetMs = pollMs + FireplaceController.STATUS_RESPONSE_TIMEOUT_MS;
267
+ while (Date.now() - start + stepBudgetMs <= ceilingMs) {
268
+ await this.delay(pollMs);
269
+ // Keep retrying the actual shutdown command until the socket accepts
270
+ // it. The receiver is idempotent for repeat GuardFlame Off sends, so
271
+ // there's no harm in re-sending; the risk we're guarding against is
272
+ // a destroyed socket on the first send silently leaving the flame on
273
+ // for the full ceiling window.
274
+ if (!offSent) {
275
+ try {
276
+ this.sendCommand('313003');
277
+ offSent = true;
278
+ this.log.info('[shutdown] GuardFlame Off command resent after earlier failure');
279
+ }
280
+ catch (_b) {
281
+ this.log.warn('[shutdown] GuardFlame Off send still failing — will retry next tick');
282
+ }
283
+ }
284
+ const responsePromise = this.waitForNextStatus(FireplaceController.STATUS_RESPONSE_TIMEOUT_MS);
285
+ try {
286
+ this.sendCommand('303303');
287
+ }
288
+ catch (_c) {
289
+ this.log.debug('[shutdown] Status poll send failed (will retry next tick)');
290
+ }
291
+ const s = await responsePromise;
292
+ const elapsed = Math.round((Date.now() - start) / 1000);
293
+ if (s && !s.guardFlameOn) {
294
+ this.log.info(`[shutdown] Confirmed off after ${elapsed}s`);
295
+ return true;
296
+ }
297
+ this.log.info(`[shutdown] Waiting for guard flame off at ${elapsed}s`);
298
+ }
299
+ const elapsedMs = Date.now() - start;
300
+ this.log.warn(`[shutdown] Did not confirm off within ${Math.round(ceilingMs / 1000)}s ceiling — ` +
301
+ 'guard flame may still be on. Emitting shutdownTimeout event.');
302
+ this.emit('shutdownTimeout', elapsedMs);
303
+ return false;
304
+ }
305
+ /**
306
+ * Wait for the next `status` event with a timeout. Subscribes
307
+ * synchronously (via `this.once`) before returning, so callers can do
308
+ *
309
+ * const responsePromise = this.waitForNextStatus(timeoutMs);
310
+ * this.sendCommand('303303');
311
+ * const s = await responsePromise;
312
+ *
313
+ * without racing the response. If no event arrives in `timeoutMs`,
314
+ * resolves with the current `lastStatus` (which may be stale or
315
+ * undefined) — the caller decides what to do with stale data.
316
+ *
317
+ * Ported from `valor-fireplace-cli` v1.1.0 — replaces a fixed 500ms
318
+ * delay that risked reading stale `lastStatus` under slow network
319
+ * conditions.
320
+ */
321
+ waitForNextStatus(timeoutMs) {
322
+ return new Promise((resolve) => {
323
+ let resolved = false;
324
+ const finish = (s) => {
325
+ if (resolved)
326
+ return;
327
+ resolved = true;
328
+ clearTimeout(timer);
329
+ this.removeListener('status', handler);
330
+ resolve(s);
331
+ };
332
+ const handler = (s) => finish(s);
333
+ const timer = setTimeout(() => finish(this.lastStatus), timeoutMs);
334
+ this.once('status', handler);
335
+ });
96
336
  }
97
337
  setEcoMode() {
98
338
  return this.sendCommand('4233303103');
@@ -162,6 +402,14 @@ class FireplaceController extends events_1.default {
162
402
  }
163
403
  async setTemperature(temperature) {
164
404
  var _a, _b, _c;
405
+ // Defensive safety cap. The HomeKit slider is already constrained by
406
+ // `setProps` in serviceController, but cached/restored state and
407
+ // internal callers can still hand us higher values.
408
+ if (temperature > FireplaceController.MAX_SAFE_TARGET_C) {
409
+ this.log.warn(`Target temperature ${temperature}°C exceeds safety cap of ` +
410
+ `${FireplaceController.MAX_SAFE_TARGET_C}°C — clamping.`);
411
+ temperature = FireplaceController.MAX_SAFE_TARGET_C;
412
+ }
165
413
  // Log in configured temperature unit
166
414
  const unit = ((_a = this.platform) === null || _a === void 0 ? void 0 : _a.temperatureUnit) || 'C';
167
415
  const displayTemp = unit === 'F' ? Math.round(temperature * 9 / 5 + 32) : temperature;
@@ -187,7 +435,7 @@ class FireplaceController extends events_1.default {
187
435
  await this.delay(1000);
188
436
  }
189
437
  async setMode(request) {
190
- var _a, _b, _c, _d, _e;
438
+ var _a, _b, _c, _d, _e, _f;
191
439
  const mode = request.mode;
192
440
  const currentMode = ((_a = this.lastStatus) === null || _a === void 0 ? void 0 : _a.mode) || operationMode_1.OperationMode.Off;
193
441
  if (this.igniting) {
@@ -196,26 +444,38 @@ class FireplaceController extends events_1.default {
196
444
  }
197
445
  if (operationMode_1.OperationModeUtils.needsIgnite(mode) && currentMode === operationMode_1.OperationMode.Off && !((_b = this.lastStatus) === null || _b === void 0 ? void 0 : _b.guardFlameOn)) {
198
446
  this.log.info('Ignite fireplace');
199
- await this.igniteFireplace();
200
- return false;
447
+ const igniteSucceeded = await this.igniteFireplace();
448
+ if (!igniteSucceeded) {
449
+ // igniteFireplace() already ran its own MAX_ATTEMPTS retry sequence
450
+ // and (on hard-fail) flipped the lockout circuit breaker. Returning
451
+ // true here keeps requestController from queueing a second-layer
452
+ // 90s retry storm on top of that.
453
+ return true;
454
+ }
455
+ // Ignition succeeded. The receiver lands in Manual by default —
456
+ // fall through so we still apply the user's requested mode (e.g.
457
+ // Temperature for HEAT) instead of leaving them stuck in Manual.
201
458
  }
202
- if (currentMode === mode) {
459
+ // Re-read mode: lastStatus was updated by the polls inside the ignite
460
+ // wait loop, so currentMode (captured above) is stale post-ignite.
461
+ const liveMode = ((_c = this.lastStatus) === null || _c === void 0 ? void 0 : _c.mode) || operationMode_1.OperationMode.Off;
462
+ if (liveMode === mode) {
203
463
  this.log.debug('Ignore same mode!');
204
464
  return true;
205
465
  }
206
466
  this.log.info(`Set mode to: ${operationMode_1.OperationMode[mode]}`);
207
- const targetTemperature = (_e = (_c = request.temperature) !== null && _c !== void 0 ? _c : (_d = this.lastStatus) === null || _d === void 0 ? void 0 : _d.targetTemperature) !== null && _e !== void 0 ? _e : 20;
467
+ const targetTemperature = (_f = (_d = request.temperature) !== null && _d !== void 0 ? _d : (_e = this.lastStatus) === null || _e === void 0 ? void 0 : _e.targetTemperature) !== null && _f !== void 0 ? _f : 20;
208
468
  switch (mode) {
209
469
  case operationMode_1.OperationMode.Manual:
210
470
  this.setManualMode();
211
- this.setFlameHeight(targetTemperature);
471
+ await this.setFlameHeight(targetTemperature);
212
472
  break;
213
473
  case operationMode_1.OperationMode.Eco:
214
- this.setFlameHeight(targetTemperature);
474
+ await this.setFlameHeight(targetTemperature);
215
475
  this.setEcoMode();
216
476
  break;
217
477
  case operationMode_1.OperationMode.Temperature:
218
- this.setTemperature(targetTemperature);
478
+ await this.setTemperature(targetTemperature);
219
479
  break;
220
480
  case operationMode_1.OperationMode.Off:
221
481
  await this.guardFlameOff();
@@ -229,6 +489,20 @@ class FireplaceController extends events_1.default {
229
489
  }
230
490
  async request(request) {
231
491
  var _a, _b, _c, _d;
492
+ // If the auto-retry ignition loop is active, an Off request should
493
+ // abort the sequence rather than queueing behind it.
494
+ if (this.igniting && request.mode === operationMode_1.OperationMode.Off) {
495
+ this.log.info('Off requested while ignition retry sequence is in progress — aborting retries');
496
+ this.ignitionAbortRequested = true;
497
+ }
498
+ // If a prior session ended in a hard lockout, block everything except
499
+ // an explicit Off (which can't hurt and may help reconcile state).
500
+ if (this.ignitionTracker.hasRecentHardLockout() && request.mode !== operationMode_1.OperationMode.Off) {
501
+ this.log.warn('Ignoring request — fireplace is in Mertik GV60 hard-lockout state. ' +
502
+ 'Physical intervention required to clear (cycle gas at the wall, paperclip-reset the WiFi module, ' +
503
+ 'or retry ignition from the handheld). Restart homebridge after recovery.');
504
+ return false;
505
+ }
232
506
  let succeeds = true;
233
507
  const currentMode = ((_a = this.lastStatus) === null || _a === void 0 ? void 0 : _a.mode) || operationMode_1.OperationMode.Off;
234
508
  this.stopStatusSubscription();
@@ -269,4 +543,38 @@ exports.FireplaceController = FireplaceController;
269
543
  FireplaceController.UNREACHABLE_TIMEOUT = 1000 * 60 * 5; //5 min
270
544
  FireplaceController.REFRESH_TIMEOUT = 1000 * 15; //15 seconds
271
545
  FireplaceController.STATUS_PACKET_LENGTH = 106; //characters
546
+ /**
547
+ * How often we poll status while waiting for an Ignite to resolve.
548
+ * Tighter than the normal 15s subscription because we want to catch
549
+ * the igniting=1 → 0 transition quickly.
550
+ */
551
+ FireplaceController.IGNITE_POLL_INTERVAL_MS = 5000;
552
+ /**
553
+ * How long to wait for a status response after issuing a poll command
554
+ * inside a transition wait. Must be longer than the normal round-trip
555
+ * but short enough that a missed response just causes the next poll to
556
+ * retry. 5s mirrors the CLI's `STATUS_RESPONSE_TIMEOUT`.
557
+ */
558
+ FireplaceController.STATUS_RESPONSE_TIMEOUT_MS = 5000;
559
+ /**
560
+ * Shutdown ceiling. Empirically a real shutdown observed at the cabin
561
+ * (2026-05-17) took 26s — comfortably under this ceiling, but the
562
+ * previous 30s blind delay was only 4s of headroom. 45s gives the gas
563
+ * valve, pilot millivolts decay, and thermopile latch release plenty of
564
+ * room without leaving HomeKit hanging.
565
+ */
566
+ FireplaceController.SHUTDOWN_CEILING_MS = 45000;
567
+ /**
568
+ * Poll cadence inside the shutdown wait. 2s is fine-grained enough to
569
+ * catch the `guardFlameOn` clear within ~2s of the actual event.
570
+ */
571
+ FireplaceController.SHUTDOWN_POLL_INTERVAL_MS = 2000;
572
+ /**
573
+ * Hard safety cap on the thermostat setpoint, in Celsius. Mirrors the
574
+ * HomeKit `setProps` cap in `serviceController` — duplicated here as a
575
+ * defense against any code path (cached HomeKit state, restored
576
+ * accessory state, future internal callers) that bypasses the slider's
577
+ * advertised maxValue. 26.5°C ≈ 79.7°F.
578
+ */
579
+ FireplaceController.MAX_SAFE_TARGET_C = 26.5;
272
580
  //# sourceMappingURL=fireplaceController.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fireplaceController.js","sourceRoot":"","sources":["../../src/controllers/fireplaceController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fireplaceController.js","sourceRoot":"","sources":["../../src/controllers/fireplaceController.ts"],"names":[],"mappings":";;;;;;AACA,oDAAkC;AAClC,8CAAkC;AAClC,+DAA4D;AAC5D,2DAA4E;AAC5E,uDAAsE;AAEtE,iEAAmE;AAGnE,uDAAoD;AA8BpD,MAAa,mBAAoB,SAAQ,gBAAY;IA2DnD,YACkB,GAAW,EACX,SAA4B,EAC5B,QAAwB;;QAExC,KAAK,EAAE,CAAC;QAJQ,QAAG,GAAH,GAAG,CAAQ;QACX,cAAS,GAAT,SAAS,CAAmB;QAC5B,aAAQ,GAAR,QAAQ,CAAgB;QA5DlC,WAAM,GAAG,yBAAW,CAAC,MAAM,CAAC;QAE5B,WAAM,GAAkB,IAAI,CAAC;QAC7B,gBAAW,GAAS,IAAI,IAAI,EAAE,CAAC;QAE/B,aAAQ,GAAG,KAAK,CAAC;QACjB,iBAAY,GAAG,KAAK,CAAC;QACrB,mBAAc,GAAG,KAAK,CAAC;QAC/B;;;WAGG;QACK,2BAAsB,GAAG,KAAK,CAAC;QA0avC,UAAK,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QAvXpD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC;QAC5C,MAAM,WAAW,GAAG,MAAA,MAAA,MAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,GAAG,0CAAE,IAAI,0CAAE,WAAW,kDAAI,CAAC;QAC9D,IAAI,CAAC,eAAe,GAAG,IAAI,iCAAe,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAClE,IAAI,CAAC,uBAAuB,EAAE,CAAC;IACjC,CAAC;IAEO,uBAAuB;QAC7B,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,EAAE,EAAE,mBAAmB,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IACtG,CAAC;IAEO,sBAAsB;QAC5B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACzC,IAAI,IAAI,CAAC,WAAW,EAAE;YACpB,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAChC,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;SAC9B;IACH,CAAC;IAEO,aAAa;QACnB,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QAEpC,IAAI,IAAI,CAAC,UAAU,EAAE;YACnB,wEAAwE;YACxE,IAAI,CAAC,cAAc,GAAG,CAAC,WAAW,CAAC;YACnC,IAAI,IAAI,CAAC,cAAc,EAAC;gBACtB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;aACjC;SACF;QAED,IAAI;YACF,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;SAC5B;QAAC,WAAM;YACN,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;SACtC;IACH,CAAC;IAEO,qBAAqB,CAAC,QAAgB;QAC5C,MAAM,SAAS,GAAG,IAAI,iCAAe,CAAC,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;QACnC,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC,YAAY,CAAC;QAC3C,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACrC,IAAI,IAAI,CAAC,cAAc,EAAE;YACvB,sEAAsE;YACtE,IAAI,CAAC,aAAa,EAAE,CAAC;SACtB;IACH,CAAC;IAED;;;;OAIG;IACI,eAAe;QACpB,OAAO,IAAI,CAAC,eAAe,CAAC,oBAAoB,EAAE,CAAC;IACrD,CAAC;IAED;;;;;;;;;;;;;OAaG;IACK,KAAK,CAAC,eAAe;;QAC3B,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAC3C,OAAO,KAAK,CAAC;SACd;QACD,IAAI,IAAI,CAAC,eAAe,CAAC,oBAAoB,EAAE,EAAE;YAC/C,IAAI,CAAC,GAAG,CAAC,KAAK,CACZ,sEAAsE;gBACtE,wFAAwF;gBACxF,8FAA8F,CAC/F,CAAC;YACF,OAAO,KAAK,CAAC;SACd;QACD,IAAI,CAAC,sBAAsB,GAAG,KAAK,CAAC;QACpC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,MAAM,GAAG,GAAG,iCAAe,CAAC,YAAY,CAAC;QACzC,IAAI;YACF,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,GAAG,EAAE,OAAO,EAAE,EAAE;gBAC/C,IAAI,IAAI,CAAC,sBAAsB,EAAE;oBAC/B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,oEAAoE,OAAO,OAAO,GAAG,EAAE,CAAC,CAAC;oBACvG,OAAO,KAAK,CAAC;iBACd;gBACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,OAAO,OAAO,GAAG,0BAA0B,CAAC,CAAC;gBAC/E,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC;gBACnF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC7B,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAC3B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBAChE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;gBACzC,MAAM,IAAI,GAAG,MAAA,MAAA,IAAI,CAAC,UAAU,0CAAE,aAAa,mCAAI,MAAM,CAAC;gBACtD,IAAI,OAAO,KAAK,SAAS,EAAE;oBACzB,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;oBACpD,IAAI,CAAC,GAAG,CAAC,IAAI,CACX,oBAAoB,OAAO,OAAO,GAAG,qBAAqB,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI;wBAC1F,eAAe,MAAM,CAAC,EAAE,YAAY,IAAI,GAAG,CAC5C,CAAC;oBACF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;oBAC5B,OAAO,IAAI,CAAC;iBACb;gBACD,IAAI,OAAO,KAAK,WAAW,EAAE;oBAC3B,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;oBACxD,IAAI,CAAC,GAAG,CAAC,IAAI,CACX,oBAAoB,OAAO,OAAO,GAAG,uBAAuB,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM;wBAC9F,oCAAoC,IAAI,2BAA2B,CACpE,CAAC;iBACH;qBAAM;oBACL,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;oBACxD,IAAI,CAAC,GAAG,CAAC,KAAK,CACZ,oBAAoB,OAAO,OAAO,GAAG,8CAA8C;wBACnF,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,aAAa,IAAI,oDAAoD,CACrG,CAAC;oBACF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;oBAC3B,OAAO,KAAK,CAAC;iBACd;gBACD,IAAI,OAAO,GAAG,GAAG,EAAE;oBACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,iCAAe,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;oBACnE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,QAAQ,oBAAoB,OAAO,GAAG,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;oBACvF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,iCAAe,CAAC,cAAc,CAAC,CAAC;oBAC1E,IAAI,OAAO,EAAE;wBACX,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,qEAAqE,CAAC,CAAC;wBACrF,OAAO,KAAK,CAAC;qBACd;iBACF;aACF;YACD,IAAI,CAAC,GAAG,CAAC,KAAK,CACZ,gBAAgB,GAAG,6DAA6D;gBAChF,sGAAsG,CACvG,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAC3B,OAAO,KAAK,CAAC;SACd;gBAAS;YACR,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;SACvB;IACH,CAAC;IAED;;;;;;;;;OASG;IACK,KAAK,CAAC,sBAAsB,CAAC,OAAe,EAAE,GAAW;QAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,iCAAe,CAAC,mBAAmB,CAAC;QACtD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,SAAS,EAAE;YACrC,MAAM,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,uBAAuB,CAAC,CAAC;YAC9D,oEAAoE;YACpE,mEAAmE;YACnE,4DAA4D;YAC5D,MAAM,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,0BAA0B,CAAC,CAAC;YAC/F,IAAI;gBACF,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;aAC5B;YAAC,WAAM;gBACN,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;aAClF;YACD,MAAM,CAAC,GAAG,MAAM,eAAe,CAAC;YAChC,IAAI,CAAC,CAAC;gBAAE,SAAS;YACjB,IAAI,CAAC,CAAC,YAAY,EAAE;gBAClB,OAAO,SAAS,CAAC;aAClB;YACD,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE;gBACf,+DAA+D;gBAC/D,6DAA6D;gBAC7D,OAAO,WAAW,CAAC;aACpB;YACD,iEAAiE;YACjE,mEAAmE;YACnE,+DAA+D;YAC/D,IAAI,CAAC,GAAG,CAAC,IAAI,CACX,oBAAoB,OAAO,IAAI,GAAG,uBAAuB,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,aAAa,GAAG,CAChI,CAAC;SACH;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,cAAc,CAAC,EAAU;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE;YACvB,IAAI,IAAI,CAAC,sBAAsB;gBAAE,OAAO,IAAI,CAAC;YAC7C,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;SACpD;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,OAAO;QACnB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzB,MAAM,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,YAAY,CAAC;QACzB,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;;;;;;;;OAYG;IACK,KAAK,CAAC,aAAa;QACzB,IAAI,IAAI,CAAC,YAAY,EAAE;YACrB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC;SACb;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI;YACF,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YAC3B,OAAO,GAAG,IAAI,CAAC;SAChB;QAAC,WAAM;YACN,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,6EAA6E,CAAC,CAAC;SAC9F;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,mBAAmB,CAAC,mBAAmB,CAAC;QAC1D,MAAM,MAAM,GAAG,mBAAmB,CAAC,yBAAyB,CAAC;QAC7D,+EAA+E;QAC/E,yEAAyE;QACzE,sEAAsE;QACtE,2DAA2D;QAC3D,MAAM,YAAY,GAAG,MAAM,GAAG,mBAAmB,CAAC,0BAA0B,CAAC;QAC7E,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,YAAY,IAAI,SAAS,EAAE;YACrD,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACzB,qEAAqE;YACrE,qEAAqE;YACrE,oEAAoE;YACpE,qEAAqE;YACrE,+BAA+B;YAC/B,IAAI,CAAC,OAAO,EAAE;gBACZ,IAAI;oBACF,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;oBAC3B,OAAO,GAAG,IAAI,CAAC;oBACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;iBACjF;gBAAC,WAAM;oBACN,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,qEAAqE,CAAC,CAAC;iBACtF;aACF;YACD,MAAM,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,0BAA0B,CAAC,CAAC;YAC/F,IAAI;gBACF,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;aAC5B;YAAC,WAAM;gBACN,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;aAC7E;YACD,MAAM,CAAC,GAAG,MAAM,eAAe,CAAC;YAChC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;YACxD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,EAAE;gBACxB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,kCAAkC,OAAO,GAAG,CAAC,CAAC;gBAC5D,OAAO,IAAI,CAAC;aACb;YACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,6CAA6C,OAAO,GAAG,CAAC,CAAC;SACxE;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QACrC,IAAI,CAAC,GAAG,CAAC,IAAI,CACX,yCAAyC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,cAAc;YACnF,8DAA8D,CAC/D,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACK,iBAAiB,CAAC,SAAiB;QACzC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,MAAM,MAAM,GAAG,CAAC,CAA8B,EAAE,EAAE;gBAChD,IAAI,QAAQ;oBAAE,OAAO;gBACrB,QAAQ,GAAG,IAAI,CAAC;gBAChB,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACvC,OAAO,CAAC,CAAC,CAAC,CAAC;YACb,CAAC,CAAC;YACF,MAAM,OAAO,GAAG,CAAC,CAAkB,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,CAAC;YACnE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,UAAU;QAChB,OAAO,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC;IAEO,aAAa;QACnB,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAEO,kBAAkB;QACxB,OAAO,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC;IAEO,YAAY;QAClB,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,MAAM;eACX,CAAC,OAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,WAAW,CAAC,IAAI,CAAC,OAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,KAAK,IAAI,CAAC,EAAE;YAC/H,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;YACjC,IAAI,CAAC,MAAM,GAAG,IAAI,aAAG,CAAC,MAAM,EAAE,CAAC;YAC/B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC9B,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,mBAAmB,CAAC,eAAe,CAAC,CAAC;YAC5D,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC/D,IAAI,QAAQ,CAAC,MAAM,KAAK,mBAAmB,CAAC,oBAAoB,EAAE;oBAChE,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;iBACtC;YACH,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC9B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC/C,IAAI,IAAI,CAAC,MAAM,IAAI,OAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,EAAE;oBAC7D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;iBACvB;YACH,CAAC,CAAC,CAAC;SACJ;QACD,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAEO,WAAW,CAAC,OAAe;QACjC,MAAM,MAAM,GAAG,wBAAwB,CAAC;QACxC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,KAAK,CAAC,CAAC;QACpD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,kBAAkB,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,SAAS;QACP,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QACxC,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,mBAAmB,CAAC,mBAAmB,CAAC;IAChE,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAID,gBAAgB;QACd,MAAM,GAAG,GAAG,MAAM,GAAG,yBAAW,CAAC,MAAM,GAAG,IAAI,CAAC;QAC/C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,WAAmB;QACtC,MAAM,UAAU,GAAG,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAC5C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAmC,UAAU,EAAE,CAAC,CAAC;QAChE,MAAM,MAAM,GAAG,8BAAgB,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;QACzD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,uBAAuB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,MAAM,IAAI,CAAC,KAAK,CAAC,KAAM,CAAC,CAAC;QACzB,MAAM,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;QACnC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACtB,MAAM,IAAI,CAAC,KAAK,CAAC,IAAK,CAAC,CAAC;IAC1B,CAAC;IAEM,cAAc;QACnB,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,WAAmB;;QAC7C,qEAAqE;QACrE,iEAAiE;QACjE,oDAAoD;QACpD,IAAI,WAAW,GAAG,mBAAmB,CAAC,iBAAiB,EAAE;YACvD,IAAI,CAAC,GAAG,CAAC,IAAI,CACX,sBAAsB,WAAW,2BAA2B;gBAC5D,GAAG,mBAAmB,CAAC,iBAAiB,gBAAgB,CACzD,CAAC;YACF,WAAW,GAAG,mBAAmB,CAAC,iBAAiB,CAAC;SACrD;QACD,qCAAqC;QACrC,MAAM,IAAI,GAAG,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,eAAe,KAAI,GAAG,CAAC;QACnD,MAAM,WAAW,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,GAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QACpF,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,sBAAsB,WAAW,IAAI,IAAI,EAAE,CAAC,CAAC;QAE3D,6DAA6D;QAC7D,MAAM,WAAW,GAAG,MAAA,IAAI,CAAC,UAAU,0CAAE,IAAI,CAAC;QAC1C,IAAI,WAAW,KAAK,6BAAa,CAAC,WAAW,EAAE;YAC7C,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,KAAK,CAAC,IAAK,CAAC,CAAC;YACxB,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,KAAK,CAAC,IAAK,CAAC,CAAC;YACxB,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,MAAM,IAAI,CAAC,KAAK,CAAC,IAAK,CAAC,CAAC;SACzB;QAED,IAAI,CAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,UAAU,0CAAE,iBAAiB,MAAK,WAAW,EAAE;YACvD,MAAM,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;SAC7C;IACH,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAAC,WAAmB;QACnD,MAAM,KAAK,GAAG,wCAAqB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACxD,MAAM,GAAG,GAAG,aAAa,GAAG,KAAK,GAAG,IAAI,CAAC;QACzC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACtB,MAAM,IAAI,CAAC,KAAK,CAAC,IAAK,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAiB;;QAC7B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAK,CAAC;QAC3B,MAAM,WAAW,GAAG,CAAA,MAAA,IAAI,CAAC,UAAU,0CAAE,IAAI,KAAI,6BAAa,CAAC,GAAG,CAAC;QAC/D,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;YACjE,OAAO,KAAK,CAAC;SACd;QACD,IAAI,kCAAkB,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,WAAW,KAAK,6BAAa,CAAC,GAAG,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,UAAU,0CAAE,YAAY,CAAA,EAAE;YAC/G,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAClC,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YACrD,IAAI,CAAC,eAAe,EAAE;gBACpB,oEAAoE;gBACpE,oEAAoE;gBACpE,iEAAiE;gBACjE,kCAAkC;gBAClC,OAAO,IAAI,CAAC;aACb;YACD,gEAAgE;YAChE,iEAAiE;YACjE,iEAAiE;SAClE;QACD,sEAAsE;QACtE,mEAAmE;QACnE,MAAM,QAAQ,GAAG,CAAA,MAAA,IAAI,CAAC,UAAU,0CAAE,IAAI,KAAI,6BAAa,CAAC,GAAG,CAAC;QAC5D,IAAI,QAAQ,KAAK,IAAI,EAAE;YACrB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACpC,OAAO,IAAI,CAAC;SACb;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,6BAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrD,MAAM,iBAAiB,GAAG,MAAA,MAAA,OAAO,CAAC,WAAW,mCAAI,MAAA,IAAI,CAAC,UAAU,0CAAE,iBAAiB,mCAAI,EAAE,CAAC;QAC1F,QAAO,IAAI,EAAE;YACX,KAAK,6BAAa,CAAC,MAAM;gBACvB,IAAI,CAAC,aAAa,EAAE,CAAC;gBACrB,MAAM,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;gBAC7C,MAAM;YACR,KAAK,6BAAa,CAAC,GAAG;gBACpB,MAAM,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;gBAC7C,IAAI,CAAC,UAAU,EAAE,CAAC;gBAClB,MAAM;YACR,KAAK,6BAAa,CAAC,WAAW;gBAC5B,MAAM,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;gBAC7C,MAAM;YACR,KAAK,6BAAa,CAAC,GAAG;gBACpB,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;gBAC3B,MAAM;SACT;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,EAAW;QAChB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAiB;;QAC7B,mEAAmE;QACnE,qDAAqD;QACrD,IAAI,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,KAAK,6BAAa,CAAC,GAAG,EAAE;YACvD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,+EAA+E,CAAC,CAAC;YAC/F,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;SACpC;QACD,sEAAsE;QACtE,mEAAmE;QACnE,IAAI,IAAI,CAAC,eAAe,CAAC,oBAAoB,EAAE,IAAI,OAAO,CAAC,IAAI,KAAK,6BAAa,CAAC,GAAG,EAAE;YACrF,IAAI,CAAC,GAAG,CAAC,IAAI,CACX,qEAAqE;gBACrE,mGAAmG;gBACnG,0EAA0E,CAC3E,CAAC;YACF,OAAO,KAAK,CAAC;SACd;QACD,IAAI,QAAQ,GAAG,IAAI,CAAC;QACpB,MAAM,WAAW,GAAG,CAAA,MAAA,IAAI,CAAC,UAAU,0CAAE,IAAI,KAAI,6BAAa,CAAC,GAAG,CAAC;QAC/D,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC9B,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;eACzB,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE;YACjC,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;SACxC;aAAM,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS;eACvC,CAAC,OAAO,CAAC,IAAI,KAAK,6BAAa,CAAC,WAAW,IAAI,CAAA,MAAA,IAAI,CAAC,UAAU,0CAAE,IAAI,MAAK,6BAAa,CAAC,WAAW,CAAC,EAAE;YACxG,IAAI,OAAO,CAAC,WAAW,IAAI,GAAG,EAAE;gBAC9B,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;aACtB;iBAAM;gBACL,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;aAChD;SACF;aAAM,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS;eACtC,CAAC,OAAO,CAAC,IAAI,KAAK,6BAAa,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,6BAAa,CAAC,GAAG;mBAC3E,CAAA,MAAA,IAAI,CAAC,UAAU,0CAAE,IAAI,MAAK,6BAAa,CAAC,MAAM,IAAI,CAAA,MAAA,IAAI,CAAC,UAAU,0CAAE,IAAI,MAAK,6BAAa,CAAC,GAAG,CAAC,EAAE;YACrG,IAAI,OAAO,CAAC,WAAW,IAAI,GAAG,EAAE;gBAC9B,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;aACtB;iBAAM;gBACL,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;aAChD;SACF;QACD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAK,CAAC,CAAC;QACxB,IAAI,CAAC,CAAC,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,GAAG,GAAG,CAAC,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE;YACtF,MAAM,IAAI,CAAC,KAAK,CAAC,IAAK,CAAC,CAAC;YACxB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC3B,MAAM,IAAI,CAAC,KAAK,CAAC,IAAK,CAAC,CAAC;SACzB;QACD,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC/B,OAAO,QAAQ,CAAC;IAClB,CAAC;;AA5lBH,kDA6lBC;AAxkBgB,uCAAmB,GAAG,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO;AAC5C,mCAAe,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,YAAY;AACzC,wCAAoB,GAAG,GAAG,CAAC,CAAC,YAAY;AACvD;;;;GAIG;AACY,2CAAuB,GAAG,IAAK,CAAC;AAC/C;;;;;GAKG;AACY,8CAA0B,GAAG,IAAK,CAAC;AAClD;;;;;;GAMG;AACY,uCAAmB,GAAG,KAAM,CAAC;AAC5C;;;GAGG;AACY,6CAAyB,GAAG,IAAK,CAAC;AACjD;;;;;;GAMG;AACY,qCAAiB,GAAG,IAAI,CAAC"}
@@ -0,0 +1,82 @@
1
+ import { Logger } from 'homebridge';
2
+ /**
3
+ * Tracks ignition attempts and persists their outcomes to disk.
4
+ *
5
+ * **Why this exists.** The Mertik GV60 receiver has its own internal
6
+ * ignition logic: when we send the Ignite command (`314103`), it opens
7
+ * the gas valve, sparks repeatedly for ~30-60s, and then either:
8
+ *
9
+ * - **Success**: the thermopile confirms flame, `guardFlameOn` goes true,
10
+ * `igniting` clears to 0.
11
+ * - **Soft failure**: the receiver gives up cleanly. `igniting` clears
12
+ * back to 0 but `guardFlameOn` stays 0. This is the common cold-start
13
+ * case — air in the pilot tube, cold thermopile, marginal gas pressure.
14
+ * Resolves on the next attempt 80% of the time.
15
+ * - **Hard lockout**: the `igniting` bit stays stuck at 1 indefinitely.
16
+ * This is the safety-lockout state — the receiver tripped its fault
17
+ * and only a paperclip reset or service visit clears it.
18
+ *
19
+ * This tracker doesn't drive retries directly; the controller's
20
+ * `igniteFireplace()` does that with explicit `Attempt N of M` logging.
21
+ * The tracker's job is to record each attempt's outcome, persist the
22
+ * history under the homebridge `storagePath` so it survives plugin
23
+ * restarts and log rotations, and expose the consecutive-failure count
24
+ * to the controller's circuit breaker.
25
+ *
26
+ * Persistence file: `<storagePath>/valor-ignition-history.json`. The
27
+ * previous all-in-memory approach lost every diagnostic the moment
28
+ * homebridge rotated its log.
29
+ */
30
+ export declare type AttemptOutcome = 'pending' | 'success' | 'soft-fail' | 'hard-fail';
31
+ export interface IgnitionAttempt {
32
+ id: number;
33
+ attemptInSequence: number;
34
+ maxInSequence: number;
35
+ startedAtIso: string;
36
+ finishedAtIso?: string;
37
+ outcome: AttemptOutcome;
38
+ durationMs?: number;
39
+ finalStatusBits?: string;
40
+ reason: string;
41
+ }
42
+ export declare class IgnitionTracker {
43
+ private readonly log;
44
+ /** Auto-retries this many times before giving up. */
45
+ static MAX_ATTEMPTS: number;
46
+ /** Wait this long for `guardFlameOn` or `igniting=0` after Ignite command. */
47
+ static IGNITION_TIMEOUT_MS: number;
48
+ /** Spacing between auto-retries to let the receiver / gas line settle. */
49
+ static RETRY_DELAY_MS: number;
50
+ /** Cap on history we keep persisted. */
51
+ static MAX_HISTORY: number;
52
+ private history;
53
+ private current;
54
+ private readonly filePath?;
55
+ constructor(log: Logger, storagePath?: string);
56
+ /**
57
+ * Caller is about to send the Ignite command for the n-th attempt in
58
+ * a retry sequence. Returns the attempt record so callers can reference
59
+ * its id in log lines.
60
+ */
61
+ recordAttemptStart(attemptInSequence: number, maxInSequence: number, reason: string): IgnitionAttempt;
62
+ /** Caller observed a successful outcome (guardFlameOn = true). */
63
+ recordSuccess(durationMs: number, finalStatusBits: string): void;
64
+ /** Caller observed a soft failure (igniting cleared back to 0, no flame). */
65
+ recordSoftFailure(durationMs: number, finalStatusBits: string): void;
66
+ /** Caller observed a hard lockout (igniting bit stuck at 1 past timeout). */
67
+ recordHardLockout(durationMs: number, finalStatusBits: string): void;
68
+ /**
69
+ * Number of consecutive failures (any kind) since the last success.
70
+ * Used by the controller to short-circuit fresh ignite requests when
71
+ * we've already burned through MAX_ATTEMPTS.
72
+ */
73
+ consecutiveFailures(): number;
74
+ /** True if the most recent terminated attempt was a hard lockout. */
75
+ hasRecentHardLockout(): boolean;
76
+ /** Read-only access for diagnostics or HomeKit fault surfacing. */
77
+ getHistory(): readonly IgnitionAttempt[];
78
+ private complete;
79
+ private load;
80
+ private persist;
81
+ }
82
+ //# sourceMappingURL=ignitionTracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ignitionTracker.d.ts","sourceRoot":"","sources":["../../src/controllers/ignitionTracker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,oBAAY,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,CAAC;AAE/E,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,eAAe;IAexB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAdtB,qDAAqD;IACrD,MAAM,CAAC,YAAY,SAAK;IACxB,8EAA8E;IAC9E,MAAM,CAAC,mBAAmB,SAAa;IACvC,0EAA0E;IAC1E,MAAM,CAAC,cAAc,SAAa;IAClC,wCAAwC;IACxC,MAAM,CAAC,WAAW,SAAO;IAEzB,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;gBAGhB,GAAG,EAAE,MAAM,EAC5B,WAAW,CAAC,EAAE,MAAM;IAUtB;;;;OAIG;IACH,kBAAkB,CAAC,iBAAiB,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe;IAarG,kEAAkE;IAClE,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IAIhE,6EAA6E;IAC7E,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IAIpE,6EAA6E;IAC7E,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IAIpE;;;;OAIG;IACH,mBAAmB,IAAI,MAAM;IAa7B,qEAAqE;IACrE,oBAAoB,IAAI,OAAO;IAa/B,mEAAmE;IACnE,UAAU,IAAI,SAAS,eAAe,EAAE;IAIxC,OAAO,CAAC,QAAQ;IAgBhB,OAAO,CAAC,IAAI;IAmBZ,OAAO,CAAC,OAAO;CAWhB"}
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.IgnitionTracker = void 0;
27
+ const fs = __importStar(require("fs"));
28
+ const path = __importStar(require("path"));
29
+ class IgnitionTracker {
30
+ constructor(log, storagePath) {
31
+ this.log = log;
32
+ this.history = [];
33
+ this.current = null;
34
+ if (storagePath) {
35
+ this.filePath = path.join(storagePath, 'valor-ignition-history.json');
36
+ this.load();
37
+ }
38
+ else {
39
+ this.log.debug('IgnitionTracker: no storagePath provided, running in-memory only');
40
+ }
41
+ }
42
+ /**
43
+ * Caller is about to send the Ignite command for the n-th attempt in
44
+ * a retry sequence. Returns the attempt record so callers can reference
45
+ * its id in log lines.
46
+ */
47
+ recordAttemptStart(attemptInSequence, maxInSequence, reason) {
48
+ var _a, _b;
49
+ const id = ((_b = (_a = this.history[this.history.length - 1]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : 0) + 1;
50
+ this.current = {
51
+ id,
52
+ attemptInSequence,
53
+ maxInSequence,
54
+ startedAtIso: new Date().toISOString(),
55
+ outcome: 'pending',
56
+ reason,
57
+ };
58
+ return this.current;
59
+ }
60
+ /** Caller observed a successful outcome (guardFlameOn = true). */
61
+ recordSuccess(durationMs, finalStatusBits) {
62
+ this.complete('success', durationMs, finalStatusBits);
63
+ }
64
+ /** Caller observed a soft failure (igniting cleared back to 0, no flame). */
65
+ recordSoftFailure(durationMs, finalStatusBits) {
66
+ this.complete('soft-fail', durationMs, finalStatusBits);
67
+ }
68
+ /** Caller observed a hard lockout (igniting bit stuck at 1 past timeout). */
69
+ recordHardLockout(durationMs, finalStatusBits) {
70
+ this.complete('hard-fail', durationMs, finalStatusBits);
71
+ }
72
+ /**
73
+ * Number of consecutive failures (any kind) since the last success.
74
+ * Used by the controller to short-circuit fresh ignite requests when
75
+ * we've already burned through MAX_ATTEMPTS.
76
+ */
77
+ consecutiveFailures() {
78
+ let n = 0;
79
+ for (let i = this.history.length - 1; i >= 0; i--) {
80
+ const a = this.history[i];
81
+ if (a.outcome === 'soft-fail' || a.outcome === 'hard-fail') {
82
+ n++;
83
+ }
84
+ else if (a.outcome === 'success') {
85
+ break;
86
+ }
87
+ }
88
+ return n;
89
+ }
90
+ /** True if the most recent terminated attempt was a hard lockout. */
91
+ hasRecentHardLockout() {
92
+ for (let i = this.history.length - 1; i >= 0; i--) {
93
+ const a = this.history[i];
94
+ if (a.outcome === 'success') {
95
+ return false;
96
+ }
97
+ if (a.outcome === 'hard-fail') {
98
+ return true;
99
+ }
100
+ }
101
+ return false;
102
+ }
103
+ /** Read-only access for diagnostics or HomeKit fault surfacing. */
104
+ getHistory() {
105
+ return this.history;
106
+ }
107
+ complete(outcome, durationMs, finalBits) {
108
+ if (!this.current) {
109
+ return;
110
+ }
111
+ this.current.outcome = outcome;
112
+ this.current.finishedAtIso = new Date().toISOString();
113
+ this.current.durationMs = durationMs;
114
+ this.current.finalStatusBits = finalBits;
115
+ this.history.push(this.current);
116
+ if (this.history.length > IgnitionTracker.MAX_HISTORY) {
117
+ this.history = this.history.slice(-IgnitionTracker.MAX_HISTORY);
118
+ }
119
+ this.current = null;
120
+ this.persist();
121
+ }
122
+ load() {
123
+ if (!this.filePath) {
124
+ return;
125
+ }
126
+ try {
127
+ if (fs.existsSync(this.filePath)) {
128
+ const raw = fs.readFileSync(this.filePath, 'utf-8');
129
+ const parsed = JSON.parse(raw);
130
+ if (Array.isArray(parsed.history)) {
131
+ this.history = parsed.history;
132
+ this.log.debug(`IgnitionTracker: loaded ${this.history.length} historical attempts from ${this.filePath}`);
133
+ }
134
+ }
135
+ }
136
+ catch (err) {
137
+ this.log.warn(`IgnitionTracker: failed to read history (${err.message}); starting fresh`);
138
+ this.history = [];
139
+ }
140
+ }
141
+ persist() {
142
+ if (!this.filePath) {
143
+ return;
144
+ }
145
+ try {
146
+ const payload = JSON.stringify({ history: this.history }, null, 2);
147
+ fs.writeFileSync(this.filePath, payload);
148
+ }
149
+ catch (err) {
150
+ this.log.warn(`IgnitionTracker: failed to persist history (${err.message})`);
151
+ }
152
+ }
153
+ }
154
+ exports.IgnitionTracker = IgnitionTracker;
155
+ /** Auto-retries this many times before giving up. */
156
+ IgnitionTracker.MAX_ATTEMPTS = 4;
157
+ /** Wait this long for `guardFlameOn` or `igniting=0` after Ignite command. */
158
+ IgnitionTracker.IGNITION_TIMEOUT_MS = 90 * 1000;
159
+ /** Spacing between auto-retries to let the receiver / gas line settle. */
160
+ IgnitionTracker.RETRY_DELAY_MS = 45 * 1000;
161
+ /** Cap on history we keep persisted. */
162
+ IgnitionTracker.MAX_HISTORY = 200;
163
+ //# sourceMappingURL=ignitionTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ignitionTracker.js","sourceRoot":"","sources":["../../src/controllers/ignitionTracker.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"serviceController.d.ts","sourceRoot":"","sources":["../../src/controllers/serviceController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAC;AAEhF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,kBAAkB;IACjC,uBAAuB,IAAI,cAAc,CAAC;IAC1C,oBAAoB,IAAI,cAAc,CAAC;IACvC,sCAAsC,IAAI,cAAc,CAAC;IACzD,qCAAqC,IAAI,cAAc,CAAC;IACxD,gCAAgC,IAAI,cAAc,CAAC;IACnD,yCAAyC,IAAI,cAAc,CAAC;IAC5D,0BAA0B,IAAI,cAAc,CAAC;IAC7C,uBAAuB,IAAI,cAAc,CAAC;IAC1C,yCAAyC,IAAI,cAAc,CAAC;IAC5D,mBAAmB,IAAI,IAAI,CAAC;CAC7B;AAED,qBAAa,iBAAkB,YAAW,kBAAkB;aAMxC,GAAG,EAAE,MAAM;aACX,SAAS,EAAE,iBAAiB;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAP3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;gBAGzB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,iBAAiB,EAC3B,QAAQ,EAAE,aAAa;IAiB1C,mBAAmB;IAiEnB,uBAAuB,uBAGnB;IAEJ,oBAAoB,uBACkD;IAEtE,sCAAsC,uBAGlC;IAEJ,qCAAqC,uBAGjC;IAEJ,gCAAgC,uBAG5B;IAEJ,yCAAyC,uBAGrC;IAEJ,0BAA0B,uBAGtB;IAEJ,uBAAuB,uBACkD;IAEzE,yCAAyC,uBAGrC;CACL"}
1
+ {"version":3,"file":"serviceController.d.ts","sourceRoot":"","sources":["../../src/controllers/serviceController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAC;AAEhF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,kBAAkB;IACjC,uBAAuB,IAAI,cAAc,CAAC;IAC1C,oBAAoB,IAAI,cAAc,CAAC;IACvC,sCAAsC,IAAI,cAAc,CAAC;IACzD,qCAAqC,IAAI,cAAc,CAAC;IACxD,gCAAgC,IAAI,cAAc,CAAC;IACnD,yCAAyC,IAAI,cAAc,CAAC;IAC5D,0BAA0B,IAAI,cAAc,CAAC;IAC7C,uBAAuB,IAAI,cAAc,CAAC;IAC1C,yCAAyC,IAAI,cAAc,CAAC;IAC5D,mBAAmB,IAAI,IAAI,CAAC;CAC7B;AAED,qBAAa,iBAAkB,YAAW,kBAAkB;aAMxC,GAAG,EAAE,MAAM;aACX,SAAS,EAAE,iBAAiB;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAP3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;gBAGzB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,iBAAiB,EAC3B,QAAQ,EAAE,aAAa;IAiB1C,mBAAmB;IAqEnB,uBAAuB,uBAGnB;IAEJ,oBAAoB,uBACkD;IAEtE,sCAAsC,uBAGlC;IAEJ,qCAAqC,uBAGjC;IAEJ,gCAAgC,uBAG5B;IAEJ,yCAAyC,uBAGrC;IAEJ,0BAA0B,uBAGtB;IAEJ,uBAAuB,uBACkD;IAEzE,yCAAyC,uBAGrC;CACL"}
@@ -49,18 +49,22 @@ class ServiceController {
49
49
  this.platform.Characteristic.TargetHeaterCoolerState.HEAT,
50
50
  ],
51
51
  });
52
- // Configure HeatingThresholdTemperature with proper props
53
- // Note: Set minValue to 0 to allow for "off" state where target temp can be 0
52
+ // Configure HeatingThresholdTemperature with proper props.
53
+ // minValue 0 keeps the "off" state addressable (target temp can be 0).
54
+ // maxValue 26.5°C (~79.7°F) is a hard safety cap — 36°C (~97°F) is
55
+ // unsafe for a fireplace thermostat and slipped through the slider
56
+ // before. If anyone needs higher they should use Manual flame-height.
54
57
  this.heatingThresholdTemperatureCharacteristic().setProps({
55
58
  minValue: 0.0,
56
- maxValue: 36.0,
59
+ maxValue: 26.5,
57
60
  minStep: 0.5,
58
61
  });
59
- // Configure CoolingThresholdTemperature - required for iOS to display detail view
60
- // Even though we don't use cooling, iOS needs this characteristic defined
62
+ // Configure CoolingThresholdTemperature - required for iOS to display
63
+ // detail view. Even though we don't use cooling, iOS needs this
64
+ // characteristic defined. Cap matches heating for consistency.
61
65
  this.coolingThresholdTemperatureCharacteristic().setProps({
62
66
  minValue: 10.0,
63
- maxValue: 35.0,
67
+ maxValue: 26.5,
64
68
  minStep: 0.5,
65
69
  });
66
70
  // Configure CurrentTemperature with proper props
@@ -1 +1 @@
1
- {"version":3,"file":"serviceController.js","sourceRoot":"","sources":["../../src/controllers/serviceController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"serviceController.js","sourceRoot":"","sources":["../../src/controllers/serviceController.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,55 @@ export declare class FireplaceStatus {
7
7
  readonly igniting: boolean;
8
8
  readonly guardFlameOn: boolean;
9
9
  readonly shuttingDown: boolean;
10
+ /** Raw 4-char hex of the status bit field (chars 16-19). Useful for diagnostics. */
11
+ readonly statusBitsHex: string;
12
+ /**
13
+ * Heuristic: a Mertik GV60 ignition lockout looks like `igniting` set with
14
+ * no `guardFlameOn` and no `shuttingDown`. The valve tried to light, the
15
+ * thermopile never confirmed flame, and the receiver killed the gas. The
16
+ * `igniting` bit stays set until a power-cycle or paperclip reset.
17
+ * Empirically observed at the cabin on 2026-05-16. See PROTOCOL.md in the
18
+ * `valor-fireplace-cli` repo for the full empirical decode.
19
+ */
20
+ readonly lockoutSuspected: boolean;
21
+ /**
22
+ * Schedule / timer / remote-program overlay active (status bit 9). Set when
23
+ * the handheld remote is driving the setpoint from a P1/P2 timer or schedule.
24
+ */
25
+ readonly scheduleActive: boolean;
26
+ /** Decorative light on/off (status bit 13). Independent of brightness. */
27
+ readonly lightOn: boolean;
28
+ /**
29
+ * Decorative light brightness setpoint, 0-255 (chars 20-21). Persists across
30
+ * light on/off — the controller remembers your last dim level.
31
+ */
32
+ readonly lightBrightness: number;
33
+ /**
34
+ * Circulating fan speed, 0-4 (chars 22-23). 0 = off, 1-4 = the four speed
35
+ * bars exposed by the Valor 10 handheld remote.
36
+ */
37
+ readonly fanSpeed: number;
38
+ /**
39
+ * Current main-burner output level, 0-255 (chars 14-15). `0x00` means pilot
40
+ * only (no main burner flame). `0xFF` means full output (Step11). Uses the
41
+ * same calibration as the outbound FlameHeight command, but in temperature
42
+ * or eco mode the firmware may report any intermediate modulated value.
43
+ */
44
+ readonly burnerOutput: number;
45
+ /**
46
+ * Pilot lit but main burner off (`guardFlameOn && burnerOutput === 0`).
47
+ * Not a distinct wire mode — just a state.
48
+ */
49
+ readonly pilotOnly: boolean;
50
+ /**
51
+ * Display-gated burner output: returns 0 unless the guard flame is on.
52
+ * Firmware does not clear chars 14-15 on shutdown — they linger at the
53
+ * last in-flight value (e.g. `0xE7` for Step9), so the raw `burnerOutput`
54
+ * would falsely show "91%" while the pilot is dead. Use this for any
55
+ * log line or HomeKit characteristic that surfaces burner output to a
56
+ * human; use the raw `burnerOutput` only for diagnostic dumps.
57
+ */
58
+ get displayBurnerOutput(): number;
10
59
  constructor(status: string);
11
60
  toString(): string;
12
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fireplaceStatus.d.ts","sourceRoot":"","sources":["../../src/models/fireplaceStatus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,qBAAa,eAAe;IAC1B,SAAgB,KAAK,EAAE,OAAO,CAAS;IACvC,SAAgB,IAAI,EAAE,aAAa,CAAqB;IACxD,SAAgB,kBAAkB,EAAE,MAAM,CAAM;IAChD,SAAgB,iBAAiB,EAAE,MAAM,CAAM;IAC/C,SAAgB,QAAQ,EAAE,OAAO,CAAS;IAC1C,SAAgB,YAAY,EAAE,OAAO,CAAS;IAC9C,SAAgB,YAAY,EAAE,OAAO,CAAS;gBAElC,MAAM,EAAE,MAAM;IAiBnB,QAAQ,IAAI,MAAM;CAS1B"}
1
+ {"version":3,"file":"fireplaceStatus.d.ts","sourceRoot":"","sources":["../../src/models/fireplaceStatus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,qBAAa,eAAe;IAC1B,SAAgB,KAAK,EAAE,OAAO,CAAS;IACvC,SAAgB,IAAI,EAAE,aAAa,CAAqB;IACxD,SAAgB,kBAAkB,EAAE,MAAM,CAAM;IAChD,SAAgB,iBAAiB,EAAE,MAAM,CAAM;IAC/C,SAAgB,QAAQ,EAAE,OAAO,CAAS;IAC1C,SAAgB,YAAY,EAAE,OAAO,CAAS;IAC9C,SAAgB,YAAY,EAAE,OAAO,CAAS;IAC9C,oFAAoF;IACpF,SAAgB,aAAa,EAAE,MAAM,CAAM;IAC3C;;;;;;;OAOG;IACH,SAAgB,gBAAgB,EAAE,OAAO,CAAS;IAClD;;;OAGG;IACH,SAAgB,cAAc,EAAE,OAAO,CAAS;IAChD,0EAA0E;IAC1E,SAAgB,OAAO,EAAE,OAAO,CAAS;IACzC;;;OAGG;IACH,SAAgB,eAAe,EAAE,MAAM,CAAK;IAC5C;;;OAGG;IACH,SAAgB,QAAQ,EAAE,MAAM,CAAK;IACrC;;;;;OAKG;IACH,SAAgB,YAAY,EAAE,MAAM,CAAK;IACzC;;;OAGG;IACH,SAAgB,SAAS,EAAE,OAAO,CAAS;IAE3C;;;;;;;OAOG;IACH,IAAW,mBAAmB,IAAI,MAAM,CAEvC;gBAEW,MAAM,EAAE,MAAM;IA0BnB,QAAQ,IAAI,MAAM;CAc1B"}
@@ -11,14 +11,63 @@ class FireplaceStatus {
11
11
  this.igniting = false;
12
12
  this.guardFlameOn = false;
13
13
  this.shuttingDown = false;
14
+ /** Raw 4-char hex of the status bit field (chars 16-19). Useful for diagnostics. */
15
+ this.statusBitsHex = '';
16
+ /**
17
+ * Heuristic: a Mertik GV60 ignition lockout looks like `igniting` set with
18
+ * no `guardFlameOn` and no `shuttingDown`. The valve tried to light, the
19
+ * thermopile never confirmed flame, and the receiver killed the gas. The
20
+ * `igniting` bit stays set until a power-cycle or paperclip reset.
21
+ * Empirically observed at the cabin on 2026-05-16. See PROTOCOL.md in the
22
+ * `valor-fireplace-cli` repo for the full empirical decode.
23
+ */
24
+ this.lockoutSuspected = false;
25
+ /**
26
+ * Schedule / timer / remote-program overlay active (status bit 9). Set when
27
+ * the handheld remote is driving the setpoint from a P1/P2 timer or schedule.
28
+ */
29
+ this.scheduleActive = false;
30
+ /** Decorative light on/off (status bit 13). Independent of brightness. */
31
+ this.lightOn = false;
32
+ /**
33
+ * Decorative light brightness setpoint, 0-255 (chars 20-21). Persists across
34
+ * light on/off — the controller remembers your last dim level.
35
+ */
36
+ this.lightBrightness = 0;
37
+ /**
38
+ * Circulating fan speed, 0-4 (chars 22-23). 0 = off, 1-4 = the four speed
39
+ * bars exposed by the Valor 10 handheld remote.
40
+ */
41
+ this.fanSpeed = 0;
42
+ /**
43
+ * Current main-burner output level, 0-255 (chars 14-15). `0x00` means pilot
44
+ * only (no main burner flame). `0xFF` means full output (Step11). Uses the
45
+ * same calibration as the outbound FlameHeight command, but in temperature
46
+ * or eco mode the firmware may report any intermediate modulated value.
47
+ */
48
+ this.burnerOutput = 0;
49
+ /**
50
+ * Pilot lit but main burner off (`guardFlameOn && burnerOutput === 0`).
51
+ * Not a distinct wire mode — just a state.
52
+ */
53
+ this.pilotOnly = false;
14
54
  const modeBits = status.substring(24, 25);
15
55
  const statusBits = status.substring(16, 20);
56
+ this.statusBitsHex = statusBits;
16
57
  this.shuttingDown = fromBitStatus(statusBits, 7);
17
58
  this.guardFlameOn = fromBitStatus(statusBits, 8);
59
+ this.scheduleActive = fromBitStatus(statusBits, 9);
18
60
  this.igniting = fromBitStatus(statusBits, 11);
61
+ this.auxOn = fromBitStatus(statusBits, 12);
62
+ this.lightOn = fromBitStatus(statusBits, 13);
63
+ this.burnerOutput = parseInt('0x' + status.substring(14, 16));
64
+ this.lightBrightness = parseInt('0x' + status.substring(20, 22));
65
+ this.fanSpeed = parseInt('0x' + status.substring(22, 24));
19
66
  this.currentTemperature = parseInt('0x' + status.substring(28, 32)) / 10;
20
67
  this.targetTemperature = parseInt('0x' + status.substring(32, 36)) / 10;
21
- this.auxOn = fromBitStatus(statusBits, 12);
68
+ this.lockoutSuspected =
69
+ this.igniting && !this.guardFlameOn && !this.shuttingDown;
70
+ this.pilotOnly = this.guardFlameOn && this.burnerOutput === 0;
22
71
  const endByte = status.substring(status.length - 2);
23
72
  let opMode = getOperationMode(modeBits, endByte);
24
73
  if (!this.guardFlameOn || this.shuttingDown) {
@@ -26,14 +75,30 @@ class FireplaceStatus {
26
75
  }
27
76
  this.mode = opMode;
28
77
  }
78
+ /**
79
+ * Display-gated burner output: returns 0 unless the guard flame is on.
80
+ * Firmware does not clear chars 14-15 on shutdown — they linger at the
81
+ * last in-flight value (e.g. `0xE7` for Step9), so the raw `burnerOutput`
82
+ * would falsely show "91%" while the pilot is dead. Use this for any
83
+ * log line or HomeKit characteristic that surfaces burner output to a
84
+ * human; use the raw `burnerOutput` only for diagnostic dumps.
85
+ */
86
+ get displayBurnerOutput() {
87
+ return this.guardFlameOn ? this.burnerOutput : 0;
88
+ }
29
89
  toString() {
30
90
  return `mode:${operationMode_1.OperationMode[this.mode]} `
31
91
  + `ignite:${this.igniting} `
32
92
  + `target:${this.targetTemperature} `
33
93
  + `aux:${this.auxOn} `
34
94
  + `current:${this.currentTemperature} `
95
+ + `burner:${this.displayBurnerOutput} `
96
+ + `fan:${this.fanSpeed} `
97
+ + `light:${this.lightOn}/${this.lightBrightness} `
35
98
  + `shutdown:${this.shuttingDown} `
36
- + `guardOn:${this.guardFlameOn}`;
99
+ + `guardOn:${this.guardFlameOn} `
100
+ + `lockout:${this.lockoutSuspected} `
101
+ + `bits:0x${this.statusBitsHex}`;
37
102
  }
38
103
  }
39
104
  exports.FireplaceStatus = FireplaceStatus;
@@ -1 +1 @@
1
- {"version":3,"file":"fireplaceStatus.js","sourceRoot":"","sources":["../../src/models/fireplaceStatus.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fireplaceStatus.js","sourceRoot":"","sources":["../../src/models/fireplaceStatus.ts"],"names":[],"mappings":";;;AAAA,mDAAgD;AAEhD,MAAa,eAAe;IA6D1B,YAAY,MAAc;QA5DV,UAAK,GAAY,KAAK,CAAC;QACvB,SAAI,GAAkB,6BAAa,CAAC,GAAG,CAAC;QACxC,uBAAkB,GAAW,EAAE,CAAC;QAChC,sBAAiB,GAAW,EAAE,CAAC;QAC/B,aAAQ,GAAY,KAAK,CAAC;QAC1B,iBAAY,GAAY,KAAK,CAAC;QAC9B,iBAAY,GAAY,KAAK,CAAC;QAC9C,oFAAoF;QACpE,kBAAa,GAAW,EAAE,CAAC;QAC3C;;;;;;;WAOG;QACa,qBAAgB,GAAY,KAAK,CAAC;QAClD;;;WAGG;QACa,mBAAc,GAAY,KAAK,CAAC;QAChD,0EAA0E;QAC1D,YAAO,GAAY,KAAK,CAAC;QACzC;;;WAGG;QACa,oBAAe,GAAW,CAAC,CAAC;QAC5C;;;WAGG;QACa,aAAQ,GAAW,CAAC,CAAC;QACrC;;;;;WAKG;QACa,iBAAY,GAAW,CAAC,CAAC;QACzC;;;WAGG;QACa,cAAS,GAAY,KAAK,CAAC;QAezC,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1C,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5C,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;QACjD,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;QACjD,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,QAAQ,GAAG,aAAa,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,KAAK,GAAG,aAAa,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAC7C,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,kBAAkB,GAAG,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;QACzE,IAAI,CAAC,iBAAiB,GAAG,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;QACxE,IAAI,CAAC,gBAAgB;YACnB,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;QAC5D,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,KAAK,CAAC,CAAC;QAC9D,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACpD,IAAI,MAAM,GAAG,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,EAAE;YAC3C,MAAM,GAAG,6BAAa,CAAC,GAAG,CAAC;SAC5B;QACD,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC;IACrB,CAAC;IApCD;;;;;;;OAOG;IACH,IAAW,mBAAmB;QAC5B,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IA4BM,QAAQ;QACb,OAAO,QAAQ,6BAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;cACnC,UAAU,IAAI,CAAC,QAAQ,GAAG;cAC1B,UAAU,IAAI,CAAC,iBAAiB,GAAG;cACnC,OAAO,IAAI,CAAC,KAAK,GAAG;cACpB,WAAW,IAAI,CAAC,kBAAkB,GAAG;cACrC,UAAU,IAAI,CAAC,mBAAmB,GAAG;cACrC,OAAO,IAAI,CAAC,QAAQ,GAAG;cACvB,SAAS,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,eAAe,GAAG;cAChD,YAAY,IAAI,CAAC,YAAY,GAAG;cAChC,WAAW,IAAI,CAAC,YAAY,GAAG;cAC/B,WAAW,IAAI,CAAC,gBAAgB,GAAG;cACnC,UAAU,IAAI,CAAC,aAAa,EAAE,CAAC;IACxC,CAAC;CACF;AArGD,0CAqGC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,gBAAgB,CAAC,QAAgB,EAAE,OAAe;IACzD,8CAA8C;IAC9C,QAAQ,QAAQ,EAAE;QAChB,KAAK,GAAG;YACN,OAAO,6BAAa,CAAC,WAAW,CAAC;QACnC,KAAK,GAAG;YACN,OAAO,6BAAa,CAAC,GAAG,CAAC;QAC3B;YACE,oDAAoD;YACpD,QAAQ,OAAO,EAAE;gBACf,KAAK,IAAI,CAAC,CAAC,kBAAkB;gBAC7B,KAAK,IAAI,CAAC,CAAC,6BAA6B;gBACxC,KAAK,IAAI,EAAE,mCAAmC;oBAC5C,OAAO,6BAAa,CAAC,WAAW,CAAC;gBACnC,KAAK,IAAI,EAAE,uBAAuB;oBAChC,OAAO,6BAAa,CAAC,MAAM,CAAC;gBAC9B;oBACE,OAAO,6BAAa,CAAC,MAAM,CAAC;aAC/B;KACJ;AACH,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,aAAa,CAAC,GAAW,EAAE,KAAa;IAC/C,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC;AAC1D,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "Valor Fireplace",
3
3
  "name": "homebridge-valor-fireplace",
4
- "version": "2.0.4",
4
+ "version": "2.1.1",
5
5
  "description": "Controls Valor Fireplace WiFi controllers, connecting real fire with Homebridge.",
6
6
  "license": "MIT",
7
7
  "author": {