@apocaliss92/nodedreame 1.10.0 → 1.11.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
@@ -69,9 +69,12 @@ __export(index_exports, {
69
69
  decodeAutoSwitchAll: () => decodeAutoSwitchAll,
70
70
  encodeAiFeatureWrite: () => encodeAiFeatureWrite,
71
71
  encodeAutoSwitchWrite: () => encodeAutoSwitchWrite,
72
+ extractMowerConsumableValues: () => extractMowerConsumableValues,
72
73
  getMowerCapabilities: () => getMowerCapabilities,
73
74
  getVacuumCapabilities: () => getVacuumCapabilities,
74
75
  isDreameConsumableKey: () => isDreameConsumableKey,
76
+ mowerConsumableIndex: () => mowerConsumableIndex,
77
+ parseMowerConsumables: () => parseMowerConsumables,
75
78
  renderMowerSvg: () => renderMowerSvg,
76
79
  renderVacuumPng: () => renderVacuumPng,
77
80
  resolveCapabilities: () => resolveCapabilities,
@@ -81,7 +84,7 @@ module.exports = __toCommonJS(index_exports);
81
84
 
82
85
  // src/support/version.ts
83
86
  var LIBRARY_NAME = "nodedreame";
84
- var LIBRARY_VERSION = "1.10.0";
87
+ var LIBRARY_VERSION = "1.11.0";
85
88
 
86
89
  // src/transport/errors.ts
87
90
  var DreameError = class extends Error {
@@ -3931,6 +3934,19 @@ function buildEdgePayload(contourIds) {
3931
3934
  function buildSpotPayload(spotAreaIds) {
3932
3935
  return { m: "a", p: 0, o: TASK_OPCODE.SPOT, d: { area: [...spotAreaIds] } };
3933
3936
  }
3937
+ function buildGetConsumablePayload() {
3938
+ return { m: "g", t: "CMS" };
3939
+ }
3940
+ function buildSetConsumablePayload(values) {
3941
+ const normalized = values.map((v) => Math.trunc(v));
3942
+ if (normalized.length !== 3) {
3943
+ throw new RangeError(`CMS values must contain exactly 3 counters; got ${normalized.length}`);
3944
+ }
3945
+ if (normalized.some((v) => v < 0)) {
3946
+ throw new RangeError(`CMS values cannot be negative; got ${JSON.stringify(normalized)}`);
3947
+ }
3948
+ return { m: "s", t: "CMS", d: { value: normalized } };
3949
+ }
3934
3950
 
3935
3951
  // src/models/mower/enums.ts
3936
3952
  var MowerStatus = /* @__PURE__ */ ((MowerStatus2) => {
@@ -4122,6 +4138,104 @@ function parseControlStatus(value) {
4122
4138
  zones
4123
4139
  };
4124
4140
  }
4141
+ var MOWER_CONSUMABLES = [
4142
+ { key: "blade", index: 0, totalMinutes: 6e3 },
4143
+ { key: "brush", index: 1, totalMinutes: 3e4 },
4144
+ { key: "maintenance", index: 2, totalMinutes: 3600 }
4145
+ ];
4146
+ function mowerConsumableIndex(item) {
4147
+ switch (item.trim().toLowerCase()) {
4148
+ case "blade":
4149
+ case "blades":
4150
+ return 0;
4151
+ case "brush":
4152
+ case "cleaning_brush":
4153
+ return 1;
4154
+ case "robot":
4155
+ case "maintenance":
4156
+ case "robot_maintenance":
4157
+ return 2;
4158
+ default:
4159
+ return null;
4160
+ }
4161
+ }
4162
+ function toInt(v) {
4163
+ if (typeof v === "number" && Number.isFinite(v)) {
4164
+ return Math.trunc(v);
4165
+ }
4166
+ if (typeof v === "string") {
4167
+ const n = Number(v);
4168
+ return Number.isFinite(n) ? Math.trunc(n) : null;
4169
+ }
4170
+ return null;
4171
+ }
4172
+ function extractCustomActionData(result) {
4173
+ if (!isRecord2(result)) {
4174
+ return null;
4175
+ }
4176
+ if (Array.isArray(result["value"])) {
4177
+ return result;
4178
+ }
4179
+ if (isRecord2(result["d"])) {
4180
+ return result["d"];
4181
+ }
4182
+ const out = result["out"];
4183
+ if (!Array.isArray(out)) {
4184
+ return null;
4185
+ }
4186
+ for (const entry of out) {
4187
+ if (!isRecord2(entry)) {
4188
+ continue;
4189
+ }
4190
+ const r = entry["r"];
4191
+ const code = entry["code"];
4192
+ const rError = r !== void 0 && r !== null && r !== 0;
4193
+ const codeError = code !== void 0 && code !== null && code !== 0;
4194
+ if (rError && codeError) {
4195
+ continue;
4196
+ }
4197
+ if (isRecord2(entry["d"])) {
4198
+ return entry["d"];
4199
+ }
4200
+ }
4201
+ return null;
4202
+ }
4203
+ function extractMowerConsumableValues(result) {
4204
+ const data = extractCustomActionData(result);
4205
+ if (data === null) {
4206
+ return null;
4207
+ }
4208
+ const values = data["value"];
4209
+ if (!Array.isArray(values) || values.length < 3) {
4210
+ return null;
4211
+ }
4212
+ const out = [];
4213
+ for (const v of values.slice(0, 3)) {
4214
+ const n = toInt(v);
4215
+ if (n === null) {
4216
+ return null;
4217
+ }
4218
+ out.push(n);
4219
+ }
4220
+ return out;
4221
+ }
4222
+ function parseMowerConsumables(result) {
4223
+ const values = extractMowerConsumableValues(result);
4224
+ if (values === null) {
4225
+ return null;
4226
+ }
4227
+ return MOWER_CONSUMABLES.map((c) => {
4228
+ const used = values[c.index] ?? 0;
4229
+ const remaining = c.totalMinutes - used;
4230
+ const pct = Math.max(0, Math.min(100, Math.round(remaining / c.totalMinutes * 1e3) / 10));
4231
+ return {
4232
+ key: c.key,
4233
+ usedMinutes: used,
4234
+ totalMinutes: c.totalMinutes,
4235
+ remainingPercent: pct
4236
+ };
4237
+ });
4238
+ }
4125
4239
 
4126
4240
  // src/models/mower/capabilities.ts
4127
4241
  var FALLBACK2 = {
@@ -4887,6 +5001,56 @@ var MowerDevice = class _MowerDevice extends BaseDevice {
4887
5001
  }
4888
5002
  return this.#sendTask(buildSpotPayload(spotAreaIds.map((s) => Math.trunc(s))));
4889
5003
  }
5004
+ // -- CMS consumables ----------------------------------------------------
5005
+ /**
5006
+ * Read the raw CMS consumable counters `[blade, brush, robot]` (minutes used),
5007
+ * via the SCHEDULING_TASK (2:50) custom-action getter `{m:'g',t:'CMS'}`. This
5008
+ * is a LIVE device action (it wakes the mower); rejects with
5009
+ * {@link DreameDeviceOfflineError} when the mower is unreachable. Returns null
5010
+ * if the response is malformed.
5011
+ */
5012
+ async getConsumableValues() {
5013
+ const result = await this.callAction(
5014
+ MOWER_PROP.SCHEDULING_TASK.siid,
5015
+ MOWER_PROP.SCHEDULING_TASK.piid,
5016
+ [buildGetConsumablePayload()]
5017
+ );
5018
+ return extractMowerConsumableValues(result);
5019
+ }
5020
+ /**
5021
+ * Read the CMS consumables as typed readings (blade/brush/maintenance) with
5022
+ * remaining %. LIVE action — see {@link getConsumableValues}. Returns null on
5023
+ * a malformed response.
5024
+ */
5025
+ async getConsumables() {
5026
+ const result = await this.callAction(
5027
+ MOWER_PROP.SCHEDULING_TASK.siid,
5028
+ MOWER_PROP.SCHEDULING_TASK.piid,
5029
+ [buildGetConsumablePayload()]
5030
+ );
5031
+ return parseMowerConsumables(result);
5032
+ }
5033
+ /**
5034
+ * Reset one CMS consumable counter to zero. Reads the current counters, zeroes
5035
+ * the selected one (leaving the others), and writes them back via the
5036
+ * `{m:'s',t:'CMS',d:{value:[…]}}` setter. LIVE action. Throws on an unknown
5037
+ * item or when the current counters cannot be read.
5038
+ */
5039
+ async resetConsumable(item) {
5040
+ const index = mowerConsumableIndex(item);
5041
+ if (index === null) {
5042
+ throw new DreameError(`resetConsumable: unknown consumable item "${item}"`);
5043
+ }
5044
+ const current = await this.getConsumableValues();
5045
+ if (current === null) {
5046
+ throw new DreameError("resetConsumable: failed to read current CMS counters");
5047
+ }
5048
+ const next = [...current];
5049
+ next[index] = 0;
5050
+ await this.callAction(MOWER_PROP.SCHEDULING_TASK.siid, MOWER_PROP.SCHEDULING_TASK.piid, [
5051
+ buildSetConsumablePayload(next)
5052
+ ]);
5053
+ }
4890
5054
  /**
4891
5055
  * Seed the cache from the CLOUD SHADOW (last-known values) WITHOUT waking the
4892
5056
  * mower — reads {@link MowerDevice.DEFAULT_PROPS} from the cloud-cached
@@ -5589,9 +5753,12 @@ function createClientDumper(client, options) {
5589
5753
  decodeAutoSwitchAll,
5590
5754
  encodeAiFeatureWrite,
5591
5755
  encodeAutoSwitchWrite,
5756
+ extractMowerConsumableValues,
5592
5757
  getMowerCapabilities,
5593
5758
  getVacuumCapabilities,
5594
5759
  isDreameConsumableKey,
5760
+ mowerConsumableIndex,
5761
+ parseMowerConsumables,
5595
5762
  renderMowerSvg,
5596
5763
  renderVacuumPng,
5597
5764
  resolveCapabilities,