@camstack/addon-provider-homematic 1.1.7 → 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.
Files changed (3) hide show
  1. package/dist/addon.js +113 -25
  2. package/dist/addon.mjs +113 -25
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -10086,15 +10086,18 @@ var humiditySensorCapability = {
10086
10086
  runtimeState: HumiditySensorStatusSchema
10087
10087
  };
10088
10088
  /**
10089
- * Image display cap. Models HA `image.*` entities — a single still image
10090
- * exposed by an integration (a snapshot, a chart, a generated picture).
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.
10091
10091
  *
10092
- * Read-only: there are no setters. The provider resolves the HA
10093
- * `entity_picture` (a relative, signed-token path) into an ABSOLUTE URL
10094
- * the browser loads directly — the token stays in the query string so no
10095
- * auth header is required. The slice carries that URL plus the upstream
10096
- * last-updated timestamp; the image changes when the entity state (a
10097
- * timestamp) changes.
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.
10098
10101
  */
10099
10102
  var ImageStatusSchema = object({
10100
10103
  /** Absolute signed URL the browser loads directly. Null when the
@@ -10120,18 +10123,47 @@ var imageCapability = {
10120
10123
  */
10121
10124
  runtimeState: ImageStatusSchema
10122
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
+ ]);
10123
10150
  var LawnMowerControlStatusSchema = object({
10124
10151
  /** Lifecycle activity of the mower. */
10125
- activity: _enum([
10126
- "idle",
10127
- "mowing",
10128
- "paused",
10129
- "docked",
10130
- "error"
10131
- ]),
10152
+ activity: LawnMowerActivitySchema,
10132
10153
  /** 0..100 battery percentage. Null when the device has no battery
10133
10154
  * reading. */
10134
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,
10135
10167
  /** Ms epoch when the slice was last updated. */
10136
10168
  lastChangedAt: number()
10137
10169
  });
@@ -12357,6 +12389,7 @@ var VacuumStateSchema = _enum([
12357
12389
  "paused",
12358
12390
  "returning",
12359
12391
  "docked",
12392
+ "drying",
12360
12393
  "error"
12361
12394
  ]);
12362
12395
  /**
@@ -12395,6 +12428,12 @@ var VacuumControlStatusSchema = object({
12395
12428
  detergent: TankStatusSchema.nullable(),
12396
12429
  /** Dust bin. Null when the hardware has no dust bin. */
12397
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(),
12398
12437
  /** Ms epoch when the slice was last updated. */
12399
12438
  lastChangedAt: number()
12400
12439
  });
@@ -13361,9 +13400,29 @@ var BaseDevice = class {
13361
13400
  * is open (Reolink writes `hasPtz/hasIntercom`, Hikvision writes
13362
13401
  * `hasSupplementalLight/hasAlarmIo`, etc).
13363
13402
  *
13364
- * Default: no-op (driver had no probe to run).
13365
- */
13366
- async onProbe() {}
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
+ }
13367
13426
  /**
13368
13427
  * Phase 5 — fired after the device + its accessories are registered.
13369
13428
  * Drivers publish streams to the broker, kick off background tasks,
@@ -14825,17 +14884,32 @@ var ReleaseInputSchema = object({
14825
14884
  * the parent cascades into every accessory. */
14826
14885
  camDeviceId: number().int().nonnegative()
14827
14886
  });
14828
- var ResyncInputSchema = object({
14829
- /** Parent CamStack device id of an adopted device. The provider resolves its
14830
- * source (integration/broker + native id) and re-aligns the device's
14831
- * structural spec (type/role/capabilities/units) with the live mapping,
14832
- * rebuilding any child whose class changed while preserving operator edits. */
14833
- 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
+ });
14834
14905
  var ResyncResultSchema = object({
14835
14906
  /** True when the persisted spec actually changed (children may have been rebuilt). */
14836
14907
  changed: boolean(),
14837
14908
  /** Number of child devices rebuilt into a new class by this re-sync. */
14838
- 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()
14839
14913
  });
14840
14914
  var deviceAdoptionCapability = {
14841
14915
  name: "device-adoption",
@@ -16600,6 +16674,11 @@ var DeviceMetaSchema = object({
16600
16674
  addonId: string(),
16601
16675
  type: string(),
16602
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(),
16603
16682
  location: string().nullable(),
16604
16683
  disabled: boolean(),
16605
16684
  parentDeviceId: number().nullable(),
@@ -16910,6 +16989,9 @@ method(object({
16910
16989
  }), method(ReleaseInputSchema.extend({ addonId: string() }), _void(), {
16911
16990
  kind: "mutation",
16912
16991
  auth: "admin"
16992
+ }), method(ResyncInputSchema, ResyncResultSchema, {
16993
+ kind: "mutation",
16994
+ auth: "admin"
16913
16995
  }), method(object({
16914
16996
  deviceId: number(),
16915
16997
  key: string(),
@@ -20672,6 +20754,12 @@ Object.freeze({
20672
20754
  addonId: null,
20673
20755
  access: "create"
20674
20756
  },
20757
+ "deviceManager.adoptionResync": {
20758
+ capName: "device-manager",
20759
+ capScope: "system",
20760
+ addonId: null,
20761
+ access: "create"
20762
+ },
20675
20763
  "deviceManager.allocateDeviceId": {
20676
20764
  capName: "device-manager",
20677
20765
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -10087,15 +10087,18 @@ var humiditySensorCapability = {
10087
10087
  runtimeState: HumiditySensorStatusSchema
10088
10088
  };
10089
10089
  /**
10090
- * Image display cap. Models HA `image.*` entities — a single still image
10091
- * exposed by an integration (a snapshot, a chart, a generated picture).
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.
10092
10092
  *
10093
- * Read-only: there are no setters. The provider resolves the HA
10094
- * `entity_picture` (a relative, signed-token path) into an ABSOLUTE URL
10095
- * the browser loads directly — the token stays in the query string so no
10096
- * auth header is required. The slice carries that URL plus the upstream
10097
- * last-updated timestamp; the image changes when the entity state (a
10098
- * timestamp) changes.
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.
10099
10102
  */
10100
10103
  var ImageStatusSchema = object({
10101
10104
  /** Absolute signed URL the browser loads directly. Null when the
@@ -10121,18 +10124,47 @@ var imageCapability = {
10121
10124
  */
10122
10125
  runtimeState: ImageStatusSchema
10123
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
+ ]);
10124
10151
  var LawnMowerControlStatusSchema = object({
10125
10152
  /** Lifecycle activity of the mower. */
10126
- activity: _enum([
10127
- "idle",
10128
- "mowing",
10129
- "paused",
10130
- "docked",
10131
- "error"
10132
- ]),
10153
+ activity: LawnMowerActivitySchema,
10133
10154
  /** 0..100 battery percentage. Null when the device has no battery
10134
10155
  * reading. */
10135
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,
10136
10168
  /** Ms epoch when the slice was last updated. */
10137
10169
  lastChangedAt: number()
10138
10170
  });
@@ -12358,6 +12390,7 @@ var VacuumStateSchema = _enum([
12358
12390
  "paused",
12359
12391
  "returning",
12360
12392
  "docked",
12393
+ "drying",
12361
12394
  "error"
12362
12395
  ]);
12363
12396
  /**
@@ -12396,6 +12429,12 @@ var VacuumControlStatusSchema = object({
12396
12429
  detergent: TankStatusSchema.nullable(),
12397
12430
  /** Dust bin. Null when the hardware has no dust bin. */
12398
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(),
12399
12438
  /** Ms epoch when the slice was last updated. */
12400
12439
  lastChangedAt: number()
12401
12440
  });
@@ -13362,9 +13401,29 @@ var BaseDevice = class {
13362
13401
  * is open (Reolink writes `hasPtz/hasIntercom`, Hikvision writes
13363
13402
  * `hasSupplementalLight/hasAlarmIo`, etc).
13364
13403
  *
13365
- * Default: no-op (driver had no probe to run).
13366
- */
13367
- async onProbe() {}
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
+ }
13368
13427
  /**
13369
13428
  * Phase 5 — fired after the device + its accessories are registered.
13370
13429
  * Drivers publish streams to the broker, kick off background tasks,
@@ -14826,17 +14885,32 @@ var ReleaseInputSchema = object({
14826
14885
  * the parent cascades into every accessory. */
14827
14886
  camDeviceId: number().int().nonnegative()
14828
14887
  });
14829
- var ResyncInputSchema = object({
14830
- /** Parent CamStack device id of an adopted device. The provider resolves its
14831
- * source (integration/broker + native id) and re-aligns the device's
14832
- * structural spec (type/role/capabilities/units) with the live mapping,
14833
- * rebuilding any child whose class changed while preserving operator edits. */
14834
- 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
+ });
14835
14906
  var ResyncResultSchema = object({
14836
14907
  /** True when the persisted spec actually changed (children may have been rebuilt). */
14837
14908
  changed: boolean(),
14838
14909
  /** Number of child devices rebuilt into a new class by this re-sync. */
14839
- 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()
14840
14914
  });
14841
14915
  var deviceAdoptionCapability = {
14842
14916
  name: "device-adoption",
@@ -16601,6 +16675,11 @@ var DeviceMetaSchema = object({
16601
16675
  addonId: string(),
16602
16676
  type: string(),
16603
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(),
16604
16683
  location: string().nullable(),
16605
16684
  disabled: boolean(),
16606
16685
  parentDeviceId: number().nullable(),
@@ -16911,6 +16990,9 @@ method(object({
16911
16990
  }), method(ReleaseInputSchema.extend({ addonId: string() }), _void(), {
16912
16991
  kind: "mutation",
16913
16992
  auth: "admin"
16993
+ }), method(ResyncInputSchema, ResyncResultSchema, {
16994
+ kind: "mutation",
16995
+ auth: "admin"
16914
16996
  }), method(object({
16915
16997
  deviceId: number(),
16916
16998
  key: string(),
@@ -20673,6 +20755,12 @@ Object.freeze({
20673
20755
  addonId: null,
20674
20756
  access: "create"
20675
20757
  },
20758
+ "deviceManager.adoptionResync": {
20759
+ capName: "device-manager",
20760
+ capScope: "system",
20761
+ addonId: null,
20762
+ access: "create"
20763
+ },
20676
20764
  "deviceManager.allocateDeviceId": {
20677
20765
  capName: "device-manager",
20678
20766
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homematic",
3
- "version": "1.1.7",
3
+ "version": "1.1.8",
4
4
  "description": "Homematic / HomematicIP (CCU3 / RaspberryMatic) device-provider addon for CamStack — wraps the nodehomematic library",
5
5
  "keywords": [
6
6
  "camstack",