@mega-yfue/eufy-sdk 0.6.0-beta.46 → 0.6.0-beta.47

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.
@@ -128,9 +128,9 @@ export declare const CELL_PARAMS: readonly number[];
128
128
  */
129
129
  export declare function isChargingState(v: string | number | boolean): boolean;
130
130
  /**
131
- * The published `battery` table: the full camera surface, minus every member on the `sensor` codec —
132
- * a sensor's 1101 is a non-cell sentinel and it has none of the camera power reads, so it exposes no
133
- * battery entity (see {@link notOnSensor}). Every getter, setter and description derives from this.
131
+ * The published `battery` table: the full camera surface, minus every member but `batteryLow` on the
132
+ * `sensor` codec — a sensor's 1101 is a non-cell sentinel and it has none of the camera power reads, so
133
+ * it exposes its low-battery flag alone (see {@link notOnSensor}). Every getter, setter and description derives from this.
134
134
  *
135
135
  * Exported but NOT published: each entry states its wire id and the evidence it was confirmed on,
136
136
  * which the reference site does not carry.
@@ -364,6 +364,22 @@ export declare const BATTERY_MEMBERS: {
364
364
  readonly unexposed: true;
365
365
  readonly description: string;
366
366
  };
367
+ /**
368
+ * A sensor's battery is low. The app reads the entry sensor's 1552 and the motion sensor's 1601 into the
369
+ * same field (`sensor_is_low_power`, `asBoolean`), so one member reads whichever the sensor reports.
370
+ * Present on the `sensor` codec only: a camera or a lock reports a level instead.
371
+ */
372
+ readonly batteryLow: {
373
+ readonly param: 1552;
374
+ readonly readAliases: readonly [{
375
+ readonly paramType: 1601;
376
+ }];
377
+ readonly type: "bool";
378
+ readonly kind: "boolean";
379
+ readonly provenance: "verified";
380
+ readonly available: (ctx: AvailabilityContext) => boolean;
381
+ readonly description: "Sensor battery low (1552 entry sensor, 1601 motion sensor; sensor_is_low_power).";
382
+ };
367
383
  };
368
384
  export declare const BATTERY: CapabilityModule;
369
385
  /**
@@ -49,7 +49,7 @@ export declare const CAMERA_CMD: {
49
49
  * (1013). (Some models omit full colour; enum in {@link NightVision}.)
50
50
  */
51
51
  readonly NIGHT_VISION_TYPE: 1277;
52
- /** T8442 infrared night vision on/off: direct L1 int-string, hardware verified (0/1). */
52
+ /** Night vision on a device reporting 2002: direct level-1 [channel][value]. */
53
53
  readonly IC_NIGHT_VISION_TYPE: 1013;
54
54
  /**
55
55
  * Push-notification STYLE — how much a detection push carries: text alone, a thumbnail, or text
@@ -170,17 +170,19 @@ export declare const SoundDetectionType: {
170
170
  /** A sound-detection type — the value side of {@link SoundDetectionType}. */
171
171
  export type SoundDetectionTypeValue = (typeof SoundDetectionType)[keyof typeof SoundDetectionType];
172
172
  /**
173
- * Night-vision mode: 0=Off, 1=Infrared (the app shows "B&W Auto"), 2=FullColor ("Color"). Use
174
- * `NightVision.FullColor` etc. with `setNightVision` / `setProperty(sn,"nightVision",…)`. Some models
175
- * omit `FullColor`.
173
+ * Night-vision mode: 0=Off, 1=Infrared (the app shows "B&W Auto"), 2=FullColor ("Color"), 3=InfraredOn.
174
+ * Use `NightVision.FullColor` etc. with `setNightVision` / `setProperty(sn,"nightVision",…)`. Each model
175
+ * offers a subset.
176
176
  */
177
177
  export declare const NightVision: {
178
178
  /** Off — never use infrared. */
179
179
  readonly Off: 0;
180
- /** Infrared / "B&W Auto" — black-and-white night vision. */
180
+ /** Infrared / "B&W Auto" — black-and-white night vision, switched on when it gets dark. */
181
181
  readonly Infrared: 1;
182
182
  /** Full colour night vision (models with a spotlight / starlight sensor). */
183
183
  readonly FullColor: 2;
184
+ /** Infrared held on — black-and-white night vision, not switched by the light level. */
185
+ readonly InfraredOn: 3;
184
186
  };
185
187
  /** A night-vision mode — the value side of {@link NightVision}. */
186
188
  export type NightVisionValue = (typeof NightVision)[keyof typeof NightVision];
@@ -261,8 +263,8 @@ export type CameraActions = Surface<typeof CAMERA_MEMBERS> & {
261
263
  /** Power the camera off. */
262
264
  off(): Promise<void>;
263
265
  };
264
- /** T8442 has a binary night-vision wire, unlike cameras with the three-mode 1277 control. */
265
- declare function isT8442(ctx: AvailabilityContext): boolean;
266
+ /** A device that reports its night vision on 2002 and not on 1277. */
267
+ declare function readsNightVisionOn2002(ctx: AvailabilityContext): boolean;
266
268
  /** A C30/C31 has reported no 1716 and no doorbell LED write was tried on it, so it keeps 1045. */
267
269
  declare const doorbellLed: (ctx: AvailabilityContext) => boolean;
268
270
  /**
@@ -436,16 +438,7 @@ export declare const CAMERA_MEMBERS: {
436
438
  readonly description: string;
437
439
  readonly write: (v: string | number | boolean, ctx: CommandContext) => Command | undefined;
438
440
  };
439
- /**
440
- * Three modes, and `FullColor` is the conditional one: a model without a spotlight or starlight
441
- * sensor omits it, and the wire accepts the value regardless — the device's own reported set is the
442
- * only statement of which of the three it has. `coerceEnumValue` rejects a value outside
443
- * {@link NightVision} rather than coercing it. The payload key on the wire is `night_sion`.
444
- *
445
- * 1277 carries more than these three on some models: the V6 app's per-model mappings put modes on
446
- * 3, 5, 6 and 8 as well, and which model takes which mapping is not in the app bundle. A reported value
447
- * outside the published options reads as `undefined` rather than as an unnamed number.
448
- */
441
+ /** Modes come from the thing description (`thing`); unlisted values read as `undefined`. */
449
442
  readonly nightVision: {
450
443
  readonly param: 1277;
451
444
  readonly type: "enum";
@@ -454,18 +447,17 @@ export declare const CAMERA_MEMBERS: {
454
447
  readonly 0: "Off";
455
448
  readonly 1: "Infrared";
456
449
  readonly 2: "Full Color";
450
+ readonly 3: "Infrared On";
457
451
  };
458
- readonly enumValuesFor: (ctx: AvailabilityContext) => {
459
- 0: string;
460
- 1: string;
461
- } | undefined;
452
+ readonly thing: readonly ["nightvision_type_new", "nightvision_type"];
462
453
  readonly provenance: "verified";
463
454
  readonly available: typeof isCameraCodec;
464
455
  readonly readAvailable: (ctx: AvailabilityContext) => boolean;
465
456
  readonly readAliases: readonly [{
466
457
  readonly paramType: 2002;
467
- readonly available: typeof isT8442;
458
+ readonly available: typeof readsNightVisionOn2002;
468
459
  }];
460
+ readonly coerce: (raw: string | number | boolean) => number;
469
461
  readonly description: string;
470
462
  readonly write: (v: string | number | boolean, ctx: CommandContext) => Command | undefined;
471
463
  };
@@ -1,52 +1,42 @@
1
1
  import { type Surface } from "./members.js";
2
- import type { CapabilityModule } from "./types.js";
2
+ import type { AvailabilityContext, CapabilityModule } from "./types.js";
3
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).
4
+ * The entry sensor's own command/param ids, each the app's own (`APP_CMD_*` in the product's settings
5
+ * bundle) and reported by a real sensor.
7
6
  */
8
7
  export declare const CONTACT_CMD: {
9
- /** Alarm sound/tone selection (app `APP_CMD_ALARM_SOUND_TYPE`). See {@link EntryAlarmTone}. */
8
+ /** Contact state (`APP_CMD_ENTRY_SENSOR_STATUS`, identifier `sensor_door_status`). */
9
+ readonly STATUS: 1550;
10
+ /** Removed from its mount (`APP_CMD_DEV_DISASSEMBLE`, identifier `sensor_disassemble_status`). */
11
+ readonly TAMPER: 61015;
12
+ /** Bypassed by the alarm (`APP_CMD_DEV_ENTRY_BYPASS`, identifier `sensor_door_bypass_status`). */
13
+ readonly BYPASS: 61016;
14
+ /** Left-open alert (`APP_CMD_SENSOR_OPEN_STATUS_ALERT`, identifier `sensor_door_open_status_alert_config`). */
15
+ readonly OPEN_ALERT: 1290;
16
+ /** Daily state check (`APP_CMD_SENSOR_DOOR_DAILY_CHECK`, identifier `sensor_door_daily_check_status_config`). */
17
+ readonly DAILY_CHECK: 1291;
18
+ /** Alarm tone (`APP_CMD_ALARM_SOUND_TYPE`, identifier `device_alarm_sound_type`). */
10
19
  readonly ALARM_SOUND_TYPE: 1507;
11
- /** Alarm volume (app `APP_CMD_ALARM_VOLUME_VALUE`). A device level 1-26, not a percentage. */
20
+ /** Alarm volume (`APP_CMD_ALARM_VOLUME_VALUE`, identifier `alarm_volume_value`). */
12
21
  readonly ALARM_VOLUME: 1508;
13
22
  };
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
- */
23
+ /** The left-open alert delays the app offers, in minutes (`sensor_door_open_status_alert_config`). */
24
+ declare const OPEN_ALERT_MINUTES: readonly [5, 10, 15, 30, 60];
25
+ /** Bound entry-sensor controls — the object returned by `dev.contact()`, derived from `CONTACT_MEMBERS`. */
35
26
  export type ContactActions = Surface<typeof CONTACT_MEMBERS>;
36
27
  /**
37
- * Every `contact` feature, declared once. `contact` (1550) is a verified read; the built-in alarm tone (1507) and volume (1508) are verified writes captured live on a T90E0.
28
+ * Every `contact` feature, declared once, each on the identifier the product's thing description names
29
+ * and the param the app's settings bundle reads it from.
38
30
  *
39
- * Exported but NOT published: each entry states its wire id and the evidence it was confirmed on,
40
- * which the reference site does not carry.
31
+ * Exported but NOT published: each entry states its wire id and its evidence, which the reference site
32
+ * does not carry.
41
33
  * @internal
42
34
  */
43
35
  export declare const CONTACT_MEMBERS: {
44
36
  /**
45
- * The headline read: `true` when the door or window is open. Polarity is the V6 app's own
46
- * `"1".equals(e)` — see `contactOpen`, which normalises every inbound source through one
47
- * predicate so the poll, the push and the station notify cannot disagree about what open means.
48
- * Reporting 1550 is also this capability's detection evidence, so a device with this getter is
49
- * confirmed to be a contact sensor.
37
+ * The headline read: `true` when the door or window is open. Every inbound source normalises through
38
+ * `contactOpen`, so the poll, the push and the station notify cannot disagree about what open means.
39
+ * Reporting 1550 is also this capability's detection evidence.
50
40
  */
51
41
  readonly open: {
52
42
  readonly param: 1550;
@@ -54,43 +44,128 @@ export declare const CONTACT_MEMBERS: {
54
44
  readonly type: "bool";
55
45
  readonly kind: "boolean";
56
46
  readonly provenance: "verified";
57
- readonly description: "Contact state, true=open (verified: param 1550 entry-sensor contact).";
47
+ readonly description: "Contact state, true=open (1550, sensor_door_status).";
48
+ };
49
+ /** The sensor was removed from its mount. Reported by a T8900; the meaning of a set value is the product bundle's. */
50
+ readonly tampered: {
51
+ readonly param: 61015;
52
+ readonly type: "bool";
53
+ readonly kind: "boolean";
54
+ readonly provenance: "apk";
55
+ readonly description: "Removed from its mount (61015, sensor_disassemble_status).";
56
+ };
57
+ /** The alarm currently skips this sensor. Reported by a T8900; the meaning of a set value is the product bundle's. */
58
+ readonly bypassed: {
59
+ readonly param: 61016;
60
+ readonly type: "bool";
61
+ readonly kind: "boolean";
62
+ readonly provenance: "apk";
63
+ readonly description: "Bypassed by the alarm (61016, sensor_door_bypass_status).";
64
+ };
65
+ /**
66
+ * The left-open alert config, whole as the sensor stores it (base64 JSON). Its two fields are the
67
+ * members below; both are set together by `setOpenAlert`, since one frame carries both.
68
+ */
69
+ readonly openAlertConfig: {
70
+ readonly param: 1290;
71
+ readonly type: "string";
72
+ readonly kind: "text";
73
+ readonly provenance: "verified";
74
+ readonly unexposed: true;
75
+ readonly writtenElsewhere: true;
76
+ readonly description: "Left-open alert config, base64 JSON {door_enable,door_time_point} (1290).";
77
+ };
78
+ /** Whether a notification fires when the door stays open longer than {@link CONTACT_MEMBERS.openAlertMinutes}. */
79
+ readonly openAlert: {
80
+ readonly readsFrom: "openAlertConfig";
81
+ readonly type: "bool";
82
+ readonly kind: "boolean";
83
+ readonly provenance: "verified";
84
+ readonly decode: (raw: unknown) => boolean | undefined;
85
+ readonly description: "Left-open alert on (1290 door_enable). Set with setOpenAlert.";
86
+ };
87
+ /** How long the door may stay open before the alert fires: one of 5, 10, 15, 30 or 60 minutes. */
88
+ readonly openAlertMinutes: {
89
+ readonly readsFrom: "openAlertConfig";
90
+ readonly type: "number";
91
+ readonly kind: "scalar";
92
+ readonly provenance: "verified";
93
+ readonly decode: (raw: unknown) => number | undefined;
94
+ readonly description: "Left-open alert delay, minutes: 5, 10, 15, 30 or 60 (1290 door_time_point).";
58
95
  };
96
+ /** The daily state check config, whole (base64 JSON); its fields are the members below. */
97
+ readonly dailyCheckConfig: {
98
+ readonly param: 1291;
99
+ readonly type: "string";
100
+ readonly kind: "text";
101
+ readonly provenance: "verified";
102
+ readonly unexposed: true;
103
+ readonly writtenElsewhere: true;
104
+ readonly description: "Daily check config, base64 JSON {door_enable,door_time_interval} (1291).";
105
+ };
106
+ /** Whether the sensor's state is notified at each of {@link CONTACT_MEMBERS.dailyCheckTimes}. */
107
+ readonly dailyCheck: {
108
+ readonly readsFrom: "dailyCheckConfig";
109
+ readonly type: "bool";
110
+ readonly kind: "boolean";
111
+ readonly provenance: "verified";
112
+ readonly decode: (raw: unknown) => boolean | undefined;
113
+ readonly description: "Daily state check on (1291 door_enable). Set with setDailyCheck.";
114
+ };
115
+ /** The times of day the state is notified, `HH:MM` comma-separated in the order the sensor holds them. */
116
+ readonly dailyCheckTimes: {
117
+ readonly readsFrom: "dailyCheckConfig";
118
+ readonly type: "string";
119
+ readonly kind: "text";
120
+ readonly provenance: "verified";
121
+ readonly decode: (raw: unknown) => string | undefined;
122
+ readonly description: "Daily check times, HH:MM comma-separated (1291 door_time_interval, minutes since midnight).";
123
+ };
124
+ /**
125
+ * Turn the left-open alert on or off, with its delay. One frame carries both: `1350` SET_PAYLOAD,
126
+ * sub-command 1290, `{door_enable, door_time_point}` — the product's settings bundle's own frame.
127
+ * Verified live on a T8900: param 1290 read back the written value and the app showed it.
128
+ */
129
+ readonly setOpenAlert: import("./members.js").MethodMember<(on: boolean, minutes: (typeof OPEN_ALERT_MINUTES)[number]) => Promise<void>>;
59
130
  /**
60
- * Rejected, not clamped, outside the tone enum: a fire-and-forget write of a bogus tone would look like
61
- * it worked. The wire is a direct-binary scalar `[ch][value][acct]` at signCode 8 — the app's own
62
- * captured frame.
131
+ * Turn the daily state check on or off, with its times of day. One frame carries both: `1350`
132
+ * SET_PAYLOAD, sub-command 1291, `{door_enable, door_time_interval}` with each time as minutes since
133
+ * midnight — the product's settings bundle's own frame.
134
+ * Verified live on a T8900: param 1291 read back the written times and the app showed them.
135
+ */
136
+ readonly setDailyCheck: import("./members.js").MethodMember<(on: boolean, times: readonly string[]) => Promise<void>>;
137
+ /**
138
+ * The built-in alarm tone, offered where the product's description lists it: a sensor may report the
139
+ * param while the app offers no such setting on it. Rejected, not clamped, outside the listed tones.
140
+ * Write: a direct-binary scalar `[ch][value][acct]` at signCode 8, captured live on a T90E0.
63
141
  */
64
142
  readonly alarmSoundType: {
65
143
  readonly param: 1507;
66
144
  readonly type: "enum";
67
145
  readonly kind: "enum";
68
146
  readonly enumValues: Record<number, string>;
147
+ readonly thing: readonly ["device_alarm_sound_type"];
69
148
  readonly provenance: "verified";
70
- readonly requires: readonly [1507];
149
+ readonly available: (ctx: AvailabilityContext) => boolean;
71
150
  readonly args: readonly [{
72
151
  readonly name: "tone";
73
152
  readonly kind: "enum";
74
- readonly description: "Silent (0) or one of the four chimes.";
153
+ readonly description: "Silent (0) or one of the four tones.";
75
154
  }];
76
- readonly description: string;
155
+ readonly description: "Alarm tone (1507, device_alarm_sound_type): 0=None,1=Water,2=Classics,3=Light,4=Ding.";
77
156
  readonly write: (v: string | number | boolean, ctx: import("./types.js").CommandContext) => import("../../index.js").Command | undefined;
78
157
  };
79
158
  /**
80
- * `1350` SET_PAYLOAD, `mChannel` = the device channel, `mValue3` 0, payload carrying the channel and a
81
- * transaction stamp — the byte-shape of the app's own captured frame. Out of range is refused rather
82
- * than clamped: the app's slider has no values outside it, so one is a caller error, not a nudge.
83
- *
84
- * Level-2 only, though the `mValue3` 0 would allow `"auto"`: an entry sensor's session IS its
85
- * HomeBase's, which always holds a key — the second of `setPayload`'s two conditions, not an oversight
86
- * of the first.
159
+ * The built-in alarm volume, a device level 1-26, offered where the product's description lists it.
160
+ * Write: `1350` SET_PAYLOAD with `mChannel` the device channel, `mValue3` 0, payload `{channel, volume,
161
+ * transaction}` — the app's own captured frame on a T90E0. Out of range is refused, not clamped.
87
162
  */
88
163
  readonly alarmVolume: {
89
164
  readonly param: 1508;
90
165
  readonly type: "number";
91
166
  readonly kind: "scalar";
92
167
  readonly provenance: "verified";
93
- readonly requires: readonly [1508];
168
+ readonly available: (ctx: AvailabilityContext) => boolean;
94
169
  readonly min: 1;
95
170
  readonly max: 26;
96
171
  readonly args: readonly [{
@@ -98,13 +173,12 @@ export declare const CONTACT_MEMBERS: {
98
173
  readonly kind: "scalar";
99
174
  readonly min: 1;
100
175
  readonly max: 26;
101
- readonly description: "A device level, not a percentage.";
176
+ readonly description: "A device level.";
102
177
  }];
103
- readonly description: string;
178
+ readonly description: "Alarm volume (1508, alarm_volume_value), a device level 1-26, not a percentage.";
104
179
  readonly write: (v: string | number | boolean, ctx: import("./types.js").CommandContext) => import("../../index.js").Command | undefined;
105
180
  };
106
181
  };
107
- /**
108
- * `contact` — entry/door-window sensor. `contact` (1550) is verified; the built-in alarm tone (1507) and volume (1508) are verified writes captured live on a T90E0.
109
- */
182
+ /** `contact` — entry (door/window) sensor. */
110
183
  export declare const CONTACT: CapabilityModule;
184
+ export {};
@@ -11,7 +11,6 @@ import { type CapabilityDescriptor } from "./manifest.js";
11
11
  import type { CapabilityModule, EventMapping, CapabilityEvent, DecodedState, InboundSignal, CommandContext, AvailabilityContext } from "./types.js";
12
12
  import type { Command } from "../../core/contracts.js";
13
13
  export { RtspRecordingMode, type RtspRecordingModeValue, type RtspAuthScheme } from "./rtsp.js";
14
- export { EntryAlarmTone, type EntryAlarmToneValue } from "./contact.js";
15
14
  export { SirenVolume, type SirenVolumeValue, SirenAlarmDuration, type SirenAlarmDurationValue } from "./siren.js";
16
15
  /**
17
16
  * Ask what a bound capability can be told to change but can never report back, and what it reports without
@@ -414,7 +413,7 @@ export interface DeviceActionMap {
414
413
  motion: MotionActions;
415
414
  /** Entry (door/window) sensor: reads `open`, `alarmSoundType`, `alarmVolume`; writes `setAlarmSoundType`, `setAlarmVolume` (present when the sensor reports the alarm params). */
416
415
  contact: ContactActions;
417
- /** Water-leak / freeze sensor reads (read-only): `leakDetected`. */
416
+ /** Water and freeze sensor reads (read-only): `leakDetected`, `lowTemperature`, `lowTemperatureThreshold`. */
418
417
  leak: LeakActions;
419
418
  /** Smoke-detector reads (read-only): `smokeDetected`. */
420
419
  smoke: SmokeActions;
@@ -1,7 +1,21 @@
1
1
  import { type Surface } from "./members.js";
2
2
  import type { CapabilityModule } from "./types.js";
3
3
  /**
4
- * Every `leak` feature, declared once — the property schema and the evidence-gated getters derive from here.
4
+ * The water sensor's own param ids, each the app's own (`APP_CMD_*` in the product's settings bundle,
5
+ * the same number in every bundle that defines it).
6
+ */
7
+ export declare const LEAK_PARAM: {
8
+ /** Water detected (`APP_CMD_WATER_SENSOR_WATER_STATE`, identifier `sensor_water_status`). */
9
+ readonly WATER: 1820;
10
+ /** Temperature below the threshold (`APP_CMD_WATER_SENSOR_TEMPERATE_LOW`, `sensor_temperature_low_status`). */
11
+ readonly LOW_TEMPERATURE: 1822;
12
+ /** Low-temperature alarm threshold, °F (`APP_CMD_WATER_SENSOR_TEMPERATURE_ALARM`). */
13
+ readonly LOW_TEMPERATURE_THRESHOLD: 1873;
14
+ };
15
+ /**
16
+ * Every `leak` feature, declared once. The params are read as the app's settings bundle reads them
17
+ * (`asBoolean` for the two states, `asInt` for the threshold); no water sensor has been read yet, so
18
+ * each getter is present only where a sensor reports its param.
5
19
  *
6
20
  * Exported but NOT published: each entry states its wire id and the evidence it was confirmed on,
7
21
  * which the reference site does not carry.
@@ -9,23 +23,47 @@ import type { CapabilityModule } from "./types.js";
9
23
  */
10
24
  export declare const LEAK_MEMBERS: {
11
25
  /**
12
- * The alarm flag, modelled as state even though the sensor announces a leak as a PUSH EVENT rather
13
- * than by holding a param — so 1560 is a `guessed` placeholder and the evidence gate will normally
14
- * leave this getter uninstalled. The push event is the reliable channel for a leak; this read is
15
- * here so the flag has a home once a capture pins a real id.
26
+ * Water is detected. The app's own `event_sensor_water_detected_notify` is this param changing, so
27
+ * the state and the alert are one fact.
16
28
  */
17
29
  readonly leakDetected: {
18
- readonly param: 1560;
30
+ readonly param: 1820;
31
+ readonly type: "bool";
32
+ readonly kind: "boolean";
33
+ readonly provenance: "apk";
34
+ readonly description: "Water detected (1820, sensor_water_status).";
35
+ };
36
+ /** The temperature is below {@link LEAK_MEMBERS.lowTemperatureThreshold}: the freeze alarm. */
37
+ readonly lowTemperature: {
38
+ readonly param: 1822;
19
39
  readonly type: "bool";
20
40
  readonly kind: "boolean";
21
- readonly provenance: "guessed";
22
- readonly description: string;
41
+ readonly provenance: "apk";
42
+ readonly description: "Temperature below the alarm threshold (1822, sensor_temperature_low_status).";
43
+ };
44
+ /**
45
+ * The temperature, in °F, below which the freeze alarm fires: one of 32, 33, 35, 37 or 40 as the
46
+ * product's description lists them. The write is the bundle's `1350` SET_PAYLOAD on 1873, not yet run
47
+ * on a device, so no setter is installed.
48
+ */
49
+ readonly lowTemperatureThreshold: {
50
+ readonly param: 1873;
51
+ readonly type: "number";
52
+ readonly kind: "enum";
53
+ readonly enumValues: {
54
+ readonly 32: "32°F";
55
+ readonly 33: "33°F";
56
+ readonly 35: "35°F";
57
+ readonly 37: "37°F";
58
+ readonly 40: "40°F";
59
+ };
60
+ readonly thing: readonly ["sensor_low_temperature_alarm_threshold"];
61
+ readonly provenance: "apk";
62
+ readonly unverified: true;
63
+ readonly description: "Freeze alarm threshold, °F: 32, 33, 35, 37 or 40 (1873, sensor_low_temperature_alarm_threshold).";
23
64
  };
24
65
  };
25
- /** Bound leak-sensor reads — the object returned by `dev.leak()`. Read-only. */
66
+ /** Bound water-sensor reads — the object returned by `dev.leak()`. Read-only. */
26
67
  export type LeakActions = Surface<typeof LEAK_MEMBERS>;
27
- /**
28
- * `leak` — water/leak (and freeze) sensor. Alarm flag is a placeholder — the T8920 Water & Freeze
29
- * sensor reports leak via a push event, not a stable param id.
30
- */
68
+ /** `leak` — water and freeze sensor (T8920, T90F0). */
31
69
  export declare const LEAK: CapabilityModule;
@@ -617,7 +617,7 @@ export declare class P2PCommandRouter {
617
617
  * Resolve a scalar `"set-param"` intent to a concrete P2P frame — the ONE place that maps a
618
618
  * capability's *what* (param + value + {@link ScalarForm}) to the *how* (encryption level + wire):
619
619
  * `"auto"` defers the level to {@link sendBySessionLevel} — the ONE decision point — while
620
- * `"int-string"` pins L1 and `"direct-binary"` pins L2.
620
+ * `"int-string"` and `"int-pair"` pin L1 and `"direct-binary"` pins L2.
621
621
  */
622
622
  private resolveScalarParam;
623
623
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mega-yfue/eufy-sdk",
3
- "version": "0.6.0-beta.46",
3
+ "version": "0.6.0-beta.47",
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",