@apocaliss92/nodedreame 1.1.0 → 1.3.0
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/README.md +48 -0
- package/dist/index.cjs +703 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +629 -20
- package/dist/index.d.ts +629 -20
- package/dist/index.js +700 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -47,6 +47,7 @@ __export(index_exports, {
|
|
|
47
47
|
MowerChargingStatus: () => MowerChargingStatus,
|
|
48
48
|
MowerControlAction: () => MowerControlAction,
|
|
49
49
|
MowerDevice: () => MowerDevice,
|
|
50
|
+
MowerFault: () => MowerFault,
|
|
50
51
|
MowerStatus: () => MowerStatus,
|
|
51
52
|
MowerTaskStatus: () => MowerTaskStatus,
|
|
52
53
|
Nodreame: () => Nodreame,
|
|
@@ -56,6 +57,8 @@ __export(index_exports, {
|
|
|
56
57
|
VacuumCapabilityResolver: () => VacuumCapabilityResolver,
|
|
57
58
|
VacuumDevice: () => VacuumDevice,
|
|
58
59
|
WaterVolume: () => WaterVolume,
|
|
60
|
+
createClientDumper: () => createClientDumper,
|
|
61
|
+
createDumper: () => createDumper,
|
|
59
62
|
getMowerCapabilities: () => getMowerCapabilities,
|
|
60
63
|
getVacuumCapabilities: () => getVacuumCapabilities,
|
|
61
64
|
renderMowerSvg: () => renderMowerSvg,
|
|
@@ -66,6 +69,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
66
69
|
|
|
67
70
|
// src/support/version.ts
|
|
68
71
|
var LIBRARY_NAME = "nodedreame";
|
|
72
|
+
var LIBRARY_VERSION = "1.3.0";
|
|
69
73
|
|
|
70
74
|
// src/transport/errors.ts
|
|
71
75
|
var DreameError = class extends Error {
|
|
@@ -1292,11 +1296,27 @@ var MiotState = /* @__PURE__ */ ((MiotState2) => {
|
|
|
1292
1296
|
MiotState2[MiotState2["ReturnToEmpty"] = 28] = "ReturnToEmpty";
|
|
1293
1297
|
MiotState2[MiotState2["WaitingForTask"] = 29] = "WaitingForTask";
|
|
1294
1298
|
MiotState2[MiotState2["CleanWashboardBase"] = 30] = "CleanWashboardBase";
|
|
1299
|
+
MiotState2[MiotState2["ReturningToDrain"] = 31] = "ReturningToDrain";
|
|
1300
|
+
MiotState2[MiotState2["Draining"] = 32] = "Draining";
|
|
1295
1301
|
MiotState2[MiotState2["AutoWaterDraining"] = 33] = "AutoWaterDraining";
|
|
1302
|
+
MiotState2[MiotState2["Emptying"] = 34] = "Emptying";
|
|
1303
|
+
MiotState2[MiotState2["DustBagDrying"] = 35] = "DustBagDrying";
|
|
1304
|
+
MiotState2[MiotState2["DustBagDryingPaused"] = 36] = "DustBagDryingPaused";
|
|
1305
|
+
MiotState2[MiotState2["HeadingToExtraCleaning"] = 37] = "HeadingToExtraCleaning";
|
|
1306
|
+
MiotState2[MiotState2["ExtraCleaning"] = 38] = "ExtraCleaning";
|
|
1307
|
+
MiotState2[MiotState2["FindingPetPaused"] = 95] = "FindingPetPaused";
|
|
1308
|
+
MiotState2[MiotState2["FindingPet"] = 96] = "FindingPet";
|
|
1296
1309
|
MiotState2[MiotState2["ShortcutRunning"] = 97] = "ShortcutRunning";
|
|
1297
1310
|
MiotState2[MiotState2["CameraMonitoring"] = 98] = "CameraMonitoring";
|
|
1298
1311
|
MiotState2[MiotState2["CameraMonitoringPaused"] = 99] = "CameraMonitoringPaused";
|
|
1299
1312
|
MiotState2[MiotState2["InitialDeepClean"] = 101] = "InitialDeepClean";
|
|
1313
|
+
MiotState2[MiotState2["InitialDeepCleanPaused"] = 102] = "InitialDeepCleanPaused";
|
|
1314
|
+
MiotState2[MiotState2["Sanitizing"] = 103] = "Sanitizing";
|
|
1315
|
+
MiotState2[MiotState2["SanitizingWithDry"] = 104] = "SanitizingWithDry";
|
|
1316
|
+
MiotState2[MiotState2["ChangingMop"] = 105] = "ChangingMop";
|
|
1317
|
+
MiotState2[MiotState2["ChangingMopPaused"] = 106] = "ChangingMopPaused";
|
|
1318
|
+
MiotState2[MiotState2["FloorMaintaining"] = 107] = "FloorMaintaining";
|
|
1319
|
+
MiotState2[MiotState2["FloorMaintainingPaused"] = 108] = "FloorMaintainingPaused";
|
|
1300
1320
|
return MiotState2;
|
|
1301
1321
|
})(MiotState || {});
|
|
1302
1322
|
var ChargingStatus = /* @__PURE__ */ ((ChargingStatus2) => {
|
|
@@ -1328,21 +1348,87 @@ var CleaningMode = /* @__PURE__ */ ((CleaningMode2) => {
|
|
|
1328
1348
|
var MiotError = /* @__PURE__ */ ((MiotError2) => {
|
|
1329
1349
|
MiotError2[MiotError2["Clear"] = 0] = "Clear";
|
|
1330
1350
|
MiotError2[MiotError2["WheelRotationAnomaly"] = 1] = "WheelRotationAnomaly";
|
|
1351
|
+
MiotError2[MiotError2["Cliff"] = 2] = "Cliff";
|
|
1352
|
+
MiotError2[MiotError2["Bumper"] = 3] = "Bumper";
|
|
1353
|
+
MiotError2[MiotError2["Gesture"] = 4] = "Gesture";
|
|
1354
|
+
MiotError2[MiotError2["BumperRepeat"] = 5] = "BumperRepeat";
|
|
1355
|
+
MiotError2[MiotError2["DropRepeat"] = 6] = "DropRepeat";
|
|
1356
|
+
MiotError2[MiotError2["OpticalFlow"] = 7] = "OpticalFlow";
|
|
1357
|
+
MiotError2[MiotError2["Box"] = 8] = "Box";
|
|
1358
|
+
MiotError2[MiotError2["TankBox"] = 9] = "TankBox";
|
|
1359
|
+
MiotError2[MiotError2["WaterBoxEmpty"] = 10] = "WaterBoxEmpty";
|
|
1360
|
+
MiotError2[MiotError2["BoxFull"] = 11] = "BoxFull";
|
|
1361
|
+
MiotError2[MiotError2["Brush"] = 12] = "Brush";
|
|
1362
|
+
MiotError2[MiotError2["SideBrush"] = 13] = "SideBrush";
|
|
1363
|
+
MiotError2[MiotError2["Fan"] = 14] = "Fan";
|
|
1364
|
+
MiotError2[MiotError2["LeftWheelMotor"] = 15] = "LeftWheelMotor";
|
|
1365
|
+
MiotError2[MiotError2["RightWheelMotor"] = 16] = "RightWheelMotor";
|
|
1366
|
+
MiotError2[MiotError2["TurnSuffocate"] = 17] = "TurnSuffocate";
|
|
1331
1367
|
MiotError2[MiotError2["RobotLifted"] = 18] = "RobotLifted";
|
|
1332
|
-
MiotError2[MiotError2["
|
|
1333
|
-
MiotError2[MiotError2["ManualMopInstallRequired"] = 74] = "ManualMopInstallRequired";
|
|
1334
|
-
MiotError2[MiotError2["WastewaterTankFull"] = 105] = "WastewaterTankFull";
|
|
1335
|
-
MiotError2[MiotError2["CleanWaterTankEmpty"] = 107] = "CleanWaterTankEmpty";
|
|
1336
|
-
MiotError2[MiotError2["WashboardFilterNeedsCleaning"] = 114] = "WashboardFilterNeedsCleaning";
|
|
1337
|
-
MiotError2[MiotError2["MopPadsMissing"] = 120] = "MopPadsMissing";
|
|
1368
|
+
MiotError2[MiotError2["ChargerGet"] = 19] = "ChargerGet";
|
|
1338
1369
|
MiotError2[MiotError2["BatteryLow"] = 20] = "BatteryLow";
|
|
1339
1370
|
MiotError2[MiotError2["ChargeFault"] = 21] = "ChargeFault";
|
|
1340
1371
|
MiotError2[MiotError2["BatteryPercentageAnomaly"] = 22] = "BatteryPercentageAnomaly";
|
|
1372
|
+
MiotError2[MiotError2["Heart"] = 23] = "Heart";
|
|
1373
|
+
MiotError2[MiotError2["CameraOcclusion"] = 24] = "CameraOcclusion";
|
|
1374
|
+
MiotError2[MiotError2["Move"] = 25] = "Move";
|
|
1375
|
+
MiotError2[MiotError2["FlowShielding"] = 26] = "FlowShielding";
|
|
1376
|
+
MiotError2[MiotError2["InfraredShielding"] = 27] = "InfraredShielding";
|
|
1341
1377
|
MiotError2[MiotError2["ChargeNoElectric"] = 28] = "ChargeNoElectric";
|
|
1342
1378
|
MiotError2[MiotError2["BatteryFault"] = 29] = "BatteryFault";
|
|
1379
|
+
MiotError2[MiotError2["FanSpeedError"] = 30] = "FanSpeedError";
|
|
1380
|
+
MiotError2[MiotError2["LeftWheelSpeed"] = 31] = "LeftWheelSpeed";
|
|
1381
|
+
MiotError2[MiotError2["RightWheelSpeed"] = 32] = "RightWheelSpeed";
|
|
1382
|
+
MiotError2[MiotError2["Bmi055Acce"] = 33] = "Bmi055Acce";
|
|
1383
|
+
MiotError2[MiotError2["Bmi055Gyro"] = 34] = "Bmi055Gyro";
|
|
1384
|
+
MiotError2[MiotError2["Xv7001"] = 35] = "Xv7001";
|
|
1385
|
+
MiotError2[MiotError2["LeftMagnet"] = 36] = "LeftMagnet";
|
|
1386
|
+
MiotError2[MiotError2["RightMagnet"] = 37] = "RightMagnet";
|
|
1387
|
+
MiotError2[MiotError2["FlowError"] = 38] = "FlowError";
|
|
1388
|
+
MiotError2[MiotError2["InfraredFault"] = 39] = "InfraredFault";
|
|
1389
|
+
MiotError2[MiotError2["CameraFault"] = 40] = "CameraFault";
|
|
1390
|
+
MiotError2[MiotError2["StrongMagnet"] = 41] = "StrongMagnet";
|
|
1391
|
+
MiotError2[MiotError2["WaterPump"] = 42] = "WaterPump";
|
|
1392
|
+
MiotError2[MiotError2["Rtc"] = 43] = "Rtc";
|
|
1393
|
+
MiotError2[MiotError2["AutoKeyTrig"] = 44] = "AutoKeyTrig";
|
|
1394
|
+
MiotError2[MiotError2["P3v3"] = 45] = "P3v3";
|
|
1395
|
+
MiotError2[MiotError2["CameraIdle"] = 46] = "CameraIdle";
|
|
1396
|
+
MiotError2[MiotError2["Blocked"] = 47] = "Blocked";
|
|
1397
|
+
MiotError2[MiotError2["LdsError"] = 48] = "LdsError";
|
|
1398
|
+
MiotError2[MiotError2["LdsBumper"] = 49] = "LdsBumper";
|
|
1399
|
+
MiotError2[MiotError2["WaterPump2"] = 50] = "WaterPump2";
|
|
1400
|
+
MiotError2[MiotError2["FilterBlocked"] = 51] = "FilterBlocked";
|
|
1401
|
+
MiotError2[MiotError2["Edge"] = 54] = "Edge";
|
|
1402
|
+
MiotError2[MiotError2["Carpet"] = 55] = "Carpet";
|
|
1403
|
+
MiotError2[MiotError2["Laser"] = 56] = "Laser";
|
|
1404
|
+
MiotError2[MiotError2["Edge2"] = 57] = "Edge2";
|
|
1405
|
+
MiotError2[MiotError2["Ultrasonic"] = 58] = "Ultrasonic";
|
|
1406
|
+
MiotError2[MiotError2["NoGoZone"] = 59] = "NoGoZone";
|
|
1407
|
+
MiotError2[MiotError2["Route"] = 61] = "Route";
|
|
1408
|
+
MiotError2[MiotError2["Route2"] = 62] = "Route2";
|
|
1409
|
+
MiotError2[MiotError2["Blocked2"] = 63] = "Blocked2";
|
|
1410
|
+
MiotError2[MiotError2["Blocked3"] = 64] = "Blocked3";
|
|
1411
|
+
MiotError2[MiotError2["Restricted"] = 65] = "Restricted";
|
|
1412
|
+
MiotError2[MiotError2["Restricted2"] = 66] = "Restricted2";
|
|
1413
|
+
MiotError2[MiotError2["Restricted3"] = 67] = "Restricted3";
|
|
1414
|
+
MiotError2[MiotError2["TaskComplete"] = 68] = "TaskComplete";
|
|
1415
|
+
MiotError2[MiotError2["MopRemoved"] = 69] = "MopRemoved";
|
|
1416
|
+
MiotError2[MiotError2["MopRemoved2"] = 70] = "MopRemoved2";
|
|
1417
|
+
MiotError2[MiotError2["MopPadStopRotate"] = 71] = "MopPadStopRotate";
|
|
1418
|
+
MiotError2[MiotError2["MopPadStopRotate2"] = 72] = "MopPadStopRotate2";
|
|
1419
|
+
MiotError2[MiotError2["ManualMopInstallRequired"] = 74] = "ManualMopInstallRequired";
|
|
1343
1420
|
MiotError2[MiotError2["LowBatteryTurnOff"] = 75] = "LowBatteryTurnOff";
|
|
1421
|
+
MiotError2[MiotError2["DirtyTankNotInstalled"] = 76] = "DirtyTankNotInstalled";
|
|
1422
|
+
MiotError2[MiotError2["RobotInHiddenRoom"] = 78] = "RobotInHiddenRoom";
|
|
1423
|
+
MiotError2[MiotError2["LdsFailedToLift"] = 79] = "LdsFailedToLift";
|
|
1344
1424
|
MiotError2[MiotError2["RobotStuck"] = 80] = "RobotStuck";
|
|
1345
1425
|
MiotError2[MiotError2["RobotStuckRepeat"] = 81] = "RobotStuckRepeat";
|
|
1426
|
+
MiotError2[MiotError2["SlipperyFloor"] = 82] = "SlipperyFloor";
|
|
1427
|
+
MiotError2[MiotError2["UnknownError"] = 84] = "UnknownError";
|
|
1428
|
+
MiotError2[MiotError2["CheckMopInstall"] = 85] = "CheckMopInstall";
|
|
1429
|
+
MiotError2[MiotError2["DirtyWaterTankFull"] = 86] = "DirtyWaterTankFull";
|
|
1430
|
+
MiotError2[MiotError2["RetractableLegStuck"] = 88] = "RetractableLegStuck";
|
|
1431
|
+
MiotError2[MiotError2["InternalError"] = 89] = "InternalError";
|
|
1346
1432
|
MiotError2[MiotError2["RobotStuck2"] = 90] = "RobotStuck2";
|
|
1347
1433
|
MiotError2[MiotError2["RobotStuckOnTables"] = 91] = "RobotStuckOnTables";
|
|
1348
1434
|
MiotError2[MiotError2["RobotStuckOnPassage"] = 92] = "RobotStuckOnPassage";
|
|
@@ -1353,19 +1439,82 @@ var MiotError = /* @__PURE__ */ ((MiotError2) => {
|
|
|
1353
1439
|
MiotError2[MiotError2["RobotStuckOnPet"] = 97] = "RobotStuckOnPet";
|
|
1354
1440
|
MiotError2[MiotError2["RobotStuckOnSlipperySurface"] = 98] = "RobotStuckOnSlipperySurface";
|
|
1355
1441
|
MiotError2[MiotError2["RobotStuckOnCarpet"] = 99] = "RobotStuckOnCarpet";
|
|
1356
|
-
MiotError2[MiotError2["RobotStuckOnCurtain"] = 200] = "RobotStuckOnCurtain";
|
|
1357
1442
|
MiotError2[MiotError2["BinFull"] = 101] = "BinFull";
|
|
1443
|
+
MiotError2[MiotError2["BinOpen"] = 102] = "BinOpen";
|
|
1444
|
+
MiotError2[MiotError2["BinOpen2"] = 103] = "BinOpen2";
|
|
1445
|
+
MiotError2[MiotError2["BinFull2"] = 104] = "BinFull2";
|
|
1446
|
+
MiotError2[MiotError2["WastewaterTankFull"] = 105] = "WastewaterTankFull";
|
|
1447
|
+
MiotError2[MiotError2["DirtyWaterTank"] = 106] = "DirtyWaterTank";
|
|
1448
|
+
MiotError2[MiotError2["CleanWaterTankEmpty"] = 107] = "CleanWaterTankEmpty";
|
|
1449
|
+
MiotError2[MiotError2["DirtyWaterTank2"] = 108] = "DirtyWaterTank2";
|
|
1450
|
+
MiotError2[MiotError2["DirtyWaterTankBlocked"] = 109] = "DirtyWaterTankBlocked";
|
|
1451
|
+
MiotError2[MiotError2["DirtyWaterTankPump"] = 110] = "DirtyWaterTankPump";
|
|
1452
|
+
MiotError2[MiotError2["MopPad"] = 111] = "MopPad";
|
|
1453
|
+
MiotError2[MiotError2["WetMopPad"] = 112] = "WetMopPad";
|
|
1454
|
+
MiotError2[MiotError2["WashboardFilterNeedsCleaning"] = 114] = "WashboardFilterNeedsCleaning";
|
|
1455
|
+
MiotError2[MiotError2["CleanTankLevel"] = 116] = "CleanTankLevel";
|
|
1358
1456
|
MiotError2[MiotError2["StationDisconnected"] = 117] = "StationDisconnected";
|
|
1457
|
+
MiotError2[MiotError2["DirtyTankLevel"] = 118] = "DirtyTankLevel";
|
|
1458
|
+
MiotError2[MiotError2["WashboardLevel"] = 119] = "WashboardLevel";
|
|
1459
|
+
MiotError2[MiotError2["MopPadsMissing"] = 120] = "MopPadsMissing";
|
|
1359
1460
|
MiotError2[MiotError2["DustBagFull"] = 121] = "DustBagFull";
|
|
1461
|
+
MiotError2[MiotError2["UnknownWarning"] = 122] = "UnknownWarning";
|
|
1462
|
+
MiotError2[MiotError2["SelfTestFailed"] = 123] = "SelfTestFailed";
|
|
1463
|
+
MiotError2[MiotError2["WashboardNotWorking"] = 124] = "WashboardNotWorking";
|
|
1464
|
+
MiotError2[MiotError2["DrainageFailed"] = 125] = "DrainageFailed";
|
|
1465
|
+
MiotError2[MiotError2["MopNotDetected"] = 126] = "MopNotDetected";
|
|
1466
|
+
MiotError2[MiotError2["MopHolderError"] = 127] = "MopHolderError";
|
|
1467
|
+
MiotError2[MiotError2["DockError"] = 128] = "DockError";
|
|
1468
|
+
MiotError2[MiotError2["WashFailed"] = 129] = "WashFailed";
|
|
1469
|
+
MiotError2[MiotError2["RobotStuckOnCurtain"] = 200] = "RobotStuckOnCurtain";
|
|
1470
|
+
MiotError2[MiotError2["EdgeMopStopRotate"] = 201] = "EdgeMopStopRotate";
|
|
1471
|
+
MiotError2[MiotError2["EdgeMopDetached"] = 202] = "EdgeMopDetached";
|
|
1472
|
+
MiotError2[MiotError2["ChassisLiftMalfunction"] = 203] = "ChassisLiftMalfunction";
|
|
1473
|
+
MiotError2[MiotError2["InternalError2"] = 207] = "InternalError2";
|
|
1474
|
+
MiotError2[MiotError2["MopCoverError"] = 209] = "MopCoverError";
|
|
1475
|
+
MiotError2[MiotError2["RollerMopError"] = 210] = "RollerMopError";
|
|
1476
|
+
MiotError2[MiotError2["OnboardWaterTankEmpty"] = 213] = "OnboardWaterTankEmpty";
|
|
1477
|
+
MiotError2[MiotError2["OnboardDirtyWaterTankFull"] = 214] = "OnboardDirtyWaterTankFull";
|
|
1478
|
+
MiotError2[MiotError2["MopNotInstalled"] = 215] = "MopNotInstalled";
|
|
1479
|
+
MiotError2[MiotError2["RollerMopError2"] = 218] = "RollerMopError2";
|
|
1480
|
+
MiotError2[MiotError2["FluffingRollerError"] = 222] = "FluffingRollerError";
|
|
1481
|
+
MiotError2[MiotError2["MopCoverError2"] = 223] = "MopCoverError2";
|
|
1482
|
+
MiotError2[MiotError2["BlockedByObstacle"] = 226] = "BlockedByObstacle";
|
|
1483
|
+
MiotError2[MiotError2["ReturnToChargeFailed"] = 1e3] = "ReturnToChargeFailed";
|
|
1360
1484
|
return MiotError2;
|
|
1361
1485
|
})(MiotError || {});
|
|
1362
1486
|
var TaskStatus = /* @__PURE__ */ ((TaskStatus2) => {
|
|
1487
|
+
TaskStatus2[TaskStatus2["Completed"] = 0] = "Completed";
|
|
1363
1488
|
TaskStatus2[TaskStatus2["InterruptedOrPaused"] = 1] = "InterruptedOrPaused";
|
|
1364
1489
|
TaskStatus2[TaskStatus2["Active"] = 2] = "Active";
|
|
1365
1490
|
TaskStatus2[TaskStatus2["Transitioning"] = 3] = "Transitioning";
|
|
1491
|
+
TaskStatus2[TaskStatus2["SpotCleaning"] = 4] = "SpotCleaning";
|
|
1492
|
+
TaskStatus2[TaskStatus2["FastMapping"] = 5] = "FastMapping";
|
|
1366
1493
|
TaskStatus2[TaskStatus2["OnDockIdle"] = 6] = "OnDockIdle";
|
|
1494
|
+
TaskStatus2[TaskStatus2["ZoneCleaningPaused"] = 7] = "ZoneCleaningPaused";
|
|
1495
|
+
TaskStatus2[TaskStatus2["SegmentCleaningPaused"] = 8] = "SegmentCleaningPaused";
|
|
1496
|
+
TaskStatus2[TaskStatus2["SpotCleaningPaused"] = 9] = "SpotCleaningPaused";
|
|
1497
|
+
TaskStatus2[TaskStatus2["MapCleaningPaused"] = 10] = "MapCleaningPaused";
|
|
1498
|
+
TaskStatus2[TaskStatus2["DockingPaused"] = 11] = "DockingPaused";
|
|
1367
1499
|
TaskStatus2[TaskStatus2["TransientPauseEdge"] = 12] = "TransientPauseEdge";
|
|
1500
|
+
TaskStatus2[TaskStatus2["SegmentMoppingPaused"] = 13] = "SegmentMoppingPaused";
|
|
1368
1501
|
TaskStatus2[TaskStatus2["NeedsIntervention"] = 14] = "NeedsIntervention";
|
|
1502
|
+
TaskStatus2[TaskStatus2["AutoMoppingPaused"] = 15] = "AutoMoppingPaused";
|
|
1503
|
+
TaskStatus2[TaskStatus2["AutoDockingPaused"] = 16] = "AutoDockingPaused";
|
|
1504
|
+
TaskStatus2[TaskStatus2["SegmentDockingPaused"] = 17] = "SegmentDockingPaused";
|
|
1505
|
+
TaskStatus2[TaskStatus2["ZoneDockingPaused"] = 18] = "ZoneDockingPaused";
|
|
1506
|
+
TaskStatus2[TaskStatus2["CruisingPath"] = 20] = "CruisingPath";
|
|
1507
|
+
TaskStatus2[TaskStatus2["CruisingPathPaused"] = 21] = "CruisingPathPaused";
|
|
1508
|
+
TaskStatus2[TaskStatus2["CruisingPoint"] = 22] = "CruisingPoint";
|
|
1509
|
+
TaskStatus2[TaskStatus2["CruisingPointPaused"] = 23] = "CruisingPointPaused";
|
|
1510
|
+
TaskStatus2[TaskStatus2["SummonCleanPaused"] = 24] = "SummonCleanPaused";
|
|
1511
|
+
TaskStatus2[TaskStatus2["ReturningInstallMop"] = 25] = "ReturningInstallMop";
|
|
1512
|
+
TaskStatus2[TaskStatus2["ReturningRemoveMop"] = 26] = "ReturningRemoveMop";
|
|
1513
|
+
TaskStatus2[TaskStatus2["StationCleaning"] = 27] = "StationCleaning";
|
|
1514
|
+
TaskStatus2[TaskStatus2["PetFinding"] = 30] = "PetFinding";
|
|
1515
|
+
TaskStatus2[TaskStatus2["AutoCleaningWashingPaused"] = 31] = "AutoCleaningWashingPaused";
|
|
1516
|
+
TaskStatus2[TaskStatus2["AreaCleaningWashingPaused"] = 32] = "AreaCleaningWashingPaused";
|
|
1517
|
+
TaskStatus2[TaskStatus2["CustomCleaningWashingPaused"] = 33] = "CustomCleaningWashingPaused";
|
|
1369
1518
|
return TaskStatus2;
|
|
1370
1519
|
})(TaskStatus || {});
|
|
1371
1520
|
|
|
@@ -2502,6 +2651,18 @@ var VacuumDevice = class _VacuumDevice extends BaseDevice {
|
|
|
2502
2651
|
get vacuumCapabilities() {
|
|
2503
2652
|
return this.#caps;
|
|
2504
2653
|
}
|
|
2654
|
+
/**
|
|
2655
|
+
* The suction levels this model supports, as a {@link SuctionLevel} enum array
|
|
2656
|
+
* (from the capability record). Lets a consumer see which fan speeds are
|
|
2657
|
+
* selectable without reaching into {@link vacuumCapabilities}.
|
|
2658
|
+
*/
|
|
2659
|
+
get supportedSuctionLevels() {
|
|
2660
|
+
return this.#caps.supportedSuctionLevels;
|
|
2661
|
+
}
|
|
2662
|
+
/** The water/mop volumes this model supports, as a {@link WaterVolume} enum array. */
|
|
2663
|
+
get supportedWaterVolumes() {
|
|
2664
|
+
return this.#caps.supportedWaterVolumes;
|
|
2665
|
+
}
|
|
2505
2666
|
#num(siid, piid) {
|
|
2506
2667
|
return asNum(this.getProperty(siid, piid)?.value);
|
|
2507
2668
|
}
|
|
@@ -2678,11 +2839,11 @@ var VacuumDevice = class _VacuumDevice extends BaseDevice {
|
|
|
2678
2839
|
}
|
|
2679
2840
|
this.#requireCap(this.#caps.canCleanPerRoom, "cleanZones", "per-room cleaning");
|
|
2680
2841
|
const { repeats, fan, water } = this.#resolveCleanOpts(opts);
|
|
2681
|
-
const areas = zones.map((
|
|
2682
|
-
Math.round(
|
|
2683
|
-
Math.round(
|
|
2684
|
-
Math.round(
|
|
2685
|
-
Math.round(
|
|
2842
|
+
const areas = zones.map((z4) => [
|
|
2843
|
+
Math.round(z4.x0),
|
|
2844
|
+
Math.round(z4.y0),
|
|
2845
|
+
Math.round(z4.x1),
|
|
2846
|
+
Math.round(z4.y1),
|
|
2686
2847
|
repeats,
|
|
2687
2848
|
fan,
|
|
2688
2849
|
water
|
|
@@ -2864,6 +3025,83 @@ var MowerTaskStatus = /* @__PURE__ */ ((MowerTaskStatus2) => {
|
|
|
2864
3025
|
MowerTaskStatus2[MowerTaskStatus2["SpotIncomplete"] = 7] = "SpotIncomplete";
|
|
2865
3026
|
return MowerTaskStatus2;
|
|
2866
3027
|
})(MowerTaskStatus || {});
|
|
3028
|
+
var MowerFault = /* @__PURE__ */ ((MowerFault2) => {
|
|
3029
|
+
MowerFault2[MowerFault2["NoDeviceCode"] = 0] = "NoDeviceCode";
|
|
3030
|
+
MowerFault2[MowerFault2["Tilted"] = 1] = "Tilted";
|
|
3031
|
+
MowerFault2[MowerFault2["Trapped"] = 2] = "Trapped";
|
|
3032
|
+
MowerFault2[MowerFault2["NarrowPathToStation"] = 3] = "NarrowPathToStation";
|
|
3033
|
+
MowerFault2[MowerFault2["LeftWheel"] = 4] = "LeftWheel";
|
|
3034
|
+
MowerFault2[MowerFault2["RightWheel"] = 5] = "RightWheel";
|
|
3035
|
+
MowerFault2[MowerFault2["LiftMotor"] = 6] = "LiftMotor";
|
|
3036
|
+
MowerFault2[MowerFault2["Cutter"] = 7] = "Cutter";
|
|
3037
|
+
MowerFault2[MowerFault2["SidedMotor"] = 8] = "SidedMotor";
|
|
3038
|
+
MowerFault2[MowerFault2["CrashPlate"] = 9] = "CrashPlate";
|
|
3039
|
+
MowerFault2[MowerFault2["Charging"] = 10] = "Charging";
|
|
3040
|
+
MowerFault2[MowerFault2["BatteryOverheat"] = 11] = "BatteryOverheat";
|
|
3041
|
+
MowerFault2[MowerFault2["LidarCovered"] = 12] = "LidarCovered";
|
|
3042
|
+
MowerFault2[MowerFault2["LidarOverheatWithoutMap"] = 13] = "LidarOverheatWithoutMap";
|
|
3043
|
+
MowerFault2[MowerFault2["LidarOverheatWithMap"] = 14] = "LidarOverheatWithMap";
|
|
3044
|
+
MowerFault2[MowerFault2["LidarOverheat"] = 15] = "LidarOverheat";
|
|
3045
|
+
MowerFault2[MowerFault2["LidarDirty"] = 16] = "LidarDirty";
|
|
3046
|
+
MowerFault2[MowerFault2["LidarAbnormal"] = 17] = "LidarAbnormal";
|
|
3047
|
+
MowerFault2[MowerFault2["LocationWeak"] = 18] = "LocationWeak";
|
|
3048
|
+
MowerFault2[MowerFault2["LocationLost"] = 19] = "LocationLost";
|
|
3049
|
+
MowerFault2[MowerFault2["Sensor"] = 20] = "Sensor";
|
|
3050
|
+
MowerFault2[MowerFault2["InForbiddenArea"] = 21] = "InForbiddenArea";
|
|
3051
|
+
MowerFault2[MowerFault2["OutOfMap"] = 22] = "OutOfMap";
|
|
3052
|
+
MowerFault2[MowerFault2["EmergencyStop"] = 23] = "EmergencyStop";
|
|
3053
|
+
MowerFault2[MowerFault2["BatteryLow"] = 24] = "BatteryLow";
|
|
3054
|
+
MowerFault2[MowerFault2["MapFileCrack"] = 25] = "MapFileCrack";
|
|
3055
|
+
MowerFault2[MowerFault2["AwayFromMap"] = 26] = "AwayFromMap";
|
|
3056
|
+
MowerFault2[MowerFault2["HumanDetected"] = 27] = "HumanDetected";
|
|
3057
|
+
MowerFault2[MowerFault2["BladeLoss"] = 28] = "BladeLoss";
|
|
3058
|
+
MowerFault2[MowerFault2["StationLoss"] = 29] = "StationLoss";
|
|
3059
|
+
MowerFault2[MowerFault2["MaintainLoss"] = 30] = "MaintainLoss";
|
|
3060
|
+
MowerFault2[MowerFault2["BackChargeFailed"] = 31] = "BackChargeFailed";
|
|
3061
|
+
MowerFault2[MowerFault2["DockingFailed"] = 32] = "DockingFailed";
|
|
3062
|
+
MowerFault2[MowerFault2["LocatingFailedWithMap"] = 33] = "LocatingFailedWithMap";
|
|
3063
|
+
MowerFault2[MowerFault2["LocatingFailedWithoutMap"] = 34] = "LocatingFailedWithoutMap";
|
|
3064
|
+
MowerFault2[MowerFault2["LocatingAbnormal"] = 35] = "LocatingAbnormal";
|
|
3065
|
+
MowerFault2[MowerFault2["TaskStartFailed"] = 36] = "TaskStartFailed";
|
|
3066
|
+
MowerFault2[MowerFault2["PathImpassable"] = 37] = "PathImpassable";
|
|
3067
|
+
MowerFault2[MowerFault2["LidarDirtyWarning"] = 38] = "LidarDirtyWarning";
|
|
3068
|
+
MowerFault2[MowerFault2["CamDirty"] = 39] = "CamDirty";
|
|
3069
|
+
MowerFault2[MowerFault2["CamAbnormal"] = 40] = "CamAbnormal";
|
|
3070
|
+
MowerFault2[MowerFault2["CamCover"] = 41] = "CamCover";
|
|
3071
|
+
MowerFault2[MowerFault2["BatteryOverheatWarning"] = 42] = "BatteryOverheatWarning";
|
|
3072
|
+
MowerFault2[MowerFault2["BatteryTempLow"] = 43] = "BatteryTempLow";
|
|
3073
|
+
MowerFault2[MowerFault2["AutobuildBorder"] = 44] = "AutobuildBorder";
|
|
3074
|
+
MowerFault2[MowerFault2["AutobuildSide"] = 45] = "AutobuildSide";
|
|
3075
|
+
MowerFault2[MowerFault2["BorderFinish"] = 46] = "BorderFinish";
|
|
3076
|
+
MowerFault2[MowerFault2["NewMap"] = 47] = "NewMap";
|
|
3077
|
+
MowerFault2[MowerFault2["TaskFinish"] = 48] = "TaskFinish";
|
|
3078
|
+
MowerFault2[MowerFault2["DestinationNotReachable"] = 49] = "DestinationNotReachable";
|
|
3079
|
+
MowerFault2[MowerFault2["TaskStart"] = 50] = "TaskStart";
|
|
3080
|
+
MowerFault2[MowerFault2["CruiseStart"] = 51] = "CruiseStart";
|
|
3081
|
+
MowerFault2[MowerFault2["PointAndGoStart"] = 52] = "PointAndGoStart";
|
|
3082
|
+
MowerFault2[MowerFault2["ScheduleStart"] = 53] = "ScheduleStart";
|
|
3083
|
+
MowerFault2[MowerFault2["BatteryLowReturning"] = 54] = "BatteryLowReturning";
|
|
3084
|
+
MowerFault2[MowerFault2["BatteryLowScheduleSuspend"] = 55] = "BatteryLowScheduleSuspend";
|
|
3085
|
+
MowerFault2[MowerFault2["BadWeatherProtecting"] = 56] = "BadWeatherProtecting";
|
|
3086
|
+
MowerFault2[MowerFault2["RainScheduleInterupted"] = 57] = "RainScheduleInterupted";
|
|
3087
|
+
MowerFault2[MowerFault2["RainScheduleSuspend"] = 58] = "RainScheduleSuspend";
|
|
3088
|
+
MowerFault2[MowerFault2["ForzenReturning"] = 59] = "ForzenReturning";
|
|
3089
|
+
MowerFault2[MowerFault2["FrozenScheduleSuspend"] = 60] = "FrozenScheduleSuspend";
|
|
3090
|
+
MowerFault2[MowerFault2["NotDisturbReturning"] = 61] = "NotDisturbReturning";
|
|
3091
|
+
MowerFault2[MowerFault2["NotDisturbScheduleSuspend"] = 62] = "NotDisturbScheduleSuspend";
|
|
3092
|
+
MowerFault2[MowerFault2["WorkingScheduleSuspend"] = 63] = "WorkingScheduleSuspend";
|
|
3093
|
+
MowerFault2[MowerFault2["RemoteControlingScheduleSuspend"] = 64] = "RemoteControlingScheduleSuspend";
|
|
3094
|
+
MowerFault2[MowerFault2["EmergencyStoppedScheduleSuspend"] = 65] = "EmergencyStoppedScheduleSuspend";
|
|
3095
|
+
MowerFault2[MowerFault2["TopCoverOpenScheduleSuspend"] = 66] = "TopCoverOpenScheduleSuspend";
|
|
3096
|
+
MowerFault2[MowerFault2["FaultModeScheduleSuspend"] = 67] = "FaultModeScheduleSuspend";
|
|
3097
|
+
MowerFault2[MowerFault2["ScheduleTimeout"] = 68] = "ScheduleTimeout";
|
|
3098
|
+
MowerFault2[MowerFault2["StationNotConnectedToWorkingArea"] = 69] = "StationNotConnectedToWorkingArea";
|
|
3099
|
+
MowerFault2[MowerFault2["ContinueFromBreakpoint"] = 70] = "ContinueFromBreakpoint";
|
|
3100
|
+
MowerFault2[MowerFault2["IdleTimeoutReturning"] = 71] = "IdleTimeoutReturning";
|
|
3101
|
+
MowerFault2[MowerFault2["PauseTimeoutReturning"] = 72] = "PauseTimeoutReturning";
|
|
3102
|
+
MowerFault2[MowerFault2["TopCoverOpen"] = 73] = "TopCoverOpen";
|
|
3103
|
+
return MowerFault2;
|
|
3104
|
+
})(MowerFault || {});
|
|
2867
3105
|
|
|
2868
3106
|
// src/models/mower/decode.ts
|
|
2869
3107
|
function isRecord(v) {
|
|
@@ -3543,6 +3781,12 @@ var STATUS = enumLookup(
|
|
|
3543
3781
|
var CHARGING2 = enumLookup(
|
|
3544
3782
|
Object.values(MowerChargingStatus).filter((v) => typeof v === "number")
|
|
3545
3783
|
);
|
|
3784
|
+
var TASK_STATUS = enumLookup(
|
|
3785
|
+
Object.values(MowerTaskStatus).filter((v) => typeof v === "number")
|
|
3786
|
+
);
|
|
3787
|
+
var FAULT = enumLookup(
|
|
3788
|
+
Object.values(MowerFault).filter((v) => typeof v === "number")
|
|
3789
|
+
);
|
|
3546
3790
|
var MowerDevice = class _MowerDevice extends BaseDevice {
|
|
3547
3791
|
#caps;
|
|
3548
3792
|
#fetchBatch;
|
|
@@ -3591,6 +3835,25 @@ var MowerDevice = class _MowerDevice extends BaseDevice {
|
|
|
3591
3835
|
get taskStatusRaw() {
|
|
3592
3836
|
return this.#num(MOWER_PROP.TASK_STATUS.siid, MOWER_PROP.TASK_STATUS.piid);
|
|
3593
3837
|
}
|
|
3838
|
+
/**
|
|
3839
|
+
* TASK_STATUS (5:104) decoded to {@link MowerTaskStatus}, or null. The donor
|
|
3840
|
+
* names only code 7 (SpotIncomplete); codes 2/3/10/13 are documented "Unknown
|
|
3841
|
+
* task status" and intentionally surface as raw via {@link taskStatusRaw}.
|
|
3842
|
+
*/
|
|
3843
|
+
get taskStatus() {
|
|
3844
|
+
return TASK_STATUS(this.taskStatusRaw);
|
|
3845
|
+
}
|
|
3846
|
+
get faultRaw() {
|
|
3847
|
+
return this.#num(MOWER_PROP.DEVICE_CODE.siid, MOWER_PROP.DEVICE_CODE.piid);
|
|
3848
|
+
}
|
|
3849
|
+
/**
|
|
3850
|
+
* DEVICE_CODE (2:2) decoded to a {@link MowerFault} (the donor's
|
|
3851
|
+
* BASE_DEVICE_CODES registry, 0..73), or null for a model-specific/undocumented
|
|
3852
|
+
* code — which still surfaces as the raw number via {@link faultRaw}.
|
|
3853
|
+
*/
|
|
3854
|
+
get fault() {
|
|
3855
|
+
return FAULT(this.faultRaw);
|
|
3856
|
+
}
|
|
3594
3857
|
/** Parsed scheduling task descriptor (2:50), or null. */
|
|
3595
3858
|
get task() {
|
|
3596
3859
|
return parseTaskDescriptor(
|
|
@@ -3665,7 +3928,7 @@ var MowerDevice = class _MowerDevice extends BaseDevice {
|
|
|
3665
3928
|
if (zoneIds.length === 0) {
|
|
3666
3929
|
throw new RangeError("startMowingZones: zoneIds must not be empty");
|
|
3667
3930
|
}
|
|
3668
|
-
return this.#sendTask(buildZonePayload(zoneIds.map((
|
|
3931
|
+
return this.#sendTask(buildZonePayload(zoneIds.map((z4) => Math.trunc(z4))));
|
|
3669
3932
|
}
|
|
3670
3933
|
/** Edge / contour mowing (2:50 o:101). Contour ids are two-int pairs [[1,0]]. */
|
|
3671
3934
|
async startMowingEdges(contourIds) {
|
|
@@ -3733,6 +3996,7 @@ var MowerDevice = class _MowerDevice extends BaseDevice {
|
|
|
3733
3996
|
/** Props worth seeding on start() / polling — exported for the facade. */
|
|
3734
3997
|
static DEFAULT_PROPS = [
|
|
3735
3998
|
MOWER_PROP.STATUS,
|
|
3999
|
+
MOWER_PROP.DEVICE_CODE,
|
|
3736
4000
|
MOWER_PROP.BATTERY,
|
|
3737
4001
|
MOWER_PROP.CHARGING_STATUS,
|
|
3738
4002
|
MOWER_PROP.TASK_STATUS,
|
|
@@ -3888,6 +4152,429 @@ var Nodreame = class extends TypedEmitter {
|
|
|
3888
4152
|
await Promise.all(this.#devices.map((d) => d.applySession(session)));
|
|
3889
4153
|
}
|
|
3890
4154
|
};
|
|
4155
|
+
|
|
4156
|
+
// src/diagnostics/redact.ts
|
|
4157
|
+
var REDACTED = "[redacted]";
|
|
4158
|
+
var SENSITIVE_KEY_FRAGMENTS = [
|
|
4159
|
+
// identity / secrets
|
|
4160
|
+
"did",
|
|
4161
|
+
"uid",
|
|
4162
|
+
"token",
|
|
4163
|
+
// accessToken, refreshToken, refresh_token, token_type stripped too (safe)
|
|
4164
|
+
"mac",
|
|
4165
|
+
"serial",
|
|
4166
|
+
"email",
|
|
4167
|
+
"account",
|
|
4168
|
+
"password",
|
|
4169
|
+
"passwd",
|
|
4170
|
+
"secret",
|
|
4171
|
+
"authorization",
|
|
4172
|
+
"auth",
|
|
4173
|
+
"credential",
|
|
4174
|
+
"apikey",
|
|
4175
|
+
"api_key",
|
|
4176
|
+
"clientid",
|
|
4177
|
+
"client_id",
|
|
4178
|
+
// location / PII
|
|
4179
|
+
"gps",
|
|
4180
|
+
"coordinate",
|
|
4181
|
+
"latitude",
|
|
4182
|
+
"longitude",
|
|
4183
|
+
"lat",
|
|
4184
|
+
"lon",
|
|
4185
|
+
"lng",
|
|
4186
|
+
"ssid",
|
|
4187
|
+
"wifi",
|
|
4188
|
+
"bssid",
|
|
4189
|
+
"ipaddr",
|
|
4190
|
+
"localip",
|
|
4191
|
+
"binddomain",
|
|
4192
|
+
"host",
|
|
4193
|
+
"address",
|
|
4194
|
+
"room",
|
|
4195
|
+
"area_name",
|
|
4196
|
+
"areaname",
|
|
4197
|
+
"segmentname",
|
|
4198
|
+
"segment_name",
|
|
4199
|
+
// map binary / geometry (location-revealing)
|
|
4200
|
+
"map_info",
|
|
4201
|
+
"mapinfo",
|
|
4202
|
+
"mapblob",
|
|
4203
|
+
// free-text device names that may carry PII. NOTE: the bare fragment `name` is
|
|
4204
|
+
// intentionally NOT listed — it would over-match the catalog's command `name`
|
|
4205
|
+
// field (an enum-derived, non-sensitive label). The specific custom-name
|
|
4206
|
+
// fields below cover every PII-bearing case.
|
|
4207
|
+
"customname",
|
|
4208
|
+
"devicename",
|
|
4209
|
+
"nickname"
|
|
4210
|
+
];
|
|
4211
|
+
var EXACT_SENSITIVE_KEYS = /* @__PURE__ */ new Set(["ip"]);
|
|
4212
|
+
function isSensitiveKey(key2) {
|
|
4213
|
+
const lower = key2.toLowerCase();
|
|
4214
|
+
if (EXACT_SENSITIVE_KEYS.has(lower)) {
|
|
4215
|
+
return true;
|
|
4216
|
+
}
|
|
4217
|
+
return SENSITIVE_KEY_FRAGMENTS.some((frag) => lower.includes(frag));
|
|
4218
|
+
}
|
|
4219
|
+
function isPlainObject(v) {
|
|
4220
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
4221
|
+
}
|
|
4222
|
+
function redact(value) {
|
|
4223
|
+
if (Array.isArray(value)) {
|
|
4224
|
+
return value.map((v) => redact(v));
|
|
4225
|
+
}
|
|
4226
|
+
if (isPlainObject(value)) {
|
|
4227
|
+
const out = {};
|
|
4228
|
+
for (const [k, v] of Object.entries(value)) {
|
|
4229
|
+
out[k] = isSensitiveKey(k) ? REDACTED : redact(v);
|
|
4230
|
+
}
|
|
4231
|
+
return out;
|
|
4232
|
+
}
|
|
4233
|
+
return value;
|
|
4234
|
+
}
|
|
4235
|
+
|
|
4236
|
+
// src/diagnostics/dump-format.ts
|
|
4237
|
+
var import_zod3 = require("zod");
|
|
4238
|
+
var DumpScalarSchema = import_zod3.z.union([import_zod3.z.string(), import_zod3.z.number(), import_zod3.z.boolean()]);
|
|
4239
|
+
var PropertyObservationSchema = import_zod3.z.object({
|
|
4240
|
+
values: import_zod3.z.array(DumpScalarSchema),
|
|
4241
|
+
unmapped: import_zod3.z.array(DumpScalarSchema),
|
|
4242
|
+
enum: import_zod3.z.string().optional(),
|
|
4243
|
+
count: import_zod3.z.number(),
|
|
4244
|
+
firstSeen: import_zod3.z.number(),
|
|
4245
|
+
lastSeen: import_zod3.z.number()
|
|
4246
|
+
});
|
|
4247
|
+
var EventObservationSchema = import_zod3.z.object({
|
|
4248
|
+
at: import_zod3.z.number(),
|
|
4249
|
+
type: import_zod3.z.string(),
|
|
4250
|
+
data: import_zod3.z.unknown().optional()
|
|
4251
|
+
});
|
|
4252
|
+
var RawFrameSchema = import_zod3.z.object({
|
|
4253
|
+
at: import_zod3.z.number(),
|
|
4254
|
+
source: import_zod3.z.string(),
|
|
4255
|
+
payload: import_zod3.z.unknown()
|
|
4256
|
+
});
|
|
4257
|
+
var CommandSchema = import_zod3.z.object({
|
|
4258
|
+
name: import_zod3.z.string(),
|
|
4259
|
+
siid: import_zod3.z.number().optional(),
|
|
4260
|
+
aiid: import_zod3.z.number().optional()
|
|
4261
|
+
});
|
|
4262
|
+
var SensorSchema = import_zod3.z.object({
|
|
4263
|
+
model: import_zod3.z.string(),
|
|
4264
|
+
channel: import_zod3.z.number().optional()
|
|
4265
|
+
});
|
|
4266
|
+
var DeviceDumpSchema = import_zod3.z.object({
|
|
4267
|
+
schemaVersion: import_zod3.z.literal(1),
|
|
4268
|
+
library: import_zod3.z.union([import_zod3.z.literal("nodedreame"), import_zod3.z.literal("nodewitt")]),
|
|
4269
|
+
libraryVersion: import_zod3.z.string(),
|
|
4270
|
+
device: import_zod3.z.object({
|
|
4271
|
+
model: import_zod3.z.string(),
|
|
4272
|
+
firmware: import_zod3.z.string().optional(),
|
|
4273
|
+
region: import_zod3.z.string().optional(),
|
|
4274
|
+
type: import_zod3.z.string().optional()
|
|
4275
|
+
}),
|
|
4276
|
+
observations: import_zod3.z.object({
|
|
4277
|
+
properties: import_zod3.z.record(import_zod3.z.string(), PropertyObservationSchema),
|
|
4278
|
+
events: import_zod3.z.array(EventObservationSchema),
|
|
4279
|
+
rawFrames: import_zod3.z.array(RawFrameSchema).optional()
|
|
4280
|
+
}),
|
|
4281
|
+
catalog: import_zod3.z.object({
|
|
4282
|
+
commands: import_zod3.z.array(CommandSchema).optional(),
|
|
4283
|
+
capabilities: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).optional(),
|
|
4284
|
+
sensors: import_zod3.z.array(SensorSchema).optional()
|
|
4285
|
+
}),
|
|
4286
|
+
meta: import_zod3.z.object({
|
|
4287
|
+
startedAt: import_zod3.z.number(),
|
|
4288
|
+
durationMs: import_zod3.z.number(),
|
|
4289
|
+
generatedAt: import_zod3.z.number()
|
|
4290
|
+
})
|
|
4291
|
+
});
|
|
4292
|
+
|
|
4293
|
+
// src/diagnostics/dumper.ts
|
|
4294
|
+
function commandsForFamily(family) {
|
|
4295
|
+
const commands = [];
|
|
4296
|
+
if (family === "vacuum") {
|
|
4297
|
+
for (const [name, ref] of Object.entries(VACUUM_ACTION)) {
|
|
4298
|
+
commands.push({ name, siid: ref.siid, aiid: ref.aiid });
|
|
4299
|
+
}
|
|
4300
|
+
} else if (family === "mower") {
|
|
4301
|
+
for (const [name, ref] of Object.entries(MOWER_ACTION)) {
|
|
4302
|
+
commands.push({ name, siid: ref.siid, aiid: ref.aiid });
|
|
4303
|
+
}
|
|
4304
|
+
}
|
|
4305
|
+
return commands;
|
|
4306
|
+
}
|
|
4307
|
+
function decoderFor(enumName, members) {
|
|
4308
|
+
const lookup = enumLookup(members);
|
|
4309
|
+
return { enumName, isMember: (raw) => lookup(raw) !== null };
|
|
4310
|
+
}
|
|
4311
|
+
function vacuumDecoders() {
|
|
4312
|
+
return {
|
|
4313
|
+
"2.1": decoderFor(
|
|
4314
|
+
"MiotState",
|
|
4315
|
+
Object.values(MiotState).filter((v) => typeof v === "number")
|
|
4316
|
+
),
|
|
4317
|
+
"3.2": decoderFor(
|
|
4318
|
+
"ChargingStatus",
|
|
4319
|
+
Object.values(ChargingStatus).filter((v) => typeof v === "number")
|
|
4320
|
+
),
|
|
4321
|
+
"4.4": decoderFor(
|
|
4322
|
+
"SuctionLevel",
|
|
4323
|
+
Object.values(SuctionLevel).filter((v) => typeof v === "number")
|
|
4324
|
+
),
|
|
4325
|
+
"4.5": decoderFor(
|
|
4326
|
+
"WaterVolume",
|
|
4327
|
+
Object.values(WaterVolume).filter((v) => typeof v === "number")
|
|
4328
|
+
),
|
|
4329
|
+
"2.6": decoderFor(
|
|
4330
|
+
"CleaningMode",
|
|
4331
|
+
Object.values(CleaningMode).filter((v) => typeof v === "number")
|
|
4332
|
+
),
|
|
4333
|
+
"4.1": decoderFor(
|
|
4334
|
+
"TaskStatus",
|
|
4335
|
+
Object.values(TaskStatus).filter((v) => typeof v === "number")
|
|
4336
|
+
)
|
|
4337
|
+
};
|
|
4338
|
+
}
|
|
4339
|
+
function mowerDecoders() {
|
|
4340
|
+
return {
|
|
4341
|
+
"2.1": decoderFor(
|
|
4342
|
+
"MowerStatus",
|
|
4343
|
+
Object.values(MowerStatus).filter((v) => typeof v === "number")
|
|
4344
|
+
),
|
|
4345
|
+
"3.2": decoderFor(
|
|
4346
|
+
"MowerChargingStatus",
|
|
4347
|
+
Object.values(MowerChargingStatus).filter(
|
|
4348
|
+
(v) => typeof v === "number"
|
|
4349
|
+
)
|
|
4350
|
+
),
|
|
4351
|
+
"5.104": decoderFor(
|
|
4352
|
+
"MowerTaskStatus",
|
|
4353
|
+
Object.values(MowerTaskStatus).filter((v) => typeof v === "number")
|
|
4354
|
+
),
|
|
4355
|
+
"2.2": decoderFor(
|
|
4356
|
+
"MowerFault",
|
|
4357
|
+
Object.values(MowerFault).filter((v) => typeof v === "number")
|
|
4358
|
+
)
|
|
4359
|
+
};
|
|
4360
|
+
}
|
|
4361
|
+
function toScalar(value) {
|
|
4362
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
4363
|
+
return value;
|
|
4364
|
+
}
|
|
4365
|
+
return null;
|
|
4366
|
+
}
|
|
4367
|
+
var PropertyAccumulator = class {
|
|
4368
|
+
#decoders;
|
|
4369
|
+
#entries = /* @__PURE__ */ new Map();
|
|
4370
|
+
constructor(decoders = {}) {
|
|
4371
|
+
this.#decoders = decoders;
|
|
4372
|
+
}
|
|
4373
|
+
record(siid, piid, rawValue, at) {
|
|
4374
|
+
const key2 = `${siid}.${piid}`;
|
|
4375
|
+
const scalar = toScalar(rawValue);
|
|
4376
|
+
let entry = this.#entries.get(key2);
|
|
4377
|
+
if (!entry) {
|
|
4378
|
+
entry = { values: [], unmapped: [], count: 0, firstSeen: at, lastSeen: at };
|
|
4379
|
+
this.#entries.set(key2, entry);
|
|
4380
|
+
}
|
|
4381
|
+
entry.count += 1;
|
|
4382
|
+
entry.lastSeen = at;
|
|
4383
|
+
if (scalar === null) {
|
|
4384
|
+
return;
|
|
4385
|
+
}
|
|
4386
|
+
if (!entry.values.includes(scalar)) {
|
|
4387
|
+
entry.values.push(scalar);
|
|
4388
|
+
}
|
|
4389
|
+
const decoder = this.#decoders[key2];
|
|
4390
|
+
if (decoder && typeof scalar === "number" && !decoder.isMember(scalar)) {
|
|
4391
|
+
if (!entry.unmapped.includes(scalar)) {
|
|
4392
|
+
entry.unmapped.push(scalar);
|
|
4393
|
+
}
|
|
4394
|
+
}
|
|
4395
|
+
}
|
|
4396
|
+
snapshot() {
|
|
4397
|
+
const out = {};
|
|
4398
|
+
for (const [key2, e] of this.#entries) {
|
|
4399
|
+
const decoder = this.#decoders[key2];
|
|
4400
|
+
const base = {
|
|
4401
|
+
values: [...e.values],
|
|
4402
|
+
unmapped: [...e.unmapped],
|
|
4403
|
+
count: e.count,
|
|
4404
|
+
firstSeen: e.firstSeen,
|
|
4405
|
+
lastSeen: e.lastSeen
|
|
4406
|
+
};
|
|
4407
|
+
out[key2] = decoder ? { ...base, enum: decoder.enumName } : base;
|
|
4408
|
+
}
|
|
4409
|
+
return out;
|
|
4410
|
+
}
|
|
4411
|
+
};
|
|
4412
|
+
var DEFAULT_REFRESH_INTERVAL_MS = 3e4;
|
|
4413
|
+
var DEFAULT_MAX_RAW_FRAMES = 500;
|
|
4414
|
+
var Dumper = class {
|
|
4415
|
+
#device;
|
|
4416
|
+
#opts;
|
|
4417
|
+
#acc;
|
|
4418
|
+
#events = [];
|
|
4419
|
+
#rawFrames = [];
|
|
4420
|
+
#catalog;
|
|
4421
|
+
#type;
|
|
4422
|
+
#onProperty;
|
|
4423
|
+
#onEvent;
|
|
4424
|
+
#timer = null;
|
|
4425
|
+
#startedAt = 0;
|
|
4426
|
+
#started = false;
|
|
4427
|
+
constructor(device, catalog, type, decoders, options = {}) {
|
|
4428
|
+
this.#device = device;
|
|
4429
|
+
this.#catalog = catalog;
|
|
4430
|
+
this.#type = type;
|
|
4431
|
+
this.#acc = new PropertyAccumulator(decoders);
|
|
4432
|
+
this.#opts = {
|
|
4433
|
+
captureRawFrames: options.captureRawFrames ?? false,
|
|
4434
|
+
maxRawFrames: options.maxRawFrames ?? DEFAULT_MAX_RAW_FRAMES,
|
|
4435
|
+
refreshIntervalMs: options.refreshIntervalMs ?? DEFAULT_REFRESH_INTERVAL_MS
|
|
4436
|
+
};
|
|
4437
|
+
this.#onProperty = (e) => {
|
|
4438
|
+
this.#acc.record(e.siid, e.piid, e.value, Date.now());
|
|
4439
|
+
this.#pushRaw("mqtt:property", e);
|
|
4440
|
+
};
|
|
4441
|
+
this.#onEvent = (e) => {
|
|
4442
|
+
this.#events.push({
|
|
4443
|
+
at: Date.now(),
|
|
4444
|
+
type: `${e.siid}.${e.eiid}`,
|
|
4445
|
+
data: { arguments: e.arguments }
|
|
4446
|
+
});
|
|
4447
|
+
this.#pushRaw("mqtt:event", e);
|
|
4448
|
+
};
|
|
4449
|
+
}
|
|
4450
|
+
/** Attach to the live stream + arm the periodic shadow refresh. Idempotent. */
|
|
4451
|
+
async start() {
|
|
4452
|
+
if (this.#started) {
|
|
4453
|
+
return;
|
|
4454
|
+
}
|
|
4455
|
+
this.#started = true;
|
|
4456
|
+
this.#startedAt = Date.now();
|
|
4457
|
+
this.#device.on("propertyChanged", this.#onProperty);
|
|
4458
|
+
this.#device.on("event", this.#onEvent);
|
|
4459
|
+
await this.#refresh();
|
|
4460
|
+
if (this.#opts.refreshIntervalMs > 0 && this.#device.refreshFromCache) {
|
|
4461
|
+
this.#timer = setInterval(() => void this.#refresh(), this.#opts.refreshIntervalMs);
|
|
4462
|
+
this.#timer.unref?.();
|
|
4463
|
+
}
|
|
4464
|
+
}
|
|
4465
|
+
/** Detach every listener + clear the timer. Idempotent. */
|
|
4466
|
+
stop() {
|
|
4467
|
+
if (!this.#started) {
|
|
4468
|
+
return Promise.resolve();
|
|
4469
|
+
}
|
|
4470
|
+
this.#started = false;
|
|
4471
|
+
if (this.#timer) {
|
|
4472
|
+
clearInterval(this.#timer);
|
|
4473
|
+
this.#timer = null;
|
|
4474
|
+
}
|
|
4475
|
+
this.#device.off("propertyChanged", this.#onProperty);
|
|
4476
|
+
this.#device.off("event", this.#onEvent);
|
|
4477
|
+
return Promise.resolve();
|
|
4478
|
+
}
|
|
4479
|
+
/** Build the anonymized, schema-valid dump. Works live or after {@link stop}. */
|
|
4480
|
+
export() {
|
|
4481
|
+
const now = Date.now();
|
|
4482
|
+
const dump = {
|
|
4483
|
+
schemaVersion: 1,
|
|
4484
|
+
library: "nodedreame",
|
|
4485
|
+
libraryVersion: LIBRARY_VERSION,
|
|
4486
|
+
device: {
|
|
4487
|
+
model: this.#device.model,
|
|
4488
|
+
type: this.#type
|
|
4489
|
+
},
|
|
4490
|
+
observations: {
|
|
4491
|
+
properties: this.#acc.snapshot(),
|
|
4492
|
+
events: [...this.#events],
|
|
4493
|
+
...this.#opts.captureRawFrames ? { rawFrames: this.#redactFrames() } : {}
|
|
4494
|
+
},
|
|
4495
|
+
catalog: this.#catalog,
|
|
4496
|
+
meta: {
|
|
4497
|
+
startedAt: this.#startedAt,
|
|
4498
|
+
durationMs: Math.max(0, now - this.#startedAt),
|
|
4499
|
+
generatedAt: now
|
|
4500
|
+
}
|
|
4501
|
+
};
|
|
4502
|
+
const anonymized = redact(dump);
|
|
4503
|
+
return DeviceDumpSchema.parse(anonymized);
|
|
4504
|
+
}
|
|
4505
|
+
/** Deterministic pretty JSON of {@link export}. */
|
|
4506
|
+
exportJson() {
|
|
4507
|
+
return JSON.stringify(this.export(), null, 2);
|
|
4508
|
+
}
|
|
4509
|
+
async #refresh() {
|
|
4510
|
+
if (this.#device.refreshFromCache) {
|
|
4511
|
+
try {
|
|
4512
|
+
await this.#device.refreshFromCache();
|
|
4513
|
+
} catch {
|
|
4514
|
+
}
|
|
4515
|
+
}
|
|
4516
|
+
}
|
|
4517
|
+
#pushRaw(source, payload) {
|
|
4518
|
+
if (!this.#opts.captureRawFrames) {
|
|
4519
|
+
return;
|
|
4520
|
+
}
|
|
4521
|
+
this.#rawFrames.push({ at: Date.now(), source, payload });
|
|
4522
|
+
if (this.#rawFrames.length > this.#opts.maxRawFrames) {
|
|
4523
|
+
this.#rawFrames.shift();
|
|
4524
|
+
}
|
|
4525
|
+
}
|
|
4526
|
+
#redactFrames() {
|
|
4527
|
+
return this.#rawFrames.map((f) => ({ at: f.at, source: f.source, payload: redact(f.payload) }));
|
|
4528
|
+
}
|
|
4529
|
+
};
|
|
4530
|
+
function familyOf(device) {
|
|
4531
|
+
if (device instanceof VacuumDevice) {
|
|
4532
|
+
return "vacuum";
|
|
4533
|
+
}
|
|
4534
|
+
if (device instanceof MowerDevice) {
|
|
4535
|
+
return "mower";
|
|
4536
|
+
}
|
|
4537
|
+
if (!(device instanceof BaseDevice)) {
|
|
4538
|
+
if (device.model.startsWith("dreame.vacuum.")) {
|
|
4539
|
+
return "vacuum";
|
|
4540
|
+
}
|
|
4541
|
+
if (device.model.startsWith("dreame.mower.")) {
|
|
4542
|
+
return "mower";
|
|
4543
|
+
}
|
|
4544
|
+
}
|
|
4545
|
+
return "device";
|
|
4546
|
+
}
|
|
4547
|
+
function decodersFor(device) {
|
|
4548
|
+
switch (familyOf(device)) {
|
|
4549
|
+
case "vacuum":
|
|
4550
|
+
return vacuumDecoders();
|
|
4551
|
+
case "mower":
|
|
4552
|
+
return mowerDecoders();
|
|
4553
|
+
default:
|
|
4554
|
+
return {};
|
|
4555
|
+
}
|
|
4556
|
+
}
|
|
4557
|
+
function typeFor(device) {
|
|
4558
|
+
return familyOf(device);
|
|
4559
|
+
}
|
|
4560
|
+
function catalogFor(device) {
|
|
4561
|
+
return {
|
|
4562
|
+
commands: commandsForFamily(familyOf(device)),
|
|
4563
|
+
capabilities: { tokens: [...device.capabilities.list()] }
|
|
4564
|
+
};
|
|
4565
|
+
}
|
|
4566
|
+
function createDumper(target, options) {
|
|
4567
|
+
return new Dumper(
|
|
4568
|
+
target,
|
|
4569
|
+
catalogFor(target),
|
|
4570
|
+
typeFor(target),
|
|
4571
|
+
decodersFor(target),
|
|
4572
|
+
options ?? {}
|
|
4573
|
+
);
|
|
4574
|
+
}
|
|
4575
|
+
function createClientDumper(client, options) {
|
|
4576
|
+
return client.devices.map((d) => createDumper(d, options));
|
|
4577
|
+
}
|
|
3891
4578
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3892
4579
|
0 && (module.exports = {
|
|
3893
4580
|
BaseDevice,
|
|
@@ -3907,6 +4594,7 @@ var Nodreame = class extends TypedEmitter {
|
|
|
3907
4594
|
MowerChargingStatus,
|
|
3908
4595
|
MowerControlAction,
|
|
3909
4596
|
MowerDevice,
|
|
4597
|
+
MowerFault,
|
|
3910
4598
|
MowerStatus,
|
|
3911
4599
|
MowerTaskStatus,
|
|
3912
4600
|
Nodreame,
|
|
@@ -3916,6 +4604,8 @@ var Nodreame = class extends TypedEmitter {
|
|
|
3916
4604
|
VacuumCapabilityResolver,
|
|
3917
4605
|
VacuumDevice,
|
|
3918
4606
|
WaterVolume,
|
|
4607
|
+
createClientDumper,
|
|
4608
|
+
createDumper,
|
|
3919
4609
|
getMowerCapabilities,
|
|
3920
4610
|
getVacuumCapabilities,
|
|
3921
4611
|
renderMowerSvg,
|