Files
Flipdot-display/tools/make_webui_screenshots.py
T
mangavalkandClaude Opus 5.5 ab001e5d18 Icons: small images of their own size for pages
Bitmaps that only pages use (backgrounds, images by state) are now icons:
own width and height, stored in /icons, not in the page lists or the Home
Assistant dropdowns. Page backgrounds and image elements use icons or
bitmaps; the renderer gets icons expanded at the top left, so pages look
the same. Web UI: Icons tab with an editor, Make icon / Make bitmap, Save
as icon on the Draw tab, icons in the backup.

A one-time migration in time-boxed steps moves the uploaded bitmaps that
only pages use, after the new firmware is marked good.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 22:03:18 +02:00

93 lines
3.2 KiB
Python

"""Saves screenshots of the web UI tabs in Pictures/web-ui/, with Microsoft Edge (or Chrome)
in headless mode.
python tools/make_webui_screenshots.py [ESP32 address, default 10.1.1.198]
Each tab is opened by its address (http://<ESP32>/#settings); the page editor with
#pages/<page name>. Edge runs with its own temporary profile. Only the Python standard
library is used.
"""
import json
import os
import shutil
import subprocess
import sys
import tempfile
import urllib.parse
import urllib.request
ESP = 'http://' + (sys.argv[1] if len(sys.argv) > 1 else '10.1.1.198')
OUT = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'Pictures', 'web-ui')
BROWSERS = [
r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe',
r'C:\Program Files\Microsoft\Edge\Application\msedge.exe',
r'C:\Program Files\Google\Chrome\Application\chrome.exe',
'microsoft-edge', 'google-chrome', 'chromium',
]
WIDTH = 1000
# File name, address part, window height
SHOTS = [
('show', 'show', 2150),
('pages', 'pages/Weer', 3000), # the page list and the editor (tall: nothing has to scroll)
('schedule', 'schedule', 1150),
('stopwatch', 'stopwatch', 560),
('bitmaps', 'bitmaps', 1600),
('icons', 'icons', 1900),
('draw', 'draw', 820),
('settings', 'settings', 1550),
('home-assistant', 'ha', 780),
('system', 'system', 1080),
]
def browser():
for b in BROWSERS:
path = shutil.which(b) or (b if os.path.exists(b) else None)
if path:
return path
sys.exit('No Edge or Chrome found')
def read_ha_values():
"""Reads the Home Assistant values of all pages, so the previews show them"""
with urllib.request.urlopen(ESP + '/api/pages', timeout=20) as r:
pages = json.loads(r.read())['pages']
for entity in {(e['entity'], e.get('attribute', '')) for p in pages for e in p['page']['elements'] if e.get('entity')}:
query = urllib.parse.urlencode({'entity': entity[0], 'attribute': entity[1]})
try:
urllib.request.urlopen(ESP + '/api/ha/value?' + query, timeout=10).read()
except Exception:
pass
def shoot(exe, profile, path, address, height):
for attempt in range(3):
try:
subprocess.run([exe, '--headless=new', '--disable-gpu', '--hide-scrollbars', '--user-data-dir=' + profile,
'--window-size=%d,%d' % (WIDTH, height), '--virtual-time-budget=20000',
'--screenshot=' + path, address],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=90)
return True
except subprocess.TimeoutExpired:
pass # the browser hung: try again
return False
def main():
exe = browser()
read_ha_values()
os.makedirs(OUT, exist_ok=True)
profile = tempfile.mkdtemp(prefix='flipdot-edge-')
try:
for name, hash_part, height in SHOTS:
path = os.path.join(OUT, name + '.png')
ok = shoot(exe, profile, path, ESP + '/#' + hash_part, height)
print(name, os.path.getsize(path) if ok and os.path.exists(path) else 'failed')
finally:
shutil.rmtree(profile, ignore_errors=True)
if __name__ == '__main__':
main()