@apocaliss92/nodelink-js 0.4.21 → 0.4.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -34,7 +34,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
34
34
  function bcHeaderHasPayloadOffset(messageClass) {
35
35
  return messageClass === BC_CLASS_MODERN_24 || messageClass === BC_CLASS_MODERN_24_ALT || messageClass === BC_CLASS_FILE_DOWNLOAD;
36
36
  }
37
- var BC_TCP_DEFAULT_PORT, BC_MAGIC, BC_MAGIC_REV, BC_XML_KEY, BC_AES_IV, BC_CLASS_LEGACY, BC_CLASS_MODERN_20, BC_CLASS_MODERN_24, BC_CLASS_MODERN_24_ALT, BC_CLASS_FILE_DOWNLOAD, BC_CMD_ID_LOGIN, BC_CMD_ID_LOGOUT, BC_CMD_ID_VIDEO, BC_CMD_ID_VIDEO_STOP, BC_CMD_ID_FILE_INFO_LIST_REPLAY, BC_CMD_ID_FILE_INFO_LIST_STOP, BC_CMD_ID_FILE_INFO_LIST_DL_VIDEO, BC_CMD_ID_FILE_INFO_LIST_DOWNLOAD, BC_CMD_ID_FILE_INFO_LIST_OPEN, BC_CMD_ID_FILE_INFO_LIST_GET, BC_CMD_ID_FILE_INFO_LIST_CLOSE, BC_CMD_ID_FIND_REC_VIDEO_OPEN, BC_CMD_ID_FIND_REC_VIDEO_GET, BC_CMD_ID_FIND_REC_VIDEO_CLOSE, BC_CMD_ID_COVER_PREVIEW, BC_CMD_ID_COVER_STANDALONE_458, BC_CMD_ID_COVER_STANDALONE_459, BC_CMD_ID_COVER_STANDALONE_460, BC_CMD_ID_COVER_STANDALONE_461, BC_CMD_ID_COVER_STANDALONE_462, BC_CMD_ID_COVER_RESPONSE, BC_CMD_ID_TALK_ABILITY, BC_CMD_ID_TALK_RESET, BC_CMD_ID_TALK_CONFIG, BC_CMD_ID_TALK, BC_CMD_ID_PTZ_CONTROL, BC_CMD_ID_PTZ_CONTROL_PRESET, BC_CMD_ID_GET_PTZ_PRESET, BC_CMD_ID_GET_PTZ_POSITION, BC_CMD_ID_GET_ZOOM_FOCUS, BC_CMD_ID_SET_ZOOM_FOCUS, BC_CMD_ID_GET_BATTERY_INFO_LIST, BC_CMD_ID_GET_BATTERY_INFO, BC_CMD_ID_UDP_KEEP_ALIVE, BC_CMD_ID_GET_PIR_INFO, BC_CMD_ID_SET_PIR_INFO, BC_CMD_ID_GET_MOTION_ALARM, BC_CMD_ID_SET_MOTION_ALARM, BC_CMD_ID_ALARM_EVENT_LIST, BC_CMD_ID_GET_AI_ALARM, BC_CMD_ID_SET_AI_ALARM, BC_CMD_ID_GET_AUDIO_ALARM, BC_CMD_ID_AUDIO_ALARM_PLAY, BC_CMD_ID_GET_WHITE_LED, BC_CMD_ID_SET_WHITE_LED_STATE, BC_CMD_ID_SET_WHITE_LED_TASK, BC_CMD_ID_FLOODLIGHT_STATUS_LIST, BC_CMD_ID_ABILITY_INFO, BC_CMD_ID_SUPPORT, BC_CMD_ID_PING, BC_CMD_ID_CHANNEL_INFO_ALL, BC_CMD_ID_GET_OSD_DATETIME, BC_CMD_ID_SET_OSD_DATETIME, BC_CMD_ID_GET_RECORD_CFG, BC_CMD_ID_GET_ABILITY_SUPPORT, BC_CMD_ID_GET_FTP_TASK, BC_CMD_ID_GET_VERSION_INFO, BC_CMD_ID_GET_RECORD, BC_CMD_ID_GET_HDD_INFO_LIST, BC_CMD_ID_GET_WIFI_SIGNAL, BC_CMD_ID_GET_WIFI, BC_CMD_ID_GET_ONLINE_USER_LIST, BC_CMD_ID_GET_DAY_RECORDS, BC_CMD_ID_GET_STREAM_INFO_LIST, BC_CMD_ID_GET_LED_STATE, BC_CMD_ID_GET_EMAIL_TASK, BC_CMD_ID_GET_AUDIO_TASK, BC_CMD_ID_GET_AUDIO_CFG, BC_CMD_ID_GET_DAY_NIGHT_THRESHOLD, BC_CMD_ID_GET_TIMELAPSE_CFG, BC_CMD_ID_GET_AI_DENOISE, BC_CMD_ID_GET_KIT_AP_CFG, BC_CMD_ID_GET_REC_ENC_CFG, BC_CMD_ID_GET_ACCESS_USER_LIST, BC_CMD_ID_GET_SLEEP_STATE, BC_CMD_ID_GET_VIDEO_INPUT, BC_CMD_ID_GET_SYSTEM_GENERAL, BC_CMD_ID_GET_SUPPORT, BC_CMD_ID_GET_AI_CFG, BC_CMD_ID_SET_AI_CFG, BC_CMD_ID_GET_SIREN_STATUS, BC_CMD_ID_SET_AUDIO_TASK, BC_CMD_ID_SET_VIDEO_INPUT, BC_CMD_ID_SET_DAY_NIGHT_THRESHOLD, BC_CMD_ID_GET_ENC, BC_CMD_ID_SET_ENC, BC_CMD_ID_GET_PRIVACY_MASK, BC_CMD_ID_SET_PRIVACY_MASK, BC_CMD_ID_SET_AI_DENOISE, BC_CMD_ID_SET_LED_STATE, BC_CMD_ID_SET_AUDIO_CFG, BC_CMD_ID_SET_RECORD, BC_CMD_ID_SET_RECORD_CFG, BC_CMD_ID_SET_EMAIL_TASK, BC_CMD_ID_GET_PUSH_TASK, BC_CMD_ID_SET_PUSH_TASK, BC_CMD_ID_GET_AUTO_FOCUS, BC_CMD_ID_SET_AUTO_FOCUS, BC_CMD_ID_GET_EMAIL, BC_CMD_ID_SET_EMAIL, BC_CMD_ID_TEST_EMAIL, BC_CMD_ID_GET_NTP, BC_CMD_ID_SET_NTP, BC_CMD_ID_SET_SYSTEM_GENERAL, BC_CMD_ID_GET_DST, BC_CMD_ID_SET_DST, BC_CMD_ID_GET_AUTO_REBOOT, BC_CMD_ID_SET_AUTO_REBOOT, BC_CMD_ID_CMD_123, BC_CMD_ID_CMD_209, BC_CMD_ID_CMD_265, BC_CMD_ID_CMD_440, BC_CMD_ID_PUSH_VIDEO_INPUT, BC_CMD_ID_PUSH_SERIAL, BC_CMD_ID_PUSH_NET_INFO, BC_CMD_ID_PUSH_DINGDONG_LIST, BC_CMD_ID_PUSH_SLEEP_STATUS, BC_CMD_ID_PUSH_COORDINATE_POINT_LIST, BC_CMD_ID_DING_DONG_CTRL, BC_CMD_ID_GET_DING_DONG_LIST, BC_CMD_ID_DING_DONG_OPT, BC_CMD_ID_GET_DING_DONG_CFG, BC_CMD_ID_SET_DING_DONG_CFG, BC_CMD_ID_QUICK_REPLY_PLAY, BC_CMD_ID_GET_DING_DONG_SILENT, BC_CMD_ID_SET_DING_DONG_SILENT;
37
+ var BC_TCP_DEFAULT_PORT, BC_MAGIC, BC_MAGIC_REV, BC_XML_KEY, BC_AES_IV, BC_CLASS_LEGACY, BC_CLASS_MODERN_20, BC_CLASS_MODERN_24, BC_CLASS_MODERN_24_ALT, BC_CLASS_FILE_DOWNLOAD, BC_CMD_ID_LOGIN, BC_CMD_ID_LOGOUT, BC_CMD_ID_VIDEO, BC_CMD_ID_VIDEO_STOP, BC_CMD_ID_FILE_INFO_LIST_REPLAY, BC_CMD_ID_FILE_INFO_LIST_STOP, BC_CMD_ID_FILE_INFO_LIST_DL_VIDEO, BC_CMD_ID_FILE_INFO_LIST_DOWNLOAD, BC_CMD_ID_FILE_INFO_LIST_OPEN, BC_CMD_ID_FILE_INFO_LIST_GET, BC_CMD_ID_FILE_INFO_LIST_CLOSE, BC_CMD_ID_FIND_REC_VIDEO_OPEN, BC_CMD_ID_FIND_REC_VIDEO_GET, BC_CMD_ID_FIND_REC_VIDEO_CLOSE, BC_CMD_ID_COVER_PREVIEW, BC_CMD_ID_COVER_STANDALONE_458, BC_CMD_ID_COVER_STANDALONE_459, BC_CMD_ID_COVER_STANDALONE_460, BC_CMD_ID_COVER_STANDALONE_461, BC_CMD_ID_COVER_STANDALONE_462, BC_CMD_ID_COVER_RESPONSE, BC_CMD_ID_TALK_ABILITY, BC_CMD_ID_TALK_RESET, BC_CMD_ID_TALK_CONFIG, BC_CMD_ID_TALK, BC_CMD_ID_PTZ_CONTROL, BC_CMD_ID_PTZ_CONTROL_PRESET, BC_CMD_ID_GET_PTZ_PRESET, BC_CMD_ID_GET_PTZ_POSITION, BC_CMD_ID_GET_ZOOM_FOCUS, BC_CMD_ID_SET_ZOOM_FOCUS, BC_CMD_ID_GET_BATTERY_INFO_LIST, BC_CMD_ID_GET_BATTERY_INFO, BC_CMD_ID_UDP_KEEP_ALIVE, BC_CMD_ID_GET_PIR_INFO, BC_CMD_ID_SET_PIR_INFO, BC_CMD_ID_GET_MOTION_ALARM, BC_CMD_ID_SET_MOTION_ALARM, BC_CMD_ID_ALARM_EVENT_LIST, BC_CMD_ID_GET_AI_ALARM, BC_CMD_ID_SET_AI_ALARM, BC_CMD_ID_GET_AUDIO_ALARM, BC_CMD_ID_AUDIO_ALARM_PLAY, BC_CMD_ID_GET_WHITE_LED, BC_CMD_ID_SET_WHITE_LED_STATE, BC_CMD_ID_SET_WHITE_LED_TASK, BC_CMD_ID_FLOODLIGHT_STATUS_LIST, BC_CMD_ID_ABILITY_INFO, BC_CMD_ID_SUPPORT, BC_CMD_ID_PING, BC_CMD_ID_GET_SNAPSHOT, BC_CMD_ID_GET_UID, BC_CMD_ID_CHANNEL_INFO_ALL, BC_CMD_ID_GET_OSD_DATETIME, BC_CMD_ID_SET_OSD_DATETIME, BC_CMD_ID_GET_RECORD_CFG, BC_CMD_ID_GET_ABILITY_SUPPORT, BC_CMD_ID_GET_FTP_TASK, BC_CMD_ID_GET_VERSION_INFO, BC_CMD_ID_GET_RECORD, BC_CMD_ID_GET_HDD_INFO_LIST, BC_CMD_ID_GET_WIFI_SIGNAL, BC_CMD_ID_GET_WIFI, BC_CMD_ID_GET_ONLINE_USER_LIST, BC_CMD_ID_GET_DAY_RECORDS, BC_CMD_ID_GET_STREAM_INFO_LIST, BC_CMD_ID_GET_LED_STATE, BC_CMD_ID_GET_EMAIL_TASK, BC_CMD_ID_GET_AUDIO_TASK, BC_CMD_ID_GET_AUDIO_CFG, BC_CMD_ID_GET_DAY_NIGHT_THRESHOLD, BC_CMD_ID_GET_TIMELAPSE_CFG, BC_CMD_ID_GET_AI_DENOISE, BC_CMD_ID_GET_KIT_AP_CFG, BC_CMD_ID_GET_REC_ENC_CFG, BC_CMD_ID_GET_ACCESS_USER_LIST, BC_CMD_ID_GET_SLEEP_STATE, BC_CMD_ID_GET_VIDEO_INPUT, BC_CMD_ID_GET_SYSTEM_GENERAL, BC_CMD_ID_GET_SUPPORT, BC_CMD_ID_GET_AI_CFG, BC_CMD_ID_SET_AI_CFG, BC_CMD_ID_GET_SIREN_STATUS, BC_CMD_ID_SET_AUDIO_TASK, BC_CMD_ID_SET_VIDEO_INPUT, BC_CMD_ID_SET_DAY_NIGHT_THRESHOLD, BC_CMD_ID_GET_ENC, BC_CMD_ID_SET_ENC, BC_CMD_ID_GET_PRIVACY_MASK, BC_CMD_ID_SET_PRIVACY_MASK, BC_CMD_ID_SET_AI_DENOISE, BC_CMD_ID_SET_LED_STATE, BC_CMD_ID_SET_AUDIO_CFG, BC_CMD_ID_SET_RECORD, BC_CMD_ID_SET_RECORD_CFG, BC_CMD_ID_SET_EMAIL_TASK, BC_CMD_ID_GET_PUSH_TASK, BC_CMD_ID_SET_PUSH_TASK, BC_CMD_ID_GET_AUTO_FOCUS, BC_CMD_ID_SET_AUTO_FOCUS, BC_CMD_ID_GET_EMAIL, BC_CMD_ID_SET_EMAIL, BC_CMD_ID_TEST_EMAIL, BC_CMD_ID_GET_NTP, BC_CMD_ID_SET_NTP, BC_CMD_ID_SET_SYSTEM_GENERAL, BC_CMD_ID_GET_DST, BC_CMD_ID_SET_DST, BC_CMD_ID_GET_AUTO_REBOOT, BC_CMD_ID_SET_AUTO_REBOOT, BC_CMD_ID_CMD_123, BC_CMD_ID_CMD_209, BC_CMD_ID_CMD_265, BC_CMD_ID_CMD_440, BC_CMD_ID_PUSH_VIDEO_INPUT, BC_CMD_ID_PUSH_SERIAL, BC_CMD_ID_PUSH_NET_INFO, BC_CMD_ID_PUSH_DINGDONG_LIST, BC_CMD_ID_PUSH_SLEEP_STATUS, BC_CMD_ID_PUSH_COORDINATE_POINT_LIST, BC_CMD_ID_DING_DONG_CTRL, BC_CMD_ID_GET_DING_DONG_LIST, BC_CMD_ID_DING_DONG_OPT, BC_CMD_ID_GET_DING_DONG_CFG, BC_CMD_ID_SET_DING_DONG_CFG, BC_CMD_ID_QUICK_REPLY_PLAY, BC_CMD_ID_GET_DING_DONG_SILENT, BC_CMD_ID_SET_DING_DONG_SILENT;
38
38
  var init_constants = __esm({
39
39
  "src/protocol/constants.ts"() {
40
40
  "use strict";
@@ -107,6 +107,8 @@ var init_constants = __esm({
107
107
  BC_CMD_ID_ABILITY_INFO = 151;
108
108
  BC_CMD_ID_SUPPORT = 199;
109
109
  BC_CMD_ID_PING = 93;
110
+ BC_CMD_ID_GET_SNAPSHOT = 109;
111
+ BC_CMD_ID_GET_UID = 114;
110
112
  BC_CMD_ID_CHANNEL_INFO_ALL = 145;
111
113
  BC_CMD_ID_GET_OSD_DATETIME = 44;
112
114
  BC_CMD_ID_SET_OSD_DATETIME = 45;
@@ -8236,10 +8238,12 @@ __export(index_exports, {
8236
8238
  BC_CMD_ID_GET_REC_ENC_CFG: () => BC_CMD_ID_GET_REC_ENC_CFG,
8237
8239
  BC_CMD_ID_GET_SIREN_STATUS: () => BC_CMD_ID_GET_SIREN_STATUS,
8238
8240
  BC_CMD_ID_GET_SLEEP_STATE: () => BC_CMD_ID_GET_SLEEP_STATE,
8241
+ BC_CMD_ID_GET_SNAPSHOT: () => BC_CMD_ID_GET_SNAPSHOT,
8239
8242
  BC_CMD_ID_GET_STREAM_INFO_LIST: () => BC_CMD_ID_GET_STREAM_INFO_LIST,
8240
8243
  BC_CMD_ID_GET_SUPPORT: () => BC_CMD_ID_GET_SUPPORT,
8241
8244
  BC_CMD_ID_GET_SYSTEM_GENERAL: () => BC_CMD_ID_GET_SYSTEM_GENERAL,
8242
8245
  BC_CMD_ID_GET_TIMELAPSE_CFG: () => BC_CMD_ID_GET_TIMELAPSE_CFG,
8246
+ BC_CMD_ID_GET_UID: () => BC_CMD_ID_GET_UID,
8243
8247
  BC_CMD_ID_GET_VERSION_INFO: () => BC_CMD_ID_GET_VERSION_INFO,
8244
8248
  BC_CMD_ID_GET_VIDEO_INPUT: () => BC_CMD_ID_GET_VIDEO_INPUT,
8245
8249
  BC_CMD_ID_GET_WHITE_LED: () => BC_CMD_ID_GET_WHITE_LED,
@@ -8313,6 +8317,7 @@ __export(index_exports, {
8313
8317
  BcUdpStream: () => BcUdpStream,
8314
8318
  CompositeRtspServer: () => CompositeRtspServer,
8315
8319
  CompositeStream: () => CompositeStream,
8320
+ DEFAULT_SHELTER_CANVAS: () => DEFAULT_SHELTER_CANVAS,
8316
8321
  DUAL_LENS_DUAL_MOTION_MODELS: () => DUAL_LENS_DUAL_MOTION_MODELS,
8317
8322
  DUAL_LENS_MODELS: () => DUAL_LENS_MODELS,
8318
8323
  DUAL_LENS_SINGLE_MOTION_MODELS: () => DUAL_LENS_SINGLE_MOTION_MODELS,
@@ -8385,8 +8390,11 @@ __export(index_exports, {
8385
8390
  createTaggedLogger: () => createTaggedLogger,
8386
8391
  decideSleepInferenceTransition: () => decideSleepInferenceTransition,
8387
8392
  decideVideoclipTranscodeMode: () => decideVideoclipTranscodeMode,
8393
+ decodeAiDetectCfg: () => decodeAiDetectCfg,
8388
8394
  decodeHeader: () => decodeHeader,
8389
8395
  decodeMotionScopeBitmap: () => decodeMotionScopeBitmap,
8396
+ decodePrivacyMaskZones: () => decodePrivacyMaskZones,
8397
+ decodeShelterCoord: () => decodeShelterCoord,
8390
8398
  deriveAesKey: () => deriveAesKey,
8391
8399
  detectIosClient: () => detectIosClient,
8392
8400
  detectVideoCodecFromNal: () => detectVideoCodecFromNal,
@@ -8400,7 +8408,12 @@ __export(index_exports, {
8400
8408
  discoverViaUdpDirect: () => discoverViaUdpDirect,
8401
8409
  encodeHeader: () => encodeHeader,
8402
8410
  encodeMotionScopeBitmap: () => encodeMotionScopeBitmap,
8411
+ encodeMotionSensitivityListXml: () => encodeMotionSensitivityListXml,
8412
+ encodeShelterCoord: () => encodeShelterCoord,
8413
+ encodeShelterListXml: () => encodeShelterListXml,
8414
+ encodeTrackShelterListXml: () => encodeTrackShelterListXml,
8403
8415
  ensureXmlHeader: () => ensureXmlHeader,
8416
+ extractCanvasFromShelterXml: () => extractCanvasFromShelterXml,
8404
8417
  extractH264ParamSetsFromAccessUnit: () => extractH264ParamSetsFromAccessUnit,
8405
8418
  extractH265ParamSetsFromAccessUnit: () => extractH265ParamSetsFromAccessUnit,
8406
8419
  extractPpsFromAnnexB: () => extractPpsFromAnnexB,
@@ -8441,7 +8454,10 @@ __export(index_exports, {
8441
8454
  parseBcMedia: () => parseBcMedia,
8442
8455
  parseRecordingFileName: () => parseRecordingFileName,
8443
8456
  parseSupportXml: () => parseSupportXml,
8457
+ patchAiDetectCfgXml: () => patchAiDetectCfgXml,
8458
+ patchMotionSensitivityListXml: () => patchMotionSensitivityListXml,
8444
8459
  patchNestedTag: () => patchNestedTag,
8460
+ patchShelterXml: () => patchShelterXml,
8445
8461
  printNvrDiagnostics: () => printNvrDiagnostics,
8446
8462
  runAllDiagnosticsConsecutively: () => runAllDiagnosticsConsecutively,
8447
8463
  runMultifocalDiagnosticsConsecutively: () => runMultifocalDiagnosticsConsecutively,
@@ -17101,15 +17117,14 @@ var getAiStateViaGetAiAlarm = async (params) => {
17101
17117
  0
17102
17118
  );
17103
17119
  };
17120
+ const isSupportedResponse = (xml) => {
17121
+ return /<AiDetectCfg[\s>]/i.test(xml) && getXmlText(xml, "type") != null;
17122
+ };
17104
17123
  for (const type of candidateTypes) {
17105
17124
  try {
17106
17125
  const xml = await tryOnce(type, ch);
17107
- if (xml) {
17108
- return {
17109
- channel: ch,
17110
- alarm_state: Number(getXmlText(xml, "alarm_state") ?? "0"),
17111
- support: Number(getXmlText(xml, "support") ?? "0")
17112
- };
17126
+ if (xml && isSupportedResponse(xml)) {
17127
+ return { channel: ch, alarm_state: 0, support: 1 };
17113
17128
  }
17114
17129
  } catch (e) {
17115
17130
  if (looksLikeConnectionDrop(e)) throw e;
@@ -17119,12 +17134,8 @@ var getAiStateViaGetAiAlarm = async (params) => {
17119
17134
  for (const type of candidateTypes) {
17120
17135
  try {
17121
17136
  const xml = await tryOnce(type, void 0);
17122
- if (xml) {
17123
- return {
17124
- channel: ch,
17125
- alarm_state: Number(getXmlText(xml, "alarm_state") ?? "0"),
17126
- support: Number(getXmlText(xml, "support") ?? "0")
17127
- };
17137
+ if (xml && isSupportedResponse(xml)) {
17138
+ return { channel: ch, alarm_state: 0, support: 1 };
17128
17139
  }
17129
17140
  } catch (e) {
17130
17141
  if (looksLikeConnectionDrop(e)) throw e;
@@ -17624,6 +17635,354 @@ var calculatePipOverlayPosition = (params) => {
17624
17635
  };
17625
17636
  };
17626
17637
 
17638
+ // src/reolink/baichuan/utils/privacyMask.ts
17639
+ init_xml();
17640
+ var DEFAULT_SHELTER_CANVAS = {
17641
+ width: 540,
17642
+ height: 304
17643
+ };
17644
+ function decodeShelterCoord(value) {
17645
+ const v = (value | 0) >>> 0;
17646
+ return { pixel: v >>> 16, canvas: v & 65535 };
17647
+ }
17648
+ function encodeShelterCoord(pixel, canvas) {
17649
+ const p = Math.min(65535, Math.max(0, Math.floor(pixel)));
17650
+ const c = Math.min(65535, Math.max(0, Math.floor(canvas)));
17651
+ return p * 65536 + c;
17652
+ }
17653
+ function clamp01(value) {
17654
+ if (!Number.isFinite(value)) return 0;
17655
+ if (value < 0) return 0;
17656
+ if (value > 1) return 1;
17657
+ return value;
17658
+ }
17659
+ function decodeRect(raw, canvas, idKey) {
17660
+ const xRaw = Number(raw["topLeftX"] ?? 0) | 0;
17661
+ const yRaw = Number(raw["topLeftY"] ?? 0) | 0;
17662
+ const wRaw = Number(raw["width"] ?? 0) | 0;
17663
+ const hRaw = Number(raw["height"] ?? 0) | 0;
17664
+ const xPixel = decodeShelterCoord(xRaw).pixel;
17665
+ const yPixel = decodeShelterCoord(yRaw).pixel;
17666
+ const wPixel = decodeShelterCoord(wRaw).pixel;
17667
+ const hPixel = decodeShelterCoord(hRaw).pixel;
17668
+ return {
17669
+ id: Number(raw[idKey] ?? 0) | 0,
17670
+ enable: Number(raw["enable"] ?? 0) === 1,
17671
+ layer: Number(raw["layer"] ?? 0) | 0,
17672
+ color: Number(raw["color"] ?? 0) | 0,
17673
+ x: canvas.width > 0 ? xPixel / canvas.width : 0,
17674
+ y: canvas.height > 0 ? yPixel / canvas.height : 0,
17675
+ width: canvas.width > 0 ? wPixel / canvas.width : 0,
17676
+ height: canvas.height > 0 ? hPixel / canvas.height : 0
17677
+ };
17678
+ }
17679
+ function extractCanvasFromShelterXml(xml) {
17680
+ const xMatch = xml.match(/<topLeftX>(\d+)<\/topLeftX>/g) ?? [];
17681
+ const yMatch = xml.match(/<topLeftY>(\d+)<\/topLeftY>/g) ?? [];
17682
+ let canvasX = 0;
17683
+ let canvasY = 0;
17684
+ for (const tag of xMatch) {
17685
+ const v = Number(tag.replace(/<\/?topLeftX>/g, "")) | 0;
17686
+ if (v > 0) {
17687
+ canvasX = v & 65535;
17688
+ break;
17689
+ }
17690
+ }
17691
+ for (const tag of yMatch) {
17692
+ const v = Number(tag.replace(/<\/?topLeftY>/g, "")) | 0;
17693
+ if (v > 0) {
17694
+ canvasY = v & 65535;
17695
+ break;
17696
+ }
17697
+ }
17698
+ return {
17699
+ width: canvasX > 0 ? canvasX : DEFAULT_SHELTER_CANVAS.width,
17700
+ height: canvasY > 0 ? canvasY : DEFAULT_SHELTER_CANVAS.height
17701
+ };
17702
+ }
17703
+ function parseRectTags(block) {
17704
+ const out = {};
17705
+ const grab = (tag) => {
17706
+ const m = block.match(new RegExp(`<${tag}>([^<]*)<\\/${tag}>`));
17707
+ if (m && m[1] !== void 0) out[tag] = m[1];
17708
+ };
17709
+ grab("id");
17710
+ grab("name");
17711
+ grab("enable");
17712
+ grab("layer");
17713
+ grab("color");
17714
+ grab("topLeftX");
17715
+ grab("topLeftY");
17716
+ grab("width");
17717
+ grab("height");
17718
+ grab("pPos");
17719
+ grab("tPos");
17720
+ grab("zPos");
17721
+ return out;
17722
+ }
17723
+ function decodePrivacyMaskZones(xml) {
17724
+ const canvas = extractCanvasFromShelterXml(xml);
17725
+ const enable = Number(getXmlText(xml, "enable") ?? "0") === 1;
17726
+ const maxNum = Number(getXmlText(xml, "maxNum") ?? "0") | 0;
17727
+ const trackEnable = Number(getXmlText(xml, "trackEnable") ?? "0") === 1;
17728
+ const maxTrackShelterNum = Number(getXmlText(xml, "maxTrackShelterNum") ?? "0") | 0;
17729
+ const shelterList = [];
17730
+ const shelterListBlock = xml.match(
17731
+ /<shelterList>([\s\S]*?)<\/shelterList>/
17732
+ )?.[1];
17733
+ if (shelterListBlock) {
17734
+ const blocks = shelterListBlock.matchAll(
17735
+ /<Shelter>([\s\S]*?)<\/Shelter>/g
17736
+ );
17737
+ for (const m of blocks) {
17738
+ const tags = parseRectTags(m[1] ?? "");
17739
+ const decoded = decodeRect(tags, canvas, "id");
17740
+ shelterList.push(decoded);
17741
+ }
17742
+ }
17743
+ const trackShelterList = [];
17744
+ const trackBlock = xml.match(
17745
+ /<trackShelterList>([\s\S]*?)<\/trackShelterList>/
17746
+ )?.[1];
17747
+ if (trackBlock) {
17748
+ const blocks = trackBlock.matchAll(
17749
+ /<trackShelter>([\s\S]*?)<\/trackShelter>/g
17750
+ );
17751
+ for (const m of blocks) {
17752
+ const tags = parseRectTags(m[1] ?? "");
17753
+ const base = decodeRect(
17754
+ tags,
17755
+ canvas,
17756
+ "name"
17757
+ );
17758
+ trackShelterList.push({
17759
+ ...base,
17760
+ pPos: Number(tags.pPos ?? -1) | 0,
17761
+ tPos: Number(tags.tPos ?? -1) | 0,
17762
+ zPos: Number(tags.zPos ?? -1) | 0
17763
+ });
17764
+ }
17765
+ }
17766
+ return {
17767
+ enable,
17768
+ maxNum,
17769
+ shelterList,
17770
+ trackEnable,
17771
+ maxTrackShelterNum,
17772
+ trackShelterList,
17773
+ canvas
17774
+ };
17775
+ }
17776
+ function denormalizeRect(rect, canvas) {
17777
+ const xPx = Math.min(canvas.width, Math.round(clamp01(rect.x) * canvas.width));
17778
+ const yPx = Math.min(canvas.height, Math.round(clamp01(rect.y) * canvas.height));
17779
+ const wPx = Math.min(
17780
+ canvas.width - xPx,
17781
+ Math.round(clamp01(rect.width) * canvas.width)
17782
+ );
17783
+ const hPx = Math.min(
17784
+ canvas.height - yPx,
17785
+ Math.round(clamp01(rect.height) * canvas.height)
17786
+ );
17787
+ return {
17788
+ topLeftX: encodeShelterCoord(xPx, canvas.width),
17789
+ topLeftY: encodeShelterCoord(yPx, canvas.height),
17790
+ width: encodeShelterCoord(wPx, canvas.width),
17791
+ height: encodeShelterCoord(hPx, canvas.height)
17792
+ };
17793
+ }
17794
+ function encodeShelterListXml(rects, canvas, maxNum) {
17795
+ if (maxNum <= 0) return "<shelterList />";
17796
+ const sorted = [...rects].sort((a, b) => a.id - b.id).slice(0, maxNum);
17797
+ const byId = new Map(sorted.map((r) => [r.id, r]));
17798
+ const parts = [];
17799
+ parts.push("<shelterList>");
17800
+ for (let id = 0; id < maxNum; id++) {
17801
+ const r = byId.get(id);
17802
+ if (r && r.enable) {
17803
+ const { topLeftX, topLeftY, width, height } = denormalizeRect(r, canvas);
17804
+ parts.push(
17805
+ `<Shelter><id>${id}</id><enable>1</enable><layer>${r.layer | 0}</layer><color>${r.color | 0}</color><topLeftX>${topLeftX}</topLeftX><topLeftY>${topLeftY}</topLeftY><width>${width}</width><height>${height}</height></Shelter>`
17806
+ );
17807
+ } else if (r) {
17808
+ const { topLeftX, topLeftY, width, height } = denormalizeRect(r, canvas);
17809
+ parts.push(
17810
+ `<Shelter><id>${id}</id><enable>0</enable><layer>${r.layer | 0}</layer><color>${r.color | 0}</color><topLeftX>${topLeftX}</topLeftX><topLeftY>${topLeftY}</topLeftY><width>${width}</width><height>${height}</height></Shelter>`
17811
+ );
17812
+ } else {
17813
+ parts.push(
17814
+ `<Shelter><id>${id}</id><enable>0</enable><layer>0</layer><color>0</color><topLeftX>0</topLeftX><topLeftY>0</topLeftY><width>0</width><height>0</height></Shelter>`
17815
+ );
17816
+ }
17817
+ }
17818
+ parts.push("</shelterList>");
17819
+ return parts.join("");
17820
+ }
17821
+ function encodeTrackShelterListXml(rects, canvas, maxNum) {
17822
+ if (maxNum <= 0) return "<trackShelterList />";
17823
+ const sorted = [...rects].sort((a, b) => a.id - b.id).slice(0, maxNum);
17824
+ const byId = new Map(sorted.map((r) => [r.id, r]));
17825
+ const parts = [];
17826
+ parts.push("<trackShelterList>");
17827
+ for (let id = 0; id < maxNum; id++) {
17828
+ const r = byId.get(id);
17829
+ if (r) {
17830
+ const { topLeftX, topLeftY, width, height } = denormalizeRect(r, canvas);
17831
+ parts.push(
17832
+ `<trackShelter><name>${id}</name><enable>${r.enable ? 1 : 0}</enable><layer>${r.layer | 0}</layer><color>${r.color | 0}</color><topLeftX>${topLeftX}</topLeftX><topLeftY>${topLeftY}</topLeftY><width>${width}</width><height>${height}</height><pPos>${r.pPos | 0}</pPos><tPos>${r.tPos | 0}</tPos><zPos>${r.zPos | 0}</zPos></trackShelter>`
17833
+ );
17834
+ } else {
17835
+ parts.push(
17836
+ `<trackShelter><name>${id}</name><enable>0</enable><layer>0</layer><color>0</color><topLeftX>0</topLeftX><topLeftY>0</topLeftY><width>0</width><height>0</height><pPos>-1</pPos><tPos>-1</tPos><zPos>-1</zPos></trackShelter>`
17837
+ );
17838
+ }
17839
+ }
17840
+ parts.push("</trackShelterList>");
17841
+ return parts.join("");
17842
+ }
17843
+ function patchShelterXml(shelterXml, patch, canvas, maxNum, maxTrackShelterNum) {
17844
+ let out = shelterXml;
17845
+ if (patch.enable !== void 0) {
17846
+ out = out.replace(
17847
+ /<enable>[^<]*<\/enable>/,
17848
+ `<enable>${patch.enable ? 1 : 0}</enable>`
17849
+ );
17850
+ }
17851
+ if (patch.shelterList !== void 0) {
17852
+ const fragment = encodeShelterListXml(patch.shelterList, canvas, maxNum);
17853
+ out = out.replace(/<shelterList[\s\S]*?(?:\/>|<\/shelterList>)/, fragment);
17854
+ }
17855
+ if (patch.trackEnable !== void 0) {
17856
+ out = out.replace(
17857
+ /<trackEnable>[^<]*<\/trackEnable>/,
17858
+ `<trackEnable>${patch.trackEnable ? 1 : 0}</trackEnable>`
17859
+ );
17860
+ }
17861
+ if (patch.trackShelterList !== void 0) {
17862
+ const fragment = encodeTrackShelterListXml(
17863
+ patch.trackShelterList,
17864
+ canvas,
17865
+ maxTrackShelterNum
17866
+ );
17867
+ out = out.replace(
17868
+ /<trackShelterList[\s\S]*?(?:\/>|<\/trackShelterList>)/,
17869
+ fragment
17870
+ );
17871
+ }
17872
+ return out;
17873
+ }
17874
+
17875
+ // src/reolink/baichuan/utils/aiDetectCfg.ts
17876
+ init_xml();
17877
+ function decodeAiDetectCfg(xml) {
17878
+ const type = getXmlText(xml, "type");
17879
+ if (type == null) throw new Error("AiDetectCfg: missing <type>");
17880
+ return {
17881
+ chn: Number(getXmlText(xml, "chn") ?? "0") | 0,
17882
+ type,
17883
+ sensitivity: Number(getXmlText(xml, "sensitivity") ?? "0") | 0,
17884
+ stayTime: Number(getXmlText(xml, "stayTime") ?? "0") | 0,
17885
+ minTargetWidth: Number(getXmlText(xml, "minTargetWidth") ?? "0"),
17886
+ minTargetHeight: Number(getXmlText(xml, "minTargetHeight") ?? "0"),
17887
+ maxTargetWidth: Number(getXmlText(xml, "maxTargetWidth") ?? "0"),
17888
+ maxTargetHeight: Number(getXmlText(xml, "maxTargetHeight") ?? "0"),
17889
+ width: Number(getXmlText(xml, "width") ?? "0") | 0,
17890
+ height: Number(getXmlText(xml, "height") ?? "0") | 0,
17891
+ area: getXmlText(xml, "area") ?? ""
17892
+ };
17893
+ }
17894
+ function clamp012(value) {
17895
+ if (!Number.isFinite(value)) return 0;
17896
+ if (value < 0) return 0;
17897
+ if (value > 1) return 1;
17898
+ return value;
17899
+ }
17900
+ function fmtFraction(value) {
17901
+ const v = clamp012(value);
17902
+ const e = v.toExponential(6);
17903
+ return e.replace(/e([+-])(\d)$/, "e$10$2");
17904
+ }
17905
+ function patchAiDetectCfgXml(currentXml, patch) {
17906
+ let out = currentXml;
17907
+ if (patch.sensitivity !== void 0) {
17908
+ out = out.replace(
17909
+ /<sensitivity>[^<]*<\/sensitivity>/,
17910
+ `<sensitivity>${patch.sensitivity | 0}</sensitivity>`
17911
+ );
17912
+ }
17913
+ if (patch.stayTime !== void 0) {
17914
+ out = out.replace(
17915
+ /<stayTime>[^<]*<\/stayTime>/,
17916
+ `<stayTime>${patch.stayTime | 0}</stayTime>`
17917
+ );
17918
+ }
17919
+ if (patch.minTargetWidth !== void 0) {
17920
+ out = out.replace(
17921
+ /<minTargetWidth>[^<]*<\/minTargetWidth>/,
17922
+ `<minTargetWidth>${fmtFraction(patch.minTargetWidth)}</minTargetWidth>`
17923
+ );
17924
+ }
17925
+ if (patch.minTargetHeight !== void 0) {
17926
+ out = out.replace(
17927
+ /<minTargetHeight>[^<]*<\/minTargetHeight>/,
17928
+ `<minTargetHeight>${fmtFraction(patch.minTargetHeight)}</minTargetHeight>`
17929
+ );
17930
+ }
17931
+ if (patch.maxTargetWidth !== void 0) {
17932
+ out = out.replace(
17933
+ /<maxTargetWidth>[^<]*<\/maxTargetWidth>/,
17934
+ `<maxTargetWidth>${fmtFraction(patch.maxTargetWidth)}</maxTargetWidth>`
17935
+ );
17936
+ }
17937
+ if (patch.maxTargetHeight !== void 0) {
17938
+ out = out.replace(
17939
+ /<maxTargetHeight>[^<]*<\/maxTargetHeight>/,
17940
+ `<maxTargetHeight>${fmtFraction(patch.maxTargetHeight)}</maxTargetHeight>`
17941
+ );
17942
+ }
17943
+ if (patch.area !== void 0) {
17944
+ out = out.replace(
17945
+ /<area>[^<]*<\/area>/,
17946
+ `<area>${patch.area}</area>`
17947
+ );
17948
+ }
17949
+ return out;
17950
+ }
17951
+
17952
+ // src/reolink/baichuan/utils/motionSensitivity.ts
17953
+ function clampInt(value, min, max) {
17954
+ if (!Number.isFinite(value)) return min;
17955
+ return Math.min(max, Math.max(min, Math.floor(value)));
17956
+ }
17957
+ function clampSensitivity(value) {
17958
+ return clampInt(value, 0, 50);
17959
+ }
17960
+ function clampHour(value) {
17961
+ return clampInt(value, 0, 23);
17962
+ }
17963
+ function clampMinute(value) {
17964
+ return clampInt(value, 0, 59);
17965
+ }
17966
+ function encodeMotionSensitivityListXml(bands) {
17967
+ if (bands.length === 0) return "<sensitivityInfoList />";
17968
+ const sorted = [...bands].sort((a, b) => a.id - b.id);
17969
+ const parts = ["<sensitivityInfoList>"];
17970
+ for (const b of sorted) {
17971
+ parts.push(
17972
+ `<sensitivityInfo><id>${b.id | 0}</id><sensitivity>${clampSensitivity(b.sensitivity)}</sensitivity><beginHour>${clampHour(b.beginHour)}</beginHour><beginMinute>${clampMinute(b.beginMinute)}</beginMinute><endHour>${clampHour(b.endHour)}</endHour><endMinute>${clampMinute(b.endMinute)}</endMinute></sensitivityInfo>`
17973
+ );
17974
+ }
17975
+ parts.push("</sensitivityInfoList>");
17976
+ return parts.join("");
17977
+ }
17978
+ function patchMotionSensitivityListXml(currentXml, bands) {
17979
+ const fragment = encodeMotionSensitivityListXml(bands);
17980
+ return currentXml.replace(
17981
+ /<sensitivityInfoList[\s\S]*?(?:\/>|<\/sensitivityInfoList>)/,
17982
+ fragment
17983
+ );
17984
+ }
17985
+
17627
17986
  // src/reolink/baichuan/utils/ptz.ts
17628
17987
  init_xml();
17629
17988
  var resolvePtzDirection = (command) => {
@@ -22979,7 +23338,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
22979
23338
  * Note: Snapshot uses a special message ID system for binary responses
22980
23339
  */
22981
23340
  async getSnapshot(channel, options) {
22982
- const cmdId = 109;
23341
+ const cmdId = BC_CMD_ID_GET_SNAPSHOT;
22983
23342
  if (channel === void 0) {
22984
23343
  const composite = options?.compositeOptions;
22985
23344
  const widerChannel = composite?.widerChannel ?? 0;
@@ -26582,6 +26941,12 @@ ${stderr}`)
26582
26941
  `<valueTable>${opts.valueTable}</valueTable>`
26583
26942
  );
26584
26943
  }
26944
+ if (opts.sensitivitySchedule !== void 0) {
26945
+ modifiedXml = patchMotionSensitivityListXml(
26946
+ modifiedXml,
26947
+ opts.sensitivitySchedule
26948
+ );
26949
+ }
26585
26950
  await this.sendXml({
26586
26951
  cmdId: BC_CMD_ID_SET_MOTION_ALARM,
26587
26952
  channel: ch,
@@ -26629,6 +26994,72 @@ ${stderr}`)
26629
26994
  payloadXml: modifiedXml
26630
26995
  });
26631
26996
  }
26997
+ /**
26998
+ * SetAiDetectionFull (cmd_id=343 — same as `setAiDetection`).
26999
+ *
27000
+ * Pcap-confirmed (May 2026, E1 Zoom): the Reolink app sends the full
27001
+ * `<AiDetectCfg>` block via cmd_id=343 for ALL fields — area mask,
27002
+ * min/maxTarget* thresholds, sensitivity, stayTime — in one round-trip.
27003
+ * There's no separate "full setter" command (we previously suspected
27004
+ * cmd_id=345 but that's used for something else not yet identified).
27005
+ *
27006
+ * Wire format note: min/maxTarget* fractions are serialized in
27007
+ * scientific notation with 6 decimal places (e.g. "5.000000e-01" for
27008
+ * 0.5). The helper {@link patchAiDetectCfgXml} handles the formatting.
27009
+ *
27010
+ * @param channel 0-based channel
27011
+ * @param aiType one of "people" / "vehicle" / "dog_cat" / "face" / "package"
27012
+ * @param patch partial edit; any omitted field is preserved as-is
27013
+ */
27014
+ async setAiDetectionFull(channel, aiType, patch) {
27015
+ const ch = this.normalizeChannel(channel);
27016
+ const resolvedAiType = await this.resolveAiTypeForSetAiDetection(
27017
+ ch,
27018
+ aiType
27019
+ );
27020
+ const getXml = `<?xml version="1.0" encoding="UTF-8" ?>
27021
+ <body>
27022
+ <AiDetectCfg version="1.1">
27023
+ <chn>${ch}</chn>
27024
+ <type>${xmlEscape(resolvedAiType)}</type>
27025
+ </AiDetectCfg>
27026
+ </body>`;
27027
+ const currentXml = await this.sendXml({
27028
+ cmdId: BC_CMD_ID_GET_AI_ALARM,
27029
+ channel: ch,
27030
+ payloadXml: getXml
27031
+ });
27032
+ const patchedXml = patchAiDetectCfgXml(currentXml, patch);
27033
+ await this.sendXml({
27034
+ cmdId: BC_CMD_ID_SET_AI_ALARM,
27035
+ channel: ch,
27036
+ payloadXml: patchedXml
27037
+ });
27038
+ }
27039
+ /**
27040
+ * GetAiDetectionFull (cmd_id=342). Typed version of `getAiAlarmRaw`
27041
+ * returning the full {@link AiDetectCfgZone} for a single AI type.
27042
+ */
27043
+ async getAiDetectionFull(channel, aiType) {
27044
+ const ch = this.normalizeChannel(channel);
27045
+ const resolvedAiType = await this.resolveAiTypeForSetAiDetection(
27046
+ ch,
27047
+ aiType
27048
+ );
27049
+ const getXml = `<?xml version="1.0" encoding="UTF-8" ?>
27050
+ <body>
27051
+ <AiDetectCfg version="1.1">
27052
+ <chn>${ch}</chn>
27053
+ <type>${xmlEscape(resolvedAiType)}</type>
27054
+ </AiDetectCfg>
27055
+ </body>`;
27056
+ const xml = await this.sendXml({
27057
+ cmdId: BC_CMD_ID_GET_AI_ALARM,
27058
+ channel: ch,
27059
+ payloadXml: getXml
27060
+ });
27061
+ return decodeAiDetectCfg(xml);
27062
+ }
26632
27063
  // --------------------
26633
27064
  // Siren/Audio Alarm APIs
26634
27065
  // --------------------
@@ -28209,6 +28640,69 @@ ${xml}`
28209
28640
  ...timeoutOpts
28210
28641
  });
28211
28642
  }
28643
+ /**
28644
+ * GetMaskZones (cmdId=52) returning a typed structure with normalized
28645
+ * 0..1 rectangles instead of the raw camera fixed-point integers.
28646
+ *
28647
+ * The camera-side coord system is `(pixel << 16) | canvas_dim` where
28648
+ * `canvas_dim` is the firmware-specific mask canvas (E1 Zoom = 540×304).
28649
+ * The returned `canvas` block remembers those dims so callers can
28650
+ * round-trip without re-fetching.
28651
+ *
28652
+ * @see decodePrivacyMaskZones — pure helper exported for UI consumers.
28653
+ */
28654
+ async getMaskZones(channel, options) {
28655
+ const xml = await this.sendPcapDerivedSettingsGetXml({
28656
+ cmdId: BC_CMD_ID_GET_PRIVACY_MASK,
28657
+ ...channel != null ? { channel } : {},
28658
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
28659
+ });
28660
+ return decodePrivacyMaskZones(xml);
28661
+ }
28662
+ /**
28663
+ * SetMaskZones (cmdId=53, read-modify-write of cmdId=52).
28664
+ *
28665
+ * Edits the rectangular shelter list and/or PTZ-tracking shelter list
28666
+ * in one call. Coordinates are normalized 0..1 of the camera mask
28667
+ * canvas — the lib re-fetches the current Shelter block, extracts the
28668
+ * canvas dims from the wire (low-16 of any non-zero coord), and
28669
+ * denormalizes back to the camera's pixel × canvas encoding.
28670
+ *
28671
+ * Pass `enable`/`trackEnable` to toggle the master enable flags without
28672
+ * touching the rectangle data. Pass `shelterList`/`trackShelterList` to
28673
+ * replace the corresponding list — missing slots are padded with
28674
+ * disabled zero-rects matching the camera's idle pattern.
28675
+ *
28676
+ * @param channel 0-based channel
28677
+ * @param patch partial edit; any omitted field is preserved as-is
28678
+ * @param options.canvas override the auto-detected mask canvas (only
28679
+ * needed when the GET response has no non-zero coords to extract from)
28680
+ * @param options.timeoutMs custom request timeout
28681
+ */
28682
+ async setMaskZones(channel, patch, options) {
28683
+ const ch = this.normalizeChannel(channel);
28684
+ const timeoutOpts = options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {};
28685
+ const currentXml = await this.sendXml({
28686
+ cmdId: BC_CMD_ID_GET_PRIVACY_MASK,
28687
+ channel: ch,
28688
+ ...timeoutOpts
28689
+ });
28690
+ const current = decodePrivacyMaskZones(currentXml);
28691
+ const canvas = options?.canvas ?? current.canvas;
28692
+ const patchedXml = patchShelterXml(
28693
+ currentXml,
28694
+ patch,
28695
+ canvas,
28696
+ current.maxNum,
28697
+ current.maxTrackShelterNum
28698
+ );
28699
+ await this.sendXml({
28700
+ cmdId: BC_CMD_ID_SET_PRIVACY_MASK,
28701
+ channel: ch,
28702
+ payloadXml: ensureXmlHeader(patchedXml),
28703
+ ...timeoutOpts
28704
+ });
28705
+ }
28212
28706
  /**
28213
28707
  * GetAudioNoise via Baichuan (cmdId=439). Reads `enable` + `level`
28214
28708
  * from the aiDenoise block. Mirrors reolink_aio's `GetAudioNoise`.
@@ -28895,6 +29389,18 @@ ${xml}`
28895
29389
  });
28896
29390
  return parseVersionInfo(xml);
28897
29391
  }
29392
+ /**
29393
+ * GetUid (cmd_id=114). Returns the device UID / serial visible in the
29394
+ * Reolink app. Response shape: `<Uid><uid>9527000XXXXX</uid></Uid>`.
29395
+ * Device-global — no channel parameter.
29396
+ */
29397
+ async getUid(options) {
29398
+ const xml = await this.sendXml({
29399
+ cmdId: BC_CMD_ID_GET_UID,
29400
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
29401
+ });
29402
+ return (getXmlText(xml, "uid") ?? "").trim();
29403
+ }
28898
29404
  async getLedState(channel, options) {
28899
29405
  const rawXml = await this.sendPcapDerivedSettingsGetXml({
28900
29406
  cmdId: BC_CMD_ID_GET_LED_STATE,
@@ -40416,10 +40922,12 @@ function base64DecodeToBytes(b64) {
40416
40922
  BC_CMD_ID_GET_REC_ENC_CFG,
40417
40923
  BC_CMD_ID_GET_SIREN_STATUS,
40418
40924
  BC_CMD_ID_GET_SLEEP_STATE,
40925
+ BC_CMD_ID_GET_SNAPSHOT,
40419
40926
  BC_CMD_ID_GET_STREAM_INFO_LIST,
40420
40927
  BC_CMD_ID_GET_SUPPORT,
40421
40928
  BC_CMD_ID_GET_SYSTEM_GENERAL,
40422
40929
  BC_CMD_ID_GET_TIMELAPSE_CFG,
40930
+ BC_CMD_ID_GET_UID,
40423
40931
  BC_CMD_ID_GET_VERSION_INFO,
40424
40932
  BC_CMD_ID_GET_VIDEO_INPUT,
40425
40933
  BC_CMD_ID_GET_WHITE_LED,
@@ -40493,6 +41001,7 @@ function base64DecodeToBytes(b64) {
40493
41001
  BcUdpStream,
40494
41002
  CompositeRtspServer,
40495
41003
  CompositeStream,
41004
+ DEFAULT_SHELTER_CANVAS,
40496
41005
  DUAL_LENS_DUAL_MOTION_MODELS,
40497
41006
  DUAL_LENS_MODELS,
40498
41007
  DUAL_LENS_SINGLE_MOTION_MODELS,
@@ -40565,8 +41074,11 @@ function base64DecodeToBytes(b64) {
40565
41074
  createTaggedLogger,
40566
41075
  decideSleepInferenceTransition,
40567
41076
  decideVideoclipTranscodeMode,
41077
+ decodeAiDetectCfg,
40568
41078
  decodeHeader,
40569
41079
  decodeMotionScopeBitmap,
41080
+ decodePrivacyMaskZones,
41081
+ decodeShelterCoord,
40570
41082
  deriveAesKey,
40571
41083
  detectIosClient,
40572
41084
  detectVideoCodecFromNal,
@@ -40580,7 +41092,12 @@ function base64DecodeToBytes(b64) {
40580
41092
  discoverViaUdpDirect,
40581
41093
  encodeHeader,
40582
41094
  encodeMotionScopeBitmap,
41095
+ encodeMotionSensitivityListXml,
41096
+ encodeShelterCoord,
41097
+ encodeShelterListXml,
41098
+ encodeTrackShelterListXml,
40583
41099
  ensureXmlHeader,
41100
+ extractCanvasFromShelterXml,
40584
41101
  extractH264ParamSetsFromAccessUnit,
40585
41102
  extractH265ParamSetsFromAccessUnit,
40586
41103
  extractPpsFromAnnexB,
@@ -40621,7 +41138,10 @@ function base64DecodeToBytes(b64) {
40621
41138
  parseBcMedia,
40622
41139
  parseRecordingFileName,
40623
41140
  parseSupportXml,
41141
+ patchAiDetectCfgXml,
41142
+ patchMotionSensitivityListXml,
40624
41143
  patchNestedTag,
41144
+ patchShelterXml,
40625
41145
  printNvrDiagnostics,
40626
41146
  runAllDiagnosticsConsecutively,
40627
41147
  runMultifocalDiagnosticsConsecutively,