@mega-yfue/eufy-sdk 0.2.0-beta.3 → 0.2.0-beta.5

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.
@@ -550,7 +550,7 @@ export { HubAlarmTone, type HubAlarmToneValue } from "./siren.js";
550
550
  * RoboVac activity and clean type are the declared returns of the public `dev.vacuumClean()` getters,
551
551
  * so both unions are published.
552
552
  */
553
- export type { VacuumActivity, VacuumCleanType, CarpetStrategy, CleanExtent } from "./vacuum-clean.js";
553
+ export type { VacuumActivity, VacuumCleanType, CarpetStrategy, CleanExtent, VacuumRoomTarget, VacuumZoneTarget, } from "./vacuum-clean.js";
554
554
  /** The lists those unions are taken from — published because each union names its own. */
555
555
  export { VACUUM_ACTIVITIES, VACUUM_CLEAN_TYPES, CARPET_STRATEGIES, CLEAN_EXTENTS, MOP_LEVELS } from "./vacuum-clean.js";
556
556
  export { SuctionLevel, suctionLevelName, type SuctionLevelValue } from "./suction.js";
@@ -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
- /** Build a scene clean, which needs only the scene's own id. @internal */
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;
@@ -188,6 +188,22 @@ export type LiveTrace =
188
188
  | {
189
189
  phase: "path-stale";
190
190
  silentMs: number;
191
+ }
192
+ /**
193
+ * A stream received nothing on its own channel for the stall window, and what was done about it.
194
+ *
195
+ * A station that switches to a sibling leaves the stream it was serving with no frames, no error and no
196
+ * stop, so this silence is the only statement that it happened. `reasserted` re-issued the media start,
197
+ * which is the repair; `declined` left the channel alone because nothing is attached to this pull and
198
+ * taking the station back would take it from a camera someone is watching.
199
+ *
200
+ * Media still arriving means this never fires, so a picture that stopped advancing while this is silent
201
+ * stopped for a reason upstream of the station's attention.
202
+ */
203
+ | {
204
+ phase: "channel-silent";
205
+ silentMs: number;
206
+ outcome: "reasserted" | "declined";
191
207
  };
192
208
  /**
193
209
  * Record one startup observation at debug level.
@@ -34,11 +34,22 @@ export declare function openLiveStream(session: P2PSession, opts?: LiveStreamOpt
34
34
  * The header states the stream's geometry when the capture started, and a stream that reconfigures
35
35
  * mid-burst leaves it describing something the returned bytes contradict; the return value describes an
36
36
  * image, so the image is its source of truth.
37
+ *
38
+ * The consumer is detached the moment the collected run is complete, and the decode that follows holds no
39
+ * station: it works on bytes already in memory. A station serves one camera at a time and the SDK refuses a
40
+ * second channel on one that is busy, so a still that kept its pull attached across its own decode would deny
41
+ * that station to every live request for the length of an FFmpeg run — measured on a real base as a live
42
+ * request refused 370ms after the still it was waiting on had already collected everything it needed.
43
+ *
44
+ * `signal` ends the collection itself, not only the wait for it, and rejects with the signal's own reason
45
+ * because the abandonment is the caller's fact and not a failure of the source. It reaches only the
46
+ * collection: past that the station is already free, so there is nothing left for it to release.
37
47
  */
38
48
  export declare function captureSnapshotFromShared(source: SharedLiveSource, opts?: {
39
49
  timeoutMs?: number;
40
50
  collectMs?: number;
41
51
  skipKeyframes?: number;
52
+ signal?: AbortSignal;
42
53
  logger?: Logger;
43
54
  ffmpegLevel?: FfmpegLevel;
44
55
  ffmpegPath?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mega-yfue/eufy-sdk",
3
- "version": "0.2.0-beta.3",
3
+ "version": "0.2.0-beta.5",
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",