From f610221db7c75cd51386045b6119422d8886acfb Mon Sep 17 00:00:00 2001 From: Xuefer H Date: Sat, 13 Jan 2024 00:41:42 +0800 Subject: [PATCH] feat(vendor.roborock): dryer module support for S7/S8 Pro and G10s Signed-off-by: Xuefer H --- .../roborock/RoborockG10SValetudoRobot.js | 3 + .../robots/roborock/RoborockQuirkFactory.js | 87 ++++++++++++++++++- .../RoborockS7ProUltraValetudoRobot.js | 3 + .../RoborockS8ProUltraValetudoRobot.js | 3 + ...borockMopDockDryManualTriggerCapability.js | 24 +++++ .../lib/robots/roborock/capabilities/index.js | 1 + 6 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 backend/lib/robots/roborock/capabilities/RoborockMopDockDryManualTriggerCapability.js diff --git a/backend/lib/robots/roborock/RoborockG10SValetudoRobot.js b/backend/lib/robots/roborock/RoborockG10SValetudoRobot.js index 034ddc6143d..07db3812793 100644 --- a/backend/lib/robots/roborock/RoborockG10SValetudoRobot.js +++ b/backend/lib/robots/roborock/RoborockG10SValetudoRobot.js @@ -55,6 +55,7 @@ class RoborockG10SValetudoRobot extends RoborockGen4ValetudoRobot { capabilities.RoborockAutoEmptyDockAutoEmptyControlCapability, capabilities.RoborockAutoEmptyDockManualTriggerCapability, capabilities.RoborockMopDockCleanManualTriggerCapability, + capabilities.RoborockMopDockDryManualTriggerCapability, capabilities.RoborockKeyLockCapability, capabilities.RoborockMappingPassCapability, capabilities.RoborockObstacleAvoidanceControlCapability, @@ -75,6 +76,8 @@ class RoborockG10SValetudoRobot extends RoborockGen4ValetudoRobot { quirkFactory.getQuirk(RoborockQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_MOP_CLEANING_FREQUENCY), quirkFactory.getQuirk(RoborockQuirkFactory.KNOWN_QUIRKS.BUTTON_LEDS), quirkFactory.getQuirk(RoborockQuirkFactory.KNOWN_QUIRKS.MOP_PATTERN), + quirkFactory.getQuirk(RoborockQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_AUTO_DRYING), + quirkFactory.getQuirk(RoborockQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_AUTO_DRYING_TIME), ] })); } diff --git a/backend/lib/robots/roborock/RoborockQuirkFactory.js b/backend/lib/robots/roborock/RoborockQuirkFactory.js index 9c802a43aec..cbc71de0297 100644 --- a/backend/lib/robots/roborock/RoborockQuirkFactory.js +++ b/backend/lib/robots/roborock/RoborockQuirkFactory.js @@ -306,6 +306,89 @@ class RoborockQuirkFactory { } } }); + case RoborockQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_AUTO_DRYING: + return new Quirk({ + id: id, + title: "Mop Auto Drying", + description: "Select if the dock should automatically dry the mop after a cleanup", + options: ["on", "off"], + getter: async () => { + const res = await this.robot.sendCommand("app_get_dryer_setting", [], {}); + + switch (res?.status) { + case 1: + return "on"; + case 0: + return "off"; + default: + throw new Error(`Received invalid value ${res?.status}`); + } + }, + setter: async (value) => { + let val; + + switch (value) { + case "on": + val = 1; + break; + case "off": + val = 0; + break; + default: + throw new Error(`Received invalid value ${value}`); + } + + /* + const config = { + "status": val, + "on": { "cliff_on": 1000, "cliff_off": 1000 }, + "off": { "cliff_on": 500, "cliff_off": 500 }, + }; + return this.robot.sendCommand("app_set_dryer_setting", config, {}); + */ + return this.robot.sendCommand("app_set_dryer_setting", { "status": val }, {}); + } + }); + case RoborockQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_AUTO_DRYING_TIME: + return new Quirk({ + id: id, + title: "Mop Auto Drying Time", + description: "Define how long the mop should be dried after a cleanup", + options: ["2h", "3h", "4h"], + getter: async () => { + const res = await this.robot.sendCommand("app_get_dryer_setting", [], {}); + + switch (res?.on.dry_time) { + case 2 * 60 * 60: + return "2h"; + case 3 * 60 * 60: + return "3h"; + case 4 * 60 * 60: + return "4h"; + default: + return String(res.on.dry_time); + } + }, + setter: async (value) => { + let val; + + switch (value) { + case "2h": + val = 2 * 60 * 60; + break; + case "3h": + val = 3 * 60 * 60; + break; + case "4h": + val = 4 * 60 * 60; + break; + default: + val = Number(value); + } + + return this.robot.sendCommand("app_set_dryer_setting", {"on": { "dry_time": val } }, {}); + } + }); default: throw new Error(`There's no quirk with id ${id}`); } @@ -319,7 +402,9 @@ RoborockQuirkFactory.KNOWN_QUIRKS = { MOP_PATTERN: "767fc859-3383-4485-bfdf-7aa800cf487e", MANUAL_MAP_SEGMENT_TRIGGER: "3e467ac1-7d14-4e66-b09b-8d0554a3194e", MOP_DOCK_MOP_CLEANING_FREQUENCY: "c50d98fb-7e29-4d09-a577-70c95ac33239", - MOP_DOCK_MOP_CLEANING_MODE: "b4ca6500-a461-49cb-966a-4726a33ad3df" + MOP_DOCK_MOP_CLEANING_MODE: "b4ca6500-a461-49cb-966a-4726a33ad3df", + MOP_DOCK_AUTO_DRYING: "308bd55a-9c94-480e-a7bb-d6c706526203", + MOP_DOCK_AUTO_DRYING_TIME: "b6ad439c-6665-4ffd-a038-cc72821e5fb1" }; module.exports = RoborockQuirkFactory; diff --git a/backend/lib/robots/roborock/RoborockS7ProUltraValetudoRobot.js b/backend/lib/robots/roborock/RoborockS7ProUltraValetudoRobot.js index 84a175f5227..930dee42493 100644 --- a/backend/lib/robots/roborock/RoborockS7ProUltraValetudoRobot.js +++ b/backend/lib/robots/roborock/RoborockS7ProUltraValetudoRobot.js @@ -54,6 +54,7 @@ class RoborockS7ProUltraValetudoRobot extends RoborockGen4ValetudoRobot { capabilities.RoborockAutoEmptyDockAutoEmptyControlCapability, capabilities.RoborockAutoEmptyDockManualTriggerCapability, capabilities.RoborockMopDockCleanManualTriggerCapability, + capabilities.RoborockMopDockDryManualTriggerCapability, capabilities.RoborockKeyLockCapability, capabilities.RoborockMappingPassCapability ].forEach(capability => { @@ -71,6 +72,8 @@ class RoborockS7ProUltraValetudoRobot extends RoborockGen4ValetudoRobot { quirkFactory.getQuirk(RoborockQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_MOP_CLEANING_FREQUENCY), quirkFactory.getQuirk(RoborockQuirkFactory.KNOWN_QUIRKS.BUTTON_LEDS), quirkFactory.getQuirk(RoborockQuirkFactory.KNOWN_QUIRKS.MOP_PATTERN), + quirkFactory.getQuirk(RoborockQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_AUTO_DRYING), + quirkFactory.getQuirk(RoborockQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_AUTO_DRYING_TIME), ] })); } diff --git a/backend/lib/robots/roborock/RoborockS8ProUltraValetudoRobot.js b/backend/lib/robots/roborock/RoborockS8ProUltraValetudoRobot.js index 6afd455bacc..25a2d61f7fb 100644 --- a/backend/lib/robots/roborock/RoborockS8ProUltraValetudoRobot.js +++ b/backend/lib/robots/roborock/RoborockS8ProUltraValetudoRobot.js @@ -54,6 +54,7 @@ class RoborockS8ProUltraValetudoRobot extends RoborockGen4ValetudoRobot { [ capabilities.RoborockAutoEmptyDockAutoEmptyControlCapability, capabilities.RoborockAutoEmptyDockManualTriggerCapability, + capabilities.RoborockMopDockDryManualTriggerCapability, capabilities.RoborockKeyLockCapability, capabilities.RoborockMappingPassCapability, capabilities.RoborockObstacleAvoidanceControlCapability, @@ -74,6 +75,8 @@ class RoborockS8ProUltraValetudoRobot extends RoborockGen4ValetudoRobot { quirkFactory.getQuirk(RoborockQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_MOP_CLEANING_FREQUENCY), quirkFactory.getQuirk(RoborockQuirkFactory.KNOWN_QUIRKS.BUTTON_LEDS), quirkFactory.getQuirk(RoborockQuirkFactory.KNOWN_QUIRKS.MOP_PATTERN), + quirkFactory.getQuirk(RoborockQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_AUTO_DRYING), + quirkFactory.getQuirk(RoborockQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_AUTO_DRYING_TIME), ] })); } diff --git a/backend/lib/robots/roborock/capabilities/RoborockMopDockDryManualTriggerCapability.js b/backend/lib/robots/roborock/capabilities/RoborockMopDockDryManualTriggerCapability.js new file mode 100644 index 00000000000..f79d8a345d5 --- /dev/null +++ b/backend/lib/robots/roborock/capabilities/RoborockMopDockDryManualTriggerCapability.js @@ -0,0 +1,24 @@ +const MopDockDryManualTriggerCapability = require("../../../core/capabilities/MopDockDryManualTriggerCapability"); + +/** + * @extends MopDockDryManualTriggerCapability + */ +class RoborockMopDockDryManualTriggerCapability extends MopDockDryManualTriggerCapability { + /** + * @abstract + * @returns {Promise} + */ + async startDrying() { + return await this.robot.sendCommand("app_set_dryer_status", { "status": 1 }, {}); + } + + /** + * @abstract + * @returns {Promise} + */ + async stopDrying() { + return await this.robot.sendCommand("app_set_dryer_status", { "status": 0 }, {}); + } +} + +module.exports = RoborockMopDockDryManualTriggerCapability; diff --git a/backend/lib/robots/roborock/capabilities/index.js b/backend/lib/robots/roborock/capabilities/index.js index f50741d67ff..3412756b960 100644 --- a/backend/lib/robots/roborock/capabilities/index.js +++ b/backend/lib/robots/roborock/capabilities/index.js @@ -22,6 +22,7 @@ module.exports = { RoborockMapSnapshotCapability: require("./RoborockMapSnapshotCapability"), RoborockMappingPassCapability: require("./RoborockMappingPassCapability"), RoborockMopDockCleanManualTriggerCapability: require("./RoborockMopDockCleanManualTriggerCapability"), + RoborockMopDockDryManualTriggerCapability: require("./RoborockMopDockDryManualTriggerCapability"), RoborockMultiMapMapResetCapability: require("./RoborockMultiMapMapResetCapability"), RoborockMultiMapPersistentMapControlCapability: require("./RoborockMultiMapPersistentMapControlCapability"), RoborockObstacleAvoidanceControlCapability: require("./RoborockObstacleAvoidanceControlCapability"),