Skip to content

Commit

Permalink
feat(vendor.roborock): update Gen4 MCU time using local.time
Browse files Browse the repository at this point in the history
Signed-off-by: Xuefer <[email protected]>
  • Loading branch information
Xuefer committed Mar 31, 2024
1 parent aa90b41 commit 21c202d
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 8 deletions.
23 changes: 18 additions & 5 deletions backend/lib/NTPClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const ntp = require("@destinationstransfers/ntp");
const execSync = require("child_process").execSync;

const Logger = require("./Logger");
const SetMCUTimeCapability = require("./core/capabilities/SetMCUTimeCapability");
const States = require("./entities/core/ntpClient");
const Tools = require("./utils/Tools");

Expand All @@ -12,9 +13,11 @@ class NTPClient {
/**
* @param {object} options
* @param {import("./Configuration")} options.config
* @param {import("./core/ValetudoRobot")} options.robot
*/
constructor(options) {
this.config = options.config;
this.robot = options.robot;

this.nextPollTimeout = undefined;
this.retryWaitTime = BASE_RETRY_WAIT_TIME;
Expand Down Expand Up @@ -47,7 +50,7 @@ class NTPClient {
if (ntpConfig.enabled === true) {
this.state = new States.ValetudoNTPClientEnabledState({});

if (this.config.get("embedded") === true) {
if (this.config.get("embedded") === true || this.robot.hasCapability(SetMCUTimeCapability.TYPE)) {
this.pollTime().catch(() => {
/* intentional */
});
Expand Down Expand Up @@ -79,7 +82,7 @@ class NTPClient {

Logger.debug("Got Time from NTP Server:", currentNTPTime);

this.setTime(currentNTPTime);
await this.setTime(currentNTPTime);

this.state = new States.ValetudoNTPClientSyncedState({
offset: currentNTPTime.getTime() - preSyncTime.getTime()
Expand Down Expand Up @@ -142,7 +145,7 @@ class NTPClient {
}


setTime(date) {
async setTime(date) {
if (this.config.get("embedded") === true) {
let dateString = "";

Expand All @@ -161,10 +164,20 @@ class NTPClient {

execSync(this.busybox + " date -s \""+dateString+"\"");

Logger.info("Successfully set the robot time via NTP to", date);
Logger.info("Successfully set the system time via NTP to", date);
} else {
Logger.warn("Cannot set the time. We are not embedded.");
Logger.warn("Cannot set the system time. We are not embedded.");
}

if (this.robot.hasCapability(SetMCUTimeCapability.TYPE)) {
try {
await this.robot.capabilities[SetMCUTimeCapability.TYPE].setTime(date);
Logger.info("Successfully set the robot MCU time via NTP to", date);
} catch (error) {
Logger.info("Error while setting MCU time", error);
}
}

}

/**
Expand Down
3 changes: 2 additions & 1 deletion backend/lib/Valetudo.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ class Valetudo {


this.ntpClient = new NTPClient({
config: this.config
config: this.config,
robot: this.robot
});

this.robot.startup();
Expand Down
27 changes: 27 additions & 0 deletions backend/lib/core/capabilities/SetMCUTimeCapability.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const Capability = require("./Capability");
const NotImplementedError = require("../NotImplementedError");

/**
* @template {import("../ValetudoRobot")} T
* @extends Capability<T>
*/
class SetMCUTimeCapability extends Capability {
/**
* Sets the MCU time
*
* @abstract
* @param {Date} date
* @returns {Promise<void>}
*/
async setTime(date) {
throw new NotImplementedError();
}

getType() {
return SetMCUTimeCapability.TYPE;
}
}

SetMCUTimeCapability.TYPE = "SetMCUTimeCapability";

module.exports = SetMCUTimeCapability;
1 change: 1 addition & 0 deletions backend/lib/core/capabilities/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ module.exports = {
PetObstacleAvoidanceControlCapability: require("./PetObstacleAvoidanceControlCapability"),
PresetSelectionCapability: require("./PresetSelectionCapability"),
QuirksCapability: require("./QuirksCapability"),
SetMCUTimeCapability: require("./SetMCUTimeCapability"),
SpeakerTestCapability: require("./SpeakerTestCapability"),
SpeakerVolumeControlCapability: require("./SpeakerVolumeControlCapability"),
TotalStatisticsCapability: require("./TotalStatisticsCapability"),
Expand Down
8 changes: 7 additions & 1 deletion backend/lib/miio/MiioSocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,11 @@ class MiioSocket {

/*
If a message has a result or error property, it is a response to a request from the robot,
local.* or _internal.* is a response with params instead of result,
meaning that we should not add it to our pending requests
*/
if (msg !== null && msg !== undefined && !msg["result"] && !msg["error"]) {
const pending = (msg !== null && msg !== undefined && !msg["result"] && !msg["error"] && !msg["method"].startsWith("local.") && !msg["method"].startsWith("_internal."));
if (pending) {
const msgId = msg["id"];

this.pendingRequests[msgId] = {
Expand Down Expand Up @@ -223,6 +225,10 @@ class MiioSocket {

Logger.debug(">>> " + this.name + ":", msg);
this.socket.send(packet, 0, packet.length, this.rinfo.port, this.rinfo.address);

if (!pending) {
resolve();
}
});
}

Expand Down
3 changes: 2 additions & 1 deletion backend/lib/robots/roborock/RoborockGen4ValetudoRobot.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ class RoborockGen4ValetudoRobot extends RoborockValetudoRobot {
capabilities.RoborockMultiMapMapResetCapability,
capabilities.RoborockMapSegmentationCapability,
capabilities.RoborockMapSegmentEditCapability,
capabilities.RoborockMapSegmentRenameCapability
capabilities.RoborockMapSegmentRenameCapability,
capabilities.RoborockSetMCUTimeCapability
].forEach(capability => {
this.registerCapability(new capability({robot: this}));
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const SetMCUTimeCapability = require("../../../core/capabilities/SetMCUTimeCapability");

/**
* @extends SetMCUTimeCapability<import("../RoborockValetudoRobot")>
*/
class RoborockSetMCUTimeCapability extends SetMCUTimeCapability {
/**
* Sets the MCU time
*
* @param {Date} date
* @returns {Promise<void>}
*/
async setTime(date) {
await this.robot.sendCommand("local.time", [Math.floor(date.valueOf() / 1000)], {});
}
}

module.exports = RoborockSetMCUTimeCapability;
1 change: 1 addition & 0 deletions backend/lib/robots/roborock/capabilities/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ module.exports = {
RoborockObstacleAvoidanceControlCapability: require("./RoborockObstacleAvoidanceControlCapability"),
RoborockPersistentMapControlCapability: require("./RoborockPersistentMapControlCapability"),
RoborockPetObstacleAvoidanceControlCapability: require("./RoborockPetObstacleAvoidanceControlCapability"),
RoborockSetMCUTimeCapability: require("./RoborockSetMCUTimeCapability"),
RoborockSpeakerTestCapability: require("./RoborockSpeakerTestCapability"),
RoborockSpeakerVolumeControlCapability: require("./RoborockSpeakerVolumeControlCapability"),
RoborockTotalStatisticsCapability: require("./RoborockTotalStatisticsCapability"),
Expand Down
1 change: 1 addition & 0 deletions backend/lib/webserver/CapabilitiesRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const CAPABILITY_TYPE_TO_ROUTER_MAPPING = {
[capabilities.ManualControlCapability.TYPE]: capabilityRouters.ManualControlCapabilityRouter,
[capabilities.CombinedVirtualRestrictionsCapability.TYPE]: capabilityRouters.CombinedVirtualRestrictionsCapabilityRouter,
[capabilities.PersistentMapControlCapability.TYPE]: capabilityRouters.SimpleToggleCapabilityRouter,
[capabilities.SetMCUTimeCapability.TYPE]: capabilityRouters.DummyCapabilityRouter,
[capabilities.SpeakerVolumeControlCapability.TYPE]: capabilityRouters.SpeakerVolumeControlCapabilityRouter,
[capabilities.MapSegmentationCapability.TYPE]: capabilityRouters.MapSegmentationCapabilityRouter,
[capabilities.DoNotDisturbCapability.TYPE]: capabilityRouters.DoNotDisturbCapabilityRouter,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const CapabilityRouter = require("./CapabilityRouter");

class DummyCapabilityRouter extends CapabilityRouter {
initRoutes() {
//intentional
}
}

module.exports = DummyCapabilityRouter;
1 change: 1 addition & 0 deletions backend/lib/webserver/capabilityRouters/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module.exports = {
CombinedVirtualRestrictionsCapabilityRouter: require("./CombinedVirtualRestrictionsCapabilityRouter"),
ConsumableMonitoringCapabilityRouter: require("./ConsumableMonitoringCapabilityRouter"),
DoNotDisturbCapabilityRouter: require("./DoNotDisturbCapabilityRouter"),
DummyCapabilityRouter: require("./DummyCapabilityRouter"),
GoToLocationCapabilityRouter: require("./GoToLocationCapabilityRouter"),
LocateCapabilityRouter: require("./LocateCapabilityRouter"),
ManualControlCapabilityRouter: require("./ManualControlCapabilityRouter"),
Expand Down

0 comments on commit 21c202d

Please sign in to comment.