@mega-yfue/eufy-sdk 0.4.0-beta.16 → 0.4.0-beta.18

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.
@@ -164,7 +164,7 @@ export declare function parseQuickResponses(voiceList: Array<{
164
164
  }>): QuickResponse[];
165
165
  /**
166
166
  * `doorbell` — chime / ringtone configuration. CONFIRMED against a real Video Doorbell (T8214):
167
- * the live ids are the `1702-1719` `CMD_BAT_DOORBELL_*` range (provenance "mega", observed). The
167
+ * the live ids are the `1702-1719` `CMD_BAT_DOORBELL_*` range, observed on that device. The
168
168
  * legacy `2015/2022/1306` ids are excluded — they appear on NO owned device. The button-
169
169
  * press *event* (ring) is delivered out-of-band via `CMD_DOORBELL_NOTIFY_PAYLOAD` (1701) /
170
170
  * push/MQTT — it is handled by the Phase-1 event normalizers, not as a device-list param.
@@ -185,9 +185,9 @@ export declare function parseQuickResponses(voiceList: Array<{
185
185
  export declare const DOORBELL_MEMBERS: {
186
186
  /**
187
187
  * The HOMEBASE as the doorbell's chime — the hub plays the ring, not the wired chime box
188
- * `mechanicalChimeSwitch` drives. `provenance` is "verified" on our own decrypt of the app's frame,
189
- * not merely the param id observed live: direct-binary `[ch][value][acct]`, 1=on/0=off, the same shape
190
- * as its 1703 sibling — captured, not inferred from the shared param range.
188
+ * `mechanicalChimeSwitch` drives. `provenance` is "verified" on our own decrypt of the app's frame:
189
+ * direct-binary `[ch][value][acct]`, 1=on/0=off, the same shape as its 1703 sibling — captured, not
190
+ * inferred from the shared param range.
191
191
  */
192
192
  readonly chimeSwitch: {
193
193
  readonly param: 1702;
@@ -198,9 +198,8 @@ export declare const DOORBELL_MEMBERS: {
198
198
  readonly write: (v: string | number | boolean, ctx: import("./types.js").CommandContext) => import("../../core/contracts.js").Command;
199
199
  };
200
200
  /**
201
- * `provenance` is "verified" not "mega": the actual write wire is confirmed (
202
- * our own P2P decrypt), not merely the param id observed on a live device. Direct-binary
203
- * `[ch][value][acct]`, 1=on/0=off — verified live on a T8214 (ON then OFF).
201
+ * `provenance` is "verified" on our own P2P decrypt of the write wire: direct-binary
202
+ * `[ch][value][acct]`, 1=on/0=off, verified live on a T8214 (ON then OFF).
204
203
  */
205
204
  readonly mechanicalChimeSwitch: {
206
205
  readonly param: 1703;
@@ -231,7 +230,7 @@ export declare const DOORBELL_MEMBERS: {
231
230
  readonly type: "number";
232
231
  readonly unit: "%";
233
232
  readonly kind: "percent";
234
- readonly provenance: "mega";
233
+ readonly provenance: "verified";
235
234
  readonly writtenElsewhere: true;
236
235
  readonly description: string;
237
236
  };
@@ -325,7 +324,7 @@ export declare const DOORBELL_MEMBERS: {
325
324
  readonly param: 1710;
326
325
  readonly type: "string";
327
326
  readonly kind: "text";
328
- readonly provenance: "mega";
327
+ readonly provenance: "verified";
329
328
  readonly description: string;
330
329
  };
331
330
  /**
@@ -98,7 +98,6 @@ export declare const MOTION_CMD: {
98
98
  * payload key AND pass mChannel 0 explicitly; the two are separate choices, not linked.)
99
99
  *
100
100
  * ⚠️ Replay + readback confirmed on a HomeBase-attached T8425 (1719 `0`→`1`→`0`), NOT byte-captured.
101
- * Provenance is `apk`, not `verified`: a divergent-but-also-accepted frame can't be ruled out.
102
101
  */
103
102
  readonly HUMAN_ONLY_AT_NIGHT: 1719;
104
103
  /**
@@ -112,7 +111,7 @@ export declare const MOTION_CMD: {
112
111
  * form, so a feature that is on reads as off.
113
112
  * Decoded by {@link decodeRadarWdSwitch} to match the app.
114
113
  *
115
- * ⚠️ Replay + readback confirmed on a T8214 (2706 `0`→`1`→`0`), NOT byte-captured. Provenance `apk`.
114
+ * ⚠️ Replay + readback confirmed on a T8214 (2706 `0`→`1`→`0`), NOT byte-captured.
116
115
  */
117
116
  readonly LOITERING_DETECTION: 2706;
118
117
  /**
@@ -354,7 +353,7 @@ export declare const MOTION_MEMBERS: {
354
353
  readonly param: 1719;
355
354
  readonly type: "bool";
356
355
  readonly kind: "boolean";
357
- readonly provenance: "apk";
356
+ readonly provenance: "verified";
358
357
  readonly description: string;
359
358
  readonly requires: readonly [1719];
360
359
  readonly write: (v: string | number | boolean, ctx: CommandContext) => Command;
@@ -367,7 +366,7 @@ export declare const MOTION_MEMBERS: {
367
366
  readonly param: 2706;
368
367
  readonly type: "bool";
369
368
  readonly kind: "boolean";
370
- readonly provenance: "apk";
369
+ readonly provenance: "verified";
371
370
  readonly coerce: (raw: string | number | boolean) => boolean;
372
371
  readonly description: string;
373
372
  readonly requires: readonly [2706];
@@ -5,10 +5,10 @@
5
5
  * Two namespaces (params are per-transport, NOT globally unique):
6
6
  * - SECURITY_PARAMS — eufy P2P param space (ids 1000+). **Membership is the observation**: an id is
7
7
  * listed only because the sweep saw it on a real owned device, so the id is real/accepted.
8
- * `provenance` is the trust of the NAME/meaning: "verified" (our captures) > "apk" (the app's own
9
- * decompiled constant name) > "guessed" (no name source — needs toggle-diff).
8
+ * `provenance` is the trust of the NAME/meaning; the tiers are defined on `PropertySource` in
9
+ * `types.ts`.
10
10
  * - CLEAN_PARAMS — RoboVac Tuya DP space (ids 1 and above), names from the cloud
11
- * `get_product_data_point` data_point_list (provenance "mega" — authoritative).
11
+ * `get_product_data_point` data_point_list, hence provenance `mega`.
12
12
  *
13
13
  * Which models reported an id, and the capture that named it, are in the commit that adds the entry.
14
14
  */
@@ -104,18 +104,17 @@ export type ValueKind = KnownValueKind | (string & {});
104
104
  */
105
105
  export declare function isKnownValueKind(kind: ValueKind): kind is KnownValueKind;
106
106
  /**
107
- * Trust provenance of a property's `param_type` mapping, most-trusted first:
108
- * - `mega` — confirmed against the live mega API / a real device's reported params.
109
- * - `apk` — extracted from the v6 app itself (the ids the app actually sends — authoritative).
110
- * - `verified` — confirmed by our own capture/observation.
111
- * - `guessed` — a plausible placeholder; lowest trust.
107
+ * How much a param's name and meaning can be trusted, most-trusted first. This is the one definition;
108
+ * the param dictionary and every `provenance` field use it.
109
+ * - `mega` — the vendor's cloud names it: its data-point catalog (`get_product_data_point`), or a
110
+ * reported value that matches what the cloud record already says (a model name or code).
111
+ * - `verified` — confirmed on a real device by this project: our own capture or observation, or
112
+ * identified by someone who has the hardware.
113
+ * - `apk` — the v6 app's own decompiled constant name, not yet confirmed on a device.
114
+ * - `guessed` — no name source; a plausible placeholder until a toggle-diff settles it.
112
115
  *
113
- * This project never relies on a third-party reverse-engineering project as a source of trust —
114
- * every id/behavior we ship is grounded in the app's
115
- * own decompiled code (`apk`) or our own capture/observation (`verified`), never someone else's
116
- * unverified guess. Absent provenance is treated as `guessed`.
117
- *
118
- * Provenance of a property definition — an internal trust label used when curating the model.
116
+ * A third-party reverse-engineering project is never a source: every name we ship comes from the
117
+ * vendor's cloud, our own observation or the app itself. Absent provenance is treated as `guessed`.
119
118
  * @internal
120
119
  */
121
120
  export type PropertySource = "mega" | "apk" | "verified" | "guessed";
@@ -566,6 +566,10 @@ export declare class P2PSession extends EventEmitter {
566
566
  * The HomeBase streams back `CMD_DATABASE` (1306) frames `{cmd:10000,count,data:[…]}`,
567
567
  * level-1-encrypted — decoded and emitted as `dbChunk` (decrypted text) per frame.
568
568
  * Tables: `familiar_faces`, `person_basic_info`, `event_person_list`, `history_record_info`.
569
+ *
570
+ * Throws while a {@link readDatabase} is accumulating: every table answers `{data:[…]}` and the
571
+ * frames tie no chunk to its request, so a second query's reply would be assembled into the first
572
+ * one's buffer and answered as its rows.
569
573
  */
570
574
  queryDatabase(table: string, opts?: {
571
575
  accountId?: string;
@@ -593,6 +597,25 @@ export declare class P2PSession extends EventEmitter {
593
597
  accountId?: string;
594
598
  channel?: number;
595
599
  }): void;
600
+ /**
601
+ * Query one on-station table and answer its rows, once the reply is whole.
602
+ *
603
+ * The request half of {@link queryDatabase} with its reply assembled: `CMD_DATABASE` arrives as
604
+ * several frames whose decrypted text is a fragment of one document, so the fragments are
605
+ * accumulated here and scanned after each one. Answers that document's `data` rows. Rejects when
606
+ * `signal` aborts, and when `timeoutMs` (default {@link DB_TABLE_TIMEOUT_MS}) elapses with no
607
+ * complete reply.
608
+ *
609
+ * One read at a time per session: while one is accumulating, every {@link queryDatabase} on the
610
+ * session throws, so a second reply cannot land in this buffer.
611
+ */
612
+ readDatabase(table: string, opts?: {
613
+ accountId?: string;
614
+ timeoutMs?: number;
615
+ signal?: AbortSignal;
616
+ }): Promise<unknown[]>;
617
+ /** Whether a {@link readDatabase} is accumulating; see {@link queryDatabase} for what it bars. */
618
+ private dbReadInFlight;
596
619
  /**
597
620
  * Request the **face feature rows** over P2P (`face_feature_info`, inner `cmd 10000`). Each row
598
621
  * carries `{person_id, face_name, face_id, face_picture_content, face_feature_file_path}` — where
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mega-yfue/eufy-sdk",
3
- "version": "0.4.0-beta.16",
3
+ "version": "0.4.0-beta.18",
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",