@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.
@@ -31,6 +31,7 @@ import {
31
31
  BC_CMD_ID_GET_AUDIO_ALARM,
32
32
  BC_CMD_ID_GET_AUDIO_CFG,
33
33
  BC_CMD_ID_GET_AUDIO_TASK,
34
+ BC_CMD_ID_GET_AUTO_FOCUS,
34
35
  BC_CMD_ID_GET_BATTERY_INFO,
35
36
  BC_CMD_ID_GET_BATTERY_INFO_LIST,
36
37
  BC_CMD_ID_GET_DAY_NIGHT_THRESHOLD,
@@ -39,6 +40,7 @@ import {
39
40
  BC_CMD_ID_GET_DING_DONG_LIST,
40
41
  BC_CMD_ID_GET_DING_DONG_SILENT,
41
42
  BC_CMD_ID_GET_EMAIL_TASK,
43
+ BC_CMD_ID_GET_ENC,
42
44
  BC_CMD_ID_GET_FTP_TASK,
43
45
  BC_CMD_ID_GET_HDD_INFO_LIST,
44
46
  BC_CMD_ID_GET_KIT_AP_CFG,
@@ -47,6 +49,7 @@ import {
47
49
  BC_CMD_ID_GET_ONLINE_USER_LIST,
48
50
  BC_CMD_ID_GET_OSD_DATETIME,
49
51
  BC_CMD_ID_GET_PIR_INFO,
52
+ BC_CMD_ID_GET_PRIVACY_MASK,
50
53
  BC_CMD_ID_GET_PTZ_POSITION,
51
54
  BC_CMD_ID_GET_PTZ_PRESET,
52
55
  BC_CMD_ID_GET_RECORD,
@@ -76,11 +79,19 @@ import {
76
79
  BC_CMD_ID_QUICK_REPLY_PLAY,
77
80
  BC_CMD_ID_SET_AI_ALARM,
78
81
  BC_CMD_ID_SET_AI_CFG,
82
+ BC_CMD_ID_SET_AI_DENOISE,
83
+ BC_CMD_ID_SET_AUDIO_CFG,
79
84
  BC_CMD_ID_SET_AUDIO_TASK,
85
+ BC_CMD_ID_SET_AUTO_FOCUS,
86
+ BC_CMD_ID_SET_DAY_NIGHT_THRESHOLD,
80
87
  BC_CMD_ID_SET_DING_DONG_CFG,
81
88
  BC_CMD_ID_SET_DING_DONG_SILENT,
89
+ BC_CMD_ID_SET_ENC,
90
+ BC_CMD_ID_SET_LED_STATE,
82
91
  BC_CMD_ID_SET_MOTION_ALARM,
83
92
  BC_CMD_ID_SET_PIR_INFO,
93
+ BC_CMD_ID_SET_PRIVACY_MASK,
94
+ BC_CMD_ID_SET_VIDEO_INPUT,
84
95
  BC_CMD_ID_SET_WHITE_LED_STATE,
85
96
  BC_CMD_ID_SET_WHITE_LED_TASK,
86
97
  BC_CMD_ID_SET_ZOOM_FOCUS,
@@ -102,6 +113,8 @@ import {
102
113
  __require,
103
114
  aesDecrypt,
104
115
  aesEncrypt,
116
+ applyStreamPatch,
117
+ applyXmlTagPatch,
105
118
  bcDecrypt,
106
119
  bcEncrypt,
107
120
  bcHeaderHasPayloadOffset,
@@ -127,6 +140,7 @@ import {
127
140
  convertToAnnexB2,
128
141
  debugLog,
129
142
  deriveAesKey,
143
+ ensureXmlHeader,
130
144
  eventTraceLog,
131
145
  extractPpsFromAnnexB,
132
146
  extractSpsFromAnnexB,
@@ -134,8 +148,11 @@ import {
134
148
  getXmlText,
135
149
  isH265Irap,
136
150
  md5StrModern,
151
+ normalizeDayNightMode,
137
152
  normalizeDebugOptions,
153
+ normalizeOpenClose,
138
154
  parseRecordingFileName,
155
+ patchNestedTag,
139
156
  recordingsTraceLog,
140
157
  runAllDiagnosticsConsecutively,
141
158
  runMultifocalDiagnosticsConsecutively,
@@ -144,7 +161,7 @@ import {
144
161
  talkTraceLog,
145
162
  traceLog,
146
163
  xmlEscape
147
- } from "./chunk-YKKQDUKU.js";
164
+ } from "./chunk-EDLMKBG2.js";
148
165
 
149
166
  // src/protocol/framing.ts
150
167
  function encodeHeader(h) {
@@ -18460,7 +18477,7 @@ ${xml}`
18460
18477
  * @returns Test results for all stream types and profiles
18461
18478
  */
18462
18479
  async testChannelStreams(channel, logger) {
18463
- const { testChannelStreams } = await import("./DiagnosticsTools-HJDH4GPP.js");
18480
+ const { testChannelStreams } = await import("./DiagnosticsTools-RNIDFEJK.js");
18464
18481
  return await testChannelStreams({
18465
18482
  api: this,
18466
18483
  channel: this.normalizeChannel(channel),
@@ -18476,7 +18493,7 @@ ${xml}`
18476
18493
  * @returns Complete diagnostics for all channels and streams
18477
18494
  */
18478
18495
  async collectMultifocalDiagnostics(logger) {
18479
- const { collectMultifocalDiagnostics } = await import("./DiagnosticsTools-HJDH4GPP.js");
18496
+ const { collectMultifocalDiagnostics } = await import("./DiagnosticsTools-RNIDFEJK.js");
18480
18497
  return await collectMultifocalDiagnostics({
18481
18498
  api: this,
18482
18499
  logger
@@ -18494,6 +18511,373 @@ ${xml}`
18494
18511
  await this.cgiApi.login();
18495
18512
  return await this.cgiApi.getAllChannelsEvents(options);
18496
18513
  }
18514
+ // ====================================================================
18515
+ // Native Baichuan tunable-settings setters
18516
+ //
18517
+ // Replace the CGI passthroughs above with on-wire Baichuan binary
18518
+ // calls. Mirrors the @http_cmd-decorated methods in reolink_aio's
18519
+ // baichuan.py — every command has a documented `cmd_id` (read) and
18520
+ // `cmd_id` (write) pair. The pattern is:
18521
+ //
18522
+ // 1. read XML via `sendXml({ cmdId: GET, channel })`
18523
+ // 2. patch fields via regex (camera firmware is XML-strict; using
18524
+ // the parser would force us to rebuild the document and risk
18525
+ // losing unmodified attributes / element order).
18526
+ // 3. write back via `sendXml({ cmdId: SET, channel, payloadXml })`
18527
+ //
18528
+ // All getters parse via `parseXmlFragmentToJson` so the consumer gets
18529
+ // a clean JSON object instead of XML.
18530
+ // ====================================================================
18531
+ /**
18532
+ * GetEnc via Baichuan (cmdId=56). Returns the `<Compression>` block:
18533
+ * per-stream `mainStream` / `subStream` / `thirdStream` with `audio`
18534
+ * flag, `width`, `height`, `frame` (NOT `frameRate`), `bitRate`,
18535
+ * `videoEncType` (0=h264, 1=h265), `encoderProfile`, `gop`. Mirrors
18536
+ * reolink_aio's `GetEnc` — note the wire payload wraps everything
18537
+ * in `Compression`, not `Enc`.
18538
+ */
18539
+ async getEnc(channel, options) {
18540
+ const xml = await this.sendPcapDerivedSettingsGetXml({
18541
+ cmdId: BC_CMD_ID_GET_ENC,
18542
+ ...channel != null ? { channel } : {},
18543
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
18544
+ });
18545
+ return parseXmlFragmentToJson(xml);
18546
+ }
18547
+ /**
18548
+ * SetEnc via Baichuan (cmdId=57). Read-modify-write — preserves
18549
+ * unspecified fields. Mirrors reolink_aio's `SetEnc`.
18550
+ *
18551
+ * @param channel - Channel number (0-based)
18552
+ * @param patch - Fields to update on `mainStream` and/or `subStream`,
18553
+ * plus a top-level `audio` toggle (0/1). Pass only what you want
18554
+ * to change.
18555
+ */
18556
+ async setEnc(channel, patch, options) {
18557
+ const ch = this.normalizeChannel(channel);
18558
+ let xml = await this.sendXml({
18559
+ cmdId: BC_CMD_ID_GET_ENC,
18560
+ channel: ch,
18561
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
18562
+ });
18563
+ if (patch.audio !== void 0) {
18564
+ xml = xml.replace(
18565
+ /<audio>[^<]*<\/audio>/g,
18566
+ `<audio>${patch.audio}</audio>`
18567
+ );
18568
+ }
18569
+ xml = applyStreamPatch(xml, "mainStream", patch.mainStream);
18570
+ xml = applyStreamPatch(xml, "subStream", patch.subStream);
18571
+ await this.sendXml({
18572
+ cmdId: BC_CMD_ID_SET_ENC,
18573
+ channel: ch,
18574
+ payloadXml: ensureXmlHeader(xml),
18575
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
18576
+ });
18577
+ }
18578
+ /**
18579
+ * SetImage via Baichuan (cmdId=25, read via cmdId=26). Patches the
18580
+ * `<VideoInput>` block: bright / contrast / saturation / hue /
18581
+ * sharpen. Mirrors reolink_aio's `SetImage`.
18582
+ */
18583
+ async setImage(channel, patch, options) {
18584
+ const ch = this.normalizeChannel(channel);
18585
+ let xml = await this.sendXml({
18586
+ cmdId: BC_CMD_ID_GET_VIDEO_INPUT,
18587
+ channel: ch,
18588
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
18589
+ });
18590
+ xml = applyXmlTagPatch(xml, "bright", patch.bright);
18591
+ xml = applyXmlTagPatch(xml, "contrast", patch.contrast);
18592
+ xml = applyXmlTagPatch(xml, "saturation", patch.saturation);
18593
+ xml = applyXmlTagPatch(xml, "hue", patch.hue);
18594
+ xml = applyXmlTagPatch(xml, "sharpen", patch.sharpen);
18595
+ await this.sendXml({
18596
+ cmdId: BC_CMD_ID_SET_VIDEO_INPUT,
18597
+ channel: ch,
18598
+ payloadXml: ensureXmlHeader(xml),
18599
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
18600
+ });
18601
+ }
18602
+ /**
18603
+ * SetIsp via Baichuan (cmdId=25 for image side, cmdId=297 for
18604
+ * dayNightThreshold). Patches the `<InputAdvanceCfg>` block:
18605
+ * `DayNight/mode`, `Exposure/mode`, `binning_mode`, `hdrSwitch`.
18606
+ * Mirrors reolink_aio's `SetIsp`.
18607
+ *
18608
+ * @param channel - Channel number (0-based)
18609
+ * @param patch - Fields to update. `dayNight` accepts the camera's
18610
+ * raw enum (`color`, `auto`, `blackAndWhite`, …) — pass it as the
18611
+ * camera reports it (PascalCase / dotted forms get normalized
18612
+ * server-side).
18613
+ */
18614
+ async setIsp(channel, patch, options) {
18615
+ const ch = this.normalizeChannel(channel);
18616
+ const timeoutOpts = options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {};
18617
+ const wantsImageWrite = patch.dayNight !== void 0 || patch.exposure !== void 0 || patch.binningMode !== void 0 || patch.hdr !== void 0;
18618
+ if (wantsImageWrite) {
18619
+ let xml = await this.sendXml({
18620
+ cmdId: BC_CMD_ID_GET_VIDEO_INPUT,
18621
+ channel: ch,
18622
+ ...timeoutOpts
18623
+ });
18624
+ if (patch.dayNight !== void 0) {
18625
+ const normalized = normalizeDayNightMode(patch.dayNight);
18626
+ xml = patchNestedTag(xml, "DayNight", "mode", normalized);
18627
+ }
18628
+ if (patch.exposure !== void 0) {
18629
+ xml = patchNestedTag(
18630
+ xml,
18631
+ "Exposure",
18632
+ "mode",
18633
+ patch.exposure.toLowerCase()
18634
+ );
18635
+ }
18636
+ if (patch.binningMode !== void 0) {
18637
+ xml = applyXmlTagPatch(xml, "binning_mode", patch.binningMode);
18638
+ }
18639
+ if (patch.hdr !== void 0) {
18640
+ xml = applyXmlTagPatch(xml, "hdrSwitch", patch.hdr);
18641
+ }
18642
+ await this.sendXml({
18643
+ cmdId: BC_CMD_ID_SET_VIDEO_INPUT,
18644
+ channel: ch,
18645
+ payloadXml: ensureXmlHeader(xml),
18646
+ ...timeoutOpts
18647
+ });
18648
+ }
18649
+ if (patch.dayNightThreshold !== void 0) {
18650
+ let xml = await this.sendXml({
18651
+ cmdId: BC_CMD_ID_GET_DAY_NIGHT_THRESHOLD,
18652
+ channel: ch,
18653
+ ...timeoutOpts
18654
+ });
18655
+ xml = applyXmlTagPatch(xml, "cur", patch.dayNightThreshold);
18656
+ await this.sendXml({
18657
+ cmdId: BC_CMD_ID_SET_DAY_NIGHT_THRESHOLD,
18658
+ channel: ch,
18659
+ payloadXml: ensureXmlHeader(xml),
18660
+ ...timeoutOpts
18661
+ });
18662
+ }
18663
+ }
18664
+ /**
18665
+ * GetIsp via Baichuan (cmdId=26). Convenience alias of
18666
+ * `getVideoInput()` so callers that switched from CGI keep the
18667
+ * familiar name. Both return the merged VideoInput +
18668
+ * InputAdvanceCfg blob.
18669
+ */
18670
+ async getIsp(channel, options) {
18671
+ return this.getVideoInput(channel, options);
18672
+ }
18673
+ /** GetImage via Baichuan (cmdId=26). Same payload as `getIsp` —
18674
+ * Reolink merged VideoInput + InputAdvanceCfg under one cmdId. */
18675
+ async getImage(channel, options) {
18676
+ return this.getVideoInput(channel, options);
18677
+ }
18678
+ /**
18679
+ * GetIrLights via Baichuan (cmdId=208). Returns LedState block:
18680
+ * `IRLedBrightness`, `state` (ir on/off), `lightState` (status LED
18681
+ * open/close), `doorbellLightState`. Mirrors reolink_aio's
18682
+ * `get_status_led`.
18683
+ */
18684
+ async getIrLights(channel, options) {
18685
+ const xml = await this.sendPcapDerivedSettingsGetXml({
18686
+ cmdId: BC_CMD_ID_GET_LED_STATE,
18687
+ ...channel != null ? { channel } : {},
18688
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
18689
+ });
18690
+ return parseXmlFragmentToJson(xml);
18691
+ }
18692
+ /**
18693
+ * SetIrLights via Baichuan (cmdId=209, read via cmdId=208). Patches
18694
+ * IR LED + status LED + doorbell LED + IR brightness. Mirrors
18695
+ * reolink_aio's `set_status_led`.
18696
+ *
18697
+ * @param channel - Channel number (0-based)
18698
+ * @param patch - `irState` ("On" | "Off" | "Auto"), `lightState`
18699
+ * (status LED), `doorbellLightState`, `irBrightness` (0..255).
18700
+ * Camera-side accepts lowercase strings (`open`/`close`); the
18701
+ * helper normalizes from the friendly variants.
18702
+ */
18703
+ async setIrLights(channel, patch, options) {
18704
+ const ch = this.normalizeChannel(channel);
18705
+ const timeoutOpts = options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {};
18706
+ let xml = await this.sendXml({
18707
+ cmdId: BC_CMD_ID_GET_LED_STATE,
18708
+ channel: ch,
18709
+ ...timeoutOpts
18710
+ });
18711
+ if (patch.lightState !== void 0) {
18712
+ xml = applyXmlTagPatch(
18713
+ xml,
18714
+ "lightState",
18715
+ patch.lightState === "On" ? "open" : "close"
18716
+ );
18717
+ }
18718
+ if (patch.doorbellLightState !== void 0) {
18719
+ xml = applyXmlTagPatch(
18720
+ xml,
18721
+ "doorbellLightState",
18722
+ normalizeOpenClose(patch.doorbellLightState)
18723
+ );
18724
+ }
18725
+ if (patch.irState !== void 0) {
18726
+ const v = String(patch.irState);
18727
+ const out = v === "Off" ? "close" : v.toLowerCase();
18728
+ xml = applyXmlTagPatch(xml, "state", out);
18729
+ }
18730
+ if (patch.irBrightness !== void 0) {
18731
+ xml = applyXmlTagPatch(xml, "IRLedBrightness", patch.irBrightness);
18732
+ }
18733
+ await this.sendXml({
18734
+ cmdId: BC_CMD_ID_SET_LED_STATE,
18735
+ channel: ch,
18736
+ payloadXml: ensureXmlHeader(xml),
18737
+ ...timeoutOpts
18738
+ });
18739
+ }
18740
+ /**
18741
+ * SetAudioCfg via Baichuan (cmdId=265, read via cmdId=264). Patches
18742
+ * volume / talk-and-reply / visitor settings. Mirrors reolink_aio's
18743
+ * `SetAudioCfg`.
18744
+ */
18745
+ async setAudioCfg(channel, patch, options) {
18746
+ const ch = this.normalizeChannel(channel);
18747
+ const timeoutOpts = options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {};
18748
+ let xml = await this.sendXml({
18749
+ cmdId: BC_CMD_ID_GET_AUDIO_CFG,
18750
+ channel: ch,
18751
+ ...timeoutOpts
18752
+ });
18753
+ xml = applyXmlTagPatch(xml, "volume", patch.volume);
18754
+ xml = applyXmlTagPatch(
18755
+ xml,
18756
+ "talkAndReplyVolume",
18757
+ patch.talkAndReplyVolume
18758
+ );
18759
+ xml = applyXmlTagPatch(xml, "visitorVolume", patch.visitorVolume);
18760
+ xml = applyXmlTagPatch(xml, "visitorLoudspeaker", patch.visitorLoudspeaker);
18761
+ await this.sendXml({
18762
+ cmdId: BC_CMD_ID_SET_AUDIO_CFG,
18763
+ channel: ch,
18764
+ payloadXml: ensureXmlHeader(xml),
18765
+ ...timeoutOpts
18766
+ });
18767
+ }
18768
+ /**
18769
+ * GetMask (privacy mask) via Baichuan (cmdId=52). Returns the
18770
+ * `<Shelter>` block — `enable` flag + `shelterList`. Mirrors
18771
+ * reolink_aio's `GetMask`.
18772
+ */
18773
+ async getMask(channel, options) {
18774
+ const xml = await this.sendPcapDerivedSettingsGetXml({
18775
+ cmdId: BC_CMD_ID_GET_PRIVACY_MASK,
18776
+ ...channel != null ? { channel } : {},
18777
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
18778
+ });
18779
+ return parseXmlFragmentToJson(xml);
18780
+ }
18781
+ /**
18782
+ * SetMask (privacy mask) via Baichuan (cmdId=53, read via cmdId=52).
18783
+ * Toggles the `<Shelter><enable>` flag. Mirrors reolink_aio's
18784
+ * `SetMask` (which only touches enable too — shelter zone editing
18785
+ * goes through a separate flow).
18786
+ */
18787
+ async setMask(channel, patch, options) {
18788
+ const ch = this.normalizeChannel(channel);
18789
+ const timeoutOpts = options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {};
18790
+ let xml = await this.sendXml({
18791
+ cmdId: BC_CMD_ID_GET_PRIVACY_MASK,
18792
+ channel: ch,
18793
+ ...timeoutOpts
18794
+ });
18795
+ if (patch.enable !== void 0) {
18796
+ xml = applyXmlTagPatch(xml, "enable", patch.enable ? 1 : 0);
18797
+ }
18798
+ await this.sendXml({
18799
+ cmdId: BC_CMD_ID_SET_PRIVACY_MASK,
18800
+ channel: ch,
18801
+ payloadXml: ensureXmlHeader(xml),
18802
+ ...timeoutOpts
18803
+ });
18804
+ }
18805
+ /**
18806
+ * GetAudioNoise via Baichuan (cmdId=439). Reads `enable` + `level`
18807
+ * from the aiDenoise block. Mirrors reolink_aio's `GetAudioNoise`.
18808
+ *
18809
+ * Note: `getAiDenoise` already returns the same payload typed as
18810
+ * `AiDenoiseConfig`. This getter exists for naming parity with
18811
+ * reolink_aio + the reolink CGI.
18812
+ */
18813
+ async getAudioNoise(channel, options) {
18814
+ const xml = await this.sendPcapDerivedSettingsGetXml({
18815
+ cmdId: BC_CMD_ID_GET_AI_DENOISE,
18816
+ ...channel != null ? { channel } : {},
18817
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
18818
+ });
18819
+ return parseXmlFragmentToJson(xml);
18820
+ }
18821
+ /**
18822
+ * SetAudioNoise via Baichuan (cmdId=440, read via cmdId=439).
18823
+ * Mirrors reolink_aio's `SetAudioNoise` — `level <= 0` flips the
18824
+ * enable flag off; positive values turn it on and update the level.
18825
+ */
18826
+ async setAudioNoise(channel, level, options) {
18827
+ const ch = this.normalizeChannel(channel);
18828
+ const timeoutOpts = options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {};
18829
+ let xml = await this.sendXml({
18830
+ cmdId: BC_CMD_ID_GET_AI_DENOISE,
18831
+ channel: ch,
18832
+ ...timeoutOpts
18833
+ });
18834
+ xml = applyXmlTagPatch(xml, "enable", level > 0 ? 1 : 0);
18835
+ if (level > 0) {
18836
+ xml = applyXmlTagPatch(xml, "level", level);
18837
+ }
18838
+ await this.sendXml({
18839
+ cmdId: BC_CMD_ID_SET_AI_DENOISE,
18840
+ channel: ch,
18841
+ payloadXml: ensureXmlHeader(xml),
18842
+ ...timeoutOpts
18843
+ });
18844
+ }
18845
+ /**
18846
+ * GetAutoFocus via Baichuan (cmdId=224). Returns the `<AutoFocus>`
18847
+ * block — only `disable` (0 = AF on, 1 = AF off). Mirrors
18848
+ * reolink_aio's `GetAutoFocus`.
18849
+ */
18850
+ async getAutoFocus(channel, options) {
18851
+ const ch = this.normalizeChannel(channel);
18852
+ const xml = await this.sendPcapDerivedSettingsGetXml({
18853
+ cmdId: BC_CMD_ID_GET_AUTO_FOCUS,
18854
+ channel: ch,
18855
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
18856
+ });
18857
+ return parseXmlFragmentToJson(xml);
18858
+ }
18859
+ /**
18860
+ * SetAutoFocus via Baichuan (cmdId=225). Mirrors reolink_aio's
18861
+ * `SetAutoFocus`. Note: write-only command — the payload is built
18862
+ * from scratch (no read-modify-write needed).
18863
+ */
18864
+ async setAutoFocus(channel, disable, options) {
18865
+ const ch = this.normalizeChannel(channel);
18866
+ const disableVal = disable ? 1 : 0;
18867
+ const payloadXml = `<?xml version="1.0" encoding="UTF-8" ?>
18868
+ <body>
18869
+ <AutoFocus version="1.1">
18870
+ <channelId>${ch}</channelId>
18871
+ <disable>${disableVal}</disable>
18872
+ </AutoFocus>
18873
+ </body>`;
18874
+ await this.sendXml({
18875
+ cmdId: BC_CMD_ID_SET_AUTO_FOCUS,
18876
+ channel: ch,
18877
+ payloadXml,
18878
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
18879
+ });
18880
+ }
18497
18881
  /**
18498
18882
  * Passthrough to ReolinkCgiApi.getAllChannelsBatteryInfo.
18499
18883
  * Fetches battery info for all channels via CGI (merged with channel status sleep flag).
@@ -22176,4 +22560,4 @@ export {
22176
22560
  isTcpFailureThatShouldFallbackToUdp,
22177
22561
  autoDetectDeviceType
22178
22562
  };
22179
- //# sourceMappingURL=chunk-VBYF3BQX.js.map
22563
+ //# sourceMappingURL=chunk-HGQ53FB3.js.map