@apocaliss92/nodelink-js 0.4.23 → 0.4.26

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.
@@ -8408,9 +8408,10 @@ function parseRectTags(block) {
8408
8408
  function decodePrivacyMaskZones(xml) {
8409
8409
  const canvas = extractCanvasFromShelterXml(xml);
8410
8410
  const enable = Number(getXmlText(xml, "enable") ?? "0") === 1;
8411
- const maxNum = Number(getXmlText(xml, "maxNum") ?? "0") | 0;
8412
8411
  const trackEnable = Number(getXmlText(xml, "trackEnable") ?? "0") === 1;
8413
8412
  const maxTrackShelterNum = Number(getXmlText(xml, "maxTrackShelterNum") ?? "0") | 0;
8413
+ const rawMaxNum = getXmlText(xml, "maxNum");
8414
+ const maxNum = rawMaxNum !== void 0 ? Number(rawMaxNum) | 0 : maxTrackShelterNum > 0 ? maxTrackShelterNum : 4;
8414
8415
  const shelterList = [];
8415
8416
  const shelterListBlock = xml.match(
8416
8417
  /<shelterList>([\s\S]*?)<\/shelterList>/
@@ -11264,6 +11265,39 @@ var applyFloodlightSettingsToXml = (xml, settings) => {
11264
11265
  return modifiedXml;
11265
11266
  };
11266
11267
 
11268
+ // src/reolink/baichuan/utils/whiteLedStatusPush.ts
11269
+ var parseFloodlightStatusListPushXml = (xml) => {
11270
+ const out = [];
11271
+ const re = /<channel>\s*(\d+)\s*<\/channel>[\s\S]*?<status>\s*(\d+)\s*<\/status>/gi;
11272
+ let m;
11273
+ while ((m = re.exec(xml)) !== null) {
11274
+ const channel = Number.parseInt(m[1] ?? "", 10);
11275
+ const status = Number.parseInt(m[2] ?? "", 10);
11276
+ if (!Number.isFinite(channel) || !Number.isFinite(status)) continue;
11277
+ out.push({ channel, status });
11278
+ }
11279
+ return out;
11280
+ };
11281
+
11282
+ // src/reolink/baichuan/utils/sirenStatusPush.ts
11283
+ var parseSirenStatusListPushXml = (xml) => {
11284
+ const out = [];
11285
+ const re = /<(?:channelId|channel)>\s*(\d+)\s*<\/(?:channelId|channel)>[\s\S]*?<status>\s*(\d+)\s*<\/status>(?:[\s\S]*?<playing>\s*(\d+)\s*<\/playing>)?/gi;
11286
+ let m;
11287
+ while ((m = re.exec(xml)) !== null) {
11288
+ const channel = Number.parseInt(m[1] ?? "", 10);
11289
+ const status = Number.parseInt(m[2] ?? "", 10);
11290
+ if (!Number.isFinite(channel) || !Number.isFinite(status)) continue;
11291
+ const entry = { channel, status };
11292
+ if (m[3] !== void 0) {
11293
+ const playing = Number.parseInt(m[3], 10);
11294
+ if (Number.isFinite(playing)) entry.playing = playing;
11295
+ }
11296
+ out.push(entry);
11297
+ }
11298
+ return out;
11299
+ };
11300
+
11267
11301
  // src/reolink/baichuan/ReolinkBaichuanApi.ts
11268
11302
  var DUAL_LENS_DUAL_MOTION_MODELS = /* @__PURE__ */ new Set([
11269
11303
  "Reolink Duo PoE",
@@ -11542,7 +11576,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
11542
11576
  });
11543
11577
  client.on("push", (frame) => {
11544
11578
  const cmdId = frame.header.cmdId;
11545
- if (cmdId !== BC_CMD_ID_PUSH_VIDEO_INPUT && cmdId !== BC_CMD_ID_PUSH_SERIAL && cmdId !== BC_CMD_ID_PUSH_NET_INFO && cmdId !== BC_CMD_ID_PUSH_DINGDONG_LIST && cmdId !== BC_CMD_ID_PUSH_SLEEP_STATUS && cmdId !== BC_CMD_ID_PUSH_COORDINATE_POINT_LIST) {
11579
+ if (cmdId !== BC_CMD_ID_PUSH_VIDEO_INPUT && cmdId !== BC_CMD_ID_PUSH_SERIAL && cmdId !== BC_CMD_ID_PUSH_NET_INFO && cmdId !== BC_CMD_ID_PUSH_DINGDONG_LIST && cmdId !== BC_CMD_ID_PUSH_SLEEP_STATUS && cmdId !== BC_CMD_ID_PUSH_COORDINATE_POINT_LIST && cmdId !== BC_CMD_ID_FLOODLIGHT_STATUS_LIST && cmdId !== BC_CMD_ID_GET_AUDIO_ALARM) {
11546
11580
  return;
11547
11581
  }
11548
11582
  try {
@@ -20583,6 +20617,33 @@ ${xml}`
20583
20617
  };
20584
20618
  return;
20585
20619
  }
20620
+ if (cmdId === BC_CMD_ID_FLOODLIGHT_STATUS_LIST) {
20621
+ const entries = parseFloodlightStatusListPushXml(xml);
20622
+ if (entries.length === 0) return;
20623
+ for (const entry of entries) {
20624
+ const channel = normalizePushChannel(entry.channel) ?? channelFromHeader;
20625
+ getEntry(channel).floodlightStatus = {
20626
+ updatedAtMs: now,
20627
+ value: { status: entry.status === 1 }
20628
+ };
20629
+ }
20630
+ return;
20631
+ }
20632
+ if (cmdId === BC_CMD_ID_GET_AUDIO_ALARM) {
20633
+ const entries = parseSirenStatusListPushXml(xml);
20634
+ if (entries.length === 0) return;
20635
+ for (const entry of entries) {
20636
+ const channel = normalizePushChannel(entry.channel) ?? channelFromHeader;
20637
+ getEntry(channel).sirenStatus = {
20638
+ updatedAtMs: now,
20639
+ value: {
20640
+ status: entry.status === 1,
20641
+ ...entry.playing !== void 0 ? { playing: entry.playing === 1 } : {}
20642
+ }
20643
+ };
20644
+ }
20645
+ return;
20646
+ }
20586
20647
  }
20587
20648
  /** Read-only snapshot of cached settings pushes (cmd_id 78/79/464/484/623/723). */
20588
20649
  getSettingsPushCacheSnapshot() {
@@ -20615,6 +20676,18 @@ ${xml}`
20615
20676
  ...entry.coordinatePointList,
20616
20677
  value: { ...entry.coordinatePointList.value }
20617
20678
  }
20679
+ } : {},
20680
+ ...entry.floodlightStatus ? {
20681
+ floodlightStatus: {
20682
+ ...entry.floodlightStatus,
20683
+ value: { ...entry.floodlightStatus.value }
20684
+ }
20685
+ } : {},
20686
+ ...entry.sirenStatus ? {
20687
+ sirenStatus: {
20688
+ ...entry.sirenStatus,
20689
+ value: { ...entry.sirenStatus.value }
20690
+ }
20618
20691
  } : {}
20619
20692
  });
20620
20693
  }
@@ -20638,6 +20711,29 @@ ${xml}`
20638
20711
  getCoordinatePointListFromPushCache(channel = 0) {
20639
20712
  return this.settingsPushCache.get(channel)?.coordinatePointList;
20640
20713
  }
20714
+ /**
20715
+ * Last cmd_id 291 (FloodlightStatusList) push observed for the channel.
20716
+ * The camera emits this whenever the floodlight transitions on/off,
20717
+ * including the auto-off after the FloodlightManual duration. This is
20718
+ * the only reliable source for the current manual state because cmd 289
20719
+ * only returns the FloodlightTask config.
20720
+ *
20721
+ * Returns undefined when no push has been received yet.
20722
+ */
20723
+ getCachedFloodlightStatus(channel = 0) {
20724
+ return this.settingsPushCache.get(channel)?.floodlightStatus;
20725
+ }
20726
+ /**
20727
+ * Last cmd_id 547 (SirenStatusList) push observed for the channel.
20728
+ * Captures the actual on/off transitions including the firmware's
20729
+ * built-in auto-off after the siren playback duration expires —
20730
+ * polling cmd 547 alone can race that auto-off.
20731
+ *
20732
+ * Returns undefined when no push has been received yet.
20733
+ */
20734
+ getCachedSirenStatus(channel = 0) {
20735
+ return this.settingsPushCache.get(channel)?.sirenStatus;
20736
+ }
20641
20737
  // --------------------
20642
20738
  // PCAP-derived settings getters (typed wrappers)
20643
20739
  // --------------------
@@ -24508,4 +24604,4 @@ export {
24508
24604
  isTcpFailureThatShouldFallbackToUdp,
24509
24605
  autoDetectDeviceType
24510
24606
  };
24511
- //# sourceMappingURL=chunk-P4X5OU25.js.map
24607
+ //# sourceMappingURL=chunk-F3XCYKYT.js.map