Skip to content

Commit

Permalink
Release 2.3.0
Browse files Browse the repository at this point in the history
Being the last release of the year, I hope everyone stay safe.
In the next few weeks I'm gonna update and stay working inside the wiki of the module.
Until then, you can see the Readme, the issues already closed, or ask a question yourself inside Issues.
Keep programming :D

Custom Shell Commands

You can use it with the endpoint in the api, and adding those commands inside the customCommand object in the config of Remote Control.  This still  an insecure way of implement this feature, so in the next update the remote endpoint will be deprecated. Try to use the API endpoints instead. Cheers! Jopyth#159

Secure the remote endpoint

Deprecation soon

Custom Menus: User Input Field (Jopyth#181) and Sliders

Soon I'll make the Wiki adding this changes and how you can use them. You also can add a text input to execute commands, so it's also useful for Jopyth#159

Closes Jopyth#181

Monitor System changed

Fixes Jopyth#234

Monitor System fix

Closes Jopyth#234 with a lot of help ;D

Payload Integer

Need more tests into this, but seems to work as expected.

Fixes Jopyth#155

Revert "Payload Integer"

This reverts commit a648bc5.

Better Template 2

Those templates are working as expected. I'll add the warning about invalid issues, and remove blank issues.

Future issues that doesn't have the appropiate template will be discarted. Sorry to those good ideas, but you'll have to think better what you're reporting.
  • Loading branch information
ezeholz committed Dec 23, 2020
1 parent c34665e commit f01c486
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 11 deletions.
2 changes: 2 additions & 0 deletions .github/ISSUE_TEMPLATE/Feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ assignees: ''
So you have a nice feature you want in the module? Nice! Feel free to let us know.
Please, make sure that your feature it's not in the PRs waiting to merge, or inside the develop branch.
Also, you accept that, if this issue it's invalid in any way, will be discarded without receiving any response about it.
You can now erase this warning, and complete the steps below. Cheers :D
-->

Expand Down
2 changes: 2 additions & 0 deletions .github/ISSUE_TEMPLATE/Question.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ assignees: ''
Keep in mind that poorly formulated questions could lead to your question never answer, and the issue closed.
Feel free to explain the problem you're having, and the community will help you.
Also, you accept that, if this issue it's invalid in any way, will be discarded without receiving any response about it.
You can now erase this warning, and complete the steps below. Cheers :D
-->

Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
blank_issues_enabled: false
2 changes: 2 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE/Feature_addition.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ So you have a nice feature you want in the module? Nice! Feel free to let us kno
Please, make sure that your feature it's not inside the develop branch already.
Please commit your contribution into the develop branch. Will be change if you don't do it.
Also, you accept that, if this Pull Request it's invalid in any way, will be discarded without receiving any response about it.
You can now erase this warning, and complete the steps below. Cheers :D
-->

Expand Down
7 changes: 7 additions & 0 deletions API/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ module.exports = {
res.status(400).json({ success: false, message: `Invalid value ${val} provided in request. Use /api/classes to see actual values` });
}
});

this.expressRouter.route('/command/:value')
.get((req, res) => {
if(!this.apiKey && this.secureEndpoints) return res.status(403).json({ success: false, message: "Forbidden: API Key Not Provided in Config! Use secureEndpoints to bypass this message" });
const val = decodeURIComponent(req.params.value)
self.executeQuery({ action: "COMMAND", command: req.params.value }, res);
});

this.expressRouter.route('/userpresence/:value?')
.get((req, res) => {
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [2.3.0] - 2020-12-23

### Added
- Custom Shell Commands for everyone! (#159)
- Custom Menus: User Input Field (#181) and Sliders

### Fixed
- "TV is off" now detected (#234)
- Toggle and Status Monitor working as expected (#234)

### Changed
- Now the system used for turn on and off the screen will be `vcgencmd` (#227 and more)

## [2.2.2] - 2020-11-24

### Fixed
Expand Down
53 changes: 52 additions & 1 deletion docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"name": "MIT License",
"url": "https://github.com/Jopyth/MMM-Remote-Control/blob/master/LICENSE"
},
"version": "2.2.0+"
"version": "2.3.0+"
},
"externalDocs": {
"url": "https://github.com/Jopyth/MMM-Remote-Control/issues",
Expand Down Expand Up @@ -152,6 +152,57 @@
}
}
},
"/api/command/{:value}": {
"get": {
"tags": [
"Mirror Control",
"API"
],
"summary": "Execute command saved in config",
"parameters": [
{
"name": ":value",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"security": [
{
"apikey": []
}
],
"responses": {
"200": {
"description": ""
},
"400": {
"description": "",
"content": {
"application/json": {
"example": {
"success": false,
"message": "Value is needed"
}
}
}
},
"403": {
"description": "",
"content": {
"application/json": {
"example": {
"success": false,
"message": "Forbidden: API Key Not Provided in Config! Use secureEndpoints to bypass this message"
}
}
}
}
}
}
},
"/api/config": {
"get": {
"tags": [
Expand Down
26 changes: 18 additions & 8 deletions node_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ module.exports = NodeHelper.create(Object.assign({
this.expressApp.get("/remote", function(req, res) {
var query = url.parse(req.url, true).query;

if (query.action) {
if (query.action && ["COMMAND"].indexOf(query.action)===-1) {
var result = self.executeQuery(query, res);
if (result === true) {
return;
Expand Down Expand Up @@ -633,25 +633,25 @@ module.exports = NodeHelper.create(Object.assign({

monitorControl: function(action, opts, res) {
let status = "unknown";
let offArr = ["false","TV is Off","standby"];
let offArr = ["false","TV is off","standby","display_power=0"];
let monitorOnCommand = (this.initialized && "monitorOnCommand" in this.thisConfig.customCommand) ?
this.thisConfig.customCommand.monitorOnCommand :
"tvservice --preferred && sudo chvt 6 && sudo chvt 7";
"vcgencmd display_power 1";
let monitorOffCommand = (this.initialized && "monitorOffCommand" in this.thisConfig.customCommand) ?
this.thisConfig.customCommand.monitorOffCommand :
"tvservice -o";
"vcgencmd display_power 0";
let monitorStatusCommand = (this.initialized && "monitorStatusCommand" in this.thisConfig.customCommand) ?
this.thisConfig.customCommand.monitorStatusCommand :
"tvservice --status";
"vcgencmd display_power -1";
switch (action) {
case "MONITORSTATUS": exec(monitorStatusCommand, opts, (error, stdout, stderr) => {
status = offArr.indexOf(stdout) !== -1 ? "off" : "on";
status = offArr.indexOf(stdout.trim()) !== -1 ? "off" : "on";
this.checkForExecError(error, stdout, stderr, res, { monitor: status });
return;
});
break;
case "MONITORTOGGLE": exec(monitorStatusCommand, opts, (error, stdout, stderr) => {
status = offArr.indexOf(stdout) !== -1 ? "off" : "on";
status = offArr.indexOf(stdout.trim()) !== -1 ? "off" : "on";
if(status === "on") this.monitorControl("MONITOROFF", opts, res);
else this.monitorControl("MONITORON", opts, res);
return;
Expand Down Expand Up @@ -697,6 +697,16 @@ module.exports = NodeHelper.create(Object.assign({
this.controlPm2(res, query);
return true;
}
if (query.action === "COMMAND") {
if (this.thisConfig.customCommand && this.thisConfig.customCommand[query.command]) {
exec(this.thisConfig.customCommand[query.command], opts, (error, stdout, stderr) => {
self.checkForExecError(error, stdout, stderr, res, { stdout: stdout });
});
} else {
self.sendResponse(res, new Error("Command not found"), query);
}
return true;
}
if (query.action === "USER_PRESENCE") {
this.sendSocketNotification("USER_PRESENCE", query.value);
this.userPresence = query.value;
Expand Down Expand Up @@ -924,7 +934,7 @@ module.exports = NodeHelper.create(Object.assign({
},

checkForExecError: function(error, stdout, stderr, res, data) {
console.log(stderr);
if(error) console.log(stderr);
this.sendResponse(res, error, data);
},

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Magic-Mirror-Module-Remote-Control",
"version": "2.2.0",
"version": "2.3.0",
"description": "This module for the Magic Mirror allows you to shutdown and configure your mirror through a web browser.",
"repository": {
"type": "git",
Expand Down
29 changes: 28 additions & 1 deletion remote.js
Original file line number Diff line number Diff line change
Expand Up @@ -1504,15 +1504,42 @@ var Remote = {
$item = $("<div>").attr("id", `${content.id}-button`).addClass(`menu-element button ${menu}-menu`);
let $mcmIcon = $('<span>').addClass(`fa fa-fw fa-${content.icon}`).attr("aria-hidden", "true");
let $mcmText = $('<span>').addClass('text').text(content.text);
$item.append($mcmIcon).append($mcmText);
if (content.icon) $item.append($mcmIcon)
if (content.type === "menu") {
if (content.text) $item.append($mcmText);
let $mcmArrow = $('<span>').addClass('fa fa-fw fa-angle-right').attr("aria-hidden", "true");
$item.append($mcmArrow);
$item.attr("data-parent", menu).attr("data-type", "menu");
$('#back-button').addClass(`${content.id}-menu`);
$('#below-fold').addClass(`${content.id}-menu`);
$item.click(() => { window.location.hash = `${content.id}-menu`; });
} else if (content.type === "slider") {
if (content.text) $item.append($mcmText.attr("style", "flex: 0 1 auto"));
let $contain = $('<div>').attr("style", "flex: 1")
let $slide = $('<input>').attr("id", `${content.id}-slider`).addClass("slider")
$slide.attr({
"type": "range",
"min": content.min || 0,
"max": content.max || 100,
"step": content.step || 10,
"value": content.defaultValue || 50
})
$slide.change(() => {
this.sendSocketNotification("REMOTE_ACTION", Object.assign({ action: content.action.toUpperCase() }, { payload:{} }, content.content, { value: document.getElementById(`${content.id}-slider`).value }));
})
$contain.append($slide);
$item.append($contain)
} else if (content.type === "input") {
$item = $("<input>").addClass(`menu-element ${menu}-menu medium`).attr({
"id": `${content.id}-input`,
"type": "text",
"placeholder": content.text || ""
});
$item.focusout(() => {
this.sendSocketNotification("REMOTE_ACTION", Object.assign({ action: content.action.toUpperCase() }, { payload:{} }, content.content, { value: document.getElementById(`${content.id}-input`).value }));
})
} else if (content.action && content.content) {
if (content.text) $item.append($mcmText);
$item.attr("data-type", "item");
// let payload = content.content.payload || {};
$item.click(() => {
Expand Down

0 comments on commit f01c486

Please sign in to comment.