@apocaliss92/nodelink-js 0.4.8 → 0.4.11

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_GET_RECORD_CFG, BC_CMD_ID_GET_ABILITY_SUPPORT, BC_CMD_ID_GET_FTP_TASK, 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_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_CHANNEL_INFO_ALL, BC_CMD_ID_GET_OSD_DATETIME, BC_CMD_ID_GET_RECORD_CFG, BC_CMD_ID_GET_ABILITY_SUPPORT, BC_CMD_ID_GET_FTP_TASK, 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_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";
@@ -137,6 +137,22 @@ var init_constants = __esm({
137
137
  BC_CMD_ID_SET_AI_CFG = 300;
138
138
  BC_CMD_ID_GET_SIREN_STATUS = 547;
139
139
  BC_CMD_ID_SET_AUDIO_TASK = 231;
140
+ BC_CMD_ID_SET_VIDEO_INPUT = 25;
141
+ BC_CMD_ID_SET_DAY_NIGHT_THRESHOLD = 297;
142
+ BC_CMD_ID_GET_ENC = 56;
143
+ BC_CMD_ID_SET_ENC = 57;
144
+ BC_CMD_ID_GET_PRIVACY_MASK = 52;
145
+ BC_CMD_ID_SET_PRIVACY_MASK = 53;
146
+ BC_CMD_ID_SET_AI_DENOISE = 440;
147
+ BC_CMD_ID_SET_LED_STATE = 209;
148
+ BC_CMD_ID_SET_AUDIO_CFG = 265;
149
+ BC_CMD_ID_SET_RECORD = 82;
150
+ BC_CMD_ID_SET_RECORD_CFG = 55;
151
+ BC_CMD_ID_SET_EMAIL_TASK = 216;
152
+ BC_CMD_ID_GET_PUSH_TASK = 219;
153
+ BC_CMD_ID_SET_PUSH_TASK = 218;
154
+ BC_CMD_ID_GET_AUTO_FOCUS = 224;
155
+ BC_CMD_ID_SET_AUTO_FOCUS = 225;
140
156
  BC_CMD_ID_CMD_123 = 123;
141
157
  BC_CMD_ID_CMD_209 = 209;
142
158
  BC_CMD_ID_CMD_265 = 265;
@@ -452,6 +468,59 @@ function buildFloodlightManualXml(channelId, status, durationSeconds = 180) {
452
468
  function buildWhiteLedStateXml(channelId, state) {
453
469
  return buildFloodlightManualXml(channelId, state ? 1 : 0);
454
470
  }
471
+ function ensureXmlHeader(xml) {
472
+ const trimmed = xml.trimStart();
473
+ if (trimmed.startsWith("<?xml")) return xml;
474
+ return `${XML_HEADER}
475
+ ${xml}`;
476
+ }
477
+ function applyXmlTagPatch(xml, tag, value) {
478
+ if (value === void 0) return xml;
479
+ const v = typeof value === "boolean" ? value ? 1 : 0 : value;
480
+ const re = new RegExp(`<${tag}>[^<]*</${tag}>`);
481
+ return xml.replace(re, `<${tag}>${v}</${tag}>`);
482
+ }
483
+ function patchNestedTag(xml, parent, child, value) {
484
+ if (value === void 0) return xml;
485
+ const v = typeof value === "boolean" ? value ? 1 : 0 : value;
486
+ const re = new RegExp(
487
+ `(<${parent}[^>]*>[\\s\\S]*?<${child}>)[^<]*(</${child}>[\\s\\S]*?</${parent}>)`
488
+ );
489
+ return xml.replace(re, `$1${v}$2`);
490
+ }
491
+ function applyStreamPatch(xml, streamTag, patch) {
492
+ if (!patch) return xml;
493
+ const re = new RegExp(
494
+ `(<${streamTag}[^>]*>)([\\s\\S]*?)(</${streamTag}>)`
495
+ );
496
+ return xml.replace(re, (_match, open, body, close) => {
497
+ let next = body;
498
+ if (patch.bitRate !== void 0) {
499
+ next = applyXmlTagPatch(next, "bitRate", patch.bitRate);
500
+ }
501
+ if (patch.frameRate !== void 0) {
502
+ next = applyXmlTagPatch(next, "frameRate", patch.frameRate);
503
+ next = applyXmlTagPatch(next, "frame", patch.frameRate);
504
+ }
505
+ if (patch.videoEncType !== void 0) {
506
+ const intVal = patch.videoEncType === "h265" ? 1 : 0;
507
+ next = applyXmlTagPatch(next, "videoEncType", intVal);
508
+ }
509
+ return `${open}${next}${close}`;
510
+ });
511
+ }
512
+ function normalizeDayNightMode(input) {
513
+ const stripped = String(input).replace(/&/g, "And");
514
+ if (!stripped) return stripped;
515
+ const first = stripped[0];
516
+ if (first === void 0) return stripped;
517
+ return first.toLowerCase() + stripped.slice(1);
518
+ }
519
+ function normalizeOpenClose(input) {
520
+ const v = String(input).toLowerCase();
521
+ if (v === "on" || v === "open" || v === "1" || v === "true") return "open";
522
+ return "close";
523
+ }
455
524
  function buildAbilityInfoExtensionXml(username) {
456
525
  return `<?xml version="1.0" encoding="UTF-8" ?>
457
526
  <Extension version="1.1">
@@ -459,9 +528,11 @@ function buildAbilityInfoExtensionXml(username) {
459
528
  <token>system, streaming, PTZ, IO, security, replay, disk, network, alarm, record, video, image</token>
460
529
  </Extension>`;
461
530
  }
531
+ var XML_HEADER;
462
532
  var init_xml = __esm({
463
533
  "src/protocol/xml.ts"() {
464
534
  "use strict";
535
+ XML_HEADER = `<?xml version="1.0" encoding="UTF-8" ?>`;
465
536
  }
466
537
  });
467
538
 
@@ -6409,6 +6480,137 @@ var init_ReolinkCgiApi = __esm({
6409
6480
  const param = channel == null ? {} : { channel };
6410
6481
  return await this.call("GetPtzPreset", param, 1);
6411
6482
  }
6483
+ // ── Isp / Image (colour, flip, day-night, exposure) ──────────────
6484
+ async GetIsp(channel) {
6485
+ const param = channel == null ? {} : { channel };
6486
+ return await this.call("GetIsp", param, 1);
6487
+ }
6488
+ async SetIsp(isp) {
6489
+ return await this.call("SetIsp", isp, 0);
6490
+ }
6491
+ async GetImage(channel) {
6492
+ const param = channel == null ? {} : { channel };
6493
+ return await this.call("GetImage", param, 1);
6494
+ }
6495
+ async SetImage(image) {
6496
+ return await this.call("SetImage", image, 0);
6497
+ }
6498
+ // ── AudioCfg (mute / volume) ─────────────────────────────────────
6499
+ async GetAudioCfg(channel) {
6500
+ const param = channel == null ? {} : { channel };
6501
+ return await this.call("GetAudioCfg", param, 1);
6502
+ }
6503
+ async SetAudioCfg(audio) {
6504
+ return await this.call("SetAudioCfg", audio, 0);
6505
+ }
6506
+ // ── Enc setter (Get already exists above) ────────────────────────
6507
+ async SetEnc(enc) {
6508
+ return await this.call("SetEnc", enc, 0);
6509
+ }
6510
+ // ── MdAlarm (motion detection sensitivity / regions) ─────────────
6511
+ async GetMdAlarm(channel) {
6512
+ const param = channel == null ? {} : { channel };
6513
+ return await this.call("GetMdAlarm", param, 1);
6514
+ }
6515
+ async SetMdAlarm(md) {
6516
+ return await this.call("SetMdAlarm", md, 0);
6517
+ }
6518
+ // ── IrLights ─────────────────────────────────────────────────────
6519
+ async GetIrLights(channel) {
6520
+ const param = channel == null ? {} : { channel };
6521
+ return await this.call("GetIrLights", param, 1);
6522
+ }
6523
+ async SetIrLights(ir) {
6524
+ return await this.call("SetIrLights", ir, 0);
6525
+ }
6526
+ // ── AiCfg (smart-detection enable + class filter) ────────────────
6527
+ async GetAiCfg(channel) {
6528
+ const param = channel == null ? {} : { channel };
6529
+ return await this.call("GetAiCfg", param, 1);
6530
+ }
6531
+ async SetAiCfg(ai) {
6532
+ return await this.call("SetAiCfg", ai, 0);
6533
+ }
6534
+ // ── Mask (privacy-mask zones) ────────────────────────────────────
6535
+ async GetMask(channel) {
6536
+ return await this.call("GetMask", { channel }, 1);
6537
+ }
6538
+ async SetMask(mask) {
6539
+ return await this.call("SetMask", mask, 0);
6540
+ }
6541
+ // ── AudioNoise (input noise reduction) ───────────────────────────
6542
+ async GetAudioNoise(channel) {
6543
+ return await this.call("GetAudioNoise", { channel }, 1);
6544
+ }
6545
+ async SetAudioNoise(noise) {
6546
+ return await this.call("SetAudioNoise", noise, 0);
6547
+ }
6548
+ // ── Rec / RecV20 (recording schedule) ────────────────────────────
6549
+ async GetRec(channel) {
6550
+ return await this.call("GetRec", { channel }, 1);
6551
+ }
6552
+ async SetRec(rec) {
6553
+ return await this.call("SetRec", rec, 0);
6554
+ }
6555
+ /** Newer firmwares advertise `GetRecV20` / `SetRecV20` with the
6556
+ * weekly-schedule `table` field. Same payload shape as `Rec`. */
6557
+ async GetRecV20(channel) {
6558
+ return await this.call("GetRecV20", { channel }, 1);
6559
+ }
6560
+ async SetRecV20(rec) {
6561
+ return await this.call("SetRecV20", rec, 0);
6562
+ }
6563
+ // ── Email (SMTP alert) ───────────────────────────────────────────
6564
+ async GetEmail(channel) {
6565
+ return await this.call("GetEmail", { channel }, 1);
6566
+ }
6567
+ async SetEmail(email) {
6568
+ return await this.call("SetEmail", email, 0);
6569
+ }
6570
+ /** V20 variant on newer firmwares with weekly-schedule `table`. */
6571
+ async GetEmailV20(channel) {
6572
+ return await this.call("GetEmailV20", { channel }, 1);
6573
+ }
6574
+ async SetEmailV20(email) {
6575
+ return await this.call("SetEmailV20", email, 0);
6576
+ }
6577
+ // ── Push (Reolink-cloud push notifications) ──────────────────────
6578
+ async GetPush(channel) {
6579
+ return await this.call("GetPush", { channel }, 1);
6580
+ }
6581
+ async SetPush(push) {
6582
+ return await this.call("SetPush", push, 0);
6583
+ }
6584
+ async GetPushV20(channel) {
6585
+ return await this.call("GetPushV20", { channel }, 1);
6586
+ }
6587
+ async SetPushV20(push) {
6588
+ return await this.call("SetPushV20", push, 0);
6589
+ }
6590
+ // ── AudioAlarm (siren-on-event) ──────────────────────────────────
6591
+ async GetAudioAlarm(channel) {
6592
+ return await this.call("GetAudioAlarm", { channel }, 1);
6593
+ }
6594
+ async SetAudioAlarm(audio) {
6595
+ return await this.call("SetAudioAlarm", audio, 0);
6596
+ }
6597
+ async SetAudioAlarmV20(audio) {
6598
+ return await this.call("SetAudioAlarmV20", audio, 0);
6599
+ }
6600
+ // ── AutoFocus (PTZ AF) ───────────────────────────────────────────
6601
+ async GetAutoFocus(channel) {
6602
+ return await this.call("GetAutoFocus", { channel }, 1);
6603
+ }
6604
+ async SetAutoFocus(af) {
6605
+ return await this.call("SetAutoFocus", af, 0);
6606
+ }
6607
+ // ── AiAlarm (per-class smart-detection thresholds) ───────────────
6608
+ async GetAiAlarm(channel, aiType) {
6609
+ return await this.call("GetAiAlarm", { channel, ai_type: aiType }, 1);
6610
+ }
6611
+ async SetAiAlarm(ai) {
6612
+ return await this.call("SetAiAlarm", ai, 0);
6613
+ }
6412
6614
  async GetAudioAlarmV20(channel) {
6413
6615
  const param = channel == null ? {} : { channel };
6414
6616
  return await this.call("GetAudioAlarmV20", param, 0);
@@ -7807,6 +8009,7 @@ __export(index_exports, {
7807
8009
  BC_CMD_ID_GET_AUDIO_ALARM: () => BC_CMD_ID_GET_AUDIO_ALARM,
7808
8010
  BC_CMD_ID_GET_AUDIO_CFG: () => BC_CMD_ID_GET_AUDIO_CFG,
7809
8011
  BC_CMD_ID_GET_AUDIO_TASK: () => BC_CMD_ID_GET_AUDIO_TASK,
8012
+ BC_CMD_ID_GET_AUTO_FOCUS: () => BC_CMD_ID_GET_AUTO_FOCUS,
7810
8013
  BC_CMD_ID_GET_BATTERY_INFO: () => BC_CMD_ID_GET_BATTERY_INFO,
7811
8014
  BC_CMD_ID_GET_BATTERY_INFO_LIST: () => BC_CMD_ID_GET_BATTERY_INFO_LIST,
7812
8015
  BC_CMD_ID_GET_DAY_NIGHT_THRESHOLD: () => BC_CMD_ID_GET_DAY_NIGHT_THRESHOLD,
@@ -7815,6 +8018,7 @@ __export(index_exports, {
7815
8018
  BC_CMD_ID_GET_DING_DONG_LIST: () => BC_CMD_ID_GET_DING_DONG_LIST,
7816
8019
  BC_CMD_ID_GET_DING_DONG_SILENT: () => BC_CMD_ID_GET_DING_DONG_SILENT,
7817
8020
  BC_CMD_ID_GET_EMAIL_TASK: () => BC_CMD_ID_GET_EMAIL_TASK,
8021
+ BC_CMD_ID_GET_ENC: () => BC_CMD_ID_GET_ENC,
7818
8022
  BC_CMD_ID_GET_FTP_TASK: () => BC_CMD_ID_GET_FTP_TASK,
7819
8023
  BC_CMD_ID_GET_HDD_INFO_LIST: () => BC_CMD_ID_GET_HDD_INFO_LIST,
7820
8024
  BC_CMD_ID_GET_KIT_AP_CFG: () => BC_CMD_ID_GET_KIT_AP_CFG,
@@ -7823,8 +8027,10 @@ __export(index_exports, {
7823
8027
  BC_CMD_ID_GET_ONLINE_USER_LIST: () => BC_CMD_ID_GET_ONLINE_USER_LIST,
7824
8028
  BC_CMD_ID_GET_OSD_DATETIME: () => BC_CMD_ID_GET_OSD_DATETIME,
7825
8029
  BC_CMD_ID_GET_PIR_INFO: () => BC_CMD_ID_GET_PIR_INFO,
8030
+ BC_CMD_ID_GET_PRIVACY_MASK: () => BC_CMD_ID_GET_PRIVACY_MASK,
7826
8031
  BC_CMD_ID_GET_PTZ_POSITION: () => BC_CMD_ID_GET_PTZ_POSITION,
7827
8032
  BC_CMD_ID_GET_PTZ_PRESET: () => BC_CMD_ID_GET_PTZ_PRESET,
8033
+ BC_CMD_ID_GET_PUSH_TASK: () => BC_CMD_ID_GET_PUSH_TASK,
7828
8034
  BC_CMD_ID_GET_RECORD: () => BC_CMD_ID_GET_RECORD,
7829
8035
  BC_CMD_ID_GET_RECORD_CFG: () => BC_CMD_ID_GET_RECORD_CFG,
7830
8036
  BC_CMD_ID_GET_REC_ENC_CFG: () => BC_CMD_ID_GET_REC_ENC_CFG,
@@ -7853,11 +8059,23 @@ __export(index_exports, {
7853
8059
  BC_CMD_ID_QUICK_REPLY_PLAY: () => BC_CMD_ID_QUICK_REPLY_PLAY,
7854
8060
  BC_CMD_ID_SET_AI_ALARM: () => BC_CMD_ID_SET_AI_ALARM,
7855
8061
  BC_CMD_ID_SET_AI_CFG: () => BC_CMD_ID_SET_AI_CFG,
8062
+ BC_CMD_ID_SET_AI_DENOISE: () => BC_CMD_ID_SET_AI_DENOISE,
8063
+ BC_CMD_ID_SET_AUDIO_CFG: () => BC_CMD_ID_SET_AUDIO_CFG,
7856
8064
  BC_CMD_ID_SET_AUDIO_TASK: () => BC_CMD_ID_SET_AUDIO_TASK,
8065
+ BC_CMD_ID_SET_AUTO_FOCUS: () => BC_CMD_ID_SET_AUTO_FOCUS,
8066
+ BC_CMD_ID_SET_DAY_NIGHT_THRESHOLD: () => BC_CMD_ID_SET_DAY_NIGHT_THRESHOLD,
7857
8067
  BC_CMD_ID_SET_DING_DONG_CFG: () => BC_CMD_ID_SET_DING_DONG_CFG,
7858
8068
  BC_CMD_ID_SET_DING_DONG_SILENT: () => BC_CMD_ID_SET_DING_DONG_SILENT,
8069
+ BC_CMD_ID_SET_EMAIL_TASK: () => BC_CMD_ID_SET_EMAIL_TASK,
8070
+ BC_CMD_ID_SET_ENC: () => BC_CMD_ID_SET_ENC,
8071
+ BC_CMD_ID_SET_LED_STATE: () => BC_CMD_ID_SET_LED_STATE,
7859
8072
  BC_CMD_ID_SET_MOTION_ALARM: () => BC_CMD_ID_SET_MOTION_ALARM,
7860
8073
  BC_CMD_ID_SET_PIR_INFO: () => BC_CMD_ID_SET_PIR_INFO,
8074
+ BC_CMD_ID_SET_PRIVACY_MASK: () => BC_CMD_ID_SET_PRIVACY_MASK,
8075
+ BC_CMD_ID_SET_PUSH_TASK: () => BC_CMD_ID_SET_PUSH_TASK,
8076
+ BC_CMD_ID_SET_RECORD: () => BC_CMD_ID_SET_RECORD,
8077
+ BC_CMD_ID_SET_RECORD_CFG: () => BC_CMD_ID_SET_RECORD_CFG,
8078
+ BC_CMD_ID_SET_VIDEO_INPUT: () => BC_CMD_ID_SET_VIDEO_INPUT,
7861
8079
  BC_CMD_ID_SET_WHITE_LED_STATE: () => BC_CMD_ID_SET_WHITE_LED_STATE,
7862
8080
  BC_CMD_ID_SET_WHITE_LED_TASK: () => BC_CMD_ID_SET_WHITE_LED_TASK,
7863
8081
  BC_CMD_ID_SET_ZOOM_FOCUS: () => BC_CMD_ID_SET_ZOOM_FOCUS,
@@ -7906,6 +8124,8 @@ __export(index_exports, {
7906
8124
  abilitiesHasAny: () => abilitiesHasAny,
7907
8125
  aesDecrypt: () => aesDecrypt,
7908
8126
  aesEncrypt: () => aesEncrypt,
8127
+ applyStreamPatch: () => applyStreamPatch,
8128
+ applyXmlTagPatch: () => applyXmlTagPatch,
7909
8129
  asLogger: () => asLogger,
7910
8130
  autoDetectDeviceType: () => autoDetectDeviceType,
7911
8131
  bcDecrypt: () => bcDecrypt,
@@ -7970,6 +8190,7 @@ __export(index_exports, {
7970
8190
  discoverViaUdpBroadcast: () => discoverViaUdpBroadcast,
7971
8191
  discoverViaUdpDirect: () => discoverViaUdpDirect,
7972
8192
  encodeHeader: () => encodeHeader,
8193
+ ensureXmlHeader: () => ensureXmlHeader,
7973
8194
  extractH264ParamSetsFromAccessUnit: () => extractH264ParamSetsFromAccessUnit,
7974
8195
  extractH265ParamSetsFromAccessUnit: () => extractH265ParamSetsFromAccessUnit,
7975
8196
  extractPpsFromAnnexB: () => extractPpsFromAnnexB,
@@ -7998,6 +8219,8 @@ __export(index_exports, {
7998
8219
  maskUid: () => maskUid,
7999
8220
  md5HexUpper: () => md5HexUpper,
8000
8221
  md5StrModern: () => md5StrModern,
8222
+ normalizeDayNightMode: () => normalizeDayNightMode,
8223
+ normalizeOpenClose: () => normalizeOpenClose,
8001
8224
  normalizeUid: () => normalizeUid,
8002
8225
  packetizeAacAdtsFrame: () => packetizeAacAdtsFrame,
8003
8226
  packetizeAacRawFrame: () => packetizeAacRawFrame,
@@ -8007,6 +8230,7 @@ __export(index_exports, {
8007
8230
  parseBcMedia: () => parseBcMedia,
8008
8231
  parseRecordingFileName: () => parseRecordingFileName,
8009
8232
  parseSupportXml: () => parseSupportXml,
8233
+ patchNestedTag: () => patchNestedTag,
8010
8234
  printNvrDiagnostics: () => printNvrDiagnostics,
8011
8235
  runAllDiagnosticsConsecutively: () => runAllDiagnosticsConsecutively,
8012
8236
  runMultifocalDiagnosticsConsecutively: () => runMultifocalDiagnosticsConsecutively,
@@ -26438,6 +26662,373 @@ ${xml}`
26438
26662
  await this.cgiApi.login();
26439
26663
  return await this.cgiApi.getAllChannelsEvents(options);
26440
26664
  }
26665
+ // ====================================================================
26666
+ // Native Baichuan tunable-settings setters
26667
+ //
26668
+ // Replace the CGI passthroughs above with on-wire Baichuan binary
26669
+ // calls. Mirrors the @http_cmd-decorated methods in reolink_aio's
26670
+ // baichuan.py — every command has a documented `cmd_id` (read) and
26671
+ // `cmd_id` (write) pair. The pattern is:
26672
+ //
26673
+ // 1. read XML via `sendXml({ cmdId: GET, channel })`
26674
+ // 2. patch fields via regex (camera firmware is XML-strict; using
26675
+ // the parser would force us to rebuild the document and risk
26676
+ // losing unmodified attributes / element order).
26677
+ // 3. write back via `sendXml({ cmdId: SET, channel, payloadXml })`
26678
+ //
26679
+ // All getters parse via `parseXmlFragmentToJson` so the consumer gets
26680
+ // a clean JSON object instead of XML.
26681
+ // ====================================================================
26682
+ /**
26683
+ * GetEnc via Baichuan (cmdId=56). Returns the `<Compression>` block:
26684
+ * per-stream `mainStream` / `subStream` / `thirdStream` with `audio`
26685
+ * flag, `width`, `height`, `frame` (NOT `frameRate`), `bitRate`,
26686
+ * `videoEncType` (0=h264, 1=h265), `encoderProfile`, `gop`. Mirrors
26687
+ * reolink_aio's `GetEnc` — note the wire payload wraps everything
26688
+ * in `Compression`, not `Enc`.
26689
+ */
26690
+ async getEnc(channel, options) {
26691
+ const xml = await this.sendPcapDerivedSettingsGetXml({
26692
+ cmdId: BC_CMD_ID_GET_ENC,
26693
+ ...channel != null ? { channel } : {},
26694
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
26695
+ });
26696
+ return parseXmlFragmentToJson(xml);
26697
+ }
26698
+ /**
26699
+ * SetEnc via Baichuan (cmdId=57). Read-modify-write — preserves
26700
+ * unspecified fields. Mirrors reolink_aio's `SetEnc`.
26701
+ *
26702
+ * @param channel - Channel number (0-based)
26703
+ * @param patch - Fields to update on `mainStream` and/or `subStream`,
26704
+ * plus a top-level `audio` toggle (0/1). Pass only what you want
26705
+ * to change.
26706
+ */
26707
+ async setEnc(channel, patch, options) {
26708
+ const ch = this.normalizeChannel(channel);
26709
+ let xml = await this.sendXml({
26710
+ cmdId: BC_CMD_ID_GET_ENC,
26711
+ channel: ch,
26712
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
26713
+ });
26714
+ if (patch.audio !== void 0) {
26715
+ xml = xml.replace(
26716
+ /<audio>[^<]*<\/audio>/g,
26717
+ `<audio>${patch.audio}</audio>`
26718
+ );
26719
+ }
26720
+ xml = applyStreamPatch(xml, "mainStream", patch.mainStream);
26721
+ xml = applyStreamPatch(xml, "subStream", patch.subStream);
26722
+ await this.sendXml({
26723
+ cmdId: BC_CMD_ID_SET_ENC,
26724
+ channel: ch,
26725
+ payloadXml: ensureXmlHeader(xml),
26726
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
26727
+ });
26728
+ }
26729
+ /**
26730
+ * SetImage via Baichuan (cmdId=25, read via cmdId=26). Patches the
26731
+ * `<VideoInput>` block: bright / contrast / saturation / hue /
26732
+ * sharpen. Mirrors reolink_aio's `SetImage`.
26733
+ */
26734
+ async setImage(channel, patch, options) {
26735
+ const ch = this.normalizeChannel(channel);
26736
+ let xml = await this.sendXml({
26737
+ cmdId: BC_CMD_ID_GET_VIDEO_INPUT,
26738
+ channel: ch,
26739
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
26740
+ });
26741
+ xml = applyXmlTagPatch(xml, "bright", patch.bright);
26742
+ xml = applyXmlTagPatch(xml, "contrast", patch.contrast);
26743
+ xml = applyXmlTagPatch(xml, "saturation", patch.saturation);
26744
+ xml = applyXmlTagPatch(xml, "hue", patch.hue);
26745
+ xml = applyXmlTagPatch(xml, "sharpen", patch.sharpen);
26746
+ await this.sendXml({
26747
+ cmdId: BC_CMD_ID_SET_VIDEO_INPUT,
26748
+ channel: ch,
26749
+ payloadXml: ensureXmlHeader(xml),
26750
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
26751
+ });
26752
+ }
26753
+ /**
26754
+ * SetIsp via Baichuan (cmdId=25 for image side, cmdId=297 for
26755
+ * dayNightThreshold). Patches the `<InputAdvanceCfg>` block:
26756
+ * `DayNight/mode`, `Exposure/mode`, `binning_mode`, `hdrSwitch`.
26757
+ * Mirrors reolink_aio's `SetIsp`.
26758
+ *
26759
+ * @param channel - Channel number (0-based)
26760
+ * @param patch - Fields to update. `dayNight` accepts the camera's
26761
+ * raw enum (`color`, `auto`, `blackAndWhite`, …) — pass it as the
26762
+ * camera reports it (PascalCase / dotted forms get normalized
26763
+ * server-side).
26764
+ */
26765
+ async setIsp(channel, patch, options) {
26766
+ const ch = this.normalizeChannel(channel);
26767
+ const timeoutOpts = options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {};
26768
+ const wantsImageWrite = patch.dayNight !== void 0 || patch.exposure !== void 0 || patch.binningMode !== void 0 || patch.hdr !== void 0;
26769
+ if (wantsImageWrite) {
26770
+ let xml = await this.sendXml({
26771
+ cmdId: BC_CMD_ID_GET_VIDEO_INPUT,
26772
+ channel: ch,
26773
+ ...timeoutOpts
26774
+ });
26775
+ if (patch.dayNight !== void 0) {
26776
+ const normalized = normalizeDayNightMode(patch.dayNight);
26777
+ xml = patchNestedTag(xml, "DayNight", "mode", normalized);
26778
+ }
26779
+ if (patch.exposure !== void 0) {
26780
+ xml = patchNestedTag(
26781
+ xml,
26782
+ "Exposure",
26783
+ "mode",
26784
+ patch.exposure.toLowerCase()
26785
+ );
26786
+ }
26787
+ if (patch.binningMode !== void 0) {
26788
+ xml = applyXmlTagPatch(xml, "binning_mode", patch.binningMode);
26789
+ }
26790
+ if (patch.hdr !== void 0) {
26791
+ xml = applyXmlTagPatch(xml, "hdrSwitch", patch.hdr);
26792
+ }
26793
+ await this.sendXml({
26794
+ cmdId: BC_CMD_ID_SET_VIDEO_INPUT,
26795
+ channel: ch,
26796
+ payloadXml: ensureXmlHeader(xml),
26797
+ ...timeoutOpts
26798
+ });
26799
+ }
26800
+ if (patch.dayNightThreshold !== void 0) {
26801
+ let xml = await this.sendXml({
26802
+ cmdId: BC_CMD_ID_GET_DAY_NIGHT_THRESHOLD,
26803
+ channel: ch,
26804
+ ...timeoutOpts
26805
+ });
26806
+ xml = applyXmlTagPatch(xml, "cur", patch.dayNightThreshold);
26807
+ await this.sendXml({
26808
+ cmdId: BC_CMD_ID_SET_DAY_NIGHT_THRESHOLD,
26809
+ channel: ch,
26810
+ payloadXml: ensureXmlHeader(xml),
26811
+ ...timeoutOpts
26812
+ });
26813
+ }
26814
+ }
26815
+ /**
26816
+ * GetIsp via Baichuan (cmdId=26). Convenience alias of
26817
+ * `getVideoInput()` so callers that switched from CGI keep the
26818
+ * familiar name. Both return the merged VideoInput +
26819
+ * InputAdvanceCfg blob.
26820
+ */
26821
+ async getIsp(channel, options) {
26822
+ return this.getVideoInput(channel, options);
26823
+ }
26824
+ /** GetImage via Baichuan (cmdId=26). Same payload as `getIsp` —
26825
+ * Reolink merged VideoInput + InputAdvanceCfg under one cmdId. */
26826
+ async getImage(channel, options) {
26827
+ return this.getVideoInput(channel, options);
26828
+ }
26829
+ /**
26830
+ * GetIrLights via Baichuan (cmdId=208). Returns LedState block:
26831
+ * `IRLedBrightness`, `state` (ir on/off), `lightState` (status LED
26832
+ * open/close), `doorbellLightState`. Mirrors reolink_aio's
26833
+ * `get_status_led`.
26834
+ */
26835
+ async getIrLights(channel, options) {
26836
+ const xml = await this.sendPcapDerivedSettingsGetXml({
26837
+ cmdId: BC_CMD_ID_GET_LED_STATE,
26838
+ ...channel != null ? { channel } : {},
26839
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
26840
+ });
26841
+ return parseXmlFragmentToJson(xml);
26842
+ }
26843
+ /**
26844
+ * SetIrLights via Baichuan (cmdId=209, read via cmdId=208). Patches
26845
+ * IR LED + status LED + doorbell LED + IR brightness. Mirrors
26846
+ * reolink_aio's `set_status_led`.
26847
+ *
26848
+ * @param channel - Channel number (0-based)
26849
+ * @param patch - `irState` ("On" | "Off" | "Auto"), `lightState`
26850
+ * (status LED), `doorbellLightState`, `irBrightness` (0..255).
26851
+ * Camera-side accepts lowercase strings (`open`/`close`); the
26852
+ * helper normalizes from the friendly variants.
26853
+ */
26854
+ async setIrLights(channel, patch, options) {
26855
+ const ch = this.normalizeChannel(channel);
26856
+ const timeoutOpts = options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {};
26857
+ let xml = await this.sendXml({
26858
+ cmdId: BC_CMD_ID_GET_LED_STATE,
26859
+ channel: ch,
26860
+ ...timeoutOpts
26861
+ });
26862
+ if (patch.lightState !== void 0) {
26863
+ xml = applyXmlTagPatch(
26864
+ xml,
26865
+ "lightState",
26866
+ patch.lightState === "On" ? "open" : "close"
26867
+ );
26868
+ }
26869
+ if (patch.doorbellLightState !== void 0) {
26870
+ xml = applyXmlTagPatch(
26871
+ xml,
26872
+ "doorbellLightState",
26873
+ normalizeOpenClose(patch.doorbellLightState)
26874
+ );
26875
+ }
26876
+ if (patch.irState !== void 0) {
26877
+ const v = String(patch.irState);
26878
+ const out = v === "Off" ? "close" : v.toLowerCase();
26879
+ xml = applyXmlTagPatch(xml, "state", out);
26880
+ }
26881
+ if (patch.irBrightness !== void 0) {
26882
+ xml = applyXmlTagPatch(xml, "IRLedBrightness", patch.irBrightness);
26883
+ }
26884
+ await this.sendXml({
26885
+ cmdId: BC_CMD_ID_SET_LED_STATE,
26886
+ channel: ch,
26887
+ payloadXml: ensureXmlHeader(xml),
26888
+ ...timeoutOpts
26889
+ });
26890
+ }
26891
+ /**
26892
+ * SetAudioCfg via Baichuan (cmdId=265, read via cmdId=264). Patches
26893
+ * volume / talk-and-reply / visitor settings. Mirrors reolink_aio's
26894
+ * `SetAudioCfg`.
26895
+ */
26896
+ async setAudioCfg(channel, patch, options) {
26897
+ const ch = this.normalizeChannel(channel);
26898
+ const timeoutOpts = options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {};
26899
+ let xml = await this.sendXml({
26900
+ cmdId: BC_CMD_ID_GET_AUDIO_CFG,
26901
+ channel: ch,
26902
+ ...timeoutOpts
26903
+ });
26904
+ xml = applyXmlTagPatch(xml, "volume", patch.volume);
26905
+ xml = applyXmlTagPatch(
26906
+ xml,
26907
+ "talkAndReplyVolume",
26908
+ patch.talkAndReplyVolume
26909
+ );
26910
+ xml = applyXmlTagPatch(xml, "visitorVolume", patch.visitorVolume);
26911
+ xml = applyXmlTagPatch(xml, "visitorLoudspeaker", patch.visitorLoudspeaker);
26912
+ await this.sendXml({
26913
+ cmdId: BC_CMD_ID_SET_AUDIO_CFG,
26914
+ channel: ch,
26915
+ payloadXml: ensureXmlHeader(xml),
26916
+ ...timeoutOpts
26917
+ });
26918
+ }
26919
+ /**
26920
+ * GetMask (privacy mask) via Baichuan (cmdId=52). Returns the
26921
+ * `<Shelter>` block — `enable` flag + `shelterList`. Mirrors
26922
+ * reolink_aio's `GetMask`.
26923
+ */
26924
+ async getMask(channel, options) {
26925
+ const xml = await this.sendPcapDerivedSettingsGetXml({
26926
+ cmdId: BC_CMD_ID_GET_PRIVACY_MASK,
26927
+ ...channel != null ? { channel } : {},
26928
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
26929
+ });
26930
+ return parseXmlFragmentToJson(xml);
26931
+ }
26932
+ /**
26933
+ * SetMask (privacy mask) via Baichuan (cmdId=53, read via cmdId=52).
26934
+ * Toggles the `<Shelter><enable>` flag. Mirrors reolink_aio's
26935
+ * `SetMask` (which only touches enable too — shelter zone editing
26936
+ * goes through a separate flow).
26937
+ */
26938
+ async setMask(channel, patch, options) {
26939
+ const ch = this.normalizeChannel(channel);
26940
+ const timeoutOpts = options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {};
26941
+ let xml = await this.sendXml({
26942
+ cmdId: BC_CMD_ID_GET_PRIVACY_MASK,
26943
+ channel: ch,
26944
+ ...timeoutOpts
26945
+ });
26946
+ if (patch.enable !== void 0) {
26947
+ xml = applyXmlTagPatch(xml, "enable", patch.enable ? 1 : 0);
26948
+ }
26949
+ await this.sendXml({
26950
+ cmdId: BC_CMD_ID_SET_PRIVACY_MASK,
26951
+ channel: ch,
26952
+ payloadXml: ensureXmlHeader(xml),
26953
+ ...timeoutOpts
26954
+ });
26955
+ }
26956
+ /**
26957
+ * GetAudioNoise via Baichuan (cmdId=439). Reads `enable` + `level`
26958
+ * from the aiDenoise block. Mirrors reolink_aio's `GetAudioNoise`.
26959
+ *
26960
+ * Note: `getAiDenoise` already returns the same payload typed as
26961
+ * `AiDenoiseConfig`. This getter exists for naming parity with
26962
+ * reolink_aio + the reolink CGI.
26963
+ */
26964
+ async getAudioNoise(channel, options) {
26965
+ const xml = await this.sendPcapDerivedSettingsGetXml({
26966
+ cmdId: BC_CMD_ID_GET_AI_DENOISE,
26967
+ ...channel != null ? { channel } : {},
26968
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
26969
+ });
26970
+ return parseXmlFragmentToJson(xml);
26971
+ }
26972
+ /**
26973
+ * SetAudioNoise via Baichuan (cmdId=440, read via cmdId=439).
26974
+ * Mirrors reolink_aio's `SetAudioNoise` — `level <= 0` flips the
26975
+ * enable flag off; positive values turn it on and update the level.
26976
+ */
26977
+ async setAudioNoise(channel, level, options) {
26978
+ const ch = this.normalizeChannel(channel);
26979
+ const timeoutOpts = options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {};
26980
+ let xml = await this.sendXml({
26981
+ cmdId: BC_CMD_ID_GET_AI_DENOISE,
26982
+ channel: ch,
26983
+ ...timeoutOpts
26984
+ });
26985
+ xml = applyXmlTagPatch(xml, "enable", level > 0 ? 1 : 0);
26986
+ if (level > 0) {
26987
+ xml = applyXmlTagPatch(xml, "level", level);
26988
+ }
26989
+ await this.sendXml({
26990
+ cmdId: BC_CMD_ID_SET_AI_DENOISE,
26991
+ channel: ch,
26992
+ payloadXml: ensureXmlHeader(xml),
26993
+ ...timeoutOpts
26994
+ });
26995
+ }
26996
+ /**
26997
+ * GetAutoFocus via Baichuan (cmdId=224). Returns the `<AutoFocus>`
26998
+ * block — only `disable` (0 = AF on, 1 = AF off). Mirrors
26999
+ * reolink_aio's `GetAutoFocus`.
27000
+ */
27001
+ async getAutoFocus(channel, options) {
27002
+ const ch = this.normalizeChannel(channel);
27003
+ const xml = await this.sendPcapDerivedSettingsGetXml({
27004
+ cmdId: BC_CMD_ID_GET_AUTO_FOCUS,
27005
+ channel: ch,
27006
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
27007
+ });
27008
+ return parseXmlFragmentToJson(xml);
27009
+ }
27010
+ /**
27011
+ * SetAutoFocus via Baichuan (cmdId=225). Mirrors reolink_aio's
27012
+ * `SetAutoFocus`. Note: write-only command — the payload is built
27013
+ * from scratch (no read-modify-write needed).
27014
+ */
27015
+ async setAutoFocus(channel, disable, options) {
27016
+ const ch = this.normalizeChannel(channel);
27017
+ const disableVal = disable ? 1 : 0;
27018
+ const payloadXml = `<?xml version="1.0" encoding="UTF-8" ?>
27019
+ <body>
27020
+ <AutoFocus version="1.1">
27021
+ <channelId>${ch}</channelId>
27022
+ <disable>${disableVal}</disable>
27023
+ </AutoFocus>
27024
+ </body>`;
27025
+ await this.sendXml({
27026
+ cmdId: BC_CMD_ID_SET_AUTO_FOCUS,
27027
+ channel: ch,
27028
+ payloadXml,
27029
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
27030
+ });
27031
+ }
26441
27032
  /**
26442
27033
  * Passthrough to ReolinkCgiApi.getAllChannelsBatteryInfo.
26443
27034
  * Fetches battery info for all channels via CGI (merged with channel status sleep flag).
@@ -37714,6 +38305,7 @@ var CompositeRtspServer = class extends import_node_events12.EventEmitter {
37714
38305
  BC_CMD_ID_GET_AUDIO_ALARM,
37715
38306
  BC_CMD_ID_GET_AUDIO_CFG,
37716
38307
  BC_CMD_ID_GET_AUDIO_TASK,
38308
+ BC_CMD_ID_GET_AUTO_FOCUS,
37717
38309
  BC_CMD_ID_GET_BATTERY_INFO,
37718
38310
  BC_CMD_ID_GET_BATTERY_INFO_LIST,
37719
38311
  BC_CMD_ID_GET_DAY_NIGHT_THRESHOLD,
@@ -37722,6 +38314,7 @@ var CompositeRtspServer = class extends import_node_events12.EventEmitter {
37722
38314
  BC_CMD_ID_GET_DING_DONG_LIST,
37723
38315
  BC_CMD_ID_GET_DING_DONG_SILENT,
37724
38316
  BC_CMD_ID_GET_EMAIL_TASK,
38317
+ BC_CMD_ID_GET_ENC,
37725
38318
  BC_CMD_ID_GET_FTP_TASK,
37726
38319
  BC_CMD_ID_GET_HDD_INFO_LIST,
37727
38320
  BC_CMD_ID_GET_KIT_AP_CFG,
@@ -37730,8 +38323,10 @@ var CompositeRtspServer = class extends import_node_events12.EventEmitter {
37730
38323
  BC_CMD_ID_GET_ONLINE_USER_LIST,
37731
38324
  BC_CMD_ID_GET_OSD_DATETIME,
37732
38325
  BC_CMD_ID_GET_PIR_INFO,
38326
+ BC_CMD_ID_GET_PRIVACY_MASK,
37733
38327
  BC_CMD_ID_GET_PTZ_POSITION,
37734
38328
  BC_CMD_ID_GET_PTZ_PRESET,
38329
+ BC_CMD_ID_GET_PUSH_TASK,
37735
38330
  BC_CMD_ID_GET_RECORD,
37736
38331
  BC_CMD_ID_GET_RECORD_CFG,
37737
38332
  BC_CMD_ID_GET_REC_ENC_CFG,
@@ -37760,11 +38355,23 @@ var CompositeRtspServer = class extends import_node_events12.EventEmitter {
37760
38355
  BC_CMD_ID_QUICK_REPLY_PLAY,
37761
38356
  BC_CMD_ID_SET_AI_ALARM,
37762
38357
  BC_CMD_ID_SET_AI_CFG,
38358
+ BC_CMD_ID_SET_AI_DENOISE,
38359
+ BC_CMD_ID_SET_AUDIO_CFG,
37763
38360
  BC_CMD_ID_SET_AUDIO_TASK,
38361
+ BC_CMD_ID_SET_AUTO_FOCUS,
38362
+ BC_CMD_ID_SET_DAY_NIGHT_THRESHOLD,
37764
38363
  BC_CMD_ID_SET_DING_DONG_CFG,
37765
38364
  BC_CMD_ID_SET_DING_DONG_SILENT,
38365
+ BC_CMD_ID_SET_EMAIL_TASK,
38366
+ BC_CMD_ID_SET_ENC,
38367
+ BC_CMD_ID_SET_LED_STATE,
37766
38368
  BC_CMD_ID_SET_MOTION_ALARM,
37767
38369
  BC_CMD_ID_SET_PIR_INFO,
38370
+ BC_CMD_ID_SET_PRIVACY_MASK,
38371
+ BC_CMD_ID_SET_PUSH_TASK,
38372
+ BC_CMD_ID_SET_RECORD,
38373
+ BC_CMD_ID_SET_RECORD_CFG,
38374
+ BC_CMD_ID_SET_VIDEO_INPUT,
37768
38375
  BC_CMD_ID_SET_WHITE_LED_STATE,
37769
38376
  BC_CMD_ID_SET_WHITE_LED_TASK,
37770
38377
  BC_CMD_ID_SET_ZOOM_FOCUS,
@@ -37813,6 +38420,8 @@ var CompositeRtspServer = class extends import_node_events12.EventEmitter {
37813
38420
  abilitiesHasAny,
37814
38421
  aesDecrypt,
37815
38422
  aesEncrypt,
38423
+ applyStreamPatch,
38424
+ applyXmlTagPatch,
37816
38425
  asLogger,
37817
38426
  autoDetectDeviceType,
37818
38427
  bcDecrypt,
@@ -37877,6 +38486,7 @@ var CompositeRtspServer = class extends import_node_events12.EventEmitter {
37877
38486
  discoverViaUdpBroadcast,
37878
38487
  discoverViaUdpDirect,
37879
38488
  encodeHeader,
38489
+ ensureXmlHeader,
37880
38490
  extractH264ParamSetsFromAccessUnit,
37881
38491
  extractH265ParamSetsFromAccessUnit,
37882
38492
  extractPpsFromAnnexB,
@@ -37905,6 +38515,8 @@ var CompositeRtspServer = class extends import_node_events12.EventEmitter {
37905
38515
  maskUid,
37906
38516
  md5HexUpper,
37907
38517
  md5StrModern,
38518
+ normalizeDayNightMode,
38519
+ normalizeOpenClose,
37908
38520
  normalizeUid,
37909
38521
  packetizeAacAdtsFrame,
37910
38522
  packetizeAacRawFrame,
@@ -37914,6 +38526,7 @@ var CompositeRtspServer = class extends import_node_events12.EventEmitter {
37914
38526
  parseBcMedia,
37915
38527
  parseRecordingFileName,
37916
38528
  parseSupportXml,
38529
+ patchNestedTag,
37917
38530
  printNvrDiagnostics,
37918
38531
  runAllDiagnosticsConsecutively,
37919
38532
  runMultifocalDiagnosticsConsecutively,