@apocaliss92/nodelink-js 0.4.32 → 0.4.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -2
- package/dist/{chunk-5Z7NVPV6.js → chunk-OZL6C2YJ.js} +30 -1
- package/dist/chunk-OZL6C2YJ.js.map +1 -0
- package/dist/cli/rtsp-server.cjs +29 -0
- package/dist/cli/rtsp-server.cjs.map +1 -1
- package/dist/cli/rtsp-server.js +1 -1
- package/dist/index.cjs +29 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-5Z7NVPV6.js.map +0 -1
package/README.md
CHANGED
|
@@ -49,14 +49,46 @@ Battery cameras (Argus, Go, …) can't reliably keep a TCP/ONVIF push subscripti
|
|
|
49
49
|
- **Auto** — manager: **Email Push** tab in the camera modal → *Auto-configure*. Scrypted: open the camera's Settings → **E-mail Push** group → *Auto-configure from Email Push Server*. Both call `setupEmailPushToManager` under the hood.
|
|
50
50
|
- **API** — `await api.setupEmailPushToManager({ managerHost, managerPort, recipientLocalPart, domain, authUsername, authPassword, triggerTypes, attachmentType }, channel)`. The lib auto-wraps a bare username as `<user@domain>` so MAIL FROM stays RFC 5321 compliant.
|
|
51
51
|
- **Manual** — fill the Reolink app form: server = manager LAN IP, port = `2525`, sender = `authUsername`, password = `authPassword`, TLS off, receiver = `cam-<id>@<domain>`.
|
|
52
|
-
4. On motion, the camera sends an e-mail. The intake parses it, classifies the trigger (`MD` / `people` / `vehicle`), and emits an `EmailPushEvent` on the shared bus.
|
|
52
|
+
4. On motion, the camera sends an e-mail. The intake parses it, classifies the trigger (`MD` / `people` / `vehicle`), and emits an `EmailPushEvent` on the shared bus. From there it lands on `api.onSimpleEvent` automatically — see "Unified event stream" below.
|
|
53
53
|
|
|
54
54
|
See [documentation/baichuan-api/email.md](./documentation/baichuan-api/email.md) for the full Baichuan API surface and [documentation/baichuan-api/time.md](./documentation/baichuan-api/time.md) for the related NTP / DST / system clock setters.
|
|
55
55
|
|
|
56
|
+
### Unified event stream (since 0.4.32)
|
|
57
|
+
|
|
58
|
+
Construct the api with `emailPushCameraId` (and optionally `emailPushChannel`) and the library wires the SMTP bus into the api's internal `simpleEventListeners` for you. Every consumer registered via `api.onSimpleEvent(...)` then receives native Baichuan push **and** SMTP-delivered motion through the same stream — no separate `onEmailPushEvent` subscription needed. The bridge survives TCP transient disconnects (it's a pure JS fan-out, not a network operation) and is released automatically by `close()`.
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { ReolinkBaichuanApi } from "@apocaliss92/nodelink-js";
|
|
62
|
+
|
|
63
|
+
const api = new ReolinkBaichuanApi({
|
|
64
|
+
host: "192.168.1.100",
|
|
65
|
+
username: "admin",
|
|
66
|
+
password: "secret",
|
|
67
|
+
transport: "udp",
|
|
68
|
+
uid: "REOLINK-UID-HERE",
|
|
69
|
+
|
|
70
|
+
// Auto-bridge SMTP motion into api.onSimpleEvent. Match the same
|
|
71
|
+
// cameraId your `createEmailPushServer({ cameraResolver })` returns
|
|
72
|
+
// (typically the camera's nativeId / stable identifier).
|
|
73
|
+
emailPushCameraId: "my-battery-cam",
|
|
74
|
+
emailPushChannel: 0, // optional, default 0
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
await api.login();
|
|
78
|
+
await api.onSimpleEvent((event) => {
|
|
79
|
+
// Fires for both native Baichuan push AND SMTP motion.
|
|
80
|
+
console.log(event.type, "on ch", event.channel, "@", event.timestamp);
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
For single-owner consumers that already manage their own bridge (e.g. a custom resolver scheme), the lower-level `api.subscribeEmailPushEvents({ cameraId | match, channel })` is still exposed.
|
|
85
|
+
|
|
56
86
|
**Library entry points**:
|
|
57
87
|
|
|
58
88
|
- `createEmailPushServer({ config, cameraResolver, logger, loadTls? })` — factory returning `{ start, stop, restart, updateConfig, getStatus }`
|
|
59
|
-
- `
|
|
89
|
+
- `new ReolinkBaichuanApi({ ..., emailPushCameraId, emailPushChannel? })` — auto-bridge into `onSimpleEvent` (recommended)
|
|
90
|
+
- `api.subscribeEmailPushEvents({ cameraId | match, channel? })` — manual per-api bridge with custom matcher
|
|
91
|
+
- `onEmailPushEvent(handler)` — raw global bus subscription (use when you need the full `EmailPushEvent` payload, not just the synthesised `ReolinkSimpleEvent`)
|
|
60
92
|
- `getRecentEmailPushEvents(limit)` — bounded in-memory ring buffer of accepted deliveries
|
|
61
93
|
- `setupEmailPushToManager(params, channel)` — orchestrator: `setEmail` + `setEmailTask` + optional `testEmail`
|
|
62
94
|
- `getEmail`, `setEmail`, `testEmail`, `getEmailTask`, `setEmailTask` — low-level Baichuan accessors
|
|
@@ -11818,6 +11818,21 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
11818
11818
|
// check every 10s
|
|
11819
11819
|
simpleEventWatchdogSilenceThresholdMs = 5 * 6e4;
|
|
11820
11820
|
// 5 min without events
|
|
11821
|
+
/**
|
|
11822
|
+
* Whether the silence-based resubscribe path of the watchdog is
|
|
11823
|
+
* enabled. On UDP (battery cameras) silence is the *normal* state
|
|
11824
|
+
* while the device sleeps — firing `ensureSimpleEventSubscribed`
|
|
11825
|
+
* every 5 minutes wakes the camera on every tick, drains the
|
|
11826
|
+
* battery, and is observably wrong because the cam emits a
|
|
11827
|
+
* sleep/awake push when it actually wakes for motion.
|
|
11828
|
+
*
|
|
11829
|
+
* Defaults: `false` on UDP, `true` on TCP / `auto`. The subscription-
|
|
11830
|
+
* failed recovery path (Case 2) stays active regardless — it only
|
|
11831
|
+
* runs when the connection is alive, doesn't wake anyone, and is
|
|
11832
|
+
* useful on every transport when the initial subscribe call lost
|
|
11833
|
+
* the response packet.
|
|
11834
|
+
*/
|
|
11835
|
+
eventWatchdogSilenceResubscribeEnabled = true;
|
|
11821
11836
|
statePollingInterval;
|
|
11822
11837
|
udpSleepInferenceInterval;
|
|
11823
11838
|
udpLastInferredSleepStateByChannel = /* @__PURE__ */ new Map();
|
|
@@ -12775,6 +12790,12 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
12775
12790
|
} else {
|
|
12776
12791
|
this.eventResubscribeEnabled = opts.transport !== "udp";
|
|
12777
12792
|
}
|
|
12793
|
+
const explicitWatchdogResubscribe = opts.enableEventWatchdogSilenceResubscribe;
|
|
12794
|
+
if (typeof explicitWatchdogResubscribe === "boolean") {
|
|
12795
|
+
this.eventWatchdogSilenceResubscribeEnabled = explicitWatchdogResubscribe;
|
|
12796
|
+
} else {
|
|
12797
|
+
this.eventWatchdogSilenceResubscribeEnabled = opts.transport !== "udp";
|
|
12798
|
+
}
|
|
12778
12799
|
const maxSessions = opts.maxDedicatedSessionsBeforeReboot;
|
|
12779
12800
|
if (typeof maxSessions === "number" && Number.isFinite(maxSessions) && maxSessions > 0) {
|
|
12780
12801
|
this.maxDedicatedSessionsBeforeReboot = Math.floor(maxSessions);
|
|
@@ -13597,6 +13618,14 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
13597
13618
|
if (this.simpleEventSubscribed && this.simpleEventLastReceivedAt > 0) {
|
|
13598
13619
|
const silence = now - this.simpleEventLastReceivedAt;
|
|
13599
13620
|
if (silence < this.simpleEventWatchdogSilenceThresholdMs) return;
|
|
13621
|
+
if (!this.eventWatchdogSilenceResubscribeEnabled) {
|
|
13622
|
+
this.logger.debug?.(
|
|
13623
|
+
`[ReolinkBaichuanApi] event watchdog: silence-based resubscribe disabled (UDP / battery), skipping`,
|
|
13624
|
+
{ host: this.host, silenceMs: silence }
|
|
13625
|
+
);
|
|
13626
|
+
this.simpleEventLastReceivedAt = now;
|
|
13627
|
+
return;
|
|
13628
|
+
}
|
|
13600
13629
|
(this.logger.warn ?? this.logger.log).call(
|
|
13601
13630
|
this.logger,
|
|
13602
13631
|
`[ReolinkBaichuanApi] event watchdog: no events for ${Math.round(silence / 6e4)} min, forcing resubscribe`,
|
|
@@ -24753,4 +24782,4 @@ export {
|
|
|
24753
24782
|
isTcpFailureThatShouldFallbackToUdp,
|
|
24754
24783
|
autoDetectDeviceType
|
|
24755
24784
|
};
|
|
24756
|
-
//# sourceMappingURL=chunk-
|
|
24785
|
+
//# sourceMappingURL=chunk-OZL6C2YJ.js.map
|