@apocaliss92/nodedreame 1.0.0 → 1.2.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/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,
@@ -351,6 +352,16 @@ var PropertyResultSchema = import_zod.z.object({
351
352
  value: import_zod.z.unknown().optional(),
352
353
  code: import_zod.z.number().optional()
353
354
  }).passthrough();
355
+ var CachedPropEntrySchema = import_zod.z.object({
356
+ key: import_zod.z.string(),
357
+ value: import_zod.z.unknown().optional(),
358
+ updateDate: import_zod.z.number().optional()
359
+ }).passthrough();
360
+ var CachedPropsResponseSchema = import_zod.z.object({
361
+ code: import_zod.z.number().optional(),
362
+ msg: import_zod.z.string().optional(),
363
+ data: import_zod.z.array(CachedPropEntrySchema).optional()
364
+ }).passthrough();
354
365
  var SendCommandResponseSchema = import_zod.z.object({
355
366
  code: import_zod.z.number().optional(),
356
367
  msg: import_zod.z.string().optional(),
@@ -540,6 +551,57 @@ async function getProperties(base, props, opts = {}) {
540
551
  const res = await sendCommand({ ...base, ...opts, method: "get_properties", params });
541
552
  return extractResultArray(res, "get_properties");
542
553
  }
554
+ async function getCachedProperties(base, props, opts = {}) {
555
+ const ctx = base.ctx ?? RequestContext.from({ ...base, host: base.apiHost });
556
+ const keys = props.map((p) => `${p.siid}.${p.piid}`).join(",");
557
+ const signal = opts.signal ?? base.signal;
558
+ const timeoutMs = opts.timeoutMs ?? base.timeoutMs;
559
+ const raw = await httpPostJsonBody({
560
+ ctx,
561
+ path: "/dreame-user-iot/iotstatus/props",
562
+ accessToken: base.session.accessToken,
563
+ body: { did: base.did, keys },
564
+ context: "cached properties",
565
+ ...signal !== void 0 ? { signal } : {},
566
+ ...timeoutMs !== void 0 ? { timeoutMs } : {}
567
+ });
568
+ const parsed = CachedPropsResponseSchema.parse(raw);
569
+ if (parsed.code !== void 0 && parsed.code !== 0) {
570
+ throw new DreameApiError(
571
+ `cached properties rejected: code=${parsed.code} msg=${parsed.msg ?? "?"}`,
572
+ 200,
573
+ parsed
574
+ );
575
+ }
576
+ return (parsed.data ?? []).flatMap((entry) => {
577
+ const [siidStr, piidStr] = entry.key.split(".");
578
+ const siid = Number(siidStr);
579
+ const piid = Number(piidStr);
580
+ if (!Number.isFinite(siid) || !Number.isFinite(piid)) {
581
+ return [];
582
+ }
583
+ const result = { siid, piid, value: coerceShadowValue(entry.value) };
584
+ if (entry.updateDate !== void 0) {
585
+ result.updateDate = entry.updateDate;
586
+ }
587
+ return [result];
588
+ });
589
+ }
590
+ function coerceShadowValue(value) {
591
+ if (typeof value !== "string") {
592
+ return value;
593
+ }
594
+ if (value === "true") {
595
+ return true;
596
+ }
597
+ if (value === "false") {
598
+ return false;
599
+ }
600
+ if (value.trim() !== "" && Number.isFinite(Number(value))) {
601
+ return Number(value);
602
+ }
603
+ return value;
604
+ }
543
605
  async function setProperties(base, writes, opts = {}) {
544
606
  const params = writes.map((p) => ({
545
607
  did: base.did,
@@ -917,6 +979,7 @@ function defaultBaseDeviceDeps() {
917
979
  return {
918
980
  createPush: (device, session, region) => new DreamePush({ device, session, region }),
919
981
  getProperties: (base, props) => getProperties(base, props),
982
+ getCachedProperties: (base, props) => getCachedProperties(base, props),
920
983
  setProperties: (base, writes) => setProperties(base, writes),
921
984
  callAction: (base, action) => callAction(base, action)
922
985
  };
@@ -1005,6 +1068,23 @@ var BaseDevice = class extends TypedEmitter {
1005
1068
  async refreshProperties(props) {
1006
1069
  this.#assertOpen();
1007
1070
  const results = await this.#deps.getProperties(this.#base(), props);
1071
+ this.#seedFromResults(results);
1072
+ return results;
1073
+ }
1074
+ /**
1075
+ * Read the CLOUD-CACHED (shadow) values of `props` WITHOUT waking the device,
1076
+ * update the cache, and emit `propertyChanged`/`stateChanged` just like
1077
+ * {@link refreshProperties} — but sourced from the cloud shadow endpoint, so
1078
+ * it works for standby/offline robots (and never surfaces a false 80001).
1079
+ */
1080
+ async refreshCachedProperties(props) {
1081
+ this.#assertOpen();
1082
+ const results = await this.#deps.getCachedProperties(this.#base(), props);
1083
+ this.#seedFromResults(results);
1084
+ return results;
1085
+ }
1086
+ /** Mirror a PropertyResult[] into the cache + emit the change events. */
1087
+ #seedFromResults(results) {
1008
1088
  const changes = [];
1009
1089
  for (const r of results) {
1010
1090
  if (typeof r.siid === "number" && typeof r.piid === "number") {
@@ -1014,7 +1094,6 @@ var BaseDevice = class extends TypedEmitter {
1014
1094
  if (changes.length > 0) {
1015
1095
  this.#onProperties(changes);
1016
1096
  }
1017
- return results;
1018
1097
  }
1019
1098
  /** Write a property to the device. */
1020
1099
  async setProperty(write) {
@@ -1214,11 +1293,27 @@ var MiotState = /* @__PURE__ */ ((MiotState2) => {
1214
1293
  MiotState2[MiotState2["ReturnToEmpty"] = 28] = "ReturnToEmpty";
1215
1294
  MiotState2[MiotState2["WaitingForTask"] = 29] = "WaitingForTask";
1216
1295
  MiotState2[MiotState2["CleanWashboardBase"] = 30] = "CleanWashboardBase";
1296
+ MiotState2[MiotState2["ReturningToDrain"] = 31] = "ReturningToDrain";
1297
+ MiotState2[MiotState2["Draining"] = 32] = "Draining";
1217
1298
  MiotState2[MiotState2["AutoWaterDraining"] = 33] = "AutoWaterDraining";
1299
+ MiotState2[MiotState2["Emptying"] = 34] = "Emptying";
1300
+ MiotState2[MiotState2["DustBagDrying"] = 35] = "DustBagDrying";
1301
+ MiotState2[MiotState2["DustBagDryingPaused"] = 36] = "DustBagDryingPaused";
1302
+ MiotState2[MiotState2["HeadingToExtraCleaning"] = 37] = "HeadingToExtraCleaning";
1303
+ MiotState2[MiotState2["ExtraCleaning"] = 38] = "ExtraCleaning";
1304
+ MiotState2[MiotState2["FindingPetPaused"] = 95] = "FindingPetPaused";
1305
+ MiotState2[MiotState2["FindingPet"] = 96] = "FindingPet";
1218
1306
  MiotState2[MiotState2["ShortcutRunning"] = 97] = "ShortcutRunning";
1219
1307
  MiotState2[MiotState2["CameraMonitoring"] = 98] = "CameraMonitoring";
1220
1308
  MiotState2[MiotState2["CameraMonitoringPaused"] = 99] = "CameraMonitoringPaused";
1221
1309
  MiotState2[MiotState2["InitialDeepClean"] = 101] = "InitialDeepClean";
1310
+ MiotState2[MiotState2["InitialDeepCleanPaused"] = 102] = "InitialDeepCleanPaused";
1311
+ MiotState2[MiotState2["Sanitizing"] = 103] = "Sanitizing";
1312
+ MiotState2[MiotState2["SanitizingWithDry"] = 104] = "SanitizingWithDry";
1313
+ MiotState2[MiotState2["ChangingMop"] = 105] = "ChangingMop";
1314
+ MiotState2[MiotState2["ChangingMopPaused"] = 106] = "ChangingMopPaused";
1315
+ MiotState2[MiotState2["FloorMaintaining"] = 107] = "FloorMaintaining";
1316
+ MiotState2[MiotState2["FloorMaintainingPaused"] = 108] = "FloorMaintainingPaused";
1222
1317
  return MiotState2;
1223
1318
  })(MiotState || {});
1224
1319
  var ChargingStatus = /* @__PURE__ */ ((ChargingStatus2) => {
@@ -1250,21 +1345,87 @@ var CleaningMode = /* @__PURE__ */ ((CleaningMode2) => {
1250
1345
  var MiotError = /* @__PURE__ */ ((MiotError2) => {
1251
1346
  MiotError2[MiotError2["Clear"] = 0] = "Clear";
1252
1347
  MiotError2[MiotError2["WheelRotationAnomaly"] = 1] = "WheelRotationAnomaly";
1348
+ MiotError2[MiotError2["Cliff"] = 2] = "Cliff";
1349
+ MiotError2[MiotError2["Bumper"] = 3] = "Bumper";
1350
+ MiotError2[MiotError2["Gesture"] = 4] = "Gesture";
1351
+ MiotError2[MiotError2["BumperRepeat"] = 5] = "BumperRepeat";
1352
+ MiotError2[MiotError2["DropRepeat"] = 6] = "DropRepeat";
1353
+ MiotError2[MiotError2["OpticalFlow"] = 7] = "OpticalFlow";
1354
+ MiotError2[MiotError2["Box"] = 8] = "Box";
1355
+ MiotError2[MiotError2["TankBox"] = 9] = "TankBox";
1356
+ MiotError2[MiotError2["WaterBoxEmpty"] = 10] = "WaterBoxEmpty";
1357
+ MiotError2[MiotError2["BoxFull"] = 11] = "BoxFull";
1358
+ MiotError2[MiotError2["Brush"] = 12] = "Brush";
1359
+ MiotError2[MiotError2["SideBrush"] = 13] = "SideBrush";
1360
+ MiotError2[MiotError2["Fan"] = 14] = "Fan";
1361
+ MiotError2[MiotError2["LeftWheelMotor"] = 15] = "LeftWheelMotor";
1362
+ MiotError2[MiotError2["RightWheelMotor"] = 16] = "RightWheelMotor";
1363
+ MiotError2[MiotError2["TurnSuffocate"] = 17] = "TurnSuffocate";
1253
1364
  MiotError2[MiotError2["RobotLifted"] = 18] = "RobotLifted";
1254
- MiotError2[MiotError2["TaskComplete"] = 68] = "TaskComplete";
1255
- MiotError2[MiotError2["ManualMopInstallRequired"] = 74] = "ManualMopInstallRequired";
1256
- MiotError2[MiotError2["WastewaterTankFull"] = 105] = "WastewaterTankFull";
1257
- MiotError2[MiotError2["CleanWaterTankEmpty"] = 107] = "CleanWaterTankEmpty";
1258
- MiotError2[MiotError2["WashboardFilterNeedsCleaning"] = 114] = "WashboardFilterNeedsCleaning";
1259
- MiotError2[MiotError2["MopPadsMissing"] = 120] = "MopPadsMissing";
1365
+ MiotError2[MiotError2["ChargerGet"] = 19] = "ChargerGet";
1260
1366
  MiotError2[MiotError2["BatteryLow"] = 20] = "BatteryLow";
1261
1367
  MiotError2[MiotError2["ChargeFault"] = 21] = "ChargeFault";
1262
1368
  MiotError2[MiotError2["BatteryPercentageAnomaly"] = 22] = "BatteryPercentageAnomaly";
1369
+ MiotError2[MiotError2["Heart"] = 23] = "Heart";
1370
+ MiotError2[MiotError2["CameraOcclusion"] = 24] = "CameraOcclusion";
1371
+ MiotError2[MiotError2["Move"] = 25] = "Move";
1372
+ MiotError2[MiotError2["FlowShielding"] = 26] = "FlowShielding";
1373
+ MiotError2[MiotError2["InfraredShielding"] = 27] = "InfraredShielding";
1263
1374
  MiotError2[MiotError2["ChargeNoElectric"] = 28] = "ChargeNoElectric";
1264
1375
  MiotError2[MiotError2["BatteryFault"] = 29] = "BatteryFault";
1376
+ MiotError2[MiotError2["FanSpeedError"] = 30] = "FanSpeedError";
1377
+ MiotError2[MiotError2["LeftWheelSpeed"] = 31] = "LeftWheelSpeed";
1378
+ MiotError2[MiotError2["RightWheelSpeed"] = 32] = "RightWheelSpeed";
1379
+ MiotError2[MiotError2["Bmi055Acce"] = 33] = "Bmi055Acce";
1380
+ MiotError2[MiotError2["Bmi055Gyro"] = 34] = "Bmi055Gyro";
1381
+ MiotError2[MiotError2["Xv7001"] = 35] = "Xv7001";
1382
+ MiotError2[MiotError2["LeftMagnet"] = 36] = "LeftMagnet";
1383
+ MiotError2[MiotError2["RightMagnet"] = 37] = "RightMagnet";
1384
+ MiotError2[MiotError2["FlowError"] = 38] = "FlowError";
1385
+ MiotError2[MiotError2["InfraredFault"] = 39] = "InfraredFault";
1386
+ MiotError2[MiotError2["CameraFault"] = 40] = "CameraFault";
1387
+ MiotError2[MiotError2["StrongMagnet"] = 41] = "StrongMagnet";
1388
+ MiotError2[MiotError2["WaterPump"] = 42] = "WaterPump";
1389
+ MiotError2[MiotError2["Rtc"] = 43] = "Rtc";
1390
+ MiotError2[MiotError2["AutoKeyTrig"] = 44] = "AutoKeyTrig";
1391
+ MiotError2[MiotError2["P3v3"] = 45] = "P3v3";
1392
+ MiotError2[MiotError2["CameraIdle"] = 46] = "CameraIdle";
1393
+ MiotError2[MiotError2["Blocked"] = 47] = "Blocked";
1394
+ MiotError2[MiotError2["LdsError"] = 48] = "LdsError";
1395
+ MiotError2[MiotError2["LdsBumper"] = 49] = "LdsBumper";
1396
+ MiotError2[MiotError2["WaterPump2"] = 50] = "WaterPump2";
1397
+ MiotError2[MiotError2["FilterBlocked"] = 51] = "FilterBlocked";
1398
+ MiotError2[MiotError2["Edge"] = 54] = "Edge";
1399
+ MiotError2[MiotError2["Carpet"] = 55] = "Carpet";
1400
+ MiotError2[MiotError2["Laser"] = 56] = "Laser";
1401
+ MiotError2[MiotError2["Edge2"] = 57] = "Edge2";
1402
+ MiotError2[MiotError2["Ultrasonic"] = 58] = "Ultrasonic";
1403
+ MiotError2[MiotError2["NoGoZone"] = 59] = "NoGoZone";
1404
+ MiotError2[MiotError2["Route"] = 61] = "Route";
1405
+ MiotError2[MiotError2["Route2"] = 62] = "Route2";
1406
+ MiotError2[MiotError2["Blocked2"] = 63] = "Blocked2";
1407
+ MiotError2[MiotError2["Blocked3"] = 64] = "Blocked3";
1408
+ MiotError2[MiotError2["Restricted"] = 65] = "Restricted";
1409
+ MiotError2[MiotError2["Restricted2"] = 66] = "Restricted2";
1410
+ MiotError2[MiotError2["Restricted3"] = 67] = "Restricted3";
1411
+ MiotError2[MiotError2["TaskComplete"] = 68] = "TaskComplete";
1412
+ MiotError2[MiotError2["MopRemoved"] = 69] = "MopRemoved";
1413
+ MiotError2[MiotError2["MopRemoved2"] = 70] = "MopRemoved2";
1414
+ MiotError2[MiotError2["MopPadStopRotate"] = 71] = "MopPadStopRotate";
1415
+ MiotError2[MiotError2["MopPadStopRotate2"] = 72] = "MopPadStopRotate2";
1416
+ MiotError2[MiotError2["ManualMopInstallRequired"] = 74] = "ManualMopInstallRequired";
1265
1417
  MiotError2[MiotError2["LowBatteryTurnOff"] = 75] = "LowBatteryTurnOff";
1418
+ MiotError2[MiotError2["DirtyTankNotInstalled"] = 76] = "DirtyTankNotInstalled";
1419
+ MiotError2[MiotError2["RobotInHiddenRoom"] = 78] = "RobotInHiddenRoom";
1420
+ MiotError2[MiotError2["LdsFailedToLift"] = 79] = "LdsFailedToLift";
1266
1421
  MiotError2[MiotError2["RobotStuck"] = 80] = "RobotStuck";
1267
1422
  MiotError2[MiotError2["RobotStuckRepeat"] = 81] = "RobotStuckRepeat";
1423
+ MiotError2[MiotError2["SlipperyFloor"] = 82] = "SlipperyFloor";
1424
+ MiotError2[MiotError2["UnknownError"] = 84] = "UnknownError";
1425
+ MiotError2[MiotError2["CheckMopInstall"] = 85] = "CheckMopInstall";
1426
+ MiotError2[MiotError2["DirtyWaterTankFull"] = 86] = "DirtyWaterTankFull";
1427
+ MiotError2[MiotError2["RetractableLegStuck"] = 88] = "RetractableLegStuck";
1428
+ MiotError2[MiotError2["InternalError"] = 89] = "InternalError";
1268
1429
  MiotError2[MiotError2["RobotStuck2"] = 90] = "RobotStuck2";
1269
1430
  MiotError2[MiotError2["RobotStuckOnTables"] = 91] = "RobotStuckOnTables";
1270
1431
  MiotError2[MiotError2["RobotStuckOnPassage"] = 92] = "RobotStuckOnPassage";
@@ -1275,19 +1436,82 @@ var MiotError = /* @__PURE__ */ ((MiotError2) => {
1275
1436
  MiotError2[MiotError2["RobotStuckOnPet"] = 97] = "RobotStuckOnPet";
1276
1437
  MiotError2[MiotError2["RobotStuckOnSlipperySurface"] = 98] = "RobotStuckOnSlipperySurface";
1277
1438
  MiotError2[MiotError2["RobotStuckOnCarpet"] = 99] = "RobotStuckOnCarpet";
1278
- MiotError2[MiotError2["RobotStuckOnCurtain"] = 200] = "RobotStuckOnCurtain";
1279
1439
  MiotError2[MiotError2["BinFull"] = 101] = "BinFull";
1440
+ MiotError2[MiotError2["BinOpen"] = 102] = "BinOpen";
1441
+ MiotError2[MiotError2["BinOpen2"] = 103] = "BinOpen2";
1442
+ MiotError2[MiotError2["BinFull2"] = 104] = "BinFull2";
1443
+ MiotError2[MiotError2["WastewaterTankFull"] = 105] = "WastewaterTankFull";
1444
+ MiotError2[MiotError2["DirtyWaterTank"] = 106] = "DirtyWaterTank";
1445
+ MiotError2[MiotError2["CleanWaterTankEmpty"] = 107] = "CleanWaterTankEmpty";
1446
+ MiotError2[MiotError2["DirtyWaterTank2"] = 108] = "DirtyWaterTank2";
1447
+ MiotError2[MiotError2["DirtyWaterTankBlocked"] = 109] = "DirtyWaterTankBlocked";
1448
+ MiotError2[MiotError2["DirtyWaterTankPump"] = 110] = "DirtyWaterTankPump";
1449
+ MiotError2[MiotError2["MopPad"] = 111] = "MopPad";
1450
+ MiotError2[MiotError2["WetMopPad"] = 112] = "WetMopPad";
1451
+ MiotError2[MiotError2["WashboardFilterNeedsCleaning"] = 114] = "WashboardFilterNeedsCleaning";
1452
+ MiotError2[MiotError2["CleanTankLevel"] = 116] = "CleanTankLevel";
1280
1453
  MiotError2[MiotError2["StationDisconnected"] = 117] = "StationDisconnected";
1454
+ MiotError2[MiotError2["DirtyTankLevel"] = 118] = "DirtyTankLevel";
1455
+ MiotError2[MiotError2["WashboardLevel"] = 119] = "WashboardLevel";
1456
+ MiotError2[MiotError2["MopPadsMissing"] = 120] = "MopPadsMissing";
1281
1457
  MiotError2[MiotError2["DustBagFull"] = 121] = "DustBagFull";
1458
+ MiotError2[MiotError2["UnknownWarning"] = 122] = "UnknownWarning";
1459
+ MiotError2[MiotError2["SelfTestFailed"] = 123] = "SelfTestFailed";
1460
+ MiotError2[MiotError2["WashboardNotWorking"] = 124] = "WashboardNotWorking";
1461
+ MiotError2[MiotError2["DrainageFailed"] = 125] = "DrainageFailed";
1462
+ MiotError2[MiotError2["MopNotDetected"] = 126] = "MopNotDetected";
1463
+ MiotError2[MiotError2["MopHolderError"] = 127] = "MopHolderError";
1464
+ MiotError2[MiotError2["DockError"] = 128] = "DockError";
1465
+ MiotError2[MiotError2["WashFailed"] = 129] = "WashFailed";
1466
+ MiotError2[MiotError2["RobotStuckOnCurtain"] = 200] = "RobotStuckOnCurtain";
1467
+ MiotError2[MiotError2["EdgeMopStopRotate"] = 201] = "EdgeMopStopRotate";
1468
+ MiotError2[MiotError2["EdgeMopDetached"] = 202] = "EdgeMopDetached";
1469
+ MiotError2[MiotError2["ChassisLiftMalfunction"] = 203] = "ChassisLiftMalfunction";
1470
+ MiotError2[MiotError2["InternalError2"] = 207] = "InternalError2";
1471
+ MiotError2[MiotError2["MopCoverError"] = 209] = "MopCoverError";
1472
+ MiotError2[MiotError2["RollerMopError"] = 210] = "RollerMopError";
1473
+ MiotError2[MiotError2["OnboardWaterTankEmpty"] = 213] = "OnboardWaterTankEmpty";
1474
+ MiotError2[MiotError2["OnboardDirtyWaterTankFull"] = 214] = "OnboardDirtyWaterTankFull";
1475
+ MiotError2[MiotError2["MopNotInstalled"] = 215] = "MopNotInstalled";
1476
+ MiotError2[MiotError2["RollerMopError2"] = 218] = "RollerMopError2";
1477
+ MiotError2[MiotError2["FluffingRollerError"] = 222] = "FluffingRollerError";
1478
+ MiotError2[MiotError2["MopCoverError2"] = 223] = "MopCoverError2";
1479
+ MiotError2[MiotError2["BlockedByObstacle"] = 226] = "BlockedByObstacle";
1480
+ MiotError2[MiotError2["ReturnToChargeFailed"] = 1e3] = "ReturnToChargeFailed";
1282
1481
  return MiotError2;
1283
1482
  })(MiotError || {});
1284
1483
  var TaskStatus = /* @__PURE__ */ ((TaskStatus2) => {
1484
+ TaskStatus2[TaskStatus2["Completed"] = 0] = "Completed";
1285
1485
  TaskStatus2[TaskStatus2["InterruptedOrPaused"] = 1] = "InterruptedOrPaused";
1286
1486
  TaskStatus2[TaskStatus2["Active"] = 2] = "Active";
1287
1487
  TaskStatus2[TaskStatus2["Transitioning"] = 3] = "Transitioning";
1488
+ TaskStatus2[TaskStatus2["SpotCleaning"] = 4] = "SpotCleaning";
1489
+ TaskStatus2[TaskStatus2["FastMapping"] = 5] = "FastMapping";
1288
1490
  TaskStatus2[TaskStatus2["OnDockIdle"] = 6] = "OnDockIdle";
1491
+ TaskStatus2[TaskStatus2["ZoneCleaningPaused"] = 7] = "ZoneCleaningPaused";
1492
+ TaskStatus2[TaskStatus2["SegmentCleaningPaused"] = 8] = "SegmentCleaningPaused";
1493
+ TaskStatus2[TaskStatus2["SpotCleaningPaused"] = 9] = "SpotCleaningPaused";
1494
+ TaskStatus2[TaskStatus2["MapCleaningPaused"] = 10] = "MapCleaningPaused";
1495
+ TaskStatus2[TaskStatus2["DockingPaused"] = 11] = "DockingPaused";
1289
1496
  TaskStatus2[TaskStatus2["TransientPauseEdge"] = 12] = "TransientPauseEdge";
1497
+ TaskStatus2[TaskStatus2["SegmentMoppingPaused"] = 13] = "SegmentMoppingPaused";
1290
1498
  TaskStatus2[TaskStatus2["NeedsIntervention"] = 14] = "NeedsIntervention";
1499
+ TaskStatus2[TaskStatus2["AutoMoppingPaused"] = 15] = "AutoMoppingPaused";
1500
+ TaskStatus2[TaskStatus2["AutoDockingPaused"] = 16] = "AutoDockingPaused";
1501
+ TaskStatus2[TaskStatus2["SegmentDockingPaused"] = 17] = "SegmentDockingPaused";
1502
+ TaskStatus2[TaskStatus2["ZoneDockingPaused"] = 18] = "ZoneDockingPaused";
1503
+ TaskStatus2[TaskStatus2["CruisingPath"] = 20] = "CruisingPath";
1504
+ TaskStatus2[TaskStatus2["CruisingPathPaused"] = 21] = "CruisingPathPaused";
1505
+ TaskStatus2[TaskStatus2["CruisingPoint"] = 22] = "CruisingPoint";
1506
+ TaskStatus2[TaskStatus2["CruisingPointPaused"] = 23] = "CruisingPointPaused";
1507
+ TaskStatus2[TaskStatus2["SummonCleanPaused"] = 24] = "SummonCleanPaused";
1508
+ TaskStatus2[TaskStatus2["ReturningInstallMop"] = 25] = "ReturningInstallMop";
1509
+ TaskStatus2[TaskStatus2["ReturningRemoveMop"] = 26] = "ReturningRemoveMop";
1510
+ TaskStatus2[TaskStatus2["StationCleaning"] = 27] = "StationCleaning";
1511
+ TaskStatus2[TaskStatus2["PetFinding"] = 30] = "PetFinding";
1512
+ TaskStatus2[TaskStatus2["AutoCleaningWashingPaused"] = 31] = "AutoCleaningWashingPaused";
1513
+ TaskStatus2[TaskStatus2["AreaCleaningWashingPaused"] = 32] = "AreaCleaningWashingPaused";
1514
+ TaskStatus2[TaskStatus2["CustomCleaningWashingPaused"] = 33] = "CustomCleaningWashingPaused";
1291
1515
  return TaskStatus2;
1292
1516
  })(TaskStatus || {});
1293
1517
 
@@ -2408,7 +2632,7 @@ var TASK = enumLookup([
2408
2632
  12 /* TransientPauseEdge */,
2409
2633
  14 /* NeedsIntervention */
2410
2634
  ]);
2411
- var VacuumDevice = class extends BaseDevice {
2635
+ var VacuumDevice = class _VacuumDevice extends BaseDevice {
2412
2636
  #caps;
2413
2637
  #lastMap = null;
2414
2638
  constructor(input) {
@@ -2424,6 +2648,18 @@ var VacuumDevice = class extends BaseDevice {
2424
2648
  get vacuumCapabilities() {
2425
2649
  return this.#caps;
2426
2650
  }
2651
+ /**
2652
+ * The suction levels this model supports, as a {@link SuctionLevel} enum array
2653
+ * (from the capability record). Lets a consumer see which fan speeds are
2654
+ * selectable without reaching into {@link vacuumCapabilities}.
2655
+ */
2656
+ get supportedSuctionLevels() {
2657
+ return this.#caps.supportedSuctionLevels;
2658
+ }
2659
+ /** The water/mop volumes this model supports, as a {@link WaterVolume} enum array. */
2660
+ get supportedWaterVolumes() {
2661
+ return this.#caps.supportedWaterVolumes;
2662
+ }
2427
2663
  #num(siid, piid) {
2428
2664
  return asNum(this.getProperty(siid, piid)?.value);
2429
2665
  }
@@ -2623,6 +2859,16 @@ var VacuumDevice = class extends BaseDevice {
2623
2859
  const points = [[Math.round(point.x), Math.round(point.y), repeats, fan, water]];
2624
2860
  return this.#startCustom(CUSTOM_CLEAN_MODE.SPOT, { points });
2625
2861
  }
2862
+ /**
2863
+ * Seed the cache from the CLOUD SHADOW (last-known values) WITHOUT waking the
2864
+ * robot — reads {@link VacuumDevice.DEFAULT_PROPS} from the cloud-cached
2865
+ * endpoint. After it resolves, every typed getter (status/battery/suction/
2866
+ * water/cleaningMode/error/charging…) reflects the cached values, so a
2867
+ * standby/docked vacuum reports its state exactly as the Dreamehome app does.
2868
+ */
2869
+ async refreshFromCache() {
2870
+ await this.refreshCachedProperties([..._VacuumDevice.DEFAULT_PROPS]);
2871
+ }
2626
2872
  // -- maps ---------------------------------------------------------------
2627
2873
  /** The most-recently-decoded map, or `null` until {@link getMap} succeeds. */
2628
2874
  get lastMap() {
@@ -2776,6 +3022,83 @@ var MowerTaskStatus = /* @__PURE__ */ ((MowerTaskStatus2) => {
2776
3022
  MowerTaskStatus2[MowerTaskStatus2["SpotIncomplete"] = 7] = "SpotIncomplete";
2777
3023
  return MowerTaskStatus2;
2778
3024
  })(MowerTaskStatus || {});
3025
+ var MowerFault = /* @__PURE__ */ ((MowerFault2) => {
3026
+ MowerFault2[MowerFault2["NoDeviceCode"] = 0] = "NoDeviceCode";
3027
+ MowerFault2[MowerFault2["Tilted"] = 1] = "Tilted";
3028
+ MowerFault2[MowerFault2["Trapped"] = 2] = "Trapped";
3029
+ MowerFault2[MowerFault2["NarrowPathToStation"] = 3] = "NarrowPathToStation";
3030
+ MowerFault2[MowerFault2["LeftWheel"] = 4] = "LeftWheel";
3031
+ MowerFault2[MowerFault2["RightWheel"] = 5] = "RightWheel";
3032
+ MowerFault2[MowerFault2["LiftMotor"] = 6] = "LiftMotor";
3033
+ MowerFault2[MowerFault2["Cutter"] = 7] = "Cutter";
3034
+ MowerFault2[MowerFault2["SidedMotor"] = 8] = "SidedMotor";
3035
+ MowerFault2[MowerFault2["CrashPlate"] = 9] = "CrashPlate";
3036
+ MowerFault2[MowerFault2["Charging"] = 10] = "Charging";
3037
+ MowerFault2[MowerFault2["BatteryOverheat"] = 11] = "BatteryOverheat";
3038
+ MowerFault2[MowerFault2["LidarCovered"] = 12] = "LidarCovered";
3039
+ MowerFault2[MowerFault2["LidarOverheatWithoutMap"] = 13] = "LidarOverheatWithoutMap";
3040
+ MowerFault2[MowerFault2["LidarOverheatWithMap"] = 14] = "LidarOverheatWithMap";
3041
+ MowerFault2[MowerFault2["LidarOverheat"] = 15] = "LidarOverheat";
3042
+ MowerFault2[MowerFault2["LidarDirty"] = 16] = "LidarDirty";
3043
+ MowerFault2[MowerFault2["LidarAbnormal"] = 17] = "LidarAbnormal";
3044
+ MowerFault2[MowerFault2["LocationWeak"] = 18] = "LocationWeak";
3045
+ MowerFault2[MowerFault2["LocationLost"] = 19] = "LocationLost";
3046
+ MowerFault2[MowerFault2["Sensor"] = 20] = "Sensor";
3047
+ MowerFault2[MowerFault2["InForbiddenArea"] = 21] = "InForbiddenArea";
3048
+ MowerFault2[MowerFault2["OutOfMap"] = 22] = "OutOfMap";
3049
+ MowerFault2[MowerFault2["EmergencyStop"] = 23] = "EmergencyStop";
3050
+ MowerFault2[MowerFault2["BatteryLow"] = 24] = "BatteryLow";
3051
+ MowerFault2[MowerFault2["MapFileCrack"] = 25] = "MapFileCrack";
3052
+ MowerFault2[MowerFault2["AwayFromMap"] = 26] = "AwayFromMap";
3053
+ MowerFault2[MowerFault2["HumanDetected"] = 27] = "HumanDetected";
3054
+ MowerFault2[MowerFault2["BladeLoss"] = 28] = "BladeLoss";
3055
+ MowerFault2[MowerFault2["StationLoss"] = 29] = "StationLoss";
3056
+ MowerFault2[MowerFault2["MaintainLoss"] = 30] = "MaintainLoss";
3057
+ MowerFault2[MowerFault2["BackChargeFailed"] = 31] = "BackChargeFailed";
3058
+ MowerFault2[MowerFault2["DockingFailed"] = 32] = "DockingFailed";
3059
+ MowerFault2[MowerFault2["LocatingFailedWithMap"] = 33] = "LocatingFailedWithMap";
3060
+ MowerFault2[MowerFault2["LocatingFailedWithoutMap"] = 34] = "LocatingFailedWithoutMap";
3061
+ MowerFault2[MowerFault2["LocatingAbnormal"] = 35] = "LocatingAbnormal";
3062
+ MowerFault2[MowerFault2["TaskStartFailed"] = 36] = "TaskStartFailed";
3063
+ MowerFault2[MowerFault2["PathImpassable"] = 37] = "PathImpassable";
3064
+ MowerFault2[MowerFault2["LidarDirtyWarning"] = 38] = "LidarDirtyWarning";
3065
+ MowerFault2[MowerFault2["CamDirty"] = 39] = "CamDirty";
3066
+ MowerFault2[MowerFault2["CamAbnormal"] = 40] = "CamAbnormal";
3067
+ MowerFault2[MowerFault2["CamCover"] = 41] = "CamCover";
3068
+ MowerFault2[MowerFault2["BatteryOverheatWarning"] = 42] = "BatteryOverheatWarning";
3069
+ MowerFault2[MowerFault2["BatteryTempLow"] = 43] = "BatteryTempLow";
3070
+ MowerFault2[MowerFault2["AutobuildBorder"] = 44] = "AutobuildBorder";
3071
+ MowerFault2[MowerFault2["AutobuildSide"] = 45] = "AutobuildSide";
3072
+ MowerFault2[MowerFault2["BorderFinish"] = 46] = "BorderFinish";
3073
+ MowerFault2[MowerFault2["NewMap"] = 47] = "NewMap";
3074
+ MowerFault2[MowerFault2["TaskFinish"] = 48] = "TaskFinish";
3075
+ MowerFault2[MowerFault2["DestinationNotReachable"] = 49] = "DestinationNotReachable";
3076
+ MowerFault2[MowerFault2["TaskStart"] = 50] = "TaskStart";
3077
+ MowerFault2[MowerFault2["CruiseStart"] = 51] = "CruiseStart";
3078
+ MowerFault2[MowerFault2["PointAndGoStart"] = 52] = "PointAndGoStart";
3079
+ MowerFault2[MowerFault2["ScheduleStart"] = 53] = "ScheduleStart";
3080
+ MowerFault2[MowerFault2["BatteryLowReturning"] = 54] = "BatteryLowReturning";
3081
+ MowerFault2[MowerFault2["BatteryLowScheduleSuspend"] = 55] = "BatteryLowScheduleSuspend";
3082
+ MowerFault2[MowerFault2["BadWeatherProtecting"] = 56] = "BadWeatherProtecting";
3083
+ MowerFault2[MowerFault2["RainScheduleInterupted"] = 57] = "RainScheduleInterupted";
3084
+ MowerFault2[MowerFault2["RainScheduleSuspend"] = 58] = "RainScheduleSuspend";
3085
+ MowerFault2[MowerFault2["ForzenReturning"] = 59] = "ForzenReturning";
3086
+ MowerFault2[MowerFault2["FrozenScheduleSuspend"] = 60] = "FrozenScheduleSuspend";
3087
+ MowerFault2[MowerFault2["NotDisturbReturning"] = 61] = "NotDisturbReturning";
3088
+ MowerFault2[MowerFault2["NotDisturbScheduleSuspend"] = 62] = "NotDisturbScheduleSuspend";
3089
+ MowerFault2[MowerFault2["WorkingScheduleSuspend"] = 63] = "WorkingScheduleSuspend";
3090
+ MowerFault2[MowerFault2["RemoteControlingScheduleSuspend"] = 64] = "RemoteControlingScheduleSuspend";
3091
+ MowerFault2[MowerFault2["EmergencyStoppedScheduleSuspend"] = 65] = "EmergencyStoppedScheduleSuspend";
3092
+ MowerFault2[MowerFault2["TopCoverOpenScheduleSuspend"] = 66] = "TopCoverOpenScheduleSuspend";
3093
+ MowerFault2[MowerFault2["FaultModeScheduleSuspend"] = 67] = "FaultModeScheduleSuspend";
3094
+ MowerFault2[MowerFault2["ScheduleTimeout"] = 68] = "ScheduleTimeout";
3095
+ MowerFault2[MowerFault2["StationNotConnectedToWorkingArea"] = 69] = "StationNotConnectedToWorkingArea";
3096
+ MowerFault2[MowerFault2["ContinueFromBreakpoint"] = 70] = "ContinueFromBreakpoint";
3097
+ MowerFault2[MowerFault2["IdleTimeoutReturning"] = 71] = "IdleTimeoutReturning";
3098
+ MowerFault2[MowerFault2["PauseTimeoutReturning"] = 72] = "PauseTimeoutReturning";
3099
+ MowerFault2[MowerFault2["TopCoverOpen"] = 73] = "TopCoverOpen";
3100
+ return MowerFault2;
3101
+ })(MowerFault || {});
2779
3102
 
2780
3103
  // src/models/mower/decode.ts
2781
3104
  function isRecord(v) {
@@ -3455,7 +3778,13 @@ var STATUS = enumLookup(
3455
3778
  var CHARGING2 = enumLookup(
3456
3779
  Object.values(MowerChargingStatus).filter((v) => typeof v === "number")
3457
3780
  );
3458
- var MowerDevice = class extends BaseDevice {
3781
+ var TASK_STATUS = enumLookup(
3782
+ Object.values(MowerTaskStatus).filter((v) => typeof v === "number")
3783
+ );
3784
+ var FAULT = enumLookup(
3785
+ Object.values(MowerFault).filter((v) => typeof v === "number")
3786
+ );
3787
+ var MowerDevice = class _MowerDevice extends BaseDevice {
3459
3788
  #caps;
3460
3789
  #fetchBatch;
3461
3790
  #lastMap = null;
@@ -3503,6 +3832,25 @@ var MowerDevice = class extends BaseDevice {
3503
3832
  get taskStatusRaw() {
3504
3833
  return this.#num(MOWER_PROP.TASK_STATUS.siid, MOWER_PROP.TASK_STATUS.piid);
3505
3834
  }
3835
+ /**
3836
+ * TASK_STATUS (5:104) decoded to {@link MowerTaskStatus}, or null. The donor
3837
+ * names only code 7 (SpotIncomplete); codes 2/3/10/13 are documented "Unknown
3838
+ * task status" and intentionally surface as raw via {@link taskStatusRaw}.
3839
+ */
3840
+ get taskStatus() {
3841
+ return TASK_STATUS(this.taskStatusRaw);
3842
+ }
3843
+ get faultRaw() {
3844
+ return this.#num(MOWER_PROP.DEVICE_CODE.siid, MOWER_PROP.DEVICE_CODE.piid);
3845
+ }
3846
+ /**
3847
+ * DEVICE_CODE (2:2) decoded to a {@link MowerFault} (the donor's
3848
+ * BASE_DEVICE_CODES registry, 0..73), or null for a model-specific/undocumented
3849
+ * code — which still surfaces as the raw number via {@link faultRaw}.
3850
+ */
3851
+ get fault() {
3852
+ return FAULT(this.faultRaw);
3853
+ }
3506
3854
  /** Parsed scheduling task descriptor (2:50), or null. */
3507
3855
  get task() {
3508
3856
  return parseTaskDescriptor(
@@ -3595,6 +3943,16 @@ var MowerDevice = class extends BaseDevice {
3595
3943
  }
3596
3944
  return this.#sendTask(buildSpotPayload(spotAreaIds.map((s) => Math.trunc(s))));
3597
3945
  }
3946
+ /**
3947
+ * Seed the cache from the CLOUD SHADOW (last-known values) WITHOUT waking the
3948
+ * mower — reads {@link MowerDevice.DEFAULT_PROPS} from the cloud-cached
3949
+ * endpoint. After it resolves, every typed getter (status/battery/charging/
3950
+ * coverage/task/controlAction…) reflects the cached values, so a docked/
3951
+ * standby mower reports its state exactly as the Dreamehome app does.
3952
+ */
3953
+ async refreshFromCache() {
3954
+ await this.refreshCachedProperties([..._MowerDevice.DEFAULT_PROPS]);
3955
+ }
3598
3956
  // -- maps ---------------------------------------------------------------
3599
3957
  /** The most-recently-parsed map, or `null` until {@link getMap} succeeds. */
3600
3958
  get lastMap() {
@@ -3635,6 +3993,7 @@ var MowerDevice = class extends BaseDevice {
3635
3993
  /** Props worth seeding on start() / polling — exported for the facade. */
3636
3994
  static DEFAULT_PROPS = [
3637
3995
  MOWER_PROP.STATUS,
3996
+ MOWER_PROP.DEVICE_CODE,
3638
3997
  MOWER_PROP.BATTERY,
3639
3998
  MOWER_PROP.CHARGING_STATUS,
3640
3999
  MOWER_PROP.TASK_STATUS,
@@ -3809,6 +4168,7 @@ var Nodreame = class extends TypedEmitter {
3809
4168
  MowerChargingStatus,
3810
4169
  MowerControlAction,
3811
4170
  MowerDevice,
4171
+ MowerFault,
3812
4172
  MowerStatus,
3813
4173
  MowerTaskStatus,
3814
4174
  Nodreame,