@apocaliss92/nodedreame 1.6.1 → 1.7.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
@@ -55,10 +55,12 @@ __export(index_exports, {
55
55
  Nodreame: () => Nodreame,
56
56
  SuctionLevel: () => SuctionLevel,
57
57
  TaskStatus: () => TaskStatus,
58
+ VACUUM_CONSUMABLES: () => VACUUM_CONSUMABLES,
58
59
  VACUUM_MODEL_CAPABILITIES: () => MODEL_CAPABILITIES,
59
60
  VacuumCapabilityResolver: () => VacuumCapabilityResolver,
60
61
  VacuumDevice: () => VacuumDevice,
61
62
  WaterVolume: () => WaterVolume,
63
+ consumableSpec: () => consumableSpec,
62
64
  createClientDumper: () => createClientDumper,
63
65
  createDumper: () => createDumper,
64
66
  decodeAiFeature: () => decodeAiFeature,
@@ -73,7 +75,7 @@ module.exports = __toCommonJS(index_exports);
73
75
 
74
76
  // src/support/version.ts
75
77
  var LIBRARY_NAME = "nodedreame";
76
- var LIBRARY_VERSION = "1.6.1";
78
+ var LIBRARY_VERSION = "1.7.0";
77
79
 
78
80
  // src/transport/errors.ts
79
81
  var DreameError = class extends Error {
@@ -1643,6 +1645,23 @@ function encodeAiFeatureWrite(raw, feature, value) {
1643
1645
  );
1644
1646
  }
1645
1647
 
1648
+ // src/models/vacuum/consumables.ts
1649
+ var VACUUM_CONSUMABLES = [
1650
+ { key: "main-brush", label: "Main Brush", life: { siid: 9, piid: 2 }, reset: { siid: 9, aiid: 1 } },
1651
+ { key: "side-brush", label: "Side Brush", life: { siid: 10, piid: 2 }, reset: { siid: 10, aiid: 1 } },
1652
+ { key: "filter", label: "Filter", life: { siid: 11, piid: 1 }, reset: { siid: 11, aiid: 1 } },
1653
+ { key: "sensor", label: "Sensor", life: { siid: 16, piid: 1 }, reset: { siid: 16, aiid: 1 } },
1654
+ { key: "tank-filter", label: "Tank Filter", life: { siid: 17, piid: 1 }, reset: { siid: 17, aiid: 1 } },
1655
+ { key: "mop-pad", label: "Mop Pad", life: { siid: 18, piid: 1 }, reset: { siid: 18, aiid: 1 } },
1656
+ { key: "silver-ion", label: "Silver-ion", life: { siid: 19, piid: 2 }, reset: { siid: 19, aiid: 1 } },
1657
+ { key: "detergent", label: "Detergent", life: { siid: 20, piid: 1 }, reset: { siid: 20, aiid: 1 } },
1658
+ { key: "squeegee", label: "Squeegee", life: { siid: 24, piid: 1 }, reset: { siid: 24, aiid: 1 } },
1659
+ { key: "dust-bag", label: "Dust Bag", life: { siid: 27, piid: 17 }, reset: null }
1660
+ ];
1661
+ function consumableSpec(key2) {
1662
+ return VACUUM_CONSUMABLES.find((c) => c.key === key2);
1663
+ }
1664
+
1646
1665
  // src/models/vacuum/capabilities.ts
1647
1666
  var X50_AI_FEATURES = [
1648
1667
  "obstacleDetection",
@@ -2844,6 +2863,51 @@ var VacuumDevice = class _VacuumDevice extends BaseDevice {
2844
2863
  get volume() {
2845
2864
  return this.#num(SETTINGS_PROP.VOLUME.siid, SETTINGS_PROP.VOLUME.piid);
2846
2865
  }
2866
+ // -- consumables --------------------------------------------------------
2867
+ /**
2868
+ * Remaining-life % (0..100) for one consumable, or `null` when the model does
2869
+ * not report it (presence == support). Call {@link refreshConsumables} first
2870
+ * on a docked robot so the cloud-shadow life values are seeded.
2871
+ */
2872
+ consumableLeftPct(key2) {
2873
+ const spec = consumableSpec(key2);
2874
+ if (spec === void 0) return null;
2875
+ return this.#num(spec.life.siid, spec.life.piid);
2876
+ }
2877
+ /**
2878
+ * The consumables this model EXPOSES — discovered by presence (a reported
2879
+ * life property), mirroring how the HA integration derives support. Each
2880
+ * reading carries the current remaining-life % and whether a reset action
2881
+ * exists. Empty until the life properties have been observed (push) or seeded
2882
+ * via {@link refreshConsumables}.
2883
+ */
2884
+ get supportedConsumables() {
2885
+ return VACUUM_CONSUMABLES.flatMap((spec) => {
2886
+ const leftPct = this.#num(spec.life.siid, spec.life.piid);
2887
+ return leftPct === null ? [] : [{ key: spec.key, label: spec.label, leftPct, resettable: spec.reset !== null }];
2888
+ });
2889
+ }
2890
+ /**
2891
+ * Seed EVERY consumable life property from the cloud shadow (no robot wake) so
2892
+ * {@link supportedConsumables} reflects the full set on a docked robot. The
2893
+ * consumable life values are static settings the robot rarely re-pushes over
2894
+ * MQTT, so a fresh connect surfaces only the actively-changing ones without this.
2895
+ */
2896
+ async refreshConsumables() {
2897
+ await this.refreshCachedProperties(VACUUM_CONSUMABLES.map((c) => c.life));
2898
+ }
2899
+ /**
2900
+ * Reset (mark replaced → life back to 100%) one consumable via its MIoT reset
2901
+ * action. Rejects when the model exposes no reset action for the key (e.g.
2902
+ * `dust-bag`) or the key is unknown.
2903
+ */
2904
+ async resetConsumable(key2) {
2905
+ const spec = consumableSpec(key2);
2906
+ if (spec === void 0 || spec.reset === null) {
2907
+ throw new DreameError(`resetConsumable: no reset action for consumable "${key2}"`);
2908
+ }
2909
+ return this.callAction(spec.reset.siid, spec.reset.aiid, []);
2910
+ }
2847
2911
  // -- AI obstacle-detection ----------------------------------------------
2848
2912
  /**
2849
2913
  * The raw `AI_DETECTION` value (siid 4 piid 22) — an int bitmask or a JSON
@@ -4829,10 +4893,12 @@ function createClientDumper(client, options) {
4829
4893
  Nodreame,
4830
4894
  SuctionLevel,
4831
4895
  TaskStatus,
4896
+ VACUUM_CONSUMABLES,
4832
4897
  VACUUM_MODEL_CAPABILITIES,
4833
4898
  VacuumCapabilityResolver,
4834
4899
  VacuumDevice,
4835
4900
  WaterVolume,
4901
+ consumableSpec,
4836
4902
  createClientDumper,
4837
4903
  createDumper,
4838
4904
  decodeAiFeature,