@riddix/hamh 2.1.0-alpha.566 → 2.1.0-alpha.567
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/dist/backend/cli.js
CHANGED
|
@@ -177925,18 +177925,6 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
|
|
|
177925
177925
|
this.state.operationalError = { errorStateId: ErrorState.NoError };
|
|
177926
177926
|
await super.initialize();
|
|
177927
177927
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
177928
|
-
try {
|
|
177929
|
-
const events = this.events;
|
|
177930
|
-
events.operationalError$Changed?.on(() => {
|
|
177931
|
-
logger195.info(
|
|
177932
|
-
`#287 diag[3]: operationalError$Changed fired for ${homeAssistant.entityId}`
|
|
177933
|
-
);
|
|
177934
|
-
});
|
|
177935
|
-
} catch (e) {
|
|
177936
|
-
logger195.warn(
|
|
177937
|
-
`#287 diag[3]: failed to attach operationalError$Changed listener: ${e instanceof Error ? e.message : String(e)}`
|
|
177938
|
-
);
|
|
177939
|
-
}
|
|
177940
177928
|
this.update(homeAssistant.entity);
|
|
177941
177929
|
this.reactTo(homeAssistant.onChange, this.update);
|
|
177942
177930
|
}
|
|
@@ -177949,9 +177937,6 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
|
|
|
177949
177937
|
this.agent
|
|
177950
177938
|
);
|
|
177951
177939
|
const previousState = this.state.operationalState;
|
|
177952
|
-
logger195.info(
|
|
177953
|
-
`#287 diag[2]: update() reactor invoked for ${entity.entity_id} \u2014 prevState=${previousState} newState=${newState} nonceBefore=${this.keepaliveNonce}`
|
|
177954
|
-
);
|
|
177955
177940
|
this.keepaliveNonce = !this.keepaliveNonce;
|
|
177956
177941
|
const errorStateId = newState === OperationalState4.Error ? ErrorState.Stuck : ErrorState.NoError;
|
|
177957
177942
|
const operationalError = { errorStateId };
|
|
@@ -181186,20 +181171,32 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
181186
181171
|
lastState;
|
|
181187
181172
|
pendingMappedChange = false;
|
|
181188
181173
|
flushUpdate;
|
|
181189
|
-
/** Periodic keepalive timer that
|
|
181190
|
-
*
|
|
181191
|
-
*
|
|
181174
|
+
/** Periodic keepalive timer that writes directly to the
|
|
181175
|
+
* RvcOperationalState cluster in a fresh transaction so Apple Home
|
|
181176
|
+
* (iOS) doesn't show "Updating..." due to stale subscription data
|
|
181177
|
+
* when the vacuum is idle and no HA events fire.
|
|
181178
|
+
*
|
|
181179
|
+
* Previous approaches that pushed state through
|
|
181180
|
+
* HomeAssistantEntityBehavior failed because the reactor writes
|
|
181181
|
+
* (RvcOperationalStateServer.update()) run inside the postCommit
|
|
181182
|
+
* phase of the HAEntityBehavior transaction — those writes are
|
|
181183
|
+
* buffered but never committed, so no attrsChanged event reaches
|
|
181184
|
+
* the ServerSubscription.
|
|
181185
|
+
*
|
|
181186
|
+
* Writing directly via endpoint.act() creates an independent
|
|
181187
|
+
* transaction that goes through the full commit lifecycle. */
|
|
181192
181188
|
keepaliveTimer;
|
|
181189
|
+
/** Alternating nonce so operationalError is structurally different
|
|
181190
|
+
* each keepalive tick. matter.js's Datasource uses isDeepEqual;
|
|
181191
|
+
* toggling errorStateDetails between absent and "" changes the
|
|
181192
|
+
* property count so the struct is never deep-equal. */
|
|
181193
|
+
keepaliveNonce = false;
|
|
181193
181194
|
constructor(type, entityId, customName, mappedEntityIds) {
|
|
181194
181195
|
super(type, entityId, customName, mappedEntityIds);
|
|
181195
181196
|
this.flushUpdate = debounce6(this.flushPendingUpdate.bind(this), 50);
|
|
181196
181197
|
this.keepaliveTimer = setInterval(() => {
|
|
181197
181198
|
if (this.lastState) {
|
|
181198
|
-
|
|
181199
|
-
`#287 diag[1]: keepalive tick for ${this.entityId} \u2014 scheduling flushUpdate`
|
|
181200
|
-
);
|
|
181201
|
-
this.pendingMappedChange = true;
|
|
181202
|
-
this.flushUpdate(this.lastState);
|
|
181199
|
+
this.pushKeepalive();
|
|
181203
181200
|
}
|
|
181204
181201
|
}, 55e3);
|
|
181205
181202
|
}
|
|
@@ -181211,6 +181208,35 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
181211
181208
|
this.flushUpdate.clear();
|
|
181212
181209
|
await super.delete();
|
|
181213
181210
|
}
|
|
181211
|
+
/**
|
|
181212
|
+
* Write directly to the RvcOperationalState cluster in a fresh
|
|
181213
|
+
* transaction. The nonce toggles errorStateDetails between absent
|
|
181214
|
+
* and "" so the struct is structurally different each call,
|
|
181215
|
+
* guaranteeing matter.js emits attrsChanged → subscription report.
|
|
181216
|
+
*/
|
|
181217
|
+
async pushKeepalive() {
|
|
181218
|
+
try {
|
|
181219
|
+
await this.act("vacuum-keepalive", async (agent) => {
|
|
181220
|
+
const opState = agent.get(RvcOperationalStateServer);
|
|
181221
|
+
this.keepaliveNonce = !this.keepaliveNonce;
|
|
181222
|
+
const errorStateId = opState.state.operationalError.errorStateId;
|
|
181223
|
+
const operationalError = { errorStateId };
|
|
181224
|
+
if (this.keepaliveNonce) {
|
|
181225
|
+
operationalError.errorStateDetails = "";
|
|
181226
|
+
}
|
|
181227
|
+
opState.state.operationalError = operationalError;
|
|
181228
|
+
});
|
|
181229
|
+
} catch (e) {
|
|
181230
|
+
if (e instanceof TransactionDestroyedError || e instanceof DestroyedDependencyError) {
|
|
181231
|
+
return;
|
|
181232
|
+
}
|
|
181233
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
181234
|
+
if (msg.includes("Endpoint storage inaccessible")) {
|
|
181235
|
+
return;
|
|
181236
|
+
}
|
|
181237
|
+
logger203.debug(`Keepalive failed for ${this.entityId}: ${msg}`);
|
|
181238
|
+
}
|
|
181239
|
+
}
|
|
181214
181240
|
async updateStates(states) {
|
|
181215
181241
|
const state = states[this.entityId] ?? {};
|
|
181216
181242
|
const mappedChanged = this.hasMappedEntityChanged(states);
|