From 30922ca93c70aeb188d1f65728447c304007ef45 Mon Sep 17 00:00:00 2001 From: nedko Date: Tue, 30 Jun 2026 16:40:10 +0300 Subject: [PATCH] Added functionality to align display refreshes --- TRMNL.cpp | 74 +++++++++++++++++++++++++++++++++++++++++++- TRMNL.h | 16 +++++++++- config_example.json | 5 ++- devices_example.json | 3 +- main.cpp | 10 ++++-- 5 files changed, 102 insertions(+), 6 deletions(-) diff --git a/TRMNL.cpp b/TRMNL.cpp index a6b2386..52c8f9b 100644 --- a/TRMNL.cpp +++ b/TRMNL.cpp @@ -1,6 +1,8 @@ #include "TRMNL.h" #include "helpers.h" +#include + using std::list; using std::map; using std::optional; @@ -11,11 +13,13 @@ using nlohmann::json; TRMNL::TRMNL(const string& id, const string& api_key, const string& friendly_id, - int refresh_rate) + int refresh_rate, + bool is_refresh_aligned) : m_id(id), m_api_key(api_key), m_friendly_id(friendly_id), m_refresh_rate(refresh_rate), +m_is_refresh_aligned(is_refresh_aligned), m_update_handler() {} @@ -52,6 +56,65 @@ int TRMNL::refresh_rate() const return m_refresh_rate; } +bool TRMNL::is_refresh_aligned() const +{ + return m_is_refresh_aligned; +} + +int TRMNL::get_next_refresh(int min_time, int offset) const +{ + if (!m_is_refresh_aligned) + { + return m_refresh_rate; + } + + if (min_time > m_refresh_rate) + { + min_time = m_refresh_rate; + } + + int result = 0; + time_t curr = time(nullptr); + struct tm* now = localtime(&curr); + + int tmp_refresh = m_refresh_rate; + bool align_minutes = false; + bool align_hours = false; + + if (0 == m_refresh_rate % 60) + { + align_minutes = true; + tmp_refresh /= 60; + + if (0 == tmp_refresh % 60) + { + align_hours = true; + tmp_refresh /= 60; + } + } + + if (align_minutes) + { + now->tm_sec = 0; + now->tm_min += 1; + } + + if (align_hours) + { + now->tm_min = 0; + now->tm_hour += 1; + } + + time_t next = mktime(now); + result = next - curr + offset; + while (result < min_time) + { + result += m_refresh_rate; + } + + return result; +} + void TRMNL::id(const std::string& id) { m_id = id; @@ -88,6 +151,15 @@ void TRMNL::refresh_rate(int refresh_rate) } } +void TRMNL::is_refresh_aligned(bool to_align) +{ + m_is_refresh_aligned = to_align; + if (m_update_handler) + { + m_update_handler(*this); + } +} + void TRMNL::set_update_handler(std::function handler) { m_update_handler = handler; diff --git a/TRMNL.h b/TRMNL.h index 3618eea..020244b 100644 --- a/TRMNL.h +++ b/TRMNL.h @@ -18,6 +18,7 @@ private: std::string m_api_key; std::string m_friendly_id; int m_refresh_rate; + bool m_is_refresh_aligned; std::function m_update_handler; @@ -26,7 +27,8 @@ public: TRMNL(const std::string& id = "", const std::string& api_key = "", const std::string& friendly_id = "", - int refresh_rate = DEFAULT_REFRESH_RATE); + int refresh_rate = DEFAULT_REFRESH_RATE, + bool is_refresh_aligned = true); TRMNL(const nlohmann::json& j); @@ -35,12 +37,24 @@ public: const std::string& api_key() const; const std::string& friendly_id() const; int refresh_rate() const; + bool is_refresh_aligned() const; + + // Uses the current time to return when next this device should refresh + // min_time + // - if calculated time is lower than this - increase by refresh rate until higher + // - Capped to the refresh rate + // offset + // - offset to apply to the refresh rate + // - Capped to the refresh rate + // - useful when generating images via cron and you want the refresh to happen a few seconds later + int get_next_refresh(int min_time = 0, int offset = 0) const; // Setters void id(const std::string& id); void api_key(const std::string& api_key); void friendly_id(const std::string& friendly_id); void refresh_rate(int refresh_rate); + void is_refresh_aligned(bool to_align); void set_update_handler(std::function handler); diff --git a/config_example.json b/config_example.json index e7a4304..b89a298 100644 --- a/config_example.json +++ b/config_example.json @@ -8,5 +8,8 @@ "devices_filename": "devices.json", "folder_images": "images", "cert_file": "path/to/file", - "key_file": "path/to/file" + "key_file": "path/to/file", + + "refresh_min": 60, + "refresh_offset": 15 } diff --git a/devices_example.json b/devices_example.json index 6231228..3d8a4b5 100644 --- a/devices_example.json +++ b/devices_example.json @@ -6,6 +6,7 @@ // Auto managed "api_key": "api key", "friendly_id": "917F0B", - "refresh_rate": 600 + "refresh_rate": 300, + "refresh_aligned": true } ] \ No newline at end of file diff --git a/main.cpp b/main.cpp index b9b43aa..1829b25 100644 --- a/main.cpp +++ b/main.cpp @@ -190,6 +190,9 @@ int main(int argc, char **argv) string cert_file = ""; string key_file = ""; + int refresh_min = 60; + int refresh_offset = 15; + shared_ptr server = nullptr; bool ok; @@ -219,6 +222,9 @@ int main(int argc, char **argv) // json_extract(cfg, "cert_file", cert_file); // json_extract(cfg, "key_file", cert_file); + json_extract(cfg, "refresh_min", refresh_min); + json_extract(cfg, "refresh_offset", refresh_offset); + if (host.empty()) { cout << "host not provided" << endl; @@ -335,7 +341,7 @@ int main(int argc, char **argv) } }; - auto display_handler = [&container, &devices_filename, &folder_images, &base_url] + auto display_handler = [&container, &devices_filename, &folder_images, &base_url, refresh_min, refresh_offset] (const httplib::Request& req, httplib::Response& res) { json response; @@ -411,7 +417,7 @@ int main(int argc, char **argv) response["filename"] = image_timestamp; } - response["refresh_rate"] = to_string(trmnl->refresh_rate()); + response["refresh_rate"] = to_string(trmnl->get_next_refresh(refresh_min, refresh_offset)); // TODO: Handle firmware updating response["update_firmware"] = false;