// Small helpers for page lambdas (available as el512::... in YAML lambdas). #pragma once #include #include #include #include "esphome/components/display/display.h" namespace esphome::el512 { // Split the "a|b|c;d|e|f" lists made by the Home Assistant package. inline std::vector split(const std::string &s, char sep) { std::vector out; if (s.empty()) return out; size_t start = 0; while (true) { const size_t end = s.find(sep, start); out.push_back(s.substr(start, end == std::string::npos ? std::string::npos : end - start)); if (end == std::string::npos) return out; start = end + 1; } } // Field i of a "|"-separated entry, or "" if missing. inline std::string field(const std::string &entry, size_t i) { const auto parts = split(entry, '|'); return i < parts.size() ? parts[i] : std::string(); } // Material Design Icons glyph (UTF-8) for a Home Assistant weather condition. inline const char *weather_icon(const std::string &c) { if (c == "clear-night") return "\U000F0594"; if (c == "cloudy") return "\U000F0590"; if (c == "fog") return "\U000F0591"; if (c == "hail") return "\U000F0592"; if (c == "lightning") return "\U000F0593"; if (c == "lightning-rainy") return "\U000F067E"; if (c == "partlycloudy") return "\U000F0595"; if (c == "pouring") return "\U000F0596"; if (c == "rainy") return "\U000F0597"; if (c == "snowy") return "\U000F0598"; if (c == "snowy-rainy") return "\U000F067F"; if (c == "sunny") return "\U000F0599"; if (c == "windy") return "\U000F059D"; if (c == "windy-variant") return "\U000F059E"; return "\U000F05D6"; // exceptional / unknown } // Readable weather condition ("partlycloudy" -> "Partly cloudy"). inline std::string weather_text(const std::string &c) { if (c == "clear-night") return "Clear"; if (c == "partlycloudy") return "Partly cloudy"; if (c == "lightning-rainy") return "Thunderstorm"; if (c == "snowy-rainy") return "Sleet"; if (c == "windy-variant") return "Windy"; if (c == "exceptional") return "Exceptional"; if (c.empty()) return ""; std::string s = c; s[0] = (char) toupper(s[0]); return s; } // Cut text with "..." so it fits in max_width pixels in the given font. inline std::string fit(display::BaseFont *font, const std::string &text, int max_width) { int w, x_off, baseline, h; font->measure(text.c_str(), &w, &x_off, &baseline, &h); if (w <= max_width) return text; std::string s = text; while (!s.empty()) { // Drop a whole UTF-8 character. do { s.pop_back(); } while (!s.empty() && (s.back() & 0xC0) == 0x80); const std::string t = s + "..."; font->measure(t.c_str(), &w, &x_off, &baseline, &h); if (w <= max_width) return t; } return "..."; } // 245 -> "4:05", 3725 -> "1:02:05". inline std::string mmss(int seconds) { if (seconds < 0) seconds = 0; char buf[16]; if (seconds >= 3600) snprintf(buf, sizeof(buf), "%d:%02d:%02d", seconds / 3600, seconds / 60 % 60, seconds % 60); else snprintf(buf, sizeof(buf), "%d:%02d", seconds / 60, seconds % 60); return buf; } // 1250 -> "1250 W", 4200 -> "4.20 kW". inline std::string watts(float w) { char buf[16]; if (w >= 1000 || w <= -1000) snprintf(buf, sizeof(buf), "%.2f kW", w / 1000.0f); else snprintf(buf, sizeof(buf), "%.0f W", w); return buf; } } // namespace esphome::el512