@mega-yfue/eufy-sdk 0.0.4 → 0.1.0-beta.0
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 +31 -12
- package/dist/client/device-registry.d.ts +343 -0
- package/dist/client/eufy-mega.d.ts +872 -0
- package/dist/client/index.d.ts +1 -6
- package/dist/client/map-channels.d.ts +22 -0
- package/dist/client/types.d.ts +383 -0
- package/dist/core/contracts.d.ts +898 -0
- package/dist/core/crypto.d.ts +98 -0
- package/dist/core/index.d.ts +9 -7
- package/dist/core/logger.d.ts +53 -0
- package/dist/core/lz4-block.d.ts +35 -0
- package/dist/core/raw-dp-hex.d.ts +32 -0
- package/dist/core/raw-dp-writer.d.ts +83 -0
- package/dist/core/store.d.ts +43 -0
- package/dist/core/types.d.ts +169 -0
- package/dist/core/util.d.ts +78 -0
- package/dist/index.d.ts +4 -7
- package/dist/index.js +25526 -14
- package/dist/index.js.map +7 -1
- package/dist/model/capabilities/access.d.ts +127 -0
- package/dist/model/capabilities/arming.d.ts +201 -0
- package/dist/model/capabilities/audio.d.ts +154 -0
- package/dist/model/capabilities/battery.d.ts +363 -0
- package/dist/model/capabilities/camera.d.ts +564 -0
- package/dist/model/capabilities/co.d.ts +40 -0
- package/dist/model/capabilities/contact.d.ts +133 -0
- package/dist/model/capabilities/doorbell.d.ts +345 -0
- package/dist/model/capabilities/dp-catalog.d.ts +38 -0
- package/dist/model/capabilities/index.d.ts +561 -0
- package/dist/model/capabilities/info.d.ts +28 -0
- package/dist/model/capabilities/keypad.d.ts +61 -0
- package/dist/model/capabilities/leak.d.ts +43 -0
- package/dist/model/capabilities/light.d.ts +174 -0
- package/dist/model/capabilities/locate.d.ts +63 -0
- package/dist/model/capabilities/lock.d.ts +242 -0
- package/dist/model/capabilities/manifest.d.ts +107 -0
- package/dist/model/capabilities/members.d.ts +647 -0
- package/dist/model/capabilities/motion.d.ts +377 -0
- package/dist/model/capabilities/person-detection.d.ts +8 -0
- package/dist/model/capabilities/ptz.d.ts +289 -0
- package/dist/model/capabilities/rtsp.d.ts +221 -0
- package/dist/model/capabilities/siren.d.ts +218 -0
- package/dist/model/capabilities/smart-light.d.ts +172 -0
- package/dist/model/capabilities/smoke.d.ts +40 -0
- package/dist/model/capabilities/snapshot.d.ts +6 -0
- package/dist/model/capabilities/storage.d.ts +11 -0
- package/dist/model/capabilities/suction.d.ts +104 -0
- package/dist/model/capabilities/types.d.ts +484 -0
- package/dist/model/capabilities/vacuum-clean.d.ts +1946 -0
- package/dist/model/capabilities/vacuum-dock.d.ts +208 -0
- package/dist/model/capabilities/video.d.ts +6 -0
- package/dist/model/classify.d.ts +78 -0
- package/dist/model/clean-record-detail.d.ts +65 -0
- package/dist/model/clean-records.d.ts +69 -0
- package/dist/model/device-family.d.ts +73 -0
- package/dist/model/device-types.d.ts +123 -0
- package/dist/model/device.d.ts +265 -0
- package/dist/model/index.d.ts +29 -4
- package/dist/model/infer.d.ts +23 -0
- package/dist/model/inspect.d.ts +61 -0
- package/dist/model/life-params.d.ts +21 -0
- package/dist/model/map-pixels.d.ts +70 -0
- package/dist/model/param-dictionary.d.ts +28 -0
- package/dist/model/param-namespace.d.ts +21 -0
- package/dist/model/proto-read.d.ts +53 -0
- package/dist/model/push-events.d.ts +147 -0
- package/dist/model/registry.d.ts +54 -0
- package/dist/model/types.d.ts +301 -0
- package/dist/model/vacuum-map-store.d.ts +92 -0
- package/dist/model/vacuum-map.d.ts +286 -0
- package/dist/model/vacuum-scenes.d.ts +76 -0
- package/dist/model/vacuum-schedules.d.ts +85 -0
- package/dist/transport/dp-preset.d.ts +102 -0
- package/dist/transport/ff09.d.ts +444 -0
- package/dist/transport/ffmpeg.d.ts +86 -0
- package/dist/transport/http/decodeImageV1.d.ts +20 -0
- package/dist/transport/http/decodeImageV2.d.ts +19 -0
- package/dist/transport/http/index.d.ts +5 -0
- package/dist/transport/http/light-catalog.d.ts +62 -0
- package/dist/transport/http/media-download.d.ts +14 -0
- package/dist/transport/http/mega-client.d.ts +514 -0
- package/dist/transport/http/phone-model.d.ts +21 -0
- package/dist/transport/index.d.ts +10 -7
- package/dist/transport/mqtt/app-client-id.d.ts +16 -0
- package/dist/transport/mqtt/availability.d.ts +14 -0
- package/dist/transport/mqtt/bare-ip-tls.d.ts +46 -0
- package/dist/transport/mqtt/biz-stream.d.ts +98 -0
- package/dist/transport/mqtt/broker-discovery.d.ts +55 -0
- package/dist/transport/mqtt/clean-codec.d.ts +14 -0
- package/dist/transport/mqtt/command-router.d.ts +285 -0
- package/dist/transport/mqtt/dp-codec.d.ts +58 -0
- package/dist/transport/mqtt/dp-color.d.ts +14 -0
- package/dist/transport/mqtt/engine.d.ts +16 -0
- package/dist/transport/mqtt/index.d.ts +5 -0
- package/dist/transport/mqtt/secure-mqtt.d.ts +107 -0
- package/dist/transport/mqtt/topics.d.ts +80 -0
- package/dist/transport/p2p/adts.d.ts +91 -0
- package/dist/transport/p2p/annexb.d.ts +124 -0
- package/dist/transport/p2p/codec.d.ts +166 -0
- package/dist/transport/p2p/command-router.d.ts +655 -0
- package/dist/transport/p2p/commands.d.ts +550 -0
- package/dist/transport/p2p/envelope.d.ts +46 -0
- package/dist/transport/p2p/fmp4.d.ts +89 -0
- package/dist/transport/p2p/fragment-recording.d.ts +33 -0
- package/dist/transport/p2p/index.d.ts +13 -0
- package/dist/transport/p2p/lan-ip.d.ts +25 -0
- package/dist/transport/p2p/live-stream.d.ts +223 -0
- package/dist/transport/p2p/live-trace.d.ts +123 -0
- package/dist/transport/p2p/media.d.ts +105 -0
- package/dist/transport/p2p/p2p-session.d.ts +620 -0
- package/dist/transport/p2p/readable-egress.d.ts +27 -0
- package/dist/transport/p2p/session-manager.d.ts +154 -0
- package/dist/transport/p2p/shared-live-source.d.ts +431 -0
- package/dist/transport/p2p/talkback.d.ts +187 -0
- package/dist/transport/p2p/video.d.ts +150 -0
- package/dist/transport/p2p/write-commands.d.ts +21 -0
- package/dist/transport/protobuf.d.ts +5 -0
- package/dist/transport/push/fcm.d.ts +23 -0
- package/dist/transport/push/index.d.ts +6 -0
- package/dist/transport/push/message-tags.d.ts +26 -0
- package/dist/transport/push/parser.d.ts +27 -0
- package/dist/transport/push/proto.d.ts +11 -0
- package/dist/transport/push/push-client.d.ts +64 -0
- package/dist/transport/push/store.d.ts +23 -0
- package/dist/transport/push/types.d.ts +180 -0
- package/dist/transport/raw-dp.d.ts +6 -0
- package/dist/transport/stored-image-cache.d.ts +23 -0
- package/dist/transport/tuya/account.d.ts +44 -0
- package/dist/transport/tuya/client.d.ts +89 -0
- package/dist/transport/tuya/command-router.d.ts +79 -0
- package/dist/transport/tuya/dp-codec.d.ts +56 -0
- package/dist/transport/tuya/index.d.ts +28 -0
- package/dist/transport/tuya/request.d.ts +157 -0
- package/dist/transport/tuya/sign.d.ts +64 -0
- package/package.json +12 -13
- package/dist/client/index.js +0 -2
- package/dist/client/index.js.map +0 -1
- package/dist/core/index.js +0 -2
- package/dist/core/index.js.map +0 -1
- package/dist/model/index.js +0 -2
- package/dist/model/index.js.map +0 -1
- package/dist/transport/index.js +0 -2
- package/dist/transport/index.js.map +0 -1
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { type Surface } from "./members.js";
|
|
2
|
+
import type { CapabilityModule } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* The entry sensor's own **command/param ids** — its built-in alarm buzzer (sounds when the door
|
|
5
|
+
* opens while armed), separate from the open/close contact read. Both write wires were captured live
|
|
6
|
+
* on a T90E0 (2026-08-03).
|
|
7
|
+
*/
|
|
8
|
+
export declare const CONTACT_CMD: {
|
|
9
|
+
/** Alarm sound/tone selection (app `APP_CMD_ALARM_SOUND_TYPE`). See {@link EntryAlarmTone}. */
|
|
10
|
+
readonly ALARM_SOUND_TYPE: 1507;
|
|
11
|
+
/** Alarm volume (app `APP_CMD_ALARM_VOLUME_VALUE`). A device level 1-26, not a percentage. */
|
|
12
|
+
readonly ALARM_VOLUME: 1508;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* The entry sensor's built-in alarm tone: silent, or one of four chimes. Pass a value to
|
|
16
|
+
* `setAlarmSoundType`.
|
|
17
|
+
*/
|
|
18
|
+
export declare const EntryAlarmTone: {
|
|
19
|
+
/** Silent — no alarm tone. */
|
|
20
|
+
readonly None: 0;
|
|
21
|
+
readonly Water: 1;
|
|
22
|
+
readonly Classic: 2;
|
|
23
|
+
readonly Light: 3;
|
|
24
|
+
readonly Ding: 4;
|
|
25
|
+
};
|
|
26
|
+
/** An entry-sensor alarm tone — the value side of {@link EntryAlarmTone}. */
|
|
27
|
+
export type EntryAlarmToneValue = (typeof EntryAlarmTone)[keyof typeof EntryAlarmTone];
|
|
28
|
+
/**
|
|
29
|
+
* Bound entry-sensor controls — the object returned by `dev.contact()`.
|
|
30
|
+
*
|
|
31
|
+
* Everything is DERIVED from `CONTACT_MEMBERS`. The open/close read is the headline; the entry
|
|
32
|
+
* sensor also carries a built-in alarm buzzer whose tone and volume are writable, each setter present
|
|
33
|
+
* only when the device reports the backing param.
|
|
34
|
+
*/
|
|
35
|
+
export type ContactActions = Surface<typeof CONTACT_MEMBERS>;
|
|
36
|
+
/**
|
|
37
|
+
* Every `contact` feature, declared once. `contact` (1550) and `lastSeen` (1551) are verified reads;
|
|
38
|
+
* the built-in alarm tone (1507) and volume (1508) are verified writes captured live on a T90E0.
|
|
39
|
+
*
|
|
40
|
+
* Exported but NOT published: each entry states its wire id and the evidence it was confirmed on,
|
|
41
|
+
* which the reference site does not carry.
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
export declare const CONTACT_MEMBERS: {
|
|
45
|
+
/**
|
|
46
|
+
* The headline read: `true` when the door or window is open. Polarity is the V6 app's own
|
|
47
|
+
* `"1".equals(e)` — see `contactOpen`, which normalises every inbound source through one
|
|
48
|
+
* predicate so the poll, the push and the station notify cannot disagree about what open means.
|
|
49
|
+
* Reporting 1550 is also this capability's detection evidence, so a device with this getter is
|
|
50
|
+
* confirmed to be a contact sensor.
|
|
51
|
+
*/
|
|
52
|
+
readonly open: {
|
|
53
|
+
readonly param: 1550;
|
|
54
|
+
readonly property: "contact";
|
|
55
|
+
readonly type: "bool";
|
|
56
|
+
readonly kind: "boolean";
|
|
57
|
+
readonly provenance: "verified";
|
|
58
|
+
readonly description: "Contact state, true=open (verified: param 1550 entry-sensor contact).";
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Unix seconds at which the sensor last checked in — the liveness read beside the contact state, and
|
|
62
|
+
* the way to tell a genuinely closed door from a sensor that stopped reporting. A `timestamp` kind
|
|
63
|
+
* takes no `unit`: it is an instant, not a duration.
|
|
64
|
+
*/
|
|
65
|
+
readonly lastSeen: {
|
|
66
|
+
readonly param: 1551;
|
|
67
|
+
readonly type: "number";
|
|
68
|
+
readonly kind: "timestamp";
|
|
69
|
+
readonly provenance: "verified";
|
|
70
|
+
readonly description: "Last-seen unix timestamp, seconds (verified: param 1551).";
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Link quality to whichever radio the sensor is paired over, in dBm as the device measures it. The
|
|
74
|
+
* same param 1141 the other sub-1G sensors report on, so the number is comparable across them —
|
|
75
|
+
* unlike a bars mapping, which this SDK never applies.
|
|
76
|
+
*/
|
|
77
|
+
readonly rssi: {
|
|
78
|
+
readonly param: 1141;
|
|
79
|
+
readonly type: "number";
|
|
80
|
+
readonly unit: "dBm";
|
|
81
|
+
readonly kind: "dbm";
|
|
82
|
+
readonly provenance: "verified";
|
|
83
|
+
readonly description: "Sub-1G/Wi-Fi signal strength (verified: param 1141 = RSSI).";
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Rejected, not clamped, outside the tone enum: a fire-and-forget write of a bogus tone would look like
|
|
87
|
+
* it worked. The wire is a direct-binary scalar `[ch][value][acct]` at signCode 8 — the app's own
|
|
88
|
+
* captured frame.
|
|
89
|
+
*/
|
|
90
|
+
readonly alarmSoundType: {
|
|
91
|
+
readonly param: 1507;
|
|
92
|
+
readonly type: "enum";
|
|
93
|
+
readonly kind: "enum";
|
|
94
|
+
readonly enumValues: Record<number, string>;
|
|
95
|
+
readonly provenance: "verified";
|
|
96
|
+
readonly requires: readonly [1507];
|
|
97
|
+
readonly args: readonly [{
|
|
98
|
+
readonly name: "tone";
|
|
99
|
+
readonly kind: "enum";
|
|
100
|
+
readonly description: "Silent (0) or one of the four chimes.";
|
|
101
|
+
}];
|
|
102
|
+
readonly description: string;
|
|
103
|
+
readonly write: (v: string | number | boolean, ctx: import("./types.js").CommandContext) => import("../../index.js").Command | undefined;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* `1350` SET_PAYLOAD, `mChannel` = the device channel, `mValue3` 0, payload carrying the channel and a
|
|
107
|
+
* transaction stamp — the byte-shape of the app's own captured frame. Out of range is refused rather
|
|
108
|
+
* than clamped: the app's slider has no values outside it, so one is a caller error, not a nudge.
|
|
109
|
+
*/
|
|
110
|
+
readonly alarmVolume: {
|
|
111
|
+
readonly param: 1508;
|
|
112
|
+
readonly type: "number";
|
|
113
|
+
readonly kind: "scalar";
|
|
114
|
+
readonly provenance: "verified";
|
|
115
|
+
readonly requires: readonly [1508];
|
|
116
|
+
readonly min: 1;
|
|
117
|
+
readonly max: 26;
|
|
118
|
+
readonly args: readonly [{
|
|
119
|
+
readonly name: "level";
|
|
120
|
+
readonly kind: "scalar";
|
|
121
|
+
readonly min: 1;
|
|
122
|
+
readonly max: 26;
|
|
123
|
+
readonly description: "A device level, not a percentage.";
|
|
124
|
+
}];
|
|
125
|
+
readonly description: string;
|
|
126
|
+
readonly write: (v: string | number | boolean, ctx: import("./types.js").CommandContext) => import("../../index.js").Command | undefined;
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* `contact` — entry/door-window sensor. `contact` (1550) and `lastSeen` (1551) are verified; the
|
|
131
|
+
* built-in alarm tone (1507) and volume (1508) are verified writes captured live on a T90E0.
|
|
132
|
+
*/
|
|
133
|
+
export declare const CONTACT: CapabilityModule;
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { type Surface } from "./members.js";
|
|
2
|
+
import type { CapabilityModule } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* The P2P **feature-command ids** this doorbell capability drives. Capability-owned wire vocabulary
|
|
5
|
+
* (transport forwards `cmd.param` opaquely; full id→name catalog in the generated
|
|
6
|
+
* `transport/p2p/commands.ts`).
|
|
7
|
+
*/
|
|
8
|
+
export declare const DOORBELL_CMD: {
|
|
9
|
+
/**
|
|
10
|
+
* Doorbell "quick response" — make the doorbell PLAY a stored voice reply. Same 136-byte
|
|
11
|
+
* direct-binary shape as the camera setters: `value` = the `voice_id` to play. Reversed from a
|
|
12
|
+
* live capture (outer-cmd 1706, signCode 8, on the doorbell's `device_channel`) + the app's
|
|
13
|
+
* `PlayQuickResponseParser` (`{cmd:1706,voice_id}`).
|
|
14
|
+
*/
|
|
15
|
+
readonly QUICK_RESPONSE: 1706;
|
|
16
|
+
/**
|
|
17
|
+
* Mechanical (wired) chime enable/disable — whether the doorbell drives an existing wired chime box
|
|
18
|
+
* (as opposed to / in addition to the wireless indoor chime, param 1702 `chimeSwitch` above). Same
|
|
19
|
+
* 136-byte direct-binary shape as `QUICK_RESPONSE`/camera on-off: `[u32 channel][u32 value][account_id
|
|
20
|
+
* ASCII, zero-padded to 128 bytes]`, outer P2P cmd = 1703 itself, signCode 8, on the device's own
|
|
21
|
+
* channel. Reversed from a live capture (outer-cmd 1703, signCode 8, captured on the doorbell's
|
|
22
|
+
* `device_channel` — channel 2 for that unit, NOT a wire constant, always use `ctx.channel`):
|
|
23
|
+
* turning ON sent `value=1`, turning OFF sent `value=0` — a plain boolean, 1=on/0=off.
|
|
24
|
+
* App `APP_CMD_BAT_DOORBELL_MECHANICAL_CHIME_SWITCH`.
|
|
25
|
+
*/
|
|
26
|
+
readonly MECHANICAL_CHIME_SWITCH: 1703;
|
|
27
|
+
/**
|
|
28
|
+
* Wide Dynamic Range (WDR) image switch — a video/image tone-mapping setting that widens the
|
|
29
|
+
* exposure range in high-contrast scenes (bright sky behind a visitor, etc). SAME 136-byte
|
|
30
|
+
* direct-binary shape/polarity/capture session as `MECHANICAL_CHIME_SWITCH` immediately above: outer
|
|
31
|
+
* P2P cmd 1704, signCode 8, device channel, `value` 1=on/0=off.
|
|
32
|
+
* App `APP_CMD_BAT_DOORBELL_WDR_SWITCH`.
|
|
33
|
+
*/
|
|
34
|
+
readonly WDR_SWITCH: 1704;
|
|
35
|
+
/**
|
|
36
|
+
* Doorbell chime ("ding-dong") volume — app `APP_CMD_BAT_DOORBELL_SET_DINGDONG_VOLUME`. UNLIKE the 1703/1704 direct-binary switches above, this rides the
|
|
37
|
+
* `SET_PAYLOAD` (1350) JSON envelope: `{account_id,cmd:1717,mChannel:<deviceCh>,mValue3:0,
|
|
38
|
+
* payload:{dingdong_volume:N}}`, GCM signCode 8, on the doorbell's `device_channel` (2 for the
|
|
39
|
+
* captured unit — always use `ctx.channel`, don't hardcode). `mValue3` is an EXPLICIT `0`, not the
|
|
40
|
+
* `SET_PAYLOAD` default of `mValue3:cmd` (see {@link module:./intent setPayload}'s doc comment) —
|
|
41
|
+
* both live frames captured showed `mValue3:0`. Reversed from a live capture (values 3 and 25
|
|
42
|
+
* observed) — a 0-100 loudness level, distinct from the already-shipped `ringtoneVolume` (1708,
|
|
43
|
+
* direct-binary, `audio.ts`), which is a DIFFERENT control.
|
|
44
|
+
*/
|
|
45
|
+
readonly DINGDONG_VOLUME: 1717;
|
|
46
|
+
/**
|
|
47
|
+
* Doorbell chime ("ding-dong") RINGTONE SELECTION — app `APP_CMD_BAT_DOORBELL_SET_DINGDONG_RINGTONE`.
|
|
48
|
+
* SAME `SET_PAYLOAD` (1350) JSON envelope shape as
|
|
49
|
+
* `DINGDONG_VOLUME` immediately above: `{account_id,cmd:1718,mChannel:<deviceCh>,mValue3:0,
|
|
50
|
+
* payload:{dingdong_ringtone:N}}`, GCM signCode 8, doorbell `device_channel`, explicit `mValue3:0`.
|
|
51
|
+
* Reversed from a live capture (values 4 and 0 observed) — `N` is an INTEGER INDEX picking one of
|
|
52
|
+
* several stored chime tones, NOT a boolean.
|
|
53
|
+
*/
|
|
54
|
+
readonly DINGDONG_RINGTONE: 1718;
|
|
55
|
+
/**
|
|
56
|
+
* Live-view quality AND the video encoding format, both in one integer — app
|
|
57
|
+
* `CMD_BAT_DOORBELL_VIDEO_QUALITY`. The value is `quality + (highCompression ? 5 : 0)`, where quality
|
|
58
|
+
* is 0 Auto / 1 Low / 2 Medium / 3 High ({@link DoorbellVideoQuality}). The app drives the two from
|
|
59
|
+
* separate menus and each write carries both, so setting either requires the other's current value —
|
|
60
|
+
* which is why neither is a derived setter.
|
|
61
|
+
*
|
|
62
|
+
* The encoding is reversed from writing every option in the app and reading the parameter back: High
|
|
63
|
+
* on high compression is 8 and on low compression 3, Low on low compression 1, Auto on high
|
|
64
|
+
* compression 5. Six of the eight combinations were observed that way; `0` (Auto, low compression) and
|
|
65
|
+
* `2` (Medium, low compression) follow the same arithmetic but were not individually written.
|
|
66
|
+
*
|
|
67
|
+
* Wire captured byte-exact from the app on a T8210 behind a HomeBase: outer P2P cmd 1705 itself — no
|
|
68
|
+
* wrapper — signCode 8, on the doorbell's own channel, the same 136-byte direct-binary
|
|
69
|
+
* `[u32 channel][u32 value][account_id ASCII pad 128]` struct as its 1703/1704 siblings. The station
|
|
70
|
+
* answers with an unencrypted level-1 frame carrying 0.
|
|
71
|
+
*
|
|
72
|
+
* Replayed from this SDK and confirmed on that device: three writes in one session, each read back off
|
|
73
|
+
* the parameter — quality alone, then the encoding format with the quality held, then a restore.
|
|
74
|
+
*/
|
|
75
|
+
readonly VIDEO_QUALITY: 1705;
|
|
76
|
+
/**
|
|
77
|
+
* Doorbell quick-response LIST fetch — the sub-command carried inside a `SET_PAYLOAD` (1350)
|
|
78
|
+
* wrapper (app `APP_CMD_GET_CUSTOMIZE_VICOE_LIST`). The station replies with a `NOTIFY_PAYLOAD`
|
|
79
|
+
* (1351) frame whose JSON is `{cmd:6237, payload:{voice_list:[{voice_id,voice_name,voice_path}]}}`.
|
|
80
|
+
* Reversed from the app's `GetQuickResponseListP2pParser` + the capture heap. NOTE: 6238
|
|
81
|
+
* (`APP_CMD_GET_QUICK_RESPONSE`) is the single-file DOWNLOAD, not the list.
|
|
82
|
+
*/
|
|
83
|
+
readonly GET_QUICK_RESPONSE_LIST: 6237;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Doorbell chime ("ding-dong") ringtone selection, as a 0-indexed list. Three indices were confirmed
|
|
87
|
+
* on-device (`0→Default`, `7→Ding`, `8→Hillside`) and land exactly on a plain top-to-bottom order, so
|
|
88
|
+
* the remaining indices follow that same linear order rather than being individually tested. Full name list
|
|
89
|
+
* (10 entries) read off the app's own picker UI. `Circuit` (index 5) is a BEST-EFFORT spelling — its
|
|
90
|
+
* index was not individually wire-tested, only its position in the read-off list.
|
|
91
|
+
*/
|
|
92
|
+
export declare const DoorbellRingtone: {
|
|
93
|
+
readonly Default: 0;
|
|
94
|
+
readonly Silent: 1;
|
|
95
|
+
readonly Beacon: 2;
|
|
96
|
+
readonly Chord: 3;
|
|
97
|
+
readonly Christmas: 4;
|
|
98
|
+
readonly Circuit: 5;
|
|
99
|
+
readonly Clock: 6;
|
|
100
|
+
readonly Ding: 7;
|
|
101
|
+
readonly Hillside: 8;
|
|
102
|
+
readonly Presto: 9;
|
|
103
|
+
};
|
|
104
|
+
/** A doorbell ringtone option — the value side of {@link DoorbellRingtone}. */
|
|
105
|
+
export type DoorbellRingtoneValue = (typeof DoorbellRingtone)[keyof typeof DoorbellRingtone];
|
|
106
|
+
export declare const DoorbellVideoQuality: {
|
|
107
|
+
/** The doorbell picks a quality from the link. */
|
|
108
|
+
readonly Auto: 0;
|
|
109
|
+
readonly Low: 1;
|
|
110
|
+
readonly Medium: 2;
|
|
111
|
+
readonly High: 3;
|
|
112
|
+
};
|
|
113
|
+
/** A doorbell live-view quality — the value side of {@link DoorbellVideoQuality}. */
|
|
114
|
+
export type DoorbellVideoQualityValue = (typeof DoorbellVideoQuality)[keyof typeof DoorbellVideoQuality];
|
|
115
|
+
/**
|
|
116
|
+
* One of a Video Doorbell's **quick responses** — a canned voice reply it can play at a visitor.
|
|
117
|
+
* Returned by `dev.doorbell()?.quickResponses()`; pass `voiceId` to `playQuickResponse`. Owned by the
|
|
118
|
+
* doorbell capability (the client transport stays doorbell-agnostic — it only knows generic P2P).
|
|
119
|
+
*/
|
|
120
|
+
export interface QuickResponse {
|
|
121
|
+
/** The response's `voice_id` — pass to `playQuickResponse` to play it. */
|
|
122
|
+
voiceId: number;
|
|
123
|
+
/** Human-readable label, e.g. "Please leave it at the door". */
|
|
124
|
+
name: string;
|
|
125
|
+
/** On-device audio path, e.g. `/system/snd//QuickReply_1.snd` or `/user/quick_respone_diy//QuickReply_5.aac`. */
|
|
126
|
+
path: string;
|
|
127
|
+
/** `false` = predefined/eufy-shipped (`/system/snd/`); `true` = user-recorded custom (`/user/…`). */
|
|
128
|
+
custom: boolean;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Bound doorbell controls — the object returned by `dev.doorbell()`. The status LED is NOT here: a
|
|
132
|
+
* doorbell is a `camera`-codec device, so its LED lives on the shared `dev.camera().setStatusLed()`
|
|
133
|
+
* surface, which swaps to the doorbell's own wire by family (one action, not a duplicate here).
|
|
134
|
+
* `playQuickResponse` is always present (it orchestrates a live stream); `quickResponses` (a P2P
|
|
135
|
+
* request/reply query that RETURNS data) is present only when the device is bound to a live client
|
|
136
|
+
* with a {@link MediaProvider} — hence optional, call with `?.`.
|
|
137
|
+
*/
|
|
138
|
+
export type DoorbellActions = Surface<typeof DOORBELL_MEMBERS>;
|
|
139
|
+
/**
|
|
140
|
+
* Parse a doorbell `voice_list` (the `{voice_id,voice_name,voice_path}` records the station returns
|
|
141
|
+
* in the quick-response GET reply) into typed {@link QuickResponse}s. Pure/offline. The `custom` flag
|
|
142
|
+
* is derived from the `voice_path` **prefix** (robust) — predefined responses live under `/system/snd/`,
|
|
143
|
+
* user-recorded ones under `/user/…` — NOT from the id range (ids 1–3 predefined, 100+ custom, but the
|
|
144
|
+
* path is authoritative).
|
|
145
|
+
*/
|
|
146
|
+
export declare function parseQuickResponses(voiceList: Array<{
|
|
147
|
+
voice_id?: unknown;
|
|
148
|
+
voice_name?: unknown;
|
|
149
|
+
voice_path?: unknown;
|
|
150
|
+
}>): QuickResponse[];
|
|
151
|
+
/**
|
|
152
|
+
* `doorbell` — chime / ringtone configuration. CONFIRMED against a real Video Doorbell (T8214):
|
|
153
|
+
* the live ids are the `1702-1719` `CMD_BAT_DOORBELL_*` range (provenance "mega", observed). The
|
|
154
|
+
* legacy `2015/2022/1306` ids are excluded — they appear on NO owned device. The button-
|
|
155
|
+
* press *event* (ring) is delivered out-of-band via `CMD_DOORBELL_NOTIFY_PAYLOAD` (1701) /
|
|
156
|
+
* push/MQTT — it is handled by the Phase-1 event normalizers, not as a device-list param.
|
|
157
|
+
*/
|
|
158
|
+
/**
|
|
159
|
+
* Every `doorbell` feature, declared once.
|
|
160
|
+
*
|
|
161
|
+
* Three of the seven reads are read-ONLY here even though the device accepts a write, because the write
|
|
162
|
+
* does not belong to this capability or is not confirmed:
|
|
163
|
+
* - `ringtoneVolume` (1708) — the WRITE lives on `audio`, which owns every volume wire. 1708 leaks
|
|
164
|
+
* onto non-doorbell cameras, so `audio` gates its setter on the doorbell capability instead.
|
|
165
|
+
* - `chimeSwitch` (1702) — READ confirmed on a T8214, the WRITE wire never captured. Its 1703/1704
|
|
166
|
+
* siblings share the param range but that is NOT evidence of a shared frame, and a wrong guess on a
|
|
167
|
+
* fire-and-forget P2P write looks exactly like success.
|
|
168
|
+
* - `notificationMode` (1710) — a config JSON the device reports whole; no write is captured.
|
|
169
|
+
*
|
|
170
|
+
* Exported but NOT published: each entry states its wire id and the evidence it was confirmed on,
|
|
171
|
+
* which the reference site does not carry.
|
|
172
|
+
* @internal
|
|
173
|
+
*/
|
|
174
|
+
export declare const DOORBELL_MEMBERS: {
|
|
175
|
+
/**
|
|
176
|
+
* The WIRELESS indoor chime — the separate plug-in unit, not the wired chime box
|
|
177
|
+
* `mechanicalChimeSwitch` drives. `unverified: true` with no `write` at all: the read is confirmed but
|
|
178
|
+
* the write frame has never been captured, so the setter is absent from the surface (a compile-time
|
|
179
|
+
* signal) and the intent path throws rather than reporting the doorbell as lacking the feature.
|
|
180
|
+
* Sharing the 1702-1719 range with its captured siblings is not evidence of a shared frame shape.
|
|
181
|
+
*/
|
|
182
|
+
readonly chimeSwitch: {
|
|
183
|
+
readonly param: 1702;
|
|
184
|
+
readonly type: "bool";
|
|
185
|
+
readonly kind: "boolean";
|
|
186
|
+
readonly provenance: "mega";
|
|
187
|
+
readonly unverified: true;
|
|
188
|
+
readonly description: string;
|
|
189
|
+
};
|
|
190
|
+
/**
|
|
191
|
+
* `provenance` is "verified" not "mega": the actual write wire is confirmed (
|
|
192
|
+
* our own P2P decrypt), not merely the param id observed on a live device. Direct-binary
|
|
193
|
+
* `[ch][value][acct]`, 1=on/0=off — verified live on a T8214 (ON then OFF).
|
|
194
|
+
*/
|
|
195
|
+
readonly mechanicalChimeSwitch: {
|
|
196
|
+
readonly param: 1703;
|
|
197
|
+
readonly type: "bool";
|
|
198
|
+
readonly kind: "boolean";
|
|
199
|
+
readonly provenance: "verified";
|
|
200
|
+
readonly description: "Mechanical chime enabled (1703; confirmed on T8214).";
|
|
201
|
+
readonly write: (v: string | number | boolean, ctx: import("./types.js").CommandContext) => import("../../core/contracts.js").Command;
|
|
202
|
+
};
|
|
203
|
+
/** Same reasoning and the same capture session as {@link DOORBELL_MEMBERS.mechanicalChimeSwitch}. */
|
|
204
|
+
readonly wdrSwitch: {
|
|
205
|
+
readonly param: 1704;
|
|
206
|
+
readonly type: "bool";
|
|
207
|
+
readonly kind: "boolean";
|
|
208
|
+
readonly provenance: "verified";
|
|
209
|
+
readonly description: "Wide Dynamic Range (WDR) image switch (1704; write wire-confirmed live on T8214 — see DOORBELL_CMD.WDR_SWITCH).";
|
|
210
|
+
readonly write: (v: string | number | boolean, ctx: import("./types.js").CommandContext) => import("../../core/contracts.js").Command;
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* The READ half of a control whose write lives on `audio` — hence `writtenElsewhere`, which is what
|
|
214
|
+
* keeps the published schema's `writable` true even though this member declares no `write`. The split
|
|
215
|
+
* is deliberate: `audio` owns every volume wire, but 1708 leaks onto non-doorbell cameras, so `audio`
|
|
216
|
+
* gates its setter on this capability while the read stays here where it is doorbell-only. Distinct
|
|
217
|
+
* from `dingdongVolume` (1717), which is a different control on a different wire.
|
|
218
|
+
*/
|
|
219
|
+
readonly ringtoneVolume: {
|
|
220
|
+
readonly param: 1708;
|
|
221
|
+
readonly type: "number";
|
|
222
|
+
readonly unit: "%";
|
|
223
|
+
readonly kind: "percent";
|
|
224
|
+
readonly provenance: "mega";
|
|
225
|
+
readonly writtenElsewhere: true;
|
|
226
|
+
readonly description: string;
|
|
227
|
+
};
|
|
228
|
+
/**
|
|
229
|
+
* A `1350` SET_PAYLOAD envelope (NOT direct-binary) with an explicit `mValue3` 0 — both live frames
|
|
230
|
+
* captured that value. Bounded 0-100 like every sibling volume setter: the write is fire-and-forget,
|
|
231
|
+
* so an out-of-range value would otherwise be sent as-is and look like it worked. `provenance` is
|
|
232
|
+
* "verified" on our own capture, not merely an observed param id.
|
|
233
|
+
*/
|
|
234
|
+
readonly dingdongVolume: {
|
|
235
|
+
readonly param: 1717;
|
|
236
|
+
readonly type: "number";
|
|
237
|
+
readonly unit: "%";
|
|
238
|
+
readonly kind: "percent";
|
|
239
|
+
readonly provenance: "verified";
|
|
240
|
+
readonly min: 0;
|
|
241
|
+
readonly max: 100;
|
|
242
|
+
readonly description: string;
|
|
243
|
+
readonly write: (v: string | number | boolean, ctx: import("./types.js").CommandContext) => import("../../core/contracts.js").Command;
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* The same `1350` SET_PAYLOAD shape and capture session as {@link DOORBELL_MEMBERS.dingdongVolume},
|
|
247
|
+
* but an INDEX rather than a level. Clamping a bad index would land on a real-but-wrong tone (garbage
|
|
248
|
+
* → 0, too-big → 9) instead of failing, and only 3 of the 10 indices (0, 7, 8) are wire-tested — so
|
|
249
|
+
* anything outside {@link DoorbellRingtone} is refused.
|
|
250
|
+
*/
|
|
251
|
+
readonly dingdongRingtone: {
|
|
252
|
+
readonly param: 1718;
|
|
253
|
+
readonly type: "number";
|
|
254
|
+
readonly kind: "enum";
|
|
255
|
+
readonly enumValues: Record<number, string>;
|
|
256
|
+
readonly provenance: "verified";
|
|
257
|
+
readonly args: readonly [{
|
|
258
|
+
readonly name: "ringtone";
|
|
259
|
+
readonly kind: "enum";
|
|
260
|
+
readonly description: "A tone INDEX, not a volume.";
|
|
261
|
+
}];
|
|
262
|
+
readonly description: string;
|
|
263
|
+
readonly write: (v: string | number | boolean, ctx: import("./types.js").CommandContext) => import("../../core/contracts.js").Command | undefined;
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* The live-view quality half of {@link DOORBELL_CMD.VIDEO_QUALITY}, lifted out of the composite by
|
|
267
|
+
* `decode`. `writtenElsewhere` because the setter needs the OTHER half's current value to rebuild the
|
|
268
|
+
* integer, which a member's `write` — given only the new value and the context — cannot read.
|
|
269
|
+
*/
|
|
270
|
+
readonly videoQuality: {
|
|
271
|
+
readonly param: 1705;
|
|
272
|
+
readonly type: "number";
|
|
273
|
+
readonly kind: "enum";
|
|
274
|
+
readonly enumValues: Record<number, string>;
|
|
275
|
+
readonly provenance: "verified";
|
|
276
|
+
readonly writtenElsewhere: true;
|
|
277
|
+
readonly decode: (raw: unknown) => number | undefined;
|
|
278
|
+
readonly decodedKind: "enum";
|
|
279
|
+
readonly decodedValues: (0 | 1 | 2 | 3)[];
|
|
280
|
+
readonly description: string;
|
|
281
|
+
};
|
|
282
|
+
/**
|
|
283
|
+
* The encoding half of the SAME integer, so it declares no param of its own and reaches into the
|
|
284
|
+
* owner's value — two members claiming 1705 would leave the second reading a name nothing is stored
|
|
285
|
+
* under, and a paramless member publishes no schema entry at all, which is what keeps that from
|
|
286
|
+
* happening structurally. High compression is the app's default on the captured device.
|
|
287
|
+
*/
|
|
288
|
+
readonly highCompressionEncoding: {
|
|
289
|
+
readonly readsFrom: "videoQuality";
|
|
290
|
+
readonly type: "bool";
|
|
291
|
+
readonly kind: "boolean";
|
|
292
|
+
readonly provenance: "verified";
|
|
293
|
+
readonly decode: (raw: unknown) => boolean | undefined;
|
|
294
|
+
readonly description: string;
|
|
295
|
+
};
|
|
296
|
+
/**
|
|
297
|
+
* Set both halves of {@link DOORBELL_CMD.VIDEO_QUALITY} at once, because the wire has no way to set
|
|
298
|
+
* one alone: every frame carries the whole integer.
|
|
299
|
+
*
|
|
300
|
+
* Taking both is not a convenience choice. An earlier shape took one and preserved the other by
|
|
301
|
+
* reading it back, and it failed on hardware: the state reader is the snapshot the device was bound
|
|
302
|
+
* with, so a second write in the same session composed against the value from before the first and
|
|
303
|
+
* silently reverted it. Requiring both puts that decision where it can be made correctly — a caller
|
|
304
|
+
* reads {@link DOORBELL_MEMBERS.videoQuality} and {@link DOORBELL_MEMBERS.highCompressionEncoding}
|
|
305
|
+
* and passes what it wants, instead of the SDK guessing from a stale copy.
|
|
306
|
+
*/
|
|
307
|
+
readonly setVideoQuality: import("./members.js").MethodMember<(quality: DoorbellVideoQualityValue, highCompression: boolean) => Promise<void>>;
|
|
308
|
+
/**
|
|
309
|
+
* A config blob the device reports WHOLE, so it is typed `string` and handed back unparsed — three
|
|
310
|
+
* settings live inside it (motion notifications, ring notifications, notification style) and the SDK
|
|
311
|
+
* lifts none of them out, because no `decode` is evidenced for the shape. Read-only: no write frame
|
|
312
|
+
* has been captured for it, and a config JSON is exactly where a guessed write does the most damage.
|
|
313
|
+
*/
|
|
314
|
+
readonly notificationMode: {
|
|
315
|
+
readonly param: 1710;
|
|
316
|
+
readonly type: "string";
|
|
317
|
+
readonly kind: "text";
|
|
318
|
+
readonly provenance: "mega";
|
|
319
|
+
readonly description: string;
|
|
320
|
+
};
|
|
321
|
+
/**
|
|
322
|
+
* Play one of the doorbell's quick responses at the visitor. `voiceId` comes from
|
|
323
|
+
* {@link DOORBELL_MEMBERS.quickResponses}. The doorbell only plays while it has an active media
|
|
324
|
+
* session, so by default this briefly engages a live stream, sends, then tears it down.
|
|
325
|
+
* `{ engage: false }` leaves an already-open stream alone.
|
|
326
|
+
*
|
|
327
|
+
* If engagement was requested but no stream comes up this THROWS, rather than firing 1706 into the
|
|
328
|
+
* void and reporting success — the doorbell would play nothing. The wire is `QUICK_RESPONSE` 1706,
|
|
329
|
+
* the SAME direct-binary command as camera on/off, carrying the voice id as its value.
|
|
330
|
+
*/
|
|
331
|
+
readonly playQuickResponse: import("./members.js").MethodMember<(voiceId: number, opts?: {
|
|
332
|
+
engage?: boolean;
|
|
333
|
+
}) => Promise<void>>;
|
|
334
|
+
/**
|
|
335
|
+
* Fetch the doorbell's quick-response list — a P2P request/reply query that returns data, so it
|
|
336
|
+
* exists only on a device bound to a media provider that offers one.
|
|
337
|
+
*
|
|
338
|
+
* The transport stays doorbell-agnostic: it runs a GENERIC SET_PAYLOAD query (sub-cmd → reply
|
|
339
|
+
* payload); this capability owns the sub-command id (6237) and the reply parsing.
|
|
340
|
+
*/
|
|
341
|
+
readonly quickResponses: import("./members.js").ProvidedMember<"media", ((opts?: {
|
|
342
|
+
timeoutMs?: number;
|
|
343
|
+
}) => Promise<QuickResponse[]>) | undefined>;
|
|
344
|
+
};
|
|
345
|
+
export declare const DOORBELL: CapabilityModule;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-SKU DP capability catalog — the parsed result of a `get_product_data_point` API call.
|
|
3
|
+
*
|
|
4
|
+
* The response carries one entry per data point, each declaring `dp_id`, a stable `code`, a
|
|
5
|
+
* human `name`, an access `mode`, a `data_type` and a `property` blob. Only the enum ranges are
|
|
6
|
+
* read here; the names and writability that same call reports are already resolved offline into
|
|
7
|
+
* `CLEAN_PARAMS`, so what this adds is the per-SKU narrowing a shared dictionary cannot carry —
|
|
8
|
+
* two products with the same DP can offer different value sets.
|
|
9
|
+
*
|
|
10
|
+
* Still defensive at every step: a missing key or a mismatched shape yields an empty catalog and
|
|
11
|
+
* capabilities fall back to their safe defaults, because a wrong range is worse than none.
|
|
12
|
+
*
|
|
13
|
+
* @module model/capabilities/dp-catalog
|
|
14
|
+
*/
|
|
15
|
+
/** The parsed DP capability catalog for one product SKU. */
|
|
16
|
+
export interface DpCatalog {
|
|
17
|
+
/**
|
|
18
|
+
* For enum-type DPs: the valid integer values as declared in the catalog.
|
|
19
|
+
* Absent for non-enum DPs (bool, raw, integer, string).
|
|
20
|
+
*/
|
|
21
|
+
readonly enumRanges: ReadonlyMap<number, readonly number[]>;
|
|
22
|
+
}
|
|
23
|
+
/** Returned whenever the API call fails or the response shape is not recognised. */
|
|
24
|
+
export declare const EMPTY_DP_CATALOG: DpCatalog;
|
|
25
|
+
/**
|
|
26
|
+
* Parse a `get_product_data_point` response into a {@link DpCatalog}.
|
|
27
|
+
*
|
|
28
|
+
* `raw` is the response's `data` object, already unwrapped by the transport — so the entry array
|
|
29
|
+
* sits at the top level under `data_point_list`.
|
|
30
|
+
*
|
|
31
|
+
* An entry's declared type is `data_type` and its constraint blob is `property`; a range is read
|
|
32
|
+
* only from an enum entry, since that is the only type whose `property` states a closed set.
|
|
33
|
+
* `data_type` is matched case-insensitively — its casing is the server's to choose and nothing
|
|
34
|
+
* here should depend on it.
|
|
35
|
+
*
|
|
36
|
+
* Returns {@link EMPTY_DP_CATALOG} on any shape mismatch — never throws.
|
|
37
|
+
*/
|
|
38
|
+
export declare function parseDpCatalog(raw: unknown): DpCatalog;
|