@camstack/addon-provider-homeassistant 1.2.632 → 1.2.634

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,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.2.634] - 2026-10-28
11
+
12
+ ### Changed
13
+
14
+ - Device value fields are named after their quantity instead of their unit; run the quantity-field migration after updating
15
+
16
+ ## [1.2.633] - 2026-10-27
17
+
18
+ ### Changed
19
+
20
+ - Shown as "Home Assistant" (was "Home Assistant Provider").
21
+
22
+ ## [1.2.632] - 2026-10-27
23
+
10
24
  ### Added
11
25
 
12
- - Package README and changelog, included in the published files list.
26
+ - Home Assistant: Home Assistant device provider addon for CamStack.
27
+ - Provides the addons Home Assistant, Home Assistant Export.
package/README.md CHANGED
@@ -1,22 +1,42 @@
1
- # @camstack/addon-provider-homeassistant
1
+ # Home Assistant
2
2
 
3
- Home Assistant device provider addon for CamStack
3
+ Home Assistant device provider addon for CamStack. Device provider (import) + native entity export (push). Two addons, one bundle, separate processes.
4
4
 
5
- ## What it does
5
+ <!-- readme:generated:start (derived from the manifest; edit outside this block) -->
6
6
 
7
- - **Home Assistant Provider** (`provider-homeassistant`): Adopt Home Assistant devices into CamStack via WebSocket
8
- - Node placement: `hub-only`.
7
+ Package `@camstack/addon-provider-homeassistant` on npm.
8
+
9
+ ## What it provides
10
+
11
+ - **Home Assistant** (`provider-homeassistant`): Adopt Home Assistant devices into CamStack via WebSocket. Category: messaging.
9
12
  - Capabilities: `broker`, `device-adoption`, `vacuum-control`, `lawn-mower-control`, `running-state`, `valve`, `humidifier`, `water-heater`, `weather`, `image`, `update`, `notification-output`, `addon-routes`, `calendar-source`.
10
- - **Home Assistant Export** (`homeassistant-export`): Pushes CamStack entities to the CamStack Home Assistant custom component over HTTP. Chooses which devices reach which Home Assistant instance; Home Assistant never polls the hub for a value.
11
- - Node placement: `hub-only`.
13
+ - **Home Assistant Export** (`homeassistant-export`): Pushes CamStack entities to the CamStack Home Assistant custom component over HTTP. Chooses which devices reach which Home Assistant instance; Home Assistant never polls the hub for a value. Category: exports.
12
14
  - Capabilities: `device-export`, `addon-routes`, `oauth-integration`.
13
15
 
14
- ## Settings
16
+ ## Configuration
17
+
18
+ Edit these from System, Addons, this addon, Settings (a device's own settings are on its device page). A password field is stored in the keychain.
19
+
20
+ **Addon settings**
15
21
 
16
- Settings this addon exposes are edited from System → Addons → this addon → Settings when they apply to the whole cluster, and from the device page when they belong to one device. A password field is stored in the keychain.
22
+ - Calendars to import: Calendars
23
+ - Home Assistant broker: Brokers are managed separately
24
+ - Home Assistant connection: Auth mode, HA base URL, Long-lived access token, Supervisor token
25
+ - Home Assistant instances: No brokers
26
+ - Connection: Hub URL Home Assistant can reach
27
+ - Advanced: Reconcile interval (s)
17
28
 
18
29
  ## Requirements
19
30
 
20
- - Peer packages already on the node: `@camstack/types`.
21
- - A CamStack hub. An agent is used only when the placement above allows it.
31
+ - Placement: hub-only.
32
+ - A CamStack hub. An agent is used only where the placement above allows it.
33
+
34
+ ## Documentation
35
+
36
+ - [docs/addons/addon-provider-homeassistant.md](https://github.com/camstack/server/blob/main/docs/addons/addon-provider-homeassistant.md)
37
+ - [docs/architecture/device-model.md](https://github.com/camstack/server/blob/main/docs/architecture/device-model.md)
38
+ - [packages/addon-provider-homeassistant/AGENTS.md](https://github.com/camstack/server/blob/main/packages/addon-provider-homeassistant/AGENTS.md)
39
+
40
+ See [CHANGELOG.md](./CHANGELOG.md) for what changed in each version.
22
41
 
42
+ <!-- readme:generated:end -->
package/dist/addon.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_dist = require("./dist-D0ZiJUPy.js");
2
+ const require_dist = require("./dist-DSRitvmZ.js");
3
3
  let node_crypto = require("node:crypto");
4
4
  let node_zlib = require("node:zlib");
5
5
  //#region src/ha-admin-link.ts
@@ -129,10 +129,10 @@ var haSourceSchemaFields = {
129
129
  features: require_dist.array(require_dist.string()).optional(),
130
130
  /** Sibling meter sensors whose readings this entity carries as `power-meter` (D951). */
131
131
  meterEntities: require_dist.object({
132
- watts: require_dist.string().optional(),
133
- kwhTotal: require_dist.string().optional(),
134
- volts: require_dist.string().optional(),
135
- amps: require_dist.string().optional()
132
+ power: require_dist.string().optional(),
133
+ energy: require_dist.string().optional(),
134
+ voltage: require_dist.string().optional(),
135
+ current: require_dist.string().optional()
136
136
  }).optional()
137
137
  };
138
138
  /** Project a persisted config blob into a typed source, or null when the
@@ -332,26 +332,26 @@ function takeReading(logger, deviceId, value, rawUnit, quantity) {
332
332
  */
333
333
  /** The `power-meter` status field a reading lands in. */
334
334
  var METER_FIELDS = [
335
- "watts",
336
- "kwhTotal",
337
- "volts",
338
- "amps"
335
+ "power",
336
+ "energy",
337
+ "voltage",
338
+ "current"
339
339
  ];
340
340
  var METER_BY_DEVICE_CLASS = {
341
341
  power: {
342
- field: "watts",
342
+ field: "power",
343
343
  quantity: "power"
344
344
  },
345
345
  energy: {
346
- field: "kwhTotal",
346
+ field: "energy",
347
347
  quantity: "energy"
348
348
  },
349
349
  voltage: {
350
- field: "volts",
350
+ field: "voltage",
351
351
  quantity: "voltage"
352
352
  },
353
353
  current: {
354
- field: "amps",
354
+ field: "current",
355
355
  quantity: "current"
356
356
  }
357
357
  };
@@ -953,10 +953,10 @@ var SUPPORTED_CAP_NAMES$1 = [
953
953
  ];
954
954
  /** Map a supported cap to its canonical "value" field. */
955
955
  var VALUE_FIELD = {
956
- "temperature-sensor": "celsius",
957
- "humidity-sensor": "percent",
958
- "ambient-light-sensor": "lux",
959
- "pressure-sensor": "hpa",
956
+ "temperature-sensor": "temperature",
957
+ "humidity-sensor": "humidity",
958
+ "ambient-light-sensor": "illuminance",
959
+ "pressure-sensor": "pressure",
960
960
  "numeric-sensor": "value"
961
961
  };
962
962
  /** Typed sensors already name their quantity. The generic sensor learns it. */
@@ -1080,7 +1080,7 @@ var HaNumericSensorDevice = class extends HaBaseChildDevice {
1080
1080
  switch (name) {
1081
1081
  case "temperature-sensor": {
1082
1082
  const COLD_START = {
1083
- celsius: 0,
1083
+ temperature: 0,
1084
1084
  lastFetchedAt: 0
1085
1085
  };
1086
1086
  this.ctx.registerNativeCap(require_dist.temperatureSensorCapability, { getStatus: async () => this.readSlice(COLD_START) });
@@ -1088,7 +1088,7 @@ var HaNumericSensorDevice = class extends HaBaseChildDevice {
1088
1088
  }
1089
1089
  case "humidity-sensor": {
1090
1090
  const COLD_START = {
1091
- percent: 0,
1091
+ humidity: 0,
1092
1092
  lastFetchedAt: 0
1093
1093
  };
1094
1094
  this.ctx.registerNativeCap(require_dist.humiditySensorCapability, { getStatus: async () => this.readSlice(COLD_START) });
@@ -1096,7 +1096,7 @@ var HaNumericSensorDevice = class extends HaBaseChildDevice {
1096
1096
  }
1097
1097
  case "ambient-light-sensor": {
1098
1098
  const COLD_START = {
1099
- lux: 0,
1099
+ illuminance: 0,
1100
1100
  lastFetchedAt: 0
1101
1101
  };
1102
1102
  this.ctx.registerNativeCap(require_dist.ambientLightSensorCapability, { getStatus: async () => this.readSlice(COLD_START) });
@@ -1104,7 +1104,7 @@ var HaNumericSensorDevice = class extends HaBaseChildDevice {
1104
1104
  }
1105
1105
  case "pressure-sensor": {
1106
1106
  const COLD_START = {
1107
- hpa: 0,
1107
+ pressure: 0,
1108
1108
  lastFetchedAt: 0
1109
1109
  };
1110
1110
  this.ctx.registerNativeCap(require_dist.pressureSensorCapability, { getStatus: async () => this.readSlice(COLD_START) });
@@ -1400,7 +1400,7 @@ var HaLightDevice = class extends HaBaseChildDevice {
1400
1400
  lastChangedAt: 0
1401
1401
  });
1402
1402
  if (this.capSet.has("brightness")) this.runtimeState.setCapState("brightness", {
1403
- percentage: 0,
1403
+ level: 0,
1404
1404
  lastChangedAt: 0
1405
1405
  });
1406
1406
  if (this.capSet.has("color")) this.runtimeState.setCapState("color", {
@@ -1420,7 +1420,7 @@ var HaLightDevice = class extends HaBaseChildDevice {
1420
1420
  if (haBrightness !== null) {
1421
1421
  const percentage = Math.max(0, Math.min(100, Math.round(haBrightness / 255 * 100)));
1422
1422
  this.runtimeState.setCapState("brightness", {
1423
- percentage,
1423
+ level: percentage,
1424
1424
  lastChangedAt
1425
1425
  });
1426
1426
  }
@@ -1450,11 +1450,11 @@ var HaLightDevice = class extends HaBaseChildDevice {
1450
1450
  this.ctx.registerNativeCap(require_dist.brightnessCapability, {
1451
1451
  getStatus: async () => {
1452
1452
  return this.runtimeState.getCapState("brightness") ?? {
1453
- percentage: 0,
1453
+ level: 0,
1454
1454
  lastChangedAt: 0
1455
1455
  };
1456
1456
  },
1457
- setBrightness: async ({ percentage }) => {
1457
+ setBrightness: async ({ level: percentage }) => {
1458
1458
  await this.callHaService("light", "turn_on", { brightness_pct: percentage });
1459
1459
  }
1460
1460
  });
@@ -1513,7 +1513,7 @@ function decodeColorSlice(colorMode, attrs, lastChangedAt) {
1513
1513
  const mireds = readNumberAttr$6(attrs, "color_temp");
1514
1514
  if (mireds !== null) return {
1515
1515
  mode: "mired",
1516
- mireds,
1516
+ colorTemperature: mireds,
1517
1517
  lastChangedAt
1518
1518
  };
1519
1519
  return null;
@@ -1531,7 +1531,7 @@ function colorInputToHaServiceData(color) {
1531
1531
  hs_color: [color.hsv.h, color.hsv.s],
1532
1532
  brightness_pct: color.hsv.v
1533
1533
  };
1534
- case "mired": return { color_temp: color.mireds };
1534
+ case "mired": return { color_temp: color.colorTemperature };
1535
1535
  }
1536
1536
  }
1537
1537
  //#endregion
@@ -2159,7 +2159,7 @@ function readNumberAttr$3(attrs, key) {
2159
2159
  //#endregion
2160
2160
  //#region src/devices/ha-fan-device.ts
2161
2161
  var FAN_COLD_START = {
2162
- percentage: null,
2162
+ speed: null,
2163
2163
  preset: "",
2164
2164
  availablePresets: [],
2165
2165
  direction: null,
@@ -2195,7 +2195,7 @@ var HaFanDevice = class extends HaBaseChildDevice {
2195
2195
  });
2196
2196
  const attrs = state.attributes;
2197
2197
  const slice = {
2198
- percentage: readNumberAttr$2(attrs, "percentage"),
2198
+ speed: readNumberAttr$2(attrs, "percentage"),
2199
2199
  percentageStep: readNumberAttr$2(attrs, "percentage_step") ?? void 0,
2200
2200
  preset: readStringAttr$4(attrs, "preset_mode") ?? "",
2201
2201
  availablePresets: readStringArray$1(attrs, "preset_modes"),
@@ -2223,7 +2223,7 @@ var HaFanDevice = class extends HaBaseChildDevice {
2223
2223
  getStatus: async () => {
2224
2224
  return this.runtimeState.getCapState("fan-control") ?? FAN_COLD_START;
2225
2225
  },
2226
- setPercentage: async ({ percentage }) => {
2226
+ setPercentage: async ({ speed: percentage }) => {
2227
2227
  await this.callHaService("fan", "set_percentage", { percentage });
2228
2228
  },
2229
2229
  setPreset: async ({ preset }) => {
@@ -2265,7 +2265,7 @@ var COLD_START$12 = {
2265
2265
  batteryLevel: null,
2266
2266
  fanSpeed: null,
2267
2267
  availableFanSpeeds: [],
2268
- progressPercent: null,
2268
+ progress: null,
2269
2269
  errorCode: null,
2270
2270
  errorLabel: null,
2271
2271
  lastChangedAt: 0
@@ -2302,7 +2302,7 @@ var HaVacuumDevice = class extends HaBaseChildDevice {
2302
2302
  batteryLevel,
2303
2303
  fanSpeed,
2304
2304
  availableFanSpeeds,
2305
- progressPercent: null,
2305
+ progress: null,
2306
2306
  errorCode: null,
2307
2307
  errorLabel: lifecycleState === "error" ? readStringAttr$3(state.attributes, "error") : null,
2308
2308
  lastChangedAt
@@ -2367,7 +2367,7 @@ function readStringArrayAttr(attrs, key) {
2367
2367
  var COLD_START$11 = {
2368
2368
  activity: "idle",
2369
2369
  batteryLevel: null,
2370
- progressPercent: null,
2370
+ progress: null,
2371
2371
  currentCode: null,
2372
2372
  currentCodeLabel: null,
2373
2373
  severity: "info",
@@ -2397,7 +2397,7 @@ var HaLawnMowerDevice = class extends HaBaseChildDevice {
2397
2397
  if (activity !== null) this.runtimeState.setCapState("lawn-mower-control", {
2398
2398
  activity,
2399
2399
  batteryLevel,
2400
- progressPercent: readNumericAttr$1(state.attributes, "mowing_progress"),
2400
+ progress: readNumericAttr$1(state.attributes, "mowing_progress"),
2401
2401
  currentCode: null,
2402
2402
  currentCodeLabel: null,
2403
2403
  severity: activity === "error" ? "error" : "info",
@@ -2448,8 +2448,8 @@ var COLD_START$10 = {
2448
2448
  source: "",
2449
2449
  availableSources: [],
2450
2450
  currentMedia: null,
2451
- positionMs: null,
2452
- durationMs: null,
2451
+ position: null,
2452
+ duration: null,
2453
2453
  shuffle: null,
2454
2454
  repeat: null,
2455
2455
  lastChangedAt: 0
@@ -2479,8 +2479,8 @@ var HaMediaPlayerDevice = class extends HaBaseChildDevice {
2479
2479
  source: readStringAttr$2(attrs, "source") ?? "",
2480
2480
  availableSources: readStringArray(attrs, "source_list"),
2481
2481
  currentMedia: buildCurrentMedia(attrs),
2482
- positionMs: readDurationMs(attrs, "media_position"),
2483
- durationMs: readDurationMs(attrs, "media_duration"),
2482
+ position: readDurationMs(attrs, "media_position"),
2483
+ duration: readDurationMs(attrs, "media_duration"),
2484
2484
  shuffle: readBooleanAttr(attrs, "shuffle"),
2485
2485
  repeat: readRepeat(attrs["repeat"]),
2486
2486
  lastChangedAt
@@ -2513,7 +2513,7 @@ var HaMediaPlayerDevice = class extends HaBaseChildDevice {
2513
2513
  previous: async () => {
2514
2514
  await this.callHaService("media_player", "media_previous_track");
2515
2515
  },
2516
- seek: async ({ positionMs }) => {
2516
+ seek: async ({ position: positionMs }) => {
2517
2517
  await this.callHaService("media_player", "media_seek", { seek_position: positionMs / 1e3 });
2518
2518
  },
2519
2519
  setVolume: async ({ volumeLevel }) => {
@@ -2682,11 +2682,17 @@ function deriveAvailableModes(attrs) {
2682
2682
  }
2683
2683
  //#endregion
2684
2684
  //#region src/devices/ha-presence-device.ts
2685
+ /** No reading yet: unknown, never 0 % (D393). */
2686
+ var COLD_BATTERY = {
2687
+ level: null,
2688
+ charging: "unknown",
2689
+ sleeping: false,
2690
+ lastUpdated: 0
2691
+ };
2685
2692
  var COLD_START$8 = {
2686
2693
  state: "unknown",
2687
2694
  location: null,
2688
2695
  gps: null,
2689
- batteryPercent: null,
2690
2696
  lastChangedAt: 0
2691
2697
  };
2692
2698
  /**
@@ -2696,14 +2702,17 @@ var COLD_START$8 = {
2696
2702
  *
2697
2703
  * HA attributes consumed:
2698
2704
  * - `latitude` / `longitude` / `gps_accuracy` → gps envelope
2699
- * - `battery_level` → batteryPercent
2705
+ * - `battery_level` → the `battery` cap (a presence provider never reports
2706
+ * battery on the presence status)
2700
2707
  * - `friendly_name` and the state value drive the `location` label
2701
2708
  */
2702
2709
  var HaPresenceDevice = class extends HaBaseChildDevice {
2703
2710
  constructor(ctx) {
2704
2711
  super(ctx);
2705
2712
  this.registerPresenceCap();
2713
+ this.registerBatteryCap();
2706
2714
  this.runtimeState.setCapState("presence", COLD_START$8);
2715
+ if (this.runtimeState.getCapState("battery") === void 0) this.runtimeState.setCapState("battery", COLD_BATTERY);
2707
2716
  }
2708
2717
  handleStatePush(state) {
2709
2718
  if (state.state === "unavailable") return;
@@ -2721,10 +2730,24 @@ var HaPresenceDevice = class extends HaBaseChildDevice {
2721
2730
  longitude: lon,
2722
2731
  accuracyMeters: acc ?? 0
2723
2732
  } : null,
2724
- batteryPercent: battery,
2725
2733
  lastChangedAt
2726
2734
  };
2727
2735
  this.runtimeState.setCapState("presence", slice);
2736
+ if (battery !== null) this.runtimeState.setCapState("battery", {
2737
+ level: Math.min(100, Math.max(0, battery)),
2738
+ charging: "unknown",
2739
+ sleeping: false,
2740
+ lastUpdated: lastChangedAt
2741
+ });
2742
+ }
2743
+ registerBatteryCap() {
2744
+ this.ctx.registerNativeCap(require_dist.batteryCapability, {
2745
+ getStatus: async () => this.runtimeState.getCapState("battery") ?? COLD_BATTERY,
2746
+ wakeForStream: async () => ({
2747
+ awoke: true,
2748
+ durationMs: 0
2749
+ })
2750
+ });
2728
2751
  }
2729
2752
  registerPresenceCap() {
2730
2753
  this.ctx.registerNativeCap(require_dist.presenceCapability, { getStatus: async () => {
@@ -3200,7 +3223,7 @@ var HaNotifierDevice = class extends HaBaseChildDevice {
3200
3223
  var COLD_START$4 = { lastFetchedAt: 0 };
3201
3224
  /**
3202
3225
  * HA-backed power-meter sensor child. Multi-field cap — the slice
3203
- * carries `watts` / `volts` / `amps` / `kwhTotal` etc., but each HA
3226
+ * carries `power` / `voltage` / `current` / `energy` etc., but each HA
3204
3227
  * `sensor.*` entity surfaces ONE metric (device_class = `power` /
3205
3228
  * `voltage` / `current` / `energy`). The class populates the field
3206
3229
  * corresponding to the entity's device_class.
@@ -3263,22 +3286,22 @@ function applyDeviceClass$1(prev, deviceClass, value, lastFetchedAt) {
3263
3286
  switch (deviceClass) {
3264
3287
  case "power": return {
3265
3288
  ...prev,
3266
- watts: value,
3289
+ power: value,
3267
3290
  lastFetchedAt
3268
3291
  };
3269
3292
  case "energy": return {
3270
3293
  ...prev,
3271
- kwhTotal: value,
3294
+ energy: value,
3272
3295
  lastFetchedAt
3273
3296
  };
3274
3297
  case "voltage": return {
3275
3298
  ...prev,
3276
- volts: value,
3299
+ voltage: value,
3277
3300
  lastFetchedAt
3278
3301
  };
3279
3302
  case "current": return {
3280
3303
  ...prev,
3281
- amps: value,
3304
+ current: value,
3282
3305
  lastFetchedAt
3283
3306
  };
3284
3307
  default: return null;
@@ -3344,12 +3367,12 @@ function applyDeviceClass(prev, deviceClass, value, lastFetchedAt) {
3344
3367
  switch (deviceClass) {
3345
3368
  case "co2": return {
3346
3369
  ...prev,
3347
- co2Ppm: value,
3370
+ co2: value,
3348
3371
  lastFetchedAt
3349
3372
  };
3350
3373
  case "volatile_organic_compounds": return {
3351
3374
  ...prev,
3352
- vocPpb: value,
3375
+ voc: value,
3353
3376
  lastFetchedAt
3354
3377
  };
3355
3378
  case "pm25":
@@ -3854,10 +3877,10 @@ var containerEntitySchema = require_dist.object({
3854
3877
  dateTimeFormat: require_dist.EnumSensorDateTimeFormatSchema.optional(),
3855
3878
  entityCategory: require_dist._enum(["config", "diagnostic"]).optional(),
3856
3879
  meterEntities: require_dist.object({
3857
- watts: require_dist.string().optional(),
3858
- kwhTotal: require_dist.string().optional(),
3859
- volts: require_dist.string().optional(),
3860
- amps: require_dist.string().optional()
3880
+ power: require_dist.string().optional(),
3881
+ energy: require_dist.string().optional(),
3882
+ voltage: require_dist.string().optional(),
3883
+ current: require_dist.string().optional()
3861
3884
  }).optional(),
3862
3885
  foldedInto: require_dist.string().optional()
3863
3886
  });
@@ -4041,10 +4064,10 @@ var haEntitySchema = require_dist.object({
4041
4064
  entityCategory: require_dist._enum(["config", "diagnostic"]).optional(),
4042
4065
  /** Sibling meter sensors this entity reads as its own power-meter (D951). */
4043
4066
  meterEntities: require_dist.object({
4044
- watts: require_dist.string().optional(),
4045
- kwhTotal: require_dist.string().optional(),
4046
- volts: require_dist.string().optional(),
4047
- amps: require_dist.string().optional()
4067
+ power: require_dist.string().optional(),
4068
+ energy: require_dist.string().optional(),
4069
+ voltage: require_dist.string().optional(),
4070
+ current: require_dist.string().optional()
4048
4071
  }).optional(),
4049
4072
  /** Set on a meter sensor folded into another entity: sectioned as Diagnostic. */
4050
4073
  foldedInto: require_dist.string().optional()
@@ -4119,7 +4142,7 @@ function deriveBatteryStatus(entities, entityId, state, now) {
4119
4142
  if (isBinaryBattery(battery)) {
4120
4143
  if (state.state !== "on" && state.state !== "off") return null;
4121
4144
  return {
4122
- percentage: state.state === "on" ? BINARY_BATTERY_LOW_PCT : BINARY_BATTERY_NORMAL_PCT,
4145
+ level: state.state === "on" ? BINARY_BATTERY_LOW_PCT : BINARY_BATTERY_NORMAL_PCT,
4123
4146
  charging: "none",
4124
4147
  sleeping: false,
4125
4148
  lastUpdated: now,
@@ -4129,7 +4152,7 @@ function deriveBatteryStatus(entities, entityId, state, now) {
4129
4152
  const raw = Number(state.state);
4130
4153
  if (!Number.isFinite(raw)) return null;
4131
4154
  return {
4132
- percentage: Math.min(100, Math.max(0, raw)),
4155
+ level: Math.min(100, Math.max(0, raw)),
4133
4156
  charging: "none",
4134
4157
  sleeping: false,
4135
4158
  lastUpdated: now
@@ -4186,7 +4209,7 @@ var HaContainerDevice = class HaContainerDevice extends require_dist.BaseDevice
4186
4209
  this.batteryEntityId = batteryEntityId(cfg.entities);
4187
4210
  if (this.batteryEntityId !== null) {
4188
4211
  const COLD = {
4189
- percentage: null,
4212
+ level: null,
4190
4213
  charging: "unknown",
4191
4214
  sleeping: false,
4192
4215
  lastUpdated: 0