@camstack/addon-import-alexa 0.2.198 → 0.2.199

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/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.199] - 2026-11-08
11
+
12
+ ### Changed
13
+
14
+ - Its integration-instances provider declares its instance kind and stamps it on every instance.
15
+
10
16
  ## [0.2.198] - 2026-11-08
11
17
 
12
18
  ### Changed
package/dist/addon.js CHANGED
@@ -6068,7 +6068,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
6068
6068
  return DeviceRole;
6069
6069
  }({});
6070
6070
  //#endregion
6071
- //#region ../types/dist/sleep-7El4r5Bl.mjs
6071
+ //#region ../types/dist/sleep-CGPZyzB5.mjs
6072
6072
  /**
6073
6073
  * The audio chunk plane's byte format, and the ONE expansion from a coded
6074
6074
  * window to float samples (D455).
@@ -7300,6 +7300,7 @@ var RecordIntegrationInstances = class {
7300
7300
  this.secretKeys = topLevelSecretKeys(kind.declaration.secretPaths);
7301
7301
  this.secretMaps = secretMapKeys(kind.declaration.secretPaths);
7302
7302
  this.nameField = kind.declaration.entry?.nameField ?? "name";
7303
+ if (hooks.kindOf === void 0 && hooks.description.kinds.length !== 1) throw new Error(`record kind '${kind.name}': describe().kinds has ${hooks.description.kinds.length} entries, so kindOf is required to say which one an instance is`);
7303
7304
  }
7304
7305
  /**
7305
7306
  * One instance read for the addon's own runtime; null when absent. When the keychain is
@@ -7341,10 +7342,21 @@ var RecordIntegrationInstances = class {
7341
7342
  }
7342
7343
  return out;
7343
7344
  }
7345
+ /** The kind an instance body is of: the provider's `kindOf`, else its one declared kind. */
7346
+ kindOfBody(body) {
7347
+ if (this.hooks.kindOf !== void 0) {
7348
+ const id = this.hooks.kindOf(body);
7349
+ if (!this.hooks.description.kinds.some((declared) => declared.id === id)) throw new Error(`record kind '${this.kind.name}': kindOf returned '${id}', which describe().kinds does not declare (D1013)`);
7350
+ return id;
7351
+ }
7352
+ const only = this.hooks.description.kinds[0];
7353
+ if (only === void 0) throw new Error(`record kind '${this.kind.name}' declares no kinds`);
7354
+ return only.id;
7355
+ }
7344
7356
  viewOf(record) {
7345
7357
  const shown = secretViewsOf(this.records.owner, this.kind.name, record.id, this.kind.declaration, record.data);
7346
7358
  const rawName = record.data[this.nameField];
7347
- const kind = this.hooks.kindOf?.(record.data);
7359
+ const kind = this.kindOfBody(record.data);
7348
7360
  const health = this.hooks.health?.(record.data, record.id);
7349
7361
  return {
7350
7362
  id: record.id,
@@ -7352,7 +7364,7 @@ var RecordIntegrationInstances = class {
7352
7364
  configured: this.hooks.configured(record.data),
7353
7365
  enabled: isInstanceEnabled(record.data),
7354
7366
  formValues: shown,
7355
- ...kind !== void 0 ? { kind } : {},
7367
+ kind,
7356
7368
  ...health?.status !== void 0 ? { status: health.status } : {},
7357
7369
  ...health?.lastCheckedAt !== void 0 ? { lastCheckedAt: health.lastCheckedAt } : {}
7358
7370
  };
@@ -15350,43 +15362,44 @@ function notificationTargetParts(records, spec) {
15350
15362
  const defined = spec.kinds[notificationTargetKindName(descriptor.kind)];
15351
15363
  if (defined === void 0) return [];
15352
15364
  const canTest = spec.probe !== void 0 && spec.canProbe(descriptor.kind);
15353
- const instances = new RecordIntegrationInstances(records, defined, {
15354
- description: {
15355
- role: "services",
15356
- instanceMode: "multiple",
15357
- kind: "target",
15358
- canTest
15359
- },
15360
- formSchema: () => formOf(descriptor),
15361
- initialBody: (name) => ({ name }),
15362
- mintId: () => spec.mintId(),
15363
- configured: () => true,
15364
- validateWrite: ({ body }) => spec.validate?.({
15365
- kind: descriptor.kind,
15366
- config: body
15367
- }),
15368
- test: async ({ id, values }) => {
15369
- if (spec.probe === void 0 || !canTest) return {
15370
- success: false,
15371
- status: "unsupported",
15372
- error: "This kind cannot be tested"
15373
- };
15374
- return probeToTestResult(await spec.probe({
15375
- kind: descriptor.kind,
15376
- config: values,
15377
- targetId: id ?? void 0
15378
- }));
15379
- }
15380
- });
15365
+ const kind = {
15366
+ id: descriptor.kind,
15367
+ label: descriptor.label,
15368
+ functionCap: NOTIFICATION_OUTPUT_CAP,
15369
+ role: "services",
15370
+ canTest
15371
+ };
15381
15372
  return [{
15382
- kind: {
15383
- id: descriptor.kind,
15384
- label: descriptor.label,
15385
- functionCap: NOTIFICATION_OUTPUT_CAP,
15386
- role: "services",
15387
- canTest
15388
- },
15389
- provider: instances.toProvider()
15373
+ kind,
15374
+ provider: new RecordIntegrationInstances(records, defined, {
15375
+ description: {
15376
+ role: "services",
15377
+ instanceMode: "multiple",
15378
+ kind: "target",
15379
+ canTest,
15380
+ kinds: [kind]
15381
+ },
15382
+ formSchema: () => formOf(descriptor),
15383
+ initialBody: (name) => ({ name }),
15384
+ mintId: () => spec.mintId(),
15385
+ configured: () => true,
15386
+ validateWrite: ({ body }) => spec.validate?.({
15387
+ kind: descriptor.kind,
15388
+ config: body
15389
+ }),
15390
+ test: async ({ id, values }) => {
15391
+ if (spec.probe === void 0 || !canTest) return {
15392
+ success: false,
15393
+ status: "unsupported",
15394
+ error: "This kind cannot be tested"
15395
+ };
15396
+ return probeToTestResult(await spec.probe({
15397
+ kind: descriptor.kind,
15398
+ config: values,
15399
+ targetId: id ?? void 0
15400
+ }));
15401
+ }
15402
+ }).toProvider()
15390
15403
  }];
15391
15404
  });
15392
15405
  }
@@ -50623,7 +50636,7 @@ var mediaPlayerCapability = {
50623
50636
  isMuted: { kind: "boolean" }
50624
50637
  } }
50625
50638
  };
50626
- DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Heater, DeviceType.Dryer, DeviceType.Gateway, DeviceType.Camera, DeviceType.Fan, DeviceType.Lock, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Gateway, DeviceType.Hub, DeviceType.Camera, DeviceType.Sensor, DeviceType.MediaPlayer, DeviceType.Vacuum, DeviceType.Generic, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.PetFountain, DeviceType.Fan, DeviceType.Humidifier, DeviceType.Climate, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder, DeviceType.Heater;
50639
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Heater, DeviceType.Dryer, DeviceType.Gateway, DeviceType.Camera, DeviceType.Fan, DeviceType.Lock, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Gateway, DeviceType.Hub, DeviceType.Camera, DeviceType.Sensor, DeviceType.MediaPlayer, DeviceType.Vacuum, DeviceType.Generic, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.PetFountain, DeviceType.Fan, DeviceType.Humidifier, DeviceType.Climate, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.MediaPlayer;
50627
50640
  var NUMBER = {
50628
50641
  kind: "fixed",
50629
50642
  result: ["number"]
@@ -57277,10 +57290,11 @@ var IntegrationInstanceDescriptionSchema = object({
57277
57290
  /** True when `testInstance` really probes the remote. */
57278
57291
  canTest: boolean(),
57279
57292
  /**
57280
- * The kinds an instance can be of. Absent or one entry: nothing to choose; more than one: the
57281
- * Add flow asks which first and sends it as `createInstance.kind`.
57293
+ * The kinds an instance can be of (D1013 rule 1), each naming its `functionCap`. One entry:
57294
+ * nothing to choose; more than one: the Add flow asks which first and sends it as
57295
+ * `createInstance.kind`. Never empty: every instance belongs to exactly one kind.
57282
57296
  */
57283
- kinds: array(IntegrationInstanceKindSchema).optional(),
57297
+ kinds: array(IntegrationInstanceKindSchema).min(1),
57284
57298
  /**
57285
57299
  * The provider accepts `createInstance.id` for an id that once existed (an adopted id, because
57286
57300
  * devices carry it). The UI then offers "restore under its old id" on Add. Absent means no.
@@ -57316,8 +57330,8 @@ var IntegrationInstanceSchema = object({
57316
57330
  * the body is the one store, `setInstanceEnabled` the one writer (epic #440, step 3).
57317
57331
  */
57318
57332
  enabled: boolean().optional(),
57319
- /** The kind of this instance (one of `describe().kinds[].id`), when the provider has kinds. */
57320
- kind: string().optional(),
57333
+ /** The kind of this instance: exactly one of `describe().kinds[].id` (D1013 rule 2). */
57334
+ kind: string().min(1),
57321
57335
  /** Values for the instance form; a secret is a `SecretFieldView`, never text. */
57322
57336
  formValues: record(string(), unknown()),
57323
57337
  status: IntegrationInstanceStatusSchema.optional(),
@@ -75686,6 +75700,16 @@ var RemoteLayoutComponentSchema = object({
75686
75700
  method(object({}), array(RemoteLayoutComponentSchema), { auth: "protected" });
75687
75701
  var RUNNING_POWER_START_DELAY_MS = 3e4;
75688
75702
  var RUNNING_POWER_STOP_DELAY_MS = 18e4;
75703
+ /**
75704
+ * Per-type overrides of the dwell defaults. A media player draws power the
75705
+ * moment it is on and stops drawing the moment it is off, so it needs neither
75706
+ * a long dwell nor a second sample. A type absent here keeps the global values.
75707
+ */
75708
+ var RUNNING_POWER_DEFAULTS_BY_TYPE = { [DeviceType.MediaPlayer]: {
75709
+ startDwellMs: 1e4,
75710
+ stopDwellMs: 1e4,
75711
+ minSamples: 1
75712
+ } };
75689
75713
  var RunningStateSourceSchema = _enum(["native", "assigned"]);
75690
75714
  var RunningStateStatusSchema = object({
75691
75715
  /** null = unknown — never coerced to false (D393). */
@@ -75778,6 +75802,7 @@ var runningStateCapability = {
75778
75802
  defaultThreshold: 5,
75779
75803
  defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
75780
75804
  defaultStopDwellMs: RUNNING_POWER_STOP_DELAY_MS,
75805
+ deviceTypeDefaults: RUNNING_POWER_DEFAULTS_BY_TYPE,
75781
75806
  thresholdUnit: "W"
75782
75807
  }]
75783
75808
  }
@@ -145181,7 +145206,14 @@ function buildAlexaAccountInstances(records, deps) {
145181
145206
  instanceMode: "multiple",
145182
145207
  kind: "account",
145183
145208
  canTest: true,
145184
- allowRestoreId: true
145209
+ allowRestoreId: true,
145210
+ kinds: [{
145211
+ id: ALEXA_ACCOUNT_KIND,
145212
+ label: "Alexa account",
145213
+ functionCap: "broker",
145214
+ role: "services",
145215
+ brokerKind: ALEXA_BROKER_KIND
145216
+ }]
145185
145217
  },
145186
145218
  formSchema: () => buildConnectionFormSchema(),
145187
145219
  initialBody: (name) => ({
@@ -145235,7 +145267,13 @@ function buildAlexaInstances(records) {
145235
145267
  role: "devices",
145236
145268
  instanceMode: "multiple",
145237
145269
  kind: "connection",
145238
- canTest: false
145270
+ canTest: false,
145271
+ kinds: [{
145272
+ id: "integration",
145273
+ label: "Alexa",
145274
+ functionCap: "device-provider",
145275
+ role: "devices"
145276
+ }]
145239
145277
  },
145240
145278
  labels: { brokerId: { label: "Alexa account" } }
145241
145279
  });
package/dist/addon.mjs CHANGED
@@ -6066,7 +6066,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
6066
6066
  return DeviceRole;
6067
6067
  }({});
6068
6068
  //#endregion
6069
- //#region ../types/dist/sleep-7El4r5Bl.mjs
6069
+ //#region ../types/dist/sleep-CGPZyzB5.mjs
6070
6070
  /**
6071
6071
  * The audio chunk plane's byte format, and the ONE expansion from a coded
6072
6072
  * window to float samples (D455).
@@ -7298,6 +7298,7 @@ var RecordIntegrationInstances = class {
7298
7298
  this.secretKeys = topLevelSecretKeys(kind.declaration.secretPaths);
7299
7299
  this.secretMaps = secretMapKeys(kind.declaration.secretPaths);
7300
7300
  this.nameField = kind.declaration.entry?.nameField ?? "name";
7301
+ if (hooks.kindOf === void 0 && hooks.description.kinds.length !== 1) throw new Error(`record kind '${kind.name}': describe().kinds has ${hooks.description.kinds.length} entries, so kindOf is required to say which one an instance is`);
7301
7302
  }
7302
7303
  /**
7303
7304
  * One instance read for the addon's own runtime; null when absent. When the keychain is
@@ -7339,10 +7340,21 @@ var RecordIntegrationInstances = class {
7339
7340
  }
7340
7341
  return out;
7341
7342
  }
7343
+ /** The kind an instance body is of: the provider's `kindOf`, else its one declared kind. */
7344
+ kindOfBody(body) {
7345
+ if (this.hooks.kindOf !== void 0) {
7346
+ const id = this.hooks.kindOf(body);
7347
+ if (!this.hooks.description.kinds.some((declared) => declared.id === id)) throw new Error(`record kind '${this.kind.name}': kindOf returned '${id}', which describe().kinds does not declare (D1013)`);
7348
+ return id;
7349
+ }
7350
+ const only = this.hooks.description.kinds[0];
7351
+ if (only === void 0) throw new Error(`record kind '${this.kind.name}' declares no kinds`);
7352
+ return only.id;
7353
+ }
7342
7354
  viewOf(record) {
7343
7355
  const shown = secretViewsOf(this.records.owner, this.kind.name, record.id, this.kind.declaration, record.data);
7344
7356
  const rawName = record.data[this.nameField];
7345
- const kind = this.hooks.kindOf?.(record.data);
7357
+ const kind = this.kindOfBody(record.data);
7346
7358
  const health = this.hooks.health?.(record.data, record.id);
7347
7359
  return {
7348
7360
  id: record.id,
@@ -7350,7 +7362,7 @@ var RecordIntegrationInstances = class {
7350
7362
  configured: this.hooks.configured(record.data),
7351
7363
  enabled: isInstanceEnabled(record.data),
7352
7364
  formValues: shown,
7353
- ...kind !== void 0 ? { kind } : {},
7365
+ kind,
7354
7366
  ...health?.status !== void 0 ? { status: health.status } : {},
7355
7367
  ...health?.lastCheckedAt !== void 0 ? { lastCheckedAt: health.lastCheckedAt } : {}
7356
7368
  };
@@ -15348,43 +15360,44 @@ function notificationTargetParts(records, spec) {
15348
15360
  const defined = spec.kinds[notificationTargetKindName(descriptor.kind)];
15349
15361
  if (defined === void 0) return [];
15350
15362
  const canTest = spec.probe !== void 0 && spec.canProbe(descriptor.kind);
15351
- const instances = new RecordIntegrationInstances(records, defined, {
15352
- description: {
15353
- role: "services",
15354
- instanceMode: "multiple",
15355
- kind: "target",
15356
- canTest
15357
- },
15358
- formSchema: () => formOf(descriptor),
15359
- initialBody: (name) => ({ name }),
15360
- mintId: () => spec.mintId(),
15361
- configured: () => true,
15362
- validateWrite: ({ body }) => spec.validate?.({
15363
- kind: descriptor.kind,
15364
- config: body
15365
- }),
15366
- test: async ({ id, values }) => {
15367
- if (spec.probe === void 0 || !canTest) return {
15368
- success: false,
15369
- status: "unsupported",
15370
- error: "This kind cannot be tested"
15371
- };
15372
- return probeToTestResult(await spec.probe({
15373
- kind: descriptor.kind,
15374
- config: values,
15375
- targetId: id ?? void 0
15376
- }));
15377
- }
15378
- });
15363
+ const kind = {
15364
+ id: descriptor.kind,
15365
+ label: descriptor.label,
15366
+ functionCap: NOTIFICATION_OUTPUT_CAP,
15367
+ role: "services",
15368
+ canTest
15369
+ };
15379
15370
  return [{
15380
- kind: {
15381
- id: descriptor.kind,
15382
- label: descriptor.label,
15383
- functionCap: NOTIFICATION_OUTPUT_CAP,
15384
- role: "services",
15385
- canTest
15386
- },
15387
- provider: instances.toProvider()
15371
+ kind,
15372
+ provider: new RecordIntegrationInstances(records, defined, {
15373
+ description: {
15374
+ role: "services",
15375
+ instanceMode: "multiple",
15376
+ kind: "target",
15377
+ canTest,
15378
+ kinds: [kind]
15379
+ },
15380
+ formSchema: () => formOf(descriptor),
15381
+ initialBody: (name) => ({ name }),
15382
+ mintId: () => spec.mintId(),
15383
+ configured: () => true,
15384
+ validateWrite: ({ body }) => spec.validate?.({
15385
+ kind: descriptor.kind,
15386
+ config: body
15387
+ }),
15388
+ test: async ({ id, values }) => {
15389
+ if (spec.probe === void 0 || !canTest) return {
15390
+ success: false,
15391
+ status: "unsupported",
15392
+ error: "This kind cannot be tested"
15393
+ };
15394
+ return probeToTestResult(await spec.probe({
15395
+ kind: descriptor.kind,
15396
+ config: values,
15397
+ targetId: id ?? void 0
15398
+ }));
15399
+ }
15400
+ }).toProvider()
15388
15401
  }];
15389
15402
  });
15390
15403
  }
@@ -50621,7 +50634,7 @@ var mediaPlayerCapability = {
50621
50634
  isMuted: { kind: "boolean" }
50622
50635
  } }
50623
50636
  };
50624
- DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Heater, DeviceType.Dryer, DeviceType.Gateway, DeviceType.Camera, DeviceType.Fan, DeviceType.Lock, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Gateway, DeviceType.Hub, DeviceType.Camera, DeviceType.Sensor, DeviceType.MediaPlayer, DeviceType.Vacuum, DeviceType.Generic, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.PetFountain, DeviceType.Fan, DeviceType.Humidifier, DeviceType.Climate, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder, DeviceType.Heater;
50637
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Heater, DeviceType.Dryer, DeviceType.Gateway, DeviceType.Camera, DeviceType.Fan, DeviceType.Lock, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Gateway, DeviceType.Hub, DeviceType.Camera, DeviceType.Sensor, DeviceType.MediaPlayer, DeviceType.Vacuum, DeviceType.Generic, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.PetFountain, DeviceType.Fan, DeviceType.Humidifier, DeviceType.Climate, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.MediaPlayer;
50625
50638
  var NUMBER = {
50626
50639
  kind: "fixed",
50627
50640
  result: ["number"]
@@ -57275,10 +57288,11 @@ var IntegrationInstanceDescriptionSchema = object({
57275
57288
  /** True when `testInstance` really probes the remote. */
57276
57289
  canTest: boolean(),
57277
57290
  /**
57278
- * The kinds an instance can be of. Absent or one entry: nothing to choose; more than one: the
57279
- * Add flow asks which first and sends it as `createInstance.kind`.
57291
+ * The kinds an instance can be of (D1013 rule 1), each naming its `functionCap`. One entry:
57292
+ * nothing to choose; more than one: the Add flow asks which first and sends it as
57293
+ * `createInstance.kind`. Never empty: every instance belongs to exactly one kind.
57280
57294
  */
57281
- kinds: array(IntegrationInstanceKindSchema).optional(),
57295
+ kinds: array(IntegrationInstanceKindSchema).min(1),
57282
57296
  /**
57283
57297
  * The provider accepts `createInstance.id` for an id that once existed (an adopted id, because
57284
57298
  * devices carry it). The UI then offers "restore under its old id" on Add. Absent means no.
@@ -57314,8 +57328,8 @@ var IntegrationInstanceSchema = object({
57314
57328
  * the body is the one store, `setInstanceEnabled` the one writer (epic #440, step 3).
57315
57329
  */
57316
57330
  enabled: boolean().optional(),
57317
- /** The kind of this instance (one of `describe().kinds[].id`), when the provider has kinds. */
57318
- kind: string().optional(),
57331
+ /** The kind of this instance: exactly one of `describe().kinds[].id` (D1013 rule 2). */
57332
+ kind: string().min(1),
57319
57333
  /** Values for the instance form; a secret is a `SecretFieldView`, never text. */
57320
57334
  formValues: record(string(), unknown()),
57321
57335
  status: IntegrationInstanceStatusSchema.optional(),
@@ -75684,6 +75698,16 @@ var RemoteLayoutComponentSchema = object({
75684
75698
  method(object({}), array(RemoteLayoutComponentSchema), { auth: "protected" });
75685
75699
  var RUNNING_POWER_START_DELAY_MS = 3e4;
75686
75700
  var RUNNING_POWER_STOP_DELAY_MS = 18e4;
75701
+ /**
75702
+ * Per-type overrides of the dwell defaults. A media player draws power the
75703
+ * moment it is on and stops drawing the moment it is off, so it needs neither
75704
+ * a long dwell nor a second sample. A type absent here keeps the global values.
75705
+ */
75706
+ var RUNNING_POWER_DEFAULTS_BY_TYPE = { [DeviceType.MediaPlayer]: {
75707
+ startDwellMs: 1e4,
75708
+ stopDwellMs: 1e4,
75709
+ minSamples: 1
75710
+ } };
75687
75711
  var RunningStateSourceSchema = _enum(["native", "assigned"]);
75688
75712
  var RunningStateStatusSchema = object({
75689
75713
  /** null = unknown — never coerced to false (D393). */
@@ -75776,6 +75800,7 @@ var runningStateCapability = {
75776
75800
  defaultThreshold: 5,
75777
75801
  defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
75778
75802
  defaultStopDwellMs: RUNNING_POWER_STOP_DELAY_MS,
75803
+ deviceTypeDefaults: RUNNING_POWER_DEFAULTS_BY_TYPE,
75779
75804
  thresholdUnit: "W"
75780
75805
  }]
75781
75806
  }
@@ -145179,7 +145204,14 @@ function buildAlexaAccountInstances(records, deps) {
145179
145204
  instanceMode: "multiple",
145180
145205
  kind: "account",
145181
145206
  canTest: true,
145182
- allowRestoreId: true
145207
+ allowRestoreId: true,
145208
+ kinds: [{
145209
+ id: ALEXA_ACCOUNT_KIND,
145210
+ label: "Alexa account",
145211
+ functionCap: "broker",
145212
+ role: "services",
145213
+ brokerKind: ALEXA_BROKER_KIND
145214
+ }]
145183
145215
  },
145184
145216
  formSchema: () => buildConnectionFormSchema(),
145185
145217
  initialBody: (name) => ({
@@ -145233,7 +145265,13 @@ function buildAlexaInstances(records) {
145233
145265
  role: "devices",
145234
145266
  instanceMode: "multiple",
145235
145267
  kind: "connection",
145236
- canTest: false
145268
+ canTest: false,
145269
+ kinds: [{
145270
+ id: "integration",
145271
+ label: "Alexa",
145272
+ functionCap: "device-provider",
145273
+ role: "devices"
145274
+ }]
145237
145275
  },
145238
145276
  labels: { brokerId: { label: "Alexa account" } }
145239
145277
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-import-alexa",
3
- "version": "0.2.198",
3
+ "version": "0.2.199",
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",
@@ -72,7 +72,7 @@
72
72
  }
73
73
  ],
74
74
  "requires": {
75
- "server": ">=1.2.805"
75
+ "server": ">=1.2.810"
76
76
  }
77
77
  },
78
78
  "files": [