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

Do not disturb capability #659

Merged
merged 4 commits into from
Jan 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
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
26 changes: 14 additions & 12 deletions client/services/api.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,16 +226,22 @@ export class ApiService {
await this.fetch("DELETE", "api/timers/" + id);
}

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

static async deleteDnd() {
await this.fetch("PUT", "api/delete_dnd");
}

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});
static async setDndConfiguration(enabled, start_hour, start_minute, end_hour, end_minute) {
await this.fetch("PUT", "api/v2/robot/capabilities/DoNotDisturbCapability", {
enabled: enabled,
start: {
hour: start_hour,
minute: start_minute
},
end: {
hour: end_hour,
minute: end_minute
}
});
}

static async getCarpetMode() {
Expand Down Expand Up @@ -270,10 +276,6 @@ export class ApiService {
}


static async setLabStatus(labStatus) {
await this.fetch("PUT", "api/set_lab_status", {lab_status: labStatus});
}

static async resetConsumable(type, subType) {
var url = "api/v2/robot/capabilities/ConsumableMonitoringCapability/" + type;

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
53 changes: 30 additions & 23 deletions client/settings-timers.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ async function updateDndTimerPage() {
dndTimerList.removeChild(dndTimerList.lastChild);
}
try {
let res = await ApiService.getDnd();
let res = await ApiService.getDndConfiguration();
// TODO: Check if multiple dnd timers can be created!
if (res.length === 0 || res[0].enabled === 0) {
if (res.length === 0 || !(res.enabled) ) {
// no timer is enabled yet, show possibility to add dnd timer
dndTimerList.appendChild(ons.createElement(
"<ons-list-item>\n" +
Expand All @@ -110,24 +110,23 @@ async function updateDndTimerPage() {
"</ons-list-item>"));
} else {
// Show current active timer
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='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 + ");'>" +
" <ons-icon icon='fa-edit'></ons-icon>" +
" </ons-button>" +
" <ons-button modifier='quiet' class='button-margin' style='font-size: 2em;' onclick='deleteDndTimer();'>" +
" <ons-icon icon='fa-trash'></ons-icon>" +
" </ons-button>" +
" </div>" +
"</ons-list-item>"));
});
dndTimerList.appendChild(ons.createElement(
"<ons-list-item>\n" +
" <div class='left'>DND will start at " + res.start.hour + ":" +
asTwoDigitNumber(res.start.minute) + " and end on " +
res.end.hour + ":" + asTwoDigitNumber(res.end.minute) + "</div>" +
" <div class='right'>" +
" <ons-button modifier='quiet' class='button-margin' style='font-size: 2em;' onclick='showDndTimerDialog(" +
res.start.hour + ", " + res.start.minute + ", " +
res.end.hour + ", " + res.end.minute + ");'>" +
" <ons-icon icon='fa-edit'></ons-icon>" +
" </ons-button>" +
" <ons-button modifier='quiet' class='button-margin' style='font-size: 2em;' onclick='deleteDndTimer();'>" +
" <ons-icon icon='fa-trash'></ons-icon>" +
" </ons-button>" +
" </div>" +
"</ons-list-item>"
));
}
} catch (err) {
ons.notification.toast(err.message,
Expand All @@ -143,7 +142,7 @@ async function deleteDndTimer() {
let answer = await ons.notification.confirm("Do you really want to disable DND?");
if (answer === 1) {
loadingBarSettingsTimers.setAttribute("indeterminate", "indeterminate");
await ApiService.deleteDnd();
await ApiService.setDndConfiguration(false, 0, 0, 0, 0);
updateDndTimerPage();
}
} catch (err) {
Expand All @@ -160,9 +159,17 @@ async function saveDndTimer() {
var start_minute = document.getElementById("edit-dnd-form").start_minute.value;
var end_hour = document.getElementById("edit-dnd-form").end_hour.value;
var end_minute = document.getElementById("edit-dnd-form").end_minute.value;

if (start_hour && start_minute && end_hour && end_minute) {
try {
await ApiService.setDnd(start_hour, start_minute, end_hour, end_minute);
await ApiService.setDndConfiguration(
true,
parseInt(start_hour),
parseInt(start_minute),
parseInt(end_hour),
parseInt(end_minute)
);

hideDndTimerDialog();
updateDndTimerPage();
} catch (err) {
Expand Down Expand Up @@ -413,4 +420,4 @@ window.deleteDndTimer = deleteDndTimer;
window.saveDndTimer = saveDndTimer;
window.addNewTimer = addNewTimer;
window.showAddTimerDialog = showAddTimerDialog;
window.hideNewTimerDialog = hideNewTimerDialog;
window.hideNewTimerDialog = hideNewTimerDialog;
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
30 changes: 30 additions & 0 deletions lib/core/capabilities/DoNotDisturbCapability.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const Capability = require("./Capability");
const NotImplementedError = require("../NotImplementedError");

class DoNotDisturbCapability extends Capability {
/**
*
* @abstract
* @returns {Promise<import("../../entities/core/ValetudoDNDConfiguration")>}
*/
async getDndConfiguration() {
throw new NotImplementedError();
}

/**
* @abstract
* @param {import("../../entities/core/ValetudoDNDConfiguration")} dndConfig
* @returns {Promise<void>}
*/
async setDndConfiguration(dndConfig) {
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"),
};
31 changes: 31 additions & 0 deletions lib/entities/core/ValetudoDNDConfiguration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const SerializableEntity = require("../SerializableEntity");


// noinspection JSCheckFunctionSignatures
class ValetudoDNDConfiguration extends SerializableEntity {
/**
* @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
*
* @param {object} [options.metaData]
*
* @class
*/
constructor(options) {
super(options);

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

module.exports = ValetudoDNDConfiguration;
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
45 changes: 45 additions & 0 deletions lib/robots/roborock/capabilities/RoborockDoNotDisturbCapability.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const DoNotDisturbCapability = require("../../../core/capabilities/DoNotDisturbCapability");
const ValetudoDNDConfiguration = require("../../../entities/core/ValetudoDNDConfiguration");

class RoborockDoNotDisturbCapability extends DoNotDisturbCapability {
/**
*
* @abstract
* @returns {Promise<ValetudoDNDConfiguration>}
*/
async getDndConfiguration() {
const res = await this.robot.sendCommand("get_dnd_timer", [], {});

return new ValetudoDNDConfiguration({
enabled: (res[0].enabled === 1),
start: {
hour: res[0].start_hour,
minute: res[0].start_minute
},
end: {
hour: res[0].end_hour,
minute: res[0].end_minute
}
});
}

/**
* @abstract
* @param {ValetudoDNDConfiguration} dndConfig
* @returns {Promise<void>}
*/
async setDndConfiguration(dndConfig) {
if (dndConfig.enabled === true) {
return this.robot.sendCommand("set_dnd_timer", [
dndConfig.start.hour,
dndConfig.start.minute,
dndConfig.end.hour,
dndConfig.end.minute
], {});
} else {
return this.robot.sendCommand("close_dnd_timer", [], {});
}
}
}

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;
30 changes: 30 additions & 0 deletions lib/webserver/capabilityRouters/DoNotDisturbCapabilityRouter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const Logger = require("../../Logger");

const CapabilityRouter = require("./CapabilityRouter");
const ValetudoDNDConfiguration = require("../../entities/core/ValetudoDNDConfiguration");

class DoNotDisturbCapabilityRouter extends CapabilityRouter {

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

this.router.put("/", async (req, res) => {
if (req.body && req.body.start && req.body.end) {
try {
await this.capability.setDndConfiguration(new ValetudoDNDConfiguration(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")
};