@camstack/addon-provider-wyze 0.1.5 → 0.1.6

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
@@ -10082,15 +10082,18 @@ var humiditySensorCapability = {
10082
10082
  runtimeState: HumiditySensorStatusSchema
10083
10083
  };
10084
10084
  /**
10085
- * Image display cap. Models HA `image.*` entities a single still image
10086
- * exposed by an integration (a snapshot, a chart, a generated picture).
10085
+ * Image display cap. Models a single still image exposed by an integration
10086
+ * a snapshot, a chart, a generated picture, or a robot's cleaning-map render.
10087
10087
  *
10088
- * Read-only: there are no setters. The provider resolves the HA
10089
- * `entity_picture` (a relative, signed-token path) into an ABSOLUTE URL
10090
- * the browser loads directly the token stays in the query string so no
10091
- * auth header is required. The slice carries that URL plus the upstream
10092
- * last-updated timestamp; the image changes when the entity state (a
10093
- * timestamp) changes.
10088
+ * Read-only: there are no setters. The provider resolves whatever upstream
10089
+ * source it has into an ABSOLUTE URL the browser loads directly:
10090
+ * - HA `image.*` entities the `entity_picture` signed-token path
10091
+ * (token stays in the query string, so no auth header is needed);
10092
+ * - a Dreame/robot map the cloud/OSS map-image URL (or an addon
10093
+ * data-plane URL serving the rendered map bytes), exposed as its own
10094
+ * Image child device grouped under the robot's container.
10095
+ * The slice carries that URL plus the upstream last-updated timestamp; the
10096
+ * image changes when the source's last-updated marker changes.
10094
10097
  */
10095
10098
  var ImageStatusSchema = object({
10096
10099
  /** Absolute signed URL the browser loads directly. Null when the
@@ -10116,18 +10119,47 @@ var imageCapability = {
10116
10119
  */
10117
10120
  runtimeState: ImageStatusSchema
10118
10121
  };
10122
+ /**
10123
+ * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
10124
+ * with a mowing lifecycle plus a dock action.
10125
+ *
10126
+ * Activity follows HA's canonical lawn-mower lifecycle: `idle` /
10127
+ * `mowing` / `paused` / `docked` / `error`. `batteryLevel` (0..100) is
10128
+ * nullable — some mowers don't report a battery percentage.
10129
+ *
10130
+ * `startMowing` begins a mowing run, `pause` halts it in place, and
10131
+ * `dock` sends the mower back to its charging station.
10132
+ */
10133
+ var LawnMowerActivitySchema = _enum([
10134
+ "idle",
10135
+ "mowing",
10136
+ "paused",
10137
+ "docked",
10138
+ "error"
10139
+ ]);
10140
+ /** Severity of the current device/error code — info (status), warning, error. */
10141
+ var DeviceCodeSeveritySchema = _enum([
10142
+ "info",
10143
+ "warning",
10144
+ "error"
10145
+ ]);
10119
10146
  var LawnMowerControlStatusSchema = object({
10120
10147
  /** Lifecycle activity of the mower. */
10121
- activity: _enum([
10122
- "idle",
10123
- "mowing",
10124
- "paused",
10125
- "docked",
10126
- "error"
10127
- ]),
10148
+ activity: LawnMowerActivitySchema,
10128
10149
  /** 0..100 battery percentage. Null when the device has no battery
10129
10150
  * reading. */
10130
10151
  batteryLevel: number().min(0).max(100).nullable(),
10152
+ /** 0..100 mowing-completion percentage of the current task, or null when no
10153
+ * task is active / progress is unavailable. */
10154
+ progressPercent: number().min(0).max(100).nullable(),
10155
+ /** Current device/event code (dynamic — mostly status, sometimes an error),
10156
+ * or null when unknown. */
10157
+ currentCode: number().nullable(),
10158
+ /** Human label for {@link currentCode}, or null when undecodable. */
10159
+ currentCodeLabel: string().nullable(),
10160
+ /** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
10161
+ * attention; `info` is normal status. */
10162
+ severity: DeviceCodeSeveritySchema,
10131
10163
  /** Ms epoch when the slice was last updated. */
10132
10164
  lastChangedAt: number()
10133
10165
  });
@@ -12353,6 +12385,7 @@ var VacuumStateSchema = _enum([
12353
12385
  "paused",
12354
12386
  "returning",
12355
12387
  "docked",
12388
+ "drying",
12356
12389
  "error"
12357
12390
  ]);
12358
12391
  /**
@@ -12391,6 +12424,12 @@ var VacuumControlStatusSchema = object({
12391
12424
  detergent: TankStatusSchema.nullable(),
12392
12425
  /** Dust bin. Null when the hardware has no dust bin. */
12393
12426
  dustBin: TankStatusSchema.nullable(),
12427
+ /** 0..100 cleaning-completion percentage of the current task, or null. */
12428
+ progressPercent: number().min(0).max(100).nullable(),
12429
+ /** Current error code (0 / null = no error). */
12430
+ errorCode: number().nullable(),
12431
+ /** Human label for {@link errorCode}, or null when none / undecodable. */
12432
+ errorLabel: string().nullable(),
12394
12433
  /** Ms epoch when the slice was last updated. */
12395
12434
  lastChangedAt: number()
12396
12435
  });
@@ -13357,9 +13396,29 @@ var BaseDevice = class {
13357
13396
  * is open (Reolink writes `hasPtz/hasIntercom`, Hikvision writes
13358
13397
  * `hasSupplementalLight/hasAlarmIo`, etc).
13359
13398
  *
13360
- * Default: no-op (driver had no probe to run).
13361
- */
13362
- async onProbe() {}
13399
+ * Default: nothing to probe mark the device PROBED (set `lastProbedAt`) so
13400
+ * the kernel treats it as ready immediately. A device that derives its shape
13401
+ * from a spec (a container, or an accessory sensor) rather than from a
13402
+ * hardware probe has no probe to "complete"; without stamping `lastProbedAt`
13403
+ * it would look perpetually un-probed — logging "Initial probe did not
13404
+ * complete" on every boot and spinning a pointless retry chain. Drivers that
13405
+ * DO probe override this and write their own `feature-probe` slice (including
13406
+ * `lastProbedAt`) once their probe actually succeeds.
13407
+ */
13408
+ async onProbe() {
13409
+ const base = this.runtimeState.getCapState("feature-probe") ?? {
13410
+ flags: {},
13411
+ deviceType: null,
13412
+ model: null,
13413
+ channelCount: null,
13414
+ lastProbedAt: 0,
13415
+ lastFetchedAt: 0
13416
+ };
13417
+ this.runtimeState.setCapState("feature-probe", {
13418
+ ...base,
13419
+ lastProbedAt: Date.now()
13420
+ });
13421
+ }
13363
13422
  /**
13364
13423
  * Phase 5 — fired after the device + its accessories are registered.
13365
13424
  * Drivers publish streams to the broker, kick off background tasks,
@@ -14821,17 +14880,32 @@ var ReleaseInputSchema = object({
14821
14880
  * the parent cascades into every accessory. */
14822
14881
  camDeviceId: number().int().nonnegative()
14823
14882
  });
14824
- var ResyncInputSchema = object({
14825
- /** Parent CamStack device id of an adopted device. The provider resolves its
14826
- * source (integration/broker + native id) and re-aligns the device's
14827
- * structural spec (type/role/capabilities/units) with the live mapping,
14828
- * rebuilding any child whose class changed while preserving operator edits. */
14829
- camDeviceId: number().int().nonnegative() });
14883
+ var ResyncInputSchema = object({
14884
+ /** Parent CamStack device id of an adopted device. The provider resolves its
14885
+ * source (integration/broker + native id) and re-aligns the device's
14886
+ * structural spec (type/role/capabilities/units) with the live mapping,
14887
+ * rebuilding any child whose class changed while preserving operator edits. */
14888
+ camDeviceId: number().int().nonnegative(),
14889
+ /** "Resync from zero" (#19). When true, the kernel PURGES every accessory
14890
+ * child of `camDeviceId` BEFORE the provider re-derives the device, so the
14891
+ * children are rebuilt fresh from source — correct names, coords, and units —
14892
+ * instead of being preserved by the incremental reconcile. Use to recover from
14893
+ * legacy generic/placeholder names that the normal name-precedence keeps frozen
14894
+ * (the operator's explicit reset). Push-driven integrations (no-op resync)
14895
+ * rebuild on their next snapshot; pull/command integrations rebuild in `resync`.
14896
+ * Operator edits on the PARENT (its name, layout, primary-child pick) survive —
14897
+ * only the children are torn down. Omitted/false ⇒ the normal incremental
14898
+ * re-sync that preserves children. */
14899
+ resetToSource: boolean().optional()
14900
+ });
14830
14901
  var ResyncResultSchema = object({
14831
14902
  /** True when the persisted spec actually changed (children may have been rebuilt). */
14832
14903
  changed: boolean(),
14833
14904
  /** Number of child devices rebuilt into a new class by this re-sync. */
14834
- rebuiltChildren: number().int().nonnegative()
14905
+ rebuiltChildren: number().int().nonnegative(),
14906
+ /** Number of accessory children torn down by a `resetToSource` purge before the
14907
+ * provider re-derived the device. 0/absent for a normal incremental re-sync. */
14908
+ removedChildren: number().int().nonnegative().optional()
14835
14909
  });
14836
14910
  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, {
14837
14911
  kind: "mutation",
@@ -16530,6 +16604,11 @@ var DeviceMetaSchema = object({
16530
16604
  addonId: string(),
16531
16605
  type: string(),
16532
16606
  name: string(),
16607
+ /** True once an operator explicitly renamed the device via `setName`. Drives
16608
+ * reconcile name-precedence (preserve operator name vs adopt fresh provider
16609
+ * name). Absent ⇒ treated as user-named (PRESERVE) for legacy rows. See
16610
+ * `DeviceMeta.userNamed`. */
16611
+ userNamed: boolean().optional(),
16533
16612
  location: string().nullable(),
16534
16613
  disabled: boolean(),
16535
16614
  parentDeviceId: number().nullable(),
@@ -16840,6 +16919,9 @@ method(object({
16840
16919
  }), method(ReleaseInputSchema.extend({ addonId: string() }), _void(), {
16841
16920
  kind: "mutation",
16842
16921
  auth: "admin"
16922
+ }), method(ResyncInputSchema, ResyncResultSchema, {
16923
+ kind: "mutation",
16924
+ auth: "admin"
16843
16925
  }), method(object({
16844
16926
  deviceId: number(),
16845
16927
  key: string(),
@@ -20709,6 +20791,12 @@ Object.freeze({
20709
20791
  addonId: null,
20710
20792
  access: "create"
20711
20793
  },
20794
+ "deviceManager.adoptionResync": {
20795
+ capName: "device-manager",
20796
+ capScope: "system",
20797
+ addonId: null,
20798
+ access: "create"
20799
+ },
20712
20800
  "deviceManager.allocateDeviceId": {
20713
20801
  capName: "device-manager",
20714
20802
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -10061,15 +10061,18 @@ var humiditySensorCapability = {
10061
10061
  runtimeState: HumiditySensorStatusSchema
10062
10062
  };
10063
10063
  /**
10064
- * Image display cap. Models HA `image.*` entities a single still image
10065
- * exposed by an integration (a snapshot, a chart, a generated picture).
10064
+ * Image display cap. Models a single still image exposed by an integration
10065
+ * a snapshot, a chart, a generated picture, or a robot's cleaning-map render.
10066
10066
  *
10067
- * Read-only: there are no setters. The provider resolves the HA
10068
- * `entity_picture` (a relative, signed-token path) into an ABSOLUTE URL
10069
- * the browser loads directly the token stays in the query string so no
10070
- * auth header is required. The slice carries that URL plus the upstream
10071
- * last-updated timestamp; the image changes when the entity state (a
10072
- * timestamp) changes.
10067
+ * Read-only: there are no setters. The provider resolves whatever upstream
10068
+ * source it has into an ABSOLUTE URL the browser loads directly:
10069
+ * - HA `image.*` entities the `entity_picture` signed-token path
10070
+ * (token stays in the query string, so no auth header is needed);
10071
+ * - a Dreame/robot map the cloud/OSS map-image URL (or an addon
10072
+ * data-plane URL serving the rendered map bytes), exposed as its own
10073
+ * Image child device grouped under the robot's container.
10074
+ * The slice carries that URL plus the upstream last-updated timestamp; the
10075
+ * image changes when the source's last-updated marker changes.
10073
10076
  */
10074
10077
  var ImageStatusSchema = object({
10075
10078
  /** Absolute signed URL the browser loads directly. Null when the
@@ -10095,18 +10098,47 @@ var imageCapability = {
10095
10098
  */
10096
10099
  runtimeState: ImageStatusSchema
10097
10100
  };
10101
+ /**
10102
+ * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
10103
+ * with a mowing lifecycle plus a dock action.
10104
+ *
10105
+ * Activity follows HA's canonical lawn-mower lifecycle: `idle` /
10106
+ * `mowing` / `paused` / `docked` / `error`. `batteryLevel` (0..100) is
10107
+ * nullable — some mowers don't report a battery percentage.
10108
+ *
10109
+ * `startMowing` begins a mowing run, `pause` halts it in place, and
10110
+ * `dock` sends the mower back to its charging station.
10111
+ */
10112
+ var LawnMowerActivitySchema = _enum([
10113
+ "idle",
10114
+ "mowing",
10115
+ "paused",
10116
+ "docked",
10117
+ "error"
10118
+ ]);
10119
+ /** Severity of the current device/error code — info (status), warning, error. */
10120
+ var DeviceCodeSeveritySchema = _enum([
10121
+ "info",
10122
+ "warning",
10123
+ "error"
10124
+ ]);
10098
10125
  var LawnMowerControlStatusSchema = object({
10099
10126
  /** Lifecycle activity of the mower. */
10100
- activity: _enum([
10101
- "idle",
10102
- "mowing",
10103
- "paused",
10104
- "docked",
10105
- "error"
10106
- ]),
10127
+ activity: LawnMowerActivitySchema,
10107
10128
  /** 0..100 battery percentage. Null when the device has no battery
10108
10129
  * reading. */
10109
10130
  batteryLevel: number().min(0).max(100).nullable(),
10131
+ /** 0..100 mowing-completion percentage of the current task, or null when no
10132
+ * task is active / progress is unavailable. */
10133
+ progressPercent: number().min(0).max(100).nullable(),
10134
+ /** Current device/event code (dynamic — mostly status, sometimes an error),
10135
+ * or null when unknown. */
10136
+ currentCode: number().nullable(),
10137
+ /** Human label for {@link currentCode}, or null when undecodable. */
10138
+ currentCodeLabel: string().nullable(),
10139
+ /** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
10140
+ * attention; `info` is normal status. */
10141
+ severity: DeviceCodeSeveritySchema,
10110
10142
  /** Ms epoch when the slice was last updated. */
10111
10143
  lastChangedAt: number()
10112
10144
  });
@@ -12332,6 +12364,7 @@ var VacuumStateSchema = _enum([
12332
12364
  "paused",
12333
12365
  "returning",
12334
12366
  "docked",
12367
+ "drying",
12335
12368
  "error"
12336
12369
  ]);
12337
12370
  /**
@@ -12370,6 +12403,12 @@ var VacuumControlStatusSchema = object({
12370
12403
  detergent: TankStatusSchema.nullable(),
12371
12404
  /** Dust bin. Null when the hardware has no dust bin. */
12372
12405
  dustBin: TankStatusSchema.nullable(),
12406
+ /** 0..100 cleaning-completion percentage of the current task, or null. */
12407
+ progressPercent: number().min(0).max(100).nullable(),
12408
+ /** Current error code (0 / null = no error). */
12409
+ errorCode: number().nullable(),
12410
+ /** Human label for {@link errorCode}, or null when none / undecodable. */
12411
+ errorLabel: string().nullable(),
12373
12412
  /** Ms epoch when the slice was last updated. */
12374
12413
  lastChangedAt: number()
12375
12414
  });
@@ -13336,9 +13375,29 @@ var BaseDevice = class {
13336
13375
  * is open (Reolink writes `hasPtz/hasIntercom`, Hikvision writes
13337
13376
  * `hasSupplementalLight/hasAlarmIo`, etc).
13338
13377
  *
13339
- * Default: no-op (driver had no probe to run).
13340
- */
13341
- async onProbe() {}
13378
+ * Default: nothing to probe mark the device PROBED (set `lastProbedAt`) so
13379
+ * the kernel treats it as ready immediately. A device that derives its shape
13380
+ * from a spec (a container, or an accessory sensor) rather than from a
13381
+ * hardware probe has no probe to "complete"; without stamping `lastProbedAt`
13382
+ * it would look perpetually un-probed — logging "Initial probe did not
13383
+ * complete" on every boot and spinning a pointless retry chain. Drivers that
13384
+ * DO probe override this and write their own `feature-probe` slice (including
13385
+ * `lastProbedAt`) once their probe actually succeeds.
13386
+ */
13387
+ async onProbe() {
13388
+ const base = this.runtimeState.getCapState("feature-probe") ?? {
13389
+ flags: {},
13390
+ deviceType: null,
13391
+ model: null,
13392
+ channelCount: null,
13393
+ lastProbedAt: 0,
13394
+ lastFetchedAt: 0
13395
+ };
13396
+ this.runtimeState.setCapState("feature-probe", {
13397
+ ...base,
13398
+ lastProbedAt: Date.now()
13399
+ });
13400
+ }
13342
13401
  /**
13343
13402
  * Phase 5 — fired after the device + its accessories are registered.
13344
13403
  * Drivers publish streams to the broker, kick off background tasks,
@@ -14800,17 +14859,32 @@ var ReleaseInputSchema = object({
14800
14859
  * the parent cascades into every accessory. */
14801
14860
  camDeviceId: number().int().nonnegative()
14802
14861
  });
14803
- var ResyncInputSchema = object({
14804
- /** Parent CamStack device id of an adopted device. The provider resolves its
14805
- * source (integration/broker + native id) and re-aligns the device's
14806
- * structural spec (type/role/capabilities/units) with the live mapping,
14807
- * rebuilding any child whose class changed while preserving operator edits. */
14808
- camDeviceId: number().int().nonnegative() });
14862
+ var ResyncInputSchema = object({
14863
+ /** Parent CamStack device id of an adopted device. The provider resolves its
14864
+ * source (integration/broker + native id) and re-aligns the device's
14865
+ * structural spec (type/role/capabilities/units) with the live mapping,
14866
+ * rebuilding any child whose class changed while preserving operator edits. */
14867
+ camDeviceId: number().int().nonnegative(),
14868
+ /** "Resync from zero" (#19). When true, the kernel PURGES every accessory
14869
+ * child of `camDeviceId` BEFORE the provider re-derives the device, so the
14870
+ * children are rebuilt fresh from source — correct names, coords, and units —
14871
+ * instead of being preserved by the incremental reconcile. Use to recover from
14872
+ * legacy generic/placeholder names that the normal name-precedence keeps frozen
14873
+ * (the operator's explicit reset). Push-driven integrations (no-op resync)
14874
+ * rebuild on their next snapshot; pull/command integrations rebuild in `resync`.
14875
+ * Operator edits on the PARENT (its name, layout, primary-child pick) survive —
14876
+ * only the children are torn down. Omitted/false ⇒ the normal incremental
14877
+ * re-sync that preserves children. */
14878
+ resetToSource: boolean().optional()
14879
+ });
14809
14880
  var ResyncResultSchema = object({
14810
14881
  /** True when the persisted spec actually changed (children may have been rebuilt). */
14811
14882
  changed: boolean(),
14812
14883
  /** Number of child devices rebuilt into a new class by this re-sync. */
14813
- rebuiltChildren: number().int().nonnegative()
14884
+ rebuiltChildren: number().int().nonnegative(),
14885
+ /** Number of accessory children torn down by a `resetToSource` purge before the
14886
+ * provider re-derived the device. 0/absent for a normal incremental re-sync. */
14887
+ removedChildren: number().int().nonnegative().optional()
14814
14888
  });
14815
14889
  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, {
14816
14890
  kind: "mutation",
@@ -16509,6 +16583,11 @@ var DeviceMetaSchema = object({
16509
16583
  addonId: string(),
16510
16584
  type: string(),
16511
16585
  name: string(),
16586
+ /** True once an operator explicitly renamed the device via `setName`. Drives
16587
+ * reconcile name-precedence (preserve operator name vs adopt fresh provider
16588
+ * name). Absent ⇒ treated as user-named (PRESERVE) for legacy rows. See
16589
+ * `DeviceMeta.userNamed`. */
16590
+ userNamed: boolean().optional(),
16512
16591
  location: string().nullable(),
16513
16592
  disabled: boolean(),
16514
16593
  parentDeviceId: number().nullable(),
@@ -16819,6 +16898,9 @@ method(object({
16819
16898
  }), method(ReleaseInputSchema.extend({ addonId: string() }), _void(), {
16820
16899
  kind: "mutation",
16821
16900
  auth: "admin"
16901
+ }), method(ResyncInputSchema, ResyncResultSchema, {
16902
+ kind: "mutation",
16903
+ auth: "admin"
16822
16904
  }), method(object({
16823
16905
  deviceId: number(),
16824
16906
  key: string(),
@@ -20688,6 +20770,12 @@ Object.freeze({
20688
20770
  addonId: null,
20689
20771
  access: "create"
20690
20772
  },
20773
+ "deviceManager.adoptionResync": {
20774
+ capName: "device-manager",
20775
+ capScope: "system",
20776
+ addonId: null,
20777
+ access: "create"
20778
+ },
20691
20779
  "deviceManager.allocateDeviceId": {
20692
20780
  capName: "device-manager",
20693
20781
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-wyze",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Wyze camera device-provider addon for CamStack — wraps the @apocaliss92/wyze-bridge-js P2P/DTLS client, feeding the stream-broker via the pull-rfc4571 lazy-publish path (a structural twin of addon-provider-reolink)",
5
5
  "keywords": [
6
6
  "camstack",