@camstack/addon-provider-homeassistant 1.2.624 → 1.2.626

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.
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  enumerable: true
25
25
  }) : target, mod));
26
26
  //#endregion
27
- const require_dist = require("../dist-_Yi49Ixo.js");
27
+ const require_dist = require("../dist-1tLY30OG.js");
28
28
  let node_crypto = require("node:crypto");
29
29
  require("node:zlib");
30
30
  let node_fs = require("node:fs");
@@ -731,12 +731,6 @@ var STATUS_UNKNOWN = "unknown";
731
731
  function consumableEntity(key, facet) {
732
732
  return `${CONSUMABLE_PREFIX}_${toSlug(key)}_${facet}`;
733
733
  }
734
- /** Home Assistant's own duration units; a cycle count is a plain count. */
735
- var REMAINING_UNIT = {
736
- days: "d",
737
- hours: "h",
738
- cycles: "cycles"
739
- };
740
734
  /**
741
735
  * The item's form (the capability's own derivation, `consumableFormOf`): the one
742
736
  * the provider declared when it is a form the capability knows, else the one its
@@ -829,7 +823,7 @@ function consumableEntities(item) {
829
823
  entityCategory: "diagnostic"
830
824
  });
831
825
  if (item.remaining !== void 0) {
832
- const isDuration = item.remaining.unit !== "cycles";
826
+ const isDuration = item.remaining.kind === "duration";
833
827
  out.push({
834
828
  ...base,
835
829
  facet: "remaining",
@@ -837,7 +831,7 @@ function consumableEntities(item) {
837
831
  uniqueSuffix: unique("remaining"),
838
832
  platform: "sensor",
839
833
  label: `${item.label} remaining`,
840
- unit: REMAINING_UNIT[item.remaining.unit],
834
+ ...isDuration ? { unit: "s" } : {},
841
835
  stateClass: "measurement",
842
836
  ...isDuration ? { deviceClass: "duration" } : {},
843
837
  icon: isDuration ? "mdi:timer-sand" : "mdi:counter",
@@ -3184,7 +3178,7 @@ mireds: {
3184
3178
  platform: "sensor",
3185
3179
  field: "desiccantLeftDays",
3186
3180
  label: "Desiccant remaining",
3187
- unit: "d",
3181
+ unit: "s",
3188
3182
  entityCategory: "diagnostic",
3189
3183
  enabledByDefault: false
3190
3184
  },
@@ -3198,11 +3192,8 @@ mireds: {
3198
3192
  }
3199
3193
  },
3200
3194
  /**
3201
- * The cap carries its OWN unit next to each measurement
3202
- * (`temperatureUnit`, `pressureUnit`, `windSpeedUnit`), so no static
3203
- * `unit_of_measurement` can be honest for a provider reporting °F.
3204
- * Declaring one anyway is how a dashboard comes to say 71 °C. Humidity
3205
- * is the exception: a percentage is a percentage.
3195
+ * Weather numbers are stored in the quantity base (°C, hPa, m/s). The
3196
+ * export advertises those symbols. A Fahrenheit dashboard converts at read.
3206
3197
  */
3207
3198
  weather: {
3208
3199
  platform: "sensor",
@@ -3213,6 +3204,8 @@ mireds: {
3213
3204
  platform: "sensor",
3214
3205
  field: "temperature",
3215
3206
  label: "Temperature",
3207
+ unit: "°C",
3208
+ deviceClass: "temperature",
3216
3209
  icon: "mdi:thermometer"
3217
3210
  },
3218
3211
  humidity: {
@@ -3226,6 +3219,8 @@ mireds: {
3226
3219
  platform: "sensor",
3227
3220
  field: "pressure",
3228
3221
  label: "Pressure",
3222
+ unit: "hPa",
3223
+ deviceClass: "pressure",
3229
3224
  icon: "mdi:gauge",
3230
3225
  enabledByDefault: false
3231
3226
  },
@@ -3233,6 +3228,8 @@ mireds: {
3233
3228
  platform: "sensor",
3234
3229
  field: "windSpeed",
3235
3230
  label: "Wind speed",
3231
+ unit: "m/s",
3232
+ deviceClass: "wind_speed",
3236
3233
  icon: "mdi:weather-windy",
3237
3234
  enabledByDefault: false
3238
3235
  },
@@ -3443,7 +3440,7 @@ function readFiniteNumber(slice, field) {
3443
3440
  * builds with nothing to choose from — so an empty list falls back to a
3444
3441
  * read-only sensor rather than a dead control.
3445
3442
  */
3446
- function controlEntitySpecs(slice) {
3443
+ function controlEntitySpecs(slice, quantity) {
3447
3444
  const kind = typeof slice?.["kind"] === "string" ? slice["kind"] : null;
3448
3445
  const primary = derivedEntityId("control");
3449
3446
  const kindExtra = {
@@ -3468,7 +3465,7 @@ function controlEntitySpecs(slice) {
3468
3465
  const min = readFiniteNumber(slice, "min") ?? PERCENT_RANGE.min;
3469
3466
  const max = readFiniteNumber(slice, "max") ?? PERCENT_RANGE.max;
3470
3467
  const step = readFiniteNumber(slice, "step") ?? PERCENT_RANGE.step;
3471
- const unit = typeof slice?.["unit"] === "string" ? slice["unit"] : void 0;
3468
+ const unit = quantity === void 0 ? void 0 : require_dist.baseUnitOf(quantity);
3472
3469
  if (min < max && step > 0) return [{
3473
3470
  entity: primary,
3474
3471
  platform: "number",
@@ -3738,7 +3735,15 @@ function buildDerivedPlan(device, options = UNNEGOTIATED_PLAN_OPTIONS) {
3738
3735
  * row stays the projector + writable-route authority.
3739
3736
  */
3740
3737
  if (cap === "control") {
3741
- specs.push(...controlEntitySpecs(device.capSlices?.["control"]).map((spec) => degradeUnsupported(spec, options)));
3738
+ specs.push(...controlEntitySpecs(device.capSlices?.["control"], device.readingQuantity).map((spec) => degradeUnsupported(spec, options)));
3739
+ continue;
3740
+ }
3741
+ if (cap === "numeric-sensor") {
3742
+ const unit = device.readingQuantity === void 0 ? void 0 : require_dist.baseUnitOf(device.readingQuantity);
3743
+ specs.push(...capEntitySpecs(cap).map((spec) => degradeUnsupported(unit === void 0 ? spec : {
3744
+ ...spec,
3745
+ unit
3746
+ }, options)));
3742
3747
  continue;
3743
3748
  }
3744
3749
  const mapping = CAP_ENTITY_MAP[cap];
@@ -7963,6 +7968,7 @@ var HaExportAddon = class extends require_dist.BaseAddon {
7963
7968
  if (items.held) heldBack = true;
7964
7969
  const manufacturer = readString(device.metadata ?? {}, "manufacturer");
7965
7970
  const model = readString(device.metadata ?? {}, "model");
7971
+ const readingQuantity = device.sourceInfo?.quantity;
7966
7972
  return {
7967
7973
  device: {
7968
7974
  id: device.id,
@@ -7984,7 +7990,8 @@ var HaExportAddon = class extends require_dist.BaseAddon {
7984
7990
  * `CatalogDevice.capSlices`.
7985
7991
  */
7986
7992
  capSlices: snapshot,
7987
- itemEntities: items.entities
7993
+ itemEntities: items.entities,
7994
+ ...require_dist.isReadingQuantity(readingQuantity) ? { readingQuantity } : {}
7988
7995
  },
7989
7996
  heldBack
7990
7997
  };
@@ -1,4 +1,4 @@
1
- import { At as BaseAddon, D as buildAddonRouteProvider, F as consumableFormOf, Gt as string, H as deviceExportCapability, I as consumableKindOf, It as nodePin, Rt as array, Ut as object, Yt as EventCategory, _ as addonRoutesCapability, a as COCO_TO_MACRO, at as oauthIntegrationCapability, c as ConsumableItemSchema, d as FanDirectionSchema, f as HvacModeSchema, i as CAMERA_SWITCH_ORDER, l as ConsumableStatusSchema, o as CameraSwitchIdSchema, p as MediaPlayerRepeatSchema, qt as unknown, s as ConsumableFormSchema, t as AlarmArmModeSchema } from "../dist-BJRmTD1G.mjs";
1
+ import { $t as unknown, D as buildAddonRouteProvider, F as consumableFormOf, H as deviceExportCapability, Ht as nodePin, I as consumableKindOf, It as baseUnitOf, Pt as BaseAddon, Vt as isReadingQuantity, Wt as array, Yt as object, Zt as string, _ as addonRoutesCapability, a as COCO_TO_MACRO, c as ConsumableItemSchema, d as FanDirectionSchema, f as HvacModeSchema, i as CAMERA_SWITCH_ORDER, l as ConsumableStatusSchema, o as CameraSwitchIdSchema, ot as oauthIntegrationCapability, p as MediaPlayerRepeatSchema, s as ConsumableFormSchema, t as AlarmArmModeSchema, tn as EventCategory } from "../dist-B7nW5y58.mjs";
2
2
  import { createHmac, timingSafeEqual } from "node:crypto";
3
3
  import "node:zlib";
4
4
  import "node:fs";
@@ -703,12 +703,6 @@ var STATUS_UNKNOWN = "unknown";
703
703
  function consumableEntity(key, facet) {
704
704
  return `${CONSUMABLE_PREFIX}_${toSlug(key)}_${facet}`;
705
705
  }
706
- /** Home Assistant's own duration units; a cycle count is a plain count. */
707
- var REMAINING_UNIT = {
708
- days: "d",
709
- hours: "h",
710
- cycles: "cycles"
711
- };
712
706
  /**
713
707
  * The item's form (the capability's own derivation, `consumableFormOf`): the one
714
708
  * the provider declared when it is a form the capability knows, else the one its
@@ -794,7 +788,7 @@ function consumableEntities(item) {
794
788
  entityCategory: "diagnostic"
795
789
  });
796
790
  if (item.remaining !== void 0) {
797
- const isDuration = item.remaining.unit !== "cycles";
791
+ const isDuration = item.remaining.kind === "duration";
798
792
  out.push({
799
793
  ...base,
800
794
  facet: "remaining",
@@ -802,7 +796,7 @@ function consumableEntities(item) {
802
796
  uniqueSuffix: unique("remaining"),
803
797
  platform: "sensor",
804
798
  label: `${item.label} remaining`,
805
- unit: REMAINING_UNIT[item.remaining.unit],
799
+ ...isDuration ? { unit: "s" } : {},
806
800
  stateClass: "measurement",
807
801
  ...isDuration ? { deviceClass: "duration" } : {},
808
802
  icon: isDuration ? "mdi:timer-sand" : "mdi:counter",
@@ -3149,7 +3143,7 @@ mireds: {
3149
3143
  platform: "sensor",
3150
3144
  field: "desiccantLeftDays",
3151
3145
  label: "Desiccant remaining",
3152
- unit: "d",
3146
+ unit: "s",
3153
3147
  entityCategory: "diagnostic",
3154
3148
  enabledByDefault: false
3155
3149
  },
@@ -3163,11 +3157,8 @@ mireds: {
3163
3157
  }
3164
3158
  },
3165
3159
  /**
3166
- * The cap carries its OWN unit next to each measurement
3167
- * (`temperatureUnit`, `pressureUnit`, `windSpeedUnit`), so no static
3168
- * `unit_of_measurement` can be honest for a provider reporting °F.
3169
- * Declaring one anyway is how a dashboard comes to say 71 °C. Humidity
3170
- * is the exception: a percentage is a percentage.
3160
+ * Weather numbers are stored in the quantity base (°C, hPa, m/s). The
3161
+ * export advertises those symbols. A Fahrenheit dashboard converts at read.
3171
3162
  */
3172
3163
  weather: {
3173
3164
  platform: "sensor",
@@ -3178,6 +3169,8 @@ mireds: {
3178
3169
  platform: "sensor",
3179
3170
  field: "temperature",
3180
3171
  label: "Temperature",
3172
+ unit: "°C",
3173
+ deviceClass: "temperature",
3181
3174
  icon: "mdi:thermometer"
3182
3175
  },
3183
3176
  humidity: {
@@ -3191,6 +3184,8 @@ mireds: {
3191
3184
  platform: "sensor",
3192
3185
  field: "pressure",
3193
3186
  label: "Pressure",
3187
+ unit: "hPa",
3188
+ deviceClass: "pressure",
3194
3189
  icon: "mdi:gauge",
3195
3190
  enabledByDefault: false
3196
3191
  },
@@ -3198,6 +3193,8 @@ mireds: {
3198
3193
  platform: "sensor",
3199
3194
  field: "windSpeed",
3200
3195
  label: "Wind speed",
3196
+ unit: "m/s",
3197
+ deviceClass: "wind_speed",
3201
3198
  icon: "mdi:weather-windy",
3202
3199
  enabledByDefault: false
3203
3200
  },
@@ -3408,7 +3405,7 @@ function readFiniteNumber(slice, field) {
3408
3405
  * builds with nothing to choose from — so an empty list falls back to a
3409
3406
  * read-only sensor rather than a dead control.
3410
3407
  */
3411
- function controlEntitySpecs(slice) {
3408
+ function controlEntitySpecs(slice, quantity) {
3412
3409
  const kind = typeof slice?.["kind"] === "string" ? slice["kind"] : null;
3413
3410
  const primary = derivedEntityId("control");
3414
3411
  const kindExtra = {
@@ -3433,7 +3430,7 @@ function controlEntitySpecs(slice) {
3433
3430
  const min = readFiniteNumber(slice, "min") ?? PERCENT_RANGE.min;
3434
3431
  const max = readFiniteNumber(slice, "max") ?? PERCENT_RANGE.max;
3435
3432
  const step = readFiniteNumber(slice, "step") ?? PERCENT_RANGE.step;
3436
- const unit = typeof slice?.["unit"] === "string" ? slice["unit"] : void 0;
3433
+ const unit = quantity === void 0 ? void 0 : baseUnitOf(quantity);
3437
3434
  if (min < max && step > 0) return [{
3438
3435
  entity: primary,
3439
3436
  platform: "number",
@@ -3703,7 +3700,15 @@ function buildDerivedPlan(device, options = UNNEGOTIATED_PLAN_OPTIONS) {
3703
3700
  * row stays the projector + writable-route authority.
3704
3701
  */
3705
3702
  if (cap === "control") {
3706
- specs.push(...controlEntitySpecs(device.capSlices?.["control"]).map((spec) => degradeUnsupported(spec, options)));
3703
+ specs.push(...controlEntitySpecs(device.capSlices?.["control"], device.readingQuantity).map((spec) => degradeUnsupported(spec, options)));
3704
+ continue;
3705
+ }
3706
+ if (cap === "numeric-sensor") {
3707
+ const unit = device.readingQuantity === void 0 ? void 0 : baseUnitOf(device.readingQuantity);
3708
+ specs.push(...capEntitySpecs(cap).map((spec) => degradeUnsupported(unit === void 0 ? spec : {
3709
+ ...spec,
3710
+ unit
3711
+ }, options)));
3707
3712
  continue;
3708
3713
  }
3709
3714
  const mapping = CAP_ENTITY_MAP[cap];
@@ -7928,6 +7933,7 @@ var HaExportAddon = class extends BaseAddon {
7928
7933
  if (items.held) heldBack = true;
7929
7934
  const manufacturer = readString(device.metadata ?? {}, "manufacturer");
7930
7935
  const model = readString(device.metadata ?? {}, "model");
7936
+ const readingQuantity = device.sourceInfo?.quantity;
7931
7937
  return {
7932
7938
  device: {
7933
7939
  id: device.id,
@@ -7949,7 +7955,8 @@ var HaExportAddon = class extends BaseAddon {
7949
7955
  * `CatalogDevice.capSlices`.
7950
7956
  */
7951
7957
  capSlices: snapshot,
7952
- itemEntities: items.entities
7958
+ itemEntities: items.entities,
7959
+ ...isReadingQuantity(readingQuantity) ? { readingQuantity } : {}
7953
7960
  },
7954
7961
  heldBack
7955
7962
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homeassistant",
3
- "version": "1.2.624",
3
+ "version": "1.2.626",
4
4
  "description": "Home Assistant device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",
@@ -13,7 +13,12 @@
13
13
  "license": "MIT",
14
14
  "repository": {
15
15
  "type": "git",
16
- "url": "https://github.com/camstack/server"
16
+ "url": "https://github.com/camstack/server.git",
17
+ "directory": "packages/addon-provider-homeassistant"
18
+ },
19
+ "homepage": "https://camstack-docs.zentik.app",
20
+ "bugs": {
21
+ "url": "https://github.com/camstack/server/issues"
17
22
  },
18
23
  "main": "./dist/index.js",
19
24
  "module": "./dist/index.mjs",