github mega-yfue/eufy-sdk v0.5.0

18 days ago

92 pull requests since 0.4.0 (plus 11 dependency bumps): the HomeBase S1 Pro and the portal's WebRTC route for call doorbells and PoE cameras, a PPCS relay fallback when no direct P2P path answers, per-mode push notification, lock actuation on the classic Wi-Fi lock and the T8530, and Tuya robots and mowers read the way the app reads them.

npm install @mega-yfue/eufy-sdk@0.5.0

WebRTC portal route

  • HomeBase S1 Pro (T9000): commands over the portal's control channel (#243), live view of the cameras behind it (#345), siren (#364, #401), a warm command session via the portal keepalive (#407), and no RTSP publish switch installed behind it (#453).
  • Live video for the standalone T8223 (#419) and T8224 (#507) doorbells over the portal call.
  • T8N00 PoE: commands over native call signaling (#354) and media over independent calls (#436). Independent optical views on NVR cameras (#479).
  • A local candidate trickles only while the signalling socket is open (#363). A refused sign's error no longer echoes the token (#427). A peer that cannot be built ends its session and fails the bring-up with that error (#466).

P2P and live video

  • Falls back to a PPCS relay when no direct path answers (#474), and a session whose RSA cipher key does not unwrap no longer fails (#505).
  • Resync after unrecovered loss (#322), the app's attached live start selector (#337), probe receive buffers sized (#367), source timestamps kept for live timing (#368), and fMP4 durations on the arrival clock (#423). The original arrival time is exposed in readable envelopes (#396).
  • Shared live consumers start at the next live keyframe (#483). Fragmented payloads are copied once (#392). UDP sends complete before close (#478).
  • Session lifecycle: independent media survives a station control close (#393), a connected peer's END closes the session (#394), a session that acks forced starts but serves nothing is replaced (#390), level 2 is negotiated from a gateway-info reply sent in the clear (#391), and a cipher-0 own-session live view starts and stops unencrypted (#475).
  • A failed live start traces its typed reason and stage (#462). Live-view quality can be set again over 2730 (#353). A short UDP receive buffer is noted at debug (#329).
  • Audio: an aac-eld frame carries the decoder config its framing lacks (#317), and talkback is sent in the codec the camera's speaker plays (#348).

Recordings. Recording pages are queried and archive downloads demonstrated (#313), and recording pictures are assembled before output (#312).

Arming. A device's push notification is read and set per guard mode, on stations (#357) and standalone cameras (#379). A T8410C gets its guard mode as the direct 1224 frame (#448).

Locks and SmartDrop

  • The classic Wi-Fi lock actuates over its keyed-payload envelope (#232), and its padded result is read by its sign code (#485).
  • T8530: control and status (#383), and its camera (#457).
  • A standalone SmartDrop opens its lid with a level-2 key negotiated over RSA (#403).

Tuya robots and mowers

  • Cloud login the way the app does it (#372). DPs read with dp.get, also when the broker refuses the subscribe (#416), robots read without bringing up the broker (#440), refreshed on the cloud poll (#442), and last data points read from the cloud on load (#347). Clean-line devices are no longer subscribed on the AIoT broker (#434).
  • Read-only mower capability from the E15's Tuya schema (#366).
  • Vacuum: one AutoClean pass starts an auto clean (#340), the alias names the robot (#344), suction range read when the catalog lists level names (#365), and a Raw-DP payload whose getter answers a boolean is kept (#443).

Devices and model

  • New or corrected models: T8E00/T8P00 PoE (#355, #376, #438), T8213 (#356), T8210C (#358), T8354 with pan/tilt (#430), T90S0 smoke alarm (#452). Doorbells are typed from the app's doorbell tables rather than a row per model (#481).
  • Capability fixes: S350 on/off through privacy mode (#321), T8423 spotlight (#351), E330 Pro spotlight (#406), T8171 spotlight not inferred (#498), T8134 ptz not granted (#431), T8442 night vision (#492), keypad charging and battery-low params (#496).
  • The manifest says whether each property has been reported (#359), the property schema resolves from realtime evidence too (#335), and Wi-Fi signal is exposed (#352). aiDetectType's JSON object form is read (#464), a stopped station alarm is told from a triggered one (#425), and a v2 thumbnail with encrypted chroma tables is recovered (#409).
  • A standalone camera can be restarted (#311). A wired station's session reopens after a standalone recycle (#426). Per-sensor indoor sensitivity is stored without warning (#405).

Push, HTTP, MQTT

  • A push bring-up that failed at startup is retried (#377). Acknowledged persistent ids are dropped after an MCS login (#495). A transition push with nothing left to move lapses quietly (#341).
  • Autonomous re-login stops once one needs a captcha or 2FA (#432), and a stored session from another country logs in again (#433).
  • Each probed broker's refusal reason is named (#429), and push and broker connection errors name the socket (#451).

Repo. Release job's npm pinned to CI's (#343), T8N00 routing spec fixed (#374), Photo / Icon toggle in the devices gallery (#399).

Deps. node-datachannel ships as a dependency (#361), so the WebRTC route installs with the SDK. Latest compatible versions (#499), mqtt 5.16.1, protobufjs 8.8.1, vitest 5.0.5 and docs toolchain bumps (#332, #333, #334, #413, #414, #417, #482, #489, #490, #493, #503). npm audit is clean.

Breaking changes

  • LiveTrace gains a start-failed phase (#462). A host typing an exhaustive table against the union needs the row before it compiles.
  • LiveAudioFrame is a union keyed on codec (#317). An aac-eld frame always carries config; aac-lc and g711a frames never do.
  • LiveConsumer.primed is removed (#483). A host reading it no longer compiles.
  • SharedLiveSourceOptions.onSessionUnreachable returns boolean (#390), not void. A () => void callback no longer typechecks.
  • DpCatalog.enumRanges holds string[] (#365), not number[].

No export removed. Two runtime exports added, MOWER_MEMBERS and SMART_DROP_MEMBERS (301, up from 299), and five types: MediaSourceSelection, MowerActions, SmartDropActions, ReceivedVideoFrame, TalkbackCodec.

What's Changed

  • chore(deps-dev): bump source-map-js from 1.2.1 to 1.2.2 in /docs by @dependabot[bot] in #334
  • chore(deps): bump brace-expansion from 5.0.9 to 5.0.12 in /docs by @dependabot[bot] in #333
  • chore(deps): bump @vue/server-renderer and vue in /docs by @dependabot[bot] in #332
  • fix(p2p): note a short UDP receive buffer at debug, not warn by @martijnpoppen in #329
  • fix(p2p): resynchronize live video after unrecovered loss by @sapireli in #322
  • feat(client): restart a standalone camera, not only a HomeBase by @martijnpoppen in #311
  • fix(model): resolve the property schema from realtime evidence too by @martijnpoppen in #335
  • feat(rtc): drive the HomeBase S1 Pro (T9000) over the portal's WebRTC control channel by @danymexi in #243
  • fix(ci): pin the release job's npm to 11.5.1, the one CI runs by @lenoxys in #343
  • fix(client): let a transition push with nothing left to move lapse quietly by @martijnpoppen in #341
  • fix(p2p): match attached live start selector from the app by @sapireli in #337
  • fix(vacuum): start an auto clean with one AutoClean pass by @martijnpoppen in #340
  • fix(p2p): describe aac-eld audio with the decoder config its framing lacks by @abavyka in #317
  • fix(client): read a robot's last data points from the cloud on load by @martijnpoppen in #347
  • fix(client): name a robot vacuum by its alias, not the product label by @martijnpoppen in #344
  • fix(model): register the T8213 Video Doorbell Dual as a doorbell by @max246 in #356
  • feat(camera): expose reported Wi-Fi signal by @genomez in #352
  • fix(light): send the T8423 spotlight enable on the level-1 int+string frame by @ImSkully in #351
  • fix(p2p): send talkback in the codec the camera's speaker plays by @abavyka in #348
  • fix(camera): set live-view quality again over 2730 by @lenoxys in #353
  • fix(p2p): assemble recording pictures before producing output by @benhei2 in #312
  • feat(p2p): query recording pages and demonstrate archive downloads by @benhei2 in #313
  • fix(rtc): connect T8N00 commands through native call signaling by @fubo08 in #354
  • feat(arming): read and set a device's push notification per guard mode by @lenoxys in #357
  • fix(p2p): size adopted probe receive buffers by @sapireli in #367
  • fix(model): classify the T8E00 PoE S4 as a camera by @fubo08 in #355
  • fix(ci): set the T8N00 child channel in the routing spec by @lenoxys in #374
  • fix(model): read a vacuum's suction range when the catalog lists level names by @martijnpoppen in #365
  • fix(deps): ship node-datachannel as a dependency by @lenoxys in #361
  • fix(rtc): trickle a local candidate only while the signalling socket is open by @danymexi in #363
  • feat(p2p): preserve source timestamps for live video timing by @sapireli in #368
  • feat(rtc): live view of a camera behind a HomeBase S1 Pro (T9000) by @danymexi in #345
  • fix(client): retry a push bring-up that failed at startup by @martijnpoppen in #377
  • feat(siren): sound a camera behind a HomeBase S1 Pro with the portal's command by @danymexi in #364
  • fix(motion): store a per-sensor indoor sensitivity list without warning by @martijnpoppen in #405
  • fix(model): register the T8210C variant as a Video Doorbell by @max246 in #358
  • chore(deps): bump protobufjs from 8.8.0 to 8.8.1 by @dependabot[bot] in #417
  • chore(deps-dev): bump the toolchain group with 2 updates by @dependabot[bot] in #413
  • fix(rtc): drop the echoed token from a refused RTC sign's error by @max246 in #427
  • fix(p2p): keep fMP4 video durations on the arrival clock by @max246 in #423
  • perf(p2p): copy fragmented payloads once at completion by @sapireli in #392
  • fix(light): route E330 Pro (T8600) spotlight switch to int-string wire by @bgagan4 in #406
  • fix(ptz): recognize the T8E00 PoE S4 model by @fubo08 in #376
  • fix(camera): route S350 on/off through privacy mode by @Tursko in #321
  • chore(deps): bump actions/setup-node from 7.0.0 to 7.1.0 by @dependabot[bot] in #414
  • fix(model): stop granting ptz to the fixed-lens T8134 from its preset params by @max246 in #431
  • fix(model): register the T8354 Baby Monitor E21 with pan/tilt by @max246 in #430
  • fix(mqtt): name each probed broker's reason when none grants the SUBSCRIBE by @max246 in #429
  • fix(client): reopen a wired station's session after a standalone recycle by @max246 in #426
  • fix(model): tell a stopped station alarm from a triggered one by @max246 in #425
  • fix(image): recover a v2 thumbnail whose chroma tables are encrypted too by @danymexi in #409
  • feat(rtc): keep a station's command session warm with the portal keepalive by @danymexi in #407
  • fix(p2p): preserve independent media when station control closes by @sapireli in #393
  • fix(p2p): close a session when its connected peer sends END by @sapireli in #394
  • docs(gallery): add a Photo / Icon toggle to the devices gallery by @martijnpoppen in #399
  • feat(model): say in the manifest whether the device has reported each property by @max246 in #359
  • feat(transport): log into the Tuya cloud the way the app does (et=3, eh- account, wire names) by @martijnpoppen in #372
  • fix(client): read Tuya DPs with dp.get, also when the broker refuses the subscribe by @martijnpoppen in #416
  • feat(arming): read and set a standalone camera's notification per guard mode by @lenoxys in #379
  • fix(client): don't subscribe Tuya clean-line devices on the AIoT broker by @martijnpoppen in #434
  • feat(model): read-only mower capability from the E15's Tuya schema by @martijnpoppen in #366
  • fix(http): stop autonomous re-login once one needs a captcha or 2FA by @max246 in #432
  • fix(p2p): negotiate level 2 from a gateway-info reply sent in the clear by @lenoxys in #391
  • fix(model): classify T8E00 and T8P00 PoE cameras as wired by @fubo08 in #438
  • fix(client): read Tuya robots without bringing up the broker by @martijnpoppen in #440
  • feat(p2p): expose original arrival time in readable envelopes by @sapireli in #396
  • fix(http): log in again when the stored session's country differs by @max246 in #433
  • fix(p2p): replace a session that acknowledges forced starts and serves nothing by @lenoxys in #390
  • fix(model): classify the T90S0 smoke alarm as a sensor by @martijnpoppen in #452
  • fix(transport): name the socket in a push or broker connection error by @martijnpoppen in #451
  • fix(rtsp): install no publish switch behind a HomeBase S1 Pro by @martijnpoppen in #453
  • feat(client): refresh Tuya robot state on the cloud poll by @martijnpoppen in #442
  • fix(arming): send a T8410C its guard mode as the direct 1224 frame by @abavyka in #448
  • feat(rtc): live video for the standalone T8223 doorbell over the portal call by @nothenkjan in #419
  • fix(model): keep a Raw-DP payload whose getter answers a boolean by @martijnpoppen in #443
  • feat(siren): admit six more camera models behind a HomeBase S1 Pro by @danymexi in #401
  • feat(p2p): open a standalone SmartDrop's lid with a level-2 key negotiated over RSA by @danymexi in #403
  • feat(lock): support for T8530 control and status reporting by @JohnONolan in #383
  • fix(rtc): end a session whose peer cannot be built, and fail its bring-up with that error by @martijnpoppen in #466
  • fix(model): read aiDetectType's JSON object form and type the clean-line direction as a string by @martijnpoppen in #464
  • feat(rtc): serve T8N00 PoE camera media over independent calls by @fubo08 in #436
  • feat(model): give the T8530 video lock its camera by @davidjortizrivera in #457
  • chore(deps-dev): bump vite from 8.3.0 to 8.3.4 in /docs by @dependabot[bot] in #482
  • fix(p2p): wait for UDP send completion before closing by @sapireli in #478
  • feat(rtc): select independent optical views on NVR cameras by @fubo08 in #479
  • fix(model): type a doorbell from the app's doorbell tables, not a row per model by @lenoxys in #481
  • feat(p2p): trace a failed live start with its typed reason and stage by @lenoxys in #462
  • chore(deps): bump markdown-it from 14.3.2 to 14.3.3 in /docs by @dependabot[bot] in #493
  • chore(deps): bump protobufjs from 8.8.0 to 8.8.1 by @dependabot[bot] in #490
  • chore(deps): bump mqtt from 5.16.0 to 5.16.1 by @dependabot[bot] in #489
  • fix(p2p): read the lock's padded result by its sign code, not by a zero tail by @tturnerdev in #485
  • fix(media): start shared live consumers at the next live keyframe by @sapireli in #483
  • fix(p2p): start and stop a cipher-0 own-session live view unencrypted by @Bielecki-UK in #475
  • chore(deps): bump markdown-it from 14.3.2 to 14.3.3 in /docs by @dependabot[bot] in #503
  • fix: support T8442 night vision read and write by @minollo in #492
  • fix(push): drop the persistent ids a successful MCS login acknowledged by @martijnpoppen in #495
  • fix(keypad): read charging from 1655, move batteryLow to 1653 by @martijnpoppen in #496
  • feat(lock): actuate the classic Wi-Fi lock over its keyed-payload envelope by @tturnerdev in #232
  • chore(deps): bump dependencies to their latest compatible versions by @lenoxys in #499
  • fix(light): don't infer spotlight support on T8171 by @BremerLabs in #498
  • fix(p2p): don't fail a session whose RSA cipher key does not unwrap by @lenoxys in #505
  • fix(rtc): route the standalone T8224 doorbell over the portal call route by @lenoxys in #507
  • feat(p2p): fall back to a PPCS relay when no direct path answers by @martijnpoppen in #474
  • release: 0.5.0 by @lenoxys in #508

New Contributors

Full Changelog: v0.4.0...v0.5.0

Don't miss a new eufy-sdk release

NewReleases is sending notifications on new releases.