@mega-yfue/eufy-sdk 0.5.0-beta.51 → 0.5.0-beta.52
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.
|
@@ -454,8 +454,9 @@ export declare class EufyMega extends EventEmitter {
|
|
|
454
454
|
*
|
|
455
455
|
* Side-effect: registers `eufy_home_tuya` devices with the Tuya command router so
|
|
456
456
|
* the command dispatcher can resolve a eufy SN → Tuya devId without a separate lookup.
|
|
457
|
-
* The Tuya id is
|
|
458
|
-
* `
|
|
457
|
+
* The Tuya id is the first non-empty `tuya_uuid`, `tuya_virtual_id`, `tuya_device_id` or
|
|
458
|
+
* `virtualId` on the raw cloud record, else the device's serial: the app keys its Tuya device by
|
|
459
|
+
* the eufy device id, and a record that carries none of those fields is read under its serial.
|
|
459
460
|
*
|
|
460
461
|
* A partial cloud outage still resolves, with the devices that answered plus the ones already known — but a
|
|
461
462
|
* session the cloud has rejected REJECTS, with {@link SessionExpiredError}. An empty list would be
|
|
@@ -790,6 +791,10 @@ export declare class EufyMega extends EventEmitter {
|
|
|
790
791
|
/**
|
|
791
792
|
* Subscribe the devices on one credential scope; a failing subscribe is reported, not fatal (one
|
|
792
793
|
* unreachable device must not stop the rest of the roster from coming up).
|
|
794
|
+
*
|
|
795
|
+
* A Tuya clean-line device's DPs are also read from the Tuya cloud, whether or not its subscribe
|
|
796
|
+
* succeeded: the cloud read is a separate plane, and the broker can refuse a subscribe for a device
|
|
797
|
+
* whose DPs the Tuya cloud still serves.
|
|
793
798
|
*/
|
|
794
799
|
private subscribeMqttDevices;
|
|
795
800
|
/**
|
package/dist/index.js
CHANGED
|
@@ -25525,11 +25525,11 @@ function buildPublishDpsAction(devId, gwId, dps) {
|
|
|
25525
25525
|
postData: JSON.stringify({ gwId, devId, dps: JSON.stringify(dps) })
|
|
25526
25526
|
};
|
|
25527
25527
|
}
|
|
25528
|
-
function buildGetDeviceDpsAction(devId
|
|
25528
|
+
function buildGetDeviceDpsAction(devId) {
|
|
25529
25529
|
return {
|
|
25530
|
-
a: "smartlife.m.device.
|
|
25531
|
-
v: "
|
|
25532
|
-
postData: JSON.stringify({ devId
|
|
25530
|
+
a: "smartlife.m.device.dp.get",
|
|
25531
|
+
v: "1.0",
|
|
25532
|
+
postData: JSON.stringify({ devId })
|
|
25533
25533
|
};
|
|
25534
25534
|
}
|
|
25535
25535
|
function buildUsernameTokenGetAction(countryCode, username) {
|
|
@@ -25685,11 +25685,12 @@ var TuyaClient = class {
|
|
|
25685
25685
|
return { sid: result.sid, uid: result.uid };
|
|
25686
25686
|
}
|
|
25687
25687
|
/**
|
|
25688
|
-
* READ
|
|
25689
|
-
* Builds the request without needing a working signer; the signer is
|
|
25688
|
+
* READ a device's current data-points (`smartlife.m.device.dp.get`). The envelope's `result` is a
|
|
25689
|
+
* flat `{ "<dpId>": value }` map. Builds the request without needing a working signer; the signer is
|
|
25690
|
+
* only exercised on send.
|
|
25690
25691
|
*/
|
|
25691
|
-
async getDeviceDps(devId
|
|
25692
|
-
return this.call(buildGetDeviceDpsAction(devId
|
|
25692
|
+
async getDeviceDps(devId) {
|
|
25693
|
+
return this.call(buildGetDeviceDpsAction(devId));
|
|
25693
25694
|
}
|
|
25694
25695
|
/**
|
|
25695
25696
|
* CONTROL: publish data-points to a device (`smartlife.m.device.dp.publish`). `dps` is
|
|
@@ -25780,9 +25781,9 @@ var TuyaCommandRouter = class {
|
|
|
25780
25781
|
/** Promise that resolves once Tuya login has completed. Reset by {@link bind}. */
|
|
25781
25782
|
loginOnce = null;
|
|
25782
25783
|
/**
|
|
25783
|
-
* eufy SN → Tuya device ids, populated
|
|
25784
|
-
* The
|
|
25785
|
-
* `
|
|
25784
|
+
* eufy SN → Tuya device ids, populated via {@link registerDevice} once the device list loads.
|
|
25785
|
+
* The Tuya id is the record's first non-empty `tuya_uuid` / `tuya_virtual_id` / `tuya_device_id` /
|
|
25786
|
+
* `virtualId`, or the device's serial when the record carries none of them.
|
|
25786
25787
|
*/
|
|
25787
25788
|
snMap = /* @__PURE__ */ new Map();
|
|
25788
25789
|
constructor(config = {}) {
|
|
@@ -25804,10 +25805,10 @@ var TuyaCommandRouter = class {
|
|
|
25804
25805
|
this.loginOnce = null;
|
|
25805
25806
|
}
|
|
25806
25807
|
/**
|
|
25807
|
-
* Register a eufy SN → Tuya devId mapping
|
|
25808
|
-
*
|
|
25809
|
-
*
|
|
25810
|
-
*
|
|
25808
|
+
* Register a eufy SN → Tuya devId mapping for an `eufy_home_tuya` device. `devId` is the record's
|
|
25809
|
+
* first non-empty `tuya_uuid` / `tuya_virtual_id` / `tuya_device_id` / `virtualId`, or the device's
|
|
25810
|
+
* serial when the record carries none of them. `gwId` defaults to `devId` — standalone devices
|
|
25811
|
+
* share the two.
|
|
25811
25812
|
*/
|
|
25812
25813
|
registerDevice(sn, devId, gwId = devId) {
|
|
25813
25814
|
this.snMap.set(sn, { devId, gwId });
|
|
@@ -25831,13 +25832,9 @@ var TuyaCommandRouter = class {
|
|
|
25831
25832
|
return this.loginOnce;
|
|
25832
25833
|
}
|
|
25833
25834
|
/**
|
|
25834
|
-
*
|
|
25835
|
-
* the
|
|
25836
|
-
*
|
|
25837
|
-
*
|
|
25838
|
-
* The response shape from `getDeviceDps` is not yet pinned from a live capture. The defensive
|
|
25839
|
-
* extraction tries both `result.dps` (a nested map) and bare `result` (a flat map), and returns
|
|
25840
|
-
* `null` when neither yields a non-empty record.
|
|
25835
|
+
* Read a device's current DPs from the Tuya cloud (`smartlife.m.device.dp.get`) and answer the DP
|
|
25836
|
+
* map: the reply's flat `result`, kept to integer DP keys with scalar values. Answers `null` for an
|
|
25837
|
+
* unregistered device, a failed reply, or a reply with no DPs.
|
|
25841
25838
|
*/
|
|
25842
25839
|
async fetchDps(sn) {
|
|
25843
25840
|
const ids = this.snMap.get(sn);
|
|
@@ -25847,12 +25844,8 @@ var TuyaCommandRouter = class {
|
|
|
25847
25844
|
const res = await this.client.getDeviceDps(ids.devId);
|
|
25848
25845
|
if (!res.success || !res.result)
|
|
25849
25846
|
return null;
|
|
25850
|
-
const
|
|
25851
|
-
|
|
25852
|
-
return nested;
|
|
25853
|
-
}
|
|
25854
|
-
const flat = parseTuyaDpEvent(res.result);
|
|
25855
|
-
return flat ? flat : null;
|
|
25847
|
+
const dps = parseTuyaDpEvent(res.result);
|
|
25848
|
+
return dps ? dps : null;
|
|
25856
25849
|
}
|
|
25857
25850
|
/**
|
|
25858
25851
|
* Route an `aiot-dp` {@link Command} to the Tuya REST API.
|
|
@@ -25871,7 +25864,7 @@ var TuyaCommandRouter = class {
|
|
|
25871
25864
|
await this.ensureLoggedIn();
|
|
25872
25865
|
const ids = this.snMap.get(sn);
|
|
25873
25866
|
if (!ids) {
|
|
25874
|
-
throw new Error(`TuyaCommandRouter: no Tuya device id registered for ${sn}. Ensure getDevices() was called
|
|
25867
|
+
throw new Error(`TuyaCommandRouter: no Tuya device id registered for ${sn}. Ensure getDevices() was called; it registers every eufy_home_tuya device under its Tuya id or its serial.`);
|
|
25875
25868
|
}
|
|
25876
25869
|
await this.client.publishDps(ids.devId, ids.gwId, { [cmd.dp]: cmd.value }, { allowUnverified: this.allowUnverified });
|
|
25877
25870
|
}
|
|
@@ -28679,8 +28672,9 @@ var EufyMega = class extends EventEmitter13 {
|
|
|
28679
28672
|
*
|
|
28680
28673
|
* Side-effect: registers `eufy_home_tuya` devices with the Tuya command router so
|
|
28681
28674
|
* the command dispatcher can resolve a eufy SN → Tuya devId without a separate lookup.
|
|
28682
|
-
* The Tuya id is
|
|
28683
|
-
* `
|
|
28675
|
+
* The Tuya id is the first non-empty `tuya_uuid`, `tuya_virtual_id`, `tuya_device_id` or
|
|
28676
|
+
* `virtualId` on the raw cloud record, else the device's serial: the app keys its Tuya device by
|
|
28677
|
+
* the eufy device id, and a record that carries none of those fields is read under its serial.
|
|
28684
28678
|
*
|
|
28685
28679
|
* A partial cloud outage still resolves, with the devices that answered plus the ones already known — but a
|
|
28686
28680
|
* session the cloud has rejected REJECTS, with {@link SessionExpiredError}. An empty list would be
|
|
@@ -28692,9 +28686,7 @@ var EufyMega = class extends EventEmitter13 {
|
|
|
28692
28686
|
if (dev.category !== "eufy_home_tuya")
|
|
28693
28687
|
continue;
|
|
28694
28688
|
const raw = dev.raw ?? {};
|
|
28695
|
-
|
|
28696
|
-
if (devId)
|
|
28697
|
-
this.tuya.registerDevice(dev.sn, devId);
|
|
28689
|
+
this.tuya.registerDevice(dev.sn, tuyaDevIdFrom(raw) ?? dev.sn);
|
|
28698
28690
|
}
|
|
28699
28691
|
return devices;
|
|
28700
28692
|
}
|
|
@@ -29362,21 +29354,25 @@ var EufyMega = class extends EventEmitter13 {
|
|
|
29362
29354
|
/**
|
|
29363
29355
|
* Subscribe the devices on one credential scope; a failing subscribe is reported, not fatal (one
|
|
29364
29356
|
* unreachable device must not stop the rest of the roster from coming up).
|
|
29357
|
+
*
|
|
29358
|
+
* A Tuya clean-line device's DPs are also read from the Tuya cloud, whether or not its subscribe
|
|
29359
|
+
* succeeded: the cloud read is a separate plane, and the broker can refuse a subscribe for a device
|
|
29360
|
+
* whose DPs the Tuya cloud still serves.
|
|
29365
29361
|
*/
|
|
29366
29362
|
async subscribeMqttDevices(scope, transport) {
|
|
29367
29363
|
for (const d of this.getMqttDevices().filter((dev) => mqttScopeFor(dev) === scope)) {
|
|
29368
29364
|
try {
|
|
29369
29365
|
await transport.subscribeDevice(d);
|
|
29370
29366
|
await this.sendRealtimeInit(d.sn);
|
|
29371
|
-
if (d.category === "eufy_home_tuya") {
|
|
29372
|
-
this.tuya.fetchDps(d.sn).then((dps) => {
|
|
29373
|
-
if (dps)
|
|
29374
|
-
this.tuyaDpRouter.deliver(d.sn, dps);
|
|
29375
|
-
}).catch((e) => this.reportError(e));
|
|
29376
|
-
}
|
|
29377
29367
|
} catch (e) {
|
|
29378
29368
|
this.reportError(e);
|
|
29379
29369
|
}
|
|
29370
|
+
if (d.category === "eufy_home_tuya") {
|
|
29371
|
+
this.tuya.fetchDps(d.sn).then((dps) => {
|
|
29372
|
+
if (dps)
|
|
29373
|
+
this.tuyaDpRouter.deliver(d.sn, dps);
|
|
29374
|
+
}).catch((e) => this.reportError(e));
|
|
29375
|
+
}
|
|
29380
29376
|
}
|
|
29381
29377
|
}
|
|
29382
29378
|
/**
|