@camstack/addon-import-alexa 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 +114 -26
  2. package/dist/addon.mjs +114 -26
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -10233,15 +10233,18 @@ var humiditySensorCapability = {
10233
10233
  runtimeState: HumiditySensorStatusSchema
10234
10234
  };
10235
10235
  /**
10236
- * Image display cap. Models HA `image.*` entities a single still image
10237
- * exposed by an integration (a snapshot, a chart, a generated picture).
10236
+ * Image display cap. Models a single still image exposed by an integration
10237
+ * a snapshot, a chart, a generated picture, or a robot's cleaning-map render.
10238
10238
  *
10239
- * Read-only: there are no setters. The provider resolves the HA
10240
- * `entity_picture` (a relative, signed-token path) into an ABSOLUTE URL
10241
- * the browser loads directly the token stays in the query string so no
10242
- * auth header is required. The slice carries that URL plus the upstream
10243
- * last-updated timestamp; the image changes when the entity state (a
10244
- * timestamp) changes.
10239
+ * Read-only: there are no setters. The provider resolves whatever upstream
10240
+ * source it has into an ABSOLUTE URL the browser loads directly:
10241
+ * - HA `image.*` entities the `entity_picture` signed-token path
10242
+ * (token stays in the query string, so no auth header is needed);
10243
+ * - a Dreame/robot map the cloud/OSS map-image URL (or an addon
10244
+ * data-plane URL serving the rendered map bytes), exposed as its own
10245
+ * Image child device grouped under the robot's container.
10246
+ * The slice carries that URL plus the upstream last-updated timestamp; the
10247
+ * image changes when the source's last-updated marker changes.
10245
10248
  */
10246
10249
  var ImageStatusSchema = object({
10247
10250
  /** Absolute signed URL the browser loads directly. Null when the
@@ -10267,18 +10270,47 @@ var imageCapability = {
10267
10270
  */
10268
10271
  runtimeState: ImageStatusSchema
10269
10272
  };
10273
+ /**
10274
+ * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
10275
+ * with a mowing lifecycle plus a dock action.
10276
+ *
10277
+ * Activity follows HA's canonical lawn-mower lifecycle: `idle` /
10278
+ * `mowing` / `paused` / `docked` / `error`. `batteryLevel` (0..100) is
10279
+ * nullable — some mowers don't report a battery percentage.
10280
+ *
10281
+ * `startMowing` begins a mowing run, `pause` halts it in place, and
10282
+ * `dock` sends the mower back to its charging station.
10283
+ */
10284
+ var LawnMowerActivitySchema = _enum([
10285
+ "idle",
10286
+ "mowing",
10287
+ "paused",
10288
+ "docked",
10289
+ "error"
10290
+ ]);
10291
+ /** Severity of the current device/error code — info (status), warning, error. */
10292
+ var DeviceCodeSeveritySchema = _enum([
10293
+ "info",
10294
+ "warning",
10295
+ "error"
10296
+ ]);
10270
10297
  var LawnMowerControlStatusSchema = object({
10271
10298
  /** Lifecycle activity of the mower. */
10272
- activity: _enum([
10273
- "idle",
10274
- "mowing",
10275
- "paused",
10276
- "docked",
10277
- "error"
10278
- ]),
10299
+ activity: LawnMowerActivitySchema,
10279
10300
  /** 0..100 battery percentage. Null when the device has no battery
10280
10301
  * reading. */
10281
10302
  batteryLevel: number().min(0).max(100).nullable(),
10303
+ /** 0..100 mowing-completion percentage of the current task, or null when no
10304
+ * task is active / progress is unavailable. */
10305
+ progressPercent: number().min(0).max(100).nullable(),
10306
+ /** Current device/event code (dynamic — mostly status, sometimes an error),
10307
+ * or null when unknown. */
10308
+ currentCode: number().nullable(),
10309
+ /** Human label for {@link currentCode}, or null when undecodable. */
10310
+ currentCodeLabel: string().nullable(),
10311
+ /** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
10312
+ * attention; `info` is normal status. */
10313
+ severity: DeviceCodeSeveritySchema,
10282
10314
  /** Ms epoch when the slice was last updated. */
10283
10315
  lastChangedAt: number()
10284
10316
  });
@@ -12504,6 +12536,7 @@ var VacuumStateSchema = _enum([
12504
12536
  "paused",
12505
12537
  "returning",
12506
12538
  "docked",
12539
+ "drying",
12507
12540
  "error"
12508
12541
  ]);
12509
12542
  /**
@@ -12542,6 +12575,12 @@ var VacuumControlStatusSchema = object({
12542
12575
  detergent: TankStatusSchema.nullable(),
12543
12576
  /** Dust bin. Null when the hardware has no dust bin. */
12544
12577
  dustBin: TankStatusSchema.nullable(),
12578
+ /** 0..100 cleaning-completion percentage of the current task, or null. */
12579
+ progressPercent: number().min(0).max(100).nullable(),
12580
+ /** Current error code (0 / null = no error). */
12581
+ errorCode: number().nullable(),
12582
+ /** Human label for {@link errorCode}, or null when none / undecodable. */
12583
+ errorLabel: string().nullable(),
12545
12584
  /** Ms epoch when the slice was last updated. */
12546
12585
  lastChangedAt: number()
12547
12586
  });
@@ -13508,9 +13547,29 @@ var BaseDevice = class {
13508
13547
  * is open (Reolink writes `hasPtz/hasIntercom`, Hikvision writes
13509
13548
  * `hasSupplementalLight/hasAlarmIo`, etc).
13510
13549
  *
13511
- * Default: no-op (driver had no probe to run).
13512
- */
13513
- async onProbe() {}
13550
+ * Default: nothing to probe mark the device PROBED (set `lastProbedAt`) so
13551
+ * the kernel treats it as ready immediately. A device that derives its shape
13552
+ * from a spec (a container, or an accessory sensor) rather than from a
13553
+ * hardware probe has no probe to "complete"; without stamping `lastProbedAt`
13554
+ * it would look perpetually un-probed — logging "Initial probe did not
13555
+ * complete" on every boot and spinning a pointless retry chain. Drivers that
13556
+ * DO probe override this and write their own `feature-probe` slice (including
13557
+ * `lastProbedAt`) once their probe actually succeeds.
13558
+ */
13559
+ async onProbe() {
13560
+ const base = this.runtimeState.getCapState("feature-probe") ?? {
13561
+ flags: {},
13562
+ deviceType: null,
13563
+ model: null,
13564
+ channelCount: null,
13565
+ lastProbedAt: 0,
13566
+ lastFetchedAt: 0
13567
+ };
13568
+ this.runtimeState.setCapState("feature-probe", {
13569
+ ...base,
13570
+ lastProbedAt: Date.now()
13571
+ });
13572
+ }
13514
13573
  /**
13515
13574
  * Phase 5 — fired after the device + its accessories are registered.
13516
13575
  * Drivers publish streams to the broker, kick off background tasks,
@@ -14972,17 +15031,32 @@ var ReleaseInputSchema = object({
14972
15031
  * the parent cascades into every accessory. */
14973
15032
  camDeviceId: number().int().nonnegative()
14974
15033
  });
14975
- var ResyncInputSchema = object({
14976
- /** Parent CamStack device id of an adopted device. The provider resolves its
14977
- * source (integration/broker + native id) and re-aligns the device's
14978
- * structural spec (type/role/capabilities/units) with the live mapping,
14979
- * rebuilding any child whose class changed while preserving operator edits. */
14980
- camDeviceId: number().int().nonnegative() });
15034
+ var ResyncInputSchema = object({
15035
+ /** Parent CamStack device id of an adopted device. The provider resolves its
15036
+ * source (integration/broker + native id) and re-aligns the device's
15037
+ * structural spec (type/role/capabilities/units) with the live mapping,
15038
+ * rebuilding any child whose class changed while preserving operator edits. */
15039
+ camDeviceId: number().int().nonnegative(),
15040
+ /** "Resync from zero" (#19). When true, the kernel PURGES every accessory
15041
+ * child of `camDeviceId` BEFORE the provider re-derives the device, so the
15042
+ * children are rebuilt fresh from source — correct names, coords, and units —
15043
+ * instead of being preserved by the incremental reconcile. Use to recover from
15044
+ * legacy generic/placeholder names that the normal name-precedence keeps frozen
15045
+ * (the operator's explicit reset). Push-driven integrations (no-op resync)
15046
+ * rebuild on their next snapshot; pull/command integrations rebuild in `resync`.
15047
+ * Operator edits on the PARENT (its name, layout, primary-child pick) survive —
15048
+ * only the children are torn down. Omitted/false ⇒ the normal incremental
15049
+ * re-sync that preserves children. */
15050
+ resetToSource: boolean().optional()
15051
+ });
14981
15052
  var ResyncResultSchema = object({
14982
15053
  /** True when the persisted spec actually changed (children may have been rebuilt). */
14983
15054
  changed: boolean(),
14984
15055
  /** Number of child devices rebuilt into a new class by this re-sync. */
14985
- rebuiltChildren: number().int().nonnegative()
15056
+ rebuiltChildren: number().int().nonnegative(),
15057
+ /** Number of accessory children torn down by a `resetToSource` purge before the
15058
+ * provider re-derived the device. 0/absent for a normal incremental re-sync. */
15059
+ removedChildren: number().int().nonnegative().optional()
14986
15060
  });
14987
15061
  var deviceAdoptionCapability = {
14988
15062
  name: "device-adoption",
@@ -16764,6 +16838,11 @@ var DeviceMetaSchema = object({
16764
16838
  addonId: string(),
16765
16839
  type: string(),
16766
16840
  name: string(),
16841
+ /** True once an operator explicitly renamed the device via `setName`. Drives
16842
+ * reconcile name-precedence (preserve operator name vs adopt fresh provider
16843
+ * name). Absent ⇒ treated as user-named (PRESERVE) for legacy rows. See
16844
+ * `DeviceMeta.userNamed`. */
16845
+ userNamed: boolean().optional(),
16767
16846
  location: string().nullable(),
16768
16847
  disabled: boolean(),
16769
16848
  parentDeviceId: number().nullable(),
@@ -17074,6 +17153,9 @@ method(object({
17074
17153
  }), method(ReleaseInputSchema.extend({ addonId: string() }), _void(), {
17075
17154
  kind: "mutation",
17076
17155
  auth: "admin"
17156
+ }), method(ResyncInputSchema, ResyncResultSchema, {
17157
+ kind: "mutation",
17158
+ auth: "admin"
17077
17159
  }), method(object({
17078
17160
  deviceId: number(),
17079
17161
  key: string(),
@@ -20853,6 +20935,12 @@ Object.freeze({
20853
20935
  addonId: null,
20854
20936
  access: "create"
20855
20937
  },
20938
+ "deviceManager.adoptionResync": {
20939
+ capName: "device-manager",
20940
+ capScope: "system",
20941
+ addonId: null,
20942
+ access: "create"
20943
+ },
20856
20944
  "deviceManager.allocateDeviceId": {
20857
20945
  capName: "device-manager",
20858
20946
  capScope: "system",
@@ -65600,7 +65688,7 @@ var AlexaProxyLoginManager = class {
65600
65688
  } catch (err) {
65601
65689
  this.#session = null;
65602
65690
  await session.dispose();
65603
- throw new Error(`alexa proxy-login: failed to start proxy — ${errMsg(err)}`);
65691
+ throw new Error(`alexa proxy-login: failed to start proxy — ${errMsg(err)}`, { cause: err });
65604
65692
  }
65605
65693
  return {
65606
65694
  sessionId,
package/dist/addon.mjs CHANGED
@@ -10233,15 +10233,18 @@ var humiditySensorCapability = {
10233
10233
  runtimeState: HumiditySensorStatusSchema
10234
10234
  };
10235
10235
  /**
10236
- * Image display cap. Models HA `image.*` entities a single still image
10237
- * exposed by an integration (a snapshot, a chart, a generated picture).
10236
+ * Image display cap. Models a single still image exposed by an integration
10237
+ * a snapshot, a chart, a generated picture, or a robot's cleaning-map render.
10238
10238
  *
10239
- * Read-only: there are no setters. The provider resolves the HA
10240
- * `entity_picture` (a relative, signed-token path) into an ABSOLUTE URL
10241
- * the browser loads directly the token stays in the query string so no
10242
- * auth header is required. The slice carries that URL plus the upstream
10243
- * last-updated timestamp; the image changes when the entity state (a
10244
- * timestamp) changes.
10239
+ * Read-only: there are no setters. The provider resolves whatever upstream
10240
+ * source it has into an ABSOLUTE URL the browser loads directly:
10241
+ * - HA `image.*` entities the `entity_picture` signed-token path
10242
+ * (token stays in the query string, so no auth header is needed);
10243
+ * - a Dreame/robot map the cloud/OSS map-image URL (or an addon
10244
+ * data-plane URL serving the rendered map bytes), exposed as its own
10245
+ * Image child device grouped under the robot's container.
10246
+ * The slice carries that URL plus the upstream last-updated timestamp; the
10247
+ * image changes when the source's last-updated marker changes.
10245
10248
  */
10246
10249
  var ImageStatusSchema = object({
10247
10250
  /** Absolute signed URL the browser loads directly. Null when the
@@ -10267,18 +10270,47 @@ var imageCapability = {
10267
10270
  */
10268
10271
  runtimeState: ImageStatusSchema
10269
10272
  };
10273
+ /**
10274
+ * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
10275
+ * with a mowing lifecycle plus a dock action.
10276
+ *
10277
+ * Activity follows HA's canonical lawn-mower lifecycle: `idle` /
10278
+ * `mowing` / `paused` / `docked` / `error`. `batteryLevel` (0..100) is
10279
+ * nullable — some mowers don't report a battery percentage.
10280
+ *
10281
+ * `startMowing` begins a mowing run, `pause` halts it in place, and
10282
+ * `dock` sends the mower back to its charging station.
10283
+ */
10284
+ var LawnMowerActivitySchema = _enum([
10285
+ "idle",
10286
+ "mowing",
10287
+ "paused",
10288
+ "docked",
10289
+ "error"
10290
+ ]);
10291
+ /** Severity of the current device/error code — info (status), warning, error. */
10292
+ var DeviceCodeSeveritySchema = _enum([
10293
+ "info",
10294
+ "warning",
10295
+ "error"
10296
+ ]);
10270
10297
  var LawnMowerControlStatusSchema = object({
10271
10298
  /** Lifecycle activity of the mower. */
10272
- activity: _enum([
10273
- "idle",
10274
- "mowing",
10275
- "paused",
10276
- "docked",
10277
- "error"
10278
- ]),
10299
+ activity: LawnMowerActivitySchema,
10279
10300
  /** 0..100 battery percentage. Null when the device has no battery
10280
10301
  * reading. */
10281
10302
  batteryLevel: number().min(0).max(100).nullable(),
10303
+ /** 0..100 mowing-completion percentage of the current task, or null when no
10304
+ * task is active / progress is unavailable. */
10305
+ progressPercent: number().min(0).max(100).nullable(),
10306
+ /** Current device/event code (dynamic — mostly status, sometimes an error),
10307
+ * or null when unknown. */
10308
+ currentCode: number().nullable(),
10309
+ /** Human label for {@link currentCode}, or null when undecodable. */
10310
+ currentCodeLabel: string().nullable(),
10311
+ /** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
10312
+ * attention; `info` is normal status. */
10313
+ severity: DeviceCodeSeveritySchema,
10282
10314
  /** Ms epoch when the slice was last updated. */
10283
10315
  lastChangedAt: number()
10284
10316
  });
@@ -12504,6 +12536,7 @@ var VacuumStateSchema = _enum([
12504
12536
  "paused",
12505
12537
  "returning",
12506
12538
  "docked",
12539
+ "drying",
12507
12540
  "error"
12508
12541
  ]);
12509
12542
  /**
@@ -12542,6 +12575,12 @@ var VacuumControlStatusSchema = object({
12542
12575
  detergent: TankStatusSchema.nullable(),
12543
12576
  /** Dust bin. Null when the hardware has no dust bin. */
12544
12577
  dustBin: TankStatusSchema.nullable(),
12578
+ /** 0..100 cleaning-completion percentage of the current task, or null. */
12579
+ progressPercent: number().min(0).max(100).nullable(),
12580
+ /** Current error code (0 / null = no error). */
12581
+ errorCode: number().nullable(),
12582
+ /** Human label for {@link errorCode}, or null when none / undecodable. */
12583
+ errorLabel: string().nullable(),
12545
12584
  /** Ms epoch when the slice was last updated. */
12546
12585
  lastChangedAt: number()
12547
12586
  });
@@ -13508,9 +13547,29 @@ var BaseDevice = class {
13508
13547
  * is open (Reolink writes `hasPtz/hasIntercom`, Hikvision writes
13509
13548
  * `hasSupplementalLight/hasAlarmIo`, etc).
13510
13549
  *
13511
- * Default: no-op (driver had no probe to run).
13512
- */
13513
- async onProbe() {}
13550
+ * Default: nothing to probe mark the device PROBED (set `lastProbedAt`) so
13551
+ * the kernel treats it as ready immediately. A device that derives its shape
13552
+ * from a spec (a container, or an accessory sensor) rather than from a
13553
+ * hardware probe has no probe to "complete"; without stamping `lastProbedAt`
13554
+ * it would look perpetually un-probed — logging "Initial probe did not
13555
+ * complete" on every boot and spinning a pointless retry chain. Drivers that
13556
+ * DO probe override this and write their own `feature-probe` slice (including
13557
+ * `lastProbedAt`) once their probe actually succeeds.
13558
+ */
13559
+ async onProbe() {
13560
+ const base = this.runtimeState.getCapState("feature-probe") ?? {
13561
+ flags: {},
13562
+ deviceType: null,
13563
+ model: null,
13564
+ channelCount: null,
13565
+ lastProbedAt: 0,
13566
+ lastFetchedAt: 0
13567
+ };
13568
+ this.runtimeState.setCapState("feature-probe", {
13569
+ ...base,
13570
+ lastProbedAt: Date.now()
13571
+ });
13572
+ }
13514
13573
  /**
13515
13574
  * Phase 5 — fired after the device + its accessories are registered.
13516
13575
  * Drivers publish streams to the broker, kick off background tasks,
@@ -14972,17 +15031,32 @@ var ReleaseInputSchema = object({
14972
15031
  * the parent cascades into every accessory. */
14973
15032
  camDeviceId: number().int().nonnegative()
14974
15033
  });
14975
- var ResyncInputSchema = object({
14976
- /** Parent CamStack device id of an adopted device. The provider resolves its
14977
- * source (integration/broker + native id) and re-aligns the device's
14978
- * structural spec (type/role/capabilities/units) with the live mapping,
14979
- * rebuilding any child whose class changed while preserving operator edits. */
14980
- camDeviceId: number().int().nonnegative() });
15034
+ var ResyncInputSchema = object({
15035
+ /** Parent CamStack device id of an adopted device. The provider resolves its
15036
+ * source (integration/broker + native id) and re-aligns the device's
15037
+ * structural spec (type/role/capabilities/units) with the live mapping,
15038
+ * rebuilding any child whose class changed while preserving operator edits. */
15039
+ camDeviceId: number().int().nonnegative(),
15040
+ /** "Resync from zero" (#19). When true, the kernel PURGES every accessory
15041
+ * child of `camDeviceId` BEFORE the provider re-derives the device, so the
15042
+ * children are rebuilt fresh from source — correct names, coords, and units —
15043
+ * instead of being preserved by the incremental reconcile. Use to recover from
15044
+ * legacy generic/placeholder names that the normal name-precedence keeps frozen
15045
+ * (the operator's explicit reset). Push-driven integrations (no-op resync)
15046
+ * rebuild on their next snapshot; pull/command integrations rebuild in `resync`.
15047
+ * Operator edits on the PARENT (its name, layout, primary-child pick) survive —
15048
+ * only the children are torn down. Omitted/false ⇒ the normal incremental
15049
+ * re-sync that preserves children. */
15050
+ resetToSource: boolean().optional()
15051
+ });
14981
15052
  var ResyncResultSchema = object({
14982
15053
  /** True when the persisted spec actually changed (children may have been rebuilt). */
14983
15054
  changed: boolean(),
14984
15055
  /** Number of child devices rebuilt into a new class by this re-sync. */
14985
- rebuiltChildren: number().int().nonnegative()
15056
+ rebuiltChildren: number().int().nonnegative(),
15057
+ /** Number of accessory children torn down by a `resetToSource` purge before the
15058
+ * provider re-derived the device. 0/absent for a normal incremental re-sync. */
15059
+ removedChildren: number().int().nonnegative().optional()
14986
15060
  });
14987
15061
  var deviceAdoptionCapability = {
14988
15062
  name: "device-adoption",
@@ -16764,6 +16838,11 @@ var DeviceMetaSchema = object({
16764
16838
  addonId: string(),
16765
16839
  type: string(),
16766
16840
  name: string(),
16841
+ /** True once an operator explicitly renamed the device via `setName`. Drives
16842
+ * reconcile name-precedence (preserve operator name vs adopt fresh provider
16843
+ * name). Absent ⇒ treated as user-named (PRESERVE) for legacy rows. See
16844
+ * `DeviceMeta.userNamed`. */
16845
+ userNamed: boolean().optional(),
16767
16846
  location: string().nullable(),
16768
16847
  disabled: boolean(),
16769
16848
  parentDeviceId: number().nullable(),
@@ -17074,6 +17153,9 @@ method(object({
17074
17153
  }), method(ReleaseInputSchema.extend({ addonId: string() }), _void(), {
17075
17154
  kind: "mutation",
17076
17155
  auth: "admin"
17156
+ }), method(ResyncInputSchema, ResyncResultSchema, {
17157
+ kind: "mutation",
17158
+ auth: "admin"
17077
17159
  }), method(object({
17078
17160
  deviceId: number(),
17079
17161
  key: string(),
@@ -20853,6 +20935,12 @@ Object.freeze({
20853
20935
  addonId: null,
20854
20936
  access: "create"
20855
20937
  },
20938
+ "deviceManager.adoptionResync": {
20939
+ capName: "device-manager",
20940
+ capScope: "system",
20941
+ addonId: null,
20942
+ access: "create"
20943
+ },
20856
20944
  "deviceManager.allocateDeviceId": {
20857
20945
  capName: "device-manager",
20858
20946
  capScope: "system",
@@ -65600,7 +65688,7 @@ var AlexaProxyLoginManager = class {
65600
65688
  } catch (err) {
65601
65689
  this.#session = null;
65602
65690
  await session.dispose();
65603
- throw new Error(`alexa proxy-login: failed to start proxy — ${errMsg(err)}`);
65691
+ throw new Error(`alexa proxy-login: failed to start proxy — ${errMsg(err)}`, { cause: err });
65604
65692
  }
65605
65693
  return {
65606
65694
  sessionId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-import-alexa",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Alexa device-import provider for CamStack — imports the smart-home devices in a user's Alexa account via the unofficial alexa-remote2 cookie/token client (the inverse of the Alexa exporter)",
5
5
  "keywords": [
6
6
  "camstack",