@camstack/addon-provider-homematic 1.1.6 → 1.1.8
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 +125 -26
- package/dist/addon.mjs +125 -26
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -4651,7 +4651,7 @@ function preprocess(fn, schema) {
|
|
|
4651
4651
|
});
|
|
4652
4652
|
}
|
|
4653
4653
|
//#endregion
|
|
4654
|
-
//#region ../types/dist/sleep-
|
|
4654
|
+
//#region ../types/dist/sleep-DVmKHFGi.mjs
|
|
4655
4655
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
4656
4656
|
EventCategory["SystemBoot"] = "system.boot";
|
|
4657
4657
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -6451,6 +6451,17 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
6451
6451
|
DeviceRole["HumiditySensor"] = "humidity-sensor";
|
|
6452
6452
|
DeviceRole["AmbientLightSensor"] = "ambient-light-sensor";
|
|
6453
6453
|
DeviceRole["PressureSensor"] = "pressure-sensor";
|
|
6454
|
+
/** Wind speed or direction (weather-station `wind-sensor` cap). */
|
|
6455
|
+
DeviceRole["WindSensor"] = "wind-sensor";
|
|
6456
|
+
/** Rain accumulation or rate (weather-station `rain-sensor` cap). */
|
|
6457
|
+
DeviceRole["RainSensor"] = "rain-sensor";
|
|
6458
|
+
/** UV index (weather-station `uv-sensor` cap). */
|
|
6459
|
+
DeviceRole["UvSensor"] = "uv-sensor";
|
|
6460
|
+
/** Solar irradiance W/m² (weather-station `solar-radiation-sensor` cap).
|
|
6461
|
+
* Distinct from AmbientLightSensor (lux). */
|
|
6462
|
+
DeviceRole["SolarRadiationSensor"] = "solar-radiation-sensor";
|
|
6463
|
+
/** Soil moisture % (garden/weather `soil-moisture-sensor` cap). */
|
|
6464
|
+
DeviceRole["SoilMoistureSensor"] = "soil-moisture-sensor";
|
|
6454
6465
|
DeviceRole["PowerSensor"] = "power-sensor";
|
|
6455
6466
|
DeviceRole["EnergySensor"] = "energy-sensor";
|
|
6456
6467
|
DeviceRole["VoltageSensor"] = "voltage-sensor";
|
|
@@ -10075,15 +10086,18 @@ var humiditySensorCapability = {
|
|
|
10075
10086
|
runtimeState: HumiditySensorStatusSchema
|
|
10076
10087
|
};
|
|
10077
10088
|
/**
|
|
10078
|
-
* Image display cap. Models
|
|
10079
|
-
*
|
|
10089
|
+
* Image display cap. Models a single still image exposed by an integration —
|
|
10090
|
+
* a snapshot, a chart, a generated picture, or a robot's cleaning-map render.
|
|
10080
10091
|
*
|
|
10081
|
-
* Read-only: there are no setters. The provider resolves
|
|
10082
|
-
*
|
|
10083
|
-
*
|
|
10084
|
-
*
|
|
10085
|
-
*
|
|
10086
|
-
*
|
|
10092
|
+
* Read-only: there are no setters. The provider resolves whatever upstream
|
|
10093
|
+
* source it has into an ABSOLUTE URL the browser loads directly:
|
|
10094
|
+
* - HA `image.*` entities → the `entity_picture` signed-token path
|
|
10095
|
+
* (token stays in the query string, so no auth header is needed);
|
|
10096
|
+
* - a Dreame/robot map → the cloud/OSS map-image URL (or an addon
|
|
10097
|
+
* data-plane URL serving the rendered map bytes), exposed as its own
|
|
10098
|
+
* Image child device grouped under the robot's container.
|
|
10099
|
+
* The slice carries that URL plus the upstream last-updated timestamp; the
|
|
10100
|
+
* image changes when the source's last-updated marker changes.
|
|
10087
10101
|
*/
|
|
10088
10102
|
var ImageStatusSchema = object({
|
|
10089
10103
|
/** Absolute signed URL the browser loads directly. Null when the
|
|
@@ -10109,18 +10123,47 @@ var imageCapability = {
|
|
|
10109
10123
|
*/
|
|
10110
10124
|
runtimeState: ImageStatusSchema
|
|
10111
10125
|
};
|
|
10126
|
+
/**
|
|
10127
|
+
* Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
|
|
10128
|
+
* with a mowing lifecycle plus a dock action.
|
|
10129
|
+
*
|
|
10130
|
+
* Activity follows HA's canonical lawn-mower lifecycle: `idle` /
|
|
10131
|
+
* `mowing` / `paused` / `docked` / `error`. `batteryLevel` (0..100) is
|
|
10132
|
+
* nullable — some mowers don't report a battery percentage.
|
|
10133
|
+
*
|
|
10134
|
+
* `startMowing` begins a mowing run, `pause` halts it in place, and
|
|
10135
|
+
* `dock` sends the mower back to its charging station.
|
|
10136
|
+
*/
|
|
10137
|
+
var LawnMowerActivitySchema = _enum([
|
|
10138
|
+
"idle",
|
|
10139
|
+
"mowing",
|
|
10140
|
+
"paused",
|
|
10141
|
+
"docked",
|
|
10142
|
+
"error"
|
|
10143
|
+
]);
|
|
10144
|
+
/** Severity of the current device/error code — info (status), warning, error. */
|
|
10145
|
+
var DeviceCodeSeveritySchema = _enum([
|
|
10146
|
+
"info",
|
|
10147
|
+
"warning",
|
|
10148
|
+
"error"
|
|
10149
|
+
]);
|
|
10112
10150
|
var LawnMowerControlStatusSchema = object({
|
|
10113
10151
|
/** Lifecycle activity of the mower. */
|
|
10114
|
-
activity:
|
|
10115
|
-
"idle",
|
|
10116
|
-
"mowing",
|
|
10117
|
-
"paused",
|
|
10118
|
-
"docked",
|
|
10119
|
-
"error"
|
|
10120
|
-
]),
|
|
10152
|
+
activity: LawnMowerActivitySchema,
|
|
10121
10153
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
10122
10154
|
* reading. */
|
|
10123
10155
|
batteryLevel: number().min(0).max(100).nullable(),
|
|
10156
|
+
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
10157
|
+
* task is active / progress is unavailable. */
|
|
10158
|
+
progressPercent: number().min(0).max(100).nullable(),
|
|
10159
|
+
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
10160
|
+
* or null when unknown. */
|
|
10161
|
+
currentCode: number().nullable(),
|
|
10162
|
+
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
10163
|
+
currentCodeLabel: string().nullable(),
|
|
10164
|
+
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
10165
|
+
* attention; `info` is normal status. */
|
|
10166
|
+
severity: DeviceCodeSeveritySchema,
|
|
10124
10167
|
/** Ms epoch when the slice was last updated. */
|
|
10125
10168
|
lastChangedAt: number()
|
|
10126
10169
|
});
|
|
@@ -12346,6 +12389,7 @@ var VacuumStateSchema = _enum([
|
|
|
12346
12389
|
"paused",
|
|
12347
12390
|
"returning",
|
|
12348
12391
|
"docked",
|
|
12392
|
+
"drying",
|
|
12349
12393
|
"error"
|
|
12350
12394
|
]);
|
|
12351
12395
|
/**
|
|
@@ -12384,6 +12428,12 @@ var VacuumControlStatusSchema = object({
|
|
|
12384
12428
|
detergent: TankStatusSchema.nullable(),
|
|
12385
12429
|
/** Dust bin. Null when the hardware has no dust bin. */
|
|
12386
12430
|
dustBin: TankStatusSchema.nullable(),
|
|
12431
|
+
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
12432
|
+
progressPercent: number().min(0).max(100).nullable(),
|
|
12433
|
+
/** Current error code (0 / null = no error). */
|
|
12434
|
+
errorCode: number().nullable(),
|
|
12435
|
+
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
12436
|
+
errorLabel: string().nullable(),
|
|
12387
12437
|
/** Ms epoch when the slice was last updated. */
|
|
12388
12438
|
lastChangedAt: number()
|
|
12389
12439
|
});
|
|
@@ -13350,9 +13400,29 @@ var BaseDevice = class {
|
|
|
13350
13400
|
* is open (Reolink writes `hasPtz/hasIntercom`, Hikvision writes
|
|
13351
13401
|
* `hasSupplementalLight/hasAlarmIo`, etc).
|
|
13352
13402
|
*
|
|
13353
|
-
* Default:
|
|
13354
|
-
|
|
13355
|
-
|
|
13403
|
+
* Default: nothing to probe → mark the device PROBED (set `lastProbedAt`) so
|
|
13404
|
+
* the kernel treats it as ready immediately. A device that derives its shape
|
|
13405
|
+
* from a spec (a container, or an accessory sensor) rather than from a
|
|
13406
|
+
* hardware probe has no probe to "complete"; without stamping `lastProbedAt`
|
|
13407
|
+
* it would look perpetually un-probed — logging "Initial probe did not
|
|
13408
|
+
* complete" on every boot and spinning a pointless retry chain. Drivers that
|
|
13409
|
+
* DO probe override this and write their own `feature-probe` slice (including
|
|
13410
|
+
* `lastProbedAt`) once their probe actually succeeds.
|
|
13411
|
+
*/
|
|
13412
|
+
async onProbe() {
|
|
13413
|
+
const base = this.runtimeState.getCapState("feature-probe") ?? {
|
|
13414
|
+
flags: {},
|
|
13415
|
+
deviceType: null,
|
|
13416
|
+
model: null,
|
|
13417
|
+
channelCount: null,
|
|
13418
|
+
lastProbedAt: 0,
|
|
13419
|
+
lastFetchedAt: 0
|
|
13420
|
+
};
|
|
13421
|
+
this.runtimeState.setCapState("feature-probe", {
|
|
13422
|
+
...base,
|
|
13423
|
+
lastProbedAt: Date.now()
|
|
13424
|
+
});
|
|
13425
|
+
}
|
|
13356
13426
|
/**
|
|
13357
13427
|
* Phase 5 — fired after the device + its accessories are registered.
|
|
13358
13428
|
* Drivers publish streams to the broker, kick off background tasks,
|
|
@@ -14814,17 +14884,32 @@ var ReleaseInputSchema = object({
|
|
|
14814
14884
|
* the parent cascades into every accessory. */
|
|
14815
14885
|
camDeviceId: number().int().nonnegative()
|
|
14816
14886
|
});
|
|
14817
|
-
var ResyncInputSchema = object({
|
|
14818
|
-
/** Parent CamStack device id of an adopted device. The provider resolves its
|
|
14819
|
-
* source (integration/broker + native id) and re-aligns the device's
|
|
14820
|
-
* structural spec (type/role/capabilities/units) with the live mapping,
|
|
14821
|
-
* rebuilding any child whose class changed while preserving operator edits. */
|
|
14822
|
-
camDeviceId: number().int().nonnegative()
|
|
14887
|
+
var ResyncInputSchema = object({
|
|
14888
|
+
/** Parent CamStack device id of an adopted device. The provider resolves its
|
|
14889
|
+
* source (integration/broker + native id) and re-aligns the device's
|
|
14890
|
+
* structural spec (type/role/capabilities/units) with the live mapping,
|
|
14891
|
+
* rebuilding any child whose class changed while preserving operator edits. */
|
|
14892
|
+
camDeviceId: number().int().nonnegative(),
|
|
14893
|
+
/** "Resync from zero" (#19). When true, the kernel PURGES every accessory
|
|
14894
|
+
* child of `camDeviceId` BEFORE the provider re-derives the device, so the
|
|
14895
|
+
* children are rebuilt fresh from source — correct names, coords, and units —
|
|
14896
|
+
* instead of being preserved by the incremental reconcile. Use to recover from
|
|
14897
|
+
* legacy generic/placeholder names that the normal name-precedence keeps frozen
|
|
14898
|
+
* (the operator's explicit reset). Push-driven integrations (no-op resync)
|
|
14899
|
+
* rebuild on their next snapshot; pull/command integrations rebuild in `resync`.
|
|
14900
|
+
* Operator edits on the PARENT (its name, layout, primary-child pick) survive —
|
|
14901
|
+
* only the children are torn down. Omitted/false ⇒ the normal incremental
|
|
14902
|
+
* re-sync that preserves children. */
|
|
14903
|
+
resetToSource: boolean().optional()
|
|
14904
|
+
});
|
|
14823
14905
|
var ResyncResultSchema = object({
|
|
14824
14906
|
/** True when the persisted spec actually changed (children may have been rebuilt). */
|
|
14825
14907
|
changed: boolean(),
|
|
14826
14908
|
/** Number of child devices rebuilt into a new class by this re-sync. */
|
|
14827
|
-
rebuiltChildren: number().int().nonnegative()
|
|
14909
|
+
rebuiltChildren: number().int().nonnegative(),
|
|
14910
|
+
/** Number of accessory children torn down by a `resetToSource` purge before the
|
|
14911
|
+
* provider re-derived the device. 0/absent for a normal incremental re-sync. */
|
|
14912
|
+
removedChildren: number().int().nonnegative().optional()
|
|
14828
14913
|
});
|
|
14829
14914
|
var deviceAdoptionCapability = {
|
|
14830
14915
|
name: "device-adoption",
|
|
@@ -16589,6 +16674,11 @@ var DeviceMetaSchema = object({
|
|
|
16589
16674
|
addonId: string(),
|
|
16590
16675
|
type: string(),
|
|
16591
16676
|
name: string(),
|
|
16677
|
+
/** True once an operator explicitly renamed the device via `setName`. Drives
|
|
16678
|
+
* reconcile name-precedence (preserve operator name vs adopt fresh provider
|
|
16679
|
+
* name). Absent ⇒ treated as user-named (PRESERVE) for legacy rows. See
|
|
16680
|
+
* `DeviceMeta.userNamed`. */
|
|
16681
|
+
userNamed: boolean().optional(),
|
|
16592
16682
|
location: string().nullable(),
|
|
16593
16683
|
disabled: boolean(),
|
|
16594
16684
|
parentDeviceId: number().nullable(),
|
|
@@ -16899,6 +16989,9 @@ method(object({
|
|
|
16899
16989
|
}), method(ReleaseInputSchema.extend({ addonId: string() }), _void(), {
|
|
16900
16990
|
kind: "mutation",
|
|
16901
16991
|
auth: "admin"
|
|
16992
|
+
}), method(ResyncInputSchema, ResyncResultSchema, {
|
|
16993
|
+
kind: "mutation",
|
|
16994
|
+
auth: "admin"
|
|
16902
16995
|
}), method(object({
|
|
16903
16996
|
deviceId: number(),
|
|
16904
16997
|
key: string(),
|
|
@@ -20661,6 +20754,12 @@ Object.freeze({
|
|
|
20661
20754
|
addonId: null,
|
|
20662
20755
|
access: "create"
|
|
20663
20756
|
},
|
|
20757
|
+
"deviceManager.adoptionResync": {
|
|
20758
|
+
capName: "device-manager",
|
|
20759
|
+
capScope: "system",
|
|
20760
|
+
addonId: null,
|
|
20761
|
+
access: "create"
|
|
20762
|
+
},
|
|
20664
20763
|
"deviceManager.allocateDeviceId": {
|
|
20665
20764
|
capName: "device-manager",
|
|
20666
20765
|
capScope: "system",
|
package/dist/addon.mjs
CHANGED
|
@@ -4652,7 +4652,7 @@ function preprocess(fn, schema) {
|
|
|
4652
4652
|
});
|
|
4653
4653
|
}
|
|
4654
4654
|
//#endregion
|
|
4655
|
-
//#region ../types/dist/sleep-
|
|
4655
|
+
//#region ../types/dist/sleep-DVmKHFGi.mjs
|
|
4656
4656
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
4657
4657
|
EventCategory["SystemBoot"] = "system.boot";
|
|
4658
4658
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -6452,6 +6452,17 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
6452
6452
|
DeviceRole["HumiditySensor"] = "humidity-sensor";
|
|
6453
6453
|
DeviceRole["AmbientLightSensor"] = "ambient-light-sensor";
|
|
6454
6454
|
DeviceRole["PressureSensor"] = "pressure-sensor";
|
|
6455
|
+
/** Wind speed or direction (weather-station `wind-sensor` cap). */
|
|
6456
|
+
DeviceRole["WindSensor"] = "wind-sensor";
|
|
6457
|
+
/** Rain accumulation or rate (weather-station `rain-sensor` cap). */
|
|
6458
|
+
DeviceRole["RainSensor"] = "rain-sensor";
|
|
6459
|
+
/** UV index (weather-station `uv-sensor` cap). */
|
|
6460
|
+
DeviceRole["UvSensor"] = "uv-sensor";
|
|
6461
|
+
/** Solar irradiance W/m² (weather-station `solar-radiation-sensor` cap).
|
|
6462
|
+
* Distinct from AmbientLightSensor (lux). */
|
|
6463
|
+
DeviceRole["SolarRadiationSensor"] = "solar-radiation-sensor";
|
|
6464
|
+
/** Soil moisture % (garden/weather `soil-moisture-sensor` cap). */
|
|
6465
|
+
DeviceRole["SoilMoistureSensor"] = "soil-moisture-sensor";
|
|
6455
6466
|
DeviceRole["PowerSensor"] = "power-sensor";
|
|
6456
6467
|
DeviceRole["EnergySensor"] = "energy-sensor";
|
|
6457
6468
|
DeviceRole["VoltageSensor"] = "voltage-sensor";
|
|
@@ -10076,15 +10087,18 @@ var humiditySensorCapability = {
|
|
|
10076
10087
|
runtimeState: HumiditySensorStatusSchema
|
|
10077
10088
|
};
|
|
10078
10089
|
/**
|
|
10079
|
-
* Image display cap. Models
|
|
10080
|
-
*
|
|
10090
|
+
* Image display cap. Models a single still image exposed by an integration —
|
|
10091
|
+
* a snapshot, a chart, a generated picture, or a robot's cleaning-map render.
|
|
10081
10092
|
*
|
|
10082
|
-
* Read-only: there are no setters. The provider resolves
|
|
10083
|
-
*
|
|
10084
|
-
*
|
|
10085
|
-
*
|
|
10086
|
-
*
|
|
10087
|
-
*
|
|
10093
|
+
* Read-only: there are no setters. The provider resolves whatever upstream
|
|
10094
|
+
* source it has into an ABSOLUTE URL the browser loads directly:
|
|
10095
|
+
* - HA `image.*` entities → the `entity_picture` signed-token path
|
|
10096
|
+
* (token stays in the query string, so no auth header is needed);
|
|
10097
|
+
* - a Dreame/robot map → the cloud/OSS map-image URL (or an addon
|
|
10098
|
+
* data-plane URL serving the rendered map bytes), exposed as its own
|
|
10099
|
+
* Image child device grouped under the robot's container.
|
|
10100
|
+
* The slice carries that URL plus the upstream last-updated timestamp; the
|
|
10101
|
+
* image changes when the source's last-updated marker changes.
|
|
10088
10102
|
*/
|
|
10089
10103
|
var ImageStatusSchema = object({
|
|
10090
10104
|
/** Absolute signed URL the browser loads directly. Null when the
|
|
@@ -10110,18 +10124,47 @@ var imageCapability = {
|
|
|
10110
10124
|
*/
|
|
10111
10125
|
runtimeState: ImageStatusSchema
|
|
10112
10126
|
};
|
|
10127
|
+
/**
|
|
10128
|
+
* Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
|
|
10129
|
+
* with a mowing lifecycle plus a dock action.
|
|
10130
|
+
*
|
|
10131
|
+
* Activity follows HA's canonical lawn-mower lifecycle: `idle` /
|
|
10132
|
+
* `mowing` / `paused` / `docked` / `error`. `batteryLevel` (0..100) is
|
|
10133
|
+
* nullable — some mowers don't report a battery percentage.
|
|
10134
|
+
*
|
|
10135
|
+
* `startMowing` begins a mowing run, `pause` halts it in place, and
|
|
10136
|
+
* `dock` sends the mower back to its charging station.
|
|
10137
|
+
*/
|
|
10138
|
+
var LawnMowerActivitySchema = _enum([
|
|
10139
|
+
"idle",
|
|
10140
|
+
"mowing",
|
|
10141
|
+
"paused",
|
|
10142
|
+
"docked",
|
|
10143
|
+
"error"
|
|
10144
|
+
]);
|
|
10145
|
+
/** Severity of the current device/error code — info (status), warning, error. */
|
|
10146
|
+
var DeviceCodeSeveritySchema = _enum([
|
|
10147
|
+
"info",
|
|
10148
|
+
"warning",
|
|
10149
|
+
"error"
|
|
10150
|
+
]);
|
|
10113
10151
|
var LawnMowerControlStatusSchema = object({
|
|
10114
10152
|
/** Lifecycle activity of the mower. */
|
|
10115
|
-
activity:
|
|
10116
|
-
"idle",
|
|
10117
|
-
"mowing",
|
|
10118
|
-
"paused",
|
|
10119
|
-
"docked",
|
|
10120
|
-
"error"
|
|
10121
|
-
]),
|
|
10153
|
+
activity: LawnMowerActivitySchema,
|
|
10122
10154
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
10123
10155
|
* reading. */
|
|
10124
10156
|
batteryLevel: number().min(0).max(100).nullable(),
|
|
10157
|
+
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
10158
|
+
* task is active / progress is unavailable. */
|
|
10159
|
+
progressPercent: number().min(0).max(100).nullable(),
|
|
10160
|
+
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
10161
|
+
* or null when unknown. */
|
|
10162
|
+
currentCode: number().nullable(),
|
|
10163
|
+
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
10164
|
+
currentCodeLabel: string().nullable(),
|
|
10165
|
+
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
10166
|
+
* attention; `info` is normal status. */
|
|
10167
|
+
severity: DeviceCodeSeveritySchema,
|
|
10125
10168
|
/** Ms epoch when the slice was last updated. */
|
|
10126
10169
|
lastChangedAt: number()
|
|
10127
10170
|
});
|
|
@@ -12347,6 +12390,7 @@ var VacuumStateSchema = _enum([
|
|
|
12347
12390
|
"paused",
|
|
12348
12391
|
"returning",
|
|
12349
12392
|
"docked",
|
|
12393
|
+
"drying",
|
|
12350
12394
|
"error"
|
|
12351
12395
|
]);
|
|
12352
12396
|
/**
|
|
@@ -12385,6 +12429,12 @@ var VacuumControlStatusSchema = object({
|
|
|
12385
12429
|
detergent: TankStatusSchema.nullable(),
|
|
12386
12430
|
/** Dust bin. Null when the hardware has no dust bin. */
|
|
12387
12431
|
dustBin: TankStatusSchema.nullable(),
|
|
12432
|
+
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
12433
|
+
progressPercent: number().min(0).max(100).nullable(),
|
|
12434
|
+
/** Current error code (0 / null = no error). */
|
|
12435
|
+
errorCode: number().nullable(),
|
|
12436
|
+
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
12437
|
+
errorLabel: string().nullable(),
|
|
12388
12438
|
/** Ms epoch when the slice was last updated. */
|
|
12389
12439
|
lastChangedAt: number()
|
|
12390
12440
|
});
|
|
@@ -13351,9 +13401,29 @@ var BaseDevice = class {
|
|
|
13351
13401
|
* is open (Reolink writes `hasPtz/hasIntercom`, Hikvision writes
|
|
13352
13402
|
* `hasSupplementalLight/hasAlarmIo`, etc).
|
|
13353
13403
|
*
|
|
13354
|
-
* Default:
|
|
13355
|
-
|
|
13356
|
-
|
|
13404
|
+
* Default: nothing to probe → mark the device PROBED (set `lastProbedAt`) so
|
|
13405
|
+
* the kernel treats it as ready immediately. A device that derives its shape
|
|
13406
|
+
* from a spec (a container, or an accessory sensor) rather than from a
|
|
13407
|
+
* hardware probe has no probe to "complete"; without stamping `lastProbedAt`
|
|
13408
|
+
* it would look perpetually un-probed — logging "Initial probe did not
|
|
13409
|
+
* complete" on every boot and spinning a pointless retry chain. Drivers that
|
|
13410
|
+
* DO probe override this and write their own `feature-probe` slice (including
|
|
13411
|
+
* `lastProbedAt`) once their probe actually succeeds.
|
|
13412
|
+
*/
|
|
13413
|
+
async onProbe() {
|
|
13414
|
+
const base = this.runtimeState.getCapState("feature-probe") ?? {
|
|
13415
|
+
flags: {},
|
|
13416
|
+
deviceType: null,
|
|
13417
|
+
model: null,
|
|
13418
|
+
channelCount: null,
|
|
13419
|
+
lastProbedAt: 0,
|
|
13420
|
+
lastFetchedAt: 0
|
|
13421
|
+
};
|
|
13422
|
+
this.runtimeState.setCapState("feature-probe", {
|
|
13423
|
+
...base,
|
|
13424
|
+
lastProbedAt: Date.now()
|
|
13425
|
+
});
|
|
13426
|
+
}
|
|
13357
13427
|
/**
|
|
13358
13428
|
* Phase 5 — fired after the device + its accessories are registered.
|
|
13359
13429
|
* Drivers publish streams to the broker, kick off background tasks,
|
|
@@ -14815,17 +14885,32 @@ var ReleaseInputSchema = object({
|
|
|
14815
14885
|
* the parent cascades into every accessory. */
|
|
14816
14886
|
camDeviceId: number().int().nonnegative()
|
|
14817
14887
|
});
|
|
14818
|
-
var ResyncInputSchema = object({
|
|
14819
|
-
/** Parent CamStack device id of an adopted device. The provider resolves its
|
|
14820
|
-
* source (integration/broker + native id) and re-aligns the device's
|
|
14821
|
-
* structural spec (type/role/capabilities/units) with the live mapping,
|
|
14822
|
-
* rebuilding any child whose class changed while preserving operator edits. */
|
|
14823
|
-
camDeviceId: number().int().nonnegative()
|
|
14888
|
+
var ResyncInputSchema = object({
|
|
14889
|
+
/** Parent CamStack device id of an adopted device. The provider resolves its
|
|
14890
|
+
* source (integration/broker + native id) and re-aligns the device's
|
|
14891
|
+
* structural spec (type/role/capabilities/units) with the live mapping,
|
|
14892
|
+
* rebuilding any child whose class changed while preserving operator edits. */
|
|
14893
|
+
camDeviceId: number().int().nonnegative(),
|
|
14894
|
+
/** "Resync from zero" (#19). When true, the kernel PURGES every accessory
|
|
14895
|
+
* child of `camDeviceId` BEFORE the provider re-derives the device, so the
|
|
14896
|
+
* children are rebuilt fresh from source — correct names, coords, and units —
|
|
14897
|
+
* instead of being preserved by the incremental reconcile. Use to recover from
|
|
14898
|
+
* legacy generic/placeholder names that the normal name-precedence keeps frozen
|
|
14899
|
+
* (the operator's explicit reset). Push-driven integrations (no-op resync)
|
|
14900
|
+
* rebuild on their next snapshot; pull/command integrations rebuild in `resync`.
|
|
14901
|
+
* Operator edits on the PARENT (its name, layout, primary-child pick) survive —
|
|
14902
|
+
* only the children are torn down. Omitted/false ⇒ the normal incremental
|
|
14903
|
+
* re-sync that preserves children. */
|
|
14904
|
+
resetToSource: boolean().optional()
|
|
14905
|
+
});
|
|
14824
14906
|
var ResyncResultSchema = object({
|
|
14825
14907
|
/** True when the persisted spec actually changed (children may have been rebuilt). */
|
|
14826
14908
|
changed: boolean(),
|
|
14827
14909
|
/** Number of child devices rebuilt into a new class by this re-sync. */
|
|
14828
|
-
rebuiltChildren: number().int().nonnegative()
|
|
14910
|
+
rebuiltChildren: number().int().nonnegative(),
|
|
14911
|
+
/** Number of accessory children torn down by a `resetToSource` purge before the
|
|
14912
|
+
* provider re-derived the device. 0/absent for a normal incremental re-sync. */
|
|
14913
|
+
removedChildren: number().int().nonnegative().optional()
|
|
14829
14914
|
});
|
|
14830
14915
|
var deviceAdoptionCapability = {
|
|
14831
14916
|
name: "device-adoption",
|
|
@@ -16590,6 +16675,11 @@ var DeviceMetaSchema = object({
|
|
|
16590
16675
|
addonId: string(),
|
|
16591
16676
|
type: string(),
|
|
16592
16677
|
name: string(),
|
|
16678
|
+
/** True once an operator explicitly renamed the device via `setName`. Drives
|
|
16679
|
+
* reconcile name-precedence (preserve operator name vs adopt fresh provider
|
|
16680
|
+
* name). Absent ⇒ treated as user-named (PRESERVE) for legacy rows. See
|
|
16681
|
+
* `DeviceMeta.userNamed`. */
|
|
16682
|
+
userNamed: boolean().optional(),
|
|
16593
16683
|
location: string().nullable(),
|
|
16594
16684
|
disabled: boolean(),
|
|
16595
16685
|
parentDeviceId: number().nullable(),
|
|
@@ -16900,6 +16990,9 @@ method(object({
|
|
|
16900
16990
|
}), method(ReleaseInputSchema.extend({ addonId: string() }), _void(), {
|
|
16901
16991
|
kind: "mutation",
|
|
16902
16992
|
auth: "admin"
|
|
16993
|
+
}), method(ResyncInputSchema, ResyncResultSchema, {
|
|
16994
|
+
kind: "mutation",
|
|
16995
|
+
auth: "admin"
|
|
16903
16996
|
}), method(object({
|
|
16904
16997
|
deviceId: number(),
|
|
16905
16998
|
key: string(),
|
|
@@ -20662,6 +20755,12 @@ Object.freeze({
|
|
|
20662
20755
|
addonId: null,
|
|
20663
20756
|
access: "create"
|
|
20664
20757
|
},
|
|
20758
|
+
"deviceManager.adoptionResync": {
|
|
20759
|
+
capName: "device-manager",
|
|
20760
|
+
capScope: "system",
|
|
20761
|
+
addonId: null,
|
|
20762
|
+
access: "create"
|
|
20763
|
+
},
|
|
20665
20764
|
"deviceManager.allocateDeviceId": {
|
|
20666
20765
|
capName: "device-manager",
|
|
20667
20766
|
capScope: "system",
|
package/package.json
CHANGED