@camstack/addon-provider-mqtt-ha 0.1.4 → 0.1.5

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/dist/addon.js CHANGED
@@ -5439,7 +5439,7 @@ var ZodIssueCode = {
5439
5439
  var ZodFirstPartyTypeKind;
5440
5440
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5441
5441
  //#endregion
5442
- //#region ../types/dist/sleep-bZIhUvjd.mjs
5442
+ //#region ../types/dist/sleep-BOjuyoPC.mjs
5443
5443
  /**
5444
5444
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5445
5445
  * window to float samples (D455).
@@ -8458,7 +8458,7 @@ object({
8458
8458
  params: record(string(), union([string(), number()])).optional()
8459
8459
  });
8460
8460
  //#endregion
8461
- //#region ../types/dist/err-msg--2RrYiLO.mjs
8461
+ //#region ../types/dist/err-msg-BXKzRBwg.mjs
8462
8462
  var DeviceType = /* @__PURE__ */ function(DeviceType) {
8463
8463
  DeviceType["Camera"] = "camera";
8464
8464
  DeviceType["Hub"] = "hub";
@@ -8550,6 +8550,10 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
8550
8550
  * native PetKit (`nodepetkit` `FeederDevice`), reusable by other feeder
8551
8551
  * integrations sharing the same food/desiccant/hopper surface. */
8552
8552
  DeviceType["PetFeeder"] = "pet-feeder";
8553
+ /** Built-in dishwasher — program lifecycle, door / remote-start gates,
8554
+ * salt and rinse-aid levels. Installed with the `dishwasher` cap.
8555
+ * Sources: native Bosch Home Connect, reusable by similar integrations. */
8556
+ DeviceType["Dishwasher"] = "dishwasher";
8553
8557
  return DeviceType;
8554
8558
  }({});
8555
8559
  var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
@@ -8807,7 +8811,7 @@ function errMsg(err) {
8807
8811
  return String(err);
8808
8812
  }
8809
8813
  //#endregion
8810
- //#region ../types/dist/composition-DOwQB_Ua.mjs
8814
+ //#region ../types/dist/composition-CB6PMT9p.mjs
8811
8815
  /**
8812
8816
  * The ffmpeg build every CamStack node downloads, per platform and arch.
8813
8817
  *
@@ -13193,8 +13197,13 @@ var AlertSeveritySchema = _enum([
13193
13197
  "info",
13194
13198
  "success",
13195
13199
  "warning",
13196
- "error"
13200
+ "error",
13201
+ "critical"
13197
13202
  ]);
13203
+ var AlertActionSchema = object({
13204
+ label: string(),
13205
+ href: string().optional()
13206
+ });
13198
13207
  var AlertStatusSchema = _enum([
13199
13208
  "active",
13200
13209
  "in-progress",
@@ -13212,6 +13221,7 @@ var AlertSchema = object({
13212
13221
  severity: AlertSeveritySchema,
13213
13222
  title: string(),
13214
13223
  message: string(),
13224
+ action: AlertActionSchema.optional(),
13215
13225
  status: AlertStatusSchema,
13216
13226
  progress: number().optional(),
13217
13227
  read: boolean(),
@@ -53770,7 +53780,8 @@ var batteryCapability = {
53770
53780
  DeviceType.Button,
53771
53781
  DeviceType.Switch,
53772
53782
  DeviceType.PetFeeder,
53773
- DeviceType.Container
53783
+ DeviceType.Container,
53784
+ DeviceType.Thermostat
53774
53785
  ],
53775
53786
  methods: {
53776
53787
  /**
@@ -55243,6 +55254,125 @@ onStatusChanged: { data: object({
55243
55254
  * whether persisting is worth a SQLite commit. */
55244
55255
  volatileStateFields: ["lastChangedAt"]
55245
55256
  };
55257
+ /**
55258
+ * Smart-dishwasher cap — program lifecycle, door / remote-start gates,
55259
+ * consumable levels (salt, rinse aid) and common program options.
55260
+ *
55261
+ * Sources: native Bosch Home Connect (`dishwasher` device type). Reusable
55262
+ * by any integration that exposes the same program / option surface.
55263
+ *
55264
+ * `kind: 'poll'` — cloud REST APIs typically have no push channel; the
55265
+ * provider refreshes the slice on an interval and eagerly after commands.
55266
+ */
55267
+ var DishwasherStateSchema = _enum([
55268
+ "idle",
55269
+ "running",
55270
+ "paused",
55271
+ "finished",
55272
+ "error",
55273
+ "unavailable"
55274
+ ]);
55275
+ var DishwasherConsumableLevelSchema = _enum([
55276
+ "ok",
55277
+ "low",
55278
+ "empty"
55279
+ ]);
55280
+ var DishwasherStatusSchema = object({
55281
+ state: DishwasherStateSchema,
55282
+ /** Active program id/name, or null when none selected / unknown. */
55283
+ program: string().nullable(),
55284
+ /** Program tokens the hardware accepts — drives the UI selector. */
55285
+ availablePrograms: array(string()),
55286
+ /** Minutes remaining on the active cycle, or null when not running. */
55287
+ remainingMinutes: number().int().nonnegative().nullable(),
55288
+ /** Cycle completion 0..100, or null when not applicable. */
55289
+ progressPercent: number().min(0).max(100).nullable(),
55290
+ /** True when the door is reported open. */
55291
+ doorOpen: boolean(),
55292
+ /** True when remote start is allowed (door closed, power on, etc.). */
55293
+ remoteStartAllowed: boolean(),
55294
+ /** Main power / switched-on state. */
55295
+ powerOn: boolean(),
55296
+ saltLevel: DishwasherConsumableLevelSchema.nullable(),
55297
+ rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
55298
+ halfLoad: boolean(),
55299
+ hygienePlus: boolean(),
55300
+ errorCode: number().nullable(),
55301
+ errorLabel: string().nullable(),
55302
+ lastFetchedAt: number()
55303
+ });
55304
+ var dishwasherCapability = {
55305
+ name: "dishwasher",
55306
+ scope: "device",
55307
+ deviceNative: true,
55308
+ mode: "singleton",
55309
+ deviceTypes: [DeviceType.Dishwasher],
55310
+ methods: {
55311
+ start: method(object({ deviceId: number().int().nonnegative() }), _void(), {
55312
+ kind: "mutation",
55313
+ auth: "protected"
55314
+ }),
55315
+ pause: method(object({ deviceId: number().int().nonnegative() }), _void(), {
55316
+ kind: "mutation",
55317
+ auth: "protected"
55318
+ }),
55319
+ stop: method(object({ deviceId: number().int().nonnegative() }), _void(), {
55320
+ kind: "mutation",
55321
+ auth: "protected"
55322
+ }),
55323
+ setProgram: method(object({
55324
+ deviceId: number().int().nonnegative(),
55325
+ program: string().min(1)
55326
+ }), _void(), {
55327
+ kind: "mutation",
55328
+ auth: "protected"
55329
+ }),
55330
+ setPower: method(object({
55331
+ deviceId: number().int().nonnegative(),
55332
+ on: boolean()
55333
+ }), _void(), {
55334
+ kind: "mutation",
55335
+ auth: "protected"
55336
+ }),
55337
+ setHalfLoad: method(object({
55338
+ deviceId: number().int().nonnegative(),
55339
+ on: boolean()
55340
+ }), _void(), {
55341
+ kind: "mutation",
55342
+ auth: "protected"
55343
+ }),
55344
+ setHygienePlus: method(object({
55345
+ deviceId: number().int().nonnegative(),
55346
+ on: boolean()
55347
+ }), _void(), {
55348
+ kind: "mutation",
55349
+ auth: "protected"
55350
+ }),
55351
+ setOption: method(object({
55352
+ deviceId: number().int().nonnegative(),
55353
+ key: string().min(1),
55354
+ value: union([
55355
+ boolean(),
55356
+ string(),
55357
+ number()
55358
+ ])
55359
+ }), _void(), {
55360
+ kind: "mutation",
55361
+ auth: "protected"
55362
+ })
55363
+ },
55364
+ status: {
55365
+ schema: DishwasherStatusSchema,
55366
+ kind: "poll"
55367
+ },
55368
+ runtimeState: DishwasherStatusSchema,
55369
+ durability: "session",
55370
+ history: { fields: { progressPercent: {
55371
+ kind: "gauge",
55372
+ unit: "%",
55373
+ deadband: 2
55374
+ } } }
55375
+ };
55246
55376
  var DoorbellStatusSchema = object({
55247
55377
  /** Ms epoch of the last press. null = never observed since this provider started. */
55248
55378
  lastPressedAt: number().nullable(),
@@ -56045,6 +56175,32 @@ var gasCapability = {
56045
56175
  * whether persisting is worth a SQLite commit. */
56046
56176
  volatileStateFields: ["lastChangedAt"]
56047
56177
  };
56178
+ var HeatingValveStatusSchema = object({
56179
+ /** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
56180
+ position: number().min(0).max(100).nullable(),
56181
+ /** Ms epoch when the slice was last updated (push or poll). */
56182
+ lastFetchedAt: number()
56183
+ });
56184
+ var heatingValveCapability = {
56185
+ name: "heating-valve",
56186
+ scope: "device",
56187
+ deviceNative: true,
56188
+ mode: "singleton",
56189
+ deviceTypes: [DeviceType.Thermostat],
56190
+ methods: {},
56191
+ status: {
56192
+ schema: HeatingValveStatusSchema,
56193
+ kind: "push"
56194
+ },
56195
+ runtimeState: HeatingValveStatusSchema,
56196
+ durability: "session",
56197
+ history: { fields: { position: {
56198
+ kind: "gauge",
56199
+ unit: "%",
56200
+ deadband: 1
56201
+ } } },
56202
+ volatileStateFields: ["lastFetchedAt"]
56203
+ };
56048
56204
  /**
56049
56205
  * Humidifier / dehumidifier cap. Models HA `humidifier.*` entities —
56050
56206
  * an on/off actuator with an optional target-humidity setpoint and an
@@ -65465,6 +65621,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
65465
65621
  dayNight: dayNightCapability,
65466
65622
  deviceDiscovery: deviceDiscoveryCapability,
65467
65623
  deviceStatus: deviceStatusCapability,
65624
+ dishwasher: dishwasherCapability,
65468
65625
  doorbell: doorbellCapability,
65469
65626
  enumSensor: enumSensorCapability,
65470
65627
  eventEmitter: eventEmitterCapability,
@@ -65472,6 +65629,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
65472
65629
  featureProbe: featureProbeCapability,
65473
65630
  flood: floodCapability,
65474
65631
  gas: gasCapability,
65632
+ heatingValve: heatingValveCapability,
65475
65633
  humidifier: humidifierCapability,
65476
65634
  humiditySensor: humiditySensorCapability,
65477
65635
  image: imageCapability,
@@ -66197,6 +66355,12 @@ var BaseDeviceProvider = class extends BaseAddon {
66197
66355
  provider: this
66198
66356
  }];
66199
66357
  }
66358
+ /** Flatten `super.onInitialize()` whether it returned an array or an envelope. */
66359
+ providerRegistrationsFromSuper(result) {
66360
+ if (Array.isArray(result)) return result;
66361
+ if (result !== void 0 && result.providers !== void 0) return [...result.providers];
66362
+ return [];
66363
+ }
66200
66364
  async onShutdown() {
66201
66365
  this._restoreShuttingDown = true;
66202
66366
  this.cancelRestoreRetries();
@@ -66723,7 +66887,7 @@ var BaseDeviceProvider = class extends BaseAddon {
66723
66887
  return toDeviceSummary(device, this.addonId);
66724
66888
  }
66725
66889
  };
66726
- DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder;
66890
+ DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher;
66727
66891
  new Set(Object.values(DeviceType));
66728
66892
  Object.freeze({
66729
66893
  "accessories.getStatus": {
@@ -69144,6 +69308,60 @@ Object.freeze({
69144
69308
  addonId: null,
69145
69309
  access: "view"
69146
69310
  },
69311
+ "dishwasher.getStatus": {
69312
+ capName: "dishwasher",
69313
+ capScope: "device",
69314
+ addonId: null,
69315
+ access: "view"
69316
+ },
69317
+ "dishwasher.pause": {
69318
+ capName: "dishwasher",
69319
+ capScope: "device",
69320
+ addonId: null,
69321
+ access: "create"
69322
+ },
69323
+ "dishwasher.setHalfLoad": {
69324
+ capName: "dishwasher",
69325
+ capScope: "device",
69326
+ addonId: null,
69327
+ access: "create"
69328
+ },
69329
+ "dishwasher.setHygienePlus": {
69330
+ capName: "dishwasher",
69331
+ capScope: "device",
69332
+ addonId: null,
69333
+ access: "create"
69334
+ },
69335
+ "dishwasher.setOption": {
69336
+ capName: "dishwasher",
69337
+ capScope: "device",
69338
+ addonId: null,
69339
+ access: "create"
69340
+ },
69341
+ "dishwasher.setPower": {
69342
+ capName: "dishwasher",
69343
+ capScope: "device",
69344
+ addonId: null,
69345
+ access: "create"
69346
+ },
69347
+ "dishwasher.setProgram": {
69348
+ capName: "dishwasher",
69349
+ capScope: "device",
69350
+ addonId: null,
69351
+ access: "create"
69352
+ },
69353
+ "dishwasher.start": {
69354
+ capName: "dishwasher",
69355
+ capScope: "device",
69356
+ addonId: null,
69357
+ access: "create"
69358
+ },
69359
+ "dishwasher.stop": {
69360
+ capName: "dishwasher",
69361
+ capScope: "device",
69362
+ addonId: null,
69363
+ access: "create"
69364
+ },
69147
69365
  "doorbell.getStatus": {
69148
69366
  capName: "doorbell",
69149
69367
  capScope: "device",
@@ -69354,6 +69572,12 @@ Object.freeze({
69354
69572
  addonId: null,
69355
69573
  access: "view"
69356
69574
  },
69575
+ "heatingValve.getStatus": {
69576
+ capName: "heating-valve",
69577
+ capScope: "device",
69578
+ addonId: null,
69579
+ access: "view"
69580
+ },
69357
69581
  "humidifier.getStatus": {
69358
69582
  capName: "humidifier",
69359
69583
  capScope: "device",
@@ -74941,7 +75165,7 @@ Object.freeze({
74941
75165
  access: "create"
74942
75166
  }
74943
75167
  });
74944
- 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;
75168
+ 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.Dishwasher;
74945
75169
  DeviceFeature.BatteryOperated;
74946
75170
  Object.freeze({
74947
75171
  "accessories.getStatus": [{
@@ -75765,6 +75989,51 @@ Object.freeze({
75765
75989
  form: "single",
75766
75990
  optional: false
75767
75991
  }],
75992
+ "dishwasher.getStatus": [{
75993
+ name: "deviceId",
75994
+ form: "single",
75995
+ optional: false
75996
+ }],
75997
+ "dishwasher.pause": [{
75998
+ name: "deviceId",
75999
+ form: "single",
76000
+ optional: false
76001
+ }],
76002
+ "dishwasher.setHalfLoad": [{
76003
+ name: "deviceId",
76004
+ form: "single",
76005
+ optional: false
76006
+ }],
76007
+ "dishwasher.setHygienePlus": [{
76008
+ name: "deviceId",
76009
+ form: "single",
76010
+ optional: false
76011
+ }],
76012
+ "dishwasher.setOption": [{
76013
+ name: "deviceId",
76014
+ form: "single",
76015
+ optional: false
76016
+ }],
76017
+ "dishwasher.setPower": [{
76018
+ name: "deviceId",
76019
+ form: "single",
76020
+ optional: false
76021
+ }],
76022
+ "dishwasher.setProgram": [{
76023
+ name: "deviceId",
76024
+ form: "single",
76025
+ optional: false
76026
+ }],
76027
+ "dishwasher.start": [{
76028
+ name: "deviceId",
76029
+ form: "single",
76030
+ optional: false
76031
+ }],
76032
+ "dishwasher.stop": [{
76033
+ name: "deviceId",
76034
+ form: "single",
76035
+ optional: false
76036
+ }],
75768
76037
  "doorbell.getStatus": [{
75769
76038
  name: "deviceId",
75770
76039
  form: "single",
@@ -75834,6 +76103,11 @@ Object.freeze({
75834
76103
  form: "single",
75835
76104
  optional: false
75836
76105
  }],
76106
+ "heatingValve.getStatus": [{
76107
+ name: "deviceId",
76108
+ form: "single",
76109
+ optional: false
76110
+ }],
75837
76111
  "humidifier.getStatus": [{
75838
76112
  name: "deviceId",
75839
76113
  form: "single",
@@ -103320,7 +103594,7 @@ var MqttHaProviderAddon = class extends BaseDeviceProvider {
103320
103594
  super({});
103321
103595
  }
103322
103596
  async onInitialize() {
103323
- const regs = await super.onInitialize();
103597
+ const regs = this.providerRegistrationsFromSuper(await super.onInitialize());
103324
103598
  wireMqttHaDiscoveryStore(this.discoveryStore);
103325
103599
  this.sessionManager = new MqttHaBrokerSessionManager({
103326
103600
  addonId: this.ctx.id,
package/dist/addon.mjs CHANGED
@@ -5440,7 +5440,7 @@ var ZodIssueCode = {
5440
5440
  var ZodFirstPartyTypeKind;
5441
5441
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5442
5442
  //#endregion
5443
- //#region ../types/dist/sleep-bZIhUvjd.mjs
5443
+ //#region ../types/dist/sleep-BOjuyoPC.mjs
5444
5444
  /**
5445
5445
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5446
5446
  * window to float samples (D455).
@@ -8459,7 +8459,7 @@ object({
8459
8459
  params: record(string(), union([string(), number()])).optional()
8460
8460
  });
8461
8461
  //#endregion
8462
- //#region ../types/dist/err-msg--2RrYiLO.mjs
8462
+ //#region ../types/dist/err-msg-BXKzRBwg.mjs
8463
8463
  var DeviceType = /* @__PURE__ */ function(DeviceType) {
8464
8464
  DeviceType["Camera"] = "camera";
8465
8465
  DeviceType["Hub"] = "hub";
@@ -8551,6 +8551,10 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
8551
8551
  * native PetKit (`nodepetkit` `FeederDevice`), reusable by other feeder
8552
8552
  * integrations sharing the same food/desiccant/hopper surface. */
8553
8553
  DeviceType["PetFeeder"] = "pet-feeder";
8554
+ /** Built-in dishwasher — program lifecycle, door / remote-start gates,
8555
+ * salt and rinse-aid levels. Installed with the `dishwasher` cap.
8556
+ * Sources: native Bosch Home Connect, reusable by similar integrations. */
8557
+ DeviceType["Dishwasher"] = "dishwasher";
8554
8558
  return DeviceType;
8555
8559
  }({});
8556
8560
  var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
@@ -8808,7 +8812,7 @@ function errMsg(err) {
8808
8812
  return String(err);
8809
8813
  }
8810
8814
  //#endregion
8811
- //#region ../types/dist/composition-DOwQB_Ua.mjs
8815
+ //#region ../types/dist/composition-CB6PMT9p.mjs
8812
8816
  /**
8813
8817
  * The ffmpeg build every CamStack node downloads, per platform and arch.
8814
8818
  *
@@ -13194,8 +13198,13 @@ var AlertSeveritySchema = _enum([
13194
13198
  "info",
13195
13199
  "success",
13196
13200
  "warning",
13197
- "error"
13201
+ "error",
13202
+ "critical"
13198
13203
  ]);
13204
+ var AlertActionSchema = object({
13205
+ label: string(),
13206
+ href: string().optional()
13207
+ });
13199
13208
  var AlertStatusSchema = _enum([
13200
13209
  "active",
13201
13210
  "in-progress",
@@ -13213,6 +13222,7 @@ var AlertSchema = object({
13213
13222
  severity: AlertSeveritySchema,
13214
13223
  title: string(),
13215
13224
  message: string(),
13225
+ action: AlertActionSchema.optional(),
13216
13226
  status: AlertStatusSchema,
13217
13227
  progress: number().optional(),
13218
13228
  read: boolean(),
@@ -53771,7 +53781,8 @@ var batteryCapability = {
53771
53781
  DeviceType.Button,
53772
53782
  DeviceType.Switch,
53773
53783
  DeviceType.PetFeeder,
53774
- DeviceType.Container
53784
+ DeviceType.Container,
53785
+ DeviceType.Thermostat
53775
53786
  ],
53776
53787
  methods: {
53777
53788
  /**
@@ -55244,6 +55255,125 @@ onStatusChanged: { data: object({
55244
55255
  * whether persisting is worth a SQLite commit. */
55245
55256
  volatileStateFields: ["lastChangedAt"]
55246
55257
  };
55258
+ /**
55259
+ * Smart-dishwasher cap — program lifecycle, door / remote-start gates,
55260
+ * consumable levels (salt, rinse aid) and common program options.
55261
+ *
55262
+ * Sources: native Bosch Home Connect (`dishwasher` device type). Reusable
55263
+ * by any integration that exposes the same program / option surface.
55264
+ *
55265
+ * `kind: 'poll'` — cloud REST APIs typically have no push channel; the
55266
+ * provider refreshes the slice on an interval and eagerly after commands.
55267
+ */
55268
+ var DishwasherStateSchema = _enum([
55269
+ "idle",
55270
+ "running",
55271
+ "paused",
55272
+ "finished",
55273
+ "error",
55274
+ "unavailable"
55275
+ ]);
55276
+ var DishwasherConsumableLevelSchema = _enum([
55277
+ "ok",
55278
+ "low",
55279
+ "empty"
55280
+ ]);
55281
+ var DishwasherStatusSchema = object({
55282
+ state: DishwasherStateSchema,
55283
+ /** Active program id/name, or null when none selected / unknown. */
55284
+ program: string().nullable(),
55285
+ /** Program tokens the hardware accepts — drives the UI selector. */
55286
+ availablePrograms: array(string()),
55287
+ /** Minutes remaining on the active cycle, or null when not running. */
55288
+ remainingMinutes: number().int().nonnegative().nullable(),
55289
+ /** Cycle completion 0..100, or null when not applicable. */
55290
+ progressPercent: number().min(0).max(100).nullable(),
55291
+ /** True when the door is reported open. */
55292
+ doorOpen: boolean(),
55293
+ /** True when remote start is allowed (door closed, power on, etc.). */
55294
+ remoteStartAllowed: boolean(),
55295
+ /** Main power / switched-on state. */
55296
+ powerOn: boolean(),
55297
+ saltLevel: DishwasherConsumableLevelSchema.nullable(),
55298
+ rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
55299
+ halfLoad: boolean(),
55300
+ hygienePlus: boolean(),
55301
+ errorCode: number().nullable(),
55302
+ errorLabel: string().nullable(),
55303
+ lastFetchedAt: number()
55304
+ });
55305
+ var dishwasherCapability = {
55306
+ name: "dishwasher",
55307
+ scope: "device",
55308
+ deviceNative: true,
55309
+ mode: "singleton",
55310
+ deviceTypes: [DeviceType.Dishwasher],
55311
+ methods: {
55312
+ start: method(object({ deviceId: number().int().nonnegative() }), _void(), {
55313
+ kind: "mutation",
55314
+ auth: "protected"
55315
+ }),
55316
+ pause: method(object({ deviceId: number().int().nonnegative() }), _void(), {
55317
+ kind: "mutation",
55318
+ auth: "protected"
55319
+ }),
55320
+ stop: method(object({ deviceId: number().int().nonnegative() }), _void(), {
55321
+ kind: "mutation",
55322
+ auth: "protected"
55323
+ }),
55324
+ setProgram: method(object({
55325
+ deviceId: number().int().nonnegative(),
55326
+ program: string().min(1)
55327
+ }), _void(), {
55328
+ kind: "mutation",
55329
+ auth: "protected"
55330
+ }),
55331
+ setPower: method(object({
55332
+ deviceId: number().int().nonnegative(),
55333
+ on: boolean()
55334
+ }), _void(), {
55335
+ kind: "mutation",
55336
+ auth: "protected"
55337
+ }),
55338
+ setHalfLoad: method(object({
55339
+ deviceId: number().int().nonnegative(),
55340
+ on: boolean()
55341
+ }), _void(), {
55342
+ kind: "mutation",
55343
+ auth: "protected"
55344
+ }),
55345
+ setHygienePlus: method(object({
55346
+ deviceId: number().int().nonnegative(),
55347
+ on: boolean()
55348
+ }), _void(), {
55349
+ kind: "mutation",
55350
+ auth: "protected"
55351
+ }),
55352
+ setOption: method(object({
55353
+ deviceId: number().int().nonnegative(),
55354
+ key: string().min(1),
55355
+ value: union([
55356
+ boolean(),
55357
+ string(),
55358
+ number()
55359
+ ])
55360
+ }), _void(), {
55361
+ kind: "mutation",
55362
+ auth: "protected"
55363
+ })
55364
+ },
55365
+ status: {
55366
+ schema: DishwasherStatusSchema,
55367
+ kind: "poll"
55368
+ },
55369
+ runtimeState: DishwasherStatusSchema,
55370
+ durability: "session",
55371
+ history: { fields: { progressPercent: {
55372
+ kind: "gauge",
55373
+ unit: "%",
55374
+ deadband: 2
55375
+ } } }
55376
+ };
55247
55377
  var DoorbellStatusSchema = object({
55248
55378
  /** Ms epoch of the last press. null = never observed since this provider started. */
55249
55379
  lastPressedAt: number().nullable(),
@@ -56046,6 +56176,32 @@ var gasCapability = {
56046
56176
  * whether persisting is worth a SQLite commit. */
56047
56177
  volatileStateFields: ["lastChangedAt"]
56048
56178
  };
56179
+ var HeatingValveStatusSchema = object({
56180
+ /** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
56181
+ position: number().min(0).max(100).nullable(),
56182
+ /** Ms epoch when the slice was last updated (push or poll). */
56183
+ lastFetchedAt: number()
56184
+ });
56185
+ var heatingValveCapability = {
56186
+ name: "heating-valve",
56187
+ scope: "device",
56188
+ deviceNative: true,
56189
+ mode: "singleton",
56190
+ deviceTypes: [DeviceType.Thermostat],
56191
+ methods: {},
56192
+ status: {
56193
+ schema: HeatingValveStatusSchema,
56194
+ kind: "push"
56195
+ },
56196
+ runtimeState: HeatingValveStatusSchema,
56197
+ durability: "session",
56198
+ history: { fields: { position: {
56199
+ kind: "gauge",
56200
+ unit: "%",
56201
+ deadband: 1
56202
+ } } },
56203
+ volatileStateFields: ["lastFetchedAt"]
56204
+ };
56049
56205
  /**
56050
56206
  * Humidifier / dehumidifier cap. Models HA `humidifier.*` entities —
56051
56207
  * an on/off actuator with an optional target-humidity setpoint and an
@@ -65466,6 +65622,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
65466
65622
  dayNight: dayNightCapability,
65467
65623
  deviceDiscovery: deviceDiscoveryCapability,
65468
65624
  deviceStatus: deviceStatusCapability,
65625
+ dishwasher: dishwasherCapability,
65469
65626
  doorbell: doorbellCapability,
65470
65627
  enumSensor: enumSensorCapability,
65471
65628
  eventEmitter: eventEmitterCapability,
@@ -65473,6 +65630,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
65473
65630
  featureProbe: featureProbeCapability,
65474
65631
  flood: floodCapability,
65475
65632
  gas: gasCapability,
65633
+ heatingValve: heatingValveCapability,
65476
65634
  humidifier: humidifierCapability,
65477
65635
  humiditySensor: humiditySensorCapability,
65478
65636
  image: imageCapability,
@@ -66198,6 +66356,12 @@ var BaseDeviceProvider = class extends BaseAddon {
66198
66356
  provider: this
66199
66357
  }];
66200
66358
  }
66359
+ /** Flatten `super.onInitialize()` whether it returned an array or an envelope. */
66360
+ providerRegistrationsFromSuper(result) {
66361
+ if (Array.isArray(result)) return result;
66362
+ if (result !== void 0 && result.providers !== void 0) return [...result.providers];
66363
+ return [];
66364
+ }
66201
66365
  async onShutdown() {
66202
66366
  this._restoreShuttingDown = true;
66203
66367
  this.cancelRestoreRetries();
@@ -66724,7 +66888,7 @@ var BaseDeviceProvider = class extends BaseAddon {
66724
66888
  return toDeviceSummary(device, this.addonId);
66725
66889
  }
66726
66890
  };
66727
- DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder;
66891
+ DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher;
66728
66892
  new Set(Object.values(DeviceType));
66729
66893
  Object.freeze({
66730
66894
  "accessories.getStatus": {
@@ -69145,6 +69309,60 @@ Object.freeze({
69145
69309
  addonId: null,
69146
69310
  access: "view"
69147
69311
  },
69312
+ "dishwasher.getStatus": {
69313
+ capName: "dishwasher",
69314
+ capScope: "device",
69315
+ addonId: null,
69316
+ access: "view"
69317
+ },
69318
+ "dishwasher.pause": {
69319
+ capName: "dishwasher",
69320
+ capScope: "device",
69321
+ addonId: null,
69322
+ access: "create"
69323
+ },
69324
+ "dishwasher.setHalfLoad": {
69325
+ capName: "dishwasher",
69326
+ capScope: "device",
69327
+ addonId: null,
69328
+ access: "create"
69329
+ },
69330
+ "dishwasher.setHygienePlus": {
69331
+ capName: "dishwasher",
69332
+ capScope: "device",
69333
+ addonId: null,
69334
+ access: "create"
69335
+ },
69336
+ "dishwasher.setOption": {
69337
+ capName: "dishwasher",
69338
+ capScope: "device",
69339
+ addonId: null,
69340
+ access: "create"
69341
+ },
69342
+ "dishwasher.setPower": {
69343
+ capName: "dishwasher",
69344
+ capScope: "device",
69345
+ addonId: null,
69346
+ access: "create"
69347
+ },
69348
+ "dishwasher.setProgram": {
69349
+ capName: "dishwasher",
69350
+ capScope: "device",
69351
+ addonId: null,
69352
+ access: "create"
69353
+ },
69354
+ "dishwasher.start": {
69355
+ capName: "dishwasher",
69356
+ capScope: "device",
69357
+ addonId: null,
69358
+ access: "create"
69359
+ },
69360
+ "dishwasher.stop": {
69361
+ capName: "dishwasher",
69362
+ capScope: "device",
69363
+ addonId: null,
69364
+ access: "create"
69365
+ },
69148
69366
  "doorbell.getStatus": {
69149
69367
  capName: "doorbell",
69150
69368
  capScope: "device",
@@ -69355,6 +69573,12 @@ Object.freeze({
69355
69573
  addonId: null,
69356
69574
  access: "view"
69357
69575
  },
69576
+ "heatingValve.getStatus": {
69577
+ capName: "heating-valve",
69578
+ capScope: "device",
69579
+ addonId: null,
69580
+ access: "view"
69581
+ },
69358
69582
  "humidifier.getStatus": {
69359
69583
  capName: "humidifier",
69360
69584
  capScope: "device",
@@ -74942,7 +75166,7 @@ Object.freeze({
74942
75166
  access: "create"
74943
75167
  }
74944
75168
  });
74945
- 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;
75169
+ 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.Dishwasher;
74946
75170
  DeviceFeature.BatteryOperated;
74947
75171
  Object.freeze({
74948
75172
  "accessories.getStatus": [{
@@ -75766,6 +75990,51 @@ Object.freeze({
75766
75990
  form: "single",
75767
75991
  optional: false
75768
75992
  }],
75993
+ "dishwasher.getStatus": [{
75994
+ name: "deviceId",
75995
+ form: "single",
75996
+ optional: false
75997
+ }],
75998
+ "dishwasher.pause": [{
75999
+ name: "deviceId",
76000
+ form: "single",
76001
+ optional: false
76002
+ }],
76003
+ "dishwasher.setHalfLoad": [{
76004
+ name: "deviceId",
76005
+ form: "single",
76006
+ optional: false
76007
+ }],
76008
+ "dishwasher.setHygienePlus": [{
76009
+ name: "deviceId",
76010
+ form: "single",
76011
+ optional: false
76012
+ }],
76013
+ "dishwasher.setOption": [{
76014
+ name: "deviceId",
76015
+ form: "single",
76016
+ optional: false
76017
+ }],
76018
+ "dishwasher.setPower": [{
76019
+ name: "deviceId",
76020
+ form: "single",
76021
+ optional: false
76022
+ }],
76023
+ "dishwasher.setProgram": [{
76024
+ name: "deviceId",
76025
+ form: "single",
76026
+ optional: false
76027
+ }],
76028
+ "dishwasher.start": [{
76029
+ name: "deviceId",
76030
+ form: "single",
76031
+ optional: false
76032
+ }],
76033
+ "dishwasher.stop": [{
76034
+ name: "deviceId",
76035
+ form: "single",
76036
+ optional: false
76037
+ }],
75769
76038
  "doorbell.getStatus": [{
75770
76039
  name: "deviceId",
75771
76040
  form: "single",
@@ -75835,6 +76104,11 @@ Object.freeze({
75835
76104
  form: "single",
75836
76105
  optional: false
75837
76106
  }],
76107
+ "heatingValve.getStatus": [{
76108
+ name: "deviceId",
76109
+ form: "single",
76110
+ optional: false
76111
+ }],
75838
76112
  "humidifier.getStatus": [{
75839
76113
  name: "deviceId",
75840
76114
  form: "single",
@@ -103321,7 +103595,7 @@ var MqttHaProviderAddon = class extends BaseDeviceProvider {
103321
103595
  super({});
103322
103596
  }
103323
103597
  async onInitialize() {
103324
- const regs = await super.onInitialize();
103598
+ const regs = this.providerRegistrationsFromSuper(await super.onInitialize());
103325
103599
  wireMqttHaDiscoveryStore(this.discoveryStore);
103326
103600
  this.sessionManager = new MqttHaBrokerSessionManager({
103327
103601
  addonId: this.ctx.id,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-mqtt-ha",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Home Assistant MQTT discovery import provider for CamStack — adopts entities published on homeassistant/+/+/config",
5
5
  "keywords": [
6
6
  "camstack",