Public Access
Add ESPHome display component; ring-buffer driver shared with PlatformIO
Driver (components/el512/el512_panel.*, ESP-IDF only): - DMA ring of 8 x 4 lines (17 KB) refilled from the I2S EOF interrupt (IRAM) instead of a 142 KB full-frame stream; ~107 KB heap freed. - 256-entry lookup table encodes 8 pixels per step. - Back buffer + displayed buffer, swapped at the start of a frame. - PlatformIO builds it via lib_extra_dirs (EL512Core); lib/EL512 keeps the Adafruit GFX front end. ESPHome external component (platform: el512): - DisplayBuffer with optional ENABLE / _LOWPWR pins, set_enabled(), set_low_power(), helper functions for page lambdas. - still_alive_page: plays the Portal end-credits show, then returns to the previous page. Still Alive engine moved to components/el512/still_alive.* with a built-in 5x7 font (from Adafruit GFX, BSD); the PlatformIO demo uses the same code. The importer writes components/el512/still_alive_data.h and stops at 200 s (--until-ms), matching the hand-trimmed data. esphome/el512-panel.yaml: 8 pages (clock, forecast, agenda, dashboard, now playing, Plex, solar, Still Alive), page select, rotation, display and low-power switches, message text. home_assistant/packages/el512_panel.yaml: helper template sensors for forecast, agenda, now playing and Plex streams. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
410885de24
commit
963590cdfe
27 files changed
+2110
-828
No files matched your search
@@ -3,14 +3,15 @@
|
||||
|
||||
Reads index.html and res/stillalive.js from
|
||||
https://github.com/SDSkyKlouD/still-alive-web (downloaded, or local copies) and
|
||||
writes src/still_alive/imported.h, which the firmware uses instead of the
|
||||
placeholder lyrics.h / art.h / credits.h when it exists.
|
||||
writes components/el512/still_alive_data.h, the content of the Still Alive show
|
||||
(components/el512/still_alive.cpp) used by both the PlatformIO demo and ESPHome.
|
||||
|
||||
python tools/import_still_alive.py # download from GitHub
|
||||
python tools/import_still_alive.py --html index.html --js stillalive.js
|
||||
python tools/import_still_alive.py --out somewhere/imported.h
|
||||
python tools/import_still_alive.py --out somewhere/still_alive_data.h
|
||||
python tools/import_still_alive.py --until-ms 0 # keep the web version's outro too
|
||||
|
||||
imported.h is committed with a disclaimer and source reference at its top.
|
||||
still_alive_data.h is committed with a disclaimer and source reference at its top.
|
||||
|
||||
Source format: each <div class="container_lyrics" data-start=ms> is one screen
|
||||
(the console clears when it starts). Inside it, <span data-start data-dur
|
||||
@@ -28,7 +29,11 @@ import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
SOURCE_BASE = "https://raw.githubusercontent.com/SDSkyKlouD/still-alive-web/master/"
|
||||
OUT = Path(__file__).resolve().parent.parent / "src" / "still_alive" / "imported.h"
|
||||
OUT = Path(__file__).resolve().parent.parent / "components" / "el512" / "still_alive_data.h"
|
||||
|
||||
# The show ends after the "... are property of their respective owners." line;
|
||||
# the web version's outro after it ("... is anyone there?") is left out.
|
||||
UNTIL_MS = 200000
|
||||
|
||||
# Timing from stillalive.js.
|
||||
SONG_START_MS = 6750
|
||||
@@ -146,12 +151,16 @@ def main():
|
||||
ap.add_argument("--html", help="local index.html (default: download)")
|
||||
ap.add_argument("--js", help="local res/stillalive.js (default: download)")
|
||||
ap.add_argument("--out", type=Path, default=OUT, help="output file (default: %(default)s)")
|
||||
ap.add_argument("--until-ms", type=int, default=UNTIL_MS,
|
||||
help="drop steps starting at or after this time, 0 = keep all (default: %(default)s)")
|
||||
args = ap.parse_args()
|
||||
|
||||
page = load(args.html, "index.html")
|
||||
arts = parse_art(page)
|
||||
art_ids = {name: i + 1 for i, name in enumerate(arts)}
|
||||
steps = parse_steps(page, art_ids)
|
||||
if args.until_ms:
|
||||
steps = [s for s in steps if s[0] < args.until_ms]
|
||||
credits = parse_credits(load(args.js, "res/stillalive.js"))
|
||||
if not steps or not arts or not credits:
|
||||
sys.exit("error: no lyrics, art or credits found; has the source changed?")
|
||||
@@ -168,7 +177,7 @@ def main():
|
||||
"// owners. This project is not affiliated with or endorsed by Valve.",
|
||||
"//",
|
||||
"// Generated by tools/import_still_alive.py - do not edit by hand.",
|
||||
"#pragma once", "", '#include "show_data.h"', ""]
|
||||
"#pragma once", "", '#include "still_alive.h"', "", "namespace el512sa {", ""]
|
||||
for name, lines in arts.items():
|
||||
out.append(f"static const char* const ART_{name.upper()}_LINES[] = {{")
|
||||
out += [f" {c_string(l)}," for l in lines]
|
||||
@@ -187,7 +196,7 @@ def main():
|
||||
out += [f"static constexpr uint32_t SONG_START_MS = {SONG_START_MS};",
|
||||
f"static constexpr uint32_t CREDITS_START_MS = {CREDITS_START_MS};",
|
||||
f"static constexpr uint32_t CREDIT_CHAR_US = {CREDIT_CHAR_US};",
|
||||
"static constexpr bool CREDITS_LOOP = false;", ""]
|
||||
"static constexpr bool CREDITS_LOOP = false;", "", "} // namespace el512sa", ""]
|
||||
|
||||
args.out.write_text("\n".join(out), encoding="utf-8", newline="\n")
|
||||
screens = sum(1 for s in steps if s[3] == "STEP_CLEAR")
|
||||
|
||||
Reference in new issue
Block a user