Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Roborock/Capability Do Not Disturb #656

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions client/services/api.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,15 +227,15 @@ export class ApiService {
}

static async getDnd() {
return await this.fetch("GET", "api/get_dnd");
return await this.fetch("GET", "api/v2/robot/capabilities/DoNotDisturbCapability");
}

static async deleteDnd() {
await this.fetch("PUT", "api/delete_dnd");
await this.fetch("DELETE", "api/v2/robot/capabilities/DoNotDisturbCapability", {action: "delete"});
}

static async setDnd(start_hour, start_minute, end_hour, end_minute) {
await this.fetch("POST", "api/set_dnd", {start_hour, start_minute, end_hour, end_minute});
await this.fetch("POST", "api/v2/robot/capabilities/DoNotDisturbCapability", {start: {hour: start_hour, minute: start_minute}, end: {hour: end_hour, minute: end_minute}});
}

static async getCarpetMode() {
Expand Down
7 changes: 5 additions & 2 deletions client/settings-timers.html
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,21 @@
</div>
<div class="center">Timers</div>
<div class="right">
<!--
<ons-toolbar-button id="settings-timers-timezone" onclick="showTimeZoneDialog();">
<ons-icon icon="fa-cog"></ons-icon>
</ons-toolbar-button>
-->
</div>
</ons-toolbar>
<ons-progress-bar id="loading-bar-settings-timers" value="0" indeterminate="indeterminate"></ons-progress-bar>

<!--
<ons-list-title style="margin-top:5px;">
Cleaning - Timers <ons-toolbar-button id="settings-timers-create-new-timer" onclick="showAddTimerDialog(-1);"><ons-icon icon="fa-plus"></ons-icon></ons-toolbar-button></div>
</ons-list-title>
<ons-list id="settings-timers-timer-list"></ons-list>

-->
<ons-list-title style="margin-top:5px;">"Do Not Disturb" - Timer</ons-list-title>
<ons-list id="settings-dnd-timer-list"></ons-list>

Expand All @@ -148,7 +151,7 @@
ons.getScriptPage().appendChild(s);

ons.getScriptPage().onShow = function() {
updateSettingsTimersPage();
//updateSettingsTimersPage();
updateDndTimerPage();
};
}
Expand Down
12 changes: 6 additions & 6 deletions client/settings-timers.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ async function updateDndTimerPage() {
try {
let res = await ApiService.getDnd();
// TODO: Check if multiple dnd timers can be created!
if (res.length === 0 || res[0].enabled === 0) {
if (res.length === 0 || !(res[0].enabled) ) {
// no timer is enabled yet, show possibility to add dnd timer
dndTimerList.appendChild(ons.createElement(
"<ons-list-item>\n" +
Expand All @@ -113,13 +113,13 @@ async function updateDndTimerPage() {
res.forEach(function(dndTimer) {
dndTimerList.appendChild(ons.createElement(
"<ons-list-item>\n" +
" <div class='left'>DND will start at " + dndTimer.start_hour + ":" +
asTwoDigitNumber(dndTimer.start_minute) + " and end on " +
dndTimer.end_hour + ":" + asTwoDigitNumber(dndTimer.end_minute) + "</div>" +
" <div class='left'>DND will start at " + dndTimer.start.hour + ":" +
asTwoDigitNumber(dndTimer.start.minute) + " and end on " +
dndTimer.end.hour + ":" + asTwoDigitNumber(dndTimer.end.minute) + "</div>" +
" <div class='right'>" +
" <ons-button modifier='quiet' class='button-margin' style='font-size: 2em;' onclick='showDndTimerDialog(" +
dndTimer.start_hour + ", " + dndTimer.start_minute + ", " +
dndTimer.end_hour + ", " + dndTimer.end_minute + ");'>" +
dndTimer.start.hour + ", " + dndTimer.start.minute + ", " +
dndTimer.end.hour + ", " + dndTimer.end.minute + ");'>" +
" <ons-icon icon='fa-edit'></ons-icon>" +
" </ons-button>" +
" <ons-button modifier='quiet' class='button-margin' style='font-size: 2em;' onclick='deleteDndTimer();'>" +
Expand Down
4 changes: 2 additions & 2 deletions client/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
<div class="title"><ons-icon icon="fa-info"></ons-icon> Info</div>
<div class="content">View device information</div>
</ons-card>
<!--

<ons-card onclick="fn.pushPage({'id': 'settings-timers.html', 'title': 'Timers'})">
<div class="title"><ons-icon icon="fa-clock-o"></ons-icon> Timers</div>
<div class="content">Manage timers</div>
</ons-card>
-->

<!--
<ons-card onclick="fn.pushPage({'id': 'settings-carpet-mode.html', 'title': 'Carpet Mode'})">
<div class="title"><ons-icon icon="fa-cart-arrow-down"></ons-icon> Carpet Mode</div>
Expand Down
39 changes: 39 additions & 0 deletions lib/core/capabilities/DoNotDisturbCapability.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const Capability = require("./Capability");
const NotImplementedError = require("../NotImplementedError");

class DoNotDisturbCapability extends Capability {
/**
* This function polls the current consumables state and stores the attributes in our robotState
*
* @abstract
* @returns {Promise<Array<import("../../entities/state/attributes/DoNotDisturbAttribute")>>}
*/
async getDnd() {
throw new NotImplementedError();
}

/**
* @abstract
* @returns {Promise<void>}
*/
async deleteDnd() {
throw new NotImplementedError();
}

/**
* @abstract
* @param {object} preset
* @returns {Promise<void>}
*/
async setDnd(preset) {
throw new NotImplementedError();
}

getType() {
return DoNotDisturbCapability.TYPE;
}
}

DoNotDisturbCapability.TYPE = "DoNotDisturbCapability";

module.exports = DoNotDisturbCapability;
1 change: 1 addition & 0 deletions lib/core/capabilities/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ module.exports = {
SensorCalibrationCapability: require("./SensorCalibrationCapability"),
SpeakerVolumeControlCapability: require("./SpeakerVolumeControlCapability"),
RawCommandCapability: require("./RawCommandCapability"),
DoNotDisturbCapability: require("./DoNotDisturbCapability"),
};
23 changes: 23 additions & 0 deletions lib/entities/state/attributes/DoNotDisturbAttribute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const StateAttribute = require("./StateAttribute");

class DoNotDisturbAttribute extends StateAttribute {
/**
* @param {object} options
* @param {boolean} options.enabled
* @param {object} options.start
* @param {number} options.start.hour
* @param {number} options.start.minute
* @param {object} options.end
* @param {number} options.end.hour
* @param {number} options.end.minute
*/
constructor(options) {
super(options);

this.enabled = options.enabled;
this.start = options.start;
this.end = options.end;
}
}

module.exports = DoNotDisturbAttribute;
3 changes: 2 additions & 1 deletion lib/entities/state/attributes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ module.exports = {
PersistentMapSettingStateAttribute: require("./PersistentMapSettingStateAttribute"),
OperationModeStateAttribute: require("./OperationModeStateAttribute"),
AttachmentStateAttribute: require("./AttachmentStateAttribute"),
MovementModeStateAttribute: require("./MovementModeStateAttribute")
MovementModeStateAttribute: require("./MovementModeStateAttribute"),
DoNotDisturbAttribute: require("./DoNotDisturbAttribute")
};
3 changes: 3 additions & 0 deletions lib/robots/roborock/RoborockValetudoRobot.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class RoborockValetudoRobot extends MiioValetudoRobot {
this.registerCapability(new capabilities.RoborockLocateCapability({
robot: this
}));
this.registerCapability(new capabilities.RoborockDoNotDisturbCapability({
robot: this
}));
}

setEmbeddedParameters() {
Expand Down
58 changes: 58 additions & 0 deletions lib/robots/roborock/capabilities/RoborockDoNotDisturbCapability.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const DoNotDisturbCapability = require("../../../core/capabilities/DoNotDisturbCapability");

const DoNotDisturbAttribute = require("../../../entities/state/attributes/DoNotDisturbAttribute");

class RoborockDoNotDisturbCapability extends DoNotDisturbCapability {
/**
* This function polls the current consumables state and stores the attributes in our robotState
*
* @abstract
* @returns {Promise<Array<import("../../../entities/state/attributes/DoNotDisturbAttribute")>>}
*/
async getDnd() {
const data = await this.robot.sendCommand("get_dnd_timer", [], {});

const dnd = [
new DoNotDisturbAttribute({
enabled: (data[0].enabled === 1),
start: {
hour: data[0].start_hour,
minute: data[0].start_minute
},
end: {
hour: data[0].end_hour,
minute: data[0].end_minute
}
})];

dnd.forEach(d => this.robot.state.upsertFirstMatchingAttribute(d));

this.robot.emitStateUpdated();

return dnd;
}

/**
* @abstract
* @returns {Promise<void>}
*/
async deleteDnd() {
await this.robot.sendCommand("close_dnd_timer", [], {});
}

/**
* @abstract
* @param {object} preset
* @returns {Promise<void>}
*/
async setDnd(preset) {
await this.robot.sendCommand("set_dnd_timer", [
parseInt(preset.start.hour),
parseInt(preset.start.minute),
parseInt(preset.end.hour),
parseInt(preset.end.minute)
], {});
}
}

module.exports = RoborockDoNotDisturbCapability;
3 changes: 2 additions & 1 deletion lib/robots/roborock/capabilities/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ module.exports = {
RoborockCombinedVirtualRestrictionsCapability: require("./RoborockCombinedVirtualRestrictionsCapability"),
RoborockPersistentMapControlCapability: require("./RoborockPersistentMapControlCapability"),
RoborockMultiMapPersistentMapControlCapability: require("./RoborockMultiMapPersistentMapControlCapability"),
RoborockMapSegmentationCapability: require("./RoborockMapSegmentationCapability")
RoborockMapSegmentationCapability: require("./RoborockMapSegmentationCapability"),
RoborockDoNotDisturbCapability: require("./RoborockDoNotDisturbCapability")
};
3 changes: 2 additions & 1 deletion lib/webserver/CapabilitiesRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ const CAPABILITY_TYPE_TO_ROUTER_MAPPING = {
[capabilities.SensorCalibrationCapability.TYPE]: capabilityRouters.SensorCalibrationCapabilityRouter,
[capabilities.SpeakerVolumeControlCapability.TYPE]: capabilityRouters.SpeakerVolumeControlCapabilityRouter,
[capabilities.RawCommandCapability.TYPE]: capabilityRouters.RawCommandCapabilityRouter,
[capabilities.MapSegmentationCapability.TYPE]: capabilityRouters.MapSegmentationCapabilityRouter
[capabilities.MapSegmentationCapability.TYPE]: capabilityRouters.MapSegmentationCapabilityRouter,
[capabilities.DoNotDisturbCapability.TYPE]: capabilityRouters.DoNotDisturbCapabilityRouter
};

module.exports = CapabilitiesRouter;
46 changes: 46 additions & 0 deletions lib/webserver/capabilityRouters/DoNotDisturbCapabilityRouter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const Logger = require("../../Logger");

const CapabilityRouter = require("./CapabilityRouter");

class DoNotDisturbCapabilityRouter extends CapabilityRouter {

initRoutes() {
this.router.get("/", async (req, res) => {
res.json(await this.capability.getDnd());
});

this.router.delete("/", async (req, res) => {
if (req.body && req.body.action) {
if (req.body.action === "delete") {
try {
await this.capability.deleteDnd();
res.sendStatus(200);
} catch (e) {
Logger.warn("Error while deleting do not disturb setting", e);
res.status(500).json(e.message);
}
} else {
res.status(400).send("Invalid action \"" + req.body.action + "\" in request body");
}
} else {
res.status(400).send("Missing action in request body");
}
});

this.router.post("/", async (req, res) => {
if (req.body && req.body.start && req.body.end) {
try {
await this.capability.setDnd(req.body);
res.sendStatus(200);
} catch (e) {
Logger.warn("Error while configuring do not disturb setting", e);
res.status(500).json(e.message);
}
} else {
res.status(400).send("Missing parameters in request body");
}
});
}
}

module.exports = DoNotDisturbCapabilityRouter;
3 changes: 2 additions & 1 deletion lib/webserver/capabilityRouters/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ module.exports = {
SensorCalibrationCapabilityRouter: require("./SensorCalibrationCapabilityRouter"),
SpeakerVolumeControlCapabilityRouter: require("./SpeakerVolumeControlCapabilityRouter"),
RawCommandCapabilityRouter: require("./RawCommandCapabilityRouter"),
MapSegmentationCapabilityRouter: require("./MapSegmentationCapabilityRouter")
MapSegmentationCapabilityRouter: require("./MapSegmentationCapabilityRouter"),
DoNotDisturbCapabilityRouter: require("./DoNotDisturbCapabilityRouter")
};