@camstack/addon-provider-reolink 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 +112 -24
  2. package/dist/addon.mjs +112 -24
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -10316,15 +10316,18 @@ var humiditySensorCapability = {
10316
10316
  runtimeState: HumiditySensorStatusSchema
10317
10317
  };
10318
10318
  /**
10319
- * Image display cap. Models HA `image.*` entities a single still image
10320
- * exposed by an integration (a snapshot, a chart, a generated picture).
10319
+ * Image display cap. Models a single still image exposed by an integration
10320
+ * a snapshot, a chart, a generated picture, or a robot's cleaning-map render.
10321
10321
  *
10322
- * Read-only: there are no setters. The provider resolves the HA
10323
- * `entity_picture` (a relative, signed-token path) into an ABSOLUTE URL
10324
- * the browser loads directly the token stays in the query string so no
10325
- * auth header is required. The slice carries that URL plus the upstream
10326
- * last-updated timestamp; the image changes when the entity state (a
10327
- * timestamp) changes.
10322
+ * Read-only: there are no setters. The provider resolves whatever upstream
10323
+ * source it has into an ABSOLUTE URL the browser loads directly:
10324
+ * - HA `image.*` entities the `entity_picture` signed-token path
10325
+ * (token stays in the query string, so no auth header is needed);
10326
+ * - a Dreame/robot map the cloud/OSS map-image URL (or an addon
10327
+ * data-plane URL serving the rendered map bytes), exposed as its own
10328
+ * Image child device grouped under the robot's container.
10329
+ * The slice carries that URL plus the upstream last-updated timestamp; the
10330
+ * image changes when the source's last-updated marker changes.
10328
10331
  */
10329
10332
  var ImageStatusSchema = object({
10330
10333
  /** Absolute signed URL the browser loads directly. Null when the
@@ -10350,18 +10353,47 @@ var imageCapability = {
10350
10353
  */
10351
10354
  runtimeState: ImageStatusSchema
10352
10355
  };
10356
+ /**
10357
+ * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
10358
+ * with a mowing lifecycle plus a dock action.
10359
+ *
10360
+ * Activity follows HA's canonical lawn-mower lifecycle: `idle` /
10361
+ * `mowing` / `paused` / `docked` / `error`. `batteryLevel` (0..100) is
10362
+ * nullable — some mowers don't report a battery percentage.
10363
+ *
10364
+ * `startMowing` begins a mowing run, `pause` halts it in place, and
10365
+ * `dock` sends the mower back to its charging station.
10366
+ */
10367
+ var LawnMowerActivitySchema = _enum([
10368
+ "idle",
10369
+ "mowing",
10370
+ "paused",
10371
+ "docked",
10372
+ "error"
10373
+ ]);
10374
+ /** Severity of the current device/error code — info (status), warning, error. */
10375
+ var DeviceCodeSeveritySchema = _enum([
10376
+ "info",
10377
+ "warning",
10378
+ "error"
10379
+ ]);
10353
10380
  var LawnMowerControlStatusSchema = object({
10354
10381
  /** Lifecycle activity of the mower. */
10355
- activity: _enum([
10356
- "idle",
10357
- "mowing",
10358
- "paused",
10359
- "docked",
10360
- "error"
10361
- ]),
10382
+ activity: LawnMowerActivitySchema,
10362
10383
  /** 0..100 battery percentage. Null when the device has no battery
10363
10384
  * reading. */
10364
10385
  batteryLevel: number().min(0).max(100).nullable(),
10386
+ /** 0..100 mowing-completion percentage of the current task, or null when no
10387
+ * task is active / progress is unavailable. */
10388
+ progressPercent: number().min(0).max(100).nullable(),
10389
+ /** Current device/event code (dynamic — mostly status, sometimes an error),
10390
+ * or null when unknown. */
10391
+ currentCode: number().nullable(),
10392
+ /** Human label for {@link currentCode}, or null when undecodable. */
10393
+ currentCodeLabel: string().nullable(),
10394
+ /** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
10395
+ * attention; `info` is normal status. */
10396
+ severity: DeviceCodeSeveritySchema,
10365
10397
  /** Ms epoch when the slice was last updated. */
10366
10398
  lastChangedAt: number()
10367
10399
  });
@@ -12587,6 +12619,7 @@ var VacuumStateSchema = _enum([
12587
12619
  "paused",
12588
12620
  "returning",
12589
12621
  "docked",
12622
+ "drying",
12590
12623
  "error"
12591
12624
  ]);
12592
12625
  /**
@@ -12625,6 +12658,12 @@ var VacuumControlStatusSchema = object({
12625
12658
  detergent: TankStatusSchema.nullable(),
12626
12659
  /** Dust bin. Null when the hardware has no dust bin. */
12627
12660
  dustBin: TankStatusSchema.nullable(),
12661
+ /** 0..100 cleaning-completion percentage of the current task, or null. */
12662
+ progressPercent: number().min(0).max(100).nullable(),
12663
+ /** Current error code (0 / null = no error). */
12664
+ errorCode: number().nullable(),
12665
+ /** Human label for {@link errorCode}, or null when none / undecodable. */
12666
+ errorLabel: string().nullable(),
12628
12667
  /** Ms epoch when the slice was last updated. */
12629
12668
  lastChangedAt: number()
12630
12669
  });
@@ -13591,9 +13630,29 @@ var BaseDevice = class {
13591
13630
  * is open (Reolink writes `hasPtz/hasIntercom`, Hikvision writes
13592
13631
  * `hasSupplementalLight/hasAlarmIo`, etc).
13593
13632
  *
13594
- * Default: no-op (driver had no probe to run).
13633
+ * Default: nothing to probe mark the device PROBED (set `lastProbedAt`) so
13634
+ * the kernel treats it as ready immediately. A device that derives its shape
13635
+ * from a spec (a container, or an accessory sensor) rather than from a
13636
+ * hardware probe has no probe to "complete"; without stamping `lastProbedAt`
13637
+ * it would look perpetually un-probed — logging "Initial probe did not
13638
+ * complete" on every boot and spinning a pointless retry chain. Drivers that
13639
+ * DO probe override this and write their own `feature-probe` slice (including
13640
+ * `lastProbedAt`) once their probe actually succeeds.
13595
13641
  */
13596
- async onProbe() {}
13642
+ async onProbe() {
13643
+ const base = this.runtimeState.getCapState("feature-probe") ?? {
13644
+ flags: {},
13645
+ deviceType: null,
13646
+ model: null,
13647
+ channelCount: null,
13648
+ lastProbedAt: 0,
13649
+ lastFetchedAt: 0
13650
+ };
13651
+ this.runtimeState.setCapState("feature-probe", {
13652
+ ...base,
13653
+ lastProbedAt: Date.now()
13654
+ });
13655
+ }
13597
13656
  /**
13598
13657
  * Phase 5 — fired after the device + its accessories are registered.
13599
13658
  * Drivers publish streams to the broker, kick off background tasks,
@@ -15067,17 +15126,32 @@ var ReleaseInputSchema = object({
15067
15126
  * the parent cascades into every accessory. */
15068
15127
  camDeviceId: number().int().nonnegative()
15069
15128
  });
15070
- var ResyncInputSchema = object({
15071
- /** Parent CamStack device id of an adopted device. The provider resolves its
15072
- * source (integration/broker + native id) and re-aligns the device's
15073
- * structural spec (type/role/capabilities/units) with the live mapping,
15074
- * rebuilding any child whose class changed while preserving operator edits. */
15075
- camDeviceId: number().int().nonnegative() });
15129
+ var ResyncInputSchema = object({
15130
+ /** Parent CamStack device id of an adopted device. The provider resolves its
15131
+ * source (integration/broker + native id) and re-aligns the device's
15132
+ * structural spec (type/role/capabilities/units) with the live mapping,
15133
+ * rebuilding any child whose class changed while preserving operator edits. */
15134
+ camDeviceId: number().int().nonnegative(),
15135
+ /** "Resync from zero" (#19). When true, the kernel PURGES every accessory
15136
+ * child of `camDeviceId` BEFORE the provider re-derives the device, so the
15137
+ * children are rebuilt fresh from source — correct names, coords, and units —
15138
+ * instead of being preserved by the incremental reconcile. Use to recover from
15139
+ * legacy generic/placeholder names that the normal name-precedence keeps frozen
15140
+ * (the operator's explicit reset). Push-driven integrations (no-op resync)
15141
+ * rebuild on their next snapshot; pull/command integrations rebuild in `resync`.
15142
+ * Operator edits on the PARENT (its name, layout, primary-child pick) survive —
15143
+ * only the children are torn down. Omitted/false ⇒ the normal incremental
15144
+ * re-sync that preserves children. */
15145
+ resetToSource: boolean().optional()
15146
+ });
15076
15147
  var ResyncResultSchema = object({
15077
15148
  /** True when the persisted spec actually changed (children may have been rebuilt). */
15078
15149
  changed: boolean(),
15079
15150
  /** Number of child devices rebuilt into a new class by this re-sync. */
15080
- rebuiltChildren: number().int().nonnegative()
15151
+ rebuiltChildren: number().int().nonnegative(),
15152
+ /** Number of accessory children torn down by a `resetToSource` purge before the
15153
+ * provider re-derived the device. 0/absent for a normal incremental re-sync. */
15154
+ removedChildren: number().int().nonnegative().optional()
15081
15155
  });
15082
15156
  method(object({ integrationId: string() }), object({ filters: array(AdoptionFilterSchema) }), { auth: "admin" }), method(ListCandidatesInputSchema, ListCandidatesOutputSchema, { auth: "admin" }), method(GetCandidateInputSchema, DiscoveredChildDeviceSchema.nullable(), { auth: "admin" }), method(object({ integrationId: string() }), AdoptionStatusSchema, {
15083
15157
  kind: "mutation",
@@ -16776,6 +16850,11 @@ var DeviceMetaSchema = object({
16776
16850
  addonId: string(),
16777
16851
  type: string(),
16778
16852
  name: string(),
16853
+ /** True once an operator explicitly renamed the device via `setName`. Drives
16854
+ * reconcile name-precedence (preserve operator name vs adopt fresh provider
16855
+ * name). Absent ⇒ treated as user-named (PRESERVE) for legacy rows. See
16856
+ * `DeviceMeta.userNamed`. */
16857
+ userNamed: boolean().optional(),
16779
16858
  location: string().nullable(),
16780
16859
  disabled: boolean(),
16781
16860
  parentDeviceId: number().nullable(),
@@ -17086,6 +17165,9 @@ method(object({
17086
17165
  }), method(ReleaseInputSchema.extend({ addonId: string() }), _void(), {
17087
17166
  kind: "mutation",
17088
17167
  auth: "admin"
17168
+ }), method(ResyncInputSchema, ResyncResultSchema, {
17169
+ kind: "mutation",
17170
+ auth: "admin"
17089
17171
  }), method(object({
17090
17172
  deviceId: number(),
17091
17173
  key: string(),
@@ -21220,6 +21302,12 @@ Object.freeze({
21220
21302
  addonId: null,
21221
21303
  access: "create"
21222
21304
  },
21305
+ "deviceManager.adoptionResync": {
21306
+ capName: "device-manager",
21307
+ capScope: "system",
21308
+ addonId: null,
21309
+ access: "create"
21310
+ },
21223
21311
  "deviceManager.allocateDeviceId": {
21224
21312
  capName: "device-manager",
21225
21313
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -10311,15 +10311,18 @@ var humiditySensorCapability = {
10311
10311
  runtimeState: HumiditySensorStatusSchema
10312
10312
  };
10313
10313
  /**
10314
- * Image display cap. Models HA `image.*` entities a single still image
10315
- * exposed by an integration (a snapshot, a chart, a generated picture).
10314
+ * Image display cap. Models a single still image exposed by an integration
10315
+ * a snapshot, a chart, a generated picture, or a robot's cleaning-map render.
10316
10316
  *
10317
- * Read-only: there are no setters. The provider resolves the HA
10318
- * `entity_picture` (a relative, signed-token path) into an ABSOLUTE URL
10319
- * the browser loads directly the token stays in the query string so no
10320
- * auth header is required. The slice carries that URL plus the upstream
10321
- * last-updated timestamp; the image changes when the entity state (a
10322
- * timestamp) changes.
10317
+ * Read-only: there are no setters. The provider resolves whatever upstream
10318
+ * source it has into an ABSOLUTE URL the browser loads directly:
10319
+ * - HA `image.*` entities the `entity_picture` signed-token path
10320
+ * (token stays in the query string, so no auth header is needed);
10321
+ * - a Dreame/robot map the cloud/OSS map-image URL (or an addon
10322
+ * data-plane URL serving the rendered map bytes), exposed as its own
10323
+ * Image child device grouped under the robot's container.
10324
+ * The slice carries that URL plus the upstream last-updated timestamp; the
10325
+ * image changes when the source's last-updated marker changes.
10323
10326
  */
10324
10327
  var ImageStatusSchema = object({
10325
10328
  /** Absolute signed URL the browser loads directly. Null when the
@@ -10345,18 +10348,47 @@ var imageCapability = {
10345
10348
  */
10346
10349
  runtimeState: ImageStatusSchema
10347
10350
  };
10351
+ /**
10352
+ * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
10353
+ * with a mowing lifecycle plus a dock action.
10354
+ *
10355
+ * Activity follows HA's canonical lawn-mower lifecycle: `idle` /
10356
+ * `mowing` / `paused` / `docked` / `error`. `batteryLevel` (0..100) is
10357
+ * nullable — some mowers don't report a battery percentage.
10358
+ *
10359
+ * `startMowing` begins a mowing run, `pause` halts it in place, and
10360
+ * `dock` sends the mower back to its charging station.
10361
+ */
10362
+ var LawnMowerActivitySchema = _enum([
10363
+ "idle",
10364
+ "mowing",
10365
+ "paused",
10366
+ "docked",
10367
+ "error"
10368
+ ]);
10369
+ /** Severity of the current device/error code — info (status), warning, error. */
10370
+ var DeviceCodeSeveritySchema = _enum([
10371
+ "info",
10372
+ "warning",
10373
+ "error"
10374
+ ]);
10348
10375
  var LawnMowerControlStatusSchema = object({
10349
10376
  /** Lifecycle activity of the mower. */
10350
- activity: _enum([
10351
- "idle",
10352
- "mowing",
10353
- "paused",
10354
- "docked",
10355
- "error"
10356
- ]),
10377
+ activity: LawnMowerActivitySchema,
10357
10378
  /** 0..100 battery percentage. Null when the device has no battery
10358
10379
  * reading. */
10359
10380
  batteryLevel: number().min(0).max(100).nullable(),
10381
+ /** 0..100 mowing-completion percentage of the current task, or null when no
10382
+ * task is active / progress is unavailable. */
10383
+ progressPercent: number().min(0).max(100).nullable(),
10384
+ /** Current device/event code (dynamic — mostly status, sometimes an error),
10385
+ * or null when unknown. */
10386
+ currentCode: number().nullable(),
10387
+ /** Human label for {@link currentCode}, or null when undecodable. */
10388
+ currentCodeLabel: string().nullable(),
10389
+ /** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
10390
+ * attention; `info` is normal status. */
10391
+ severity: DeviceCodeSeveritySchema,
10360
10392
  /** Ms epoch when the slice was last updated. */
10361
10393
  lastChangedAt: number()
10362
10394
  });
@@ -12582,6 +12614,7 @@ var VacuumStateSchema = _enum([
12582
12614
  "paused",
12583
12615
  "returning",
12584
12616
  "docked",
12617
+ "drying",
12585
12618
  "error"
12586
12619
  ]);
12587
12620
  /**
@@ -12620,6 +12653,12 @@ var VacuumControlStatusSchema = object({
12620
12653
  detergent: TankStatusSchema.nullable(),
12621
12654
  /** Dust bin. Null when the hardware has no dust bin. */
12622
12655
  dustBin: TankStatusSchema.nullable(),
12656
+ /** 0..100 cleaning-completion percentage of the current task, or null. */
12657
+ progressPercent: number().min(0).max(100).nullable(),
12658
+ /** Current error code (0 / null = no error). */
12659
+ errorCode: number().nullable(),
12660
+ /** Human label for {@link errorCode}, or null when none / undecodable. */
12661
+ errorLabel: string().nullable(),
12623
12662
  /** Ms epoch when the slice was last updated. */
12624
12663
  lastChangedAt: number()
12625
12664
  });
@@ -13586,9 +13625,29 @@ var BaseDevice = class {
13586
13625
  * is open (Reolink writes `hasPtz/hasIntercom`, Hikvision writes
13587
13626
  * `hasSupplementalLight/hasAlarmIo`, etc).
13588
13627
  *
13589
- * Default: no-op (driver had no probe to run).
13628
+ * Default: nothing to probe mark the device PROBED (set `lastProbedAt`) so
13629
+ * the kernel treats it as ready immediately. A device that derives its shape
13630
+ * from a spec (a container, or an accessory sensor) rather than from a
13631
+ * hardware probe has no probe to "complete"; without stamping `lastProbedAt`
13632
+ * it would look perpetually un-probed — logging "Initial probe did not
13633
+ * complete" on every boot and spinning a pointless retry chain. Drivers that
13634
+ * DO probe override this and write their own `feature-probe` slice (including
13635
+ * `lastProbedAt`) once their probe actually succeeds.
13590
13636
  */
13591
- async onProbe() {}
13637
+ async onProbe() {
13638
+ const base = this.runtimeState.getCapState("feature-probe") ?? {
13639
+ flags: {},
13640
+ deviceType: null,
13641
+ model: null,
13642
+ channelCount: null,
13643
+ lastProbedAt: 0,
13644
+ lastFetchedAt: 0
13645
+ };
13646
+ this.runtimeState.setCapState("feature-probe", {
13647
+ ...base,
13648
+ lastProbedAt: Date.now()
13649
+ });
13650
+ }
13592
13651
  /**
13593
13652
  * Phase 5 — fired after the device + its accessories are registered.
13594
13653
  * Drivers publish streams to the broker, kick off background tasks,
@@ -15062,17 +15121,32 @@ var ReleaseInputSchema = object({
15062
15121
  * the parent cascades into every accessory. */
15063
15122
  camDeviceId: number().int().nonnegative()
15064
15123
  });
15065
- var ResyncInputSchema = object({
15066
- /** Parent CamStack device id of an adopted device. The provider resolves its
15067
- * source (integration/broker + native id) and re-aligns the device's
15068
- * structural spec (type/role/capabilities/units) with the live mapping,
15069
- * rebuilding any child whose class changed while preserving operator edits. */
15070
- camDeviceId: number().int().nonnegative() });
15124
+ var ResyncInputSchema = object({
15125
+ /** Parent CamStack device id of an adopted device. The provider resolves its
15126
+ * source (integration/broker + native id) and re-aligns the device's
15127
+ * structural spec (type/role/capabilities/units) with the live mapping,
15128
+ * rebuilding any child whose class changed while preserving operator edits. */
15129
+ camDeviceId: number().int().nonnegative(),
15130
+ /** "Resync from zero" (#19). When true, the kernel PURGES every accessory
15131
+ * child of `camDeviceId` BEFORE the provider re-derives the device, so the
15132
+ * children are rebuilt fresh from source — correct names, coords, and units —
15133
+ * instead of being preserved by the incremental reconcile. Use to recover from
15134
+ * legacy generic/placeholder names that the normal name-precedence keeps frozen
15135
+ * (the operator's explicit reset). Push-driven integrations (no-op resync)
15136
+ * rebuild on their next snapshot; pull/command integrations rebuild in `resync`.
15137
+ * Operator edits on the PARENT (its name, layout, primary-child pick) survive —
15138
+ * only the children are torn down. Omitted/false ⇒ the normal incremental
15139
+ * re-sync that preserves children. */
15140
+ resetToSource: boolean().optional()
15141
+ });
15071
15142
  var ResyncResultSchema = object({
15072
15143
  /** True when the persisted spec actually changed (children may have been rebuilt). */
15073
15144
  changed: boolean(),
15074
15145
  /** Number of child devices rebuilt into a new class by this re-sync. */
15075
- rebuiltChildren: number().int().nonnegative()
15146
+ rebuiltChildren: number().int().nonnegative(),
15147
+ /** Number of accessory children torn down by a `resetToSource` purge before the
15148
+ * provider re-derived the device. 0/absent for a normal incremental re-sync. */
15149
+ removedChildren: number().int().nonnegative().optional()
15076
15150
  });
15077
15151
  method(object({ integrationId: string() }), object({ filters: array(AdoptionFilterSchema) }), { auth: "admin" }), method(ListCandidatesInputSchema, ListCandidatesOutputSchema, { auth: "admin" }), method(GetCandidateInputSchema, DiscoveredChildDeviceSchema.nullable(), { auth: "admin" }), method(object({ integrationId: string() }), AdoptionStatusSchema, {
15078
15152
  kind: "mutation",
@@ -16771,6 +16845,11 @@ var DeviceMetaSchema = object({
16771
16845
  addonId: string(),
16772
16846
  type: string(),
16773
16847
  name: string(),
16848
+ /** True once an operator explicitly renamed the device via `setName`. Drives
16849
+ * reconcile name-precedence (preserve operator name vs adopt fresh provider
16850
+ * name). Absent ⇒ treated as user-named (PRESERVE) for legacy rows. See
16851
+ * `DeviceMeta.userNamed`. */
16852
+ userNamed: boolean().optional(),
16774
16853
  location: string().nullable(),
16775
16854
  disabled: boolean(),
16776
16855
  parentDeviceId: number().nullable(),
@@ -17081,6 +17160,9 @@ method(object({
17081
17160
  }), method(ReleaseInputSchema.extend({ addonId: string() }), _void(), {
17082
17161
  kind: "mutation",
17083
17162
  auth: "admin"
17163
+ }), method(ResyncInputSchema, ResyncResultSchema, {
17164
+ kind: "mutation",
17165
+ auth: "admin"
17084
17166
  }), method(object({
17085
17167
  deviceId: number(),
17086
17168
  key: string(),
@@ -21215,6 +21297,12 @@ Object.freeze({
21215
21297
  addonId: null,
21216
21298
  access: "create"
21217
21299
  },
21300
+ "deviceManager.adoptionResync": {
21301
+ capName: "device-manager",
21302
+ capScope: "system",
21303
+ addonId: null,
21304
+ access: "create"
21305
+ },
21218
21306
  "deviceManager.allocateDeviceId": {
21219
21307
  capName: "device-manager",
21220
21308
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-reolink",
3
- "version": "1.1.7",
3
+ "version": "1.1.8",
4
4
  "description": "Reolink camera device provider addon for CamStack — native Baichuan protocol",
5
5
  "keywords": [
6
6
  "camstack",