@apocaliss92/nodelink-js 0.4.12 → 0.4.14

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_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_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";
@@ -155,6 +155,16 @@ var init_constants = __esm({
155
155
  BC_CMD_ID_SET_PUSH_TASK = 218;
156
156
  BC_CMD_ID_GET_AUTO_FOCUS = 224;
157
157
  BC_CMD_ID_SET_AUTO_FOCUS = 225;
158
+ BC_CMD_ID_GET_EMAIL = 42;
159
+ BC_CMD_ID_SET_EMAIL = 43;
160
+ BC_CMD_ID_TEST_EMAIL = 141;
161
+ BC_CMD_ID_GET_NTP = 38;
162
+ BC_CMD_ID_SET_NTP = 39;
163
+ BC_CMD_ID_SET_SYSTEM_GENERAL = 105;
164
+ BC_CMD_ID_GET_DST = 106;
165
+ BC_CMD_ID_SET_DST = 107;
166
+ BC_CMD_ID_GET_AUTO_REBOOT = 101;
167
+ BC_CMD_ID_SET_AUTO_REBOOT = 100;
158
168
  BC_CMD_ID_CMD_123 = 123;
159
169
  BC_CMD_ID_CMD_209 = 209;
160
170
  BC_CMD_ID_CMD_265 = 265;
@@ -8117,6 +8127,7 @@ __export(index_exports, {
8117
8127
  BC_CMD_ID_GET_AUDIO_CFG: () => BC_CMD_ID_GET_AUDIO_CFG,
8118
8128
  BC_CMD_ID_GET_AUDIO_TASK: () => BC_CMD_ID_GET_AUDIO_TASK,
8119
8129
  BC_CMD_ID_GET_AUTO_FOCUS: () => BC_CMD_ID_GET_AUTO_FOCUS,
8130
+ BC_CMD_ID_GET_AUTO_REBOOT: () => BC_CMD_ID_GET_AUTO_REBOOT,
8120
8131
  BC_CMD_ID_GET_BATTERY_INFO: () => BC_CMD_ID_GET_BATTERY_INFO,
8121
8132
  BC_CMD_ID_GET_BATTERY_INFO_LIST: () => BC_CMD_ID_GET_BATTERY_INFO_LIST,
8122
8133
  BC_CMD_ID_GET_DAY_NIGHT_THRESHOLD: () => BC_CMD_ID_GET_DAY_NIGHT_THRESHOLD,
@@ -8124,6 +8135,8 @@ __export(index_exports, {
8124
8135
  BC_CMD_ID_GET_DING_DONG_CFG: () => BC_CMD_ID_GET_DING_DONG_CFG,
8125
8136
  BC_CMD_ID_GET_DING_DONG_LIST: () => BC_CMD_ID_GET_DING_DONG_LIST,
8126
8137
  BC_CMD_ID_GET_DING_DONG_SILENT: () => BC_CMD_ID_GET_DING_DONG_SILENT,
8138
+ BC_CMD_ID_GET_DST: () => BC_CMD_ID_GET_DST,
8139
+ BC_CMD_ID_GET_EMAIL: () => BC_CMD_ID_GET_EMAIL,
8127
8140
  BC_CMD_ID_GET_EMAIL_TASK: () => BC_CMD_ID_GET_EMAIL_TASK,
8128
8141
  BC_CMD_ID_GET_ENC: () => BC_CMD_ID_GET_ENC,
8129
8142
  BC_CMD_ID_GET_FTP_TASK: () => BC_CMD_ID_GET_FTP_TASK,
@@ -8131,6 +8144,7 @@ __export(index_exports, {
8131
8144
  BC_CMD_ID_GET_KIT_AP_CFG: () => BC_CMD_ID_GET_KIT_AP_CFG,
8132
8145
  BC_CMD_ID_GET_LED_STATE: () => BC_CMD_ID_GET_LED_STATE,
8133
8146
  BC_CMD_ID_GET_MOTION_ALARM: () => BC_CMD_ID_GET_MOTION_ALARM,
8147
+ BC_CMD_ID_GET_NTP: () => BC_CMD_ID_GET_NTP,
8134
8148
  BC_CMD_ID_GET_ONLINE_USER_LIST: () => BC_CMD_ID_GET_ONLINE_USER_LIST,
8135
8149
  BC_CMD_ID_GET_OSD_DATETIME: () => BC_CMD_ID_GET_OSD_DATETIME,
8136
8150
  BC_CMD_ID_GET_PIR_INFO: () => BC_CMD_ID_GET_PIR_INFO,
@@ -8171,19 +8185,24 @@ __export(index_exports, {
8171
8185
  BC_CMD_ID_SET_AUDIO_CFG: () => BC_CMD_ID_SET_AUDIO_CFG,
8172
8186
  BC_CMD_ID_SET_AUDIO_TASK: () => BC_CMD_ID_SET_AUDIO_TASK,
8173
8187
  BC_CMD_ID_SET_AUTO_FOCUS: () => BC_CMD_ID_SET_AUTO_FOCUS,
8188
+ BC_CMD_ID_SET_AUTO_REBOOT: () => BC_CMD_ID_SET_AUTO_REBOOT,
8174
8189
  BC_CMD_ID_SET_DAY_NIGHT_THRESHOLD: () => BC_CMD_ID_SET_DAY_NIGHT_THRESHOLD,
8175
8190
  BC_CMD_ID_SET_DING_DONG_CFG: () => BC_CMD_ID_SET_DING_DONG_CFG,
8176
8191
  BC_CMD_ID_SET_DING_DONG_SILENT: () => BC_CMD_ID_SET_DING_DONG_SILENT,
8192
+ BC_CMD_ID_SET_DST: () => BC_CMD_ID_SET_DST,
8193
+ BC_CMD_ID_SET_EMAIL: () => BC_CMD_ID_SET_EMAIL,
8177
8194
  BC_CMD_ID_SET_EMAIL_TASK: () => BC_CMD_ID_SET_EMAIL_TASK,
8178
8195
  BC_CMD_ID_SET_ENC: () => BC_CMD_ID_SET_ENC,
8179
8196
  BC_CMD_ID_SET_LED_STATE: () => BC_CMD_ID_SET_LED_STATE,
8180
8197
  BC_CMD_ID_SET_MOTION_ALARM: () => BC_CMD_ID_SET_MOTION_ALARM,
8198
+ BC_CMD_ID_SET_NTP: () => BC_CMD_ID_SET_NTP,
8181
8199
  BC_CMD_ID_SET_OSD_DATETIME: () => BC_CMD_ID_SET_OSD_DATETIME,
8182
8200
  BC_CMD_ID_SET_PIR_INFO: () => BC_CMD_ID_SET_PIR_INFO,
8183
8201
  BC_CMD_ID_SET_PRIVACY_MASK: () => BC_CMD_ID_SET_PRIVACY_MASK,
8184
8202
  BC_CMD_ID_SET_PUSH_TASK: () => BC_CMD_ID_SET_PUSH_TASK,
8185
8203
  BC_CMD_ID_SET_RECORD: () => BC_CMD_ID_SET_RECORD,
8186
8204
  BC_CMD_ID_SET_RECORD_CFG: () => BC_CMD_ID_SET_RECORD_CFG,
8205
+ BC_CMD_ID_SET_SYSTEM_GENERAL: () => BC_CMD_ID_SET_SYSTEM_GENERAL,
8187
8206
  BC_CMD_ID_SET_VIDEO_INPUT: () => BC_CMD_ID_SET_VIDEO_INPUT,
8188
8207
  BC_CMD_ID_SET_WHITE_LED_STATE: () => BC_CMD_ID_SET_WHITE_LED_STATE,
8189
8208
  BC_CMD_ID_SET_WHITE_LED_TASK: () => BC_CMD_ID_SET_WHITE_LED_TASK,
@@ -8193,6 +8212,7 @@ __export(index_exports, {
8193
8212
  BC_CMD_ID_TALK_ABILITY: () => BC_CMD_ID_TALK_ABILITY,
8194
8213
  BC_CMD_ID_TALK_CONFIG: () => BC_CMD_ID_TALK_CONFIG,
8195
8214
  BC_CMD_ID_TALK_RESET: () => BC_CMD_ID_TALK_RESET,
8215
+ BC_CMD_ID_TEST_EMAIL: () => BC_CMD_ID_TEST_EMAIL,
8196
8216
  BC_CMD_ID_UDP_KEEP_ALIVE: () => BC_CMD_ID_UDP_KEEP_ALIVE,
8197
8217
  BC_CMD_ID_VIDEO: () => BC_CMD_ID_VIDEO,
8198
8218
  BC_CMD_ID_VIDEO_STOP: () => BC_CMD_ID_VIDEO_STOP,
@@ -16302,6 +16322,309 @@ function parseXmlFragmentToJson(xml) {
16302
16322
  return parsed.root;
16303
16323
  }
16304
16324
 
16325
+ // src/reolink/baichuan/utils/email.ts
16326
+ init_xml();
16327
+ var parseInt01 = (text) => {
16328
+ if (text === void 0) return void 0;
16329
+ return text.trim() === "1" ? 1 : 0;
16330
+ };
16331
+ var parseNumberSafe = (text) => {
16332
+ if (text === void 0) return void 0;
16333
+ const n = Number(text);
16334
+ return Number.isFinite(n) ? n : void 0;
16335
+ };
16336
+ var VALID_ATTACHMENT_TYPES = [
16337
+ "picture",
16338
+ "video",
16339
+ "none"
16340
+ ];
16341
+ var VALID_TEXT_TYPES = ["withText", "noText"];
16342
+ var normalizeAttachmentType = (text) => {
16343
+ const t = (text ?? "").trim();
16344
+ return VALID_ATTACHMENT_TYPES.includes(t) ? t : "picture";
16345
+ };
16346
+ var normalizeTextType = (text) => {
16347
+ const t = (text ?? "").trim();
16348
+ return VALID_TEXT_TYPES.includes(t) ? t : "withText";
16349
+ };
16350
+ function parseEmailConfigFromXml(xml) {
16351
+ const cfg = {
16352
+ smtpServer: getXmlText(xml, "smtpServer") ?? "",
16353
+ userName: getXmlText(xml, "userName") ?? "",
16354
+ password: getXmlText(xml, "password") ?? "",
16355
+ address1: getXmlText(xml, "address1") ?? "",
16356
+ address2: getXmlText(xml, "address2") ?? "",
16357
+ address3: getXmlText(xml, "address3") ?? "",
16358
+ smtpPort: parseNumberSafe(getXmlText(xml, "smtpPort")) ?? 0,
16359
+ sendNickname: getXmlText(xml, "sendNickname") ?? "",
16360
+ attachment: parseInt01(getXmlText(xml, "attachment")) ?? 0,
16361
+ attachmentType: normalizeAttachmentType(getXmlText(xml, "attachmentType")),
16362
+ textType: normalizeTextType(getXmlText(xml, "textType")),
16363
+ ssl: parseInt01(getXmlText(xml, "ssl")) ?? 0,
16364
+ interval: parseNumberSafe(getXmlText(xml, "interval")) ?? 30
16365
+ };
16366
+ const senderMaxLen = parseNumberSafe(getXmlText(xml, "senderMaxLen"));
16367
+ if (senderMaxLen !== void 0) cfg.senderMaxLen = senderMaxLen;
16368
+ const pwdMaxLen = parseNumberSafe(getXmlText(xml, "pwdMaxLen"));
16369
+ if (pwdMaxLen !== void 0) cfg.pwdMaxLen = pwdMaxLen;
16370
+ const ability = parseNumberSafe(getXmlText(xml, "emailAttachAbility"));
16371
+ if (ability !== void 0) cfg.emailAttachAbility = ability;
16372
+ return cfg;
16373
+ }
16374
+ function buildSetEmailXml(current, patch) {
16375
+ const merged = { ...current, ...patch };
16376
+ return ensureXmlHeader(
16377
+ `<body><Email version="1.1"><smtpServer>${xmlEscape(merged.smtpServer)}</smtpServer><userName>${xmlEscape(merged.userName)}</userName><password>${xmlEscape(merged.password)}</password><address1>${xmlEscape(merged.address1)}</address1><address2>${xmlEscape(merged.address2)}</address2><address3>${xmlEscape(merged.address3)}</address3><smtpPort>${merged.smtpPort}</smtpPort><sendNickname>${xmlEscape(merged.sendNickname)}</sendNickname><attachment>${merged.attachment}</attachment><attachmentType>${merged.attachmentType}</attachmentType><textType>${merged.textType}</textType><ssl>${merged.ssl}</ssl><interval>${merged.interval}</interval></Email></body>`
16378
+ );
16379
+ }
16380
+ function parseEmailTaskFromXml(xml) {
16381
+ const channelId = parseNumberSafe(getXmlText(xml, "channelId")) ?? 0;
16382
+ const enable = parseInt01(getXmlText(xml, "enable")) ?? 0;
16383
+ const items = [];
16384
+ const itemRe = /<item>([\s\S]*?)<\/item>/g;
16385
+ let match;
16386
+ while ((match = itemRe.exec(xml)) !== null) {
16387
+ const block = match[1] ?? "";
16388
+ items.push({
16389
+ type: getXmlText(block, "type") ?? "none",
16390
+ valueTable: getXmlText(block, "valueTable") ?? ""
16391
+ });
16392
+ }
16393
+ return { channelId, enable, typeScheduleList: items };
16394
+ }
16395
+ function buildEmailScheduleValueTable(spec) {
16396
+ if (spec.kind === "always") return "1".repeat(168);
16397
+ const grid = new Array(168).fill("0");
16398
+ if (spec.kind === "never") return grid.join("");
16399
+ for (const w of spec.windows) {
16400
+ const startH = Math.max(0, Math.min(24, w.startHour));
16401
+ const endH = Math.max(startH, Math.min(24, w.endHour));
16402
+ for (const d of w.days) {
16403
+ if (d < 0 || d > 6) continue;
16404
+ for (let h = startH; h < endH; h++) {
16405
+ grid[d * 24 + h] = "1";
16406
+ }
16407
+ }
16408
+ }
16409
+ return grid.join("");
16410
+ }
16411
+ function buildSetEmailTaskXml(task) {
16412
+ const items = task.typeScheduleList.map(
16413
+ (item) => `<item><type>${xmlEscape(item.type)}</type><valueTable>${xmlEscape(item.valueTable)}</valueTable></item>`
16414
+ ).join("");
16415
+ return ensureXmlHeader(
16416
+ `<body><EmailTask version="1.1"><channelId>${task.channelId}</channelId><enable>${task.enable}</enable><typeScheduleList>${items}</typeScheduleList></EmailTask></body>`
16417
+ );
16418
+ }
16419
+
16420
+ // src/reolink/baichuan/utils/ntp.ts
16421
+ init_xml();
16422
+ var parseNumberSafe2 = (text) => {
16423
+ if (text === void 0) return void 0;
16424
+ const n = Number(text);
16425
+ return Number.isFinite(n) ? n : void 0;
16426
+ };
16427
+ var parseInt012 = (text) => {
16428
+ if (text === void 0) return void 0;
16429
+ return text.trim() === "1" ? 1 : 0;
16430
+ };
16431
+ function parseNtpConfigFromXml(xml) {
16432
+ return {
16433
+ enable: parseInt012(getXmlText(xml, "enable")) ?? 0,
16434
+ server: getXmlText(xml, "server") ?? "",
16435
+ synchronizeInterval: parseNumberSafe2(getXmlText(xml, "synchronizeInterval")) ?? 1440,
16436
+ port: parseNumberSafe2(getXmlText(xml, "port")) ?? 123
16437
+ };
16438
+ }
16439
+ function buildSetNtpXml(current, patch) {
16440
+ const merged = { ...current, ...patch };
16441
+ return ensureXmlHeader(
16442
+ `<body><Ntp version="1.1"><enable>${merged.enable}</enable><server>${xmlEscape(merged.server)}</server><synchronizeInterval>${merged.synchronizeInterval}</synchronizeInterval><port>${merged.port}</port></Ntp></body>`
16443
+ );
16444
+ }
16445
+
16446
+ // src/reolink/baichuan/utils/dst.ts
16447
+ init_xml();
16448
+ var parseNumberSafe3 = (text) => {
16449
+ if (text === void 0) return void 0;
16450
+ const n = Number(text);
16451
+ return Number.isFinite(n) ? n : void 0;
16452
+ };
16453
+ var parseInt013 = (text) => {
16454
+ if (text === void 0) return void 0;
16455
+ return text.trim() === "1" ? 1 : 0;
16456
+ };
16457
+ var VALID_WEEKDAYS = [
16458
+ "Sunday",
16459
+ "Monday",
16460
+ "Tuesday",
16461
+ "Wednesday",
16462
+ "Thursday",
16463
+ "Friday",
16464
+ "Saturday"
16465
+ ];
16466
+ var normalizeWeekday = (text) => {
16467
+ const t = (text ?? "").trim();
16468
+ return VALID_WEEKDAYS.includes(t) ? t : "Sunday";
16469
+ };
16470
+ function parseDstConfigFromXml(xml) {
16471
+ const cfg = {
16472
+ enable: parseInt013(getXmlText(xml, "enable")) ?? 0,
16473
+ offset: parseNumberSafe3(getXmlText(xml, "offset")) ?? 1,
16474
+ startMonth: parseNumberSafe3(getXmlText(xml, "startMonth")) ?? 3,
16475
+ startWeekIndex: parseNumberSafe3(getXmlText(xml, "startWeekIndex")) ?? 5,
16476
+ startWeekday: normalizeWeekday(getXmlText(xml, "startWeekday")),
16477
+ startHour: parseNumberSafe3(getXmlText(xml, "startHour")) ?? 2,
16478
+ startMinute: parseNumberSafe3(getXmlText(xml, "startMinute")) ?? 0,
16479
+ startSecond: parseNumberSafe3(getXmlText(xml, "startSecond")) ?? 0,
16480
+ endMonth: parseNumberSafe3(getXmlText(xml, "endMonth")) ?? 10,
16481
+ endWeekIndex: parseNumberSafe3(getXmlText(xml, "endWeekIndex")) ?? 4,
16482
+ endWeekday: normalizeWeekday(getXmlText(xml, "endWeekday")),
16483
+ endHour: parseNumberSafe3(getXmlText(xml, "endHour")) ?? 3,
16484
+ endMinute: parseNumberSafe3(getXmlText(xml, "endMinute")) ?? 0,
16485
+ endSecond: parseNumberSafe3(getXmlText(xml, "endSecond")) ?? 0
16486
+ };
16487
+ const version = parseNumberSafe3(getXmlText(xml, "version"));
16488
+ if (version !== void 0) cfg.version = version;
16489
+ return cfg;
16490
+ }
16491
+ function buildSetDstXml(current, patch) {
16492
+ const merged = { ...current, ...patch };
16493
+ return ensureXmlHeader(
16494
+ `<body><Dst version="1.1"><enable>${merged.enable}</enable><offset>${merged.offset}</offset><startMonth>${merged.startMonth}</startMonth><startWeekIndex>${merged.startWeekIndex}</startWeekIndex><startWeekday>${xmlEscape(merged.startWeekday)}</startWeekday><startHour>${merged.startHour}</startHour><startMinute>${merged.startMinute}</startMinute><startSecond>${merged.startSecond}</startSecond><endMonth>${merged.endMonth}</endMonth><endWeekIndex>${merged.endWeekIndex}</endWeekIndex><endWeekday>${xmlEscape(merged.endWeekday)}</endWeekday><endHour>${merged.endHour}</endHour><endMinute>${merged.endMinute}</endMinute><endSecond>${merged.endSecond}</endSecond></Dst></body>`
16495
+ );
16496
+ }
16497
+
16498
+ // src/reolink/baichuan/utils/autoReboot.ts
16499
+ init_xml();
16500
+ var parseNumberSafe4 = (text) => {
16501
+ if (text === void 0) return void 0;
16502
+ const n = Number(text);
16503
+ return Number.isFinite(n) ? n : void 0;
16504
+ };
16505
+ var parseInt014 = (text) => {
16506
+ if (text === void 0) return void 0;
16507
+ return text.trim() === "1" ? 1 : 0;
16508
+ };
16509
+ var VALID_WEEKDAYS2 = [
16510
+ "Sunday",
16511
+ "Monday",
16512
+ "Tuesday",
16513
+ "Wednesday",
16514
+ "Thursday",
16515
+ "Friday",
16516
+ "Saturday",
16517
+ "everyday"
16518
+ ];
16519
+ var normalizeWeekday2 = (text) => {
16520
+ const t = (text ?? "").trim();
16521
+ return VALID_WEEKDAYS2.includes(t) ? t : "Sunday";
16522
+ };
16523
+ function parseAutoRebootFromXml(xml) {
16524
+ return {
16525
+ enable: parseInt014(getXmlText(xml, "enable")) ?? 0,
16526
+ weekDay: normalizeWeekday2(getXmlText(xml, "weekDay")),
16527
+ hour: parseNumberSafe4(getXmlText(xml, "hour")) ?? 0,
16528
+ minute: parseNumberSafe4(getXmlText(xml, "minute")) ?? 0,
16529
+ second: parseNumberSafe4(getXmlText(xml, "second")) ?? 0
16530
+ };
16531
+ }
16532
+ function buildSetAutoRebootXml(current, patch) {
16533
+ const merged = { ...current, ...patch };
16534
+ return ensureXmlHeader(
16535
+ `<body><AutoReboot version="1.1"><enable>${merged.enable}</enable><weekDay>${xmlEscape(merged.weekDay)}</weekDay><hour>${merged.hour}</hour><minute>${merged.minute}</minute><second>${merged.second}</second></AutoReboot></body>`
16536
+ );
16537
+ }
16538
+
16539
+ // src/reolink/baichuan/utils/systemGeneral.ts
16540
+ init_xml();
16541
+ var parseNumberSafe5 = (text) => {
16542
+ if (text === void 0) return void 0;
16543
+ const n = Number(text);
16544
+ return Number.isFinite(n) ? n : void 0;
16545
+ };
16546
+ var parseInt015 = (text) => {
16547
+ if (text === void 0) return void 0;
16548
+ return text.trim() === "1" ? 1 : 0;
16549
+ };
16550
+ var VALID_OSD_FORMATS = ["DMY", "MDY", "YMD"];
16551
+ var normalizeOsdFormat = (text) => {
16552
+ const t = (text ?? "").trim();
16553
+ return VALID_OSD_FORMATS.includes(t) ? t : "YMD";
16554
+ };
16555
+ function parseSystemGeneralFromXml(xml) {
16556
+ return {
16557
+ timeZone: parseNumberSafe5(getXmlText(xml, "timeZone")) ?? 0,
16558
+ osdFormat: normalizeOsdFormat(getXmlText(xml, "osdFormat")),
16559
+ year: parseNumberSafe5(getXmlText(xml, "year")) ?? 0,
16560
+ month: parseNumberSafe5(getXmlText(xml, "month")) ?? 0,
16561
+ day: parseNumberSafe5(getXmlText(xml, "day")) ?? 0,
16562
+ hour: parseNumberSafe5(getXmlText(xml, "hour")) ?? 0,
16563
+ minute: parseNumberSafe5(getXmlText(xml, "minute")) ?? 0,
16564
+ second: parseNumberSafe5(getXmlText(xml, "second")) ?? 0,
16565
+ deviceId: parseNumberSafe5(getXmlText(xml, "deviceId")) ?? 0,
16566
+ timeFormat: parseInt015(getXmlText(xml, "timeFormat")) ?? 0,
16567
+ language: getXmlText(xml, "language") ?? "English",
16568
+ deviceName: getXmlText(xml, "deviceName") ?? "",
16569
+ loginLock: parseInt015(getXmlText(xml, "loginLock")) ?? 0,
16570
+ lockTime: parseNumberSafe5(getXmlText(xml, "lockTime")) ?? 0,
16571
+ allowedTimes: parseNumberSafe5(getXmlText(xml, "allowedTimes")) ?? 0,
16572
+ isDst: parseInt015(getXmlText(xml, "isDst")) ?? 0
16573
+ };
16574
+ }
16575
+ function buildSetSystemGeneralXml(patch) {
16576
+ const parts = [];
16577
+ const isDeviceNameOnly = patch.deviceName !== void 0 && patch.timeZone === void 0 && patch.osdFormat === void 0 && patch.timeFormat === void 0 && patch.language === void 0 && patch.loginLock === void 0 && patch.lockTime === void 0 && patch.allowedTimes === void 0 && patch.manualTime === void 0;
16578
+ if (isDeviceNameOnly) {
16579
+ parts.push("<year>0</year>");
16580
+ parts.push(`<deviceName>${xmlEscape(patch.deviceName)}</deviceName>`);
16581
+ parts.push("<deviceNameOnly>1</deviceNameOnly>");
16582
+ } else if (patch.manualTime !== void 0) {
16583
+ const mt = patch.manualTime;
16584
+ if (patch.timeZone !== void 0)
16585
+ parts.push(`<timeZone>${patch.timeZone}</timeZone>`);
16586
+ if (patch.osdFormat !== void 0)
16587
+ parts.push(`<osdFormat>${patch.osdFormat}</osdFormat>`);
16588
+ parts.push(`<year>${mt.year}</year>`);
16589
+ parts.push(`<month>${mt.month}</month>`);
16590
+ parts.push(`<day>${mt.day}</day>`);
16591
+ parts.push(`<hour>${mt.hour}</hour>`);
16592
+ parts.push(`<minute>${mt.minute}</minute>`);
16593
+ parts.push(`<second>${mt.second}</second>`);
16594
+ if (patch.timeFormat !== void 0)
16595
+ parts.push(`<timeFormat>${patch.timeFormat}</timeFormat>`);
16596
+ if (patch.language !== void 0)
16597
+ parts.push(`<language>${xmlEscape(patch.language)}</language>`);
16598
+ if (patch.deviceName !== void 0)
16599
+ parts.push(`<deviceName>${xmlEscape(patch.deviceName)}</deviceName>`);
16600
+ if (patch.loginLock !== void 0)
16601
+ parts.push(`<loginLock>${patch.loginLock}</loginLock>`);
16602
+ if (patch.lockTime !== void 0)
16603
+ parts.push(`<lockTime>${patch.lockTime}</lockTime>`);
16604
+ if (patch.allowedTimes !== void 0)
16605
+ parts.push(`<allowedTimes>${patch.allowedTimes}</allowedTimes>`);
16606
+ } else {
16607
+ if (patch.timeZone !== void 0)
16608
+ parts.push(`<timeZone>${patch.timeZone}</timeZone>`);
16609
+ if (patch.osdFormat !== void 0)
16610
+ parts.push(`<osdFormat>${patch.osdFormat}</osdFormat>`);
16611
+ if (patch.timeFormat !== void 0)
16612
+ parts.push(`<timeFormat>${patch.timeFormat}</timeFormat>`);
16613
+ if (patch.language !== void 0)
16614
+ parts.push(`<language>${xmlEscape(patch.language)}</language>`);
16615
+ if (patch.loginLock !== void 0)
16616
+ parts.push(`<loginLock>${patch.loginLock}</loginLock>`);
16617
+ if (patch.lockTime !== void 0)
16618
+ parts.push(`<lockTime>${patch.lockTime}</lockTime>`);
16619
+ if (patch.allowedTimes !== void 0)
16620
+ parts.push(`<allowedTimes>${patch.allowedTimes}</allowedTimes>`);
16621
+ parts.push("<year>0</year>");
16622
+ }
16623
+ return ensureXmlHeader(
16624
+ `<body><SystemGeneral version="1.1">${parts.join("")}</SystemGeneral></body>`
16625
+ );
16626
+ }
16627
+
16305
16628
  // src/reolink/baichuan/ReolinkBaichuanApi.ts
16306
16629
  var import_jimp = require("jimp");
16307
16630
  init_ReolinkCgiApi();
@@ -28325,7 +28648,26 @@ ${xml}`
28325
28648
  */
28326
28649
  async getEncOptions(channel, options) {
28327
28650
  const list = await this.getStreamInfoList(channel, options);
28328
- return buildEncOptions(list, channel);
28651
+ const built = buildEncOptions(list, channel);
28652
+ try {
28653
+ const enc = await this.getEnc(channel, options);
28654
+ const compression = enc.body?.Compression;
28655
+ const mergeGop = (target, stream) => {
28656
+ if (!target || !stream) return;
28657
+ const g = stream.gop;
28658
+ if (!g) return;
28659
+ target.gopRange = {
28660
+ ...g.cur !== void 0 ? { cur: g.cur } : {},
28661
+ ...g.min !== void 0 ? { min: g.min } : {},
28662
+ ...g.max !== void 0 ? { max: g.max } : {}
28663
+ };
28664
+ };
28665
+ mergeGop(built.mainStream, compression?.mainStream);
28666
+ mergeGop(built.subStream, compression?.subStream);
28667
+ mergeGop(built.thirdStream, compression?.thirdStream);
28668
+ } catch {
28669
+ }
28670
+ return built;
28329
28671
  }
28330
28672
  /**
28331
28673
  * Read the camera's `<VersionInfo>` block (cmd_id=80). Returns the
@@ -28430,7 +28772,279 @@ ${xml}`
28430
28772
  ...channel != null ? { channel } : {},
28431
28773
  ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
28432
28774
  });
28433
- return parseXmlFragmentToJson(xml);
28775
+ return parseEmailTaskFromXml(xml);
28776
+ }
28777
+ /**
28778
+ * SetEmailTask via Baichuan (cmdId=216). Updates the email alarm schedule
28779
+ * (per-event-type 7×24 valueTable + master enable).
28780
+ *
28781
+ * Reolink expects the FULL `typeScheduleList` — pass the array from a prior
28782
+ * GET and only flip the entries you care about. Slots you don't track must
28783
+ * be sent back unchanged to avoid the camera dropping them.
28784
+ */
28785
+ async setEmailTask(channel, task, options) {
28786
+ const ch = this.normalizeChannel(channel);
28787
+ const payloadXml = buildSetEmailTaskXml({ ...task, channelId: ch });
28788
+ await this.sendXml({
28789
+ cmdId: BC_CMD_ID_SET_EMAIL_TASK,
28790
+ channel: ch,
28791
+ payloadXml,
28792
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
28793
+ });
28794
+ }
28795
+ /**
28796
+ * Convenience wrapper that patches the schedule of one or more trigger
28797
+ * types on the camera's EmailTask without touching the others.
28798
+ *
28799
+ * Pass a high-level schedule spec (`always` / `never` / explicit windows)
28800
+ * and the trigger types it should apply to. The method:
28801
+ *
28802
+ * 1. Reads the current EmailTask via GET (so we keep every existing slot).
28803
+ * 2. Builds the new `valueTable` once from `schedule`.
28804
+ * 3. Replaces the `valueTable` of every matching `type` in the list.
28805
+ * 4. Appends entries for any requested type not already present.
28806
+ * 5. Writes the merged list back via SET.
28807
+ *
28808
+ * Returns the list of types that were actually touched.
28809
+ */
28810
+ async patchEmailSchedule(channel, spec, options) {
28811
+ const current = await this.getEmailTask(channel, options);
28812
+ const newValueTable = buildEmailScheduleValueTable(spec.schedule);
28813
+ const targetSet = new Set(spec.types);
28814
+ const touched = [];
28815
+ const updatedList = current.typeScheduleList.map((item) => {
28816
+ if (targetSet.has(item.type)) {
28817
+ touched.push(item.type);
28818
+ return { ...item, valueTable: newValueTable };
28819
+ }
28820
+ return item;
28821
+ });
28822
+ for (const t of spec.types) {
28823
+ if (!current.typeScheduleList.some((item) => item.type === t)) {
28824
+ updatedList.push({ type: t, valueTable: newValueTable });
28825
+ touched.push(t);
28826
+ }
28827
+ }
28828
+ await this.setEmailTask(
28829
+ channel,
28830
+ {
28831
+ channelId: current.channelId,
28832
+ enable: spec.enable ?? current.enable,
28833
+ typeScheduleList: updatedList
28834
+ },
28835
+ options
28836
+ );
28837
+ return { touchedTypes: touched };
28838
+ }
28839
+ // ====================================================================
28840
+ // Email server (cmdId 42/43/141), NTP (38/39), DST (106/107),
28841
+ // SystemGeneral SET (105), AutoReboot (100/101).
28842
+ // Schemas derived from Reolink Client pcap (2026-05-16).
28843
+ // ====================================================================
28844
+ /**
28845
+ * Read the SMTP email configuration (cmdId=42). Returns the full `<Email>`
28846
+ * block including capability hints (`senderMaxLen`, `pwdMaxLen`,
28847
+ * `emailAttachAbility`).
28848
+ */
28849
+ async getEmail(options) {
28850
+ const xml = await this.sendXml({
28851
+ cmdId: BC_CMD_ID_GET_EMAIL,
28852
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
28853
+ });
28854
+ return parseEmailConfigFromXml(xml);
28855
+ }
28856
+ /**
28857
+ * Patch the SMTP email configuration (cmdId=43). Reads the current config
28858
+ * first then merges the patch — Reolink rejects partial `<Email>` blocks.
28859
+ */
28860
+ async setEmail(patch, options) {
28861
+ const current = await this.getEmail(options);
28862
+ const payloadXml = buildSetEmailXml(current, patch);
28863
+ await this.sendXml({
28864
+ cmdId: BC_CMD_ID_SET_EMAIL,
28865
+ payloadXml,
28866
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
28867
+ });
28868
+ }
28869
+ /**
28870
+ * Send a test email using either the current config or an override patch
28871
+ * (cmdId=141). Returns true when the camera reports 200 (test succeeded),
28872
+ * false when it reports 482 (test failed — server unreachable / bad creds).
28873
+ * Other non-200 codes propagate as exceptions via `sendXml`.
28874
+ */
28875
+ async testEmail(patch, options) {
28876
+ const current = await this.getEmail(options);
28877
+ const payloadXml = buildSetEmailXml(current, patch ?? {});
28878
+ const timeoutMs = options?.timeoutMs ?? 6e4;
28879
+ try {
28880
+ await this.sendXml({
28881
+ cmdId: BC_CMD_ID_TEST_EMAIL,
28882
+ payloadXml,
28883
+ timeoutMs
28884
+ });
28885
+ return true;
28886
+ } catch (err) {
28887
+ const msg = err instanceof Error ? err.message : String(err);
28888
+ if (msg.includes("response_code 482") || msg.includes("response_code=482")) {
28889
+ return false;
28890
+ }
28891
+ throw err;
28892
+ }
28893
+ }
28894
+ /**
28895
+ * Read the NTP server configuration (cmdId=38).
28896
+ */
28897
+ async getNtp(options) {
28898
+ const xml = await this.sendXml({
28899
+ cmdId: BC_CMD_ID_GET_NTP,
28900
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
28901
+ });
28902
+ return parseNtpConfigFromXml(xml);
28903
+ }
28904
+ /**
28905
+ * Patch the NTP server configuration (cmdId=39). Reads the current state
28906
+ * first and merges the patch — Reolink rejects partial `<Ntp>` blocks.
28907
+ */
28908
+ async setNtp(patch, options) {
28909
+ const current = await this.getNtp(options);
28910
+ const payloadXml = buildSetNtpXml(current, patch);
28911
+ await this.sendXml({
28912
+ cmdId: BC_CMD_ID_SET_NTP,
28913
+ payloadXml,
28914
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
28915
+ });
28916
+ }
28917
+ /**
28918
+ * Patch SystemGeneral (cmdId=105). Supports partial payloads: include only
28919
+ * the fields you want to change. By default the builder emits `<year>0</year>`
28920
+ * as the "do not set manual clock" marker; pass `manualTime` to actually
28921
+ * set the date/time. Setting only `deviceName` automatically uses the
28922
+ * Reolink Client's `deviceNameOnly=1` shape.
28923
+ */
28924
+ async setSystemGeneral(patch, options) {
28925
+ const payloadXml = buildSetSystemGeneralXml(patch);
28926
+ await this.sendXml({
28927
+ cmdId: BC_CMD_ID_SET_SYSTEM_GENERAL,
28928
+ payloadXml,
28929
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
28930
+ });
28931
+ }
28932
+ /**
28933
+ * Read the Daylight Saving Time configuration (cmdId=106).
28934
+ */
28935
+ async getDst(options) {
28936
+ const xml = await this.sendXml({
28937
+ cmdId: BC_CMD_ID_GET_DST,
28938
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
28939
+ });
28940
+ return parseDstConfigFromXml(xml);
28941
+ }
28942
+ /**
28943
+ * Patch the DST configuration (cmdId=107). Reads the current state first
28944
+ * and merges the patch.
28945
+ */
28946
+ async setDst(patch, options) {
28947
+ const current = await this.getDst(options);
28948
+ const payloadXml = buildSetDstXml(current, patch);
28949
+ await this.sendXml({
28950
+ cmdId: BC_CMD_ID_SET_DST,
28951
+ payloadXml,
28952
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
28953
+ });
28954
+ }
28955
+ /**
28956
+ * Read the auto-reboot schedule (cmdId=101).
28957
+ */
28958
+ async getAutoReboot(options) {
28959
+ const xml = await this.sendXml({
28960
+ cmdId: BC_CMD_ID_GET_AUTO_REBOOT,
28961
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
28962
+ });
28963
+ return parseAutoRebootFromXml(xml);
28964
+ }
28965
+ /**
28966
+ * Patch the auto-reboot schedule (cmdId=100).
28967
+ */
28968
+ async setAutoReboot(patch, options) {
28969
+ const current = await this.getAutoReboot(options);
28970
+ const payloadXml = buildSetAutoRebootXml(current, patch);
28971
+ await this.sendXml({
28972
+ cmdId: BC_CMD_ID_SET_AUTO_REBOOT,
28973
+ payloadXml,
28974
+ ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
28975
+ });
28976
+ }
28977
+ /**
28978
+ * High-level helper that configures the camera to deliver motion alerts via
28979
+ * SMTP to the local nodelink manager. Orchestrates `setEmail` + `setEmailTask`
28980
+ * in a single call so UI code can offer "auto-configure" without juggling
28981
+ * the underlying commands.
28982
+ *
28983
+ * Pass `runTest: true` to also send a test email (cmdId=141). Returns a
28984
+ * structured result describing each leg of the flow so the caller can show
28985
+ * granular feedback.
28986
+ *
28987
+ * @param params Auto-configuration parameters
28988
+ * @param channel Logical channel (default 0). Used for the EmailTask SET.
28989
+ */
28990
+ async setupEmailPushToManager(params, channel, options) {
28991
+ const port = params.managerPort ?? 2525;
28992
+ const domain = params.domain ?? "nodelink.local";
28993
+ const recipient = `${params.recipientLocalPart}@${domain}`;
28994
+ const triggers = params.triggerTypes ?? ["MD", "people", "vehicle"];
28995
+ const attachmentType = params.attachmentType ?? "picture";
28996
+ const interval = params.interval ?? 30;
28997
+ const emailPatch = {
28998
+ smtpServer: params.managerHost,
28999
+ smtpPort: port,
29000
+ userName: params.authUsername ?? recipient,
29001
+ password: params.authPassword ?? "",
29002
+ address1: recipient,
29003
+ address2: "",
29004
+ address3: "",
29005
+ sendNickname: params.sendNickname ?? params.recipientLocalPart,
29006
+ attachment: attachmentType === "none" ? 0 : 1,
29007
+ attachmentType,
29008
+ textType: "withText",
29009
+ ssl: 0,
29010
+ interval
29011
+ };
29012
+ await this.setEmail(emailPatch, options);
29013
+ const fullWeekOn = "1".repeat(168);
29014
+ const current = await this.getEmailTask(channel, options);
29015
+ const triggerSet = new Set(triggers);
29016
+ const touched = [];
29017
+ const updatedList = current.typeScheduleList.map((item) => {
29018
+ if (triggerSet.has(item.type)) {
29019
+ touched.push(item.type);
29020
+ return { ...item, valueTable: fullWeekOn };
29021
+ }
29022
+ return item;
29023
+ });
29024
+ for (const t of triggers) {
29025
+ if (!current.typeScheduleList.some((item) => item.type === t)) {
29026
+ updatedList.push({ type: t, valueTable: fullWeekOn });
29027
+ touched.push(t);
29028
+ }
29029
+ }
29030
+ await this.setEmailTask(
29031
+ channel,
29032
+ {
29033
+ channelId: current.channelId,
29034
+ enable: 1,
29035
+ typeScheduleList: updatedList
29036
+ },
29037
+ options
29038
+ );
29039
+ const result = {
29040
+ setEmail: { applied: true },
29041
+ setEmailTask: { applied: true, touchedTypes: touched }
29042
+ };
29043
+ if (params.runTest) {
29044
+ const ok = await this.testEmail(emailPatch, options);
29045
+ result.testEmail = { success: ok };
29046
+ }
29047
+ return result;
28434
29048
  }
28435
29049
  /**
28436
29050
  * Get siren-on-motion state via AudioTask (cmdId=232).
@@ -28699,7 +29313,7 @@ ${xml}`
28699
29313
  cmdId: BC_CMD_ID_GET_SYSTEM_GENERAL,
28700
29314
  ...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
28701
29315
  });
28702
- return parseXmlFragmentToJson(xml);
29316
+ return parseSystemGeneralFromXml(xml);
28703
29317
  }
28704
29318
  /**
28705
29319
  * Get device support/capability flags.
@@ -39567,6 +40181,7 @@ function base64DecodeToBytes(b64) {
39567
40181
  BC_CMD_ID_GET_AUDIO_CFG,
39568
40182
  BC_CMD_ID_GET_AUDIO_TASK,
39569
40183
  BC_CMD_ID_GET_AUTO_FOCUS,
40184
+ BC_CMD_ID_GET_AUTO_REBOOT,
39570
40185
  BC_CMD_ID_GET_BATTERY_INFO,
39571
40186
  BC_CMD_ID_GET_BATTERY_INFO_LIST,
39572
40187
  BC_CMD_ID_GET_DAY_NIGHT_THRESHOLD,
@@ -39574,6 +40189,8 @@ function base64DecodeToBytes(b64) {
39574
40189
  BC_CMD_ID_GET_DING_DONG_CFG,
39575
40190
  BC_CMD_ID_GET_DING_DONG_LIST,
39576
40191
  BC_CMD_ID_GET_DING_DONG_SILENT,
40192
+ BC_CMD_ID_GET_DST,
40193
+ BC_CMD_ID_GET_EMAIL,
39577
40194
  BC_CMD_ID_GET_EMAIL_TASK,
39578
40195
  BC_CMD_ID_GET_ENC,
39579
40196
  BC_CMD_ID_GET_FTP_TASK,
@@ -39581,6 +40198,7 @@ function base64DecodeToBytes(b64) {
39581
40198
  BC_CMD_ID_GET_KIT_AP_CFG,
39582
40199
  BC_CMD_ID_GET_LED_STATE,
39583
40200
  BC_CMD_ID_GET_MOTION_ALARM,
40201
+ BC_CMD_ID_GET_NTP,
39584
40202
  BC_CMD_ID_GET_ONLINE_USER_LIST,
39585
40203
  BC_CMD_ID_GET_OSD_DATETIME,
39586
40204
  BC_CMD_ID_GET_PIR_INFO,
@@ -39621,19 +40239,24 @@ function base64DecodeToBytes(b64) {
39621
40239
  BC_CMD_ID_SET_AUDIO_CFG,
39622
40240
  BC_CMD_ID_SET_AUDIO_TASK,
39623
40241
  BC_CMD_ID_SET_AUTO_FOCUS,
40242
+ BC_CMD_ID_SET_AUTO_REBOOT,
39624
40243
  BC_CMD_ID_SET_DAY_NIGHT_THRESHOLD,
39625
40244
  BC_CMD_ID_SET_DING_DONG_CFG,
39626
40245
  BC_CMD_ID_SET_DING_DONG_SILENT,
40246
+ BC_CMD_ID_SET_DST,
40247
+ BC_CMD_ID_SET_EMAIL,
39627
40248
  BC_CMD_ID_SET_EMAIL_TASK,
39628
40249
  BC_CMD_ID_SET_ENC,
39629
40250
  BC_CMD_ID_SET_LED_STATE,
39630
40251
  BC_CMD_ID_SET_MOTION_ALARM,
40252
+ BC_CMD_ID_SET_NTP,
39631
40253
  BC_CMD_ID_SET_OSD_DATETIME,
39632
40254
  BC_CMD_ID_SET_PIR_INFO,
39633
40255
  BC_CMD_ID_SET_PRIVACY_MASK,
39634
40256
  BC_CMD_ID_SET_PUSH_TASK,
39635
40257
  BC_CMD_ID_SET_RECORD,
39636
40258
  BC_CMD_ID_SET_RECORD_CFG,
40259
+ BC_CMD_ID_SET_SYSTEM_GENERAL,
39637
40260
  BC_CMD_ID_SET_VIDEO_INPUT,
39638
40261
  BC_CMD_ID_SET_WHITE_LED_STATE,
39639
40262
  BC_CMD_ID_SET_WHITE_LED_TASK,
@@ -39643,6 +40266,7 @@ function base64DecodeToBytes(b64) {
39643
40266
  BC_CMD_ID_TALK_ABILITY,
39644
40267
  BC_CMD_ID_TALK_CONFIG,
39645
40268
  BC_CMD_ID_TALK_RESET,
40269
+ BC_CMD_ID_TEST_EMAIL,
39646
40270
  BC_CMD_ID_UDP_KEEP_ALIVE,
39647
40271
  BC_CMD_ID_VIDEO,
39648
40272
  BC_CMD_ID_VIDEO_STOP,