camstack 1.2.101 → 1.2.102

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.
@@ -14522,7 +14522,7 @@ function date4(params) {
14522
14522
  // ../../node_modules/zod/v4/classic/external.js
14523
14523
  config(en_default());
14524
14524
 
14525
- // ../types/dist/sleep-Db7MvrdS.mjs
14525
+ // ../types/dist/sleep-BRy4r7RG.mjs
14526
14526
  var WELL_KNOWN_TABS = [
14527
14527
  {
14528
14528
  id: "overview",
@@ -32150,6 +32150,85 @@ var batteryCapability = {
32150
32150
  * whether persisting is worth a SQLite commit. */
32151
32151
  volatileStateFields: ["lastUpdated"]
32152
32152
  };
32153
+ var NETWORK_LINK_TYPES = [
32154
+ "wifi",
32155
+ "ethernet",
32156
+ "cellular",
32157
+ "unknown"
32158
+ ];
32159
+ var NetworkLinkStatusSchema = external_exports.object({
32160
+ /** The link the device is on. `'unknown'` = not read yet, not "no link". */
32161
+ type: external_exports.enum(NETWORK_LINK_TYPES),
32162
+ /**
32163
+ * Link quality, 0..100 inclusive, normalised by the provider from whatever
32164
+ * the firmware reports (bars, RSSI, a vendor scale). **`null` means NOT
32165
+ * KNOWN or NOT APPLICABLE** — a wired link has no signal, and a wireless
32166
+ * one whose reading has not landed must not be drawn at 0 %. Consumers
32167
+ * SKIP a null rather than coerce it.
32168
+ */
32169
+ signalPercent: external_exports.number().min(0).max(100).nullable(),
32170
+ /** Raw received signal strength in dBm, when the firmware reports one. */
32171
+ rssiDbm: external_exports.number().optional(),
32172
+ /** Network name of a wireless link, when the firmware reports it. */
32173
+ ssid: external_exports.string().optional(),
32174
+ /** Ms epoch of the last observation. Lets consumers reason about freshness. */
32175
+ lastUpdated: external_exports.number()
32176
+ });
32177
+ var NETWORK_LINK_UNKNOWN = {
32178
+ type: "unknown",
32179
+ signalPercent: null,
32180
+ lastUpdated: 0
32181
+ };
32182
+ var networkLinkCapability = {
32183
+ name: "network-link",
32184
+ scope: "device",
32185
+ deviceNative: true,
32186
+ mode: "singleton",
32187
+ deviceTypes: [
32188
+ DeviceType.Camera,
32189
+ DeviceType.Sensor,
32190
+ DeviceType.Button,
32191
+ DeviceType.Switch,
32192
+ DeviceType.Light,
32193
+ DeviceType.Lock,
32194
+ DeviceType.Siren
32195
+ ],
32196
+ methods: {},
32197
+ events: {
32198
+ /**
32199
+ * Emitted whenever the cached status changes (a link switch, a signal
32200
+ * reading that moved). Mirrored on the parent chain by the
32201
+ * DeviceEventPropagator like `battery.onStatusChanged`.
32202
+ */
32203
+ onStatusChanged: { data: external_exports.object({
32204
+ deviceId: external_exports.number(),
32205
+ status: NetworkLinkStatusSchema
32206
+ }) }
32207
+ },
32208
+ status: {
32209
+ schema: NetworkLinkStatusSchema,
32210
+ kind: "push",
32211
+ empty: NETWORK_LINK_UNKNOWN
32212
+ },
32213
+ /**
32214
+ * Runtime-state slice — every provider stores the same shape under
32215
+ * `device.runtimeState['network-link']`, read once by the badge and the
32216
+ * Home Assistant projector regardless of the driver.
32217
+ */
32218
+ runtimeState: NetworkLinkStatusSchema,
32219
+ /**
32220
+ * Runtime-state durability: **restored** — a link reading is slow to
32221
+ * change and a sleeping battery camera may not report for hours; the
32222
+ * restored slice is what the badge shows until the next read.
32223
+ *
32224
+ * See `RuntimeStateDurability`. Enforced by
32225
+ * `scripts/check-runtime-state-durability.ts`.
32226
+ */
32227
+ durability: "restored",
32228
+ /** Clock fields: written, but excluded from the compare that decides
32229
+ * whether persisting is worth a SQLite commit. */
32230
+ volatileStateFields: ["lastUpdated"]
32231
+ };
32153
32232
  var BinaryStatusSchema = external_exports.object({
32154
32233
  on: external_exports.boolean(),
32155
32234
  /** Ms epoch of the last transition. 0 if never observed. */
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDiscover
4
- } from "./chunk-7N7KEXGL.js";
4
+ } from "./chunk-TPJZXJTF.js";
5
5
  import "./chunk-LMMQX4CK.js";
6
6
 
7
7
  // src/cli.ts
@@ -38,7 +38,7 @@ async function runServe(args) {
38
38
  ...typeof values.data === "string" ? { data: values.data } : {}
39
39
  };
40
40
  Object.assign(process.env, buildServeEnv(opts));
41
- await import("./launcher-Q6SAJY4R.js");
41
+ await import("./launcher-DTWKSRVF.js");
42
42
  }
43
43
 
44
44
  // src/commands/agent.ts
@@ -83,7 +83,7 @@ async function runAgent(args) {
83
83
  ...typeof values.port === "string" ? { port: values.port } : {}
84
84
  };
85
85
  Object.assign(process.env, buildAgentEnv(opts));
86
- await import("./launcher-Q6SAJY4R.js");
86
+ await import("./launcher-DTWKSRVF.js");
87
87
  }
88
88
 
89
89
  // src/commands/setup.ts
@@ -1130,7 +1130,7 @@ function isUnknown(_value) {
1130
1130
  return true;
1131
1131
  }
1132
1132
  async function resolveServerInteractive(presetNamespace) {
1133
- const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-3TATRQOW.js");
1133
+ const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-33RHXYBU.js");
1134
1134
  if (presetNamespace) {
1135
1135
  const spinner4 = clack.spinner();
1136
1136
  spinner4.start(`Discovering hub on LAN (namespace "${presetNamespace}")`);
@@ -5,7 +5,7 @@ import {
5
5
  filterHubNodes,
6
6
  resolveHubFromDiscovered,
7
7
  runDiscover
8
- } from "./chunk-7N7KEXGL.js";
8
+ } from "./chunk-TPJZXJTF.js";
9
9
  import "./chunk-LMMQX4CK.js";
10
10
  export {
11
11
  DEFAULT_HUB_HTTPS_PORT,
@@ -23633,9 +23633,9 @@ var require_zod = __commonJS({
23633
23633
  }
23634
23634
  });
23635
23635
 
23636
- // ../system/dist/dist-DyO7xSEt.js
23637
- var require_dist_DyO7xSEt = __commonJS({
23638
- "../system/dist/dist-DyO7xSEt.js"(exports) {
23636
+ // ../system/dist/dist-B0Cf6q_P.js
23637
+ var require_dist_B0Cf6q_P = __commonJS({
23638
+ "../system/dist/dist-B0Cf6q_P.js"(exports) {
23639
23639
  "use strict";
23640
23640
  var zod = require_zod();
23641
23641
  var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
@@ -23719,6 +23719,7 @@ var require_dist_DyO7xSEt = __commonJS({
23719
23719
  EventCategory2["DeviceStateChanged"] = "device.state-changed";
23720
23720
  EventCategory2["ZoneAnalyticsOccupancyChanged"] = "zone-analytics.occupancy-changed";
23721
23721
  EventCategory2["BatteryOnStatusChanged"] = "battery.onStatusChanged";
23722
+ EventCategory2["NetworkLinkOnStatusChanged"] = "network-link.onStatusChanged";
23722
23723
  EventCategory2["BatteryOnWakeStarted"] = "battery.onWakeStarted";
23723
23724
  EventCategory2["DoorbellOnPressed"] = "doorbell.onPressed";
23724
23725
  EventCategory2["EventEmitted"] = "event-emitter.event";
@@ -42710,6 +42711,83 @@ var require_dist_DyO7xSEt = __commonJS({
42710
42711
  * whether persisting is worth a SQLite commit. */
42711
42712
  volatileStateFields: ["lastUpdated"]
42712
42713
  };
42714
+ var NetworkLinkStatusSchema = zod.z.object({
42715
+ /** The link the device is on. `'unknown'` = not read yet, not "no link". */
42716
+ type: zod.z.enum([
42717
+ "wifi",
42718
+ "ethernet",
42719
+ "cellular",
42720
+ "unknown"
42721
+ ]),
42722
+ /**
42723
+ * Link quality, 0..100 inclusive, normalised by the provider from whatever
42724
+ * the firmware reports (bars, RSSI, a vendor scale). **`null` means NOT
42725
+ * KNOWN or NOT APPLICABLE** — a wired link has no signal, and a wireless
42726
+ * one whose reading has not landed must not be drawn at 0 %. Consumers
42727
+ * SKIP a null rather than coerce it.
42728
+ */
42729
+ signalPercent: zod.z.number().min(0).max(100).nullable(),
42730
+ /** Raw received signal strength in dBm, when the firmware reports one. */
42731
+ rssiDbm: zod.z.number().optional(),
42732
+ /** Network name of a wireless link, when the firmware reports it. */
42733
+ ssid: zod.z.string().optional(),
42734
+ /** Ms epoch of the last observation. Lets consumers reason about freshness. */
42735
+ lastUpdated: zod.z.number()
42736
+ });
42737
+ var networkLinkCapability = {
42738
+ name: "network-link",
42739
+ scope: "device",
42740
+ deviceNative: true,
42741
+ mode: "singleton",
42742
+ deviceTypes: [
42743
+ DeviceType.Camera,
42744
+ DeviceType.Sensor,
42745
+ DeviceType.Button,
42746
+ DeviceType.Switch,
42747
+ DeviceType.Light,
42748
+ DeviceType.Lock,
42749
+ DeviceType.Siren
42750
+ ],
42751
+ methods: {},
42752
+ events: {
42753
+ /**
42754
+ * Emitted whenever the cached status changes (a link switch, a signal
42755
+ * reading that moved). Mirrored on the parent chain by the
42756
+ * DeviceEventPropagator like `battery.onStatusChanged`.
42757
+ */
42758
+ onStatusChanged: { data: zod.z.object({
42759
+ deviceId: zod.z.number(),
42760
+ status: NetworkLinkStatusSchema
42761
+ }) }
42762
+ },
42763
+ status: {
42764
+ schema: NetworkLinkStatusSchema,
42765
+ kind: "push",
42766
+ empty: {
42767
+ type: "unknown",
42768
+ signalPercent: null,
42769
+ lastUpdated: 0
42770
+ }
42771
+ },
42772
+ /**
42773
+ * Runtime-state slice — every provider stores the same shape under
42774
+ * `device.runtimeState['network-link']`, read once by the badge and the
42775
+ * Home Assistant projector regardless of the driver.
42776
+ */
42777
+ runtimeState: NetworkLinkStatusSchema,
42778
+ /**
42779
+ * Runtime-state durability: **restored** — a link reading is slow to
42780
+ * change and a sleeping battery camera may not report for hours; the
42781
+ * restored slice is what the badge shows until the next read.
42782
+ *
42783
+ * See `RuntimeStateDurability`. Enforced by
42784
+ * `scripts/check-runtime-state-durability.ts`.
42785
+ */
42786
+ durability: "restored",
42787
+ /** Clock fields: written, but excluded from the compare that decides
42788
+ * whether persisting is worth a SQLite commit. */
42789
+ volatileStateFields: ["lastUpdated"]
42790
+ };
42713
42791
  var BinaryStatusSchema = zod.z.object({
42714
42792
  on: zod.z.boolean(),
42715
42793
  /** Ms epoch of the last transition. 0 if never observed. */
@@ -50735,6 +50813,7 @@ var require_dist_DyO7xSEt = __commonJS({
50735
50813
  "motion-zones",
50736
50814
  "mqtt-broker",
50737
50815
  "native-object-detection",
50816
+ "network-link",
50738
50817
  "notifier",
50739
50818
  "numeric-sensor",
50740
50819
  "osd",
@@ -50852,6 +50931,7 @@ var require_dist_DyO7xSEt = __commonJS({
50852
50931
  mqttBrokerCapability,
50853
50932
  nativeObjectDetectionCapability,
50854
50933
  networkAccessCapability,
50934
+ networkLinkCapability,
50855
50935
  networkQualityCapability,
50856
50936
  nodesCapability,
50857
50937
  notificationOutputCapability,
@@ -58944,6 +59024,10 @@ var require_dist_DyO7xSEt = __commonJS({
58944
59024
  durability: "restored",
58945
59025
  volatileFields: ["lastFetchedAt"]
58946
59026
  },
59027
+ "network-link": {
59028
+ durability: "restored",
59029
+ volatileFields: ["lastUpdated"]
59030
+ },
58947
59031
  "notifier": {
58948
59032
  durability: "session",
58949
59033
  volatileFields: []
@@ -60194,7 +60278,7 @@ var require_alerts_addon = __commonJS({
60194
60278
  [Symbol.toStringTag]: { value: "Module" }
60195
60279
  });
60196
60280
  require_chunk_Cek0wNdY();
60197
- var require_dist10 = require_dist_DyO7xSEt();
60281
+ var require_dist10 = require_dist_B0Cf6q_P();
60198
60282
  function selectExpired(alerts, cutoffMs) {
60199
60283
  return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
60200
60284
  }
@@ -61013,7 +61097,7 @@ var require_console_logging = __commonJS({
61013
61097
  [Symbol.toStringTag]: { value: "Module" }
61014
61098
  });
61015
61099
  require_chunk_Cek0wNdY();
61016
- var require_dist10 = require_dist_DyO7xSEt();
61100
+ var require_dist10 = require_dist_B0Cf6q_P();
61017
61101
  var require_formatter = require_formatter_DqAKDlvN();
61018
61102
  var LEVEL_RANK = {
61019
61103
  debug: 0,
@@ -61107,7 +61191,7 @@ var require_core_blocks_addon = __commonJS({
61107
61191
  "use strict";
61108
61192
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
61109
61193
  var require_chunk = require_chunk_Cek0wNdY();
61110
- var require_dist10 = require_dist_DyO7xSEt();
61194
+ var require_dist10 = require_dist_B0Cf6q_P();
61111
61195
  var node_crypto = __require("crypto");
61112
61196
  var node_fs_promises = __require("fs/promises");
61113
61197
  node_fs_promises = require_chunk.__toESM(node_fs_promises);
@@ -62004,11 +62088,11 @@ var require_core_blocks = __commonJS({
62004
62088
  }
62005
62089
  });
62006
62090
 
62007
- // ../system/dist/retired-settings-keys-BD6-AoDL.js
62008
- var require_retired_settings_keys_BD6_AoDL = __commonJS({
62009
- "../system/dist/retired-settings-keys-BD6-AoDL.js"(exports) {
62091
+ // ../system/dist/retired-settings-keys-mP95OCUi.js
62092
+ var require_retired_settings_keys_mP95OCUi = __commonJS({
62093
+ "../system/dist/retired-settings-keys-mP95OCUi.js"(exports) {
62010
62094
  "use strict";
62011
- var require_dist10 = require_dist_DyO7xSEt();
62095
+ var require_dist10 = require_dist_B0Cf6q_P();
62012
62096
  function settingsStoreIsAuthoritativeHere(env) {
62013
62097
  const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
62014
62098
  return raw === "" || raw === "hub";
@@ -64222,8 +64306,8 @@ var require_device_manager_addon = __commonJS({
64222
64306
  [Symbol.toStringTag]: { value: "Module" }
64223
64307
  });
64224
64308
  require_chunk_Cek0wNdY();
64225
- var require_dist10 = require_dist_DyO7xSEt();
64226
- var require_retired_settings_keys = require_retired_settings_keys_BD6_AoDL();
64309
+ var require_dist10 = require_dist_B0Cf6q_P();
64310
+ var require_retired_settings_keys = require_retired_settings_keys_mP95OCUi();
64227
64311
  var node_crypto = __require("crypto");
64228
64312
  var _camstack_types_node = require_node();
64229
64313
  var JOB_HISTORY = 20;
@@ -69738,7 +69822,7 @@ var require_hub_forwarder = __commonJS({
69738
69822
  [Symbol.toStringTag]: { value: "Module" }
69739
69823
  });
69740
69824
  require_chunk_Cek0wNdY();
69741
- var require_dist10 = require_dist_DyO7xSEt();
69825
+ var require_dist10 = require_dist_B0Cf6q_P();
69742
69826
  var require_formatter = require_formatter_DqAKDlvN();
69743
69827
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
69744
69828
  var HubForwarderDestination = class {
@@ -69875,7 +69959,7 @@ var require_liveness_monitor_addon = __commonJS({
69875
69959
  "use strict";
69876
69960
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
69877
69961
  require_chunk_Cek0wNdY();
69878
- var require_dist10 = require_dist_DyO7xSEt();
69962
+ var require_dist10 = require_dist_B0Cf6q_P();
69879
69963
  var NO_DEVICES = "liveness:no-devices";
69880
69964
  var ALL_OFFLINE = "liveness:all-devices-offline";
69881
69965
  var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
@@ -70071,7 +70155,7 @@ var require_local_auth_addon = __commonJS({
70071
70155
  [Symbol.toStringTag]: { value: "Module" }
70072
70156
  });
70073
70157
  var require_chunk = require_chunk_Cek0wNdY();
70074
- var require_dist10 = require_dist_DyO7xSEt();
70158
+ var require_dist10 = require_dist_B0Cf6q_P();
70075
70159
  var node_crypto = __require("crypto");
70076
70160
  node_crypto = require_chunk.__toESM(node_crypto);
70077
70161
  var crypto$1 = __require("crypto");
@@ -77884,7 +77968,7 @@ var require_loki_logging = __commonJS({
77884
77968
  [Symbol.toStringTag]: { value: "Module" }
77885
77969
  });
77886
77970
  require_chunk_Cek0wNdY();
77887
- var require_dist10 = require_dist_DyO7xSEt();
77971
+ var require_dist10 = require_dist_B0Cf6q_P();
77888
77972
  function sanitizeLabelName(raw) {
77889
77973
  const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
77890
77974
  return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
@@ -78449,7 +78533,7 @@ var require_native_metrics_addon = __commonJS({
78449
78533
  [Symbol.toStringTag]: { value: "Module" }
78450
78534
  });
78451
78535
  var require_chunk = require_chunk_Cek0wNdY();
78452
- var require_dist10 = require_dist_DyO7xSEt();
78536
+ var require_dist10 = require_dist_B0Cf6q_P();
78453
78537
  var node_fs_promises = __require("fs/promises");
78454
78538
  var node_child_process = __require("child_process");
78455
78539
  var node_util = __require("util");
@@ -81033,7 +81117,7 @@ var require_filesystem_storage_addon = __commonJS({
81033
81117
  [Symbol.toStringTag]: { value: "Module" }
81034
81118
  });
81035
81119
  var require_chunk = require_chunk_Cek0wNdY();
81036
- var require_dist10 = require_dist_DyO7xSEt();
81120
+ var require_dist10 = require_dist_B0Cf6q_P();
81037
81121
  var node_crypto = __require("crypto");
81038
81122
  var node_fs_promises = __require("fs/promises");
81039
81123
  var node_path = __require("path");
@@ -82149,8 +82233,8 @@ var require_sqlite_settings_addon = __commonJS({
82149
82233
  [Symbol.toStringTag]: { value: "Module" }
82150
82234
  });
82151
82235
  var require_chunk = require_chunk_Cek0wNdY();
82152
- var require_dist10 = require_dist_DyO7xSEt();
82153
- var require_retired_settings_keys = require_retired_settings_keys_BD6_AoDL();
82236
+ var require_dist10 = require_dist_B0Cf6q_P();
82237
+ var require_retired_settings_keys = require_retired_settings_keys_mP95OCUi();
82154
82238
  var node_crypto = __require("crypto");
82155
82239
  var node_fs = __require("fs");
82156
82240
  var node_module = __require("module");
@@ -84640,7 +84724,7 @@ var require_storage_orchestrator_addon = __commonJS({
84640
84724
  [Symbol.toStringTag]: { value: "Module" }
84641
84725
  });
84642
84726
  var require_chunk = require_chunk_Cek0wNdY();
84643
- var require_dist10 = require_dist_DyO7xSEt();
84727
+ var require_dist10 = require_dist_B0Cf6q_P();
84644
84728
  var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
84645
84729
  var zod = require_zod();
84646
84730
  var node_crypto = __require("crypto");
@@ -87591,7 +87675,7 @@ var require_system_config_addon = __commonJS({
87591
87675
  [Symbol.toStringTag]: { value: "Module" }
87592
87676
  });
87593
87677
  require_chunk_Cek0wNdY();
87594
- var require_dist10 = require_dist_DyO7xSEt();
87678
+ var require_dist10 = require_dist_B0Cf6q_P();
87595
87679
  var SECTION_TITLES = {
87596
87680
  server: "Server",
87597
87681
  auth: "Authentication"
@@ -105652,7 +105736,7 @@ var require_winston_logging = __commonJS({
105652
105736
  [Symbol.toStringTag]: { value: "Module" }
105653
105737
  });
105654
105738
  var require_chunk = require_chunk_Cek0wNdY();
105655
- var require_dist10 = require_dist_DyO7xSEt();
105739
+ var require_dist10 = require_dist_B0Cf6q_P();
105656
105740
  var require_formatter = require_formatter_DqAKDlvN();
105657
105741
  var node_path = __require("path");
105658
105742
  node_path = require_chunk.__toESM(node_path);
@@ -107428,9 +107512,9 @@ ${(0, node_fs.readFileSync)(ca.caCertPath, "utf-8").trimEnd()}
107428
107512
  }
107429
107513
  });
107430
107514
 
107431
- // ../types/dist/event-category-BaEgqJNv.js
107432
- var require_event_category_BaEgqJNv = __commonJS({
107433
- "../types/dist/event-category-BaEgqJNv.js"(exports) {
107515
+ // ../types/dist/event-category-b8kBSOTT.js
107516
+ var require_event_category_b8kBSOTT = __commonJS({
107517
+ "../types/dist/event-category-b8kBSOTT.js"(exports) {
107434
107518
  "use strict";
107435
107519
  var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
107436
107520
  EventCategory2["SystemBoot"] = "system.boot";
@@ -107513,6 +107597,7 @@ var require_event_category_BaEgqJNv = __commonJS({
107513
107597
  EventCategory2["DeviceStateChanged"] = "device.state-changed";
107514
107598
  EventCategory2["ZoneAnalyticsOccupancyChanged"] = "zone-analytics.occupancy-changed";
107515
107599
  EventCategory2["BatteryOnStatusChanged"] = "battery.onStatusChanged";
107600
+ EventCategory2["NetworkLinkOnStatusChanged"] = "network-link.onStatusChanged";
107516
107601
  EventCategory2["BatteryOnWakeStarted"] = "battery.onWakeStarted";
107517
107602
  EventCategory2["DoorbellOnPressed"] = "doorbell.onPressed";
107518
107603
  EventCategory2["EventEmitted"] = "event-emitter.event";
@@ -107595,11 +107680,11 @@ var require_event_category_BaEgqJNv = __commonJS({
107595
107680
  }
107596
107681
  });
107597
107682
 
107598
- // ../types/dist/sleep-DVTaZZHP.js
107599
- var require_sleep_DVTaZZHP = __commonJS({
107600
- "../types/dist/sleep-DVTaZZHP.js"(exports) {
107683
+ // ../types/dist/sleep-TVipGseU.js
107684
+ var require_sleep_TVipGseU = __commonJS({
107685
+ "../types/dist/sleep-TVipGseU.js"(exports) {
107601
107686
  "use strict";
107602
- var require_event_category = require_event_category_BaEgqJNv();
107687
+ var require_event_category = require_event_category_b8kBSOTT();
107603
107688
  var zod = require_zod();
107604
107689
  var WELL_KNOWN_TABS = [
107605
107690
  {
@@ -109992,6 +110077,7 @@ var require_sleep_DVTaZZHP = __commonJS({
109992
110077
  motionTrigger: createSliceHandle(stateSource, binding.deviceId, "motion-trigger"),
109993
110078
  motionZones: createSliceHandle(stateSource, binding.deviceId, "motion-zones"),
109994
110079
  nativeObjectDetection: createSliceHandle(stateSource, binding.deviceId, "native-object-detection"),
110080
+ networkLink: createSliceHandle(stateSource, binding.deviceId, "network-link"),
109995
110081
  notifier: createSliceHandle(stateSource, binding.deviceId, "notifier"),
109996
110082
  numericSensor: createSliceHandle(stateSource, binding.deviceId, "numeric-sensor"),
109997
110083
  petFeeder: createSliceHandle(stateSource, binding.deviceId, "pet-feeder"),
@@ -110225,6 +110311,7 @@ var require_sleep_DVTaZZHP = __commonJS({
110225
110311
  setEnabled: (input) => dispatch("native-object-detection", "nativeObjectDetection", "setEnabled", "mutation", input),
110226
110312
  getStatus: (input) => dispatch("native-object-detection", "nativeObjectDetection", "getStatus", "query", input)
110227
110313
  },
110314
+ networkLink: { getStatus: (input) => dispatch("network-link", "networkLink", "getStatus", "query", input) },
110228
110315
  notificationRules: {
110229
110316
  listRules: (input) => dispatch("notification-rules", "notificationRules", "listRules", "query", input),
110230
110317
  getRule: (input) => dispatch("notification-rules", "notificationRules", "getRule", "query", input),
@@ -111286,8 +111373,8 @@ var require_addon = __commonJS({
111286
111373
  "../types/dist/addon.js"(exports) {
111287
111374
  "use strict";
111288
111375
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
111289
- var require_event_category = require_event_category_BaEgqJNv();
111290
- var require_sleep = require_sleep_DVTaZZHP();
111376
+ var require_event_category = require_event_category_b8kBSOTT();
111377
+ var require_sleep = require_sleep_TVipGseU();
111291
111378
  var require_err_msg = require_err_msg_COpsHMw2();
111292
111379
  var CAP_INPUT_DEFAULTS = Object.freeze({
111293
111380
  "addons": { "getLogs": { "limit": 100 } },
@@ -130247,7 +130334,7 @@ var require_dist3 = __commonJS({
130247
130334
  "use strict";
130248
130335
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
130249
130336
  var require_chunk = require_chunk_Cek0wNdY();
130250
- var require_dist10 = require_dist_DyO7xSEt();
130337
+ var require_dist10 = require_dist_B0Cf6q_P();
130251
130338
  var require_builtins_alerts_alerts_addon = require_alerts_addon();
130252
130339
  require_alerts();
130253
130340
  var require_formatter = require_formatter_DqAKDlvN();
@@ -211343,7 +211430,7 @@ var require_enums = __commonJS({
211343
211430
  "../types/dist/enums.js"(exports) {
211344
211431
  "use strict";
211345
211432
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
211346
- var require_event_category = require_event_category_BaEgqJNv();
211433
+ var require_event_category = require_event_category_b8kBSOTT();
211347
211434
  var EventSourceType = /* @__PURE__ */ (function(EventSourceType2) {
211348
211435
  EventSourceType2["Addon"] = "addon";
211349
211436
  EventSourceType2["Core"] = "core";
@@ -211363,8 +211450,8 @@ var require_dist4 = __commonJS({
211363
211450
  "../types/dist/index.js"(exports) {
211364
211451
  "use strict";
211365
211452
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
211366
- var require_event_category = require_event_category_BaEgqJNv();
211367
- var require_sleep = require_sleep_DVTaZZHP();
211453
+ var require_event_category = require_event_category_b8kBSOTT();
211454
+ var require_sleep = require_sleep_TVipGseU();
211368
211455
  var require_canonical_hash = require_canonical_hash_DNV8S5ET();
211369
211456
  var require_enums2 = require_enums();
211370
211457
  var require_err_msg = require_err_msg_COpsHMw2();
@@ -231288,6 +231375,94 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
231288
231375
  * whether persisting is worth a SQLite commit. */
231289
231376
  volatileStateFields: ["lastUpdated"]
231290
231377
  };
231378
+ var NETWORK_LINK_TYPES = [
231379
+ "wifi",
231380
+ "ethernet",
231381
+ "cellular",
231382
+ "unknown"
231383
+ ];
231384
+ var NetworkLinkStatusSchema = zod.z.object({
231385
+ /** The link the device is on. `'unknown'` = not read yet, not "no link". */
231386
+ type: zod.z.enum(NETWORK_LINK_TYPES),
231387
+ /**
231388
+ * Link quality, 0..100 inclusive, normalised by the provider from whatever
231389
+ * the firmware reports (bars, RSSI, a vendor scale). **`null` means NOT
231390
+ * KNOWN or NOT APPLICABLE** — a wired link has no signal, and a wireless
231391
+ * one whose reading has not landed must not be drawn at 0 %. Consumers
231392
+ * SKIP a null rather than coerce it.
231393
+ */
231394
+ signalPercent: zod.z.number().min(0).max(100).nullable(),
231395
+ /** Raw received signal strength in dBm, when the firmware reports one. */
231396
+ rssiDbm: zod.z.number().optional(),
231397
+ /** Network name of a wireless link, when the firmware reports it. */
231398
+ ssid: zod.z.string().optional(),
231399
+ /** Ms epoch of the last observation. Lets consumers reason about freshness. */
231400
+ lastUpdated: zod.z.number()
231401
+ });
231402
+ var NETWORK_LINK_UNKNOWN = {
231403
+ type: "unknown",
231404
+ signalPercent: null,
231405
+ lastUpdated: 0
231406
+ };
231407
+ function signalPercentFromBars(bars, maxBars) {
231408
+ if (bars === void 0 || !Number.isFinite(bars) || maxBars <= 0) return null;
231409
+ if (bars < 0 || bars > maxBars) return null;
231410
+ return Math.round(bars / maxBars * 100);
231411
+ }
231412
+ function signalPercentFromRssi(rssiDbm) {
231413
+ if (rssiDbm === void 0 || !Number.isFinite(rssiDbm) || rssiDbm > 0) return null;
231414
+ return Math.round((Math.min(-50, Math.max(-100, rssiDbm)) + 100) * 2);
231415
+ }
231416
+ var networkLinkCapability = {
231417
+ name: "network-link",
231418
+ scope: "device",
231419
+ deviceNative: true,
231420
+ mode: "singleton",
231421
+ deviceTypes: [
231422
+ require_sleep.DeviceType.Camera,
231423
+ require_sleep.DeviceType.Sensor,
231424
+ require_sleep.DeviceType.Button,
231425
+ require_sleep.DeviceType.Switch,
231426
+ require_sleep.DeviceType.Light,
231427
+ require_sleep.DeviceType.Lock,
231428
+ require_sleep.DeviceType.Siren
231429
+ ],
231430
+ methods: {},
231431
+ events: {
231432
+ /**
231433
+ * Emitted whenever the cached status changes (a link switch, a signal
231434
+ * reading that moved). Mirrored on the parent chain by the
231435
+ * DeviceEventPropagator like `battery.onStatusChanged`.
231436
+ */
231437
+ onStatusChanged: { data: zod.z.object({
231438
+ deviceId: zod.z.number(),
231439
+ status: NetworkLinkStatusSchema
231440
+ }) }
231441
+ },
231442
+ status: {
231443
+ schema: NetworkLinkStatusSchema,
231444
+ kind: "push",
231445
+ empty: NETWORK_LINK_UNKNOWN
231446
+ },
231447
+ /**
231448
+ * Runtime-state slice — every provider stores the same shape under
231449
+ * `device.runtimeState['network-link']`, read once by the badge and the
231450
+ * Home Assistant projector regardless of the driver.
231451
+ */
231452
+ runtimeState: NetworkLinkStatusSchema,
231453
+ /**
231454
+ * Runtime-state durability: **restored** — a link reading is slow to
231455
+ * change and a sleeping battery camera may not report for hours; the
231456
+ * restored slice is what the badge shows until the next read.
231457
+ *
231458
+ * See `RuntimeStateDurability`. Enforced by
231459
+ * `scripts/check-runtime-state-durability.ts`.
231460
+ */
231461
+ durability: "restored",
231462
+ /** Clock fields: written, but excluded from the compare that decides
231463
+ * whether persisting is worth a SQLite commit. */
231464
+ volatileStateFields: ["lastUpdated"]
231465
+ };
231291
231466
  var BinaryStatusSchema = zod.z.object({
231292
231467
  on: zod.z.boolean(),
231293
231468
  /** Ms epoch of the last transition. 0 if never observed. */
@@ -239371,6 +239546,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
239371
239546
  motionTrigger: motionTriggerCapability,
239372
239547
  motionZones: motionZonesCapability,
239373
239548
  nativeObjectDetection: nativeObjectDetectionCapability,
239549
+ networkLink: networkLinkCapability,
239374
239550
  notifier: notifierCapability,
239375
239551
  numericSensor: numericSensorCapability,
239376
239552
  petFeeder: petFeederCapability,
@@ -241850,6 +242026,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
241850
242026
  "motion-zones",
241851
242027
  "mqtt-broker",
241852
242028
  "native-object-detection",
242029
+ "network-link",
241853
242030
  "notifier",
241854
242031
  "numeric-sensor",
241855
242032
  "osd",
@@ -241967,6 +242144,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
241967
242144
  mqttBroker: "mqtt-broker",
241968
242145
  nativeObjectDetection: "native-object-detection",
241969
242146
  networkAccess: "network-access",
242147
+ networkLink: "network-link",
241970
242148
  networkQuality: "network-quality",
241971
242149
  nodes: "nodes",
241972
242150
  notificationOutput: "notification-output",
@@ -242391,6 +242569,10 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
242391
242569
  key: "networkAccess",
242392
242570
  name: "network-access"
242393
242571
  },
242572
+ {
242573
+ key: "networkLink",
242574
+ name: "network-link"
242575
+ },
242394
242576
  {
242395
242577
  key: "networkQuality",
242396
242578
  name: "network-quality"
@@ -242731,6 +242913,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
242731
242913
  mqttBrokerCapability,
242732
242914
  nativeObjectDetectionCapability,
242733
242915
  networkAccessCapability,
242916
+ networkLinkCapability,
242734
242917
  networkQualityCapability,
242735
242918
  nodesCapability,
242736
242919
  notificationOutputCapability,
@@ -251231,6 +251414,10 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
251231
251414
  durability: "restored",
251232
251415
  volatileFields: ["lastFetchedAt"]
251233
251416
  },
251417
+ "network-link": {
251418
+ durability: "restored",
251419
+ volatileFields: ["lastUpdated"]
251420
+ },
251234
251421
  "notifier": {
251235
251422
  durability: "session",
251236
251423
  volatileFields: []
@@ -251363,6 +251550,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
251363
251550
  "lock-control",
251364
251551
  "motion-zones",
251365
251552
  "native-object-detection",
251553
+ "network-link",
251366
251554
  "numeric-sensor",
251367
251555
  "power-meter",
251368
251556
  "presence",
@@ -255324,6 +255512,8 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
255324
255512
  exports.NC_SYSTEM_DELIVERY = NC_SYSTEM_DELIVERY;
255325
255513
  exports.NC_SYSTEM_EVENT_FILTER_KEYS = NC_SYSTEM_EVENT_FILTER_KEYS;
255326
255514
  exports.NC_TAXONOMY = NC_TAXONOMY;
255515
+ exports.NETWORK_LINK_TYPES = NETWORK_LINK_TYPES;
255516
+ exports.NETWORK_LINK_UNKNOWN = NETWORK_LINK_UNKNOWN;
255327
255517
  exports.NativeCropBboxSchema = NativeCropBboxSchema;
255328
255518
  exports.NativeCropRefSchema = NativeCropRefSchema;
255329
255519
  exports.NativeCropResultSchema = NativeCropResultSchema;
@@ -255382,6 +255572,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
255382
255572
  exports.NetworkAccessStatusSchema = NetworkAccessStatusSchema;
255383
255573
  exports.NetworkAddressSchema = NetworkAddressSchema;
255384
255574
  exports.NetworkEndpointSchema = NetworkEndpointSchema;
255575
+ exports.NetworkLinkStatusSchema = NetworkLinkStatusSchema;
255385
255576
  exports.NotificationActionIconSchema = NotificationActionIconSchema;
255386
255577
  exports.NotificationActionSchema = NotificationActionSchema;
255387
255578
  exports.NotificationFormatSchema = NotificationFormatSchema;
@@ -256041,6 +256232,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
256041
256232
  exports.mqttBrokerCapability = mqttBrokerCapability;
256042
256233
  exports.nativeObjectDetectionCapability = nativeObjectDetectionCapability;
256043
256234
  exports.networkAccessCapability = networkAccessCapability;
256235
+ exports.networkLinkCapability = networkLinkCapability;
256044
256236
  exports.networkQualityCapability = networkQualityCapability;
256045
256237
  exports.nodePin = require_sleep.nodePin;
256046
256238
  exports.nodesCapability = nodesCapability;
@@ -256154,6 +256346,8 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
256154
256346
  exports.serverManagementCapability = serverManagementCapability;
256155
256347
  exports.setByPath = setByPath;
256156
256348
  exports.settingsStoreCapability = settingsStoreCapability;
256349
+ exports.signalPercentFromBars = signalPercentFromBars;
256350
+ exports.signalPercentFromRssi = signalPercentFromRssi;
256157
256351
  exports.sleep = require_sleep.sleep;
256158
256352
  exports.sleepCancellable = require_sleep.sleepCancellable;
256159
256353
  exports.sliceActiveValue = sliceActiveValue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstack",
3
- "version": "1.2.101",
3
+ "version": "1.2.102",
4
4
  "description": "CLI tool for managing and running CamStack server",
5
5
  "keywords": [
6
6
  "camstack",