From 9f2848df44f6bd4173482e2be8f25ab7079d4e61 Mon Sep 17 00:00:00 2001 From: ejalal Date: Tue, 19 Sep 2023 19:31:24 +0200 Subject: [PATCH 1/4] implement deep sleep --- src/MQTTManager.cpp | 21 ++++++++++++++++++++ src/PowerManager.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++ src/PowerManager.h | 18 +++++++++++++++++ src/ServerManager.cpp | 8 ++++++++ 4 files changed, 92 insertions(+) create mode 100644 src/PowerManager.cpp create mode 100644 src/PowerManager.h diff --git a/src/MQTTManager.cpp b/src/MQTTManager.cpp index 46050f2a..e2494fa2 100644 --- a/src/MQTTManager.cpp +++ b/src/MQTTManager.cpp @@ -8,6 +8,7 @@ #include "Dictionary.h" #include "PeripheryManager.h" #include "UpdateManager.h" +#include "PowerManager.h" WiFiClient espClient; HADevice device; @@ -283,6 +284,25 @@ void onMqttMessage(const char *topic, const uint8_t *payload, uint16_t length) return; } + if (strTopic.equals(MQTT_PREFIX + "/sleep")) + { + StaticJsonDocument<128> doc; + DeserializationError error = deserializeJson(doc, payload); + if (error) + { + if (DEBUG_MODE) + DEBUG_PRINTLN(F("Failed to parse json")); + return; + } + if (doc.containsKey("sleep")) + { + PowerManager.sleep(doc["sleep"].as()); + } + + delete[] payloadCopy; + return; + } + if (strTopic.equals(MQTT_PREFIX + "/indicator1")) { DisplayManager.indicatorParser(1, payloadCopy); @@ -360,6 +380,7 @@ void onMqttConnected() "/nextapp", "/apps", "/power", + "/sleep", "/indicator1", "/indicator2", "/indicator3", diff --git a/src/PowerManager.cpp b/src/PowerManager.cpp new file mode 100644 index 00000000..85210406 --- /dev/null +++ b/src/PowerManager.cpp @@ -0,0 +1,45 @@ +#include +#include +#include "Globals.h" + +#define uS_TO_S_FACTOR 1000000 + +// The getter for the instantiated singleton instance +PowerManager_ &PowerManager_::getInstance() +{ + static PowerManager_ instance; + return instance; +} + +// Initialize the global shared instance +PowerManager_ &PowerManager = PowerManager.getInstance(); + +void PowerManager_::setup() +{ + +} + +void PowerManager_::sleepParser(const char *json) +{ + StaticJsonDocument<128> doc; + DeserializationError error = deserializeJson(doc, json); + if (error) + { + if (DEBUG_MODE) + DEBUG_PRINTLN(F("Failed to parse json")); + return; + } + + if (doc.containsKey("sleep")) + { + uint32_t seconds = doc["sleep"].as(); + sleep(seconds); + } +} + +void PowerManager_::sleep(uint32_t seconds) +{ + esp_sleep_enable_timer_wakeup(seconds * uS_TO_S_FACTOR); + Serial.print("Going to sleep...\n"); + esp_deep_sleep_start(); +} \ No newline at end of file diff --git a/src/PowerManager.h b/src/PowerManager.h new file mode 100644 index 00000000..52bd0d83 --- /dev/null +++ b/src/PowerManager.h @@ -0,0 +1,18 @@ +#ifndef PowerManager_h +#define PowerManager_h + +#include + +class PowerManager_ +{ +private: + PowerManager_() = default; +public: + static PowerManager_ &getInstance(); + void setup(); + void sleepParser(const char*); + void sleep(uint32_t); +}; + +extern PowerManager_ &PowerManager; +#endif diff --git a/src/ServerManager.cpp b/src/ServerManager.cpp index 108bf34c..c4780b59 100644 --- a/src/ServerManager.cpp +++ b/src/ServerManager.cpp @@ -10,6 +10,7 @@ #include "DisplayManager.h" #include "UpdateManager.h" #include "PeripheryManager.h" +#include "PowerManager.h" #include WiFiUDP udp; @@ -46,6 +47,13 @@ void addHandler() { mws.addHandler("/api/power", HTTP_POST, []() { DisplayManager.powerStateParse(mws.webserver->arg("plain").c_str()); mws.webserver->send(200,F("text/plain"),F("OK")); }); + mws.addHandler( + "/api/sleep", HTTP_POST, []() + { + mws.webserver->send(200,F("text/plain"),F("OK")); + DisplayManager.setPower(false); + PowerManager.sleepParser(mws.webserver->arg("plain").c_str()); + }); mws.addHandler("/api/loop", HTTP_GET, []() { mws.webserver->send_P(200, "application/json", DisplayManager.getAppsAsJson().c_str()); }); mws.addHandler("/api/effects", HTTP_GET, []() From 6d41ee7cadc3b7a07e849b5ee459c256a09cc789 Mon Sep 17 00:00:00 2001 From: ejalal Date: Tue, 19 Sep 2023 19:55:29 +0200 Subject: [PATCH 2/4] forgot mqtt part --- src/MQTTManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/MQTTManager.cpp b/src/MQTTManager.cpp index e2494fa2..e8533137 100644 --- a/src/MQTTManager.cpp +++ b/src/MQTTManager.cpp @@ -296,6 +296,7 @@ void onMqttMessage(const char *topic, const uint8_t *payload, uint16_t length) } if (doc.containsKey("sleep")) { + DisplayManager.setPower(false); PowerManager.sleep(doc["sleep"].as()); } From 33a9004e195afe76c8368d7dce89ff77649323bf Mon Sep 17 00:00:00 2001 From: ejalal Date: Tue, 19 Sep 2023 20:08:58 +0200 Subject: [PATCH 3/4] forgot documentation too --- docs/api.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/api.md b/docs/api.md index 0a06cba9..1d34f21d 100644 --- a/docs/api.md +++ b/docs/api.md @@ -40,6 +40,11 @@ Toggle the matrix on or off: | ---------------- | ----------------------------- | ------------------------- | ----------- | | `[PREFIX]/power` | `http://[IP]/api/power` | `{"power": true}` or `{"power": false}` | POST | +Send the board in deep sleep mode (turns off the matrix as well), good for saving battery life: + +| MQTT Topic | HTTP URL | Payload/Body | HTTP Method | +| ---------------- | ----------------------------- | ------------------------- | ----------- | +| `[PREFIX]/sleep` | `http://[IP]/api/sleep` | `{"sleep": X}` where X is number of seconds | POST | ## Sound Playback From d87b2524cdd3e5093b79892c69fc66edc0ea130d Mon Sep 17 00:00:00 2001 From: ejalal Date: Sat, 23 Sep 2023 18:42:19 +0200 Subject: [PATCH 4/4] revolve issue where sleep max duration was limited (71 minutes !!) by uint32 type --- src/MQTTManager.cpp | 2 +- src/PowerManager.cpp | 6 +++--- src/PowerManager.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/MQTTManager.cpp b/src/MQTTManager.cpp index e8533137..86d5e9dd 100644 --- a/src/MQTTManager.cpp +++ b/src/MQTTManager.cpp @@ -297,7 +297,7 @@ void onMqttMessage(const char *topic, const uint8_t *payload, uint16_t length) if (doc.containsKey("sleep")) { DisplayManager.setPower(false); - PowerManager.sleep(doc["sleep"].as()); + PowerManager.sleep(doc["sleep"].as()); } delete[] payloadCopy; diff --git a/src/PowerManager.cpp b/src/PowerManager.cpp index 85210406..867a86f2 100644 --- a/src/PowerManager.cpp +++ b/src/PowerManager.cpp @@ -2,7 +2,7 @@ #include #include "Globals.h" -#define uS_TO_S_FACTOR 1000000 +#define uS_TO_S_FACTOR 1000000L // The getter for the instantiated singleton instance PowerManager_ &PowerManager_::getInstance() @@ -32,12 +32,12 @@ void PowerManager_::sleepParser(const char *json) if (doc.containsKey("sleep")) { - uint32_t seconds = doc["sleep"].as(); + uint64_t seconds = doc["sleep"].as(); sleep(seconds); } } -void PowerManager_::sleep(uint32_t seconds) +void PowerManager_::sleep(uint64_t seconds) { esp_sleep_enable_timer_wakeup(seconds * uS_TO_S_FACTOR); Serial.print("Going to sleep...\n"); diff --git a/src/PowerManager.h b/src/PowerManager.h index 52bd0d83..b9f9979c 100644 --- a/src/PowerManager.h +++ b/src/PowerManager.h @@ -11,7 +11,7 @@ class PowerManager_ static PowerManager_ &getInstance(); void setup(); void sleepParser(const char*); - void sleep(uint32_t); + void sleep(uint64_t); }; extern PowerManager_ &PowerManager;