@mega-yfue/eufy-sdk 0.5.0-beta.72 → 0.5.0-beta.74

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.
@@ -182,6 +182,11 @@ export interface AiDetectFlags {
182
182
  export declare function encodeAiDetectType(flags: AiDetectFlags): number;
183
183
  /** Decode an `ai_detect_type` bitmask → which detection types are on. */
184
184
  export declare function decodeAiDetectType(value: number): AiDetectFlags;
185
+ /**
186
+ * The `ai_detect_type` bitmask from a stored 1298 value: the bare number, or the numeric
187
+ * `ai_detect_type` field of the JSON object form. Answers `undefined` for any other shape.
188
+ */
189
+ declare function decodeAiDetectTypeParam(raw: unknown): number | undefined;
185
190
  /**
186
191
  * Decode a `radar_wd_switch` (2706, loitering) read the way the app does:
187
192
  * `typeof v === "object" ? v.radar_wd_switch : v`. The device may store it as a JSON object
@@ -245,11 +250,15 @@ export declare const MOTION_MEMBERS: {
245
250
  * 1298 holds the detailed AI-type BITMASK (live-observed: `0x30000` enabled-base | type bits, e.g. a
246
251
  * T8425 reads `0x3000f`). Cams also report 1299 (`hbAiDetectType`) but that is a separate, simpler
247
252
  * value (1) — NOT this bitmask, so 1298 is the read/write id.
253
+ *
254
+ * The value arrives in two shapes, both read by the app's 1298 parser: a bare bitmask, or a JSON
255
+ * object carrying the same bitmask as `ai_detect_type` (see {@link decodeAiDetectTypeParam}).
248
256
  */
249
257
  readonly aiDetectType: {
250
258
  readonly param: 1298;
251
- readonly type: "number";
252
- readonly kind: "bitfield";
259
+ readonly type: "string";
260
+ readonly decode: typeof decodeAiDetectTypeParam;
261
+ readonly decodedKind: "bitfield";
253
262
  readonly provenance: "verified";
254
263
  readonly description: string;
255
264
  readonly write: (v: string | number | boolean, ctx: CommandContext) => Command | undefined;
@@ -379,3 +388,4 @@ export declare const MOTION_MEMBERS: {
379
388
  };
380
389
  };
381
390
  export declare const MOTION: CapabilityModule;
391
+ export {};
@@ -47,6 +47,8 @@ export declare const isHomeBase: (ctx: FamilyContext) => boolean;
47
47
  export declare const isStation9000: (ctx: FamilyContext) => boolean;
48
48
  /** T8N00 NVR, identified by its reported model. */
49
49
  export declare const isNvrT8N00: (ctx: FamilyContext) => boolean;
50
+ /** PoE cameras whose media is served by their NVR's portal call. */
51
+ export declare const isNvrMediaCamera: (ctx: FamilyContext) => boolean;
50
52
  /** Video Doorbell C31 (T8223), identified by its reported model. */
51
53
  export declare const isDoorbellT8223: (ctx: FamilyContext) => boolean;
52
54
  /** Wired doorbell (DeviceType.DOORBELL). */
@@ -0,0 +1,14 @@
1
+ import type { AudioCodec } from "../../core/contracts.js";
2
+ export declare const CMD_AUDIO_FRAME = 1301;
3
+ /** Length of the audio frame header before the payload. */
4
+ export declare const AUDIO_HEADER_LEN = 16;
5
+ /** Byte offset of the codec id between the frame-size and frame-number fields. */
6
+ export declare const AUDIO_TYPE_OFFSET = 5;
7
+ /**
8
+ * Codec ids the station puts at {@link AUDIO_TYPE_OFFSET}, as the v6 app maps them
9
+ * (`AudioReader.AAC_LC = 0`, `G711A = 2`, `AAC_ELD = 7`).
10
+ *
11
+ * The app's `PCM_SILENCE = -1` is absent on purpose: it is not a wire value. The app injects it
12
+ * itself when a stream produces no audio at all, to feed its decoder silence.
13
+ */
14
+ export declare const AUDIO_CODECS: Readonly<Record<number, AudioCodec>>;
@@ -85,6 +85,10 @@ export declare class RtcCommandRouter {
85
85
  * session. Recording has no wire here and is refused.
86
86
  */
87
87
  trackMediaProviderFor(route: RtcRoute): MediaProvider;
88
+ /** NVR media uses a dedicated call per camera, independent of station commands. */
89
+ nvrMediaProviderFor(route: RtcLiveRoute): MediaProvider;
90
+ /** Share a dedicated-call source and its consumer operations under one route key. */
91
+ private callMediaProviderFor;
88
92
  /**
89
93
  * Tear down every station session (logout / shutdown). Each live source is disposed before its session
90
94
  * closes, so its consumers end cleanly and its stop still rides the session.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The live pull of one camera behind a **HomeBase S1 Pro (T9000)**, over the station's control session.
2
+ * A portal camera live pull: T9000 shares its control session, NVR media owns a dedicated call.
3
3
  *
4
4
  * Wire, as the portal sends it on the command data channel:
5
5
  *
@@ -12,8 +12,8 @@
12
12
  * - A raw, unframed keepalive (a 20-byte prefix and a bare `XZYH 1139`) goes out every ~29 s; the hub
13
13
  * echoes it.
14
14
  *
15
- * The station serves one live view at a time on that play slot, so the router builds at most one pull per
16
- * station. This is a {@link LiveStreamHandle}: fan-out, backpressure and the start deadline are the
15
+ * A session serves one live view on that play slot. This is a {@link LiveStreamHandle}:
16
+ * fan-out, backpressure and the start deadline are the
17
17
  * shared live source's.
18
18
  */
19
19
  import { EventEmitter } from "node:events";
@@ -42,15 +42,19 @@ export interface RtcLiveOptions {
42
42
  /** The station's `member.admin_user_id`. */
43
43
  accountId: string;
44
44
  logger?: Logger;
45
+ /** NVR media owns and connects its session; uses the portal default sensor. */
46
+ nvr?: boolean;
45
47
  }
46
48
  /**
47
49
  * One camera's live pull. `start()` sends the start; a non-zero start ACK or a closed session ends it with
48
- * `error`, and `stop()` sends the stop. Frames are `h265` Annex B, keyframes being IDRs.
50
+ * `error`, and `stop()` sends the stop. Video is H.265 Annex B, keyframes being IDRs.
49
51
  */
50
52
  export declare class RtcLiveStream extends EventEmitter implements LiveStreamHandle {
51
53
  private readonly opts;
52
54
  private running;
53
55
  private startSegment;
56
+ private readonly onConnected;
57
+ private readonly onError;
54
58
  private keepalive?;
55
59
  private width;
56
60
  private height;
@@ -60,6 +64,7 @@ export declare class RtcLiveStream extends EventEmitter implements LiveStreamHan
60
64
  constructor(opts: RtcLiveOptions);
61
65
  private get tag();
62
66
  start(): this;
67
+ private sendStart;
63
68
  stop(): void;
64
69
  private teardown;
65
70
  private fail;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mega-yfue/eufy-sdk",
3
- "version": "0.5.0-beta.72",
3
+ "version": "0.5.0-beta.74",
4
4
  "description": "One typed TypeScript client for the Anker eufy v6 cloud — capability-driven devices, realtime events over P2P/MQTT/push, and live media",
5
5
  "license": "Apache-2.0",
6
6
  "author": "mega-yfue",