@mega-yfue/eufy-sdk 0.6.0-beta.24 → 0.6.0-beta.26
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/core/contracts.d.ts +2 -0
- package/dist/index.js +38 -22
- package/dist/index.js.map +2 -2
- package/dist/model/capabilities/access.d.ts +3 -2
- package/dist/model/capabilities/arming.d.ts +2 -1
- package/dist/model/capabilities/battery.d.ts +1 -1
- package/dist/model/capabilities/camera.d.ts +4 -0
- package/dist/model/capabilities/members.d.ts +3 -1
- package/dist/transport/p2p/command-router.d.ts +3 -0
- package/package.json +1 -1
package/dist/core/contracts.d.ts
CHANGED
|
@@ -344,6 +344,8 @@ export type Command = {
|
|
|
344
344
|
cmd: number;
|
|
345
345
|
value: number;
|
|
346
346
|
channel: number;
|
|
347
|
+
/** `"auto"`: the seal follows the session, level-2 with a key and level-1 without. Absent, level-2 only. */
|
|
348
|
+
form?: Extract<ScalarForm, "auto">;
|
|
347
349
|
}
|
|
348
350
|
/** P2P int-plus-string frame; the transport injects the authenticated account id string. */
|
|
349
351
|
| {
|
package/dist/index.js
CHANGED
|
@@ -3304,8 +3304,8 @@ function setJsonRaw(cmd, data, ctx, channel) {
|
|
|
3304
3304
|
function setPayload(cmd, payload, ctx, mValue3, channel, form) {
|
|
3305
3305
|
return { kind: "set-payload", cmd, payload, channel: channel ?? ctx.channel, mValue3, form };
|
|
3306
3306
|
}
|
|
3307
|
-
function setStationScalar(cmd, value, channel) {
|
|
3308
|
-
return { kind: "p2p-station-scalar", cmd, value, channel };
|
|
3307
|
+
function setStationScalar(cmd, value, channel, form) {
|
|
3308
|
+
return { kind: "p2p-station-scalar", cmd, value, channel, ...form ? { form } : {} };
|
|
3309
3309
|
}
|
|
3310
3310
|
function describeDevice(ctx) {
|
|
3311
3311
|
return `deviceType=${ctx.deviceType ?? "?"} model=${ctx.model ?? "?"} serial=${ctx.serial ?? "?"} channel=${ctx.channel} codec=${ctx.codec}`;
|
|
@@ -3474,12 +3474,13 @@ function describe(description, fn, m) {
|
|
|
3474
3474
|
function reports(requires, ctx) {
|
|
3475
3475
|
return !requires || requires.some((p) => ctx.paramIds.has(p));
|
|
3476
3476
|
}
|
|
3477
|
-
function narrow(type, read, prop) {
|
|
3477
|
+
function narrow(type, read, prop, values) {
|
|
3478
3478
|
if (type === "bool")
|
|
3479
3479
|
return readBool(read, prop);
|
|
3480
3480
|
if (type === "string")
|
|
3481
3481
|
return readStr(read, prop);
|
|
3482
|
-
|
|
3482
|
+
const n = readNum(read, prop);
|
|
3483
|
+
return values && n !== void 0 && !(n in values) ? void 0 : n;
|
|
3483
3484
|
}
|
|
3484
3485
|
function reads(m, ctx) {
|
|
3485
3486
|
return m.realtime === true || sent(m, ctx);
|
|
@@ -3532,7 +3533,9 @@ function bindMembers(members, deps) {
|
|
|
3532
3533
|
if (reported && !m.writeOnly && !m.unexposed) {
|
|
3533
3534
|
const decode = m.decode;
|
|
3534
3535
|
const raw = () => read(prop)?.value ?? (borrowed === void 0 ? void 0 : read(borrowed)?.value);
|
|
3535
|
-
const
|
|
3536
|
+
const { values, dynamic } = resolvedEnum(m, ctx);
|
|
3537
|
+
const domain = (dynamic ? "enum" : m.kind) === "enum" ? values : void 0;
|
|
3538
|
+
const get = decode ? () => decode(raw(), rawDp2, ctx) : () => narrow(m.type, read, prop, domain);
|
|
3536
3539
|
Object.defineProperty(out, name, { get, enumerable: true, configurable: true });
|
|
3537
3540
|
}
|
|
3538
3541
|
if (!m.write || m.unverified || !installs(m, ctx))
|
|
@@ -4802,7 +4805,7 @@ var BATTERY_MEMBERS = cellGated({
|
|
|
4802
4805
|
/**
|
|
4803
4806
|
* 1293 is the READABLE indicator (6445 is write-only/cloud-hidden). Verified live on a T8124R via an
|
|
4804
4807
|
* app-toggle before/after diff: 0 = Battery, 1 = External Solar Panel. Values beyond 0/1 (some models
|
|
4805
|
-
* report 5)
|
|
4808
|
+
* report 5) read as `undefined` — `enumValues` holds only the two that are confirmed.
|
|
4806
4809
|
*
|
|
4807
4810
|
* The write is a `1350` SET_PAYLOAD, inner cmd 1293, `{charge_mode:N}`, `mValue3` 0 (the app uses 0,
|
|
4808
4811
|
* not the cmd id), and the setter accepts a NAME as well as the index the getter answers.
|
|
@@ -4817,7 +4820,7 @@ var BATTERY_MEMBERS = cellGated({
|
|
|
4817
4820
|
requires: [BATTERY_PARAM.POWER_CHARGE],
|
|
4818
4821
|
args: [{ name: "source", kind: "enum", description: "The raw value, or the name `battery`/`external`." }],
|
|
4819
4822
|
...accepts(),
|
|
4820
|
-
description: "Configured power source (1293): 0 = Battery, 1 = External Solar Panel. Verified live on T8124R. The richer raw APP_CMD_SET_POWER_SOURCE blob is surfaced separately as `powerSourceInfo` (6445). Format varies by model (plain int or JSON {power_source:N});
|
|
4823
|
+
description: "Configured power source (1293): 0 = Battery, 1 = External Solar Panel. Verified live on T8124R. The richer raw APP_CMD_SET_POWER_SOURCE blob is surfaced separately as `powerSourceInfo` (6445). Format varies by model (plain int or JSON {power_source:N}); a value beyond 0/1 reads undefined.",
|
|
4821
4824
|
write: (v, ctx) => setPayload(BATTERY_PARAM.POWER_CHARGE, { charge_mode: v === "external" ? 1 : v === "battery" ? 0 : asBool(v) ? 1 : 0 }, ctx, 0, void 0, "auto")
|
|
4822
4825
|
},
|
|
4823
4826
|
/**
|
|
@@ -6199,6 +6202,10 @@ var CAMERA_MEMBERS = {
|
|
|
6199
6202
|
* sensor omits it, and the wire accepts the value regardless — the device's own reported set is the
|
|
6200
6203
|
* only statement of which of the three it has. `coerceEnumValue` rejects a value outside
|
|
6201
6204
|
* {@link NightVision} rather than coercing it. The payload key on the wire is `night_sion`.
|
|
6205
|
+
*
|
|
6206
|
+
* 1277 carries more than these three on some models: the V6 app's per-model mappings put modes on
|
|
6207
|
+
* 3, 5, 6 and 8 as well, and which model takes which mapping is not in the app bundle. A reported value
|
|
6208
|
+
* outside the published options reads as `undefined` rather than as an unnamed number.
|
|
6202
6209
|
*/
|
|
6203
6210
|
nightVision: {
|
|
6204
6211
|
param: CAMERA_CMD.NIGHT_VISION_TYPE,
|
|
@@ -7970,7 +7977,8 @@ var ARMING_CMD = {
|
|
|
7970
7977
|
* was captured on holds a level-2 key and seals it level-2, while an own-session camera that never
|
|
7971
7978
|
* negotiates one carries the same envelope level-1. See `armingCommand`.
|
|
7972
7979
|
*
|
|
7973
|
-
* A T8410C
|
|
7980
|
+
* A T8410C and a T8410 take the mode as a direct frame instead of this envelope; see
|
|
7981
|
+
* {@link DIRECT_ARMING_MODELS} and {@link BROADCAST_ARMING_MODELS}.
|
|
7974
7982
|
*/
|
|
7975
7983
|
SET_ARMING: 1224,
|
|
7976
7984
|
/**
|
|
@@ -8010,7 +8018,7 @@ var ARMING_CMD = {
|
|
|
8010
8018
|
var DEVICE_NOTIFY_FLAG = 8;
|
|
8011
8019
|
var STANDALONE_ACTION_MODELS = /* @__PURE__ */ new Set(["T8170", "T8171"]);
|
|
8012
8020
|
var DIRECT_ARMING_MODELS = /* @__PURE__ */ new Set(["T8410C"]);
|
|
8013
|
-
var
|
|
8021
|
+
var BROADCAST_ARMING_MODELS = /* @__PURE__ */ new Set(["T8410"]);
|
|
8014
8022
|
var STANDALONE_READ_MODELS = /* @__PURE__ */ new Set([...STANDALONE_ACTION_MODELS, "T8400", "T8442", "T8410"]);
|
|
8015
8023
|
function ownAction(read, mode) {
|
|
8016
8024
|
const value = Number(read(`${mode}Action`)?.value);
|
|
@@ -8043,10 +8051,11 @@ function armingCommand(mode, ctx) {
|
|
|
8043
8051
|
if (!ctx.accountName) {
|
|
8044
8052
|
throw new Error(`arming: missing account identity (user_name) [${describeDevice(ctx)}]`);
|
|
8045
8053
|
}
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
|
|
8049
|
-
|
|
8054
|
+
const model = ctx.model ?? "";
|
|
8055
|
+
if (BROADCAST_ARMING_MODELS.has(model)) {
|
|
8056
|
+
return setStationScalar(ARMING_CMD.SET_ARMING, ARMING_MODE_WIRE[mode], STATION_CHANNEL2, "auto");
|
|
8057
|
+
}
|
|
8058
|
+
if (DIRECT_ARMING_MODELS.has(model)) {
|
|
8050
8059
|
return setStationScalar(ARMING_CMD.SET_ARMING, ARMING_MODE_WIRE[mode], ctx.channel);
|
|
8051
8060
|
}
|
|
8052
8061
|
return setPayload(ARMING_CMD.SET_ARMING, { mode_type: ARMING_MODE_WIRE[mode], user_name: ctx.accountName }, ctx, 0, void 0, "auto");
|
|
@@ -8104,7 +8113,7 @@ var ARMING_MEMBERS = {
|
|
|
8104
8113
|
kind: "enum",
|
|
8105
8114
|
enumValues: ARMING_MODE_LABELS,
|
|
8106
8115
|
provenance: "verified",
|
|
8107
|
-
description: "Guard mode (verified: param 1224 = GUARD_MODE, read/write mechanism confirmed). Reads and SETS all 9 modes the app defines \u2014 away/home/schedule/custom1/custom2/custom3/off/geo/disarmed. Three are byte-captured writes and six are live-confirmed (each sent and observed to report its own MODE_SWITCH); see ARMING_MODE_WIRE in arming.ts for the per-value evidence.
|
|
8116
|
+
description: "Guard mode (verified: param 1224 = GUARD_MODE, read/write mechanism confirmed). Reads and SETS all 9 modes the app defines \u2014 away/home/schedule/custom1/custom2/custom3/off/geo/disarmed. Three are byte-captured writes and six are live-confirmed (each sent and observed to report its own MODE_SWITCH); see ARMING_MODE_WIRE in arming.ts for the per-value evidence.",
|
|
8108
8117
|
observation: {
|
|
8109
8118
|
event: "armingModeChanged",
|
|
8110
8119
|
reflects: (value) => ({ param: ARMING_CMD.SET_ARMING, expected: ARMING_MODE_WIRE[armingModeOf(value)] }),
|
|
@@ -14185,7 +14194,7 @@ var Device = class _Device {
|
|
|
14185
14194
|
const spec = this.specByName.get(name);
|
|
14186
14195
|
if (!spec)
|
|
14187
14196
|
continue;
|
|
14188
|
-
const value = spec.raw ? void 0 : narrow(spec.type, (n) => this.state.get(n), name);
|
|
14197
|
+
const value = spec.raw ? void 0 : narrow(spec.type, (n) => this.state.get(n), name, spec.kind === "enum" ? spec.enumValues : void 0);
|
|
14189
14198
|
out.push(value === void 0 ? { property: name } : { property: name, value });
|
|
14190
14199
|
}
|
|
14191
14200
|
return out;
|
|
@@ -22795,7 +22804,7 @@ var P2PCommandRouter = class _P2PCommandRouter {
|
|
|
22795
22804
|
await this.sendSetPayloadEnvelope(sn, cmd.cmd, cmd.payload, cmd.channel, cmd.mValue3, void 0, cmd.form, cmd.level2Sender);
|
|
22796
22805
|
return;
|
|
22797
22806
|
case "p2p-station-scalar":
|
|
22798
|
-
await this.sendStationScalar(sn, cmd.cmd, cmd.value, cmd.channel);
|
|
22807
|
+
await this.sendStationScalar(sn, cmd.cmd, cmd.value, cmd.channel, cmd.form);
|
|
22799
22808
|
return;
|
|
22800
22809
|
case "p2p-int-string":
|
|
22801
22810
|
await this.sendIntString(sn, cmd.cmd, cmd.value, cmd.valueSub, cmd.channel);
|
|
@@ -22837,10 +22846,7 @@ var P2PCommandRouter = class _P2PCommandRouter {
|
|
|
22837
22846
|
* control here is.
|
|
22838
22847
|
*/
|
|
22839
22848
|
async rebootStation(sn) {
|
|
22840
|
-
|
|
22841
|
-
l2: (resolved) => this.replayLevel2Send(sn, `reboot ${sn}`, ({ session, accountId }) => session.sendRawLevel2Bytes(buildDirectBinaryBody(0, accountId), 255, P2P_ENVELOPE.RESTART_HUB, 8), resolved),
|
|
22842
|
-
l1: (resolved) => this.replayLevel2Send(sn, `reboot ${sn}`, ({ session, accountId }) => session.sendRawLevel1Bytes(buildDirectBinaryBody(0, accountId), 255, P2P_ENVELOPE.RESTART_HUB), resolved)
|
|
22843
|
-
});
|
|
22849
|
+
return this.sendStationScalar(sn, P2P_ENVELOPE.RESTART_HUB, 0, 255, "auto");
|
|
22844
22850
|
}
|
|
22845
22851
|
/**
|
|
22846
22852
|
* A {@link MediaProvider} bound to one serial — resolves the session then calls `p2p/media`.
|
|
@@ -23736,9 +23742,19 @@ var P2PCommandRouter = class _P2PCommandRouter {
|
|
|
23736
23742
|
* **Station-scoped scalar** (`p2p-station-scalar` intent): the 132-byte channel-less body
|
|
23737
23743
|
* ({@link buildDirectBinaryBody} with no `channel`) on an EXPLICIT channel, signCode 8. The
|
|
23738
23744
|
* HomeBase's own controls ride the station broadcast channel 255 (alarm/speaker volume 1235).
|
|
23745
|
+
*
|
|
23746
|
+
* `form` `"auto"` seals it at the session's level, as {@link sendBySessionLevel} defines it: level-2 on a
|
|
23747
|
+
* keyed session, the same body sealed level-1 on a keyless one. Absent, the send waits for the level-2 key.
|
|
23739
23748
|
*/
|
|
23740
|
-
async sendStationScalar(sn, outerCmd, value, channel) {
|
|
23741
|
-
|
|
23749
|
+
async sendStationScalar(sn, outerCmd, value, channel, form) {
|
|
23750
|
+
const describe2 = `station scalar cmd ${outerCmd}`;
|
|
23751
|
+
const l2 = (resolved) => this.replayLevel2Send(sn, describe2, ({ session, accountId }) => session.sendRawLevel2Bytes(buildDirectBinaryBody(value, accountId), channel, outerCmd, 8), resolved);
|
|
23752
|
+
if (form !== "auto")
|
|
23753
|
+
return l2();
|
|
23754
|
+
await this.sendBySessionLevel(sn, {
|
|
23755
|
+
l2,
|
|
23756
|
+
l1: (resolved) => this.replayLevel2Send(sn, describe2, ({ session, accountId }) => session.sendRawLevel1Bytes(buildDirectBinaryBody(value, accountId), channel, outerCmd), resolved)
|
|
23757
|
+
});
|
|
23742
23758
|
}
|
|
23743
23759
|
/** Send a level-1 int-plus-string frame with authenticated account identity injected by the transport. */
|
|
23744
23760
|
async sendIntString(sn, commandType, value, valueSub, channel) {
|