@camstack/addon-provider-rademacher 0.2.72 → 0.2.74
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/addon.js +51 -0
- package/dist/addon.mjs +51 -0
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -34453,6 +34453,53 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
34453
34453
|
const ids = [...this._permanentRestoreFailures.keys()].join(", ");
|
|
34454
34454
|
return `${this._permanentRestoreFailures.size} device(s) permanently failed restore (deviceIds: ${ids}) — restart the ${this.providerName} provider to retry`;
|
|
34455
34455
|
}
|
|
34456
|
+
/**
|
|
34457
|
+
* A top-level persisted row with NO configuration is a leftover, not a
|
|
34458
|
+
* device — quarantine it instead of dialling it.
|
|
34459
|
+
*
|
|
34460
|
+
* Device 614 was deleted, resurrected as a config-less shell by a write
|
|
34461
|
+
* already in flight (D376), and then dialled at every single boot: eight
|
|
34462
|
+
* `Failed to restore device — bounded retry scheduled` lines in one day,
|
|
34463
|
+
* each one the same Zod refusal on `host` and `password`. The bound was
|
|
34464
|
+
* real, but it is a bound PER PROCESS, and the runner restarts — so nothing
|
|
34465
|
+
* about the row ever stopped costing attempts and log lines.
|
|
34466
|
+
*
|
|
34467
|
+
* No retry can add a configuration that is not there. The row is reported
|
|
34468
|
+
* once, with its `deviceId`, and set aside.
|
|
34469
|
+
*
|
|
34470
|
+
* Top-level only: an accessory child legitimately carries an empty blob (it
|
|
34471
|
+
* lives off its parent), and a hub-adopted child with an emptied blob is
|
|
34472
|
+
* repaired by `healSavedConfig` from its parent instead. Providers that
|
|
34473
|
+
* genuinely create configuration-free top-level devices turn this off.
|
|
34474
|
+
*/
|
|
34475
|
+
quarantineConfiglessTopLevelRestores = true;
|
|
34476
|
+
isUnrestorableShell(saved) {
|
|
34477
|
+
if (!this.quarantineConfiglessTopLevelRestores) return false;
|
|
34478
|
+
if (saved.parentDeviceId !== null) return false;
|
|
34479
|
+
const config = saved.config;
|
|
34480
|
+
if (config === void 0) return false;
|
|
34481
|
+
return Object.keys(config).length === 0;
|
|
34482
|
+
}
|
|
34483
|
+
quarantineShell(saved) {
|
|
34484
|
+
this._permanentRestoreFailures.set(saved.id, {
|
|
34485
|
+
deviceId: saved.id,
|
|
34486
|
+
stableId: saved.stableId,
|
|
34487
|
+
type: saved.type,
|
|
34488
|
+
attempts: 0,
|
|
34489
|
+
lastError: "persisted row has no configuration",
|
|
34490
|
+
failedAt: Date.now()
|
|
34491
|
+
});
|
|
34492
|
+
this.ctx.logger.error("Persisted device row has NO configuration — quarantined: not restored, not retried. Remove it (deviceManager.removeDevice) or re-add the device.", {
|
|
34493
|
+
tags: {
|
|
34494
|
+
deviceId: saved.id,
|
|
34495
|
+
stableId: saved.stableId
|
|
34496
|
+
},
|
|
34497
|
+
meta: {
|
|
34498
|
+
type: saved.type,
|
|
34499
|
+
provider: this.providerName
|
|
34500
|
+
}
|
|
34501
|
+
});
|
|
34502
|
+
}
|
|
34456
34503
|
cancelRestoreRetries() {
|
|
34457
34504
|
this._restoreRetryScheduler?.cancel();
|
|
34458
34505
|
this._restoreRetryScheduler = null;
|
|
@@ -34637,6 +34684,10 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
34637
34684
|
});
|
|
34638
34685
|
return;
|
|
34639
34686
|
}
|
|
34687
|
+
if (this.isUnrestorableShell(saved)) {
|
|
34688
|
+
this.quarantineShell(saved);
|
|
34689
|
+
return;
|
|
34690
|
+
}
|
|
34640
34691
|
try {
|
|
34641
34692
|
await attemptRestore(saved);
|
|
34642
34693
|
} catch (err) {
|
package/dist/addon.mjs
CHANGED
|
@@ -34452,6 +34452,53 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
34452
34452
|
const ids = [...this._permanentRestoreFailures.keys()].join(", ");
|
|
34453
34453
|
return `${this._permanentRestoreFailures.size} device(s) permanently failed restore (deviceIds: ${ids}) — restart the ${this.providerName} provider to retry`;
|
|
34454
34454
|
}
|
|
34455
|
+
/**
|
|
34456
|
+
* A top-level persisted row with NO configuration is a leftover, not a
|
|
34457
|
+
* device — quarantine it instead of dialling it.
|
|
34458
|
+
*
|
|
34459
|
+
* Device 614 was deleted, resurrected as a config-less shell by a write
|
|
34460
|
+
* already in flight (D376), and then dialled at every single boot: eight
|
|
34461
|
+
* `Failed to restore device — bounded retry scheduled` lines in one day,
|
|
34462
|
+
* each one the same Zod refusal on `host` and `password`. The bound was
|
|
34463
|
+
* real, but it is a bound PER PROCESS, and the runner restarts — so nothing
|
|
34464
|
+
* about the row ever stopped costing attempts and log lines.
|
|
34465
|
+
*
|
|
34466
|
+
* No retry can add a configuration that is not there. The row is reported
|
|
34467
|
+
* once, with its `deviceId`, and set aside.
|
|
34468
|
+
*
|
|
34469
|
+
* Top-level only: an accessory child legitimately carries an empty blob (it
|
|
34470
|
+
* lives off its parent), and a hub-adopted child with an emptied blob is
|
|
34471
|
+
* repaired by `healSavedConfig` from its parent instead. Providers that
|
|
34472
|
+
* genuinely create configuration-free top-level devices turn this off.
|
|
34473
|
+
*/
|
|
34474
|
+
quarantineConfiglessTopLevelRestores = true;
|
|
34475
|
+
isUnrestorableShell(saved) {
|
|
34476
|
+
if (!this.quarantineConfiglessTopLevelRestores) return false;
|
|
34477
|
+
if (saved.parentDeviceId !== null) return false;
|
|
34478
|
+
const config = saved.config;
|
|
34479
|
+
if (config === void 0) return false;
|
|
34480
|
+
return Object.keys(config).length === 0;
|
|
34481
|
+
}
|
|
34482
|
+
quarantineShell(saved) {
|
|
34483
|
+
this._permanentRestoreFailures.set(saved.id, {
|
|
34484
|
+
deviceId: saved.id,
|
|
34485
|
+
stableId: saved.stableId,
|
|
34486
|
+
type: saved.type,
|
|
34487
|
+
attempts: 0,
|
|
34488
|
+
lastError: "persisted row has no configuration",
|
|
34489
|
+
failedAt: Date.now()
|
|
34490
|
+
});
|
|
34491
|
+
this.ctx.logger.error("Persisted device row has NO configuration — quarantined: not restored, not retried. Remove it (deviceManager.removeDevice) or re-add the device.", {
|
|
34492
|
+
tags: {
|
|
34493
|
+
deviceId: saved.id,
|
|
34494
|
+
stableId: saved.stableId
|
|
34495
|
+
},
|
|
34496
|
+
meta: {
|
|
34497
|
+
type: saved.type,
|
|
34498
|
+
provider: this.providerName
|
|
34499
|
+
}
|
|
34500
|
+
});
|
|
34501
|
+
}
|
|
34455
34502
|
cancelRestoreRetries() {
|
|
34456
34503
|
this._restoreRetryScheduler?.cancel();
|
|
34457
34504
|
this._restoreRetryScheduler = null;
|
|
@@ -34636,6 +34683,10 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
34636
34683
|
});
|
|
34637
34684
|
return;
|
|
34638
34685
|
}
|
|
34686
|
+
if (this.isUnrestorableShell(saved)) {
|
|
34687
|
+
this.quarantineShell(saved);
|
|
34688
|
+
return;
|
|
34689
|
+
}
|
|
34639
34690
|
try {
|
|
34640
34691
|
await attemptRestore(saved);
|
|
34641
34692
|
} catch (err) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-rademacher",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.74",
|
|
4
4
|
"description": "Rademacher HomePilot device-provider addon for CamStack — wraps the @apocaliss92/noderademacher local-hub client (roller shutters over the cover cap)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|