diff --git a/data/display.html b/data/display.html
index 2df521c0..1707aeb4 100644
--- a/data/display.html
+++ b/data/display.html
@@ -60,7 +60,9 @@
Display
Red/Yellow shaded: Slot is sticky and locked.
+
+
Currently active fade effect: Linear
@@ -261,10 +263,27 @@ Display
}
}
+ function prevSlot() {
+ var buttonActionIdPrevSlot = 2; /* See ButtonActionId */
+ disableUI();
+
+ return wsClient.triggerButton({"actionId": buttonActionIdPrevSlot}).then(function(rsp) {
+ /* Nothing to do */
+ }).catch(function(err) {
+ if ("undefined" !== typeof err) {
+ console.error(err);
+ }
+ return dialog.showError("Failed.
");
+ }).finally(function() {
+ enableUI();
+ });
+ }
+
function nextSlot() {
+ var buttonActionIdNextSlot = 1; /* See ButtonActionId */
disableUI();
- return wsClient.triggerButton().then(function(rsp) {
+ return wsClient.triggerButton({"actionId": buttonActionIdNextSlot}).then(function(rsp) {
/* Nothing to do */
}).catch(function(err) {
if ("undefined" !== typeof err) {
@@ -276,6 +295,22 @@ Display
});
}
+ function updateDisplay() {
+ disableUI();
+
+ /* Currently off? */
+ if (0 === timerId) {
+ timerId = window.setTimeout(getDisplayContent, period);
+ $("#updateDisplayButton").text("Disable auto. display update");
+ } else {
+ window.clearTimeout(timerId);
+ timerId = 0;
+ $("#updateDisplayButton").text("Enable auto. display update");
+ }
+
+ enableUI();
+ }
+
function move(uid, slotId) {
return wsClient.move({
uid: uid,
@@ -566,9 +601,6 @@ Display
currentFadeEffect = rsp.fadeEffect;
updateFadeEffect();
}).then(function(rsp) {
- /* Request display content periodically. */
- timerId = window.setTimeout(getDisplayContent, period);
-
/* UI is enabled at least. */
enableUI();
}).catch(function(err) {
diff --git a/data/js/ws.js b/data/js/ws.js
index d175ccdd..0ad93201 100644
--- a/data/js/ws.js
+++ b/data/js/ws.js
@@ -557,14 +557,21 @@ pixelix.ws.Client.prototype.stopIperf = function(options) {
}.bind(this));
};
-pixelix.ws.Client.prototype.triggerButton = function() {
+pixelix.ws.Client.prototype.triggerButton = function(options) {
return new Promise(function(resolve, reject) {
+ var par = null;
+
if (null === this._socket) {
reject();
} else {
+
+ if ("number" === typeof options.actionId) {
+ par = options.actionId.toString();
+ }
+
this._sendCmd({
name: "BUTTON",
- par: null,
+ par: par,
resolve: resolve,
reject: reject
});
diff --git a/src/Common/ButtonActions.h b/src/Common/ButtonActions.h
index 71e7efe7..f6857cbe 100644
--- a/src/Common/ButtonActions.h
+++ b/src/Common/ButtonActions.h
@@ -66,7 +66,9 @@ enum ButtonActionId
BUTTON_ACTION_ID_TOGGLE_DISPLAY_OFF_ON, /**< Toggle the display off/on */
BUTTON_ACTION_ID_SWEEP_BRIGHTNESS, /**< Sweep brightness from dark to bright and reverse */
BUTTON_ACTION_ID_INC_BRIGHTNESS, /**< Increase display brightness till maximum. */
- BUTTON_ACTION_ID_DEC_BRIGHTNESS /**< Decrease display brightness till minimum. */
+ BUTTON_ACTION_ID_DEC_BRIGHTNESS, /**< Decrease display brightness till minimum. */
+
+ BUTTON_ACTION_ID_MAX /**< Max. action id (always the last one) */
};
/**
diff --git a/src/Web/RestApi.cpp b/src/Web/RestApi.cpp
index 56505f04..765483ed 100644
--- a/src/Web/RestApi.cpp
+++ b/src/Web/RestApi.cpp
@@ -42,6 +42,7 @@
#include "FileSystem.h"
#include "RestUtil.h"
#include "SlotList.h"
+#include "ButtonActions.h"
#include
#include
@@ -71,6 +72,42 @@ typedef struct
} ContentTypeElem;
+/**
+ * Virtual button which can be triggered via REST API.
+ */
+class RestApiButton : public ButtonActions
+{
+public:
+
+ /**
+ * Construct virtual button instance.
+ */
+ RestApiButton() :
+ ButtonActions()
+ {
+ }
+
+ /**
+ * Destroy virtual button instance.
+ */
+ virtual ~RestApiButton()
+ {
+ }
+
+ /**
+ * Execute action by button action id.
+ *
+ * @param[in] id Button action id
+ */
+ void executeAction(ButtonActionId id)
+ {
+ ButtonActions::executeAction(id);
+ }
+
+private:
+
+};
+
/******************************************************************************
* Prototypes
*****************************************************************************/
@@ -201,10 +238,38 @@ static void handleButton(AsyncWebServerRequest* request)
}
else
{
- DisplayMgr::getInstance().activateNextSlot();
-
- (void)RestUtil::prepareRspSuccess(jsonDoc);
- httpStatusCode = HttpStatus::STATUS_CODE_OK;
+ ButtonActionId actionId = BUTTON_ACTION_ID_ACTIVATE_NEXT_SLOT; /* Default */
+ bool isSuccessful = true;
+
+ if (true == request->hasArg("actionId"))
+ {
+ int32_t i32ActionId = request->arg("actionId").toInt();
+
+ if ((0 > i32ActionId) ||
+ (BUTTON_ACTION_ID_MAX <= i32ActionId))
+ {
+ isSuccessful = false;
+ }
+ else
+ {
+ actionId = static_cast(i32ActionId);
+ }
+ }
+
+ if (false == isSuccessful)
+ {
+ RestUtil::prepareRspError(jsonDoc, "Invalid action id.");
+ httpStatusCode = HttpStatus::STATUS_CODE_METHOD_NOT_ALLOWED;
+ }
+ else
+ {
+ RestApiButton buttonActions;
+
+ buttonActions.executeAction(actionId);
+
+ (void)RestUtil::prepareRspSuccess(jsonDoc);
+ httpStatusCode = HttpStatus::STATUS_CODE_OK;
+ }
}
RestUtil::sendJsonRsp(request, jsonDoc, httpStatusCode);
diff --git a/src/Web/WsCommand/WsCmdButton.cpp b/src/Web/WsCommand/WsCmdButton.cpp
index 1c63b13a..6e1f82b1 100644
--- a/src/Web/WsCommand/WsCmdButton.cpp
+++ b/src/Web/WsCommand/WsCmdButton.cpp
@@ -33,7 +33,7 @@
* Includes
*****************************************************************************/
#include "WsCmdButton.h"
-#include "DisplayMgr.h"
+#include "ButtonActions.h"
#include
@@ -76,7 +76,7 @@ void WsCmdButton::execute(AsyncWebSocket* server, AsyncWebSocketClient* client)
}
else
{
- DisplayMgr::getInstance().activateNextSlot();
+ executeAction(m_actionId);
sendPositiveResponse(server, client);
}
@@ -86,9 +86,16 @@ void WsCmdButton::execute(AsyncWebSocket* server, AsyncWebSocketClient* client)
void WsCmdButton::setPar(const char* par)
{
- UTIL_NOT_USED(par);
+ uint8_t actionId;
- m_isError = true;
+ if (false == Util::strToUInt8(par, actionId))
+ {
+ m_isError = true;
+ }
+ else
+ {
+ m_actionId = static_cast(actionId);
+ }
}
/******************************************************************************
diff --git a/src/Web/WsCommand/WsCmdButton.h b/src/Web/WsCommand/WsCmdButton.h
index cb9c0d29..cade8191 100644
--- a/src/Web/WsCommand/WsCmdButton.h
+++ b/src/Web/WsCommand/WsCmdButton.h
@@ -44,6 +44,7 @@
* Includes
*****************************************************************************/
#include "WsCmd.h"
+#include "ButtonActions.h"
/******************************************************************************
* Macros
@@ -56,7 +57,7 @@
/**
* Websocket command to control the virtual user button.
*/
-class WsCmdButton: public WsCmd
+class WsCmdButton: public WsCmd, public ButtonActions
{
public:
@@ -65,7 +66,9 @@ class WsCmdButton: public WsCmd
*/
WsCmdButton() :
WsCmd("BUTTON"),
- m_isError(false)
+ ButtonActions(),
+ m_isError(false),
+ m_actionId(BUTTON_ACTION_ID_ACTIVATE_NEXT_SLOT) /* Default */
{
}
@@ -93,7 +96,8 @@ class WsCmdButton: public WsCmd
private:
- bool m_isError; /**< Any error happened during parameter reception? */
+ bool m_isError; /**< Any error happened during parameter reception? */
+ ButtonActionId m_actionId; /**< Id of the action, which to execute. */
WsCmdButton(const WsCmdButton& cmd);
WsCmdButton& operator=(const WsCmdButton& cmd);