camstack 1.2.100 → 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-REUU5U7C.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-REUU5U7C.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-Ci7Ln6Rt.js
23637
- var require_dist_Ci7Ln6Rt = __commonJS({
23638
- "../system/dist/dist-Ci7Ln6Rt.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_Ci7Ln6Rt = __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_Ci7Ln6Rt = __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_Ci7Ln6Rt = __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_Ci7Ln6Rt = __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_Ci7Ln6Rt = __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: []
@@ -59642,6 +59726,12 @@ var require_dist_Ci7Ln6Rt = __commonJS({
59642
59726
  return ReadinessTimeoutError;
59643
59727
  }
59644
59728
  });
59729
+ Object.defineProperty(exports, "RecordingStatusSchema", {
59730
+ enumerable: true,
59731
+ get: function() {
59732
+ return RecordingStatusSchema;
59733
+ }
59734
+ });
59645
59735
  Object.defineProperty(exports, "SOURCE_CAPS", {
59646
59736
  enumerable: true,
59647
59737
  get: function() {
@@ -60188,7 +60278,7 @@ var require_alerts_addon = __commonJS({
60188
60278
  [Symbol.toStringTag]: { value: "Module" }
60189
60279
  });
60190
60280
  require_chunk_Cek0wNdY();
60191
- var require_dist10 = require_dist_Ci7Ln6Rt();
60281
+ var require_dist10 = require_dist_B0Cf6q_P();
60192
60282
  function selectExpired(alerts, cutoffMs) {
60193
60283
  return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
60194
60284
  }
@@ -61007,7 +61097,7 @@ var require_console_logging = __commonJS({
61007
61097
  [Symbol.toStringTag]: { value: "Module" }
61008
61098
  });
61009
61099
  require_chunk_Cek0wNdY();
61010
- var require_dist10 = require_dist_Ci7Ln6Rt();
61100
+ var require_dist10 = require_dist_B0Cf6q_P();
61011
61101
  var require_formatter = require_formatter_DqAKDlvN();
61012
61102
  var LEVEL_RANK = {
61013
61103
  debug: 0,
@@ -61101,7 +61191,7 @@ var require_core_blocks_addon = __commonJS({
61101
61191
  "use strict";
61102
61192
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
61103
61193
  var require_chunk = require_chunk_Cek0wNdY();
61104
- var require_dist10 = require_dist_Ci7Ln6Rt();
61194
+ var require_dist10 = require_dist_B0Cf6q_P();
61105
61195
  var node_crypto = __require("crypto");
61106
61196
  var node_fs_promises = __require("fs/promises");
61107
61197
  node_fs_promises = require_chunk.__toESM(node_fs_promises);
@@ -61998,11 +62088,11 @@ var require_core_blocks = __commonJS({
61998
62088
  }
61999
62089
  });
62000
62090
 
62001
- // ../system/dist/retired-settings-keys-Ye3I5xd0.js
62002
- var require_retired_settings_keys_Ye3I5xd0 = __commonJS({
62003
- "../system/dist/retired-settings-keys-Ye3I5xd0.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) {
62004
62094
  "use strict";
62005
- var require_dist10 = require_dist_Ci7Ln6Rt();
62095
+ var require_dist10 = require_dist_B0Cf6q_P();
62006
62096
  function settingsStoreIsAuthoritativeHere(env) {
62007
62097
  const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
62008
62098
  return raw === "" || raw === "hub";
@@ -64216,8 +64306,8 @@ var require_device_manager_addon = __commonJS({
64216
64306
  [Symbol.toStringTag]: { value: "Module" }
64217
64307
  });
64218
64308
  require_chunk_Cek0wNdY();
64219
- var require_dist10 = require_dist_Ci7Ln6Rt();
64220
- var require_retired_settings_keys = require_retired_settings_keys_Ye3I5xd0();
64309
+ var require_dist10 = require_dist_B0Cf6q_P();
64310
+ var require_retired_settings_keys = require_retired_settings_keys_mP95OCUi();
64221
64311
  var node_crypto = __require("crypto");
64222
64312
  var _camstack_types_node = require_node();
64223
64313
  var JOB_HISTORY = 20;
@@ -69732,7 +69822,7 @@ var require_hub_forwarder = __commonJS({
69732
69822
  [Symbol.toStringTag]: { value: "Module" }
69733
69823
  });
69734
69824
  require_chunk_Cek0wNdY();
69735
- var require_dist10 = require_dist_Ci7Ln6Rt();
69825
+ var require_dist10 = require_dist_B0Cf6q_P();
69736
69826
  var require_formatter = require_formatter_DqAKDlvN();
69737
69827
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
69738
69828
  var HubForwarderDestination = class {
@@ -69869,7 +69959,7 @@ var require_liveness_monitor_addon = __commonJS({
69869
69959
  "use strict";
69870
69960
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
69871
69961
  require_chunk_Cek0wNdY();
69872
- var require_dist10 = require_dist_Ci7Ln6Rt();
69962
+ var require_dist10 = require_dist_B0Cf6q_P();
69873
69963
  var NO_DEVICES = "liveness:no-devices";
69874
69964
  var ALL_OFFLINE = "liveness:all-devices-offline";
69875
69965
  var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
@@ -69895,6 +69985,7 @@ var require_liveness_monitor_addon = __commonJS({
69895
69985
  if (!cam.online) continue;
69896
69986
  const silentFor = facts.nowMs - cam.lastSegmentMs;
69897
69987
  if (silentFor <= facts.staleAfterMs) continue;
69988
+ if (cam.activeMode !== null && cam.activeMode !== "continuous") continue;
69898
69989
  findings.push({
69899
69990
  id: `${NO_FOOTAGE_PREFIX}${cam.deviceId}`,
69900
69991
  severity: "error",
@@ -69968,11 +70059,16 @@ var require_liveness_monitor_addon = __commonJS({
69968
70059
  };
69969
70060
  const cameraDevices = devices.filter((d) => d.isCamera === true);
69970
70061
  const cameras = [];
69971
- for (const device of cameraDevices) cameras.push({
69972
- deviceId: device.id,
69973
- online: device.online === true,
69974
- lastSegmentMs: await this.lastSegmentMs(device.id, nowMs, staleAfterMs)
69975
- });
70062
+ for (const device of cameraDevices) {
70063
+ const lastSegmentMs = await this.lastSegmentMs(device.id, nowMs, staleAfterMs);
70064
+ const activeMode = lastSegmentMs !== null && nowMs - lastSegmentMs > staleAfterMs ? require_dist10.RecordingStatusSchema.parse(await this.ctx.api.recording.getStatus.query({ deviceId: device.id })).activeMode : null;
70065
+ cameras.push({
70066
+ deviceId: device.id,
70067
+ online: device.online === true,
70068
+ lastSegmentMs,
70069
+ activeMode
70070
+ });
70071
+ }
69976
70072
  return {
69977
70073
  nowMs,
69978
70074
  deviceCount: devices.length,
@@ -70059,7 +70155,7 @@ var require_local_auth_addon = __commonJS({
70059
70155
  [Symbol.toStringTag]: { value: "Module" }
70060
70156
  });
70061
70157
  var require_chunk = require_chunk_Cek0wNdY();
70062
- var require_dist10 = require_dist_Ci7Ln6Rt();
70158
+ var require_dist10 = require_dist_B0Cf6q_P();
70063
70159
  var node_crypto = __require("crypto");
70064
70160
  node_crypto = require_chunk.__toESM(node_crypto);
70065
70161
  var crypto$1 = __require("crypto");
@@ -77872,7 +77968,7 @@ var require_loki_logging = __commonJS({
77872
77968
  [Symbol.toStringTag]: { value: "Module" }
77873
77969
  });
77874
77970
  require_chunk_Cek0wNdY();
77875
- var require_dist10 = require_dist_Ci7Ln6Rt();
77971
+ var require_dist10 = require_dist_B0Cf6q_P();
77876
77972
  function sanitizeLabelName(raw) {
77877
77973
  const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
77878
77974
  return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
@@ -78437,7 +78533,7 @@ var require_native_metrics_addon = __commonJS({
78437
78533
  [Symbol.toStringTag]: { value: "Module" }
78438
78534
  });
78439
78535
  var require_chunk = require_chunk_Cek0wNdY();
78440
- var require_dist10 = require_dist_Ci7Ln6Rt();
78536
+ var require_dist10 = require_dist_B0Cf6q_P();
78441
78537
  var node_fs_promises = __require("fs/promises");
78442
78538
  var node_child_process = __require("child_process");
78443
78539
  var node_util = __require("util");
@@ -81021,7 +81117,7 @@ var require_filesystem_storage_addon = __commonJS({
81021
81117
  [Symbol.toStringTag]: { value: "Module" }
81022
81118
  });
81023
81119
  var require_chunk = require_chunk_Cek0wNdY();
81024
- var require_dist10 = require_dist_Ci7Ln6Rt();
81120
+ var require_dist10 = require_dist_B0Cf6q_P();
81025
81121
  var node_crypto = __require("crypto");
81026
81122
  var node_fs_promises = __require("fs/promises");
81027
81123
  var node_path = __require("path");
@@ -82137,8 +82233,8 @@ var require_sqlite_settings_addon = __commonJS({
82137
82233
  [Symbol.toStringTag]: { value: "Module" }
82138
82234
  });
82139
82235
  var require_chunk = require_chunk_Cek0wNdY();
82140
- var require_dist10 = require_dist_Ci7Ln6Rt();
82141
- var require_retired_settings_keys = require_retired_settings_keys_Ye3I5xd0();
82236
+ var require_dist10 = require_dist_B0Cf6q_P();
82237
+ var require_retired_settings_keys = require_retired_settings_keys_mP95OCUi();
82142
82238
  var node_crypto = __require("crypto");
82143
82239
  var node_fs = __require("fs");
82144
82240
  var node_module = __require("module");
@@ -84628,7 +84724,7 @@ var require_storage_orchestrator_addon = __commonJS({
84628
84724
  [Symbol.toStringTag]: { value: "Module" }
84629
84725
  });
84630
84726
  var require_chunk = require_chunk_Cek0wNdY();
84631
- var require_dist10 = require_dist_Ci7Ln6Rt();
84727
+ var require_dist10 = require_dist_B0Cf6q_P();
84632
84728
  var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
84633
84729
  var zod = require_zod();
84634
84730
  var node_crypto = __require("crypto");
@@ -87579,7 +87675,7 @@ var require_system_config_addon = __commonJS({
87579
87675
  [Symbol.toStringTag]: { value: "Module" }
87580
87676
  });
87581
87677
  require_chunk_Cek0wNdY();
87582
- var require_dist10 = require_dist_Ci7Ln6Rt();
87678
+ var require_dist10 = require_dist_B0Cf6q_P();
87583
87679
  var SECTION_TITLES = {
87584
87680
  server: "Server",
87585
87681
  auth: "Authentication"
@@ -105640,7 +105736,7 @@ var require_winston_logging = __commonJS({
105640
105736
  [Symbol.toStringTag]: { value: "Module" }
105641
105737
  });
105642
105738
  var require_chunk = require_chunk_Cek0wNdY();
105643
- var require_dist10 = require_dist_Ci7Ln6Rt();
105739
+ var require_dist10 = require_dist_B0Cf6q_P();
105644
105740
  var require_formatter = require_formatter_DqAKDlvN();
105645
105741
  var node_path = __require("path");
105646
105742
  node_path = require_chunk.__toESM(node_path);
@@ -107416,9 +107512,9 @@ ${(0, node_fs.readFileSync)(ca.caCertPath, "utf-8").trimEnd()}
107416
107512
  }
107417
107513
  });
107418
107514
 
107419
- // ../types/dist/event-category-BaEgqJNv.js
107420
- var require_event_category_BaEgqJNv = __commonJS({
107421
- "../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) {
107422
107518
  "use strict";
107423
107519
  var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
107424
107520
  EventCategory2["SystemBoot"] = "system.boot";
@@ -107501,6 +107597,7 @@ var require_event_category_BaEgqJNv = __commonJS({
107501
107597
  EventCategory2["DeviceStateChanged"] = "device.state-changed";
107502
107598
  EventCategory2["ZoneAnalyticsOccupancyChanged"] = "zone-analytics.occupancy-changed";
107503
107599
  EventCategory2["BatteryOnStatusChanged"] = "battery.onStatusChanged";
107600
+ EventCategory2["NetworkLinkOnStatusChanged"] = "network-link.onStatusChanged";
107504
107601
  EventCategory2["BatteryOnWakeStarted"] = "battery.onWakeStarted";
107505
107602
  EventCategory2["DoorbellOnPressed"] = "doorbell.onPressed";
107506
107603
  EventCategory2["EventEmitted"] = "event-emitter.event";
@@ -107583,11 +107680,11 @@ var require_event_category_BaEgqJNv = __commonJS({
107583
107680
  }
107584
107681
  });
107585
107682
 
107586
- // ../types/dist/sleep-DVTaZZHP.js
107587
- var require_sleep_DVTaZZHP = __commonJS({
107588
- "../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) {
107589
107686
  "use strict";
107590
- var require_event_category = require_event_category_BaEgqJNv();
107687
+ var require_event_category = require_event_category_b8kBSOTT();
107591
107688
  var zod = require_zod();
107592
107689
  var WELL_KNOWN_TABS = [
107593
107690
  {
@@ -109980,6 +110077,7 @@ var require_sleep_DVTaZZHP = __commonJS({
109980
110077
  motionTrigger: createSliceHandle(stateSource, binding.deviceId, "motion-trigger"),
109981
110078
  motionZones: createSliceHandle(stateSource, binding.deviceId, "motion-zones"),
109982
110079
  nativeObjectDetection: createSliceHandle(stateSource, binding.deviceId, "native-object-detection"),
110080
+ networkLink: createSliceHandle(stateSource, binding.deviceId, "network-link"),
109983
110081
  notifier: createSliceHandle(stateSource, binding.deviceId, "notifier"),
109984
110082
  numericSensor: createSliceHandle(stateSource, binding.deviceId, "numeric-sensor"),
109985
110083
  petFeeder: createSliceHandle(stateSource, binding.deviceId, "pet-feeder"),
@@ -110213,6 +110311,7 @@ var require_sleep_DVTaZZHP = __commonJS({
110213
110311
  setEnabled: (input) => dispatch("native-object-detection", "nativeObjectDetection", "setEnabled", "mutation", input),
110214
110312
  getStatus: (input) => dispatch("native-object-detection", "nativeObjectDetection", "getStatus", "query", input)
110215
110313
  },
110314
+ networkLink: { getStatus: (input) => dispatch("network-link", "networkLink", "getStatus", "query", input) },
110216
110315
  notificationRules: {
110217
110316
  listRules: (input) => dispatch("notification-rules", "notificationRules", "listRules", "query", input),
110218
110317
  getRule: (input) => dispatch("notification-rules", "notificationRules", "getRule", "query", input),
@@ -111274,8 +111373,8 @@ var require_addon = __commonJS({
111274
111373
  "../types/dist/addon.js"(exports) {
111275
111374
  "use strict";
111276
111375
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
111277
- var require_event_category = require_event_category_BaEgqJNv();
111278
- var require_sleep = require_sleep_DVTaZZHP();
111376
+ var require_event_category = require_event_category_b8kBSOTT();
111377
+ var require_sleep = require_sleep_TVipGseU();
111279
111378
  var require_err_msg = require_err_msg_COpsHMw2();
111280
111379
  var CAP_INPUT_DEFAULTS = Object.freeze({
111281
111380
  "addons": { "getLogs": { "limit": 100 } },
@@ -130235,7 +130334,7 @@ var require_dist3 = __commonJS({
130235
130334
  "use strict";
130236
130335
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
130237
130336
  var require_chunk = require_chunk_Cek0wNdY();
130238
- var require_dist10 = require_dist_Ci7Ln6Rt();
130337
+ var require_dist10 = require_dist_B0Cf6q_P();
130239
130338
  var require_builtins_alerts_alerts_addon = require_alerts_addon();
130240
130339
  require_alerts();
130241
130340
  var require_formatter = require_formatter_DqAKDlvN();
@@ -211331,7 +211430,7 @@ var require_enums = __commonJS({
211331
211430
  "../types/dist/enums.js"(exports) {
211332
211431
  "use strict";
211333
211432
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
211334
- var require_event_category = require_event_category_BaEgqJNv();
211433
+ var require_event_category = require_event_category_b8kBSOTT();
211335
211434
  var EventSourceType = /* @__PURE__ */ (function(EventSourceType2) {
211336
211435
  EventSourceType2["Addon"] = "addon";
211337
211436
  EventSourceType2["Core"] = "core";
@@ -211351,8 +211450,8 @@ var require_dist4 = __commonJS({
211351
211450
  "../types/dist/index.js"(exports) {
211352
211451
  "use strict";
211353
211452
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
211354
- var require_event_category = require_event_category_BaEgqJNv();
211355
- var require_sleep = require_sleep_DVTaZZHP();
211453
+ var require_event_category = require_event_category_b8kBSOTT();
211454
+ var require_sleep = require_sleep_TVipGseU();
211356
211455
  var require_canonical_hash = require_canonical_hash_DNV8S5ET();
211357
211456
  var require_enums2 = require_enums();
211358
211457
  var require_err_msg = require_err_msg_COpsHMw2();
@@ -231276,6 +231375,94 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
231276
231375
  * whether persisting is worth a SQLite commit. */
231277
231376
  volatileStateFields: ["lastUpdated"]
231278
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
+ };
231279
231466
  var BinaryStatusSchema = zod.z.object({
231280
231467
  on: zod.z.boolean(),
231281
231468
  /** Ms epoch of the last transition. 0 if never observed. */
@@ -239359,6 +239546,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
239359
239546
  motionTrigger: motionTriggerCapability,
239360
239547
  motionZones: motionZonesCapability,
239361
239548
  nativeObjectDetection: nativeObjectDetectionCapability,
239549
+ networkLink: networkLinkCapability,
239362
239550
  notifier: notifierCapability,
239363
239551
  numericSensor: numericSensorCapability,
239364
239552
  petFeeder: petFeederCapability,
@@ -241838,6 +242026,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
241838
242026
  "motion-zones",
241839
242027
  "mqtt-broker",
241840
242028
  "native-object-detection",
242029
+ "network-link",
241841
242030
  "notifier",
241842
242031
  "numeric-sensor",
241843
242032
  "osd",
@@ -241955,6 +242144,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
241955
242144
  mqttBroker: "mqtt-broker",
241956
242145
  nativeObjectDetection: "native-object-detection",
241957
242146
  networkAccess: "network-access",
242147
+ networkLink: "network-link",
241958
242148
  networkQuality: "network-quality",
241959
242149
  nodes: "nodes",
241960
242150
  notificationOutput: "notification-output",
@@ -242379,6 +242569,10 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
242379
242569
  key: "networkAccess",
242380
242570
  name: "network-access"
242381
242571
  },
242572
+ {
242573
+ key: "networkLink",
242574
+ name: "network-link"
242575
+ },
242382
242576
  {
242383
242577
  key: "networkQuality",
242384
242578
  name: "network-quality"
@@ -242719,6 +242913,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
242719
242913
  mqttBrokerCapability,
242720
242914
  nativeObjectDetectionCapability,
242721
242915
  networkAccessCapability,
242916
+ networkLinkCapability,
242722
242917
  networkQualityCapability,
242723
242918
  nodesCapability,
242724
242919
  notificationOutputCapability,
@@ -251219,6 +251414,10 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
251219
251414
  durability: "restored",
251220
251415
  volatileFields: ["lastFetchedAt"]
251221
251416
  },
251417
+ "network-link": {
251418
+ durability: "restored",
251419
+ volatileFields: ["lastUpdated"]
251420
+ },
251222
251421
  "notifier": {
251223
251422
  durability: "session",
251224
251423
  volatileFields: []
@@ -251351,6 +251550,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
251351
251550
  "lock-control",
251352
251551
  "motion-zones",
251353
251552
  "native-object-detection",
251553
+ "network-link",
251354
251554
  "numeric-sensor",
251355
251555
  "power-meter",
251356
251556
  "presence",
@@ -255312,6 +255512,8 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
255312
255512
  exports.NC_SYSTEM_DELIVERY = NC_SYSTEM_DELIVERY;
255313
255513
  exports.NC_SYSTEM_EVENT_FILTER_KEYS = NC_SYSTEM_EVENT_FILTER_KEYS;
255314
255514
  exports.NC_TAXONOMY = NC_TAXONOMY;
255515
+ exports.NETWORK_LINK_TYPES = NETWORK_LINK_TYPES;
255516
+ exports.NETWORK_LINK_UNKNOWN = NETWORK_LINK_UNKNOWN;
255315
255517
  exports.NativeCropBboxSchema = NativeCropBboxSchema;
255316
255518
  exports.NativeCropRefSchema = NativeCropRefSchema;
255317
255519
  exports.NativeCropResultSchema = NativeCropResultSchema;
@@ -255370,6 +255572,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
255370
255572
  exports.NetworkAccessStatusSchema = NetworkAccessStatusSchema;
255371
255573
  exports.NetworkAddressSchema = NetworkAddressSchema;
255372
255574
  exports.NetworkEndpointSchema = NetworkEndpointSchema;
255575
+ exports.NetworkLinkStatusSchema = NetworkLinkStatusSchema;
255373
255576
  exports.NotificationActionIconSchema = NotificationActionIconSchema;
255374
255577
  exports.NotificationActionSchema = NotificationActionSchema;
255375
255578
  exports.NotificationFormatSchema = NotificationFormatSchema;
@@ -256029,6 +256232,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
256029
256232
  exports.mqttBrokerCapability = mqttBrokerCapability;
256030
256233
  exports.nativeObjectDetectionCapability = nativeObjectDetectionCapability;
256031
256234
  exports.networkAccessCapability = networkAccessCapability;
256235
+ exports.networkLinkCapability = networkLinkCapability;
256032
256236
  exports.networkQualityCapability = networkQualityCapability;
256033
256237
  exports.nodePin = require_sleep.nodePin;
256034
256238
  exports.nodesCapability = nodesCapability;
@@ -256142,6 +256346,8 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
256142
256346
  exports.serverManagementCapability = serverManagementCapability;
256143
256347
  exports.setByPath = setByPath;
256144
256348
  exports.settingsStoreCapability = settingsStoreCapability;
256349
+ exports.signalPercentFromBars = signalPercentFromBars;
256350
+ exports.signalPercentFromRssi = signalPercentFromRssi;
256145
256351
  exports.sleep = require_sleep.sleep;
256146
256352
  exports.sleepCancellable = require_sleep.sleepCancellable;
256147
256353
  exports.sliceActiveValue = sliceActiveValue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstack",
3
- "version": "1.2.100",
3
+ "version": "1.2.102",
4
4
  "description": "CLI tool for managing and running CamStack server",
5
5
  "keywords": [
6
6
  "camstack",