mod.ts

Reolink camera client over Baichuan, Reolink's own TCP protocol (port 9000).

Examples

Stream doorbell and motion events

import { createClient } from "@hertzg/reolink-api";

const conn = await Deno.connect({ hostname: "192.168.1.10", port: 9000 });
const client = createClient({ readable: conn.readable, writable: conn.writable });

await client.login({ username: "admin", password: "secret" });
const events = await client.subscribe();

for await (const event of events) {
  // { channel: 0, motion: true, visitor: false, tamper: false, ai: ["people"] }
  console.log(event);
}

await client.close();
conn.close();

Read a setting with any command

import { COMMANDS, createClient } from "@hertzg/reolink-api";

const conn = await Deno.connect({ hostname: "192.168.1.10", port: 9000 });
const client = createClient({ readable: conn.readable, writable: conn.writable });

await client.login({ username: "admin", password: "secret" });
const { body } = await client.call(COMMANDS.GET_NTPCFG_V20);
console.log(body.Ntp);

await client.close();
conn.close();

Take a snapshot and sound the siren

import { createClient } from "@hertzg/reolink-api";

const conn = await Deno.connect({ hostname: "192.168.1.10", port: 9000 });
const client = createClient({ readable: conn.readable, writable: conn.writable });

await client.login({ username: "admin", password: "secret" });
await Deno.writeFile("front-door.jpg", await client.snapshot());
await client.playSiren({ times: 2 });

await client.close();
conn.close();

Functions

f
createClient(options: ClientOptions): Client

Creates a Baichuan client over the given connection streams.

Type Aliases

T
AlarmEvent = { channel: number; motion: boolean; visitor: boolean; tamper: boolean; ai: string[]; }

The alarm state of one channel, as the camera pushed it.

T
CallOptions<C extends Command> = { channel?: number; body?: CommandBody<C>; }

Options for Client.call.

T
CallReply<C extends Command> = { body: CommandBody<C>; payload: Uint8Array; }

The reply to Client.call.

T
ChannelOptions = { channel?: number; }

Which camera a request is about.

  • channel: number

    The zero-based channel number. A standalone camera is 0, the default.

T
Client = { login: (options: LoginOptions) => Promise<void>; subscribe: (options?: SubscribeOptions) => Promise<ReadableStream<AlarmEvent>>; playSiren: (options?: ChannelOptions & { times?: number; }) => Promise<void>; startSiren: (options?: ChannelOptions) => Promise<void>; stopSiren: (options?: ChannelOptions) => Promise<void>; privacyMode: (options?: ChannelOptions) => Promise<boolean>; setPrivacyMode: (options: ChannelOptions & { enabled: boolean; }) => Promise<void>; snapshot: (options?: ChannelOptions & { stream?: "main" | "sub"; }) => Promise<Uint8Array>; ptz: (options: ChannelOptions & { command: PtzCommand; speed?: number; }) => Promise<void>; ptzPresets: (options?: ChannelOptions) => Promise<PtzPreset[]>; ptzGoToPreset: (options: ChannelOptions & { id: number; }) => Promise<void>; ptzPosition: (options?: ChannelOptions) => Promise<PtzPosition>; call: <C extends Command>(
command: C,
options?: CallOptions<C>
) => Promise<CallReply<C>>
; pushes: () => ReadableStream<Push>; close: () => Promise<void>; }

A Baichuan client bound to one connection.

T
Command<P extends readonly AnyXmlParam[] = readonly AnyXmlParam[]> = { id: number; name: string; params: P; firmware: readonly Firmware[]; }

A Baichuan command: its id, firmware name, and parameter elements.

  • firmware: readonly Firmware[]

    The firmware builds known to register the command, empty when unknown. Registration does not promise that a given device answers it.

  • id: number

    The command id sent in the message header.

  • name: string

    The name the firmware's dispatch table gives the command.

  • params: P

    The parameter elements the command's bodies may carry.

T
CommandBody<C extends Command> = [P in C["params"][number] in keyof P["name"]]?: XmlParamValue<P>

The body of a Command, request or reply: each of its parameters by element name, all optional.

T
Commands = { HEART_BEAT_V20: Command<readonly [heartBeat]>; LOGIN: Command<
readonly [
loginUser,
loginNet,
ipcVersionList,
deviceInfo,
streamInfoList,
loginErrInfo,
accessInfo
]
>
; LOGOUT: Command<readonly [loginUser]>; START_PREVIEW: Command<readonly [preview]>; STOP_PREVIEW: Command<readonly [preview]>; START_REPLAY: Command<readonly [fileInfoList]>; STOP_REPLAY: Command<readonly [fileInfoList]>; DOWNLOAD_V20: Command<readonly [fileInfoList]>; DOWNLOAD_STOP_V20: Command<readonly [fileInfoList]>; GET_TALK_ABILITY: Command<readonly [talkAbility]>; TALK_CLOSE_V20: Command<readonly []>; FILE_INFO: Command<readonly [fileInfoList]>; SEARCH_OPEN: Command<readonly [fileInfoList]>; SEARCH_FILE: Command<readonly [fileInfoList]>; SEARCH_CLOSE: Command<readonly [fileInfoList]>; PTZ_CONTROL_V20: Command<readonly [ptzControl]>; PTZ_PRESET_V20: Command<readonly [ptzPreset]>; PTZ_CRUISE_V20: Command<readonly [ptzCruise]>; REBOOT_V20: Command<readonly []>; SETVEDIOPARAM_V20: Command<readonly [videoInput, inputAdvanceCfg]>; GETVEDIOPARAM_V20: Command<readonly [videoInput, inputAdvanceCfg]>; START_ALARM_REPORT: Command<readonly []>; SET_NETPORT_CFG_V20: Command<
readonly [
serverPort,
httpPort,
rtspPort,
onvifPort,
httpsPort,
rtmpPort
]
>
; GET_NETPORT_CFG_V20: Command<
readonly [
serverPort,
httpPort,
rtspPort,
onvifPort,
httpsPort,
rtmpPort
]
>
; GET_NTPCFG_V20: Command<readonly [ntp]>; SET_NTPCFG_V20: Command<readonly [ntp]>; GET_DDNSCFG_V20: Command<readonly [ddns]>; SET_DDNSCFG_V20: Command<readonly [ddns]>; GET_EMAILCFG_V20: Command<readonly [email]>; SET_EMAILCFG_V20: Command<readonly [email]>; GET_OSD_CFG_V20: Command<readonly [osdChannelName, osdDatetime]>; SET_OSD_CFG_V20: Command<readonly [osdChannelName, osdDatetime]>; GET_MD_CFG_V20: Command<readonly [md]>; SET_MD_CFG_V20: Command<readonly [md]>; GET_SHELTER_CFG_V20: Command<readonly [shelter]>; SET_SHELTER_CFG_V20: Command<readonly [shelter]>; GET_RECORD_V20: Command<readonly [recordCfg]>; SET_RECORD_V20: Command<readonly [recordCfg]>; GET_COMPRESSIONCFG_V20: Command<readonly [compression]>; SET_COMPRESSIONCFG_V20: Command<readonly [compression]>; GET_USERCFG_V20: Command<readonly [abilitySuppport, userList]>; SET_USERCFG_V20: Command<readonly [userList]>; GET_PTZCRUISE_V20: Command<readonly [ptzCruise]>; EXPORT_CFG_V20: Command<readonly [configFileInfo]>; UPDATE_DEVICE: Command<readonly [configFileInfo, paramDataV20]>; GET_FTPCFG_V20: Command<readonly [ftp]>; SET_FTPCFG_V20: Command<readonly [ftp]>; GET_FTPTASK_V20: Command<readonly [ftpTask]>; SET_FTPTASK_V20: Command<readonly [ftpTask]>; GET_LOCAL_LINK_V20: Command<readonly [dhcp, autoDns, ip, dns]>; SET_LOCAL_LINK_V20: Command<readonly [dhcp, autoDns, ip, dns]>; GET_VERSION_V20: Command<readonly [versionInfo]>; GET_RECSCHEDULE_V20: Command<readonly [record]>; SET_RECSCHEDULE_V20: Command<readonly [record]>; GET_LINK_TYPE: Command<readonly [linkType]>; GET_UPNPSTATE_V20: Command<readonly [upnp]>; SET_UPNPSTATE_V20: Command<readonly [upnp]>; SET_RESTORE_V20: Command<readonly [restore]>; SET_AUTO_REBOOT_CFG_V20: Command<readonly [autoReboot]>; GET_AUTO_REBOOT_CFG_V20: Command<readonly [autoReboot]>; GET_HDD_CFG_V20: Command<readonly [hddInfoList]>; INIT_HDD_V20: Command<readonly [hddInitList]>; GET_SYSGENERAL_CFG_V20: Command<readonly [systemGeneral, norm]>; SET_SYSGENERAL_CFG_V20: Command<readonly [systemGeneral, norm]>; GET_DST_CFG_V20: Command<readonly [dst]>; SET_DST_CFG_V20: Command<readonly [dst]>; SNAP_V20: Command<readonly [snap]>; GET_DEF_OSD_CFG_V20: Command<readonly [osdChannelName, osdDatetime]>; GET_DEF_INPUT_CFG_V20: Command<readonly [videoInput, shelter]>; GET_DEF_ENC_CFG_V20: Command<readonly [compression]>; GET_DEF_MD_CFG_V20: Command<readonly [md]>; GET_UID_CFG_V20: Command<readonly [uid]>; GET_WIFI_SIGNAL_V20: Command<readonly [wifiSignal]>; GET_WIFI_INFO_V20: Command<readonly [wifi]>; SET_WIFI_INFO_V20: Command<readonly [wifi]>; GET_USER_ONLINE_V20: Command<readonly [onlineUserList]>; SET_USER_ONLINE_V20: Command<readonly [onlineUserList]>; INFO_PERFORMANCE_V20: Command<readonly [performanceInfo]>; REPLAY_SEEK: Command<readonly [replaySeek]>; PUSH_ADD_V20: Command<readonly [pushInfo, pushRspInfo]>; PUSH_DEL_V20: Command<readonly [pushInfo]>; GET_DEF_ISP_CFG_V20: Command<readonly [inputAdvanceCfg, videoInput]>; EMAIL_TEST_V20: Command<readonly [email]>; GET_DAY_RECORD: Command<readonly [dayRecords]>; DOWNLOAD_CUT_V20: Command<readonly [fileInfoList]>; DOWNLOAD_CUT_STOP_V20: Command<readonly []>; GET_ENC_CAPABILITY_V20: Command<readonly [streamInfoList]>; GET_ABILITY: Command<readonly [abilityInfo]>; CGI_GET_POWER_LINE_FREQUENCY: Command<readonly [inputAdvanceCfg, powerLineFrequency]>; CGI_SET_POWER_LINE_FREQUENCY: Command<readonly [inputAdvanceCfg]>; CGI_GET_EXPOSURE: Command<readonly [inputAdvanceCfg, exposureCfg]>; CGI_SET_EXPOSURE: Command<readonly [inputAdvanceCfg]>; CGI_GET_SHUTTER: Command<readonly [inputAdvanceCfg, shutter]>; CGI_SET_SHUTTER: Command<readonly [inputAdvanceCfg]>; CGI_GET_GAIN: Command<readonly [inputAdvanceCfg, gain]>; CGI_SET_GAIN: Command<readonly [inputAdvanceCfg]>; CGI_GET_SCENE: Command<readonly [inputAdvanceCfg, scene]>; CGI_SET_SCENE: Command<readonly [inputAdvanceCfg]>; CGI_GET_DAY_NIGHT_MODE: Command<readonly [inputAdvanceCfg, dayNightMode]>; CGI_SET_DAY_NIGHT_MODE: Command<readonly [inputAdvanceCfg]>; CGI_GET_IRCUT_MODE: Command<readonly [inputAdvanceCfg, ircutMode]>; CGI_SET_IRCUT_MODE: Command<readonly [inputAdvanceCfg]>; CGI_GET_BLC: Command<readonly [inputAdvanceCfg, blc]>; CGI_SET_BLC: Command<readonly [inputAdvanceCfg]>; CGI_GET_MIRROR: Command<readonly [inputAdvanceCfg, mirror]>; CGI_SET_MIRROR: Command<readonly [inputAdvanceCfg]>; CGI_GET_FLIP: Command<readonly [inputAdvanceCfg, flip]>; CGI_SET_FLIP: Command<readonly [inputAdvanceCfg]>; IFRAME_REQUEST: Command<readonly [requestIframe]>; GET_PTZ_PRESET_V20: Command<readonly [ptzPreset]>; ONLINE_UPDATE_V20: Command<readonly [onlineUpdate]>; START_ALARM_REPORT_192: Command<readonly []>; FTP_TEST_V20: Command<readonly [ftp, ftpTestResult]>; UPDATE_CFG_GET_V20: Command<readonly [autoUpdate]>; UPDATE_CFG_SET_V20: Command<readonly [autoUpdate]>; GET_ONLINE_NEW_FW_V20: Command<readonly [onlineNewFirmwareInfo]>; GET_SCAN_AP_V20: Command<readonly [scanAp]>; GET_SUPPORT: Command<readonly [support]>; WIFI_TEST_V20: Command<readonly [wifi]>; TALK_OPEN_V20: Command<readonly [talkConfig]>; TALK_FDX_STREAM_V20: Command<readonly [paramDataV20]>; GET_LED_STATE_V20: Command<readonly [ledState]>; SET_LED_STATE_V20: Command<readonly [ledState]>; GET_PTOP_CFG_V20: Command<readonly [ptop]>; SET_PTOP_CFG_V20: Command<readonly [ptop]>; GET_RF_CFG_V20: Command<readonly [rfAlarmCfg]>; SET_RF_CFG_V20: Command<readonly [rfAlarmCfg]>; SET_EMAILTASK_V20: Command<readonly [emailTask]>; GET_EMAILTASK_V20: Command<readonly [emailTask]>; SET_PUSHTASK_V20: Command<readonly [pushTask]>; GET_PUSHTASK_V20: Command<readonly [pushTask]>; GET_AUTO_FOCUS_V20: Command<readonly [autoFocus]>; SET_AUTO_FOCUS_V20: Command<readonly [autoFocus]>; GET_ONLINE_UPDATE_STATE: Command<readonly [upgradeState]>; GET_CROP_V20: Command<readonly [crop]>; SET_CROP_V20: Command<readonly [crop]>; CROP_SNAP_V20: Command<readonly [cropSnap, cropSnapReply]>; SET_AUDIOTASK_V20: Command<readonly [audioTask]>; GET_AUDIOTASK_V20: Command<readonly [audioTask]>; SET_DEVICE_SLEEP: Command<readonly []>; SET_CLOUD_TASK_V20: Command<readonly [cloudTask]>; GET_CLOUD_TASK_V20: Command<readonly [cloudTask]>; GET_BAT_INFO_V20: Command<readonly [chargeBatteryInfo, batteryInfo]>; GET_4GNET_INFO: Command<readonly [net3g4gInfo]>; GET_4GMODULE_INFO: Command<readonly [net3g4gModuleInfo]>; GET_BATTERY_REMAIN_V20: Command<readonly [batteryRemainList]>; GET_AUDIO_INFO_V20: Command<readonly [audioFileInfo]>; IMPORT_AUDIO_V20: Command<readonly [audioFileInfo, paramDataV20]>; SAVE_AUDIO_V20: Command<readonly [audioFileInfo]>; PLAY_AUDIO_V20: Command<readonly [audioPlayInfo]>; GET_AUDIO_CFG_V20: Command<readonly [audioCfg]>; SET_AUDIO_CFG_V20: Command<readonly [audioCfg]>; MUTE_AUDIO_V20: Command<readonly [muteAudio]>; GET_AUDIO_ENCODE_ABILITY_V20: Command<readonly [audioEncodeAbility]>; NEW_GET_CLOUD_BIND_INFO_V20: Command<readonly [cloudBindInfo]>; NEW_BIND_CLOUD_V20: Command<readonly [bindCloud]>; GET_CLOUD_CFG_V20: Command<readonly [cloudUploadCfg]>; SET_CLOUD_CFG_V20: Command<readonly [cloudUploadCfg]>; START_FIND_ALARM_VIDEO_V20: Command<readonly [findAlarmVideo]>; DO_FIND_ALARM_VIDEO_V20: Command<readonly [findAlarmVideo, alarmVideoInfo]>; STOP_FIND_ALARM_VIDEO_V20: Command<readonly [findAlarmVideo]>; BIND_NAS: Command<readonly [bindUnbindNas]>; UNBIND_NAS: Command<readonly [bindUnbindNas]>; GET_BIND_INFO_V20: Command<readonly [bindNasInfoList]>; GET_CLOUD_LOGIN_V20: Command<readonly [cloudLoginKey]>; SET_CLOUD_LOGIN_V20: Command<readonly [cloudLoginKey]>; SET_GOP_V20: Command<readonly [gopCfg]>; SET_TIME_V20: Command<readonly [timeCfg]>; SET_FLOODLIGHT_STATUS: Command<readonly [floodlightManual]>; GET_FLOODLIGHT_TASK: Command<readonly [floodlightTask]>; SET_FLOODLIGHT_TASK: Command<readonly [floodlightTask]>; GET_ZOOM_FOCUS_INFO_V20: Command<readonly [zoomFocusInfo, ptzZoomFocus]>; GET_ZOOM_FOCUS_INFO_V20_295: Command<readonly [startZoomFocus]>; GET_DAY_NIGHT_THRESHOLD_V20: Command<readonly [dayNightThreshold]>; SET_DAY_NIGHT_THRESHOLD_V20: Command<readonly [dayNightThreshold]>; COVER_PREVIEW: Command<readonly [coverPreview]>; GET_AI_CFG: Command<readonly [aiCfg]>; SET_AI_CFG: Command<readonly [aiCfg]>; GET_NAS_CFG: Command<readonly [nasUploadCfg]>; SET_NAS_CFG: Command<readonly [nasUploadCfg]>; GET_TIMELAPSE_CFG_V20: Command<readonly [timelapseCfg]>; SET_TIMELAPSE_CFG_V20: Command<readonly [timelapseCfg]>; GET_TIMELAPSE_TASK_V20: Command<readonly [timelapseTasks]>; GET_TIMELAPSE_DATE_V20: Command<readonly [timelapseDateTbl]>; GET_TIMELAPSE_OPEN_V20: Command<readonly [timelapseFileSearch]>; GET_TIMELAPSE_NEXT_V20: Command<readonly [timelapseFileSearch]>; GET_TIMELAPSE_CLOSE_V20: Command<readonly [timelapseFileSearch]>; GET_TIMELAPSE_FILE_COVER_V20: Command<readonly [timelapseCover]>; GET_TIMELAPSE_DOWNLOAD_V20: Command<readonly [timelapseDownload]>; GET_TIMELAPSE_DLD_STOP_V20: Command<readonly []>; GET_TIMELAPSE_DELETE_V20: Command<readonly [timelapseTaskDel]>; GET_TIMELAPSE_FILE_DEL_V20: Command<readonly [timelapseFileDel]>; SET_GUARD_V20: Command<readonly [ptzGuard]>; GET_GUARD_V20: Command<readonly [ptzGuard]>; GET_PTZ_AUTO_TEST_V20: Command<readonly [ptzAutoTest]>; PTZ_AUTO_TEST_V20: Command<readonly []>; GET_AI_DETECT_CFG_V20: Command<readonly [aiDetectCfg]>; SET_AI_DETECT_CFG_V20: Command<readonly [aiDetectCfg]>; GET_DEF_AI_DETECT_CFG_V20: Command<readonly [aiDetectCfg]>; SET_ALARM_AREA_V20: Command<readonly [alarmArea]>; GET_SMT_PLAY_URL_V20: Command<readonly [smtPlayUrl, smtPlayUrlReply]>; GET_AUDIO_FILE_INFO_LIST_V20: Command<readonly [audioFileInfoList]>; DELETE_AUDIO_FILE_V20: Command<readonly [audioFileInfo]>; PLAY_ALARM_ALERTOR_V20: Command<readonly [audioFileInfo]>; STOP_ALARM_ALERTOR_V20: Command<readonly []>; GET_NETWORK_DIAGNOSIS_DATA_V20: Command<readonly [networkDiagnosisData]>; PUSH_TEST_V20: Command<readonly [pushTestResult]>; GET_AI_TRACK_DATA_V20: Command<readonly [aiTrackData]>; GET_PUSH_CFG_V20: Command<readonly [pushCfg]>; SET_PUSH_CFG_V20: Command<readonly [pushCfg]>; CLOUD_TEST_V20: Command<readonly [cloudTestResult]>; SET_AUDIO_FILE_INFO_LIST_V20: Command<readonly [audioFileInfoList]>; START_REPLAY_BY_TM: Command<readonly [replayByTimeV2]>; STOP_REPLAY_BY_TM: Command<readonly [replayByTimeV2]>; SEEK_REPLAY_BY_TM: Command<readonly [replaySeekV2]>; BIND_IOT_V20: Command<readonly [iotBindUnBind]>; UNBIND_IOT_V20: Command<readonly [iotBindUnBind]>; GET_BIND_IOT_INFO_V20: Command<readonly [iotBindInfoList]>; GET_IOT_ACTION_V20: Command<readonly [iotAction, iotActionList]>; SET_IOT_ACTION_V20: Command<readonly [iotAction]>; EXPORT_AUDIO_V20: Command<readonly [audioFileInfo]>; IMPORT_IMAGE_V20: Command<readonly [imageFileInfo, paramDataV20]>; EXPORT_IMAGE_V20: Command<readonly [imageFileInfo]>; GET_AUTO_REPLY: Command<readonly [autoReply]>; SET_AUTO_REPLY: Command<readonly [autoReply]>; GET_PTZ_CUR_POS_V20: Command<readonly [ptzCurPos]>; GET_AI_TRACK_LIMIT_V20: Command<readonly [trackLimit]>; SET_AI_TRACK_LIMIT_V20: Command<readonly [trackLimit]>; GET_AI_TRACK_TASK_V20: Command<readonly [trackSchedule]>; SET_AI_TRACK_TASK_V20: Command<readonly [trackSchedule]>; PTZ_3D_LOCATION_V20: Command<readonly [ptz3DLocation]>; GET_AF_ALGORITHM_V20: Command<readonly [afAlgorithm]>; SET_AF_ALGORITHM_V20: Command<readonly [afAlgorithm]>; GET_HTTPS_CERT_INFO: Command<readonly [certificateInfo]>; SET_HTTPS_CERT_INFO: Command<readonly [certificateInfo]>; DINGDONG_CTRL: Command<readonly [dingdongCtrl]>; DINGDONG_LIST_GET: Command<readonly [dingdongList]>; DINGDONG_DEV_OPT: Command<readonly [dingdongDeviceOpt]>; DINGDONG_CFG_GET: Command<readonly [dingdongCfg]>; DINGDONG_CFG_SET: Command<readonly [dingdongCfg]>; AUTH_MODE_CODE_GET: Command<readonly [authInfo]>; GET_SHARED_USER_CFG: Command<readonly [accessUserList]>; SET_SHARED_USER_CFG: Command<readonly [accessUserList]>; SYNC_SSID: Command<readonly [syncSsid]>; GET_CLIENT_ID: Command<readonly [pushClientId]>; CREATE_PUSH_LISTENER: Command<readonly [pushCreateListener]>; SYNC_CLIENT_LIST: Command<readonly []>; GET_CLIENT_STATE: Command<readonly [pushClientState]>; GET_SLEEP_STATE: Command<readonly [sleepState]>; SET_SLEEP_STATE: Command<readonly [sleepState]>; NET_GET_FREQ_CORRECT_RESULT: Command<readonly [freqCorrectResult]>; GET_DINGDONG_SILENT_MODE: Command<readonly [dingdongSilentMode]>; SET_DINGDONG_SILENT_MODE: Command<readonly [dingdongSilentMode]>; INSTANT_PLAY_AUDIO: Command<readonly [audioFileInfo, paramDataV20]>; SET_ANSWER_EVENT: Command<readonly [answerEvent]>; DELETE_RECORD_FILE: Command<readonly [deleteRecordFile]>; SET_AI_YUV_STREAM_CFG: Command<readonly [aiyuvCfg]>; }

The firmware request commands, keyed by name.

T
LoginOptions = { username: string; password: string; }

Camera credentials for Client.login.

T
PtzCommand = (PTZ_COMMAND)[keyof PTZ_COMMAND]

Union of the PTZ_COMMAND values.

T
PtzPosition = { pan: number; tilt: number; }

Where the camera points, in the camera's own motor units.

T
PtzPreset = { id: number; name: string; }

A saved PTZ position.

T
Pushes = { ALARM_EVENT_REPORT: Command<readonly [alarmEventList]>; VIDEO_INPUT_CHANGE_REPORT: Command<readonly [videoInput]>; SERIAL_CHANGE_REPORT: Command<readonly [serial]>; BATTERY_CAMERA_HEARTBEAT: Command<readonly []>; BATTERY_STATUS_REPORT: Command<readonly [batteryList]>; MOBILE_NETWORK_REPORT: Command<readonly [net3g4gInfo]>; FLOODLIGHT_STATUS_REPORT: Command<readonly [floodlightStatusList]>; CHIME_SCAN_REPORT: Command<readonly [dingdongList]>; SLEEP_STATUS_REPORT: Command<readonly [sleepStatus]>; }

The messages the firmware pushes unasked, keyed by a descriptive name.

T
SubscribeOptions = { keepAliveMs?: number; }

Options for Client.subscribe.

  • keepAliveMs: number

    How long the connection may stay silent before the client pings the camera, in milliseconds. If a second interval passes with nothing from the camera, the event stream errors. Defaults to 30_000.

Variables

v
COMMANDS: Commands

The firmware request commands, for Client.call.

v
PTZ_COMMAND: { STOP: string; LEFT: string; RIGHT: string; UP: string; DOWN: string; LEFT_UP: string; LEFT_DOWN: string; RIGHT_UP: string; RIGHT_DOWN: string; ZOOM_IN: string; ZOOM_OUT: string; AUTO: string; }

PTZ commands for ptzControlXml. A move keeps going until STOP.

v
PUSHES: Pushes

The messages the firmware pushes unasked. Names are descriptive: the firmware dispatch tables only list requests.

encoding/header.ts

Baichuan message header coder.

Examples

Encode and decode the nonce request header

import { assertEquals } from "@std/assert";
import { decode, encode } from "@hertzg/binstruct";
import {
  BAICHUAN_MESSAGE_CLASS,
  baichuanHeader,
} from "@hertzg/reolink-api/encoding/header";

const header = {
  cmdId: 1,
  bodyLength: 0,
  channelId: 250,
  messageId: 1,
  encryption: 0xdc12,
  messageClass: BAICHUAN_MESSAGE_CLASS.LEGACY,
};

const bytes = encode(baichuanHeader(), header);

assertEquals(bytes.length, 20);
assertEquals(decode(baichuanHeader(), bytes), header);

Functions

f
baichuanHeader(): Coder<BaichuanHeader>

Creates a coder for a BaichuanHeader.

f
headerLength(messageClass: number): 20 | 24

Returns the header length in bytes for a message class.

Type Aliases

Variables

v
BAICHUAN_MAGIC: 180150000

The four bytes f0 de bc 0a that open every message, read as u32le.

v
BAICHUAN_MESSAGE_CLASS: { LEGACY: number; MODERN: number; MODERN_WITH_OFFSET: number; MODERN_WITH_OFFSET_ALT: number; }

Message classes (bytes 18-19, read as u16be). The class decides the header length, see headerLength.

encoding/cipher.ts

The two ciphers Baichuan uses for message bodies.

Examples

Scramble and unscramble a body with the XOR cipher

import { assertEquals } from "@std/assert";
import { xorCipher } from "@hertzg/reolink-api/encoding/cipher";

const plain = new TextEncoder().encode("<?xml");
const scrambled = xorCipher(plain, 250);

assertEquals(scrambled, Uint8Array.of(0xfa, 0x8e, 0xd8, 0xfe, 0xee));
assertEquals(xorCipher(scrambled, 250), plain);

Functions

f
aesCfbDecrypt(
key: Uint8Array,
data: Uint8Array
): Uint8Array

Decrypts a body encrypted with AES-128-CFB, 128-bit segments, IV "0123456789abcdef".

f
aesCfbEncrypt(
key: Uint8Array,
data: Uint8Array
): Uint8Array

Encrypts a body with AES-128-CFB, 128-bit segments, IV "0123456789abcdef".

f
xorCipher(
data: Uint8Array,
offset: number
): Uint8Array

Applies the Baichuan XOR cipher. The cipher is its own inverse, so the same call encrypts and decrypts.

protocol/message.ts

Baichuan messages: a header plus the bytes that follow it.

Examples

Build a subscribe request and read its header

import { assertEquals } from "@std/assert";
import {
  BAICHUAN_CHANNEL,
  BAICHUAN_CMD,
  createMessage,
} from "@hertzg/reolink-api/protocol/message";

const message = createMessage({
  cmdId: BAICHUAN_CMD.SUBSCRIBE,
  channelId: BAICHUAN_CHANNEL.PUSH,
  messageId: 3,
});

assertEquals(message.header, {
  cmdId: 31,
  bodyLength: 0,
  channelId: 251,
  messageId: 3,
  status: 0,
  messageClass: 0x1464,
  payloadOffset: 0,
});

Functions

f
createMessage(options: CreateMessageOptions): BaichuanMessage

Builds a request message, filling in the header from the options.

f
decryptPayload(
message: BaichuanMessage,
aesKey: Uint8Array
): Uint8Array

Decrypts the binary payload of a received message, such as a snapshot chunk.

f
extensionXml(channel: number): string

Builds the extension XML that addresses a request to one camera channel.

Type Aliases

T
BaichuanMessage = { header: BaichuanHeader; body: Uint8Array; payload: Uint8Array; }

A Baichuan message: a header and the bytes after it, split at header.payloadOffset.

T
CreateMessageOptions = { cmdId: number; channelId: number; messageId: number; messageClass?:
BAICHUAN_MESSAGE_CLASS.LEGACY
| BAICHUAN_MESSAGE_CLASS.MODERN_WITH_OFFSET
; extension?: Uint8Array; body?: Uint8Array; }

Fields for createMessage.

Variables

v
BAICHUAN_CHANNEL: { HOST: number; PUSH: number; }

Channel ids (the header's channelId) for requests that address the device rather than one camera channel. Camera channels are 1-100, the channel number plus one.

v
BAICHUAN_CMD: { LOGIN: number; SUBSCRIBE: number; ALARM_EVENT: number; PING: number; PTZ_CONTROL: number; PTZ_PRESET: number; SNAPSHOT: number; PTZ_PRESETS: number; PTZ_POSITION: number; SIREN: number; PRIVACY_MODE: number; SET_PRIVACY_MODE: number; }

Command ids (the header's cmdId) this package sends or reads.

protocol/login.ts

Baichuan "modern" login: nonce, hashed credentials and the session key.

Examples

Build the login body from a nonce

import { assertEquals, assertStringIncludes } from "@std/assert";
import {
  loginCredentials,
  loginXml,
  parseNonce,
} from "@hertzg/reolink-api/protocol/login";

const nonce = parseNonce(
  "<body><Encryption><nonce>NONCE-0123</nonce></Encryption></body>",
);
const credentials = loginCredentials({
  username: "admin",
  password: "hunter2",
  nonce,
});

assertEquals(nonce, "NONCE-0123");
assertStringIncludes(
  loginXml(credentials),
  "<userName>329F51D2942C5953794C5C99EB43D46</userName>",
);

Functions

f
loginCredentials(options: LoginCredentialsOptions): LoginCredentials

Derives the hashed credentials and the AES session key from a nonce.

f
md5Modern(text: string): string

Hashes a string the way Baichuan's modern login does: MD5 of the UTF-8 bytes, as upper-case hex, with the last hex digit dropped (31 characters).

f
parseNonce(xml: string): string

Reads the nonce from the camera's reply to the nonce request.

Type Aliases

T
LoginCredentials = { userHash: string; passwordHash: string; aesKey: Uint8Array; }

The hashed credentials sent at login, and the session key that follows.

T
LoginCredentialsOptions = { username: string; password: string; nonce: string; }

What the login needs: the user's credentials and the camera's nonce.

protocol/event.ts

Alarm events pushed by the camera (cmd 33).

Examples

Parse a doorbell press

import { assertEquals } from "@std/assert";
import { parseAlarmEvents } from "@hertzg/reolink-api/protocol/event";

const events = parseAlarmEvents(
  "<body><AlarmEventList><AlarmEvent>" +
    "<channelId>0</channelId><status>visitor</status><AItype>none</AItype>" +
    "</AlarmEvent></AlarmEventList></body>",
);

assertEquals(events, [
  { channel: 0, motion: false, visitor: true, tamper: false, ai: [] },
]);

Functions

f
parseAlarmEvents(xml: string): AlarmEvent[]

Reads every <AlarmEvent> from a decrypted cmd 33 push.

Type Aliases

T
AlarmEvent = { channel: number; motion: boolean; visitor: boolean; tamper: boolean; ai: string[]; }

The alarm state of one channel, as the camera pushed it.

protocol/xml.ts

Typed XML codecs for Baichuan parameters.

Examples

Describe a parameter and round-trip it

import { assertEquals, assertStringIncludes } from "@std/assert";
import { parse } from "@std/xml";
import { int, xmlParam } from "@hertzg/reolink-api/protocol/xml";

const rtspPort = xmlParam("RtspPort", { rtspPort: int(), enable: int() });

const xml = rtspPort.encode({ rtspPort: 554, enable: 1 });
assertStringIncludes(xml, "<rtspPort>554</rtspPort>");
assertEquals(rtspPort.decode(parse(xml).root), { rtspPort: 554, enable: 1 });

Functions

f
float(): XmlField<number>

A floating point field.

f
int(): XmlField<number>

A signed integer field, such as <channelId>0</channelId>.

f
list<T>(
itemName: string,
item: XmlField<T>
): XmlField<T[]>

A wrapper element holding repeated items, such as <presetList><preset>…</preset><preset>…</preset></presetList>.

f
oneOf<V extends string>(...values: V[]): XmlField<V>

A text field limited to known values, such as <parity>none</parity>.

f
optional<T>(field: XmlField<T>): XmlField<T> & { optional: true; }

Marks a field as possibly missing: it reads as absent instead of throwing, and is not written when absent.

f
repeated<T>(item: XmlField<T>): XmlField<T[]>

Elements repeated directly under the parent, such as several <AlarmEvent> inside <AlarmEventList>. Missing elements read as [].

f
text(): XmlField<string>

A text field, such as <name>Front door</name>. XML entities are escaped on write and unescaped on read.

f
u64(): XmlField<bigint>

An unsigned 64-bit integer field, read as a bigint so no digit is lost.

f
uint(): XmlField<number>

An unsigned 32-bit integer field.

Type Aliases

T
AnyXmlParam = XmlParam<string, any>

Any XmlParam, whatever its value. any for the same variance reason as XmlFields.

T
XmlField<T> = { encode: (
name: string,
value: T
) => string
; decode: (
name: string,
parent: XmlElement
) => T
; optional?: boolean; }

Reads and writes one XML field: an element's text, a nested element, or a run of repeated elements.

T
XmlFields = Record<string, XmlField<any>>

A record of named field codecs, as passed to obj and xmlParam.

T
XmlParam<N extends string, T> = { name: N; fields: XmlFields; encode: (value: T) => string; decode: (element: XmlElement) => T; }

A Baichuan parameter: a named top-level element of <body>.

protocol/command.ts

Baichuan commands as data: an id, the firmware's name, and the parameter elements its bodies carry.

Examples

Encode and decode a command body

import { assertEquals } from "@std/assert";
import {
  command,
  decodeCommandBody,
  encodeCommandBody,
} from "@hertzg/reolink-api/protocol/command";
import { int, xmlParam } from "@hertzg/reolink-api/protocol/xml";

const rtspPort = xmlParam("RtspPort", { rtspPort: int(), enable: int() });
const setPorts = command(36, "SET_NETPORT_CFG_V20", [rtspPort]);

const xml = encodeCommandBody(setPorts, {
  RtspPort: { rtspPort: 554, enable: 1 },
});

assertEquals(decodeCommandBody(setPorts, xml), {
  RtspPort: { rtspPort: 554, enable: 1 },
});

Functions

f
decodeCommandBody<C extends Command>(
command: C,
xml: string
): CommandBody<C>

Reads a command body. Elements that are not among the command's parameters are ignored.

f
encodeCommandBody<C extends Command>(
command: C,
body: CommandBody<C>
): string

Writes a command body as XML. Parameters missing from body are left out; an empty body gives an empty string, which the firmware treats as "use the current values" rather than as an empty <body/>.

Type Aliases

T
Command<P extends readonly AnyXmlParam[] = readonly AnyXmlParam[]> = { id: number; name: string; params: P; firmware: readonly Firmware[]; }

A Baichuan command: its id, firmware name, and parameter elements.

  • firmware: readonly Firmware[]

    The firmware builds known to register the command, empty when unknown. Registration does not promise that a given device answers it.

  • id: number

    The command id sent in the message header.

  • name: string

    The name the firmware's dispatch table gives the command.

  • params: P

    The parameter elements the command's bodies may carry.

T
CommandBody<C extends Command> = [P in C["params"][number] in keyof P["name"]]?: XmlParamValue<P>

The body of a Command, request or reply: each of its parameters by element name, all optional.

T
Firmware = "RLC-823A" | "Video Doorbell PoE"

A firmware build whose command table this package was derived from.

protocol/params/mod.ts

Codecs for every Baichuan parameter element the RLC-823A firmware (IPC_523SD10.2898_23110119) reads or writes, one per element name.

Examples

Read a pushed <Serial> element

import { assertEquals } from "@std/assert";
import { parse } from "@std/xml";
import { serial } from "@hertzg/reolink-api/protocol/params";

const root = parse(
  '<Serial version="1.1"><channelId>0</channelId><baudRate>9600</baudRate>' +
    "<dataBit>CS8</dataBit><stopBit>1</stopBit><parity>none</parity>" +
    "<flowControl>none</flowControl><controlProtocol>PELCO_D</controlProtocol>" +
    "<controlAddress>1</controlAddress></Serial>",
).root;

assertEquals(serial.decode(root).baudRate, 9600);

Type Aliases

T
AbilityAlarmModule = { subModule: { channelId?: number; abilityValue: string; }[]; }

The alarm module: an optional device-wide entry, then per-channel ones.

T
AbilityChannelModule = { subModule: { channelId: number; abilityValue: string; }[]; }

A module with permissions per channel.

T
AbilityInfo = { userName: string; system?: AbilityGlobalModule; streaming?: AbilityChannelModule; record?: AbilityChannelModule; network?: AbilityGlobalModule; PTZ?: AbilityGlobalModule; IO?: AbilityGlobalModule; alarm?: AbilityAlarmModule; image?: AbilityChannelModule; video?: AbilityChannelModule; audio?: AbilityGlobalModule; security?: AbilityGlobalModule; replay?: AbilityChannelModule; disk?: AbilityGlobalModule; }

The user's permissions in <AbilityInfo>.

T
AccessInfo = { userName: string; accesskey: string; }

The credentials in <accessInfo>.

T
AccessUser = { userId?: string; notes?: string; phoneModel?: string; userLevel?: number; validHours?: number; loginState?: number; ability?: number; userSetState?: "delete" | "modify"; }

One shared user, a <User> in <accessUserList>.

T
AccessUserList = { maxAccessUserNum?: number; availableAbility?: number; User: AccessUser[]; }

The shared users in <accessUserList>.

T
AfAlgorithm = { channelId?: number; algorithm?: number; }

The autofocus algorithm setting in <afAlgorithm>.

T
AfLearn = { channelId?: number; }

The autofocus learning request in <AfLearn>.

T
AfLearnRes = { zoomPos?: number; focusPos?: number; rangeMin?: number; rangeMax?: number; afStudyState?: number; afStudyRusult?: number; backLashz?: number; backLashf?: number; }

The autofocus learning outcome in <AfLearnRes>.

T
AgingTest = { channelId?: number; enable?: number; fileName?: string; size?: number; }

The aging test request in <AgingTest>.

T
AiCfg = { channelId?: number; smartTrack?: number; smartTrackMode?: number; smartTrackModeAbility?: number; detectType?: string; smartTrackType?: string; smartTrackPt?: number; smartTrackObjectStopDelay?: number; smartTrackObjectDisappearDelay?: number; }

The AI settings in <AiCfg>.

T
AiDetectCfg = { chn?: number; type?:
"people"
| "vehicle"
| "face"
| "dog_cat"
| "other"
| "package"
; sensitivity?: number; stayTime?: number; minTargetHeight?: number; minTargetWidth?: number; maxTargetHeight?: number; maxTargetWidth?: number; width?: number; height?: number; area?: string; }

AI detection settings for one target type, in <AiDetectCfg>.

T
AiTrackData = { fileName?: string; size?: number; year?: number; month?: number; day?: number; }

The AI tracking data request and reply in <AiTrackData>.

T
AiyuvCfg = { needTLV?: number; gapms?: number; resoWidth?: number; resoHeight?: number; algorithm?: number; }

The AI YUV stream settings in <AIYUVCfg>.

T
AlarmAreaGrid = { width: number; height: number; area: string; }

One detection grid inside <AlarmArea>.

T
AlarmVideoInfo = { channelId: number; fileHandle: number; bFinished: number; alarmVideoList: AlarmVideoInfoItem[]; }

One page of search results in <alarmVideoInfo>.

T
AlarmVideoInfoItem = { fileName: string; alarmType: string; fileId: string; typeExtension?: number; startTime: AlarmVideoInfoTime; endTime: AlarmVideoInfoTime; }

One recording, an <alarmVideo> in <alarmVideoList>.

T
AnswerEvent = { startTime?: number; }

The answered call in <answerEvent>.

  • startTime: number

    When the call was answered. Parsed as a 64-bit integer but stored in 32 bits, so only the low 32 bits reach the device.

T
AudioCfg = { channelId?: number; timeout?: number; audioSelect?: number; volume?: number; preAlarm?: number; visitorLoudspeaker?: number; }

The alarm sound settings in <audioCfg>.

T
AudioFileInfo = { channelId?: number; fileSize?: number; audioLen?: number; customName?: string; id?: number; timeout?: number; }

The custom alarm sound file in <audioFileInfo>.

T
AudioFileInfoList = { audioFileInfo: AudioFileInfoListItem[]; item?: AudioFileInfoListLegacyItem[]; maxFileNumber?: number; }

The audio file list in <audioFileInfoList>.

T
AudioFileInfoListItem = { id?: number; fileSize?: number; audioLen?: number; fileName?: string; extId?: string; type?: "alarm" | "reply"; }

One stored audio file, an <audioFileInfo> in <audioFileInfoList>.

T
AudioFileInfoListLegacyItem = { id?: number; fileSize?: number; audioLen?: number; customName?: string; }

One file in the RLC-823A's cmd 347 reply, an <item>.

T
AudioPlayInfo = { channelId?: number; playMode?: number; playDuration?: number; playTimes?: number; onOff?: number; }

The play request in <audioPlayInfo>.

T
AudioTask = { channelId?: number; enable?: number; typeScheduleList?: { type: string; valueTable: string; }[]; }

The alarm sound schedule in <AudioTask>.

T
AuthInfo = { notes?: string; validhours?: number; userLevel?: number; ability?: number; channelAbility?: bigint; code?: number; }

The authorization code request and reply in <authInfo>.

T
AutoDns = { enable: number; }

The automatic DNS switch in <AutoDns>.

T
AutoFocus = { channelId?: number; disable?: number; }

The autofocus switch in <AutoFocus>.

T
AutoReply = { enable?: number; timeout?: number; audioId?: number; extId?: string; fileName?: string; fesEnable?: number; fesAudioId?: number; fesExtId?: string; fesFileName?: string; startTime?: AutoReplyTime; endTime?: AutoReplyTime; current?: number; }

The automatic reply settings in <AutoReply>.

T
AutoUpdate = { enable?: number; }

The automatic update setting in <AutoUpdate>.

  • enable: number

    1 to update automatically, 0 not to; the reply always carries it.

T
BandWidthTest = { enable?: number; }

The bandwidth test switch in <BandWidthTest>.

  • enable: number

    1 to run the test, 0 to stop it; the firmware rejects a negative value.

T
BatteryInfo = { channelId: number; chargeStatus: "none" | "charging" | "chargeComplete"; adapterStatus: "none" | "adapter" | "solarPanel"; voltage: number; current: number; temperature: number; batteryPercent: number; lowPower: number; batteryVersion: number; }

The battery state in <BatteryInfo>.

T
BatteryRemainList = { channelId: number; batteryTable: string; }

The battery level table in <BatteryRemainList>.

T
BindCloud = { authToken?: string; }

The bind request in <BindCloud>.

T
BindNasInfo = { devName?: string; uid?: string; bBinded?: number; }

One bound NAS in <BindNasInfoList>.

T
BindNasInfoList = { info?: BindNasInfo[]; }

The bound NAS devices in <BindNasInfoList>.

T
BindUnbindNas = { userName?: string; password?: string; devName?: string; uid?: string; token?: string; }

The NAS bind request in <BindUnbindNas>.

T
BinoAdjust = { lineWidthRef?: number; lineWidthMin?: number; lineWidthMax?: number; heightDiffMax?: number; heightDiff?: number; widthDiff?: number; }

The binocular alignment request and result in <BinoAdjust>.

T
Blc = { enable: number; BLCMode: "backLight" | "dynamicRange"; level: number; }

The backlight compensation setting in <BLC>.

T
Button443 = Record<PropertyKey, never>

The value of <Button443>: the firmware reads no fields.

T
CertificateInfo = { enable?: number; certName?: string; keyName?: string; key?: string; cert?: string; option?: "import" | "clear"; }

The HTTPS certificate in <certificateInfo>.

T
CloudBindInfo = { binded: number; }

The cloud binding state in <CloudBindInfo>.

T
CloudLoginKey = { enable?: number; }

The cloud login switch in <CloudLoginKey>.

T
CloudTask = { channelId?: number; enable?: number; typeScheduleList?: { type: string; valueTable: string; }[]; }

The cloud upload schedule in <CloudTask>.

T
CloudTestResult = { rspCode: number; detail: string; }

The cloud test outcome in <CloudTestResult>.

T
CloudUploadCfg = { enable?: number; version?: number; streamOpList?: string; streamCfgList?: string; }

The cloud upload settings in <CloudUploadCfg>.

T
Compression = { channelId?: number; isNoTranslateFrame?: number; mainStream?: CompressionStream; subStream?: CompressionStream; thirdStream?: CompressionStream; }

The video encoder settings in <Compression>.

T
CompressionStream = { audio?: number; resolutionName?: string; width?: number; height?: number; encoderType?: "vbr" | "cbr"; frame?: number; bitRate?: number; encoderProfile?: "default" | "baseLine" | "high" | "main"; gop?: { cur?: number; max?: number; min?: number; }; }

One stream's encoder settings in <Compression>.

T
ConfigFileInfo = { fileName?: string; fileSize?: number; curSize?: number; updateParameter?: number; usedForFactory?: number; }

The configuration file transfer in <ConfigFileInfo>.

T
CoverPreview = { channelId?: number; streamType?: "mainStream" | "subStream" | "mobileStream" | "externStream"; startTime?: CoverPreviewTime; endTime?: CoverPreviewTime; frameList?: number[]; }

The preview request in <CoverPreview>.

T
CoverPreviewTime = { year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number; }

A date and time in <CoverPreview>.

T
Crop = { channelId?: number; topLeftX?: number; topLeftY?: number; cropWidth?: number; cropHeight?: number; mainWidth?: number; mainHeight?: number; subHeight?: number; subWidth?: number; version?: number; }

The crop region in <Crop>.

T
CropSnap = { channelId?: number; width?: number; heigth?: number; }

The snapshot size in <CropSnap>.

T
CropSnapReply = { channelId: number; pictureSize: number; }

The snapshot description in <cropSnap>.

T
DayNightMode = { mode: "auto" | "color" | "blackAndWhite"; }

The day/night setting in <DayNightMode>.

T
DayNightThreshold = { channelId?: number; threshold?: "default" | "custom"; stat?: "day" | "night"; thresholdval?: DayNightThresholdValue; }

The day/night switch point in <DayNightThreshold>.

T
DayNightThresholdValue = { min?: number; max?: number; cur?: number; }

The threshold range in <DayNightThreshold>.

T
DayRecordsChannel = { index?: number; channelId?: number; dayTypeList?: DayRecordsDayType[]; }

One channel's days, in <DayRecord>.

T
DayRecordsDayType = { index: number; type: "none" | "normal" | "alarm" | "all"; }

One day with recordings, in <dayType>.

T
DayRecordsTime = { year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number; }

A point in time in <startTime> or <endTime>.

T
Ddns = { enable?: number; ddnsType?: "swann" | "dyndns" | "peatnuts" | "3322" | "no-ip"; ddnsName?: string; userName?: string; password?: string; }

The dynamic DNS settings in <Ddns>.

T
DeleteRecordFile = { chnbits?: bigint; streamType?: number; bmerge?: number; startTime?: DeleteRecordFileTime; endTime?: DeleteRecordFileTime; }

The recordings to delete in <DeleteRecordFile>.

T
DeleteRecordFileTime = { year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number; }

A point in time in <startTime> or <endTime> of <DeleteRecordFile>.

T
DevBodyCode = Record<PropertyKey, never>

The value of <DevBodyCode>: the firmware reads and writes no fields.

T
DeviceInfo = { firmVersion: string; IOInputPortNum: number; IOOutputPortNum: number; diskNum: number; type:
"dvr"
| "ipc"
| "nvr"
| "wifi_ipc"
| "wifi_nvr"
| "nxp_ipc"
| "wifi_solo_ipc"
| "base"
| "alertor"
| "smart_bell"
| "smart_plug"
; channelNum: number; audioNum: number; ipChannel: number; analogChnNum: number; resolution?: { resolutionName: string; width: number; height: number; }; secretCode?: string; bootSecret?: string; language: string; sdCard: number; ptzMode: "none" | "af" | "ptz" | "pt" | "p"; typeInfo: string; softVer: number; hardVer: number; panelVer: number; hdChannel1: number; hdChannel2: number; hdChannel3: number; hdChannel4: number; norm: "NTSC" | "PAL"; osdFormat: string; B485: number; supportAutoUpdate: number; userVer: number; FrameworkVer: number; authMode: number; sleep?: number; feature?: number; binoType?: number; }

The device identity and capabilities in <DeviceInfo>.

T
Dhcp = { enable: number; }

The DHCP switch in <Dhcp>.

T
DingdongCfg = { deviceCfg: DingdongCfgDevice[]; pairThreshold?: number; }

The chime alarm rules in <dingdongCfg>.

T
DingdongCfgAlarm = { type?:
"visitor"
| "people"
| "package"
| "MD"
| "vehicle"
| "dog_cat"
; valid?: number; musicId?: number; }

One alarm rule of a chime, an <alarminCfg> in <deviceCfg>.

T
DingdongCfgDevice = { id?: number; name?: string; alarminCfg: DingdongCfgAlarm[]; }

One paired chime, a <deviceCfg> in <dingdongCfg>.

T
DingdongCtrl = { opt?: "enter" | "exit" | "reset"; }

The chime pairing control in <dingdongCtrl>.

T
DingdongDeviceOpt = { id?: number; opt?:
"addDevice"
| "delDevice"
| "getParam"
| "setParam"
| "ringWithMusic"
; musicId?: number; volLevel?: number; ledState?: number; name?: string; }

The chime operation in <dingdongDeviceOpt>.

T
DingdongList = { maxPairNumber?: number; pairedList?: DingdongListPairedDevice[]; scanList?: DingdongListScannedDevice[]; }

The chime list in <dingdongList>.

T
DingdongListPairedDevice = { id: number; netstate?: number; name: string; netState?: number; }

A paired chime, a <dingdongDeviceInfo> in <pairedList>.

T
DingdongListScannedDevice = { id: number; name: string; }

A chime found by a pairing scan, a <dingdongDeviceInfo> in <scanList>.

T
DingdongSilentMode = { id?: number; time?: number; remainTime?: number; type?: number; }

The chime silent mode in <dingdongSilentMode>.

  • id: number

    The paired chime id.

  • remainTime: number

    Reply only: how much of the silent period is left.

  • time: number

    The silent period. Parsed as a 64-bit integer but stored in 32 bits, so only the low 32 bits survive; replies write it sign-extended.

  • type: number

    The silent mode kind; its values are not established.

T
Dns = { dns1?: string; dns2?: string; }

The static DNS servers in <Dns>.

T
DoorbellDingdingtest = { freq?: number; curFreq?: number; sub1gTestResult?: number; update?: DoorbellDingdingtestUpdate[]; dingdongTestResult?: DoorbellDingdingtestResult[]; }

The factory chime test result in <doorbellDingdingtest>.

T
DoorbellDingdingtestResult = { state: number; verifyResult: number; agingResult: number; }

One chime test, a <dingdongTestResult> in <doorbellDingdingtest>.

T
DoorbellDingdingtestUpdate = { result: number; curVer: string; reqVer: string; }

One chime firmware update, an <update> in <doorbellDingdingtest>.

T
Email = { smtpServer?: string; userName?: string; senderMaxLen?: number; password?: string; pwdMaxLen?: number; address1?: string; address2?: string; address3?: string; sendNickname?: string; smtpPort?: number; attachment?: number; attachmentType?: "none" | "picture" | "video"; textType?: "mustBeText" | "withText" | "withoutText"; ssl?: number; interval?: number; emailAttachType?: number; }

The SMTP settings in <Email>.

T
EmailTask = { channelId?: number; enable?: number; typeScheduleList?: { type: string; valueTable: string; }[]; }

The alarm email schedule in <EmailTask>.

T
ExposureCfg = { exposureType: "auto" | "shutterFirst" | "gainFist" | "manual"; }

The exposure setting in <ExposureCfg>.

T
FileInfoTime = { year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number; }

A wall-clock time in a <FileInfo>, as the firmware writes it.

T
FindAlarmVideo = { channelId?: number; fileHandle?: number; streamType?: number; startTime?: FindAlarmVideoTime; endTime?: FindAlarmVideoTime; alarmType?: string; }

The alarm recording search in <findAlarmVideo>.

T
FindAlarmVideoTime = { year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number; }

A point in time in <startTime> or <endTime> of <findAlarmVideo>.

T
Flip = { status: number; }

The flipping setting in <Flip>.

T
FloodlightManual = { channel?: number; status?: number; }

The manual floodlight switch in <FloodlightManual>.

T
FloodlightSchedule = { startHour?: number; startMin?: number; endHour?: number; endMin?: number; }

A daily time window in <FloodlightTask>.

T
FloodlightStatus = { channel: number; status: number; }

One floodlight in <FloodlightStatusList>.

T
FloodlightStatusList = { FloodlightStatus: FloodlightStatus[]; }

The floodlight states in <FloodlightStatusList>.

T
FloodlightTask = { channel?: number; alarmMode?: number; enable?: number; preview_auto?: number; duration?: number; brightness_cur?: number; brightness_max?: number; brightness_min?: number; schedule?: FloodlightSchedule; lightAlarmSchedule?: FloodlightSchedule; detectType?: string; }

The automatic floodlight settings in <FloodlightTask>.

T
FreqCorrectResult = { result: "success" | "fail" | "unknow"; }

The frequency correction outcome in <freqCorrectResult>.

T
Ftp = { server?: string; port?: number; nonymous?: number; remoteDir?: string; userName?: string; password?: string; pwdMaxLen?: number; fileLen?: number; supportTest?: number; streamType?: number; ftpVersion?: number; intervals?: number; mode?: number; bnameEncrypt?: number; autoDir?: number; picPolicy?: number; picName?: string; picType?: number; picHeight?: number; picWidth?: number; picIntervals?: number; videoPolicy?: number; videoName?: string; onlyFtps?: number; }

The FTP upload settings in <Ftp>.

T
FtpTestResult = { rspCode?: number; detail?: string; }

The FTP test outcome in <FtpTestResult>.

  • detail: string

    The FTP server's reply text; written together with rspCode.

  • rspCode: number

    The FTP server's reply code; written only when the test produced a result.

T
FtyAudioTest = { ratedPower?: number; difPower?: number; difHz?: number; difZero?: number; difCrest?: number; difSame?: number; difFreq?: number; flitFreq?: number; }

The factory audio test parameters in <ftyAudioTest>.

T
FtyDoorbellTest = { testDuration?: number; testTimes?: number; result?: number; op?: number; testTotalCount?: number; }

The factory doorbell button test in <ftyDoorbellTest>.

T
FtyImageDetechRet = { deadpix?: number; blot?: number; }

The image defect detection result in <ftyImageDetechRet>.

T
FtySnapCfg = Record<PropertyKey, never>

The value of <ftySnapCfg>: the firmware reads and writes no fields.

T
FtyTestRangeBounds = { max?: number; min?: number; }

One pass range in <ftyTestRange>.

T
Gain = { gainLevel: number; }

The gain setting in <Gain>.

T
GopCfg = { channel?: number; streamType?: number; gopTime?: number; }

The GOP setting in <GopCfg>.

T
HddInitList = { HddInit: { initId?: number; }[]; }

The storage devices to format in <HddInitList>.

T
HeartBeat = { size?: number; sec: number; usec: number; }

The keep-alive timestamp in <HeartBeat>.

T
HttpPort = { httpPort?: number; enable?: number; }

The port settings in <HttpPort>.

T
HttpsPort = { httpsPort?: number; enable?: number; }

The port settings in <HttpsPort>.

T
ImageCheck = Record<PropertyKey, never>

The value of <ImageCheck>: the firmware reads and writes no fields.

T
ImageFileInfo = { channelId?: number; fileSize?: number; imageName?: string; delete?: number; }

An image file to import or export, in <imageFileInfo>.

T
InputAdvanceCfg = { channelId?: number; digitalChannel?: number; PowerLineFrequency?: { mode?: "outdoor" | "50hz" | "60hz"; enable?: number; }; Exposure?: { mode?: "auto" | "shutterFirst" | "gainFist" | "manual"; Gainctl?: IspAreaCtrl; Shutterctl?: IspAreaCtrl; shutterLevel?:
"1/3"
| "1/4"
| "1/5"
| "1/6"
| "1/8"
| "1/12"
| "1/15"
| "1/25"
| "1/30"
| "1/50"
| "1/60"
| "1/100"
| "1/120"
| "1/250"
| "1/500"
| "1/1000"
| "1/2000"
| "1/4000"
| "1/10000"
; gainLevel?: number; }
; Scene?: { mode?: "auto" | "indoor" | "outdoor" | "manual"; modeList?: string; Redgain?: IspRange; Bluegain?: IspRange; }; DayNight?: { mode?: "auto" | "color" | "blackAndWhite"; IrcutMode?: "auto" | "ir"; Threshold?: "low" | "medium" | "high"; }; BLC?: { enable?: number; mode?: "backLight" | "dynamicRange"; backlight?: IspRange; dynamicrange?: IspRange; }; bdDayColor?: IspBrightDark; bdNight?: IspBrightDark; bdNightColor?: IspBrightDark; mirror?: number; flip?: number; Iris?: { enable?: number; state?: string; focusAutoiris?: number; }; nr3d?: { value?: "high" | "medium" | "low" | "off"; enable?: number; }; firstFrameStrategy?: number; constantFrameRate?: number; constantFrameRateAbility?: number; binning_mode?: number; encTypeAbility?: number; encType?: number; hdrAbility?: number; hdrSwitch?: number; }

The image settings in <InputAdvanceCfg>.

T
IotAction = { channelBits?: bigint; setState?: number; actionID?: number; name?: string; uid?: string; content?: string; alarmType?: string; timeTable?: string; }

One IoT action in <IOTAction>.

T
IotActionList = { item: IotActionListItem[]; }

The IoT linkage actions in <IOTActionList>.

T
IotActionListItem = { actionID: number; channelBits: bigint; deviceType: number; name: string; uid: string; content: string; alarmType: string; timeTable: string; }

One IoT linkage action, an <item> in <IOTActionList>.

T
IotBindUnBind = { name?: string; uid?: string; userName?: string; password?: string; token?: string; deviceType?: number; }

An IoT device to bind or unbind, in <IOTBindUnBind>.

T
Ip = { ip?: string; mask?: string; mac?: string; gateway?: string; }

The wired address in <Ip>.

T
IrCutInfo = Record<PropertyKey, never>

The value of <IrCutInfo>: the firmware reads and writes no fields.

T
IrcutMode = { mode: "auto" | "ir"; }

The IR-cut filter setting in <IrcutMode>.

T
IspAreaCtrl = { defMin?: number; defMax?: number; curMin?: number; curMax?: number; }

A default and a current range, used by the exposure gain and shutter.

T
IspBrightDark = { mode: "auto" | "manual"; bright?: IspRange; dark?: IspRange; }

Brightness and darkness limits for one day/night state.

T
IspRange = { min?: number; max?: number; cur?: number; }

A bounded value as min, max and current value cur.

T
LedState = { channelId?: number; ledVersion?: number; state?: "auto" | "close" | "open"; lightState?: "close" | "open"; doorbellLightState?: "close" | "open" | "keepOff" | "keepOn"; }

The LED settings in <LedState>.

T
LinkType = { type: "LAN" | "PPPOE" | "CDMA"; }

The network link in <LinkType>.

T
LoginErrInfo = { remainTimes?: number; unlockTime?: number; }

The lockout state in <LoginErrInfo>.

T
LoginNet = { type?: "LAN" | "WAN"; udpPort?: number; }

The client network settings in <LoginNet>.

T
LoginUser = { userName?: string; password?: string; userVer?: number; handleSpecial?: number; authSignature?: string; authToken?: string; authUser?: string; admin?: number; scopes?: { channelId: number; privileges?: string; }[]; }

The login credentials in <LoginUser>.

T
MdSensInfo = { priority: number; sensitivity?: number; beginHour?: number; beginMinute?: number; endHour?: number; endMinute?: number; }

One enabled sensitivity period in <sensInfoList>.

T
MdSensitivityInfo = { id?: number; sensitivity?: number; beginHour?: number; beginMinute?: number; endHour?: number; endMinute?: number; enable?: number; }

One fixed sensitivity period in <sensitivityInfoList>.

T
Mirror = { status: number; }

The mirroring setting in <Mirror>.

T
MuteAudio = { channelId?: number; mute?: number; }

The mute request in <muteAudio>.

T
NasUploadCfg = { enable?: number; streamAbility?: number; streamConfig?: number; }

The NAS upload settings in <NasUploadCfg>.

T
Net3g4gInfo = { sigIntensityLevel: number; sigIntensityValue: number; netMode: number; mobileOperator: number; }

The cellular state in <Net3g4gInfo>.

T
Net3g4gModuleInfo = { iccid?: string; imei?: string; phoneNumber?: string; }

The cellular module identifiers in <Net3g4gModuleInfo>.

T
NetworkDiagnosisData = { channelId?: number; fileName?: string; size?: number; }

A network diagnosis data file, in <NetworkDiagnosisData>.

T
Norm = { norm: "PAL" | "NTSC"; }

The video standard in <Norm>.

T
Ntp = { enable?: number; server?: string; synchronizeInterval?: number; port?: number; }

The time sync settings in <Ntp>.

T
OffsetAdjust = { maxOffset?: number; OffsetX?: number; OffsetY?: number; Offset?: number; }

The offset calibration request and result in <OffsetAdjust>.

T
OnlineNewFirmwareInfo = { hasNewFirmware: number; }

The online firmware check result in <OnlineNewFirmwareInfo>.

T
OnlineUpdate = { needUpdate?: number; }

The online update request in <OnlineUpdate>.

T
OnlineUser = { userId?: number; sessionId: number; userName?: string; password?: string; userLevel?: number; ipAddress?: string; macAddress?: string; enableOutoffLine?: number; isOnline?: number; }

One logged-in session in <OnlineUser>.

T
OnlineUserList = { OnlineUser: OnlineUser[]; }

The logged-in sessions in <OnlineUserList>.

T
OnvifPort = { onvifPort?: number; enable?: number; }

The port settings in <OnvifPort>.

T
OsdChannelName = { channelId?: number; name?: string; enable?: number; topLeftX?: number; topLeftY?: number; enWatermark?: number; enBgcolor?: number; }

The channel name overlay in <OsdChannelName>.

T
OsdDatetime = { channelId?: number; enable?: number; topLeftX?: number; topLeftY?: number; width?: number; height?: number; language?: "Chinese" | "English"; }

The date and time overlay in <OsdDatetime>.

T
ParamDataV20 = Record<PropertyKey, never>

The value of <PARAM_DATA_V20>: none, the payload is raw bytes.

T
PerformanceInfo = { cpuUseRate: number; codeRate: number; netDataRate: number; }

CPU load and bitrates in <PerformanceInfo>.

T
PeriPheralStat = Record<PropertyKey, never>

The value of <PeriPheralStat>: the firmware reads no fields.

T
PowerLineFrequency = { mode: "outdoor" | "50hz" | "60hz"; enable: number; }

The anti-flicker setting in <PowerLineFrequency>.

T
Preview = { channelId?: number; handle?: number; streamType?:
"mainStream"
| "subStream"
| "mobileStream"
| "externStream"
| "aiYuvData"
; preRec?: number; resolution?: number; fps?: number; needTLV?: number; gapms?: number; resoWidth?: number; resoHeight?: number; algorithm?: number; }

The live stream selection in <Preview>.

T
Ptop = { enable: number; }

The peer-to-peer setting in <PTOP>.

T
Ptz3DLocation = { channelId?: number; topLeftX?: number; topLeftY?: number; width?: number; height?: number; speed?: number; streamType?: "mainStream" | "subStream" | "mobileStream" | "externStream"; }

The rectangle to move onto, in <Ptz3DLocation>.

T
PtzAutoTest = { testStat: number; }

The PTZ self-test state in <PtzAutoTest>.

  • testStat: number

    Self-test state as a number; the firmware does not name the values.

T
PtzControl = { channelId?: number; command?:
"stop"
| "left"
| "right"
| "up"
| "down"
| "leftUp"
| "leftDown"
| "rightUp"
| "rightDown"
| "irisDec"
| "irisInc"
| "zoomDec"
| "zoomInc"
| "focusDec"
| "focusInc"
| "setPos"
| "delPos"
| "toPos"
| "auto"
| "highSpeed"
| "startPatrol"
| "stopPatrol"
| "clearPatrol"
| "enablePattern"
| "startPattern"
| "stopPattern"
| "startSavePattern"
| "stopSavePattern"
| "cleanPattern"
| "zoomPos"
| "focusPos"
| "zoomStepInc"
| "zoomStepDec"
| "focusStepInc"
| "focusStepDec"
| "setGrd"
| "toGrd"
; patrolId?: number; keyPos?: number; presetId?: number; patternId?: number; speed?: number; dwellTime?: number; }

The PTZ command in <PtzControl>.

T
PtzCurPos = { pPos: number; tPos: number; }

The current PTZ position in <ptzCurPos>; units are not established.

T
PtzGuard = { channelId?: number; timeout?: number; benable?: number; bvalid?: number; imageName?: string; needSetPos?: number; command?: string; }

The PTZ guard position settings in <PtzGuard>.

  • benable: number

    Nonzero when returning to the guard position is on.

  • bvalid: number

    Nonzero when a guard position is stored; written in replies only.

  • channelId: number

    Zero-based channel; the parser rejects 64 and above.

  • command: string

    PTZ command name, such as setGrd or toGrd; the parser rejects a name outside the firmware's 37 PTZ commands. Read from requests only.

  • imageName: string

    Name of the guard position preview image, up to 31 characters.

  • needSetPos: number

    Nonzero to store the current position as the guard position; read from requests only.

  • timeout: number

    Seconds idle before the camera returns to the guard position.

T
PtzPreset = { channelId: number; maxPresetNum?: number; maxPresetPicNum?: number; presetList?: { id: number; name?: string; imageName?: string; command?:
"stop"
| "left"
| "right"
| "up"
| "down"
| "leftUp"
| "leftDown"
| "rightUp"
| "rightDown"
| "irisDec"
| "irisInc"
| "zoomDec"
| "zoomInc"
| "focusDec"
| "focusInc"
| "setPos"
| "delPos"
| "toPos"
| "auto"
| "highSpeed"
| "startPatrol"
| "stopPatrol"
| "clearPatrol"
| "enablePattern"
| "startPattern"
| "stopPattern"
| "startSavePattern"
| "stopSavePattern"
| "cleanPattern"
| "zoomPos"
| "focusPos"
| "zoomStepInc"
| "zoomStepDec"
| "focusStepInc"
| "focusStepDec"
| "setGrd"
| "toGrd"
; }[]
; }

The saved PTZ positions in <PtzPreset>.

T
PtzZoomFocusRange = { maxPos: number; minPos: number; curPos: number; }

One motor's range and position; units are not established.

T
PushCfg = { interval?: number; richNotificationEnable?: number; consentAgreement?: number; }

The push notification settings in <PushCfg>.

T
PushClientId = { clientType?: string; pushToken?: string; clientID?: string; }

The push registration in <PushClientID>.

T
PushClientState = { clientID?: string; channelIdList?: string[]; }

The push client state in <PushClientState>.

T
PushCreateListener = { clientID?: string; channelId?: string; }

The listener request in <PushCreateListener>.

T
PushInfo = { token?: string; phoneType?: string; clientID?: string; }

The push registration in <PushInfo>.

T
PushRspInfo = { registerHandle: number; uid: string; uidKey: string; }

The push registration result in <PushRspInfo>.

T
PushTask = { channelId?: number; enable?: number; typeScheduleList?: { type: string; valueTable: string; }[]; }

The push notification schedule in <PushTask>.

T
PushTestResult = { rspCode: number; detail: string; }

The push test outcome in <PushTestResult>.

T
RecordCfg = { channelId?: number; cycle?: number; recordAbility?: number; smartRecord?: number; talkRecord?: number; recordDelayTime?: number; preRecordTime?: number; packageTime?: number; cyclelist?: number[]; timeList?: number[]; }

The recording settings in <RecordCfg>.

T
ReplayByTimeV2Duration = { channelId?: number; times?: ReplayByTimeV2Period[]; }

The recorded periods of one channel, a <duration> in <durationList>.

T
ReplayByTimeV2DurationList = { year?: number; month?: number; day?: number; duration: ReplayByTimeV2Duration[]; }

The recorded periods of one day, in <durationList>.

T
ReplayByTimeV2Period = { s?: number; e?: number; }

One recorded period, an <i> in <times>.

  • e: number

    End, in seconds since midnight; must not be negative.

  • s: number

    Start, in seconds since midnight; must not be negative.

T
ReplayByTimeV2Time = { year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number; }

A date and time in <ReplayByTimeV2>.

T
ReplaySeek = { channelId?: number; seekTime?: ReplaySeekTime; seq?: number; }

The playback seek request in <ReplaySeek>.

T
ReplaySeekTime = { year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number; }

The point in time to seek to, in <seekTime>.

T
ReplaySeekV2 = { seekTime?: ReplaySeekV2Time; seq?: number; durationList?: ReplaySeekV2DurationList; }

The playback seek request in <ReplaySeekV2>.

T
ReplaySeekV2Duration = { channelId?: number; times?: ReplaySeekV2Period[]; }

The recorded periods of one channel, a <duration> in <durationList>.

T
ReplaySeekV2DurationList = { year?: number; month?: number; day?: number; duration: ReplaySeekV2Duration[]; }

The recorded periods of one day, in <durationList>.

T
ReplaySeekV2Period = { s?: number; e?: number; }

One recorded period, an <i> in <times>.

  • e: number

    End, in seconds since midnight; must not be negative.

  • s: number

    Start, in seconds since midnight; must not be negative.

T
ReplaySeekV2Time = { year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number; }

The point in time to seek to, in <seekTime>.

T
Restore = { all?: number; display?: number; recording?: number; network?: number; alarm?: number; device?: number; system?: number; wifi?: number; IPC?: number; }

The settings groups to reset in <Restore>; 1 resets, 0 keeps.

T
RfAlarmCfg = { enable?: number; sensiValue?: number; reduceFalseAlarm?: number; }

The PIR alarm settings in <rfAlarmCfg>.

T
RtmpPort = { rtmpPort?: number; enable?: number; }

The port settings in <RtmpPort>.

T
RtspPort = { rtspPort?: number; enable?: number; }

The port settings in <RtspPort>.

T
ScanAp = { udidList?: ScanApUdid[]; }

The scanned access points in <ScanAp>.

T
ScanApUdid = { name: string; signal: number; encrypt: number; type?: number; }

One access point in <udidList>, as a <udid> element.

T
Scene = { sceneMode: "indoor" | "outdoor"; }

The scene setting in <Scene>.

T
ServerPort = { serverPort?: number; enable?: number; }

The port settings in <ServerPort>.

T
Shelter = { channelId?: number; enable?: number; shelterList?: ShelterArea[]; }

The privacy masks in <Shelter>.

T
SleepState = { operate?: number; sleep?: number; mode?: number; panPos?: number; tiltPos?: number; imageName?: string; }

The privacy state in <sleepState>.

  • imageName: string

    Request only: an image name up to 32 bytes; parsed but unused on the doorbell.

  • mode: number

    Request only: parsed but unused on the doorbell.

  • operate: number

    Request only: the operation; cmd 575 succeeds only with 2.

  • panPos: number

    Request only: pan position; parsed but unused on the doorbell.

  • sleep: number

    The stored sleep word. 1 makes the doorbell refuse live view (cmd 3) and snapshots (cmd 109); 0 is the ordinary state.

  • tiltPos: number

    Request only: tilt position; parsed but unused on the doorbell.

T
SleepStatus = { sleep: number; }

The pushed privacy state in <sleepStatus>.

  • sleep: number

    The stored sleep word. 1 makes the doorbell refuse live view (cmd 3) and snapshots (cmd 109); 0 is the ordinary state.

T
SmtPlayUrl = { channelId?: number; stream_type?: number; }

The play URL request in <SmtPlayUrl>.

T
SmtPlayUrlReply = { url: string; }

The play URL in <SmtPlayURL>.

T
Snap = { channelId?: number; fileName?: string; time?: number; pictureSize?: number; snapPolicy?: number; }

The snapshot request or reply in <Snap>.

T
StartFtyImageClarityDetect = { threshold?: string; aeExpTime?: number; aeIsoGain?: number; awbRgain?: number; awbGgain?: number; awbBgain?: number; desc?: string; }

The image clarity check settings in <startFtyImageClarityDetect>.

T
StreamInfo = { channelBits: number; encodeTable: StreamInfoEncodeTable[]; }

One group of channels and its streams, in <StreamInfo>.

T
StreamInfoEncodeTable = { type: "mainStream" | "subStream" | "mobileStream" | "externStream"; resolution: { width: number; height: number; }; defaultFramerate: number; defaultBitrate: number; framerateTable: string; bitrateTable: string; defaultGop?: number; }

One stream's encoder choices, in <encodeTable>.

T
StreamInfoList = { StreamInfo: StreamInfo[]; }

The encoder capabilities in <StreamInfoList>.

T
Sub1gTest = { correctResult?: number; }

The radio test result in <sub1gTest>.

T
Support = { IOInputPortNum: number; IOOutputPortNum: number; diskNum: number; channelNum: number; audioNum: number; ptzMode: "none" | "af" | "ptz" | "pt" | "p"; ptzCfg: number; B485: number; autoUpdate: number; pushAlarm: number; ftp: number; ftpTest: number; email: number; wifi: number; record: number; wifiTest: number; rtsp: number; onvif: number; audioTalk: number; rfVersion: number; rtmp: number; noExternStream: number; timeFormat: number; ddnsVersion: number; emailVersion: number; pushVersion: number; pushType: number; audioAlarm: number; apMode: number; cloudVersion: number; replayVersion: number; mobComVersion: number; ExportImport: number; languageVer: number; videoStandard: number; syncTime: number; netPort: number; nasVersion: number; needReboot: number; reboot: number; audioCfg: number; networkDiagnosis: number; loginLocked?: number; heightDiffAdjust?: number; wifiVersion: number; previewVersion: number; netSecurity: number; user?: number; IOTLink: number; IOTLinkActionMax: number; autoTest?: number; recordCfg?: number; smartHome: SupportSmartHome; item: SupportChannel[]; }

The device features in <Support>.

T
SupportChannel = { chnID: number; ptzType: number; rfCfg: number; noAudio: number; autoFocus: number; videoClip: number; battery: number; ispCfg: number; osdCfg: number; batAnalysis: number; dynamicReso: number; audioVersion: number; ledCtrl: number; ptzControl: number; newIspCfg: number; ptzPreset: number; ptzPatrol: number; ptzTattern: number; autoPt: number; h264Profile: number; motion: number; aitype: number; aiAnimalType?: number; eventTypeVersion?: number; timelapse: number; snap: number; encCtrl: number; zfBacklash: number; IOTLinkAbility: number; ipcAudioTalk?: number; shelter?: number; thumbnail?: number; doorbellVersion?: number; aiUpdateAbility?: number; remoteAbility?: number; }

One channel's feature flags, in a top-level <item>.

T
SupportSmartHome = { version?: number; item: SupportSmartHomeItem[]; }

The smart home assistants, in <smartHome>.

T
SupportSmartHomeItem = { name: string; ver: number; }

One smart home assistant, in <smartHome><item>.

T
SyncSsid = { ssid2Dot4G?: string; ssid5G?: string; }

The Wi-Fi network names in <syncSSID>.

T
SystemGeneral = { timeZone?: number; osdFormat?: "MDY" | "YMD" | "DMY" | "MDY_CN" | "YMD_CN" | "DMY_CN"; year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number; deviceId?: number; timeFormat?: number; language?: string; deviceName?: string; loginLock?: number; lockTime?: number; allowedTimes?: number; isDst?: number; }

The general system settings in <SystemGeneral>.

T
T1MicTest = Record<PropertyKey, never>

The value of <T1MicTest>: the firmware reads and writes no fields.

T
TalkConfig = { duplex?: "FDX" | "HDX"; audioStreamMode?: "followVideoStream" | "onlyAudioStream" | "mixAudioStream"; audioConfig?: TalkAudioConfig; }

The two-way audio session in <TalkConfig>.

T
TimeCfg = { realTime?: number; }

The clock setting in <TimeCfg>.

T
TimelapseCfg = { channelId?: number; overwrite?: number; maxFileNum?: number; item?: TimelapseCfgItem; }

The time-lapse settings in <timelapseCfg>.

T
TimelapseCfgTime = { year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number; }

A date and time in <timelapseCfg>. The item's range is written with year to minute, a duration window with hour to second.

T
TimelapseCover = { id?: string; }

The file reference in <timelapseCover>.

T
TimelapseDateTbl = { channelId?: number; uid?: string; id?: string; item?: TimelapseDateTblItem[]; }

The days with time-lapse files in <timelapseDateTbl>.

T
TimelapseDateTblItem = { year?: number; dateTable?: string; }

One year in <timelapseDateTbl>.

T
TimelapseDownload = { position?: bigint; id?: string; taskType?: "mp4" | "jpeg"; }

One timelapse file to download, in <timelapseDownload>.

T
TimelapseFile = { id?: string; fileName?: string; resoHight?: number; resowidth?: number; size?: bigint; duration?: number; startTime?: TimelapseFileTime; endTime?: TimelapseFileTime; }

One stored file in a <timelapseFileSearch> item.

T
TimelapseFileDel = { taskType?: "mp4" | "jpeg"; item: { id?: string; }[]; }

Timelapse files to delete, in <timelapseFileDel>.

T
TimelapseFileItem = { original?: TimelapseFile; thumbnail?: TimelapseFile; }

One result in <timelapseFileSearch>.

T
TimelapseFileSearch = { channelId?: number; handle?: number; totalNum?: number; finished?: number; uid?: string; id?: string; fromWhere?: number; startTime?: TimelapseFileTime; endTime?: TimelapseFileTime; taskType?: "mp4" | "jpeg"; item?: TimelapseFileItem[]; }

The search state and results in <timelapseFileSearch>.

T
TimelapseFileTime = { year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number; }

A date and time in <timelapseFileSearch>.

T
TimelapseTaskDel = { uid?: string; id?: string; }

A timelapse task to delete, in <timelapseTaskDel>.

T
TimelapseTasks = { channelId?: number; uid?: string; item?: TimelapseTask[]; }

The stored time-lapse tasks in <timelapseTasks>.

T
TrackLimit = { channelId?: number; leftLimit?: number; leftImageName?: string; rightLimit?: number; rightImageName?: string; }

The AI tracking pan limits in <trackLimit>.

T
TrackSchedule = { channelId?: number; timeTable?: string; }

The AI tracking schedule in <trackSchedule>.

  • channelId: number

    Zero-based channel.

  • timeTable: string

    Schedule as text of up to 168 characters, stored as-is. The same field in <IOTAction> holds one 0 or 1 per hour of the week.

T
Uid = { uid: string; }

The camera's P2P UID in <Uid>.

T
Upnp = { enable: number; }

The UPnP switch in <Upnp>.

T
UserList = { User: UserListUser[]; }

The user accounts in <UserList>.

T
UserListUser = { userId?: number; userName?: string; userLevel?: number; loginState?: number; userSetState?: "none" | "add" | "delete" | "modify"; password?: string; }

One account in <UserList>.

T
VersionInfo = { name: string; type: string; serialNumber: string; buildDay: string; hardwareVersion: string; cfgVersion: string; firmwareVersion: string; detail: string; IEClient: string; pakSuffix: string; itemNo?: string; aiVersion?: string; anotherPakSuffix?: string; helpVersion?: string; }

The device and firmware identity in <VersionInfo>.

T
VideoInput = { channelId?: number; bright?: number; contrast?: number; saturation?: number; hue?: number; sharpen?: number; }

The image adjustments in <VideoInput>.

T
WhiteLightInfo = Record<PropertyKey, never>

The value of <whiteLightInfo>: the firmware reads and writes no fields.

T
Wifi = { scanAp?: number; freqPolicy?: number; protocol?: number; mode?: "station" | "ap"; authMode?: "open" | "shared" | "wpapsk" | "wpa2psk" | "detect"; encryptType?: "none" | "wep" | "tkip" | "aes" | "detect"; udidList?: WifiUdid[]; ssid?: string; key?: string; channel?: number; type?: number; staticSsid?: string; staticKey?: string; countryCode?: string; }

The Wi-Fi client settings in <Wifi>.

T
WifiSignal = { signal: number; }

The Wi-Fi signal strength in <WifiSignal>.

T
WifiUdid = { name?: string; signal?: number; encrypt?: number; type?: number; protocol?: number; }

One access point in <udidList>, as a <udid> element.

T
ZfBacklash = { fBacklash?: number; zBacklash?: number; }

The zoom and focus motor backlash in <ZfBacklash>.

T
ZoomFocusInfo = { channelId?: number; zoom?: ZoomFocusPos; focus?: ZoomFocusPos; }

The zoom and focus positions in <ZoomFocusInfo>.

T
ZoomFocusPos = { maxPos?: number; minPos?: number; curPos?: number; }

One motor's range and position in <ZoomFocusInfo>.

Variables

v
v
devBodyCode: XmlParam<"DevBodyCode", DevBodyCode>

Codec for <DevBodyCode>. It reads any element as {}.

v
v
v
v
ftySnapCfg: XmlParam<"ftySnapCfg", FtySnapCfg>

Codec for <ftySnapCfg>. It reads any element as {}.

v
imageCheck: XmlParam<"ImageCheck", ImageCheck>

Codec for <ImageCheck>. It reads any element as {}.

v
ip: XmlParam<"Ip", Ip>

Codec for <Ip>.

v
irCutInfo: XmlParam<"IrCutInfo", IrCutInfo>

Codec for <IrCutInfo>. It reads any element as {}.

v
md: XmlParam<"MD", Md>

Codec for <MD>.

v
v
paramDataV20: XmlParam<"PARAM_DATA_V20", ParamDataV20>

Codec for <PARAM_DATA_V20>. It has no fields: the payload it names is binary and is not part of the XML body.

v
v
whiteLightInfo: XmlParam<"whiteLightInfo", WhiteLightInfo>

Codec for <whiteLightInfo>. It reads any element as {}.

protocol/commands.ts

Every Baichuan command registered by the firmware builds this package was derived from, and the messages they push unasked, as data for Client.call and Client.pushes.

Examples

Read the network ports

import { createClient } from "@hertzg/reolink-api";
import { COMMANDS } from "@hertzg/reolink-api/protocol/commands";

const conn = await Deno.connect({ hostname: "192.168.1.10", port: 9000 });
const client = createClient({ readable: conn.readable, writable: conn.writable });
await client.login({ username: "admin", password: "secret" });

const { body } = await client.call(COMMANDS.GET_NETPORT_CFG_V20);
console.log(body.RtspPort?.rtspPort);

Look up a command

import { assertEquals } from "@std/assert";
import { COMMANDS } from "@hertzg/reolink-api/protocol/commands";

assertEquals(COMMANDS.GET_NETPORT_CFG_V20.id, 37);
assertEquals(
  COMMANDS.GET_NETPORT_CFG_V20.params.map((param) => param.name),
  ["ServerPort", "HttpPort", "RtspPort", "OnvifPort", "HttpsPort", "RtmpPort"],
);

Type Aliases

T
Commands = { HEART_BEAT_V20: Command<readonly [heartBeat]>; LOGIN: Command<
readonly [
loginUser,
loginNet,
ipcVersionList,
deviceInfo,
streamInfoList,
loginErrInfo,
accessInfo
]
>
; LOGOUT: Command<readonly [loginUser]>; START_PREVIEW: Command<readonly [preview]>; STOP_PREVIEW: Command<readonly [preview]>; START_REPLAY: Command<readonly [fileInfoList]>; STOP_REPLAY: Command<readonly [fileInfoList]>; DOWNLOAD_V20: Command<readonly [fileInfoList]>; DOWNLOAD_STOP_V20: Command<readonly [fileInfoList]>; GET_TALK_ABILITY: Command<readonly [talkAbility]>; TALK_CLOSE_V20: Command<readonly []>; FILE_INFO: Command<readonly [fileInfoList]>; SEARCH_OPEN: Command<readonly [fileInfoList]>; SEARCH_FILE: Command<readonly [fileInfoList]>; SEARCH_CLOSE: Command<readonly [fileInfoList]>; PTZ_CONTROL_V20: Command<readonly [ptzControl]>; PTZ_PRESET_V20: Command<readonly [ptzPreset]>; PTZ_CRUISE_V20: Command<readonly [ptzCruise]>; REBOOT_V20: Command<readonly []>; SETVEDIOPARAM_V20: Command<readonly [videoInput, inputAdvanceCfg]>; GETVEDIOPARAM_V20: Command<readonly [videoInput, inputAdvanceCfg]>; START_ALARM_REPORT: Command<readonly []>; SET_NETPORT_CFG_V20: Command<
readonly [
serverPort,
httpPort,
rtspPort,
onvifPort,
httpsPort,
rtmpPort
]
>
; GET_NETPORT_CFG_V20: Command<
readonly [
serverPort,
httpPort,
rtspPort,
onvifPort,
httpsPort,
rtmpPort
]
>
; GET_NTPCFG_V20: Command<readonly [ntp]>; SET_NTPCFG_V20: Command<readonly [ntp]>; GET_DDNSCFG_V20: Command<readonly [ddns]>; SET_DDNSCFG_V20: Command<readonly [ddns]>; GET_EMAILCFG_V20: Command<readonly [email]>; SET_EMAILCFG_V20: Command<readonly [email]>; GET_OSD_CFG_V20: Command<readonly [osdChannelName, osdDatetime]>; SET_OSD_CFG_V20: Command<readonly [osdChannelName, osdDatetime]>; GET_MD_CFG_V20: Command<readonly [md]>; SET_MD_CFG_V20: Command<readonly [md]>; GET_SHELTER_CFG_V20: Command<readonly [shelter]>; SET_SHELTER_CFG_V20: Command<readonly [shelter]>; GET_RECORD_V20: Command<readonly [recordCfg]>; SET_RECORD_V20: Command<readonly [recordCfg]>; GET_COMPRESSIONCFG_V20: Command<readonly [compression]>; SET_COMPRESSIONCFG_V20: Command<readonly [compression]>; GET_USERCFG_V20: Command<readonly [abilitySuppport, userList]>; SET_USERCFG_V20: Command<readonly [userList]>; GET_PTZCRUISE_V20: Command<readonly [ptzCruise]>; EXPORT_CFG_V20: Command<readonly [configFileInfo]>; UPDATE_DEVICE: Command<readonly [configFileInfo, paramDataV20]>; GET_FTPCFG_V20: Command<readonly [ftp]>; SET_FTPCFG_V20: Command<readonly [ftp]>; GET_FTPTASK_V20: Command<readonly [ftpTask]>; SET_FTPTASK_V20: Command<readonly [ftpTask]>; GET_LOCAL_LINK_V20: Command<readonly [dhcp, autoDns, ip, dns]>; SET_LOCAL_LINK_V20: Command<readonly [dhcp, autoDns, ip, dns]>; GET_VERSION_V20: Command<readonly [versionInfo]>; GET_RECSCHEDULE_V20: Command<readonly [record]>; SET_RECSCHEDULE_V20: Command<readonly [record]>; GET_LINK_TYPE: Command<readonly [linkType]>; GET_UPNPSTATE_V20: Command<readonly [upnp]>; SET_UPNPSTATE_V20: Command<readonly [upnp]>; SET_RESTORE_V20: Command<readonly [restore]>; SET_AUTO_REBOOT_CFG_V20: Command<readonly [autoReboot]>; GET_AUTO_REBOOT_CFG_V20: Command<readonly [autoReboot]>; GET_HDD_CFG_V20: Command<readonly [hddInfoList]>; INIT_HDD_V20: Command<readonly [hddInitList]>; GET_SYSGENERAL_CFG_V20: Command<readonly [systemGeneral, norm]>; SET_SYSGENERAL_CFG_V20: Command<readonly [systemGeneral, norm]>; GET_DST_CFG_V20: Command<readonly [dst]>; SET_DST_CFG_V20: Command<readonly [dst]>; SNAP_V20: Command<readonly [snap]>; GET_DEF_OSD_CFG_V20: Command<readonly [osdChannelName, osdDatetime]>; GET_DEF_INPUT_CFG_V20: Command<readonly [videoInput, shelter]>; GET_DEF_ENC_CFG_V20: Command<readonly [compression]>; GET_DEF_MD_CFG_V20: Command<readonly [md]>; GET_UID_CFG_V20: Command<readonly [uid]>; GET_WIFI_SIGNAL_V20: Command<readonly [wifiSignal]>; GET_WIFI_INFO_V20: Command<readonly [wifi]>; SET_WIFI_INFO_V20: Command<readonly [wifi]>; GET_USER_ONLINE_V20: Command<readonly [onlineUserList]>; SET_USER_ONLINE_V20: Command<readonly [onlineUserList]>; INFO_PERFORMANCE_V20: Command<readonly [performanceInfo]>; REPLAY_SEEK: Command<readonly [replaySeek]>; PUSH_ADD_V20: Command<readonly [pushInfo, pushRspInfo]>; PUSH_DEL_V20: Command<readonly [pushInfo]>; GET_DEF_ISP_CFG_V20: Command<readonly [inputAdvanceCfg, videoInput]>; EMAIL_TEST_V20: Command<readonly [email]>; GET_DAY_RECORD: Command<readonly [dayRecords]>; DOWNLOAD_CUT_V20: Command<readonly [fileInfoList]>; DOWNLOAD_CUT_STOP_V20: Command<readonly []>; GET_ENC_CAPABILITY_V20: Command<readonly [streamInfoList]>; GET_ABILITY: Command<readonly [abilityInfo]>; CGI_GET_POWER_LINE_FREQUENCY: Command<readonly [inputAdvanceCfg, powerLineFrequency]>; CGI_SET_POWER_LINE_FREQUENCY: Command<readonly [inputAdvanceCfg]>; CGI_GET_EXPOSURE: Command<readonly [inputAdvanceCfg, exposureCfg]>; CGI_SET_EXPOSURE: Command<readonly [inputAdvanceCfg]>; CGI_GET_SHUTTER: Command<readonly [inputAdvanceCfg, shutter]>; CGI_SET_SHUTTER: Command<readonly [inputAdvanceCfg]>; CGI_GET_GAIN: Command<readonly [inputAdvanceCfg, gain]>; CGI_SET_GAIN: Command<readonly [inputAdvanceCfg]>; CGI_GET_SCENE: Command<readonly [inputAdvanceCfg, scene]>; CGI_SET_SCENE: Command<readonly [inputAdvanceCfg]>; CGI_GET_DAY_NIGHT_MODE: Command<readonly [inputAdvanceCfg, dayNightMode]>; CGI_SET_DAY_NIGHT_MODE: Command<readonly [inputAdvanceCfg]>; CGI_GET_IRCUT_MODE: Command<readonly [inputAdvanceCfg, ircutMode]>; CGI_SET_IRCUT_MODE: Command<readonly [inputAdvanceCfg]>; CGI_GET_BLC: Command<readonly [inputAdvanceCfg, blc]>; CGI_SET_BLC: Command<readonly [inputAdvanceCfg]>; CGI_GET_MIRROR: Command<readonly [inputAdvanceCfg, mirror]>; CGI_SET_MIRROR: Command<readonly [inputAdvanceCfg]>; CGI_GET_FLIP: Command<readonly [inputAdvanceCfg, flip]>; CGI_SET_FLIP: Command<readonly [inputAdvanceCfg]>; IFRAME_REQUEST: Command<readonly [requestIframe]>; GET_PTZ_PRESET_V20: Command<readonly [ptzPreset]>; ONLINE_UPDATE_V20: Command<readonly [onlineUpdate]>; START_ALARM_REPORT_192: Command<readonly []>; FTP_TEST_V20: Command<readonly [ftp, ftpTestResult]>; UPDATE_CFG_GET_V20: Command<readonly [autoUpdate]>; UPDATE_CFG_SET_V20: Command<readonly [autoUpdate]>; GET_ONLINE_NEW_FW_V20: Command<readonly [onlineNewFirmwareInfo]>; GET_SCAN_AP_V20: Command<readonly [scanAp]>; GET_SUPPORT: Command<readonly [support]>; WIFI_TEST_V20: Command<readonly [wifi]>; TALK_OPEN_V20: Command<readonly [talkConfig]>; TALK_FDX_STREAM_V20: Command<readonly [paramDataV20]>; GET_LED_STATE_V20: Command<readonly [ledState]>; SET_LED_STATE_V20: Command<readonly [ledState]>; GET_PTOP_CFG_V20: Command<readonly [ptop]>; SET_PTOP_CFG_V20: Command<readonly [ptop]>; GET_RF_CFG_V20: Command<readonly [rfAlarmCfg]>; SET_RF_CFG_V20: Command<readonly [rfAlarmCfg]>; SET_EMAILTASK_V20: Command<readonly [emailTask]>; GET_EMAILTASK_V20: Command<readonly [emailTask]>; SET_PUSHTASK_V20: Command<readonly [pushTask]>; GET_PUSHTASK_V20: Command<readonly [pushTask]>; GET_AUTO_FOCUS_V20: Command<readonly [autoFocus]>; SET_AUTO_FOCUS_V20: Command<readonly [autoFocus]>; GET_ONLINE_UPDATE_STATE: Command<readonly [upgradeState]>; GET_CROP_V20: Command<readonly [crop]>; SET_CROP_V20: Command<readonly [crop]>; CROP_SNAP_V20: Command<readonly [cropSnap, cropSnapReply]>; SET_AUDIOTASK_V20: Command<readonly [audioTask]>; GET_AUDIOTASK_V20: Command<readonly [audioTask]>; SET_DEVICE_SLEEP: Command<readonly []>; SET_CLOUD_TASK_V20: Command<readonly [cloudTask]>; GET_CLOUD_TASK_V20: Command<readonly [cloudTask]>; GET_BAT_INFO_V20: Command<readonly [chargeBatteryInfo, batteryInfo]>; GET_4GNET_INFO: Command<readonly [net3g4gInfo]>; GET_4GMODULE_INFO: Command<readonly [net3g4gModuleInfo]>; GET_BATTERY_REMAIN_V20: Command<readonly [batteryRemainList]>; GET_AUDIO_INFO_V20: Command<readonly [audioFileInfo]>; IMPORT_AUDIO_V20: Command<readonly [audioFileInfo, paramDataV20]>; SAVE_AUDIO_V20: Command<readonly [audioFileInfo]>; PLAY_AUDIO_V20: Command<readonly [audioPlayInfo]>; GET_AUDIO_CFG_V20: Command<readonly [audioCfg]>; SET_AUDIO_CFG_V20: Command<readonly [audioCfg]>; MUTE_AUDIO_V20: Command<readonly [muteAudio]>; GET_AUDIO_ENCODE_ABILITY_V20: Command<readonly [audioEncodeAbility]>; NEW_GET_CLOUD_BIND_INFO_V20: Command<readonly [cloudBindInfo]>; NEW_BIND_CLOUD_V20: Command<readonly [bindCloud]>; GET_CLOUD_CFG_V20: Command<readonly [cloudUploadCfg]>; SET_CLOUD_CFG_V20: Command<readonly [cloudUploadCfg]>; START_FIND_ALARM_VIDEO_V20: Command<readonly [findAlarmVideo]>; DO_FIND_ALARM_VIDEO_V20: Command<readonly [findAlarmVideo, alarmVideoInfo]>; STOP_FIND_ALARM_VIDEO_V20: Command<readonly [findAlarmVideo]>; BIND_NAS: Command<readonly [bindUnbindNas]>; UNBIND_NAS: Command<readonly [bindUnbindNas]>; GET_BIND_INFO_V20: Command<readonly [bindNasInfoList]>; GET_CLOUD_LOGIN_V20: Command<readonly [cloudLoginKey]>; SET_CLOUD_LOGIN_V20: Command<readonly [cloudLoginKey]>; SET_GOP_V20: Command<readonly [gopCfg]>; SET_TIME_V20: Command<readonly [timeCfg]>; SET_FLOODLIGHT_STATUS: Command<readonly [floodlightManual]>; GET_FLOODLIGHT_TASK: Command<readonly [floodlightTask]>; SET_FLOODLIGHT_TASK: Command<readonly [floodlightTask]>; GET_ZOOM_FOCUS_INFO_V20: Command<readonly [zoomFocusInfo, ptzZoomFocus]>; GET_ZOOM_FOCUS_INFO_V20_295: Command<readonly [startZoomFocus]>; GET_DAY_NIGHT_THRESHOLD_V20: Command<readonly [dayNightThreshold]>; SET_DAY_NIGHT_THRESHOLD_V20: Command<readonly [dayNightThreshold]>; COVER_PREVIEW: Command<readonly [coverPreview]>; GET_AI_CFG: Command<readonly [aiCfg]>; SET_AI_CFG: Command<readonly [aiCfg]>; GET_NAS_CFG: Command<readonly [nasUploadCfg]>; SET_NAS_CFG: Command<readonly [nasUploadCfg]>; GET_TIMELAPSE_CFG_V20: Command<readonly [timelapseCfg]>; SET_TIMELAPSE_CFG_V20: Command<readonly [timelapseCfg]>; GET_TIMELAPSE_TASK_V20: Command<readonly [timelapseTasks]>; GET_TIMELAPSE_DATE_V20: Command<readonly [timelapseDateTbl]>; GET_TIMELAPSE_OPEN_V20: Command<readonly [timelapseFileSearch]>; GET_TIMELAPSE_NEXT_V20: Command<readonly [timelapseFileSearch]>; GET_TIMELAPSE_CLOSE_V20: Command<readonly [timelapseFileSearch]>; GET_TIMELAPSE_FILE_COVER_V20: Command<readonly [timelapseCover]>; GET_TIMELAPSE_DOWNLOAD_V20: Command<readonly [timelapseDownload]>; GET_TIMELAPSE_DLD_STOP_V20: Command<readonly []>; GET_TIMELAPSE_DELETE_V20: Command<readonly [timelapseTaskDel]>; GET_TIMELAPSE_FILE_DEL_V20: Command<readonly [timelapseFileDel]>; SET_GUARD_V20: Command<readonly [ptzGuard]>; GET_GUARD_V20: Command<readonly [ptzGuard]>; GET_PTZ_AUTO_TEST_V20: Command<readonly [ptzAutoTest]>; PTZ_AUTO_TEST_V20: Command<readonly []>; GET_AI_DETECT_CFG_V20: Command<readonly [aiDetectCfg]>; SET_AI_DETECT_CFG_V20: Command<readonly [aiDetectCfg]>; GET_DEF_AI_DETECT_CFG_V20: Command<readonly [aiDetectCfg]>; SET_ALARM_AREA_V20: Command<readonly [alarmArea]>; GET_SMT_PLAY_URL_V20: Command<readonly [smtPlayUrl, smtPlayUrlReply]>; GET_AUDIO_FILE_INFO_LIST_V20: Command<readonly [audioFileInfoList]>; DELETE_AUDIO_FILE_V20: Command<readonly [audioFileInfo]>; PLAY_ALARM_ALERTOR_V20: Command<readonly [audioFileInfo]>; STOP_ALARM_ALERTOR_V20: Command<readonly []>; GET_NETWORK_DIAGNOSIS_DATA_V20: Command<readonly [networkDiagnosisData]>; PUSH_TEST_V20: Command<readonly [pushTestResult]>; GET_AI_TRACK_DATA_V20: Command<readonly [aiTrackData]>; GET_PUSH_CFG_V20: Command<readonly [pushCfg]>; SET_PUSH_CFG_V20: Command<readonly [pushCfg]>; CLOUD_TEST_V20: Command<readonly [cloudTestResult]>; SET_AUDIO_FILE_INFO_LIST_V20: Command<readonly [audioFileInfoList]>; START_REPLAY_BY_TM: Command<readonly [replayByTimeV2]>; STOP_REPLAY_BY_TM: Command<readonly [replayByTimeV2]>; SEEK_REPLAY_BY_TM: Command<readonly [replaySeekV2]>; BIND_IOT_V20: Command<readonly [iotBindUnBind]>; UNBIND_IOT_V20: Command<readonly [iotBindUnBind]>; GET_BIND_IOT_INFO_V20: Command<readonly [iotBindInfoList]>; GET_IOT_ACTION_V20: Command<readonly [iotAction, iotActionList]>; SET_IOT_ACTION_V20: Command<readonly [iotAction]>; EXPORT_AUDIO_V20: Command<readonly [audioFileInfo]>; IMPORT_IMAGE_V20: Command<readonly [imageFileInfo, paramDataV20]>; EXPORT_IMAGE_V20: Command<readonly [imageFileInfo]>; GET_AUTO_REPLY: Command<readonly [autoReply]>; SET_AUTO_REPLY: Command<readonly [autoReply]>; GET_PTZ_CUR_POS_V20: Command<readonly [ptzCurPos]>; GET_AI_TRACK_LIMIT_V20: Command<readonly [trackLimit]>; SET_AI_TRACK_LIMIT_V20: Command<readonly [trackLimit]>; GET_AI_TRACK_TASK_V20: Command<readonly [trackSchedule]>; SET_AI_TRACK_TASK_V20: Command<readonly [trackSchedule]>; PTZ_3D_LOCATION_V20: Command<readonly [ptz3DLocation]>; GET_AF_ALGORITHM_V20: Command<readonly [afAlgorithm]>; SET_AF_ALGORITHM_V20: Command<readonly [afAlgorithm]>; GET_HTTPS_CERT_INFO: Command<readonly [certificateInfo]>; SET_HTTPS_CERT_INFO: Command<readonly [certificateInfo]>; DINGDONG_CTRL: Command<readonly [dingdongCtrl]>; DINGDONG_LIST_GET: Command<readonly [dingdongList]>; DINGDONG_DEV_OPT: Command<readonly [dingdongDeviceOpt]>; DINGDONG_CFG_GET: Command<readonly [dingdongCfg]>; DINGDONG_CFG_SET: Command<readonly [dingdongCfg]>; AUTH_MODE_CODE_GET: Command<readonly [authInfo]>; GET_SHARED_USER_CFG: Command<readonly [accessUserList]>; SET_SHARED_USER_CFG: Command<readonly [accessUserList]>; SYNC_SSID: Command<readonly [syncSsid]>; GET_CLIENT_ID: Command<readonly [pushClientId]>; CREATE_PUSH_LISTENER: Command<readonly [pushCreateListener]>; SYNC_CLIENT_LIST: Command<readonly []>; GET_CLIENT_STATE: Command<readonly [pushClientState]>; GET_SLEEP_STATE: Command<readonly [sleepState]>; SET_SLEEP_STATE: Command<readonly [sleepState]>; NET_GET_FREQ_CORRECT_RESULT: Command<readonly [freqCorrectResult]>; GET_DINGDONG_SILENT_MODE: Command<readonly [dingdongSilentMode]>; SET_DINGDONG_SILENT_MODE: Command<readonly [dingdongSilentMode]>; INSTANT_PLAY_AUDIO: Command<readonly [audioFileInfo, paramDataV20]>; SET_ANSWER_EVENT: Command<readonly [answerEvent]>; DELETE_RECORD_FILE: Command<readonly [deleteRecordFile]>; SET_AI_YUV_STREAM_CFG: Command<readonly [aiyuvCfg]>; }

The firmware request commands, keyed by name.

T
Pushes = { ALARM_EVENT_REPORT: Command<readonly [alarmEventList]>; VIDEO_INPUT_CHANGE_REPORT: Command<readonly [videoInput]>; SERIAL_CHANGE_REPORT: Command<readonly [serial]>; BATTERY_CAMERA_HEARTBEAT: Command<readonly []>; BATTERY_STATUS_REPORT: Command<readonly [batteryList]>; MOBILE_NETWORK_REPORT: Command<readonly [net3g4gInfo]>; FLOODLIGHT_STATUS_REPORT: Command<readonly [floodlightStatusList]>; CHIME_SCAN_REPORT: Command<readonly [dingdongList]>; SLEEP_STATUS_REPORT: Command<readonly [sleepStatus]>; }

The messages the firmware pushes unasked, keyed by a descriptive name.

Variables

v
COMMANDS: Commands

The firmware request commands, for Client.call.

v
PUSHES: Pushes

The messages the firmware pushes unasked. Names are descriptive: the firmware dispatch tables only list requests.

protocol/siren.ts

Siren requests (cmd 263).

Examples

Build a request that plays the siren twice

import { assertStringIncludes } from "@std/assert";
import { sirenXml } from "@hertzg/reolink-api/protocol/siren";

const xml = sirenXml({ channel: 0, times: 2 });

assertStringIncludes(xml, "<playMode>0</playMode>");
assertStringIncludes(xml, "<playTimes>2</playTimes>");

Functions

f
sirenXml(request: SirenRequest): string

Builds the body of a siren request.

Type Aliases

T
SirenRequest =
{ channel?: number; }
& (
{ times: number; on?: never; }
| { on: boolean; times?: never; }
)

What sirenXml asks the siren to do: play a number of times, or turn manual play on or off.

protocol/privacy.ts

Privacy mode, which Reolink also calls sleep: the camera stops recording and streaming until it is turned off again.

Examples

Turn privacy mode on, then read it back

import { assertEquals, assertStringIncludes } from "@std/assert";
import {
  parsePrivacyMode,
  privacyModeXml,
} from "@hertzg/reolink-api/protocol/privacy";

assertStringIncludes(privacyModeXml(true), "<sleep>1</sleep>");
assertEquals(
  parsePrivacyMode("<body><sleepState><sleep>1</sleep></sleepState></body>"),
  true,
);

Functions

f
parsePrivacyMode(xml: string): boolean

Reads the privacy mode state from the reply to a cmd 574 request.

f
privacyModeXml(enabled: boolean): string

Builds the body of a request that turns privacy mode on or off.

protocol/snapshot.ts

Snapshot requests (cmd 109): a JPEG of the current frame.

Examples

Build a request and read the announced size

import { assertEquals, assertStringIncludes } from "@std/assert";
import {
  parseSnapshotSize,
  snapshotXml,
} from "@hertzg/reolink-api/protocol/snapshot";

assertStringIncludes(
  snapshotXml({ channel: 0, stream: "main" }),
  "<streamType>main</streamType>",
);
assertEquals(
  parseSnapshotSize("<body><Snap><pictureSize>48213</pictureSize></Snap></body>"),
  48213,
);

Functions

f
parseSnapshotSize(xml: string): number

Reads the announced image size from the reply to a snapshot request.

f
snapshotXml(request: SnapshotRequest): string

Builds the body of a snapshot request.

Type Aliases

T
SnapshotRequest = { channel: number; stream: "main" | "sub"; }

What snapshotXml asks for.

protocol/ptz.ts

PTZ (pan, tilt, zoom) requests.

Examples

Pan left, then stop

import { assertStringIncludes } from "@std/assert";
import { PTZ_COMMAND, ptzControlXml } from "@hertzg/reolink-api/protocol/ptz";

assertStringIncludes(
  ptzControlXml({ channel: 0, command: PTZ_COMMAND.LEFT, speed: 32 }),
  "<command>Left</command>",
);
assertStringIncludes(
  ptzControlXml({ channel: 0, command: PTZ_COMMAND.STOP }),
  "<command>Stop</command>",
);

Functions

f
parsePtzPosition(xml: string): PtzPosition

Reads the current position from the reply to a cmd 433 request.

f
parsePtzPresets(xml: string): PtzPreset[]

Reads the saved presets from the reply to a cmd 190 request.

f
ptzControlXml(request: PtzControlRequest): string

Builds the body of a PTZ move (cmd 18).

f
ptzPresetXml(request: { channel: number; id: number; }): string

Builds the body of a request that moves to a saved preset (cmd 19).

Type Aliases

T
PtzCommand = (PTZ_COMMAND)[keyof PTZ_COMMAND]

Union of the PTZ_COMMAND values.

T
PtzControlRequest = { channel: number; command: PtzCommand; speed?: number; }

What ptzControlXml asks the camera to do.

T
PtzPosition = { pan: number; tilt: number; }

Where the camera points, in the camera's own motor units.

T
PtzPreset = { id: number; name: string; }

A saved PTZ position.

Variables

v
PTZ_COMMAND: { STOP: string; LEFT: string; RIGHT: string; UP: string; DOWN: string; LEFT_UP: string; LEFT_DOWN: string; RIGHT_UP: string; RIGHT_DOWN: string; ZOOM_IN: string; ZOOM_OUT: string; AUTO: string; }

PTZ commands for ptzControlXml. A move keeps going until STOP.

streams/encode.ts

Encode stream: Baichuan messages to bytes.

Examples

Encode the nonce request

import { assertEquals } from "@std/assert";
import { decodeHex } from "@std/encoding/hex";
import { createMessage } from "@hertzg/reolink-api/protocol/message";
import { createBaichuanEncodeStream } from "@hertzg/reolink-api/streams/encode";

const chunks = await Array.fromAsync(
  ReadableStream.from([
    createMessage({
      cmdId: 1,
      channelId: 250,
      messageId: 1,
      messageClass: 0x1465,
    }),
  ]).pipeThrough(createBaichuanEncodeStream()),
);

assertEquals(chunks, [decodeHex("f0debc0a0100000000000000fa01000012dc1465")]);

Functions

f
createBaichuanEncodeStream(): TransformStream<BaichuanMessage, Uint8Array>

Creates a TransformStream that writes each message as header, body and payload, in one chunk per message.

streams/decode.ts

Decode stream: bytes to Baichuan messages.

Examples

Decode a subscribe reply that arrives in two chunks

import { assertEquals } from "@std/assert";
import { decodeHex } from "@std/encoding/hex";
import { createBaichuanDecodeStream } from "@hertzg/reolink-api/streams/decode";

const bytes = decodeHex("f0debc0a1f00000000000000fb030000c800146400000000");

const messages = await Array.fromAsync(
  ReadableStream.from([bytes.subarray(0, 10), bytes.subarray(10)])
    .pipeThrough(createBaichuanDecodeStream()),
);

assertEquals(messages.length, 1);
assertEquals(messages[0].header.cmdId, 31);
assertEquals(messages[0].header.status, 200);

Functions

f
createBaichuanDecodeStream(): TransformStream<Uint8Array, BaichuanMessage>

Creates a TransformStream that frames a Baichuan byte stream into messages.

client.ts

Reolink Baichuan client: login, then a stream of alarm events.

Examples

Stream doorbell and motion events

import { createClient } from "@hertzg/reolink-api/client";

const conn = await Deno.connect({ hostname: "192.168.1.10", port: 9000 });
const client = createClient({ readable: conn.readable, writable: conn.writable });

await client.login({ username: "admin", password: "secret" });
const events = await client.subscribe();

for await (const event of events) {
  console.log(event.channel, event.visitor, event.motion, event.ai);
}

Functions

f
createClient(options: ClientOptions): Client

Creates a Baichuan client over the given connection streams.

Type Aliases

T
CallOptions<C extends Command> = { channel?: number; body?: CommandBody<C>; }

Options for Client.call.

T
CallReply<C extends Command> = { body: CommandBody<C>; payload: Uint8Array; }

The reply to Client.call.

T
ChannelOptions = { channel?: number; }

Which camera a request is about.

  • channel: number

    The zero-based channel number. A standalone camera is 0, the default.

T
Client = { login: (options: LoginOptions) => Promise<void>; subscribe: (options?: SubscribeOptions) => Promise<ReadableStream<AlarmEvent>>; playSiren: (options?: ChannelOptions & { times?: number; }) => Promise<void>; startSiren: (options?: ChannelOptions) => Promise<void>; stopSiren: (options?: ChannelOptions) => Promise<void>; privacyMode: (options?: ChannelOptions) => Promise<boolean>; setPrivacyMode: (options: ChannelOptions & { enabled: boolean; }) => Promise<void>; snapshot: (options?: ChannelOptions & { stream?: "main" | "sub"; }) => Promise<Uint8Array>; ptz: (options: ChannelOptions & { command: PtzCommand; speed?: number; }) => Promise<void>; ptzPresets: (options?: ChannelOptions) => Promise<PtzPreset[]>; ptzGoToPreset: (options: ChannelOptions & { id: number; }) => Promise<void>; ptzPosition: (options?: ChannelOptions) => Promise<PtzPosition>; call: <C extends Command>(
command: C,
options?: CallOptions<C>
) => Promise<CallReply<C>>
; pushes: () => ReadableStream<Push>; close: () => Promise<void>; }

A Baichuan client bound to one connection.

T
LoginOptions = { username: string; password: string; }

Camera credentials for Client.login.

T
SubscribeOptions = { keepAliveMs?: number; }

Options for Client.subscribe.

  • keepAliveMs: number

    How long the connection may stay silent before the client pings the camera, in milliseconds. If a second interval passes with nothing from the camera, the event stream errors. Defaults to 30_000.