@camstack/addon-provider-dreame 0.1.3 → 0.1.5
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/addon.js +112 -10
- package/dist/addon.mjs +112 -10
- package/package.json +4 -1
package/dist/addon.js
CHANGED
|
@@ -4680,7 +4680,7 @@ function preprocess(fn, schema) {
|
|
|
4680
4680
|
});
|
|
4681
4681
|
}
|
|
4682
4682
|
//#endregion
|
|
4683
|
-
//#region ../types/dist/sleep-
|
|
4683
|
+
//#region ../types/dist/sleep-DVmKHFGi.mjs
|
|
4684
4684
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
4685
4685
|
EventCategory["SystemBoot"] = "system.boot";
|
|
4686
4686
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -6480,6 +6480,17 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
6480
6480
|
DeviceRole["HumiditySensor"] = "humidity-sensor";
|
|
6481
6481
|
DeviceRole["AmbientLightSensor"] = "ambient-light-sensor";
|
|
6482
6482
|
DeviceRole["PressureSensor"] = "pressure-sensor";
|
|
6483
|
+
/** Wind speed or direction (weather-station `wind-sensor` cap). */
|
|
6484
|
+
DeviceRole["WindSensor"] = "wind-sensor";
|
|
6485
|
+
/** Rain accumulation or rate (weather-station `rain-sensor` cap). */
|
|
6486
|
+
DeviceRole["RainSensor"] = "rain-sensor";
|
|
6487
|
+
/** UV index (weather-station `uv-sensor` cap). */
|
|
6488
|
+
DeviceRole["UvSensor"] = "uv-sensor";
|
|
6489
|
+
/** Solar irradiance W/m² (weather-station `solar-radiation-sensor` cap).
|
|
6490
|
+
* Distinct from AmbientLightSensor (lux). */
|
|
6491
|
+
DeviceRole["SolarRadiationSensor"] = "solar-radiation-sensor";
|
|
6492
|
+
/** Soil moisture % (garden/weather `soil-moisture-sensor` cap). */
|
|
6493
|
+
DeviceRole["SoilMoistureSensor"] = "soil-moisture-sensor";
|
|
6483
6494
|
DeviceRole["PowerSensor"] = "power-sensor";
|
|
6484
6495
|
DeviceRole["EnergySensor"] = "energy-sensor";
|
|
6485
6496
|
DeviceRole["VoltageSensor"] = "voltage-sensor";
|
|
@@ -73204,10 +73215,66 @@ function decodeVacuumTanks(caps) {
|
|
|
73204
73215
|
dustBin: caps?.canAutoEmpty ? present : null
|
|
73205
73216
|
};
|
|
73206
73217
|
}
|
|
73218
|
+
/**
|
|
73219
|
+
* Clamp a raw consumable percentage to `[0, 100]`, or return `null` when the
|
|
73220
|
+
* value is absent / non-finite. The library reports remaining life as a 0..100
|
|
73221
|
+
* integer; we clamp defensively so an out-of-range firmware value never violates
|
|
73222
|
+
* the cap schema.
|
|
73223
|
+
*/
|
|
73224
|
+
function clampConsumablePct(value) {
|
|
73225
|
+
if (value === null || !Number.isFinite(value)) return null;
|
|
73226
|
+
return Math.max(0, Math.min(100, value));
|
|
73227
|
+
}
|
|
73228
|
+
/**
|
|
73229
|
+
* Build the `consumables` cap runtime-state slice from a live {@link VacuumDevice}
|
|
73230
|
+
* handle. The returned object satisfies the cap's `runtimeState` schema
|
|
73231
|
+
* (`ConsumablesStatusSchema.extend({ lastFetchedAt: z.number() })`).
|
|
73232
|
+
*
|
|
73233
|
+
* Always present: main-brush / filter (every Dreame vacuum has both).
|
|
73234
|
+
* Conditional: side-brush — only included when the model capability record
|
|
73235
|
+
* (`vacuumCapabilities.hasSideBrush`) confirms hardware presence, so a brush-less
|
|
73236
|
+
* model does not report a phantom consumable.
|
|
73237
|
+
*
|
|
73238
|
+
* The library exposes NO per-consumable reset action (no MIoT action id for
|
|
73239
|
+
* resetting brushes/filter in the current property maps), so all items report
|
|
73240
|
+
* `resettable: false`.
|
|
73241
|
+
*/
|
|
73242
|
+
function buildVacuumConsumables(vacuum) {
|
|
73243
|
+
const baseItems = [{
|
|
73244
|
+
key: "main-brush",
|
|
73245
|
+
label: "Main Brush",
|
|
73246
|
+
level: clampConsumablePct(vacuum.mainBrushLeftPct),
|
|
73247
|
+
status: null,
|
|
73248
|
+
lastResetAt: null,
|
|
73249
|
+
resettable: false
|
|
73250
|
+
}, {
|
|
73251
|
+
key: "filter",
|
|
73252
|
+
label: "Filter",
|
|
73253
|
+
level: clampConsumablePct(vacuum.filterLeftPct),
|
|
73254
|
+
status: null,
|
|
73255
|
+
lastResetAt: null,
|
|
73256
|
+
resettable: false
|
|
73257
|
+
}];
|
|
73258
|
+
const sideBrushItem = vacuum.vacuumCapabilities.hasSideBrush ? {
|
|
73259
|
+
key: "side-brush",
|
|
73260
|
+
label: "Side Brush",
|
|
73261
|
+
level: clampConsumablePct(vacuum.sideBrushLeftPct),
|
|
73262
|
+
status: null,
|
|
73263
|
+
lastResetAt: null,
|
|
73264
|
+
resettable: false
|
|
73265
|
+
} : null;
|
|
73266
|
+
const now = Date.now();
|
|
73267
|
+
return {
|
|
73268
|
+
items: sideBrushItem !== null ? [...baseItems, sideBrushItem] : [...baseItems],
|
|
73269
|
+
lastChangedAt: now,
|
|
73270
|
+
lastFetchedAt: now
|
|
73271
|
+
};
|
|
73272
|
+
}
|
|
73207
73273
|
//#endregion
|
|
73208
73274
|
//#region src/devices/dreame-vacuum-device.ts
|
|
73209
73275
|
var CAP_NAME$1 = "vacuum-control";
|
|
73210
|
-
var
|
|
73276
|
+
var CONSUMABLES_CAP_NAME = "consumables";
|
|
73277
|
+
var CONTROL_COLD_START = {
|
|
73211
73278
|
state: "idle",
|
|
73212
73279
|
batteryLevel: null,
|
|
73213
73280
|
fanSpeed: null,
|
|
@@ -73218,9 +73285,15 @@ var COLD_START$1 = {
|
|
|
73218
73285
|
dustBin: null,
|
|
73219
73286
|
lastChangedAt: 0
|
|
73220
73287
|
};
|
|
73288
|
+
var CONSUMABLES_COLD_START = {
|
|
73289
|
+
items: [],
|
|
73290
|
+
lastChangedAt: 0,
|
|
73291
|
+
lastFetchedAt: 0
|
|
73292
|
+
};
|
|
73221
73293
|
/**
|
|
73222
|
-
* Dreame robot-vacuum device. Registers the `vacuum-control`
|
|
73223
|
-
* library `VacuumDevice` getters → the cap
|
|
73294
|
+
* Dreame robot-vacuum device. Registers the `vacuum-control` and `consumables`
|
|
73295
|
+
* caps and maps the library `VacuumDevice` getters → the cap slices on every
|
|
73296
|
+
* `stateChanged` push.
|
|
73224
73297
|
*
|
|
73225
73298
|
* Commands route to the live handle: `start`→`startCleaning()`, `pause`→
|
|
73226
73299
|
* `pause()`, `stop`→`stop()`, `returnToBase`→`dock()`, `locate`→`locate()`,
|
|
@@ -73233,8 +73306,12 @@ var COLD_START$1 = {
|
|
|
73233
73306
|
* level, not a tank fill) plus brush/filter consumable life. We therefore map
|
|
73234
73307
|
* tank PRESENCE only (from the model capability flags via `decodeVacuumTanks`):
|
|
73235
73308
|
* a present tank reports `{ level: null, status: null }` (exists, level unknown)
|
|
73236
|
-
* and an absent tank reports `null`.
|
|
73237
|
-
*
|
|
73309
|
+
* and an absent tank reports `null`.
|
|
73310
|
+
*
|
|
73311
|
+
* Consumables: main-brush / filter (always present), side-brush (conditional on
|
|
73312
|
+
* `vacuumCapabilities.hasSideBrush`). The library exposes no MIoT reset action
|
|
73313
|
+
* for consumables, so all items report `resettable: false` and `reset()` is a
|
|
73314
|
+
* no-op that throws.
|
|
73238
73315
|
*
|
|
73239
73316
|
* Map data: the library exposes `lastMap` / `currentSegmentId` (a room/segment
|
|
73240
73317
|
* list), but no existing camstack cap models a vacuum room map — surfacing it
|
|
@@ -73252,7 +73329,7 @@ var DreameVacuumDevice = class extends DreameChildDevice {
|
|
|
73252
73329
|
}
|
|
73253
73330
|
registerControlCap() {
|
|
73254
73331
|
this.ctx.registerNativeCap(vacuumControlCapability, {
|
|
73255
|
-
getStatus: async () => this.runtimeState.getCapState(CAP_NAME$1) ??
|
|
73332
|
+
getStatus: async () => this.runtimeState.getCapState(CAP_NAME$1) ?? CONTROL_COLD_START,
|
|
73256
73333
|
start: async () => {
|
|
73257
73334
|
await this.requireVacuum().startCleaning();
|
|
73258
73335
|
},
|
|
@@ -73275,13 +73352,36 @@ var DreameVacuumDevice = class extends DreameChildDevice {
|
|
|
73275
73352
|
await vacuum.setSuction(level);
|
|
73276
73353
|
}
|
|
73277
73354
|
});
|
|
73278
|
-
this.runtimeState.setCapState(CAP_NAME$1,
|
|
73355
|
+
this.runtimeState.setCapState(CAP_NAME$1, CONTROL_COLD_START);
|
|
73356
|
+
this.registerConsumablesCap();
|
|
73357
|
+
}
|
|
73358
|
+
/**
|
|
73359
|
+
* Register the `consumables` cap. The provider surfaces remaining life % for
|
|
73360
|
+
* main-brush / filter (always present) and side-brush (model-conditional).
|
|
73361
|
+
*
|
|
73362
|
+
* The library exposes no MIoT reset action for consumables, so `reset()` throws
|
|
73363
|
+
* an informative error on every call — all items are marked `resettable: false`
|
|
73364
|
+
* so the UI suppresses the reset button and the mutation is a guard-only path.
|
|
73365
|
+
*/
|
|
73366
|
+
registerConsumablesCap() {
|
|
73367
|
+
this.ctx.registerNativeCap(consumablesCapability, {
|
|
73368
|
+
getStatus: async () => this.runtimeState.getCapState(CONSUMABLES_CAP_NAME) ?? CONSUMABLES_COLD_START,
|
|
73369
|
+
reset: async ({ key }) => {
|
|
73370
|
+
throw new Error(`dreame vacuum: consumable reset not supported (item="${key}", device=${this.dreameDeviceId})`);
|
|
73371
|
+
}
|
|
73372
|
+
});
|
|
73373
|
+
this.runtimeState.setCapState(CONSUMABLES_CAP_NAME, CONSUMABLES_COLD_START);
|
|
73279
73374
|
}
|
|
73375
|
+
/**
|
|
73376
|
+
* `registerControlCap()` (called by `super.onActivate()`) already registers
|
|
73377
|
+
* the consumables cap before the parent seeds the first slice via
|
|
73378
|
+
* `recomputeSlice()`. No additional work needed here; the override is removed.
|
|
73379
|
+
*/
|
|
73280
73380
|
recomputeSlice() {
|
|
73281
73381
|
const vacuum = this.resolveVacuum();
|
|
73282
73382
|
if (vacuum === null) return;
|
|
73283
73383
|
const tanks = decodeVacuumTanks(vacuum.vacuumCapabilities);
|
|
73284
|
-
const
|
|
73384
|
+
const controlSlice = {
|
|
73285
73385
|
state: mapMiotStateToVacuumState(vacuum.status),
|
|
73286
73386
|
batteryLevel: clampBatteryLevel$1(vacuum.battery),
|
|
73287
73387
|
fanSpeed: suctionLevelToken(vacuum.suction),
|
|
@@ -73292,7 +73392,9 @@ var DreameVacuumDevice = class extends DreameChildDevice {
|
|
|
73292
73392
|
dustBin: tanks.dustBin,
|
|
73293
73393
|
lastChangedAt: Date.now()
|
|
73294
73394
|
};
|
|
73295
|
-
this.runtimeState.setCapState(CAP_NAME$1,
|
|
73395
|
+
this.runtimeState.setCapState(CAP_NAME$1, controlSlice);
|
|
73396
|
+
const consumablesSlice = buildVacuumConsumables(vacuum);
|
|
73397
|
+
this.runtimeState.setCapState(CONSUMABLES_CAP_NAME, consumablesSlice);
|
|
73296
73398
|
}
|
|
73297
73399
|
/** The live typed vacuum handle, or throw a clear error when disconnected. */
|
|
73298
73400
|
requireVacuum() {
|
package/dist/addon.mjs
CHANGED
|
@@ -4680,7 +4680,7 @@ function preprocess(fn, schema) {
|
|
|
4680
4680
|
});
|
|
4681
4681
|
}
|
|
4682
4682
|
//#endregion
|
|
4683
|
-
//#region ../types/dist/sleep-
|
|
4683
|
+
//#region ../types/dist/sleep-DVmKHFGi.mjs
|
|
4684
4684
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
4685
4685
|
EventCategory["SystemBoot"] = "system.boot";
|
|
4686
4686
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -6480,6 +6480,17 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
6480
6480
|
DeviceRole["HumiditySensor"] = "humidity-sensor";
|
|
6481
6481
|
DeviceRole["AmbientLightSensor"] = "ambient-light-sensor";
|
|
6482
6482
|
DeviceRole["PressureSensor"] = "pressure-sensor";
|
|
6483
|
+
/** Wind speed or direction (weather-station `wind-sensor` cap). */
|
|
6484
|
+
DeviceRole["WindSensor"] = "wind-sensor";
|
|
6485
|
+
/** Rain accumulation or rate (weather-station `rain-sensor` cap). */
|
|
6486
|
+
DeviceRole["RainSensor"] = "rain-sensor";
|
|
6487
|
+
/** UV index (weather-station `uv-sensor` cap). */
|
|
6488
|
+
DeviceRole["UvSensor"] = "uv-sensor";
|
|
6489
|
+
/** Solar irradiance W/m² (weather-station `solar-radiation-sensor` cap).
|
|
6490
|
+
* Distinct from AmbientLightSensor (lux). */
|
|
6491
|
+
DeviceRole["SolarRadiationSensor"] = "solar-radiation-sensor";
|
|
6492
|
+
/** Soil moisture % (garden/weather `soil-moisture-sensor` cap). */
|
|
6493
|
+
DeviceRole["SoilMoistureSensor"] = "soil-moisture-sensor";
|
|
6483
6494
|
DeviceRole["PowerSensor"] = "power-sensor";
|
|
6484
6495
|
DeviceRole["EnergySensor"] = "energy-sensor";
|
|
6485
6496
|
DeviceRole["VoltageSensor"] = "voltage-sensor";
|
|
@@ -73204,10 +73215,66 @@ function decodeVacuumTanks(caps) {
|
|
|
73204
73215
|
dustBin: caps?.canAutoEmpty ? present : null
|
|
73205
73216
|
};
|
|
73206
73217
|
}
|
|
73218
|
+
/**
|
|
73219
|
+
* Clamp a raw consumable percentage to `[0, 100]`, or return `null` when the
|
|
73220
|
+
* value is absent / non-finite. The library reports remaining life as a 0..100
|
|
73221
|
+
* integer; we clamp defensively so an out-of-range firmware value never violates
|
|
73222
|
+
* the cap schema.
|
|
73223
|
+
*/
|
|
73224
|
+
function clampConsumablePct(value) {
|
|
73225
|
+
if (value === null || !Number.isFinite(value)) return null;
|
|
73226
|
+
return Math.max(0, Math.min(100, value));
|
|
73227
|
+
}
|
|
73228
|
+
/**
|
|
73229
|
+
* Build the `consumables` cap runtime-state slice from a live {@link VacuumDevice}
|
|
73230
|
+
* handle. The returned object satisfies the cap's `runtimeState` schema
|
|
73231
|
+
* (`ConsumablesStatusSchema.extend({ lastFetchedAt: z.number() })`).
|
|
73232
|
+
*
|
|
73233
|
+
* Always present: main-brush / filter (every Dreame vacuum has both).
|
|
73234
|
+
* Conditional: side-brush — only included when the model capability record
|
|
73235
|
+
* (`vacuumCapabilities.hasSideBrush`) confirms hardware presence, so a brush-less
|
|
73236
|
+
* model does not report a phantom consumable.
|
|
73237
|
+
*
|
|
73238
|
+
* The library exposes NO per-consumable reset action (no MIoT action id for
|
|
73239
|
+
* resetting brushes/filter in the current property maps), so all items report
|
|
73240
|
+
* `resettable: false`.
|
|
73241
|
+
*/
|
|
73242
|
+
function buildVacuumConsumables(vacuum) {
|
|
73243
|
+
const baseItems = [{
|
|
73244
|
+
key: "main-brush",
|
|
73245
|
+
label: "Main Brush",
|
|
73246
|
+
level: clampConsumablePct(vacuum.mainBrushLeftPct),
|
|
73247
|
+
status: null,
|
|
73248
|
+
lastResetAt: null,
|
|
73249
|
+
resettable: false
|
|
73250
|
+
}, {
|
|
73251
|
+
key: "filter",
|
|
73252
|
+
label: "Filter",
|
|
73253
|
+
level: clampConsumablePct(vacuum.filterLeftPct),
|
|
73254
|
+
status: null,
|
|
73255
|
+
lastResetAt: null,
|
|
73256
|
+
resettable: false
|
|
73257
|
+
}];
|
|
73258
|
+
const sideBrushItem = vacuum.vacuumCapabilities.hasSideBrush ? {
|
|
73259
|
+
key: "side-brush",
|
|
73260
|
+
label: "Side Brush",
|
|
73261
|
+
level: clampConsumablePct(vacuum.sideBrushLeftPct),
|
|
73262
|
+
status: null,
|
|
73263
|
+
lastResetAt: null,
|
|
73264
|
+
resettable: false
|
|
73265
|
+
} : null;
|
|
73266
|
+
const now = Date.now();
|
|
73267
|
+
return {
|
|
73268
|
+
items: sideBrushItem !== null ? [...baseItems, sideBrushItem] : [...baseItems],
|
|
73269
|
+
lastChangedAt: now,
|
|
73270
|
+
lastFetchedAt: now
|
|
73271
|
+
};
|
|
73272
|
+
}
|
|
73207
73273
|
//#endregion
|
|
73208
73274
|
//#region src/devices/dreame-vacuum-device.ts
|
|
73209
73275
|
var CAP_NAME$1 = "vacuum-control";
|
|
73210
|
-
var
|
|
73276
|
+
var CONSUMABLES_CAP_NAME = "consumables";
|
|
73277
|
+
var CONTROL_COLD_START = {
|
|
73211
73278
|
state: "idle",
|
|
73212
73279
|
batteryLevel: null,
|
|
73213
73280
|
fanSpeed: null,
|
|
@@ -73218,9 +73285,15 @@ var COLD_START$1 = {
|
|
|
73218
73285
|
dustBin: null,
|
|
73219
73286
|
lastChangedAt: 0
|
|
73220
73287
|
};
|
|
73288
|
+
var CONSUMABLES_COLD_START = {
|
|
73289
|
+
items: [],
|
|
73290
|
+
lastChangedAt: 0,
|
|
73291
|
+
lastFetchedAt: 0
|
|
73292
|
+
};
|
|
73221
73293
|
/**
|
|
73222
|
-
* Dreame robot-vacuum device. Registers the `vacuum-control`
|
|
73223
|
-
* library `VacuumDevice` getters → the cap
|
|
73294
|
+
* Dreame robot-vacuum device. Registers the `vacuum-control` and `consumables`
|
|
73295
|
+
* caps and maps the library `VacuumDevice` getters → the cap slices on every
|
|
73296
|
+
* `stateChanged` push.
|
|
73224
73297
|
*
|
|
73225
73298
|
* Commands route to the live handle: `start`→`startCleaning()`, `pause`→
|
|
73226
73299
|
* `pause()`, `stop`→`stop()`, `returnToBase`→`dock()`, `locate`→`locate()`,
|
|
@@ -73233,8 +73306,12 @@ var COLD_START$1 = {
|
|
|
73233
73306
|
* level, not a tank fill) plus brush/filter consumable life. We therefore map
|
|
73234
73307
|
* tank PRESENCE only (from the model capability flags via `decodeVacuumTanks`):
|
|
73235
73308
|
* a present tank reports `{ level: null, status: null }` (exists, level unknown)
|
|
73236
|
-
* and an absent tank reports `null`.
|
|
73237
|
-
*
|
|
73309
|
+
* and an absent tank reports `null`.
|
|
73310
|
+
*
|
|
73311
|
+
* Consumables: main-brush / filter (always present), side-brush (conditional on
|
|
73312
|
+
* `vacuumCapabilities.hasSideBrush`). The library exposes no MIoT reset action
|
|
73313
|
+
* for consumables, so all items report `resettable: false` and `reset()` is a
|
|
73314
|
+
* no-op that throws.
|
|
73238
73315
|
*
|
|
73239
73316
|
* Map data: the library exposes `lastMap` / `currentSegmentId` (a room/segment
|
|
73240
73317
|
* list), but no existing camstack cap models a vacuum room map — surfacing it
|
|
@@ -73252,7 +73329,7 @@ var DreameVacuumDevice = class extends DreameChildDevice {
|
|
|
73252
73329
|
}
|
|
73253
73330
|
registerControlCap() {
|
|
73254
73331
|
this.ctx.registerNativeCap(vacuumControlCapability, {
|
|
73255
|
-
getStatus: async () => this.runtimeState.getCapState(CAP_NAME$1) ??
|
|
73332
|
+
getStatus: async () => this.runtimeState.getCapState(CAP_NAME$1) ?? CONTROL_COLD_START,
|
|
73256
73333
|
start: async () => {
|
|
73257
73334
|
await this.requireVacuum().startCleaning();
|
|
73258
73335
|
},
|
|
@@ -73275,13 +73352,36 @@ var DreameVacuumDevice = class extends DreameChildDevice {
|
|
|
73275
73352
|
await vacuum.setSuction(level);
|
|
73276
73353
|
}
|
|
73277
73354
|
});
|
|
73278
|
-
this.runtimeState.setCapState(CAP_NAME$1,
|
|
73355
|
+
this.runtimeState.setCapState(CAP_NAME$1, CONTROL_COLD_START);
|
|
73356
|
+
this.registerConsumablesCap();
|
|
73357
|
+
}
|
|
73358
|
+
/**
|
|
73359
|
+
* Register the `consumables` cap. The provider surfaces remaining life % for
|
|
73360
|
+
* main-brush / filter (always present) and side-brush (model-conditional).
|
|
73361
|
+
*
|
|
73362
|
+
* The library exposes no MIoT reset action for consumables, so `reset()` throws
|
|
73363
|
+
* an informative error on every call — all items are marked `resettable: false`
|
|
73364
|
+
* so the UI suppresses the reset button and the mutation is a guard-only path.
|
|
73365
|
+
*/
|
|
73366
|
+
registerConsumablesCap() {
|
|
73367
|
+
this.ctx.registerNativeCap(consumablesCapability, {
|
|
73368
|
+
getStatus: async () => this.runtimeState.getCapState(CONSUMABLES_CAP_NAME) ?? CONSUMABLES_COLD_START,
|
|
73369
|
+
reset: async ({ key }) => {
|
|
73370
|
+
throw new Error(`dreame vacuum: consumable reset not supported (item="${key}", device=${this.dreameDeviceId})`);
|
|
73371
|
+
}
|
|
73372
|
+
});
|
|
73373
|
+
this.runtimeState.setCapState(CONSUMABLES_CAP_NAME, CONSUMABLES_COLD_START);
|
|
73279
73374
|
}
|
|
73375
|
+
/**
|
|
73376
|
+
* `registerControlCap()` (called by `super.onActivate()`) already registers
|
|
73377
|
+
* the consumables cap before the parent seeds the first slice via
|
|
73378
|
+
* `recomputeSlice()`. No additional work needed here; the override is removed.
|
|
73379
|
+
*/
|
|
73280
73380
|
recomputeSlice() {
|
|
73281
73381
|
const vacuum = this.resolveVacuum();
|
|
73282
73382
|
if (vacuum === null) return;
|
|
73283
73383
|
const tanks = decodeVacuumTanks(vacuum.vacuumCapabilities);
|
|
73284
|
-
const
|
|
73384
|
+
const controlSlice = {
|
|
73285
73385
|
state: mapMiotStateToVacuumState(vacuum.status),
|
|
73286
73386
|
batteryLevel: clampBatteryLevel$1(vacuum.battery),
|
|
73287
73387
|
fanSpeed: suctionLevelToken(vacuum.suction),
|
|
@@ -73292,7 +73392,9 @@ var DreameVacuumDevice = class extends DreameChildDevice {
|
|
|
73292
73392
|
dustBin: tanks.dustBin,
|
|
73293
73393
|
lastChangedAt: Date.now()
|
|
73294
73394
|
};
|
|
73295
|
-
this.runtimeState.setCapState(CAP_NAME$1,
|
|
73395
|
+
this.runtimeState.setCapState(CAP_NAME$1, controlSlice);
|
|
73396
|
+
const consumablesSlice = buildVacuumConsumables(vacuum);
|
|
73397
|
+
this.runtimeState.setCapState(CONSUMABLES_CAP_NAME, consumablesSlice);
|
|
73296
73398
|
}
|
|
73297
73399
|
/** The live typed vacuum handle, or throw a clear error when disconnected. */
|
|
73298
73400
|
requireVacuum() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-dreame",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Dreame robot-vacuum / lawn-mower device-provider addon for CamStack — wraps the @apocaliss92/nodedreame Dreamehome cloud client",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|
|
@@ -54,6 +54,9 @@
|
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
56
|
"name": "device-adoption"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"name": "consumables"
|
|
57
60
|
}
|
|
58
61
|
]
|
|
59
62
|
}
|