Repository navigation
feat(@hertzg/reolink-api): add Reolink Baichuan client for events, PTZ and every firmware command - #302
Merged
Conversation
Reolink cameras push doorbell, motion, tamper and AI detection state over their own TCP protocol on port 9000. No JSR package speaks it; the only Reolink client covers the HTTP API, which has no push events. The client logs in with the modern nonce + MD5 login, subscribes with cmd 31 and turns cmd 33 pushes into an AlarmEvent stream. It keeps an idle subscription alive with cmd 93 and errors the stream when the camera stops answering, leaving reconnects to the caller.
Requests sent after the camera closed the connection used to wait forever, and cancelling the event stream during subscribe left the keepalive pinging. The client state is now one subscription record and one ended reason, so every way of stopping goes through one shutdown.
…tick The subscription and its keepalive are now created synchronously when the event stream starts, so a concurrent subscribe sees it and throws, and a camera that never answers the subscribe request fails it instead of hanging.
… a slow write Closing rejected requests whose write was still queued, before anything listened to their reply, which surfaced as an unhandled rejection.
…fails to decode The read loop cancelled the connection's readable when a message threw, which closes a Deno socket the client promises not to touch.
…ocol constants Bytes 16-17 of a Baichuan header are a status code in 24-byte headers and an encryption marker in 20-byte ones, so every reader had to re-derive the meaning from the message class. The header now decodes to `status` plus `payloadOffset`, or to `encryption`, and command ids, channel ids and message classes are exported as BAICHUAN_CMD, BAICHUAN_CHANNEL and BAICHUAN_MESSAGE_CLASS. BREAKING CHANGE: BaichuanHeader no longer has `code`. Read `status` on 24-byte headers and `encryption` on 20-byte headers.
…payloads Requests about one camera carry an encrypted channel extension in front of their body, with payloadOffset pointing past it. Replies such as snapshots stream binary payload whose leading encryptLen bytes are AES-encrypted.
…messages Request builders and reply parsers for cmd 263, 574/575, 109 and 18/19/190, following reolink_aio's Baichuan XML.
… and ptz The client gains playSiren, startSiren, stopSiren, privacyMode, setPrivacyMode, snapshot, ptz, ptzPresets and ptzGoToPreset. These reach battery cameras and doorbells that have no HTTP API, and features such as privacy mode that only Baichuan exposes.
Some cameras push no PTZ state, so polling cmd 433 until pan and tilt stop changing is the only way to tell a move has finished. Checked against a real camera: replies take 125-260 ms and settle about 0.4 s after stop.
…them with call Reolink firmware dispatches 225 commands, each reading and writing a fixed set of XML parameter elements. Hand-writing a client method per command does not scale, so parameters become typed codecs, commands become an id plus their parameters, and one call() sends any command and decodes its reply. The parameter codecs for the RLC-823A firmware start as placeholders, to be filled from the firmware's serializers.
…A and Video Doorbell PoE Each XML parameter element either firmware reads or writes now has a codec recovered from the firmware's serializers and parsers, 199 in all. The command table covers the 257 commands the two builds register, tags each with the builds that have it, and adds the elements a reply was found to carry instead of the listed ones, so call() decodes them. pushes() streams every message the camera sends unasked, decoded by a push table, and passes unknown ones through as raw XML so nothing is dropped.
…ra firmware lacks A live read-only run against a doorbell failed TalkAbility on mixAudioStream, a stream mode only the doorbell firmware has. Checking every enum and field against the doorbell firmware found three more: the package AI type, the doorbell button light state in LedState, which was dropped silently, and the aiYuvData preview stream with its fields.
…erver adds A read-only run against a doorbell listed reply elements no codec read. The doorbell builds these replies in netserver rather than the shared library, so they were missing from the library evidence: recordAbility, smartRecord and talkRecord in RecordCfg, itemNo and aiVersion in VersionInfo, visitorLoudspeaker in audioCfg, and richNotificationEnable and consentAgreement in PushCfg.
Contributor
|
Docs preview: https://hertzg.github.io/jsr-monorepo/pr/302/ |
Contributor
Benchmark ResultsNo significant changes detected. 31 benchmark(s) within their noise floor. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #302 +/- ##
==========================================
+ Coverage 96.79% 97.78% +0.98%
==========================================
Files 159 374 +215
Lines 8499 13794 +5295
Branches 1300 1458 +158
==========================================
+ Hits 8227 13489 +5262
- Misses 152 175 +23
- Partials 120 130 +10 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
New package
@hertzg/reolink-api: a client for Reolink's own TCP protocol, Baichuan (port 9000). It works with cameras and doorbells that have no HTTP API.What's in it
subscribe()streams alarm state (motion, doorbell, tamper, AI types) and keeps idle connections alive with pings. Reconnecting stays with the caller.playSiren/startSiren/stopSiren,privacyMode/setPrivacyMode,snapshot,ptz,ptzPresets,ptzGoToPreset,ptzPosition.call(COMMANDS.X)sends any of the 257 commands the RLC-823A (IPC_523SD10.2898_23110119) and Video Doorbell PoE (DB_566128M5MP_P.4662_2508071283) firmware register, with typed request and reply bodies. Each command lists the firmware that has it.pushes()streams all unsolicited messages, typed for the 9 known ones and raw XML for anything else.How it was checked
Known limits