@camstack/addon-provider-rademacher 0.2.153 → 0.2.154

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.154] - 2026-10-31
11
+
12
+ ### Changed
13
+
14
+ - The adoption modal lists the HomePilot gateway beside its roller shutters instead of nesting them under it.
15
+
10
16
  ## [0.2.153] - 2026-10-31
11
17
 
12
18
  ### Changed
package/dist/addon.js CHANGED
@@ -5458,7 +5458,7 @@ var ZodIssueCode = {
5458
5458
  var ZodFirstPartyTypeKind;
5459
5459
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5460
5460
  //#endregion
5461
- //#region ../types/dist/sleep-0RR2wzNB.mjs
5461
+ //#region ../types/dist/sleep-DSVWZfJC.mjs
5462
5462
  /**
5463
5463
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5464
5464
  * window to float samples (D455).
@@ -7161,6 +7161,26 @@ var BaseAddon = class {
7161
7161
  * alternative — skip it — turns a rename into a surface that quietly
7162
7162
  * empties, which looks exactly like an addon with nothing to configure.
7163
7163
  */
7164
+ /**
7165
+ * The form schema of ONE integration instance, or `null` to use {@link globalSettingsSchema}.
7166
+ *
7167
+ * Override it only when an `instanceMode: multiple` addon's instances differ: an NVR integration
7168
+ * needs its connection fields, the default integration the addon's own sections. It is the
7169
+ * SHAPE of the form only — the values live in `integrations.getSettings`, and the write path is
7170
+ * unchanged (`integrations.setSettings` for an account integration).
7171
+ */
7172
+ async integrationSettingsSchema(_instance) {
7173
+ return null;
7174
+ }
7175
+ /**
7176
+ * What the create wizard and the integration edit page render for one instance: the addon's
7177
+ * per-instance schema when it declares one, else its global schema (what they always showed).
7178
+ */
7179
+ async getIntegrationFormSchema(instance, nodeId) {
7180
+ const scoped = await this.integrationSettingsSchema(instance);
7181
+ if (scoped === null) return this.getGlobalSettings(void 0, void 0, nodeId);
7182
+ return hydrateSchema(scoped, {}, { inlineSecretsAsViews: true });
7183
+ }
7164
7184
  async getIntegrationSettings(nodeId) {
7165
7185
  const declared = this.integrationSettingSections();
7166
7186
  if (declared.length === 0) return null;
@@ -9847,7 +9867,8 @@ Object.freeze({
9847
9867
  "unlocked",
9848
9868
  "locking",
9849
9869
  "unlocking",
9850
- "jammed"
9870
+ "jammed",
9871
+ "door-open"
9851
9872
  ]
9852
9873
  }],
9853
9874
  "media-player": [
@@ -12335,6 +12356,25 @@ var EventOwnerTypeSchema = _enum(EVENT_OWNER_TYPES);
12335
12356
  /** The same list as a Zod enum, for the cap input that carries it. */
12336
12357
  var MediaPresenceOwnerKindSchema = _enum([...EVENT_OWNER_TYPES, "track"]);
12337
12358
  new Set(EVENT_OWNER_TYPES);
12359
+ /**
12360
+ * Which integration instance a settings form is for. An addon that serves several instances
12361
+ * (`instanceMode: multiple`) can show a different form per instance — an NVR integration
12362
+ * needs its connection, the default integration needs the addon's own sections.
12363
+ *
12364
+ * - `integrationId` is `null` in the create wizard: nothing exists yet, the operator is
12365
+ * setting up a NEW instance.
12366
+ * - `mode` is the wizard mode of the integration type (`getAvailableTypes`).
12367
+ * - `candidateStableId` is the discovery candidate a wizard was seeded from, if any.
12368
+ */
12369
+ var IntegrationInstanceRefSchema = object({
12370
+ integrationId: string().nullable(),
12371
+ mode: _enum([
12372
+ "standalone",
12373
+ "account",
12374
+ "broker"
12375
+ ]),
12376
+ candidateStableId: string().optional()
12377
+ });
12338
12378
  var EncodeProfileSchema = object({
12339
12379
  video: object({
12340
12380
  codec: _enum([
@@ -16274,6 +16314,11 @@ var ACTUATOR_CAP_VOCABULARY = {
16274
16314
  value: "jammed",
16275
16315
  label: t("Jammed", "Inceppata"),
16276
16316
  phrase: t("When {device} jams", "Quando {device} si inceppa")
16317
+ },
16318
+ {
16319
+ value: "door-open",
16320
+ label: t("Door open", "Porta aperta"),
16321
+ phrase: t("When the door of {device} opens", "Quando la porta di {device} si apre")
16277
16322
  }
16278
16323
  ],
16279
16324
  icon: "lock"
@@ -42210,6 +42255,10 @@ method(object({
42210
42255
  }), method(object({
42211
42256
  addonId: string(),
42212
42257
  nodeId: string().optional()
42258
+ }), SettingsSchemaWithValuesSchema.nullable()), method(object({
42259
+ addonId: string(),
42260
+ nodeId: string().optional(),
42261
+ instance: IntegrationInstanceRefSchema
42213
42262
  }), SettingsSchemaWithValuesSchema.nullable()), method(object({
42214
42263
  addonId: string(),
42215
42264
  nodeId: string().optional()
@@ -44977,6 +45026,7 @@ method(object({
44977
45026
  kind: "mutation",
44978
45027
  auth: "admin"
44979
45028
  }), method(object({ blockIds: array(string()) }), object({ states: array(CompositionBlockStateSchema) }), { auth: "admin" });
45029
+ 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.Dryer, DeviceType.Gateway, DeviceType.Camera, 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.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.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.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.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;
44980
45030
  var NUMBER = {
44981
45031
  kind: "fixed",
44982
45032
  result: ["number"]
@@ -68202,6 +68252,8 @@ var IntegrationWithStateSchema = object({
68202
68252
  name: string(),
68203
68253
  enabled: boolean(),
68204
68254
  info: record(string(), unknown()).readonly(),
68255
+ /** The discovery candidate this integration was set up from (D984). */
68256
+ originStableId: string().optional(),
68205
68257
  createdAt: number(),
68206
68258
  updatedAt: number(),
68207
68259
  processState: string()
@@ -68212,6 +68264,8 @@ var IntegrationLiteSchema = object({
68212
68264
  name: string(),
68213
68265
  enabled: boolean(),
68214
68266
  info: record(string(), unknown()).readonly(),
68267
+ /** The discovery candidate this integration was set up from (D984). */
68268
+ originStableId: string().optional(),
68215
68269
  createdAt: number(),
68216
68270
  updatedAt: number()
68217
68271
  });
@@ -68309,6 +68363,8 @@ var CreateIntegrationInputSchema = object({
68309
68363
  name: string(),
68310
68364
  enabled: boolean().optional(),
68311
68365
  info: record(string(), unknown()).optional(),
68366
+ /** `stableId` of the discovery candidate the form was seeded from (D984). */
68367
+ originStableId: string().optional(),
68312
68368
  settings: record(string(), unknown()).optional(),
68313
68369
  /** Keys of `settings` the form's schema declares secret (by type) — kept in
68314
68370
  * the keychain, not the table (D787). */
@@ -69077,11 +69133,44 @@ var LockControlStatusSchema = object({
69077
69133
  "unlocked",
69078
69134
  "locking",
69079
69135
  "unlocking",
69080
- "jammed"
69136
+ "jammed",
69137
+ "door-open"
69081
69138
  ]),
69082
69139
  /** Ms epoch when the slice was last updated. */
69083
69140
  lastChangedAt: number()
69084
69141
  });
69142
+ /**
69143
+ * "Door contact" Customize extension (D984): the ONE extension that replaces a
69144
+ * native field. `state` is listed in `overridable` for this target, so the
69145
+ * validator and the guard accept it and nothing else.
69146
+ */
69147
+ var lockControlCustomize = {
69148
+ version: 1,
69149
+ overridable: [{
69150
+ path: "state",
69151
+ by: "door-contact"
69152
+ }],
69153
+ targets: [{
69154
+ id: "door-contact",
69155
+ cardinality: "scalar",
69156
+ vocabulary: {
69157
+ cap: "lock-control",
69158
+ stateField: "state"
69159
+ },
69160
+ deviceTypes: [DeviceType.Lock],
69161
+ apply: "replace",
69162
+ path: "state",
69163
+ override: {
69164
+ whenSourceTrue: "door-open",
69165
+ unlessNative: ["jammed"]
69166
+ },
69167
+ sources: [{
69168
+ kind: "binary",
69169
+ transforms: [{ kind: "identity" }]
69170
+ }],
69171
+ sourceReport: { status: "assignment-status" }
69172
+ }]
69173
+ };
69085
69174
  var lockControlCapability = {
69086
69175
  name: "lock-control",
69087
69176
  scope: "device",
@@ -69127,6 +69216,7 @@ var lockControlCapability = {
69127
69216
  * transitions.
69128
69217
  */
69129
69218
  runtimeState: LockControlStatusSchema,
69219
+ customize: lockControlCustomize,
69130
69220
  /**
69131
69221
  * Runtime-state durability: **restored** — a lock left locked must still read locked.
69132
69222
  *
@@ -77531,7 +77621,6 @@ discriminatedUnion("kind", [object({
77531
77621
  })]);
77532
77622
  DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
77533
77623
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
77534
- 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.Dryer, DeviceType.Gateway, DeviceType.Camera, 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.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.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.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.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;
77535
77624
  String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
77536
77625
  DeviceRole.BinarySensor, DeviceRole.MotionSensor;
77537
77626
  new Set(CAP_NAMES);
@@ -79553,6 +79642,13 @@ Object.freeze({
79553
79642
  access: "view",
79554
79643
  role: "admin"
79555
79644
  },
79645
+ "addonSettings.getIntegrationFormSchema": {
79646
+ capName: "addon-settings",
79647
+ capScope: "system",
79648
+ addonId: null,
79649
+ access: "view",
79650
+ role: "admin"
79651
+ },
79556
79652
  "addonSettings.getIntegrationSettings": {
79557
79653
  capName: "addon-settings",
79558
79654
  capScope: "system",
@@ -93087,6 +93183,7 @@ new Set([
93087
93183
  "locking",
93088
93184
  "unlocking",
93089
93185
  "jammed",
93186
+ "door-open",
93090
93187
  "on",
93091
93188
  "off",
93092
93189
  "home",
@@ -94102,8 +94199,8 @@ function resolveNativeId(integrationId, covers, childNativeId) {
94102
94199
  /**
94103
94200
  * The adoption candidates of one integration, pure and in a fixed order: the hub
94104
94201
  * box ({@link DeviceType.Gateway}), then one {@link DeviceType.Cover} per roller
94105
- * shutter. Each cover names the gateway through `parentStableId`, so the
94106
- * adoption modal nests it under the hub.
94202
+ * shutter. The gateway is a sibling of the covers, never their parent: no
94203
+ * cover names a `parentStableId`.
94107
94204
  */
94108
94205
  function buildRademacherCandidates(input) {
94109
94206
  const gatewayId = gatewayNativeId(input.integrationId);
@@ -94135,8 +94232,7 @@ function buildRademacherCandidates(input) {
94135
94232
  },
94136
94233
  alreadyAdopted: adoptedId !== null,
94137
94234
  adoptedDeviceId: adoptedId,
94138
- capabilities: [coverCapability.name],
94139
- parentStableId: gatewayId
94235
+ capabilities: [coverCapability.name]
94140
94236
  });
94141
94237
  }
94142
94238
  return out;
package/dist/addon.mjs CHANGED
@@ -5457,7 +5457,7 @@ var ZodIssueCode = {
5457
5457
  var ZodFirstPartyTypeKind;
5458
5458
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5459
5459
  //#endregion
5460
- //#region ../types/dist/sleep-0RR2wzNB.mjs
5460
+ //#region ../types/dist/sleep-DSVWZfJC.mjs
5461
5461
  /**
5462
5462
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5463
5463
  * window to float samples (D455).
@@ -7160,6 +7160,26 @@ var BaseAddon = class {
7160
7160
  * alternative — skip it — turns a rename into a surface that quietly
7161
7161
  * empties, which looks exactly like an addon with nothing to configure.
7162
7162
  */
7163
+ /**
7164
+ * The form schema of ONE integration instance, or `null` to use {@link globalSettingsSchema}.
7165
+ *
7166
+ * Override it only when an `instanceMode: multiple` addon's instances differ: an NVR integration
7167
+ * needs its connection fields, the default integration the addon's own sections. It is the
7168
+ * SHAPE of the form only — the values live in `integrations.getSettings`, and the write path is
7169
+ * unchanged (`integrations.setSettings` for an account integration).
7170
+ */
7171
+ async integrationSettingsSchema(_instance) {
7172
+ return null;
7173
+ }
7174
+ /**
7175
+ * What the create wizard and the integration edit page render for one instance: the addon's
7176
+ * per-instance schema when it declares one, else its global schema (what they always showed).
7177
+ */
7178
+ async getIntegrationFormSchema(instance, nodeId) {
7179
+ const scoped = await this.integrationSettingsSchema(instance);
7180
+ if (scoped === null) return this.getGlobalSettings(void 0, void 0, nodeId);
7181
+ return hydrateSchema(scoped, {}, { inlineSecretsAsViews: true });
7182
+ }
7163
7183
  async getIntegrationSettings(nodeId) {
7164
7184
  const declared = this.integrationSettingSections();
7165
7185
  if (declared.length === 0) return null;
@@ -9846,7 +9866,8 @@ Object.freeze({
9846
9866
  "unlocked",
9847
9867
  "locking",
9848
9868
  "unlocking",
9849
- "jammed"
9869
+ "jammed",
9870
+ "door-open"
9850
9871
  ]
9851
9872
  }],
9852
9873
  "media-player": [
@@ -12334,6 +12355,25 @@ var EventOwnerTypeSchema = _enum(EVENT_OWNER_TYPES);
12334
12355
  /** The same list as a Zod enum, for the cap input that carries it. */
12335
12356
  var MediaPresenceOwnerKindSchema = _enum([...EVENT_OWNER_TYPES, "track"]);
12336
12357
  new Set(EVENT_OWNER_TYPES);
12358
+ /**
12359
+ * Which integration instance a settings form is for. An addon that serves several instances
12360
+ * (`instanceMode: multiple`) can show a different form per instance — an NVR integration
12361
+ * needs its connection, the default integration needs the addon's own sections.
12362
+ *
12363
+ * - `integrationId` is `null` in the create wizard: nothing exists yet, the operator is
12364
+ * setting up a NEW instance.
12365
+ * - `mode` is the wizard mode of the integration type (`getAvailableTypes`).
12366
+ * - `candidateStableId` is the discovery candidate a wizard was seeded from, if any.
12367
+ */
12368
+ var IntegrationInstanceRefSchema = object({
12369
+ integrationId: string().nullable(),
12370
+ mode: _enum([
12371
+ "standalone",
12372
+ "account",
12373
+ "broker"
12374
+ ]),
12375
+ candidateStableId: string().optional()
12376
+ });
12337
12377
  var EncodeProfileSchema = object({
12338
12378
  video: object({
12339
12379
  codec: _enum([
@@ -16273,6 +16313,11 @@ var ACTUATOR_CAP_VOCABULARY = {
16273
16313
  value: "jammed",
16274
16314
  label: t("Jammed", "Inceppata"),
16275
16315
  phrase: t("When {device} jams", "Quando {device} si inceppa")
16316
+ },
16317
+ {
16318
+ value: "door-open",
16319
+ label: t("Door open", "Porta aperta"),
16320
+ phrase: t("When the door of {device} opens", "Quando la porta di {device} si apre")
16276
16321
  }
16277
16322
  ],
16278
16323
  icon: "lock"
@@ -42209,6 +42254,10 @@ method(object({
42209
42254
  }), method(object({
42210
42255
  addonId: string(),
42211
42256
  nodeId: string().optional()
42257
+ }), SettingsSchemaWithValuesSchema.nullable()), method(object({
42258
+ addonId: string(),
42259
+ nodeId: string().optional(),
42260
+ instance: IntegrationInstanceRefSchema
42212
42261
  }), SettingsSchemaWithValuesSchema.nullable()), method(object({
42213
42262
  addonId: string(),
42214
42263
  nodeId: string().optional()
@@ -44976,6 +45025,7 @@ method(object({
44976
45025
  kind: "mutation",
44977
45026
  auth: "admin"
44978
45027
  }), method(object({ blockIds: array(string()) }), object({ states: array(CompositionBlockStateSchema) }), { auth: "admin" });
45028
+ 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.Dryer, DeviceType.Gateway, DeviceType.Camera, 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.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.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.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.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;
44979
45029
  var NUMBER = {
44980
45030
  kind: "fixed",
44981
45031
  result: ["number"]
@@ -68201,6 +68251,8 @@ var IntegrationWithStateSchema = object({
68201
68251
  name: string(),
68202
68252
  enabled: boolean(),
68203
68253
  info: record(string(), unknown()).readonly(),
68254
+ /** The discovery candidate this integration was set up from (D984). */
68255
+ originStableId: string().optional(),
68204
68256
  createdAt: number(),
68205
68257
  updatedAt: number(),
68206
68258
  processState: string()
@@ -68211,6 +68263,8 @@ var IntegrationLiteSchema = object({
68211
68263
  name: string(),
68212
68264
  enabled: boolean(),
68213
68265
  info: record(string(), unknown()).readonly(),
68266
+ /** The discovery candidate this integration was set up from (D984). */
68267
+ originStableId: string().optional(),
68214
68268
  createdAt: number(),
68215
68269
  updatedAt: number()
68216
68270
  });
@@ -68308,6 +68362,8 @@ var CreateIntegrationInputSchema = object({
68308
68362
  name: string(),
68309
68363
  enabled: boolean().optional(),
68310
68364
  info: record(string(), unknown()).optional(),
68365
+ /** `stableId` of the discovery candidate the form was seeded from (D984). */
68366
+ originStableId: string().optional(),
68311
68367
  settings: record(string(), unknown()).optional(),
68312
68368
  /** Keys of `settings` the form's schema declares secret (by type) — kept in
68313
68369
  * the keychain, not the table (D787). */
@@ -69076,11 +69132,44 @@ var LockControlStatusSchema = object({
69076
69132
  "unlocked",
69077
69133
  "locking",
69078
69134
  "unlocking",
69079
- "jammed"
69135
+ "jammed",
69136
+ "door-open"
69080
69137
  ]),
69081
69138
  /** Ms epoch when the slice was last updated. */
69082
69139
  lastChangedAt: number()
69083
69140
  });
69141
+ /**
69142
+ * "Door contact" Customize extension (D984): the ONE extension that replaces a
69143
+ * native field. `state` is listed in `overridable` for this target, so the
69144
+ * validator and the guard accept it and nothing else.
69145
+ */
69146
+ var lockControlCustomize = {
69147
+ version: 1,
69148
+ overridable: [{
69149
+ path: "state",
69150
+ by: "door-contact"
69151
+ }],
69152
+ targets: [{
69153
+ id: "door-contact",
69154
+ cardinality: "scalar",
69155
+ vocabulary: {
69156
+ cap: "lock-control",
69157
+ stateField: "state"
69158
+ },
69159
+ deviceTypes: [DeviceType.Lock],
69160
+ apply: "replace",
69161
+ path: "state",
69162
+ override: {
69163
+ whenSourceTrue: "door-open",
69164
+ unlessNative: ["jammed"]
69165
+ },
69166
+ sources: [{
69167
+ kind: "binary",
69168
+ transforms: [{ kind: "identity" }]
69169
+ }],
69170
+ sourceReport: { status: "assignment-status" }
69171
+ }]
69172
+ };
69084
69173
  var lockControlCapability = {
69085
69174
  name: "lock-control",
69086
69175
  scope: "device",
@@ -69126,6 +69215,7 @@ var lockControlCapability = {
69126
69215
  * transitions.
69127
69216
  */
69128
69217
  runtimeState: LockControlStatusSchema,
69218
+ customize: lockControlCustomize,
69129
69219
  /**
69130
69220
  * Runtime-state durability: **restored** — a lock left locked must still read locked.
69131
69221
  *
@@ -77530,7 +77620,6 @@ discriminatedUnion("kind", [object({
77530
77620
  })]);
77531
77621
  DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
77532
77622
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
77533
- 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.Dryer, DeviceType.Gateway, DeviceType.Camera, 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.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.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.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.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;
77534
77623
  String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
77535
77624
  DeviceRole.BinarySensor, DeviceRole.MotionSensor;
77536
77625
  new Set(CAP_NAMES);
@@ -79552,6 +79641,13 @@ Object.freeze({
79552
79641
  access: "view",
79553
79642
  role: "admin"
79554
79643
  },
79644
+ "addonSettings.getIntegrationFormSchema": {
79645
+ capName: "addon-settings",
79646
+ capScope: "system",
79647
+ addonId: null,
79648
+ access: "view",
79649
+ role: "admin"
79650
+ },
79555
79651
  "addonSettings.getIntegrationSettings": {
79556
79652
  capName: "addon-settings",
79557
79653
  capScope: "system",
@@ -93086,6 +93182,7 @@ new Set([
93086
93182
  "locking",
93087
93183
  "unlocking",
93088
93184
  "jammed",
93185
+ "door-open",
93089
93186
  "on",
93090
93187
  "off",
93091
93188
  "home",
@@ -94101,8 +94198,8 @@ function resolveNativeId(integrationId, covers, childNativeId) {
94101
94198
  /**
94102
94199
  * The adoption candidates of one integration, pure and in a fixed order: the hub
94103
94200
  * box ({@link DeviceType.Gateway}), then one {@link DeviceType.Cover} per roller
94104
- * shutter. Each cover names the gateway through `parentStableId`, so the
94105
- * adoption modal nests it under the hub.
94201
+ * shutter. The gateway is a sibling of the covers, never their parent: no
94202
+ * cover names a `parentStableId`.
94106
94203
  */
94107
94204
  function buildRademacherCandidates(input) {
94108
94205
  const gatewayId = gatewayNativeId(input.integrationId);
@@ -94134,8 +94231,7 @@ function buildRademacherCandidates(input) {
94134
94231
  },
94135
94232
  alreadyAdopted: adoptedId !== null,
94136
94233
  adoptedDeviceId: adoptedId,
94137
- capabilities: [coverCapability.name],
94138
- parentStableId: gatewayId
94234
+ capabilities: [coverCapability.name]
94139
94235
  });
94140
94236
  }
94141
94237
  return out;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-rademacher",
3
- "version": "0.2.153",
3
+ "version": "0.2.154",
4
4
  "description": "Rademacher HomePilot device-provider addon for CamStack — wraps the @apocaliss92/noderademacher local-hub client (roller shutters over the cover cap)",
5
5
  "keywords": [
6
6
  "camstack",