Fist commit

This commit is contained in:
Angel Ivan
2026-10-02 12:08:21 -06:00
commit 2a9eabce14
54 changed files with 10737 additions and 0 deletions

96
scripts/embed_ui.py Executable file
View File

@@ -0,0 +1,96 @@
Import("env") # noqa: F821
from pathlib import Path
import hashlib
import shutil
import subprocess
project_dir = Path(env.subst("$PROJECT_DIR")) # noqa: F821
ui_dir = project_dir / "ui"
generated_dir = project_dir / "src" / "generated"
generated_dir.mkdir(parents=True, exist_ok=True)
npm = shutil.which("npm")
if npm and (ui_dir / "node_modules").is_dir():
subprocess.run([npm, "run", "build"], cwd=ui_dir, check=True)
assets = {
"indexHtml": ui_dir / "dist" / "index.html",
"appCss": ui_dir / "dist" / "styles.min.css",
"appJs": ui_dir / "dist" / "app.min.js",
}
if not all(path.is_file() for path in assets.values()):
assets = {
"indexHtml": ui_dir / "index.html",
"appCss": ui_dir / "styles.css",
"appJs": ui_dir / "app.js",
}
missing = [str(path) for path in assets.values() if not path.is_file()]
if missing:
raise SystemExit(
"Missing UI assets: " + ", ".join(missing)
)
def emit_array(name, data):
lines = [f"const char {name}[] PROGMEM = {{"]
for offset in range(0, len(data), 16):
chunk = data[offset : offset + 16]
values = ", ".join(f"0x{value:02X}" for value in chunk)
lines.append(f" {values},")
lines.append(" 0x00")
lines.append("};")
return "\n".join(lines)
def emit_length(name, data):
return f"const std::size_t {name}Length = {len(data)}U;"
header_lines = [
"#pragma once",
"",
"#include <Arduino.h>",
"#include <pgmspace.h>",
"",
"#include <cstddef>",
"",
]
source_lines = [
"// Generated by scripts/embed_ui.py. Do not edit manually.",
"#include \"UiAssets.h\"",
"",
"#include <cstddef>",
"",
]
for name, path in assets.items():
data = path.read_bytes()
digest = hashlib.sha256(data).hexdigest()
header_lines.append(f"extern const char {name}[] PROGMEM;")
header_lines.append(f"extern const std::size_t {name}Length;")
header_lines.append(f"extern const char {name}Sha256[] PROGMEM;")
source_lines.extend(
[
emit_array(name, data),
emit_length(name, data),
f'const char {name}Sha256[] PROGMEM = "{digest}";',
"",
]
)
def write_if_changed(path, content):
if path.is_file() and path.read_text(encoding="utf-8") == content:
return
path.write_text(content, encoding="utf-8")
write_if_changed(generated_dir / "UiAssets.h", "\n".join(header_lines) + "\n")
write_if_changed(generated_dir / "UiAssets.cpp", "\n".join(source_lines) + "\n")
print("Embedded UI assets:")
for name, path in assets.items():
data = path.read_bytes()
print(f" {name}: {path.name} ({len(data)} bytes)")