@mega-yfue/eufy-sdk 0.2.0-beta.4 → 0.2.0-beta.6
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/dist/index.js +212 -4
- package/dist/index.js.map +3 -3
- package/dist/model/capabilities/display.d.ts +85 -0
- package/dist/model/capabilities/index.d.ts +5 -1
- package/dist/model/capabilities/types.d.ts +9 -2
- package/dist/model/capabilities/vacuum-clean.d.ts +74 -25
- package/dist/model/param-dictionary.d.ts +24 -0
- package/dist/model/param-namespace.d.ts +1 -1
- package/dist/model/types.d.ts +5 -5
- package/package.json +1 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { CapabilityModule } from "./types.js";
|
|
2
|
+
import { type Surface } from "./members.js";
|
|
3
|
+
/**
|
|
4
|
+
* `display` — a eufy Smart Display's charge.
|
|
5
|
+
*
|
|
6
|
+
* One typed read, and the smallness is the finding rather than a gap. The captured unit (a T87A0,
|
|
7
|
+
* 2026-09-04) connects over secure MQTT with no `p2p_did`, so it speaks no P2P at all, and it reported
|
|
8
|
+
* six params in an id range no other line uses. Only one of them tells a caller something it could not
|
|
9
|
+
* get another way:
|
|
10
|
+
*
|
|
11
|
+
* - 8005 and 8006 restate the model's retail name and code, which `info` already answers from the
|
|
12
|
+
* curated registry and the cloud record. Their evidence IS that agreement, so a getter beside `info`
|
|
13
|
+
* would offer a caller a second spelling of what it just read. They are named in the display param
|
|
14
|
+
* dictionary, which is what makes them readable off `getProperties()`.
|
|
15
|
+
* - 8003 is version-shaped and nothing confirms what it means, so it is `unexposed`: in the schema with
|
|
16
|
+
* its type and its `guessed` label, reachable through `getProperty`, no typed getter.
|
|
17
|
+
*
|
|
18
|
+
* Nothing is writable. No capture pins a write for any display param, and an AIoT write is
|
|
19
|
+
* fire-and-forget, so a wrong frame to a device that acknowledges nothing looks exactly like success. A
|
|
20
|
+
* screen, a volume, an assistant: the device plainly has all three and reports none of them in anything
|
|
21
|
+
* captured, which means the reads have to arrive before a control can be honest about what it moves.
|
|
22
|
+
*
|
|
23
|
+
* @module model/capabilities/display
|
|
24
|
+
*/
|
|
25
|
+
/** Smart Display param ids this capability reads. The rest of the range is named in the dictionary. */
|
|
26
|
+
export declare const DISPLAY_PARAM: {
|
|
27
|
+
readonly BATTERY: 8001;
|
|
28
|
+
readonly SOFTWARE_VERSION: 8003;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* The `display` reads. Read-only; see the module note for why there is no write.
|
|
32
|
+
*
|
|
33
|
+
* Exported but NOT published: the entries state their wire ids and what each claim rests on, which the
|
|
34
|
+
* reference site does not carry.
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
export declare const DISPLAY_MEMBERS: {
|
|
38
|
+
/**
|
|
39
|
+
* Battery level, 0-100.
|
|
40
|
+
*
|
|
41
|
+
* **On this capability rather than on `battery`, and that is the line partition doing its job.** The
|
|
42
|
+
* security-line `battery` capability reads param 1101 and a Smart Display's charge is 8001 in its own
|
|
43
|
+
* id space — two wires that happen to mean the same thing. One capability reading both would be a claim
|
|
44
|
+
* that the two ecosystems share a param space, so a consumer reads a display's charge through
|
|
45
|
+
* `dev.display()` and a camera's through `dev.battery()`.
|
|
46
|
+
*
|
|
47
|
+
* `verified` rather than `mega`: the id is in the device's cloud record, but the NAME came from the
|
|
48
|
+
* maintainer's own knowledge of the hardware rather than from the cloud data-point list, and `"100"`
|
|
49
|
+
* fits brightness, volume or charge equally.
|
|
50
|
+
*
|
|
51
|
+
* The scale is `percent` on the reading itself, not on convention alone: a full charge reads `255` on a
|
|
52
|
+
* 0-255 scale and `1000` on a 0-1000 one, so `"100"` on a charged unit is positive evidence for 0-100
|
|
53
|
+
* rather than merely consistent with it. What nobody has done is watch it MOVE, which is why a value
|
|
54
|
+
* frozen at 100 would not yet be distinguishable from a healthy one.
|
|
55
|
+
*/
|
|
56
|
+
readonly battery: {
|
|
57
|
+
readonly param: 8001;
|
|
58
|
+
readonly type: "number";
|
|
59
|
+
readonly unit: "%";
|
|
60
|
+
readonly kind: "percent";
|
|
61
|
+
readonly provenance: "verified";
|
|
62
|
+
readonly description: "Battery level, 0-100 (param 8001).";
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Version-shaped, and that shape is the whole of the evidence — hence `guessed`, and hence no typed
|
|
66
|
+
* getter: a caller reading this off a bound object cannot see the label.
|
|
67
|
+
*
|
|
68
|
+
* `unexposed` rather than absent, so the schema still carries its type and that label and
|
|
69
|
+
* `getProperty("softwareVersion")` still answers. `dev.info()?.firmwareVersion` is the field to trust
|
|
70
|
+
* where the cloud record carries one; on this display it does not, which is the only reason 8003 is
|
|
71
|
+
* named at all.
|
|
72
|
+
*/
|
|
73
|
+
readonly softwareVersion: {
|
|
74
|
+
readonly param: 8003;
|
|
75
|
+
readonly type: "string";
|
|
76
|
+
readonly kind: "text";
|
|
77
|
+
readonly provenance: "guessed";
|
|
78
|
+
readonly unexposed: true;
|
|
79
|
+
readonly description: "Version-shaped string (param 8003), meaning unconfirmed — prefer `info.firmwareVersion`.";
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
/** `display` — a eufy Smart Display (T87Ax). Read-only; no display write is captured. */
|
|
83
|
+
export declare const DISPLAY: CapabilityModule;
|
|
84
|
+
/** Bound Smart Display reads — the object returned by `dev.display()`. Read-only. */
|
|
85
|
+
export type DisplayActions = Surface<typeof DISPLAY_MEMBERS>;
|
|
@@ -40,6 +40,7 @@ import type { KeypadActions } from "./keypad.js";
|
|
|
40
40
|
import type { RtspActions } from "./rtsp.js";
|
|
41
41
|
import type { VacuumCleanActions } from "./vacuum-clean.js";
|
|
42
42
|
import type { VacuumDockActions } from "./vacuum-dock.js";
|
|
43
|
+
import type { DisplayActions } from "./display.js";
|
|
43
44
|
import type { SuctionActions } from "./suction.js";
|
|
44
45
|
import type { LocateActions } from "./locate.js";
|
|
45
46
|
import type { DeviceInfo } from "./info.js";
|
|
@@ -411,6 +412,8 @@ export interface DeviceActionMap {
|
|
|
411
412
|
suction: SuctionActions;
|
|
412
413
|
/** RoboVac locate (find-robot beep): `locating`; `locate(on?)`. */
|
|
413
414
|
locate: LocateActions;
|
|
415
|
+
/** Smart Display (read-only): `battery`. No display write is captured. */
|
|
416
|
+
display: DisplayActions;
|
|
414
417
|
/** Identity metadata (read-only): `{ manufacturer, model, serialNumber, name, deviceType?, firmwareVersion?, hardwareVersion? }`. */
|
|
415
418
|
info: DeviceInfo;
|
|
416
419
|
}
|
|
@@ -529,6 +532,7 @@ export { RTSP_MEMBERS } from "./rtsp.js";
|
|
|
529
532
|
export { SIREN_MEMBERS } from "./siren.js";
|
|
530
533
|
export { SMART_LIGHT_MEMBERS } from "./smart-light.js";
|
|
531
534
|
export { SMOKE_MEMBERS } from "./smoke.js";
|
|
535
|
+
export { DISPLAY_MEMBERS, type DisplayActions } from "./display.js";
|
|
532
536
|
export { SUCTION_MEMBERS } from "./suction.js";
|
|
533
537
|
export { VACUUM_CLEAN_MEMBERS } from "./vacuum-clean.js";
|
|
534
538
|
export type { DeviceInfo } from "./info.js";
|
|
@@ -550,7 +554,7 @@ export { HubAlarmTone, type HubAlarmToneValue } from "./siren.js";
|
|
|
550
554
|
* RoboVac activity and clean type are the declared returns of the public `dev.vacuumClean()` getters,
|
|
551
555
|
* so both unions are published.
|
|
552
556
|
*/
|
|
553
|
-
export type { VacuumActivity, VacuumCleanType, CarpetStrategy, CleanExtent } from "./vacuum-clean.js";
|
|
557
|
+
export type { VacuumActivity, VacuumCleanType, CarpetStrategy, CleanExtent, VacuumRoomTarget, VacuumZoneTarget, } from "./vacuum-clean.js";
|
|
554
558
|
/** The lists those unions are taken from — published because each union names its own. */
|
|
555
559
|
export { VACUUM_ACTIVITIES, VACUUM_CLEAN_TYPES, CARPET_STRATEGIES, CLEAN_EXTENTS, MOP_LEVELS } from "./vacuum-clean.js";
|
|
556
560
|
export { SuctionLevel, suctionLevelName, type SuctionLevelValue } from "./suction.js";
|
|
@@ -41,12 +41,19 @@ export interface DetectionSpec {
|
|
|
41
41
|
*
|
|
42
42
|
* eufy ships several ecosystems that share a cloud account and nothing else: `security` (cameras,
|
|
43
43
|
* stations, locks, sensors — P2P plus the security-scoped broker), `life` (the T8L0x smart-lighting
|
|
44
|
-
* line — its own credential and its own DP wire),
|
|
44
|
+
* line — its own credential and its own DP wire), `clean` (robot vacuums — Tuya data points) and
|
|
45
|
+
* `display` (the T87Ax Smart Display — secure MQTT, never P2P, its own 8001-8006 param space).
|
|
45
46
|
* They overlap in retail vocabulary but share no wire, no param space and no semantics.
|
|
46
47
|
*
|
|
48
|
+
* `display` is a line of its own for the second of those reasons rather than the first: without it,
|
|
49
|
+
* every security capability detected by a NAME regex is attachable to a Smart Display — measured at six,
|
|
50
|
+
* on a device that can answer for none of them because it speaks no P2P at all. A line holding one
|
|
51
|
+
* capability still buys that, which is why the count is not the measure of whether a line is worth
|
|
52
|
+
* declaring.
|
|
53
|
+
*
|
|
47
54
|
* `any` is for the handful of capabilities that are genuinely line-independent (device identity).
|
|
48
55
|
*/
|
|
49
|
-
export type ProductLine = "security" | "life" | "clean" | "print" | "any";
|
|
56
|
+
export type ProductLine = "security" | "life" | "clean" | "print" | "display" | "any";
|
|
50
57
|
/**
|
|
51
58
|
* A structural subset of a P2P frame. Deliberately NOT `import`ed from `p2p/*` — keeping it
|
|
52
59
|
* structural avoids a model→p2p cycle, and the real `P2PFrame` is assignable to it. It is the
|
|
@@ -192,35 +192,27 @@ export declare const ModeCtrlMethod: {
|
|
|
192
192
|
readonly STOP_SMART_FOLLOW: 18;
|
|
193
193
|
readonly START_GLOBAL_CRUISE: 20;
|
|
194
194
|
};
|
|
195
|
-
/**
|
|
196
|
-
* The methods that carry a `Param` oneof — room, zone, goto, schedule, cruise and scene cleans.
|
|
197
|
-
*
|
|
198
|
-
* Deliberately absent from {@link ModeCtrlMethod}. Each needs an argument the caller has to supply and
|
|
199
|
-
* this SDK cannot yet answer: a room or zone id comes from map data, which is not decodable here, and a
|
|
200
|
-
* coordinate is signed centimetres in a frame no capture has pinned. Listing their numbers beside the
|
|
201
|
-
* parameterless ones would invite a caller to send one with an empty payload, which is a valid frame
|
|
202
|
-
* meaning something nobody intended.
|
|
203
|
-
*/
|
|
204
|
-
/**
|
|
205
|
-
* Encode a `ModeCtrlRequest` protobuf (DP 152) as a DP value: `varint(bodyLen) ++ {method:1, seq:2}`.
|
|
206
|
-
*
|
|
207
|
-
* Built on {@link RawDpWriter} rather than hand-rolled bytes. The frame is unchanged and the existing
|
|
208
|
-
* byte-level test is what proves it — that test was written against a live T2351 capture, so it holds
|
|
209
|
-
* the writer to the wire rather than to this function's own idea of the wire.
|
|
210
|
-
*
|
|
211
|
-
* Method 0 (START_AUTO_CLEAN) is omitted rather than written as an explicit zero, per the proto3
|
|
212
|
-
* default-field rule and confirmed on that same capture. The writer deliberately does not apply that
|
|
213
|
-
* rule itself: whether an explicit zero and an absent field mean the same thing is the
|
|
214
|
-
* message's business, not the encoder's.
|
|
215
|
-
* @internal
|
|
216
|
-
*/
|
|
217
195
|
/**
|
|
218
196
|
* The area-selecting `ModeCtrlRequest` methods, and the `Param` field each one's payload rides in.
|
|
219
197
|
*
|
|
220
198
|
* Kept apart from {@link ModeCtrlMethod} because these are a different kind of thing: a parameterless
|
|
221
199
|
* verb is complete on its own, whereas each of these is meaningless without an argument the caller has
|
|
222
200
|
* to supply. Sending one with an empty payload is a well-formed frame that means something nobody
|
|
223
|
-
* intended, which is exactly why the numbers do not sit beside the others.
|
|
201
|
+
* intended, which is exactly why the numbers do not sit beside the others. Each verb built on one takes
|
|
202
|
+
* its argument in the signature: {@link VACUUM_CLEAN_MEMBERS.startScene},
|
|
203
|
+
* {@link VACUUM_CLEAN_MEMBERS.cleanRooms} and {@link VACUUM_CLEAN_MEMBERS.cleanZones}.
|
|
204
|
+
*
|
|
205
|
+
* The outer frame these ride in is byte-verified on a live T2351, and `SCENE`, `SELECT_ROOMS` and
|
|
206
|
+
* `SELECT_ZONES` have each since been RUN on a T2351 and did what they name — so their numbers rest on
|
|
207
|
+
* observed behaviour rather than on the vendor's definition alone.
|
|
208
|
+
*
|
|
209
|
+
* That distinction is the whole point of checking, and this is the one place it is argued: an AIoT
|
|
210
|
+
* data-point write is fire-and-forget, so a wrong number would be a different command arriving and
|
|
211
|
+
* looking exactly like success, which no frame check could catch. Watching the number is the only thing
|
|
212
|
+
* that rules it out.
|
|
213
|
+
*
|
|
214
|
+
* `GOTO` carries no encoder because a goto point is a coordinate no read on this SDK supplies, where a
|
|
215
|
+
* scene id and a map id both arrive on DP 180.
|
|
224
216
|
*/
|
|
225
217
|
export declare const ModeCtrlParamMethod: {
|
|
226
218
|
/** `START_SELECT_ROOMS_CLEAN` — clean the named rooms of a named map. */
|
|
@@ -267,7 +259,7 @@ export interface VacuumZoneTarget {
|
|
|
267
259
|
* `mapId` is required and has no default, deliberately. The obvious shortcut is to assume the map a
|
|
268
260
|
* single-floor home would have; on a two-floor home that silently sends the robot's ids against the
|
|
269
261
|
* wrong floor's map. A caller that cannot name the map cannot safely make this call, and saying so is
|
|
270
|
-
* better than picking for them.
|
|
262
|
+
* better than picking for them. {@link VACUUM_CLEAN_MEMBERS.cleanRooms} dispatches this.
|
|
271
263
|
* @internal
|
|
272
264
|
*/
|
|
273
265
|
export declare function encodeSelectRoomsClean(mapId: number, rooms: readonly VacuumRoomTarget[], cleanTimes?: number): string;
|
|
@@ -276,8 +268,25 @@ export declare function encodeSelectRoomsClean(mapId: number, rooms: readonly Va
|
|
|
276
268
|
* @internal
|
|
277
269
|
*/
|
|
278
270
|
export declare function encodeSelectZonesClean(mapId: number, zones: readonly VacuumZoneTarget[]): string;
|
|
279
|
-
/**
|
|
271
|
+
/**
|
|
272
|
+
* Build a scene clean, which needs only the scene's own id — `VacuumScene.id`, as DP 180 reports it.
|
|
273
|
+
* {@link VACUUM_CLEAN_MEMBERS.startScene} dispatches this.
|
|
274
|
+
* @internal
|
|
275
|
+
*/
|
|
280
276
|
export declare function encodeSceneClean(sceneId: number): string;
|
|
277
|
+
/**
|
|
278
|
+
* Encode a `ModeCtrlRequest` protobuf (DP 152) as a DP value: `varint(bodyLen) ++ {method:1, seq:2}`.
|
|
279
|
+
*
|
|
280
|
+
* Built on {@link RawDpWriter} rather than hand-rolled bytes. The frame is unchanged and the existing
|
|
281
|
+
* byte-level test is what proves it — that test was written against a live T2351 capture, so it holds
|
|
282
|
+
* the writer to the wire rather than to this function's own idea of the wire.
|
|
283
|
+
*
|
|
284
|
+
* Method 0 (START_AUTO_CLEAN) is omitted rather than written as an explicit zero, per the proto3
|
|
285
|
+
* default-field rule and confirmed on that same capture. The writer deliberately does not apply that
|
|
286
|
+
* rule itself: whether an explicit zero and an absent field mean the same thing is the
|
|
287
|
+
* message's business, not the encoder's.
|
|
288
|
+
* @internal
|
|
289
|
+
*/
|
|
281
290
|
export declare function encodeModeCtrl(method: number, seq: number): string;
|
|
282
291
|
/**
|
|
283
292
|
* Every value {@link VacuumActivity} can take, as data — the read's declared domain, so the schema a
|
|
@@ -1941,6 +1950,46 @@ export declare const VACUUM_CLEAN_MEMBERS: {
|
|
|
1941
1950
|
readonly pauseCleaning: import("./members.js").MethodMember<() => Promise<void>> & {
|
|
1942
1951
|
available: (ctx: import("./types.js").CommandContext) => boolean;
|
|
1943
1952
|
};
|
|
1953
|
+
/**
|
|
1954
|
+
* Run a saved cleaning scene by its id (ModeCtrlRequest method 24 over DP 152).
|
|
1955
|
+
*
|
|
1956
|
+
* The id is the device's own, as {@link VACUUM_CLEAN_MEMBERS.scenes} reports it — `VacuumScene.id`
|
|
1957
|
+
* off the `SceneResponse` on DP 180. A scene the device reports invalid stays reportable and running
|
|
1958
|
+
* it is still a well-formed request; `VacuumScene.invalidReason` says why the device will refuse.
|
|
1959
|
+
*
|
|
1960
|
+
* Frame shape is byte-proven against the shared outer `ModeCtrlRequest`, and method 24 has been
|
|
1961
|
+
* WATCHED: run on a T2351, it started the named scene.
|
|
1962
|
+
*/
|
|
1963
|
+
readonly startScene: import("./members.js").MethodMember<(sceneId: number) => Promise<void>> & {
|
|
1964
|
+
available: (ctx: import("./types.js").CommandContext) => boolean;
|
|
1965
|
+
};
|
|
1966
|
+
/**
|
|
1967
|
+
* Clean the named rooms of a named map (ModeCtrlRequest method 1 over DP 152).
|
|
1968
|
+
*
|
|
1969
|
+
* `mapId` has no default and that is deliberate: room ids are per map, so assuming the map a
|
|
1970
|
+
* single-floor home would have sends a two-floor home's ids against the wrong floor. `SceneInfo.mapid`
|
|
1971
|
+
* on DP 180 and a scheduled rooms-clean's `map_id` are the two real map ids the device reports.
|
|
1972
|
+
*
|
|
1973
|
+
* `cleanTimes` is how many passes to make over the set; rooms with no `order` are visited in the
|
|
1974
|
+
* order given.
|
|
1975
|
+
*
|
|
1976
|
+
* Frame shape is byte-proven against the shared outer `ModeCtrlRequest`, and method 1 has been
|
|
1977
|
+
* WATCHED: run on a T2351, it cleaned the rooms named.
|
|
1978
|
+
*/
|
|
1979
|
+
readonly cleanRooms: import("./members.js").MethodMember<(mapId: number, rooms: readonly VacuumRoomTarget[], cleanTimes?: number) => Promise<void>> & {
|
|
1980
|
+
available: (ctx: import("./types.js").CommandContext) => boolean;
|
|
1981
|
+
};
|
|
1982
|
+
/**
|
|
1983
|
+
* Clean the given rectangles of a named map (ModeCtrlRequest method 2 over DP 152).
|
|
1984
|
+
*
|
|
1985
|
+
* Corners are SIGNED centimetres in the map's own frame, whose origin sits wherever the robot first
|
|
1986
|
+
* mapped from — negative coordinates are ordinary and are ZigZag-encoded, not written as plain
|
|
1987
|
+
* varints. Same `mapId` reasoning as {@link VACUUM_CLEAN_MEMBERS.cleanRooms}, and the same evidence:
|
|
1988
|
+
* method 2 was run on a T2351 and cleaned the rectangles given.
|
|
1989
|
+
*/
|
|
1990
|
+
readonly cleanZones: import("./members.js").MethodMember<(mapId: number, zones: readonly VacuumZoneTarget[]) => Promise<void>> & {
|
|
1991
|
+
available: (ctx: import("./types.js").CommandContext) => boolean;
|
|
1992
|
+
};
|
|
1944
1993
|
};
|
|
1945
1994
|
/** `vacuum_clean` — core RoboVac scalar state + decoded activity: power, activity, volume, battery. */
|
|
1946
1995
|
export declare const VACUUM_CLEAN: CapabilityModule;
|
|
@@ -26,3 +26,27 @@ export interface ParamDef {
|
|
|
26
26
|
export declare const SECURITY_PARAMS: Record<number, ParamDef>;
|
|
27
27
|
/** RoboVac Tuya DP space (ids ~150-180), from get_product_data_point. */
|
|
28
28
|
export declare const CLEAN_PARAMS: Record<number, ParamDef>;
|
|
29
|
+
/**
|
|
30
|
+
* eufy Smart Display (T87Ax) param space — ids 8001-8006.
|
|
31
|
+
*
|
|
32
|
+
* Its own table rather than a corner of {@link SECURITY_PARAMS}: nothing in the 8000s carries a security
|
|
33
|
+
* meaning, so reading these ids there would decode a future security param assigned in this range as
|
|
34
|
+
* whatever it means on a camera.
|
|
35
|
+
*
|
|
36
|
+
* Every id here was reported by a live T87A0 (captured 2026-09-04). That the device SENT an id is what
|
|
37
|
+
* earns it a place in this table; the provenance label beside each one rates something narrower — how far
|
|
38
|
+
* its NAME is trusted. `modelName` and `modelCode` are `mega`, their values matching what the cloud
|
|
39
|
+
* record already carried. `battery` is `verified`: the id is real and the reading consistent, but the
|
|
40
|
+
* name came from the maintainer's own knowledge of the hardware rather than from the cloud data-point
|
|
41
|
+
* list, and `"100"` fits brightness, volume or charge equally.
|
|
42
|
+
*
|
|
43
|
+
* A dictionary entry is what makes a param readable by name off `getProperties()`. `capabilities/display.ts`
|
|
44
|
+
* decides separately which of them reach the typed surface, and only `battery` does.
|
|
45
|
+
*
|
|
46
|
+
* **8002 (`"1"`) and 8004 (a serial-shaped string) are absent, deliberately.** Neither meaning is
|
|
47
|
+
* legible from one value: `1` fits any enum or flag, and a serial could be the display's own or the
|
|
48
|
+
* station's it is bound to. They arrive as `unknown_8002` / `unknown_8004`, which is the measure of this
|
|
49
|
+
* list: it holds what is unknown, not what is unknowable. What would settle them: the vendor app's own
|
|
50
|
+
* display settings screen, one control at a time, params diffed after each.
|
|
51
|
+
*/
|
|
52
|
+
export declare const DISPLAY_PARAMS: Record<number, ParamDef>;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import type { Codec } from "./types.js";
|
|
15
15
|
import { type ParamDef } from "./param-dictionary.js";
|
|
16
16
|
/** The param id spaces this SDK models. */
|
|
17
|
-
export type ParamNamespace = "security" | "clean" | "life" | "print";
|
|
17
|
+
export type ParamNamespace = "security" | "clean" | "life" | "print" | "display";
|
|
18
18
|
/** Look up a param def in the given namespace. */
|
|
19
19
|
export declare function paramDef(ns: ParamNamespace, paramType: number): ParamDef | undefined;
|
|
20
20
|
/** The param namespace a device's ids live in, from its codec, via the module-local `NAMESPACE_BY_CODEC` table. */
|
package/dist/model/types.d.ts
CHANGED
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
*
|
|
29
29
|
* `display` is the T87Ax Smart Display line — its own codec because its `device_type` collides with
|
|
30
30
|
* the security residual range (confirmed live, 2026-09-04: it connects over secure MQTT with no
|
|
31
|
-
* `p2p_did`, never P2P).
|
|
32
|
-
*
|
|
33
|
-
* targets it
|
|
34
|
-
*
|
|
31
|
+
* `p2p_did`, never P2P). It owns its own param namespace (ids 8001-8006) and its own product line, so
|
|
32
|
+
* no other line's capability can attach to it — see `namespaceForCodec` and `CODEC_LINE`. The `display`
|
|
33
|
+
* capability targets it and reads the charge; no screen/audio/assistant param has been observed, so
|
|
34
|
+
* those are absent rather than deferred.
|
|
35
35
|
*/
|
|
36
36
|
export type Codec = "station" | "camera" | "sensor" | "lock" | "keypad" | "vacuum" | "mower" | "light" | "printer" | "display";
|
|
37
37
|
/**
|
|
@@ -39,7 +39,7 @@ export type Codec = "station" | "camera" | "sensor" | "lock" | "keypad" | "vacuu
|
|
|
39
39
|
* it maps to a {@link CapabilityModule} that owns its property schema. Extend this union as
|
|
40
40
|
* new capabilities are modelled — adding one never requires a subclass.
|
|
41
41
|
*/
|
|
42
|
-
export type Capability = "video" | "snapshot" | "motion" | "person_detection" | "battery" | "light" | "ptz" | "doorbell" | "contact" | "leak" | "smoke" | "co" | "siren" | "lock" | "keypad" | "arming" | "storage" | "rtsp" | "camera" | "audio" | "vacuum_clean" | "vacuum_dock" | "suction" | "locate" | "smart_light" | "info";
|
|
42
|
+
export type Capability = "video" | "snapshot" | "motion" | "person_detection" | "battery" | "light" | "ptz" | "doorbell" | "contact" | "leak" | "smoke" | "co" | "siren" | "lock" | "keypad" | "arming" | "storage" | "rtsp" | "camera" | "audio" | "vacuum_clean" | "vacuum_dock" | "suction" | "locate" | "smart_light" | "display" | "info";
|
|
43
43
|
/** Value type of a property. */
|
|
44
44
|
export type PropertyValueType = "bool" | "number" | "string" | "enum";
|
|
45
45
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mega-yfue/eufy-sdk",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.6",
|
|
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",
|