From 22e41e4203c3b18515bff7f835f70bf77b354511 Mon Sep 17 00:00:00 2001 From: ESPHome Device Builder Date: Tue, 9 Jun 2026 23:15:27 +1200 Subject: [PATCH] Edit esp-ledmatrix1.yaml --- esphome/esp-ledmatrix1.yaml | 97 ++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/esphome/esp-ledmatrix1.yaml b/esphome/esp-ledmatrix1.yaml index 1b42699..aa0db1c 100644 --- a/esphome/esp-ledmatrix1.yaml +++ b/esphome/esp-ledmatrix1.yaml @@ -13,6 +13,8 @@ # https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-ledmatrix1.yaml #:########################################################################################:# # VERSIONS: +# V1.16 2026-06-04 Added leading /s token support for intentional display spaces in scroll and announce text. +# V1.15 2026-06-04 Preserved visible leading spaces in long static transition messages using a pixel offset. # V1.14 2026-06-04 Added per-announcement static wait and stored sound_id parameter. # V1.13 2026-06-04 Fixed remaining leading-space stripping in static transitions and MQTT announce parsing. # V1.12 2026-06-04 Preserved leading spaces in scroll/static/announcement text for layout control. @@ -70,6 +72,7 @@ # - The text box clears itself after a valid scroll request is accepted. # - Empty scroll requests are ignored and do not replay the previous message. # - Leading spaces in scroll/static/announcement text are preserved for manual layout control. +# - Leading /s tokens are converted to display spaces, so /s/sHello becomes two leading spaces. # - Long static transition messages use leading spaces as a pixel offset before the text. # - Scroll Delay controls the default delay in milliseconds between scroll steps. # - Static Wait Time controls how long static notifications hold before scrolling/returning. @@ -159,7 +162,7 @@ substitutions: # Project Naming project_name: "Generic.ESP32 Supermini" - project_version: "v1.15a" + project_version: "v1.16" # Passwords & Secrets api_key: !secret esp-api_key @@ -636,6 +639,29 @@ text: s.erase(std::remove_if(s.begin(), s.end(), [](unsigned char c){ return c < 0x20; }), s.end()); + auto expand_leading_space_tokens = [](std::string &s) { + int spaces_to_add = 0; + size_t pos = 0; + + // Convert leading /s tokens into real display spaces. + // Supports /sHello, /s/sHello, and /s/s/s/Hello. + while ((pos + 1) < s.length() && s[pos] == '/' && s[pos + 1] == 's') { + spaces_to_add += 1; + pos += 2; + } + + // Allow one optional separator slash after a run of /s tokens. + if (spaces_to_add > 0 && pos < s.length() && s[pos] == '/') { + pos += 1; + } + + if (spaces_to_add > 0) { + s = std::string(spaces_to_add, ' ') + s.substr(pos); + } + }; + + expand_leading_space_tokens(s); + // Publish the cleaned text so the HA UI updates immediately. id(ha_scroll_text).publish_state(s.c_str()); @@ -1635,6 +1661,29 @@ api: s.erase(std::remove_if(s.begin(), s.end(), [](unsigned char c){ return c < 0x20; }), s.end()); + auto expand_leading_space_tokens = [](std::string &s) { + int spaces_to_add = 0; + size_t pos = 0; + + // Convert leading /s tokens into real display spaces. + // Supports /sHello, /s/sHello, and /s/s/s/Hello. + while ((pos + 1) < s.length() && s[pos] == '/' && s[pos + 1] == 's') { + spaces_to_add += 1; + pos += 2; + } + + // Allow one optional separator slash after a run of /s tokens. + if (spaces_to_add > 0 && pos < s.length() && s[pos] == '/') { + pos += 1; + } + + if (spaces_to_add > 0) { + s = std::string(spaces_to_add, ' ') + s.substr(pos); + } + }; + + expand_leading_space_tokens(s); + // Ignore empty API scroll commands completely. if (s.empty()) return; @@ -1676,6 +1725,29 @@ mqtt: s.erase(std::remove_if(s.begin(), s.end(), [](unsigned char c){ return c < 0x20; }), s.end()); + auto expand_leading_space_tokens = [](std::string &s) { + int spaces_to_add = 0; + size_t pos = 0; + + // Convert leading /s tokens into real display spaces. + // Supports /sHello, /s/sHello, and /s/s/s/Hello. + while ((pos + 1) < s.length() && s[pos] == '/' && s[pos + 1] == 's') { + spaces_to_add += 1; + pos += 2; + } + + // Allow one optional separator slash after a run of /s tokens. + if (spaces_to_add > 0 && pos < s.length() && s[pos] == '/') { + pos += 1; + } + + if (spaces_to_add > 0) { + s = std::string(spaces_to_add, ' ') + s.substr(pos); + } + }; + + expand_leading_space_tokens(s); + // Ignore empty MQTT scroll commands completely. if (s.empty()) return; @@ -1728,6 +1800,29 @@ mqtt: message.erase(std::find_if(message.rbegin(), message.rend(), [](unsigned char ch){ return !std::isspace(ch); }).base(), message.end()); + auto expand_leading_space_tokens = [](std::string &s) { + int spaces_to_add = 0; + size_t pos = 0; + + // Convert leading /s tokens into real display spaces. + // Supports /sHello, /s/sHello, and /s/s/s/Hello. + while ((pos + 1) < s.length() && s[pos] == '/' && s[pos + 1] == 's') { + spaces_to_add += 1; + pos += 2; + } + + // Allow one optional separator slash after a run of /s tokens. + if (spaces_to_add > 0 && pos < s.length() && s[pos] == '/') { + pos += 1; + } + + if (spaces_to_add > 0) { + s = std::string(spaces_to_add, ' ') + s.substr(pos); + } + }; + + expand_leading_space_tokens(message); + trim(vars); if (message.empty() || vars.empty()) {