Skip to content

Commit

Permalink
feat: AutoEmptyDockAutoEmptyIntervalControlCapability
Browse files Browse the repository at this point in the history
  • Loading branch information
Hypfer committed Apr 21, 2024
1 parent 99e13da commit 6465975
Show file tree
Hide file tree
Showing 22 changed files with 513 additions and 65 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const Capability = require("./Capability");
const NotImplementedError = require("../NotImplementedError");

/**
* @template {import("../ValetudoRobot")} T
* @extends Capability<T>
*/
class AutoEmptyDockAutoEmptyIntervalControlCapability extends Capability {
/**
*
* @param {object} options
* @param {T} options.robot
* @class
*/
constructor(options) {
super(options);
}

/**
* @returns {Promise<AutoEmptyDockAutoEmptyIntervalControlCapabilityInterval>}
*/
async getInterval() {
throw new NotImplementedError();
}

/**
*
* @param {AutoEmptyDockAutoEmptyIntervalControlCapabilityInterval} newMode
* @returns {Promise<void>}
*/
async setInterval(newMode) {
throw new NotImplementedError();
}

/**
* @returns {{supportedIntervals: Array<AutoEmptyDockAutoEmptyIntervalControlCapabilityInterval>}}
*/
getProperties() {
return {
supportedIntervals: []
};
}

getType() {
return AutoEmptyDockAutoEmptyIntervalControlCapability.TYPE;
}
}

AutoEmptyDockAutoEmptyIntervalControlCapability.TYPE = "AutoEmptyDockAutoEmptyIntervalControlCapability";

/**
* @typedef {string} AutoEmptyDockAutoEmptyIntervalControlCapabilityInterval
* @enum {string}
*
*/
AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL = Object.freeze({
INFREQUENT: "infrequent",
NORMAL: "normal",
FREQUENT: "frequent",
});


module.exports = AutoEmptyDockAutoEmptyIntervalControlCapability;

1 change: 1 addition & 0 deletions backend/lib/core/capabilities/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = {
AutoEmptyDockAutoEmptyControlCapability: require("./AutoEmptyDockAutoEmptyControlCapability"),
AutoEmptyDockAutoEmptyIntervalControlCapability: require("./AutoEmptyDockAutoEmptyIntervalControlCapability"),
AutoEmptyDockManualTriggerCapability: require("./AutoEmptyDockManualTriggerCapability"),
BasicControlCapability: require("./BasicControlCapability"),
CarpetModeControlCapability: require("./CarpetModeControlCapability"),
Expand Down
2 changes: 1 addition & 1 deletion backend/lib/robots/dreame/DreameD10SPlusValetudoRobot.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class DreameD10SPlusValetudoRobot extends DreameGen2LidarValetudoRobot {
capabilities.DreameAICameraObstacleAvoidanceControlCapability,
capabilities.DreamePetObstacleAvoidanceControlCapability,
capabilities.DreameCollisionAvoidantNavigationControlCapability,
capabilities.DreameAutoEmptyDockAutoEmptyIntervalControlCapabilityV1
].forEach(capability => {
this.registerCapability(new capability({robot: this}));
});
Expand All @@ -113,7 +114,6 @@ class DreameD10SPlusValetudoRobot extends DreameGen2LidarValetudoRobot {
quirks: [
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.CARPET_MODE_SENSITIVITY),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.TIGHT_MOP_PATTERN),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.AUTO_EMPTY_INTERVAL),
]
}));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ class DreameL10SProUltraHeatValetudoRobot extends DreameGen2LidarValetudoRobot {
capabilities.DreameAICameraLineLaserObstacleAvoidanceControlCapability,
capabilities.DreamePetObstacleAvoidanceControlCapability,
capabilities.DreameCollisionAvoidantNavigationControlCapability,
capabilities.DreameAutoEmptyDockAutoEmptyIntervalControlCapabilityV2
].forEach(capability => {
this.registerCapability(new capability({robot: this}));
});
Expand All @@ -164,8 +165,6 @@ class DreameL10SProUltraHeatValetudoRobot extends DreameGen2LidarValetudoRobot {
robot: this,
quirks: [
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.CARPET_MODE_SENSITIVITY),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.TIGHT_MOP_PATTERN),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.AUTO_EMPTY_INTERVAL),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_MOP_CLEANING_FREQUENCY),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DRYING_TIME),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_DETERGENT),
Expand Down
2 changes: 1 addition & 1 deletion backend/lib/robots/dreame/DreameL10SUltraValetudoRobot.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ class DreameL10SUltraValetudoRobot extends DreameGen2LidarValetudoRobot {
capabilities.DreameAICameraLineLaserObstacleAvoidanceControlCapability,
capabilities.DreamePetObstacleAvoidanceControlCapability,
capabilities.DreameCollisionAvoidantNavigationControlCapability,
capabilities.DreameAutoEmptyDockAutoEmptyIntervalControlCapabilityV1
].forEach(capability => {
this.registerCapability(new capability({robot: this}));
});
Expand All @@ -158,7 +159,6 @@ class DreameL10SUltraValetudoRobot extends DreameGen2LidarValetudoRobot {
quirks: [
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.CARPET_MODE_SENSITIVITY),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.TIGHT_MOP_PATTERN),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.AUTO_EMPTY_INTERVAL),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_MOP_CLEANING_FREQUENCY),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DRYING_TIME),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_DETERGENT),
Expand Down
2 changes: 1 addition & 1 deletion backend/lib/robots/dreame/DreameL10UltraValetudoRobot.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ class DreameL10UltraValetudoRobot extends DreameGen2LidarValetudoRobot {
capabilities.DreameMopDockCleanManualTriggerCapability,
capabilities.DreameMopDockDryManualTriggerCapability,
capabilities.DreameCollisionAvoidantNavigationControlCapability,
capabilities.DreameAutoEmptyDockAutoEmptyIntervalControlCapabilityV1
].forEach(capability => {
this.registerCapability(new capability({robot: this}));
});
Expand All @@ -147,7 +148,6 @@ class DreameL10UltraValetudoRobot extends DreameGen2LidarValetudoRobot {
quirks: [
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.CARPET_MODE_SENSITIVITY),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.TIGHT_MOP_PATTERN),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.AUTO_EMPTY_INTERVAL),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_MOP_CLEANING_FREQUENCY),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DRYING_TIME),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_WET_DRY_SWITCH),
Expand Down
2 changes: 1 addition & 1 deletion backend/lib/robots/dreame/DreameP2150ValetudoRobot.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class DreameP2150ValetudoRobot extends DreameGen2LidarValetudoRobot {
capabilities.DreameKeyLockCapability,
capabilities.DreameAutoEmptyDockAutoEmptyControlCapability,
capabilities.DreameAutoEmptyDockManualTriggerCapability,
capabilities.DreameAutoEmptyDockAutoEmptyIntervalControlCapabilityV1
].forEach(capability => {
this.registerCapability(new capability({robot: this}));
});
Expand All @@ -113,7 +114,6 @@ class DreameP2150ValetudoRobot extends DreameGen2LidarValetudoRobot {
robot: this,
quirks: [
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.CARPET_MODE_SENSITIVITY),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.AUTO_EMPTY_INTERVAL)
]
}));

Expand Down
50 changes: 0 additions & 50 deletions backend/lib/robots/dreame/DreameQuirkFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,55 +107,6 @@ class DreameQuirkFactory {
);
}
});
case DreameQuirkFactory.KNOWN_QUIRKS.AUTO_EMPTY_INTERVAL:
return new Quirk({
id: id,
title: "Auto-empty Interval",
description: "Depending on the size of your home, you might not need to auto-empty the dustbin on " +
"every single cleanup. Note that you can also disable auto-empty entirely and manually trigger " +
"it via REST and/or MQTT instead of changing the interval.",
options: ["every_cleanup", "every_second_cleanup", "every_third_cleanup"],
getter: async () => {
const res = await this.helper.readProperty(
DreameMiotServices["GEN2"].AUTO_EMPTY_DOCK.SIID,
DreameMiotServices["GEN2"].AUTO_EMPTY_DOCK.PROPERTIES.INTERVAL.PIID
);

switch (res) {
case 1:
return "every_cleanup";
case 2:
return "every_second_cleanup";
case 3:
return "every_third_cleanup";
default:
throw new Error(`Received invalid value ${res}`);
}
},
setter: async (value) => {
let val;

switch (value) {
case "every_cleanup":
val = 1;
break;
case "every_second_cleanup":
val = 2;
break;
case "every_third_cleanup":
val = 3;
break;
default:
throw new Error(`Received invalid value ${value}`);
}

return this.helper.writeProperty(
DreameMiotServices["GEN2"].AUTO_EMPTY_DOCK.SIID,
DreameMiotServices["GEN2"].AUTO_EMPTY_DOCK.PROPERTIES.INTERVAL.PIID,
val
);
}
});
case DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_MOP_ONLY_MODE:
return new Quirk({
id: id,
Expand Down Expand Up @@ -899,7 +850,6 @@ class DreameQuirkFactory {
DreameQuirkFactory.KNOWN_QUIRKS = {
CARPET_MODE_SENSITIVITY: "f8cb91ab-a47a-445f-b300-0aac0d4937c0",
TIGHT_MOP_PATTERN: "8471c118-f1e1-4866-ad2e-3c11865a5ba8",
AUTO_EMPTY_INTERVAL: "d38118f2-fb5d-4ed9-b668-262db15e5269",
MOP_DOCK_MOP_ONLY_MODE: "6afbb882-c4c4-4672-b008-887454e6e0d1",
MOP_DOCK_MOP_CLEANING_FREQUENCY: "a6709b18-57af-4e11-8b4c-8ae33147ab34",
MOP_DOCK_UV_TREATMENT: "7f97b603-967f-44f0-9dfb-35bcdc21f433",
Expand Down
2 changes: 1 addition & 1 deletion backend/lib/robots/dreame/DreameX10PlusValetudoRobot.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ class DreameX10PlusValetudoRobot extends DreameGen2LidarValetudoRobot {
capabilities.DreameMopDockDryManualTriggerCapability,
capabilities.DreameAICameraLineLaserObstacleAvoidanceControlCapability,
capabilities.DreamePetObstacleAvoidanceControlCapability,
capabilities.DreameAutoEmptyDockAutoEmptyIntervalControlCapabilityV1
].forEach(capability => {
this.registerCapability(new capability({robot: this}));
});
Expand All @@ -148,7 +149,6 @@ class DreameX10PlusValetudoRobot extends DreameGen2LidarValetudoRobot {
quirks: [
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.CARPET_MODE_SENSITIVITY),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.TIGHT_MOP_PATTERN),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.AUTO_EMPTY_INTERVAL),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_MOP_CLEANING_FREQUENCY),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_WET_DRY_SWITCH),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_AUTO_REPAIR_TRIGGER),
Expand Down
2 changes: 1 addition & 1 deletion backend/lib/robots/dreame/DreameZ10ProValetudoRobot.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class DreameZ10ProValetudoRobot extends DreameGen2LidarValetudoRobot {
capabilities.DreameAutoEmptyDockAutoEmptyControlCapability,
capabilities.DreameAutoEmptyDockManualTriggerCapability,
capabilities.DreameLineLaserObstacleAvoidanceControlCapability,
capabilities.DreameAutoEmptyDockAutoEmptyIntervalControlCapabilityV1
].forEach(capability => {
this.registerCapability(new capability({robot: this}));
});
Expand All @@ -115,7 +116,6 @@ class DreameZ10ProValetudoRobot extends DreameGen2LidarValetudoRobot {
quirks: [
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.CARPET_MODE_SENSITIVITY),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.TIGHT_MOP_PATTERN),
QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.AUTO_EMPTY_INTERVAL)
]
}));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ class DreameAutoEmptyDockAutoEmptyControlCapability extends AutoEmptyDockAutoEmp
async isEnabled() {
const res = await this.helper.readProperty(this.siid, this.piid);

return res === 1;
// On newer dreames such as the l10spuh, for whatever reason, the interval is also encoded in this value
// To stay compatible with the older ones while also handling that gracefully, this needs to be >= 1 instead of === 1
return res >= 1;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const AutoEmptyDockAutoEmptyIntervalControlCapability = require("../../../core/capabilities/AutoEmptyDockAutoEmptyIntervalControlCapability");
const DreameMiotHelper = require("../DreameMiotHelper");
const DreameMiotServices = require("../DreameMiotServices");

/**
* @extends AutoEmptyDockAutoEmptyIntervalControlCapability<import("../DreameValetudoRobot")>
*/
class DreameAutoEmptyDockAutoEmptyIntervalControlCapabilityV1 extends AutoEmptyDockAutoEmptyIntervalControlCapability {

/**
* @param {object} options
* @param {import("../DreameValetudoRobot")} options.robot
*/
constructor(options) {
super(options);

this.siid = DreameMiotServices["GEN2"].AUTO_EMPTY_DOCK.SIID;
this.piid = DreameMiotServices["GEN2"].AUTO_EMPTY_DOCK.PROPERTIES.INTERVAL.PIID;

this.helper = new DreameMiotHelper({robot: this.robot});
}

async getInterval() {
const res = await this.helper.readProperty(this.siid, this.piid);

if (res === 1) {
return AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL.NORMAL;
} else {
return AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL.INFREQUENT;
}
}

async setInterval(newInterval) {
let val;

switch (newInterval) {
case AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL.NORMAL:
val = 1;
break;
case AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL.INFREQUENT:
val = 3;
break;
default:
throw new Error(`Received invalid interval ${newInterval}`);
}

await this.helper.writeProperty(this.siid, this.piid, val);
}

getProperties() {
return {
supportedIntervals: [
AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL.NORMAL,
AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL.INFREQUENT,
]
};
}
}

module.exports = DreameAutoEmptyDockAutoEmptyIntervalControlCapabilityV1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const AutoEmptyDockAutoEmptyIntervalControlCapability = require("../../../core/capabilities/AutoEmptyDockAutoEmptyIntervalControlCapability");
const DreameMiotHelper = require("../DreameMiotHelper");
const DreameMiotServices = require("../DreameMiotServices");

/**
* @extends AutoEmptyDockAutoEmptyIntervalControlCapability<import("../DreameValetudoRobot")>
*/
class DreameAutoEmptyDockAutoEmptyIntervalControlCapabilityV2 extends AutoEmptyDockAutoEmptyIntervalControlCapability {

/**
* @param {object} options
* @param {import("../DreameValetudoRobot")} options.robot
*/
constructor(options) {
super(options);

this.siid = DreameMiotServices["GEN2"].AUTO_EMPTY_DOCK.SIID;
this.piid = DreameMiotServices["GEN2"].AUTO_EMPTY_DOCK.PROPERTIES.AUTO_EMPTY_ENABLED.PIID;

this.helper = new DreameMiotHelper({robot: this.robot});
}

async getInterval() {
const res = await this.helper.readProperty(this.siid, this.piid);

switch (res) {
case 3:
return AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL.INFREQUENT;
case 2:
return AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL.FREQUENT;

case 1:
default:
return AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL.NORMAL;
}
}

async setInterval(newInterval) {
let val;

switch (newInterval) {
case AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL.NORMAL:
val = 1;
break;
case AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL.FREQUENT:
val = 2;
break;
case AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL.INFREQUENT:
val = 3;
break;
default:
throw new Error(`Received invalid interval ${newInterval}`);
}

await this.helper.writeProperty(this.siid, this.piid, val);
}

getProperties() {
return {
supportedIntervals: [
AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL.NORMAL,
AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL.FREQUENT,
AutoEmptyDockAutoEmptyIntervalControlCapability.INTERVAL.INFREQUENT,
]
};
}
}

module.exports = DreameAutoEmptyDockAutoEmptyIntervalControlCapabilityV2;
2 changes: 2 additions & 0 deletions backend/lib/robots/dreame/capabilities/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ module.exports = {
DreameAICameraLineLaserObstacleAvoidanceControlCapability: require("./DreameAICameraLineLaserObstacleAvoidanceControlCapability"),
DreameAICameraObstacleAvoidanceControlCapability: require("./DreameAICameraObstacleAvoidanceControlCapability"),
DreameAutoEmptyDockAutoEmptyControlCapability: require("./DreameAutoEmptyDockAutoEmptyControlCapability"),
DreameAutoEmptyDockAutoEmptyIntervalControlCapabilityV1: require("./DreameAutoEmptyDockAutoEmptyIntervalControlCapabilityV1"),
DreameAutoEmptyDockAutoEmptyIntervalControlCapabilityV2: require("./DreameAutoEmptyDockAutoEmptyIntervalControlCapabilityV2"),
DreameAutoEmptyDockManualTriggerCapability: require("./DreameAutoEmptyDockManualTriggerCapability"),
DreameBasicControlCapability: require("./DreameBasicControlCapability"),
DreameCarpetModeControlCapability: require("./DreameCarpetModeControlCapability"),
Expand Down
Loading

0 comments on commit 6465975

Please sign in to comment.