[codex] Add ESP32 flash profiles, USB control, and SD assets#244
Open
mariusandra wants to merge 27 commits into
Open
[codex] Add ESP32 flash profiles, USB control, and SD assets#244mariusandra wants to merge 27 commits into
mariusandra wants to merge 27 commits into
Conversation
Collaborator
Author
|
Added in
Validation rerun:
|
Collaborator
Author
|
Follow-up in
Validation rerun:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/srv/assets, and hide the SD card field group unless that option is enabledmariusandra/pixiedependency for ESP32 builds instead of requiring a separate embedded Pixie checkoutbootupevents, mark browser/USB-flashed firmware as deployed when the boot follows a generated image, and compare git-describe firmware versions correctly in the deploy UIhttpd_ssl_startinstead of skipping at the old 96KB total-free thresholdusb_api imageafter render-complete serial logs, uploading it to the backend, and broadcastingframe_renderedpackedvshash-onlypreview storage from available 8-bit PSRAMRoot Cause
ESP32 frames can be flashed outside the normal deploy path, so the backend was still comparing against the old
last_successful_deploysnapshot even after the device reported a newer booted firmware. Direct commands could also keep targeting a stale mDNS/HTTPS host even when the ESP32 had reported a usable boot IP.For native ESP32 HTTPS, FrameOS was skipping the HTTPS server before trying ESP-IDF's allocator whenever total free internal heap was below 96KB. On the observed 7.3e boot, the device had about 54KB free internal heap and a 53KB largest block, so the old total-free guard rejected it even though the contiguous block was large enough to make an HTTPS start attempt reasonable.
The OTA trigger used the same direct frame HTTP helper, but a TLS certificate verification error on the first HTTPS candidate aborted the request before the embedded boot-IP fallback could run. If
frame_hostwas an IP like10.8.0.232and the certificate only covered a hostname, the backend returned a 502 even though the ESP32 had reported a reachable plain HTTP boot IP.The ESP32 setup UI was exposed on the normal LAN with no firmware-side request authentication. That made setup/control routes too sensitive for public reachability. The firmware now bakes/stores frame admin credentials, challenges browsers with Basic auth outside hotspot mode, denies setup access when no admin credentials exist, and still accepts the backend
server_api_keybearer token for automated deploy/control requests.When a board is plugged in over USB but LAN HTTP is unreachable, the UI looked connected because logs streamed, while deploy/control/image paths still depended on HTTP. The new serial API gives the browser a direct command path over the already-selected USB port.
The current frame image had the same gap: serial logs are client-local, so a USB-only render could finish without the backend ever seeing a render event or refreshing
/imageover HTTP. The frontend now detects render-complete USB log lines, pulls the preview throughusb_api image, and uploads that image into the backend cache used by the normal frame preview URL.For e-paper refresh avoidance, the useful invariant is the panel-packed output, not the RGB source. The firmware now hashes the packed buffer and stores that small state in NVS across boots/deep sleep. It keeps the full packed snapshot in PSRAM only when the largest 8-bit PSRAM block and remaining free PSRAM can afford it; otherwise it stays in hash-only mode to avoid blowing up smaller boards.
For firmware sizing, the build output had measured binary sizes but the UI did not show how those bytes map to flash slots or how panel buffers map to PSRAM. The firmware metadata now derives that layout from the same flash profile, partition CSV, panel dimensions, and render buffer formulas used by the build/runtime code.
The workspace had two deploy drawer states: the URL-backed workspace drawer selection and the local
deployPlanModalOpenright-panel state on frame/scene/app pages. Opening Add scene cleared the workspace drawer but could leave the local deploy panel open above it, while deploy sub-view switches only changed local state and never made the URL round-trip capable.Browser flashing used the normal frame-tool navigation action to open Logs after flashing, which also closed the deploy drawer. At the same time, a first boot log could make an embedded frame eligible for the main deploy view, causing the Firmware view and footprint card to disappear mid-flash. Firmware status updates could also replace rich layout metadata with sparse queued/stale records.
Validation
pytest -q backend/app/api/tests/test_log.py backend/app/models/tests/test_log.py backend/app/utils/tests/test_frame_http.pypytest -q backend/app/tasks/tests/test_frame_deploy_workflow.py::test_plan_fast_for_embedded_uses_http_scene_reload_plan backend/app/tasks/tests/test_frame_deploy_workflow.py::test_execute_embedded_fast_uploads_scenes_then_reloadspytest -q backend/app/api/tests/test_frames.py::test_api_frame_new_embedded_waveshare_13in3e6_preset backend/app/api/tests/test_frames.py::test_api_frame_new_embedded_waveshare_photopainter_preset backend/app/api/tests/test_frames.py::test_api_frame_embedded_usb_deploy_complete_marks_snapshot backend/app/api/tests/test_frames.py::test_api_frame_embedded_usb_deploy_complete_rejects_non_embedded backend/app/utils/tests/test_frame_http.pypytest -q backend/app/api/tests/test_frames.pypytest -q backend/app/api/tests/test_embedded_firmware.pypytest -q backend/app/utils/tests/test_frame_http.py backend/app/api/tests/test_embedded_firmware.pypytest -q backend/app/models/tests/test_settings.py backend/app/api/tests/test_settings.pypnpm --dir frontend run build:keapnpm --dir frontend exec tsc --noEmitgit diff --checkFRAMEOS_SELECTED_PANEL=EPD_7in3e idf.py -B build-codex-https-guard build/dev/cu.usbmodem1101;usb_api statusreturned the new render fields,usb_api renderacknowledged, and the follow-up status reportedlastRefreshSkipped=true,snapshotMode=packed, andpreviewBytes=192000