Skip to content

Device Screen ​

The current usage notes on this page are verified against the unified editing workspace, screen-config validation, touch runtime, and recent-records service in the source code. Whether a running device has these features deployed must be checked against the firmware/web versions; the historical deployment and failure records from September-October 2026 are kept at the end of the page, where IPs, serial ports, candidate versions, and the word "current" refer only to their time windows and are not this device's state or acceptance result.

Display and Hardware ​

The Device Screen targets ESP32-S3; type 56 denotes a graphical display peripheral, with backends supporting SPI ST7789/ILI9341 and controlled RGB ST7701, and optional GT911 touch. SPI/RGB drivers, dimensions, initialization sequences, and board configs must match; a generic esp32s3-F16R8 image does not automatically equal RGB-specific board firmware. RGB 480x480 needs PSRAM, and buffer/internal-RAM admission is verified against the actual build contract.

First enable developer mode in Advanced Config with the current password, enable screenPanel in Feature Config, then add the display peripheral and verify shared I2C/pin resources. Saved, applied, restart-required, and driver-init-failed are different states; when touch initialization fails, a read-only display can be kept, but navigation and control cannot be operated, and auto screen-off that relies on touch wake is not enabled.

For the Waveshare Rev4/CH32V003, the backlight, buzzer, and GT911 reset are managed by the same display backend — do not create separate output peripherals at the same address. The runtime JSON has moved to the firmware repository at docs/device-test-configs/com8-com9-esp32s3-touch/config/. Identical board names, F16R8 capacity, or GT911 model cannot replace pin/board-revision verification.

Editing in One Workspace ​

The page uses a unified workspace and no longer requires switching between separate "Preview/Config" tabs. The left side manages pages, templates, and components; the center canvas shows the draft; the right side switches between page/component/global properties; on mobile, a closable property drawer is used. "More" provides layout import/export plus weather and record settings; the unified write entry is "Save and Apply".

Drag or click-add components from the component library; when selected, adjust title, source, position, and size. A canvas update does not mean the config has been written to the device — switches, motors, "Execute once", and restart controls in the web UI are previews only and produce no real output.

At most 8 pages and 24 cards. New components look for a free position; out-of-bounds, overlap, and minimum interaction size are validated — do not shrink buttons to bypass touch-size requirements. Template reflow is an explicit rearrangement of the whole page; ordinary dragging does not move other components. Layout drafts are isolated by device MAC and revision — you cannot restore to another device by the same IP alone; an unsaved weather Key does not enter the local draft.

Page theme and background default to "Inherit global": changes to the global properties' theme and background sync to all inheriting pages, while pages with an explicit theme/background only affect themselves. When a page does not change after a global theme change, first check whether that page uses an independent theme, restore it to "Inherit global", and save again; global changes first apply to the editing draft and are handed to the device only after Save and Apply.

Data and Recent Records ​

ComponentSources and boundaries
Value, status, iconExisting collection/parsing results; expired, offline, error, and not-collected are shown separately
GaugeOne valid value with reasonable min/max
Bar chartUp to 4 non-duplicate, same-unit sources
Line chartLatest 10 valid numeric samples of a point; real gaps and incomparable cross-boot spans are not connected
ClockDevice system time and its quality; the computer time is not used in place of device time
WeatherShared Seniverse live-weather cache
ControlRules/motor sources that are permitted and still valid

Refreshing the canvas reads only the cache and does not additionally poll I2C/Modbus. Collection rules must produce data first; display cards cannot replace collection, drivers, or CAN protocol parsing. Missing values are not backfilled with 0, and old values must not pretend to be fresh.

History supports at most 24 sources and 10 points per source; settings live in /config/point_history.json and data in /data/point_history.json. Samples are held in memory first; when log-to-disk is active, they ride the same Flash write window as the log flush and commit in about 2 minutes; when logging is quiet, a fallback flush writes within at most 3 minutes. A sudden power cut may lose samples in that window not yet written. Restart-recovery points carry a history marker and do not serve as live readings. Choosing "all enabled recorded value sources" does not auto-enable recordHistory for every rule. Deleting a trend card does not delete the shared history. Compiled capability follows the target capabilities — on C3 with history trimmed, enabling the UI switch alone cannot restore the endpoints.

Weather ​

The current unified weather entry only supports Seniverse live weather, Simplified Chinese, and Celsius; legacy multi-provider, three-day forecasts, and arbitrary field mappings are not current editor features. Configure the city and your own Key, with automatic updates every 15/30/60 minutes (default 30); all weather cards share the config and cache. When a Key is set, leaving it empty keeps it; only explicitly checking "clear and disable" deletes it.

Save weather changes before using "Update weather"; manual refreshes are at least 5 minutes apart. Offline, uncalibrated time, busy OTA, insufficient memory, and service failures each show waiting/error states, keeping the last valid data and marking it stale. Cellular networks do not support this weather HTTPS path.

When migrating multiple legacy sources, choose the source to keep; when other sources are still referenced by rules, saving is rejected instead of silently moving them to another city. Weather credentials do not enter layout exports or public examples.

Physical System Operations ​

ControlBehavior
BrightnessDevices with continuous brightness use a 0-100 slider; 0 keeps the minimum visible brightness, and only an explicit screen-off turns off the backlight
Screen off nowThe next touch only wakes the screen and does not execute the touched control
Auto screen-offSet globally or via a supported selector control; no auto sleep when touch is unavailable
Touch beepSwitch controls whether feedback plays; duration is set in the display peripheral config; the CH32 onboard buzzer has no volume slider
Control-confirmation intervalRestricted selector control, configurable from 15 to 600 seconds
RestartScheduled only when both the global allowSystemRestart permission and the card confirmation are satisfied; refused during OTA/critical writes

The touch-beep duration is set under "Peripheral Configuration → the corresponding display peripheral", with common steps 20, 30, 60, 100, 150 ms and a default of 30 ms; this is the display peripheral's own save entry and the duration is not a volume. When an existing config lacks the touchBuzzerDurationMs field, it loads as 30 ms; the endpoint accepts integer milliseconds from 20 to 150; display devices without buzzer capability show the corresponding capability hint.

For this Waveshare Rev4 instance, backlightActiveHigh should be false: 100% is the brightest and 0% retains about 10% brightness; this value must not be generalized to other boards. Physical adjustments of brightness, touch beep, screen-off time, and confirmation interval can enter a controlled merged-save queue and are written per revision after about 2 seconds without new adjustments; failures/conflicts require checking the applied state — every touch cannot be promised to hit disk immediately, nor retention after restart guaranteed.

Up to five pages can use bottom-bar navigation; more pages go through the "More" list; swipe left/right to switch pages, and slider drags are consumed by the slider. Trend charts do not execute outputs. Display/touch/beep and restart each require real-device acceptance separately.

Rules and Motor Control ​

Generic control cards only select rules with allowPanelControl=true that are enabled and whose fingerprint still matches. Re-bind after content changes, source deletion, permission revocation, or config revision changes; cards must not directly fill in arbitrary URLs, Topics, scripts, or registers. Numeric control is constrained by source type, finite values, range, and step; the display unit does not auto-convert scaling.

The motor component is an independent controlled source providing forward, reverse, stop, speed, and pulse controls, and must still go through the existing motor service, travel reference, and feedback admission. Re-confirm after first use or an idle period; stop needs no confirmation. When TRAVEL_REFERENCE_REQUIRED appears, check the actual reference position first; do not use a generic FC06 rule to bypass the protection. Command acceptance, register readback, and the motor's actual motion are judged separately; motion commands with unknown results are not auto-replayed after a disconnect.

Remote switches should wait for real readback to match; without readback, only sent/unconfirmed is shown. There is currently no generic HTTP action endpoint for the browser to directly execute arbitrary screen cards.

Save, Import, and API ​

"Save and Apply" coordinates weather, history, and layout; only changed items are written, but it is not a cross-file atomic transaction. Partial success requires handling the remaining items per the prompts — already-succeeded items may already be in effect. Revision conflicts return 409; keep the draft, re-read, and merge — do not overwrite someone else's newer version.

MethodPathContent
GET / POST/api/screen-panel/configRead/save layout; POST contains expectedRevision and config
GET/api/screen-panel/choicesSelect sources by kind/q/page/pageSize
GET/api/screen-panel/stateQuality, values, results, and applied state
GET/api/periph-exec/history?sourceRef=...Recent records of a single source
GET / POST/api/periph-exec/history/configHistory switches and sourceAllowlist

Reading requires login; config writes also require developer mode. The screen_panel.json export contains touchUiMigration=2, and the dedicated import re-validates against the target revision; check legacy layouts in the editor before exporting. History migrates collection settings only and does not include samples. Layout files are protected by a dedicated transaction and backup — do not bypass with the generic file-write endpoints. Saving does not equal applying, and changing the display device may require a restart.

Resources and Acceptance ​

Turning off screenPanel does not automatically stop standalone sampling/remote sources, nor shrink the already-flashed Flash. RGB framebuffer, stripes, internal DMA/bounce, task stacks, and network peaks must be counted separately; PSRAM headroom cannot substitute for internal-DRAM reservation. Recovery after memory-protection suspension needs confirmation that the driver restarted; a busy recovery does not mean config is lost.

This page's source review involves no device operations. The final acceptance still requires display/touch, data freshness, config recovery, failure paths, and 24/72-hour acceptance matching the firmware/web, the specific hardware, and the load; historical short tests or passes from other S3s cannot replace that.

Historical development, deployment, and failure records (2026-09 to 2026-10; not current usage notes)

The original records below are kept for traceability, including deprecated old editing flows, old weather features, and old configuration parameters, and must not override the current feature descriptions above. Wording such as "current", "latest", and "in progress" corresponds only to the marked dates and does not mean still being monitored, deployed, or verified today.

In Development: Config Backup Round-trip (2026-10-03, untested/unreleased) ​

The screen editor export adds the touchUiMigration=2 marker. The device configuration page can import this version of screen_panel.json, saving with the target's current revision while the server re-validates the layout and references; legacy layouts must be re-exported after an editor check. Saving and applying are confirmed separately; changing the display target may require a restart; a lost response is not auto-retried. Point history imports collection settings only and does not migrate historical samples. Save-failure preservation, revision exhaustion, and readback-corruption regressions are prepared and await centralized software verification; they do not change the historical deployment conclusions below.

2026-10-02 Software-fix Verification ​

16:20 follow-up: the GT911 dual-address and draft-refresh fixes below have been merged into the main directory; GT911 keeps another startup-config retry/controller-size change. Post-merge has not been retested; the r15 awaiting candidate was canceled, and per the latest requirement, centralized testing waits until development completes. This state does not change the deployment evidence of the other independent candidates on this page.

14:35 new staging-area verification (not yet promoted to main source, not deployed): GT911 keeps both 0x5D/0x14 before reset or probing, consuming two slots of the shared manager; on address conflict or insufficient capacity it does not operate the touch GPIO, ownership is verified per transaction at runtime, and both leases are cleaned up on exit and destruction. The full real backend/manager and related offline regressions passed 82/82. Also fixed the issue where the editor refreshed before the 160ms draft debounce finished and lost the last edit; page leave now synchronously completes pending saves; MAC isolation, the original revision/baseline, and history drafts are preserved without saving field configs. 24 loopback browser checks and two source/minified tests passed, and the original r14 failure is kept. Both items still await promotion after freeze, a complete new candidate, and physical acceptance — the deployment conclusions below must not be updated based on them.

GT911's I2C reads now update results only after full-sample validation; short writes, missing bytes, and abnormal values are treated as failures, and abnormal drain counts have an upper limit. RGB backlight/buzzer control obtains shared-bus address ownership with per-transaction re-verification; cleanup after an initialization conflict or loss of ownership does not write to other co-client addresses. A failed control write does not advance the software shadow.

The staging area and main source each passed 70 offline regression items, covering the full GT911, RGB multi-config, PCF expansion IO, and shared-bus lifecycle. The corresponding new candidate's full gates, RGB-specific build, device touch/backlight/buzzer, and long-term operation are still to be accepted; historical deployment conclusions below must not be carried over. An I2C failure does not guarantee the hardware has rolled back; field outputs still need wiring and safety-condition verification.

Current Deployment and Acceptance Status (2026-09-22) ​

The Device Screen currently targets only the ESP32-S3; page layouts, display drivers, and touch configuration remain generic and do not establish separate product versions per dev board. Config files determine whether supported features are enabled by default; actual startup still passes hardware and resource checks. Different chips must use their corresponding target images.

COM8's r6 application and the matching canonical r3 Web have been written and verified, and the user confirmed the picture is "stable"; web, panel APIs, preview, and short data tests passed. After SHT30 changed to 8 seconds with the TTL unchanged, the 180-second strict-freshness/consistency/transport checks all passed, but the single-device long test had a real resource-transfer failure in round 2 that subsequent recovery and waiting could not offset. COM15's new field-r2 from another task has been deployed and passed short checks, with peripheral hardware not fully accepted; the C3's last deployment is r3, and the classic ESP32 is r4 with the overall web still failing. The main task is running r8 regression and C3/COM16 target builds; gains must be measured after deployment. Physical tapping, swiping, brightness, and the four devices' long-term stability are all unfinished:

2026-09-22 01:48:50 (UTC+8) long-test update: round 2 reported net::ERR_CONTENT_LENGTH_MISMATCH for /js/chunk-3-state.js?v=20260921-2341-93cd18cf, plus one HTTP-probe timeout with retry and a 13,447ms login. Round 3 had 12/12 menus with errors recovered to 0, but the probe took 7,176ms. artifacts/touch-soak-20260922-r6/fleet-stability-verdict.json is false: beyond the insufficient 0.167 hours against 24 hours, there was 1 transient probe failure, 1 resource-request failure, 1 console error, and probe p95 over 5,000ms. This error is not the legacy page-navigation cancel; recovery does not offset the earlier failures, the first three rounds had no restart/503, the original monitoring continues, and the root cause is pending.

DeviceAddress at the timeLast verified deployment
COM15 ordinary S3192.168.5.18field-r2 canonical, 3,902,896 B, 58 web files; write/verify and short identity/input/9600/Web manifest checks passed; 3 peripheral/exec/protocol configs explicitly updated among 10 non-web files; peripheral hardware not fully accepted
COM4 C3192.168.5.50canonical r3, 3,314,672 B, 51 matching web files, 9 non-www files kept; new HTTP 9/9 and desktop/mobile menus 14/14 passed
COM8 touch S3192.168.5.52RGB r6, 3,829,872 B; app1 and canonical r3's 58 web files verified; 38 non-web files and app0 kept, revision10; short picture/web/8s sampling passed; real resource failure in long-test round 2
COM16 ESP32192.168.5.51r4 application 3,318,496 B verified, r3 web/filesystem kept; MQTT fragment and subsequent mobile/features timeouts, overall failure; r8 build/deploy re-verification pending

COM15's new evidence is in the firmware repository at artifacts/com15-field-release-20260922-r2/build.json, com15-field-deployment-20260922-r2.json, com15-field-verification-20260922-r2.json, and com15-field-final-check-20260922.json, with sourceStable=true and SHA256 298f4d0f039ee6b682455632c5ecc8b2bafff5f99eace7c17aa0c482772a4db7. The first field version's worker-stack crash is kept as history; r2 had no crash in the short window, and the address at 02:07:39 was still .18. Address timeouts on 1/5/6, the A1 low input, and physical actions are followed up by that field task; do not expand deployment success into all peripherals passing, and do not use the old r3 all-menu evidence to represent the new version.

This round's r6 artifacts/resume-20260922-COM8-r6-http.json is 9/9 with a max of 1,371.5 ms; menus/report.json is 24/24 with zero HTTP/page/request errors, login 10,005 ms, slowest menu 5,759 ms; the same-prefix panel-api.json 15 items, and panel-browser/report.json preview/draft-add/mobile-layout passed without saving. live-data.json confirmed NTP, weather, both SHT30 channels and their 10-point histories, layout revision 10. These are short real measurements and cannot replace long-term operation or all physical operations.

The same-prefix consistency.json 120-second check passed same-group consistency with 0 mixed-generation and request errors, 13 new points per channel and a max interval of 11,679 ms, but 2 stale occurrences per channel — that window's strict-freshness failure is kept. sample-margin.json confirmed only collect_sht30 changed to 8-second sampling with before/after kept: the TTL is still 10,000 ms, and actions, other rules, and motor collection intervals were unchanged. The sampling rate increased 25%, leaving scheduling margin without extending the old validity. Public templates sync that rule name and period; the follow-up 180-second retest is below.

The follow-up same-prefix consistency-8s.json 180-second window completed: 50 responses, 24 new points per channel across both channels, max interval 8,868 ms, no stale/mixed-generation/request errors; strict freshness, consistency, and transport all passed. 8s-serial.log had no reset/panic, the worker stack's lowest remaining was 2,092 B, but there was one log_flush 2,513 ms over-budget warning, kept with monitoring continuing.

COM8's single-device long test started at 2026-09-22 01:33:49 (UTC+8), PID10344, directory artifacts/touch-soak-20260922-r6, with startup and stdout/stderr in the same-named -prepared directory; every 300 seconds/289 rounds, requiring at least 24 hours. Round 1's 12/12 menus with zero errors represent only that round; round 2's failure is kept. At 02:08:50 the verdict measured 0.500 hours, still with transient probe failures, resource/console errors, and p95 over the limit, overall false. Original monitoring continues, the other three devices were not included, old durations are not stitched, and neither 24h nor 72h passed.

The full host regression is in artifacts/resume-20260922-r6-host-unit.log: 681 items, 680 passed, 1 skipped due to Windows symlink permission, 199.813 seconds, exit code 0. Local tests, short real-device runs, and long-term stability results remain distinct.

The touch-recovery evidence is in the firmware repository at artifacts/resume-20260922-COM8-priority-serial.log, resume-20260922-COM8-priority-http.json, and resume-20260922-COM8-preupgrade-history.json. HTTP static resources max 1,678.7 ms, all requests max 2,595.8 ms; history recovery passed=true represents only this controlled restart — sudden power loss, sustained freshness, physical interaction, and 24/72 hours still need separate acceptance.

The new touch r6 is sourceStable=true, sdkRecompiled=false, BIN 3,829,872 B, SHA-256 31da1e3f048b37819108260ce180d23858b35a23798117601eb7ddc551599007. The 30 tests of the temperature/humidity same-group atomic-commit and panel-consistent-snapshot fixes, the Arduino String compatibility retest, and 34 network-response tests passed; SDK, RGB timing, and TTL were unchanged. It has completed write-verification, and runtime measurement is still to be closed out — do not treat local tests or write success as field feature acceptance.

The first two r6 attempts failed respectively at filesystem-backup transfer and download connection; resume-20260922-COM8-r6-all-write.json and resume-20260922-COM8-r6-all-retry-write.json are kept as history with writes never started. Then artifacts/resume-20260922-COM8-r6-manual-write.json shows written=true, verified=true, writeStarted=true, completing the application and web update while keeping 38 non-web files and the entire app0, with identical app0 MD5 before and after. resume-20260922-COM8-r6-exit-download.log records a deliberate watchdog reset to exit download mode after confirming device identity; it no longer waits for BOOT, pending the new version's runtime retest results.

COM16 r4's write and filesystem-preservation verification is in resume-20260922-COM16-r4-write.json; the menu report resume-20260922-COM16-r4-menus/report.json rendered 14 pages but still had an MQTT fragment resource timing out after about 8 seconds — overall failure. The worker's recovery was once deferred during memory protection, but later health confirmed recovery; do not call it permanently stopped. The r3 failure below is kept history.

The new COM15 sequential HTTP max is 4,006.5 ms, login 5,430 ms; the C3 sequential HTTP max is 813.6 ms, login 4,716 ms. Both devices passed all 14/14 menus with zero HTTP/page/request errors — short-test passes that still cannot claim sustained performance or long-term stability. COM16 sequential HTTP max is 1,480.6 ms, but the full browser hit low-memory 503 and two connection timeouts on desktop/device, login 9,926 ms — still failing. COM8's anomalies are in the next paragraph. Pre-upgrade short tests, sequential-request success, or about 25 hours of uptime cannot replace the full browser and a valid long test. Addresses are DHCP-assigned; check the current STA address when access fails.

Evidence is archived in the firmware repository at artifacts/final-release-20260921-r3/builds.json; the ordinary three devices are respectively artifacts/resume-20260921-COM15-final-write.json, resume-20260921-COM4-final-write.json, and resume-20260921-COM16-final-write.json, all written=true, verified=true, keeping boot, partition table, NVS, OTA selection, and non-www files. Runtime evidence is resume-20260921-COM4-postfinal-http.json, resume-20260921-COM4-postfinal-menus/report.json, and the corresponding COM16 files.

COM15's new-version evidence is artifacts/resume-20260921-COM15-postfinal-http.json and resume-20260921-COM15-postfinal-menus/report.json. COM16 also reproduced content-length mismatch in the r3 historical window's no-login/no-JSON static-resource stage, with internal free dropping to about 7.3 KB and triggering severe protection; after the dependency-patch 34 local tests passed it entered r4 deployment, but resource timeouts remain — see the top of this page. Diagnosis is in the firmware repository at artifacts/COM16-postfinal-diagnosis-20260922.md.

The RGB r3 application only updated app1; the write and verification both passed, app0 and the whole field filesystem MD5 stayed identical, and the SDK was unchanged. After deployment, the serial showed SHT30 collecting about every 10 seconds within about two minutes, but two HTTP freshness checks timed out after 3 and 7 samples respectively; then the main CSS received only 995 B before timing out at about 15.55 seconds, and serial rechecks still showed multiple Power-on resets. Firmware-repository evidence: artifacts/resume-20260921-COM8-app-r3-write.json, resume-20260921-COM8-r3-http.json, resume-20260921-COM8-r3-recheck-serial.log, resume-20260921-COM8-power-reset-recheck.log. Field check of USB plug, power supply, and motor connections was requested; the reset cause is undetermined and must not be written as recovered or stable.

In COM8's follow-up about-120-second polling, temperature and humidity each had 12 new samples with a max interval of 10,460 ms, but humidity had one stale; resume-20260921-COM8-freshness-r3-recovery.json still failed. Before the controlled restart both channels had 10 points each; the post-restart recovery-point request timed out, and resume-20260921-COM8-prefinal-web-history.json also failed; history-recovery pass cannot be claimed, nor can point loss be concluded from the timeout alone. Short re-access does not offset the earlier resets/timeouts. COM8's matching new web, physical display/touch/brightness/buzzer, and final sustained collection and restart recovery remain to be verified.

On 2026-09-22, earlier passive serial recorded 11 Power-on resets in about 25 seconds with no restart request sent by us; evidence is artifacts/resume-20260922-COM8-passive-serial.log. The user then replugged the data cable and confirmed the picture was normal; the short recovery is recorded at the top of this page. Failure evidence stays kept; the root cause cannot be asserted to be the power supply, cable, or a specific software module just from the reset label or the timing after replugging.

The canonical r2 web gzip once exceeded the budget by a few bytes, and the failure record is kept; after the request-governance code reduced about 222 B more, canonical r3 passed the three-target build without raising the budget. The full local regressions below correspond to the earlier frozen snapshot; later changes still need affected checks and final runtime-release verification.

On September 20, the two long tests on the ordinary S3/C3 and the touch S3 were both stopped, with measured windows of about 2.583 and 1.781 hours and the 24-hour acceptance unfinished; automatic follow-up is paused. C3 503s, load shedding, and request failures, plus the touch S3's raw SSE failures and intermittent temperature/humidity stale states are all kept; COM16 did not participate in the original long tests, so the three devices' results must not be written as four. Later short-test successes cannot offset these failure records; the 72-hour acceptance is also unfinished.

The main cause of temperature/humidity not updating during continuous browsing has been located: every web request renews a 3.5-second foreground protection and pauses the collection-timer scheduling, and the status polling about every 3 seconds keeps renewing the protection. Overlapping serial and HTTP sampling verified this stall; do not treat the stale on-screen values as live data, nor attribute it only to the sensor cache.

This round's fix keeps the collection scheduling when PSRAM is available, internal 8-bit free is at least 30 KiB (30,720 B), the largest contiguous block is at least 8 KiB (8,192 B), and the device is not under severe memory pressure, and allows re-collection during continuous browsing after short pressure recovery. C3/classic ESP32 without PSRAM still yield to the foreground; do not claim collection on all devices is unaffected during browsing. Existing scheduler/worker memory protection stays effective; the SDK, RGB timing, and collection period were not changed. Another cache-boundary fix: rules request new samples this round, same-round temperature/humidity reuse, and the driver's minimum interval, real sampling time, and expiry threshold are unchanged.

Foreground-yield, watchdog, memory-recovery, and collection-interval targeted tests 14/14; full native 2,371/2,371; local contracts and isolated static/meta passed. The static chain includes 11 web-capability builds, S3/C3 smoke, gzip, and release consistency; the S3 web is about 315.0 KB, within the existing 315.0 KB budget. Evidence is archived in the firmware repository at artifacts/resume-20260921-web-sampling-tests.log, resume-20260921-native.log, resume-20260921-contracts.log, resume-20260921-static.log, and resume-20260921-meta.log. These do not replace same-version real-device collection freshness, the full browser, or long-term acceptance; the r7/r8/r19 and old addresses below are historical evidence.

Features and Hardware Boundaries ​

The Device Screen displays the firmware's existing data and operations on a physical screen. Users select components, bind sources, and adjust positions in the web UI; the device generates backgrounds, icons, cards, and basic charts with built-in drawing code, without producing full-screen images or writing UI scripts. The internal feature key remains screenPanel, and existing APIs and config-file paths stay compatible.

The Device Screen targets only ESP32-S3 and supports different dev boards within that chip via generic configuration. The system is still one firmware product, enabling capabilities on demand via config. Current backends include SPI ST7789 / ILI9341 and the ESP32-S3 esp_lcd RGB ST7701 test backend, with optional I2C GT911 touch; controller, wiring, dimensions, and parameters must match. SPI configs: the short side must not exceed 240 and the long side must not exceed 320. The RGB st7701_type1 initialization profile only accepts 480x480 and needs PSRAM; other controllers/initialization sequences cannot be applied directly. The Waveshare ESP32-S3-Touch-LCD-4 Rev4 has completed code integration; the latest touch application as of 2026-09-22 is RGB r6, with deployment and runtime acceptance boundaries at the top of this page. Earlier r19/r8 web and RGB r3 short serial, weather, menu, and field-picture results are version-specific evidence and cannot serve as r6 hardware acceptance. Other touch controllers, multiple physical screens, image upload, arbitrary SVG/HTML, and user-script-style UIs are outside the current implementation.

ESP32-S3-F16R8 only denotes the chip, Flash, and PSRAM resource specification and does not mean arbitrary S3 screen boards work directly. New RGB configurations first target the Waveshare ESP32-S3-Touch-LCD-4 Rev4 for real measurement, using the CH32V003 0x24 to manage reset/backlight and sharing I2C with touch and SHT30. Same-resolution boards like ESP32-4848S040 still need initialization sequence, timing, pins, and control-circuit verification; GT911 being reusable does not equal whole-board compatibility.

Rev4 parameters were checked against the Waveshare product page, V4 resource entry, Arduino notes, and official repository; this round's source baseline commit is aa604c132ef2442013ac93910c65789763329c05. The online product page contains early-version diagrams; Rev4 electrical details must be confirmed jointly from the V4 schematic, the current official repository, and physical silkscreen — do not mix the old TCA9554 wiring with the Rev4 CH32V003 wiring.

Framework versions must not be mixed either: the Waveshare Arduino page still lists 3.0.7, the current official repository's Build Examples CI uses 3.3.11, while the current FastBee candidate pins Arduino-ESP32 3.3.8 / ESP-IDF 5.5.4. This round only references the official pins, initialization, and buffer configs and does not upgrade FastBee to 3.3.11; any candidate must record the actual core/IDF, the official commit, and the effective Flash/PSRAM configuration — conclusions cannot be carried across versions.

The control-expansion initialization parameters are reset, enable, backlight, buzzer, and an extra low-level mask; all masks must not overlap. The Rev4 buzzer is bit 6, and the target config uses controlBuzzerMask=64; controlInactiveMask=0, and the system enable remains bit 5. The buzzer is controlled by the CH32V003 output shadow shared with the display backend — do not create another independent peripheral writing the same 0x24 address. The generic default is still 0, which is not a generic value for other boards. The r17 deployment file adjusted the device config from the historical 0/64 to 64/0 and confirmed the rest of the JSON is equal; the r18 firmware-only update kept that config. The bounded short beep at startup and the abnormal return to low level are still unaccepted. A sustained beeping occurred in the field; fields, local tests, and write verification cannot replace physical re-verification with the matching config.

Touch is optional. When display initialization succeeds but touch initialization fails, the firmware logs a warning and keeps a read-only display; pages can still show information, but navigation, switching, and scenes cannot be operated by touch. Without configured touch or with touch not ready, auto screen-off does not engage to avoid having no local wake entry; the configured idle screen-off time only takes effect when touch is ready. A display initialization failure itself is still reported explicitly as an error and is not a read-only-display success.

Whether menus and drivers are available depends on the firmware's compiled capabilities. esp32-F4R0 keeps existing features and meets the app-partition size by not compiling the panel and remote resources, but still compiles recent records; esp32c3-F4R0's 4 MB single-app slot is tighter and currently trims the panel, panel web, recent records, and remote resources, keeping live collection, Modbus, PeriphExec, and ordinary web. Disabling a feature at runtime only releases related runtime resources and cannot shrink the already-flashed firmware.

Historical Release Status (2026-09-20) ​

This section keeps only the September 20 deployment and failure evidence; the "current"/"latest" below refer to that window. The current state follows the top of this page, and old DHCP addresses are not current access addresses.

2026-09-20 latest status: the last successfully written touch firmware version was r19, still using two 16-line internal bounce buffers totaling 30,720 B. The build was sourceStable=true, sdkRecompiled=false, networkDependenciesMatchCanonical=true; firmware 3,819,712 B, SHA-256 5d7f322d7dda7628e8cb0f3f24c0e983b3fe5d7c122cfb6a75463e2dee855173. COM8 app1 was written, followed by the matching r8 web preservation write reporting written=true, verified=true; app0 and the field filesystem protection area were not written, MD5 unchanged before/after, and 38 non-www files plus field configs such as the buzzer 64/0 were kept.

r19's 120-second serial short test showed the device was connected to 192.168.5.33, with NTP triggered, continuous SHT30 collection, and RGBSCAN scan/frame counts consistent; no panic or restart was recorded. Then COM8 passed 5/5 HTTP, desktop/mobile 24/24 menus, main stylesheet 1,594 rules, and revision 9 weather/system previews; only the collect_sht30 rule was allowed panel invocation, with real rule-fingerprint binding tests 26/26. Final targeted host 35/35 and main-stylesheet contract 3/3 passed; this machine evidence cannot replace physical display, touch, buzzer, or long-term acceptance.

The pre-upgrade read-only reports screen-live-state-r16.json and screen-live-data-r17-before.json correspond to the r16 firmware, not the current running evidence. r19 automatically obtained Beijing cloudy 26 °C after a 13,584 ms cold boot, with NTP, SHT30 temperature/humidity, and both ten-point trends good, with no manual test reads or Key re-entry. Actual test credential values are not written into documents, public templates, or logs; the device's read endpoints only return masked values, and follow-up retests keep confirming that status and error logs do not echo keys.

r17's full touch-web acceptance did not pass: login, root page, and CSS transfer failed in turn; build logs showed the dependency-patch script checked the default .pio/libdeps and missed the AsyncTCP/ESPAsyncWebServer in the actual C:/p12/libdeps. r18 fixed the directory resolution and rebuilt the application only, with SDK, RGB timing, and display parameters unchanged; 9/9 HTTP 200, complete CSS 24,244 B, the Device Screen browser, and desktop/mobile 12 menus each all passed with zero HTTP, page, and request errors. r17's web failure is closed, but these short results do not represent the physical panel or long-term stability.

r19's first combined live-data script failed about 17 seconds into startup before SHT30 produced its first sample; a later ready report confirmed weather, NTP, SHT30, and both ten-point histories good, closing that startup window. The browser's first-round root page showed ERR_CONTENT_LENGTH_MISMATCH; the follow-up r8 web retest passed features/menus, but the history screenshot missing the main-frame CSS window is kept — physical display stability cannot be claimed from early screenshots or menu passes alone.

Historical r15 used 32 lines, 61,440 B; at cold boot internal free was 25,524 B and the largest block 7,668 B, Wi-Fi hit ESP_ERR_NO_MEM, SHT30 was async_unavailable, and the user saw fast vertical jitter and ghosting — runtime acceptance failed. r16 reduced the buffer by 30,720 B; after Wi-Fi recovered, the first 30-second window had internal free 41,556 B and the largest block 31,732 B, up 16,032 B and 24,064 B from r15 respectively. r15 evidence stays as history; r16's short physical conclusion came from user observation — the machine short test itself cannot prove visual stability, much less replace full-load or long-term acceptance.

Historical record: r14 was at the time written and read back consistently on COM8, and the field configs and web filesystem were not replaced by the deployment flow; after the failure, only the application was rolled back to rgb-recovery-v1 with a complete re-readback. The brief download mode, black screen, and USB re-enumeration after rollback are kept as troubleshooting evidence but have been superseded by the current state after the cold power cut above. Evidence is in the firmware repository at artifacts/COM8-r14-write-20260920.json, rgb-xip40-v12-revalidated-r14.json, touch-r14-single-session-runtime.log, artifacts/COM8-r14-app-rollback-20260920.json.

The other three devices were deployed with canonical r7. The ordinary S3 .22 and C3 .34 r7 real-browser desktop/mobile menus each passed 14/14 with no page or HTTP errors; they still do not equal long-term stability. COM16 .32's full-menu window had a low-memory 503, which belongs to a resource-risk window and must not be written as a smooth pass. The two devices' first long-term-stability monitoring was only 1 cycle (0 hours): S3 had no errors, while C3 had 2 503s, 4 HTTP/request errors, and 2 console errors, auto-judged as failed; 24/72 hours remained to be done.

As of 2026-09-20, the Device Screen source was frozen and host regressions completed: host 662 items with 661 passed and 1 skipped due to Windows symlink permission; native C++ 2,371/2,371; the Device Screen offline browser special 10/10; the full offline browser matrix 140/140 in the previous round; web quality gate 314.9/315.0 KiB; and the deployment-helper contract preserving field files 57/57. Canonical r7 built successfully for the S3, C3, and ESP32 targets with sourceStable=true. Host regressions and build results do not mean the touchscreen passed physical acceptance; r17's web failure was closed by r18's same-device retest.

COM15 was formally written with canonical r8 firmware and matching web; COM4 and COM16 kept the verified canonical r7. COM15 .22 r8 and COM4 .34 r7 strict browser checks were both desktop/mobile 14 pages with 1,594 main-stylesheet rules readable, zero failures, and zero writes. Touch r19 was written to app1, and r8 web was also written preservation-style and verified; .33 passed 5/5 HTTP, 24/24 menus, weather/system previews, revision 9 data chain, and 26/26 rule-binding tests, but physical display/touch, physical weather, buzzer, and long-term operation were not accepted. r16's NTP, ten-point trends, weather binding, and the user's short display-stable observation are kept only as pre-upgrade history; r12/r13 build rejections, r14 rollback, r15 runtime failure, and r17 web failure records remain kept.

The touch candidate was always developed against the official Arduino-ESP32 3.3.8 / ESP-IDF 5.5.4 SDK provided by pioarduino. The "SDK recompile" in this document means letting the official source components regenerate in an isolated directory per the target sdkconfig build-time options — it does not modify, upgrade, or privately fork the SDK, nor does it overwrite PlatformIO's shared SDK installation. The isolated diagnostics __wrap_log_printf conditional patch and builder adaptation only solve compatibility with the current PlatformIO/pioarduino full-rebuild path; they do not change display timing, display/touch drivers, or board-level hardware logic; both the shared package and the isolated copy have summaries and recovery checks.

The 41 requests before deployment and the 2026-09-20 12:48 four-device refresh are only historical connectivity evidence. The current .22 S3 r8 and .34 C3 r7 strict-browser desktop/mobile 14 pages and main-stylesheet checks passed; .33 completed the r8 web preservation write, followed by 5/5 HTTP, 24/24 menus, revision 9 weather/system previews, and 26/26 rule-binding tests passing. The two early COM8 r8 web-write connection-failure windows with written=false are kept as history; the user reported physical black-screen recovery and edge-curl/drift — physical display/touch pass cannot be declared. COM16 .32's full-menu window had a low-memory 503; the ordinary S3/C3 first-round monitoring also failed due to C3 503/request errors, and 24/72-hour monitoring was not completed.

Configuration Flow ​

2026-09-20 evening configuration recheck: field revision 9 had merged weather into the home page and provides three-step brightness, screen-off, beep, confirmed restart, and SHT30 "Collect once". Follow-up continuous read-only sampling found temperature/humidity intermittently expiring, with two new points once about 58 seconds apart, exceeding the rule's 10-second period; collection scheduling vs screen snapshot updates is being distinguished — a single normal reading earlier must not be read as sustained-freshness acceptance. The touch board's independent 24-hour web monitoring after the menu-directory fix has started, with round 1 12/12 menus and zero 503s; physical display, touch, brightness, and buzzer still need field confirmation.

EntryResponsible content
Peripheral ConfigurationAdd display devices; configure SPI, backlight, optional touch, and pin/bus preflight
PeriphExec, Communication ProtocolsConfigure collection rules, panel-callable controls, and weather/remote sources
Device ScreenPut existing data/controls into pages; adjust theme, template, position, and size

First enable screenPanel in "Feature Config", save, and restart. It is off by default; turning on the switch does not mean the screen is connected. The page separately reports whether the config is saved, applied, restart-required, and driver errors. Without a screen you can still configure and preview; the physical display still needs actual hardware acceptance.

After entering the page, "Preview" and "Config" tabs are shown directly, without large titles, description cards, or duplicate toolbars occupying the first screen:

  1. In "Preview", manage pages, open the component library, view the device canvas, and edit directly; you can add data, control, clock, weather, page-entry, or system components, drag, resize, snap, and modify the selected card's properties.
  2. Preview and editing use the same canvas; the draft shows before saving, and the saved device picture can be expanded for comparison. Switches, values, buzzer, and restart controls in the web preview do not execute real operations.
  3. In "Config", select the display device, theme/background, default page, brightness, auto screen-off, system-operation permissions, and recent records, with links to peripheral configuration, PeriphExec, and weather/remote sources.
  4. After saving, view "Saved / Applied / Pending restart / Apply failed"; handle restart-required prompts when hardware parameters change.

When using the CH32V003 control expansion, the display device exclusively owns the whole control address; reset, enable, backlight, buzzer, and outputs that must stay inactive must be explicitly declared in the control mask. Direction/output registers are maintained through a software shadow; the first input sample keeps latched values for undeclared bits, but undeclared pins are still set as inputs and cannot inherit unknown output directions from old firmware. Other outputs at the same address must not be handed to another peripheral for simultaneous control. TCA9554 uses real register read-modify-write with different semantics. The Rev4 template uses controlBuzzerMask=64, controlInactiveMask=0, controlTouchIntMask=4; buzzer, backlight, and touch linkage still need physical re-verification on the final deployment version. A readable GT911 product number and an all-zero config checksum cannot serve as evidence that touch is ready.

The default template can quickly generate five initial draft pages — environment monitoring, trends, weather, control, and system operations — or pages can be added individually. Five pages are just a template example, not a fixed interface or count limit; users can add, remove, rename, reorder pages, and adjust card layouts freely. The weather page binds the weather source; the collection page picks values from existing unified collection results of I2C, Modbus, or others; the control page binds remote switches, scenes, or local rules allowed panel invocation. Templates and the web preview only edit layouts and do not execute real actions.

The current maximum is 8 pages and 24 cards total. The logical canvas is separate from the physical resolution; small screens must still keep text readable and buttons easy to tap. Devices support touch page-switching, swiping, and buttons; devices without touch do not enable touch-wake auto sleep.

When there is no weather API credential or no execution rule selected yet, weather cards and control cards may be saved as empty-binding placeholders showing a to-be-configured state; they do not show fabricated weather, do not treat unknown switches as off, and cannot execute actions. The Waveshare Rev4 public template now has four pages — home, trends, scenes and switches, system operations — with 18 cards total; the home page merges weather, NTP time, and temperature/humidity, and weather no longer occupies a whole page. "Collect once" binds the SHT30 collection rule allowed panel invocation; switches and scenes are still to be bound. The field revision 9 keeps the existing motor page, at five pages and 24 cards, with the motor motion rule kept disabled. These are just editable layouts that users can freely modify; the public template contains no field weather keys.

The field motor has been confirmed at address 8, 9600, 8-N-1, with the user-provided protocol writing 1 via FC06 to registers 0/1/2 for forward/reverse/stop, and FC03 reading with count 1 the speed at 5, pulses at 7, count at 4, and baud-rate code at 10. The example uses four independent generic collection tasks and four single-task collection actions to avoid auto-merging widening the read range; the generic FC06 PeriphExec rule reuses the protocol-generated type=51 virtual peripheral. Explicitly fill in the confirmed register table without relying on implicit default tables, without the built-in motor's continuous-range readStatus, and without soft limits that may additionally write pulses. All parameters and actions can be modified per other devices' protocols, adding no motor-specific panel logic.

The hardware is currently disconnected, and the read tasks and collection rules are disabled by default; the three write rules for forward/reverse/stop are disabled by default and not allowed panel invocation. Without real sampling, no speed/count cards are created and no fake values are shown. Enabling control requires the user to select a rule and explicitly authorize it, saving the binding via the dedicated API; forward/reverse should use a second confirmation. By default there are no address/baud-rate modification rules and no trial runs. The address 01 and CRC in example frames must not be copied directly — the firmware generates RTU frames with the actual address 8. The PM tasks, rules, and sources no longer connected have been removed from the public template.

System Operations and Network Boundaries ​

System components use the firmware whitelist and do not accept URLs, arbitrary registers, commands, or scripts:

ActionBehavior and limits
Set brightnessThe card saves a fixed value from 1 to 100; 0 is not a brightness action — use the dedicated screen-off
Screen off nowTurns off the backlight; the next touch only wakes the screen and does not execute the touched card
Buzzer beepOnly a short beep executes, with auto-off on the abnormal path; unavailable when the backend has no buzzer capability
Restart deviceRequires both the global permission and the card confirmation; refused during OTA/critical writes

The Waveshare Rev4 example and the field revision 9 provide 25%/70%/100% three-step brightness, screen-off-now, beep, and confirmed restart; the default brightness is 70% and auto screen-off is 0 seconds. This example explicitly sets allowSystemRestart=true and keeps the card second confirmation; the firmware generic default remains false — remove the card and turn off the global permission when no restart entry is needed. Brightness buttons change the current running brightness; the default brightness after restart is still saved in the web "Config". Touchscreens provide no physical-screen network provisioning or web network-configuration shortcut entry, do not enter, save, or echo passwords on the screen, and do not directly sync network restarts from screen tasks. If local provisioning is added later, network-object switching must go through the main-loop queue, with failure fallback and a safe AP verified separately.

Themes are dark, light, and high-contrast; backgrounds are solid, light-gradient, and grid, all drawn in code. The web preview and import only edit drafts — clicking switches, scenes, or restart cards in them does not execute real operations.

Data Binding and Charts ​

ContentSources and limits
Value, status, iconExisting collection results, Modbus-parsed fields, remote states, and compatible device metrics
GaugeA single valid value; reasonable min/max must be set
Bar chartMain source plus up to 3 same-unit value sources; each shows value, status, and sampling time
Line chartThe latest 10 valid numeric samples of a collection point
WeatherSeniverse or compatible custom APIs, showing the weather icon, temperature, city, and available forecast
Time, dateReuses synced system time, NTP, and timezone; shows unknown when unsynced
Control, scenesPeriphExec rules explicitly allowed panel invocation; supports switches, execute-once, and restricted numeric controls

Refreshing the UI reads only the cache and does not additionally poll I2C/Modbus when turning pages or opening the browser. I2C sensors need existing collection rules to produce data first. CAN currently has no complete driver/parsing chain — you cannot read CAN just by adding a card; the panel can be reused once unified collection results are available later.

Not-collected, expired, offline, and error states are shown separately. Missing values are not shown as zero, old values do not pose as live values, and unknown switches are not treated as off. Deleting/disabling a source invalidates its bindings; after source mappings, units, and similar definitions change, old and new chart series are not mixed.

For new bar configurations, choose the data source in the component settings, then choose "Compare source 2-4" — no register changes or collection-task duplication needed. Sources must all be numeric with the same unit; templates add height for multi-item comparison, and canvas mode must reserve the hinted minimum size. T+12s denotes the sample at the 12th second after this boot and does not pose as calendar time when uncalibrated. Different cards keep their own comparison items even when sharing the main source.

The web clock preview uses the time and date returned by the device state, follows the device timezone, and does not substitute the computer time. When the device is uncalibrated it shows "Time not synced"; on read failure it keeps the last device time and marks "Device time not updated". The above multi-source, theme-identifier, and device-clock consistency fixes passed local testing and entered the canonical r7 and touch r17/r18 builds/deployments. The responsive rules for mobile multi-source bar charts were merged into web-src/css/screen-panel.css; the same rules previously passed 9 cases of 360/390/desktop and the three theme combinations, and the original six cropping-failure reports remain kept. Final host/native, the Device Screen offline special, and the full offline browser matrix all covered this code; host or browser results still cannot pose as physical-screen acceptance.

Latest Ten Records ​

The history feature is independent of the display driver, enabled on demand with selectable allowed sources. Up to 24 numeric sources, each with a 10-entry ring record; switches, error responses, empty values, and invalid values are not written. Repeatedly displaying the same sample does not create a new point.

The latest-ten remains subject to compiled capability. The current esp32c3-F4R0 sets pointHistory=false by default to fit the 0x330000 app slot, so there are no history config/query endpoints; live collection values still work in peripherals and the ordinary web. esp32-F4R0 and the full S3 targets keep it compiled. The final word follows the target release manifest and /api/system/capabilities.

Records enter RAM first, then merge-write to /data/point_history.json: when log-to-disk is active, dirty data rides the same Flash write window as the log flush about 2 minutes after filling; when logging is quiet, a fallback write lands within at most 3 minutes, avoiding a Flash write per sample. Settings are saved in /config/point_history.json. A normal controlled restart requests a save first; a sudden power cut may lose samples not yet committed in the last write window (up to about 3 minutes). Web/API reads use the in-memory cache and are unaffected by the write window.

Restart-recovery points carry a history marker and are not treated as live state. Without synced NTP, boot identifier, sequence number, and uptime are used — they do not pose as absolute time continuous across restarts. This feature is for short-trend observation, not a long-term database; the history data file is not included in ordinary config exports.

Remote Control and Weather ​

First define MQTT switches/actions and readback in "Communication Protocols" remote-resource configuration, then set the corresponding actions in PeriphExec, enable panel invocation, save allowPanelControl=true, and finally bind the control card. Rules without this explicit permission do not appear in the available control sources, and cards cannot bypass rules to directly fill in Topics, URLs, or payloads.

After sending a switch command, wait for the actual readback to match before confirming; when offline, new commands are rejected, and queued controls are not replayed after a disconnect. In no-readback scenarios, only sent-result-unconfirmed is reported. After a rule's content changes, the panel binding must be saved again.

The "Execute once" button reuses rules from the PeriphExec list and can be used for one collection, scene, or other allowed peripheral action. The user first enables "Allow panel invocation" for that rule in PeriphExec, then selects the control component and action style in the Device Screen and binds the rule; the Device Dashboard and Device Screen share existing rules and do not copy URLs, Topics, or payloads. Merely showing the button, loading the web preview, or switching pages does not trigger execution. After permission revocation, rule disabling, or content change, old bindings cannot keep bypassing the checks to execute.

Generic Modbus fixed-value actions can be created in PeriphExec by choosing "Write single register (FC06)" and filling in decimal address:value, for example 5:255; after editing and saving, the generic register action is kept and does not automatically become a motor forward/reverse action. Single-coil/switch actions use channel offset:state, with the offset added to the device base address, state 0/1, and the actual function code following that device's configuration. The legacy sub-device action editing style is still kept.

Numeric control uses visualType=number. The web editor can configure lower limit, upper limit, step, initial value, display precision, and unit; the physical panel adjusts with minus, plus, and "Execute" buttons and submits, while the web preview only demonstrates style and does not execute. Both save and execution check finite values, precision, range, step alignment, rule still enabled, allowPanelControl=true, and the binding fingerprint; after a rule is modified, the binding must be saved again.

The numeric control is not an arbitrary register/script entry. It currently only accepts controlled actions with consistent input types that explicitly use the running value: integers 50-60000 for blink/breathe period, PWM 0-65535, DAC 0-255, Modbus FC06 0-65535, display digits, and writable remote number with commandTopic configured. The FC06 action template may only be empty, $value, or a fixed register address:$value; FC05, stepper-motor actions, RAW payloads, command scripts, and arbitrary string templates are not exposed as numeric controls. Display precision and unit only affect interaction/display and do not auto-convert scaling; engineering-unit conversion should be defined explicitly in the rule or the remote protocol.

Weather is visualized with icons and cards, supporting Seniverse live weather and up to three days of forecast, and can also be configured with other HTTP(S) API addresses and field/code mappings. When permissions or fields are missing, only actual data is shown. See Weather and Remote Resources.

Optional Restart Button ​

The restart card requires both the panel allow-system-restart permission and the card confirmation option; it is scheduled only after a second confirmation on touch. When a history save fails, this ordinary panel restart is canceled for that attempt with a reason shown; the user may explicitly confirm again to continue restarting without saving history. The browser preview does not restart the device.

The panel entry's refusal of restart requests while an OTA is in progress passed local host tests and entered the canonical r7 and touch r17/r18 builds/deployments; actual operation still awaits verification — do not treat this entry check as all concurrent restart timings being accepted.

Configuration and API ​

MethodPathPurpose
GET / POST/api/screen-panel/configRead/save config; POST contains expectedRevision, config
GET/api/screen-panel/choicesPaged source/control queries supporting kind, q, page, pageSize
GET/api/screen-panel/stateCard values, quality, operation results, and applied state
GET/api/periph-exec/history?sourceRef=...Latest ten of a single source plus persistence state
GET / POST/api/periph-exec/history/configHistory switches and sourceAllowlist

Reading requires login, and config writes also require developer mode. Version conflicts return 409 — reload and handle the draft; do not overwrite another window's new config. /config/screen_panel.json uses a versioned wrapper plus the previous-generation backup; the generic file-write endpoints cannot bypass the dedicated validation.

Compiled capability is given by screenPanel, screenUi, pointHistory, and remoteResources in /api/system/capabilities. Turning off the runtime panel does not remove firmware code, nor does it stop independently-configured collection and remote sources; reducing Flash requires disabling the compile macro and rebuilding matching web assets. Touch actions are scheduled by the device-local runtime, and there is currently no generic HTTP action endpoint for the browser to directly execute cards.

Resources and Target Capabilities ​

When memory is severely insufficient, the device can pause the optional display to protect basic services. On recovery it actually restarts the screen runtime, and only a successful startup clears memorySuspended and the pause flag in the health state; a failed startup keeps the pending-recovery state and later health checks retry. Within a short recovery window, modifications, disabling, and deletion of the same display device may return SCREEN_MEMORY_RESTORE_IN_PROGRESS — retry later; do not misread this state as config loss. This fix passed local host regression, and the COM8 recovery-version log also confirmed the runtime actually recovered after a SEVERE pause; picture recovery and stability still need field confirmation.

COM8's historical driver-sync firmware once confirmed in a stable-start window the GT911 firmware 0x1060, config 0x4F, report/config size 480x480, address 0x5D, and valid checksum, with continuous polling free of read failures, ack failures, or invalid frames. The RGB cache-safe candidate 8bdeba… was later also written to COM8 and verified by readback, with the whole field filesystem (including web and configs) MD5 identical before and after; a build/deploy pass does not equal the physical jitter being fixed. That phase's pure-PnP observation did not open the serial port, and COM8/COM9 still re-enumerated frequently; the ROM output was rst:0x15 (USB_UART_CHIP_RESET). One HTTP status window showed uptime growing continuously from 277,809 ms to 319,425 ms, proving that USB enumeration change was not an application continuous-restart; but the follow-up special check then timed out and dropped after completing 11 requests. The above is only a historical troubleshooting window; the later IRAM-candidate failure, rollback, and on-demand-restart candidate progress are in the last section — the historical online state must not be carried over. Physical taps, left/right swipes, and user-visible page switches also formed no valid closure.

The regular RTS hard_reset after an RGB firmware write did not get this device out of download mode, with COM8 silent and .33 timing out at the time. Without a physical button, esptool --chip esp32s3 --port COM8 --before no-reset --after watchdog-reset read-mac was used to check MAC E8:3D:C1:F7:65:44 and exit download mode, after which it re-enumerated as COM9. This command is the recovery record for that device state — do not generalize that all USB re-enumerations are application resets, nor judge application startup success from a port-number change alone.

The feature config's planning estimate is about 80 KiB Flash and 69,632 B (about 68 KiB) RAM. The startup budget first requires at least 20 KiB of internal 8-bit DRAM — this is only the internal-memory threshold for task stacks and the backend, not the total RAM usage. The about-48 KiB snapshot/stripe buffer prefers PSRAM; without PSRAM it must obtain a full contiguous allocation in internal memory, and on failure the panel does not start and reports a memory error. Therefore F16R8 is the preferred complete target, and no-PSRAM targets must have their runtime margin verified separately even if they compile.

The above estimates are the original budgets for SPI/generic panels and cannot serve as the RGB backend's total usage. A 480x480 RGB565 single frame needs 460,800 bytes of PSRAM; the 16-line draw stripe needs another 15,360 bytes, preferably allocated to PSRAM, with the snapshot, task stacks, and LCD/DMA objects counted separately. The old about-1 KiB fill-line buffer has been removed. The generic default requests at most two 4-line internal bounce buffers, with a fallback when conditions or margin are insufficient; a historical recovery candidate actually fell back to 0. The current r19 controlled build uses two 16-line buffers totaling 30,720 B and sets 48 KiB total free and 20 KiB largest-contiguous-block admission; the weather-scheduling fix did not change the SDK or display parameters — do not write the historical bounce=0 as the current value.

The local official-repository snapshot aa604c132ef2442013ac93910c65789763329c05's Arduino_GFX example is 480x480; OPI PSRAM defaults to PCLK 12 MHz with H timing 10/8/50 and V timing 10/8/20. The example requests one PSRAM framebuffer and two 40-line internal buffers, totaling 76,800 B. FastBee r14 fell back due to actual startup memory shortage; r15's 32 lines / 61,440 B still squeezed Wi-Fi/collection memory and failed physically; r16's 16 lines / 30,720 B once restored networking and collection and was observed stable by the user for a short time. r18 kept the 16 lines and the same display parameters, but r16's physical observation cannot be migrated into the current candidate's conclusion. The RGB backend uses esp_lcd without introducing full LVGL/GFX; turning off the backlight still keeps RGB refresh and is not power-saving sleep.

TargetscreenPanelscreenUipointHistoryremoteResourcesCurrent conclusion
esp32s3-F16R8CompiledCompiledCompiledCompiledCOM15's canonical r7 was written and passed the r7 browser; touch r18 app1 was written and verified, with serial/HTTP/API and desktop/mobile full browser passing. Weather retry, physical screen, and long-term stability pending — do not carry over COM15 or r16 results
esp32c3-F4R0OffOffOffOffcanonical r7 is 3,314,576 / 3,342,336 B, 27,760 B left; COM4 was formally written and passed the matching r7 browser, keeping live collection, Modbus, PeriphExec, and ordinary web; long-term stability pending
esp32-F4R0OffOffOnOffcanonical r7 is 3,318,208 / 3,342,336 B, 24,128 B left; COM16 was formally written and verified, but the latest recheck still had no STA IP; network recovery and 24/72-hour soak pending
esp32c6-F4R0To verifyTo verifyTo verifyTo verifyKeeping the previous locally-trimmed build result; the device has been removed and this round does not rebuild or deploy

"Compiled" only means it exists in the BIN; the S3 device capability endpoints were separately verified, but that does not equal display and touch hardware acceptance. Do not claim device support based only on source macros, chip names, or the existence of web files. Capacity checks follow the actual BIN size, not just the Flash percentage in the compile output.

Acceptance Boundaries ​

Acceptance of the base firmware, web, physical display, and local collection does not depend on a weather account. Without a third-party weather key or remote devices, continue completing the base checks; weather and third-party controls are independently pending acceptance — do not fake actual data with fixed samples or simulated receipts.

Target-specific Web Archives ​

Firmware and web must use the same target-capability profile. A release audit once found that the old www directories for ESP32, C3, and S3 wrongly reused the same S3 web: the no-PSRAM ESP32/C3 thus got a normal-state request concurrency of 2/2, where their target values should have been 1/1. Filesystem write and readback verification only prove the archive was completely written, not that the archive selection was correct.

The archive tool and release gates have been fixed. Local verification confirms ESP32 F4R0 at 1/1, C3 F4R0 at 1/1, and S3 F16R8 at 2/2; the three web trees differ, and the manifests, extraction scripts, and PlatformIO profiles are consistent — the old wrong packages are rejected by the gates. After the first-round C3/ESP32-specific web preservation-config deployment, COM4 was 12/14 and COM16 had a low-memory 503/401; these are historical unpassed results. The latest matching web in the evening achieved 14/14 on COM4/COM16 — see the current status in the last section.

2026-09-19 Early Touch and Web-fix History ​

This section records the old release packages and troubleshooting process and does not represent the evening's latest firmware; current measured conclusions follow the "current deployment status" in the last section.

The early release package screen-panel-release-20260919-touch-web completed three-target firmware compilation and four-device write verification: COM8/COM15 S3 f8fc82244087b35c11c9bd96c47f3b93ffeaea31d5de702f35425bff9bbed101, COM4 C3 4594bf5fde55185f5663f703c773e4212813c1430cd9aff2fb0bdca8116488c5, COM16 ESP32 6c9d2d90ce761630846ef2c3d329b86f2024b1d42f89ca5a8fbf8fbf12b09227. All four deployment reports were written=true, verified=true, with firmware hashes matching the release package and field files outside the web directory kept; but COM4/COM16 had at the time been written with the wrongly reused S3 web, so it cannot be called "matching web deployed". The corresponding BINs are 3,851,664 / 3,342,048 / 3,315,408 bytes, with 3,488,368 / 288 / 26,928 bytes left in the partitions; C3 had only 288 bytes left, so production code should not be added casually. All of the above are whole-firmware occupancies of that stage, not panel-feature increments or the later firmware table.

This version included the TaskManager, Modbus, status JSON, WebGuard, GT911 sync/config readback, display-memory recovery, and peripheral-type catalog streaming-response fixes. Local Python totaled 567 items: 566 passed, 1 skipped due to Windows symlink permission, 0 failures; flash verification does not replace full web, low-memory recovery, or physical-screen acceptance, and the release name does not mean stability passed.

On 2026-09-19, the addresses after re-checking by MAC were COM8 192.168.5.33, COM15 192.168.5.22, COM4 192.168.5.34, COM16 192.168.5.32. The old addresses .84, .26, .23, .54 had changed. COM8 .33 once got HTTP 200 again, MAC E8:3D:C1:F7:65:44; USB serial re-enumeration is not an application continuous restart, but the follow-up 11-request check then dropped off the network, and that round's access stability did not pass. A successful health request does not mean the full web, physical touch, or smoothness passed.

Legacy archive measurements: COM15 and COM4 desktop/mobile were both 14/14 pages with API completeness 7/7 and zero HTTP, JavaScript, request, and config-write errors; logins were 7.111 seconds and 5.407 seconds respectively. Both sequential checks were 13/13 HTTP 200, health NORMAL, with resource average/max of 534.4/1,526.5 ms and 408.7/1,120.9 ms. COM15 used the correct S3 web and its conclusion is valid for that test window; COM4 used the wrongly reused S3 web and is kept only as historical physical evidence. After the first-round target C3 web deployment, sequential 13/13, three CSS complete at 24,092 B, API 6/6, and mobile 7/7 passed, but the desktop peripheral/exec pages had error placeholders, so the full browser was 12/14. COM16's first-round target ESP32 web check had one low-memory 503, then functional/MQTT status 401 and stalled at desktop 6/7. Both devices' matching webs later achieved 14/14, and the old failure results are no longer listed as pending deployment items.

COM8's historical stable-start log confirmed GT911 product 39313100, firmware 0x1060, config 0x4F, report/config size 480x480, address 0x5D, and valid checksum; touch polling had no read failures, ack failures, or invalid frames, and RGB PCLK was 6 MHz. The panel-API special passed, but the full browser test timed out. That stage's 120-second pure-PnP observation never opened the serial port; COM9's longest continuous enumeration was about 4.97 seconds and COM8's about 2.87 seconds, with 36/23 state transitions respectively; the dynamic log clearly read ESP-ROM:esp32s3-20210327 and USB_UART_CHIP_RESET. This shows the USB changes were not caused by the serial-diagnostic script opening the port that round, but the continuously growing system uptime proves the application did not keep restarting with them. The USB-enumeration root cause is still pending; coordinate events and user-visible page switches must be evidenced in the same application run window before taps and swipes can be judged as passing.

The following are the previous recovery version's historical measurements, kept for comparison and not counted as the final fixed version passing:

DeviceHistorical recovery-version measurements
COM15 / S3Recovery version: desktop/mobile 14/14 menus, 7 structural checks passed, zero JavaScript/HTTP/request errors; type-37 items complete MQTT fields, DRAM 30 KB, largest block 20 KB. Login 16.368 seconds, one page 8.227 seconds — function passed but smoothness failed; no physical screen attached
COM8 / screen S3Round 1: CSS truncated, login aborted; round 2: 18/18 menus, 7 structural checks passed, zero request errors, login 11.859 seconds, mobile peripheral page 13.933 seconds. Round 2 cannot cover the cold-load failure nor prove physical-screen interaction passing
COM4 / C3Recovery version 0cd169… flashed and passed; 8 of 14 browser runs passed with 10 low-memory/WebGuard 503s. The follow-up firmware's 14/14 pages and 13/13 sequential requests with the wrongly reused S3 web are only historical physical evidence; the C3-specific web retest was not yet done at the time and was completed in the evening. OLED software actions were previously SUCCESS; DHT11 GPIO10 obtained no real reading
COM16 / ESP32Recovery version b3fb99… flashed and passed; serial 5 requests succeeded, the full browser hit a TaskManager memory-allocation panic, and the session was then lost producing 401. Follow-up firmware fixed that panic and the type catalog, but the first test used the wrongly reused S3 web; the ESP32-specific web retest was not yet done at the time and was completed in the evening

COM8 early on once showed zero config and refused to enable touch, and once showed black screen then lit with taps/swipes unresponsive; these are kept as historical faults. That stage's firmware once recovered the controller config and polling in a stable-start window, with the application and APIs running continuously during that observation, but USB serial enumeration was unstable; display stability, touch direction/navigation, backlight, and sleep-wake still need acceptance within the same application run window with physical feedback and touch events — do not judge a pass solely from historical driver-initialization success.

COM8 once read SHT30 22.2 C / 69.9 %RH, with 10 latest points each for temperature and humidity; the earlier controlled-restart recovery check also confirmed the latest point's value, sequence, boot identifier, and history marker were correct. Continuous sampling does not guarantee observing a dirty=false gap — defer to controlled commits and post-restart data. Sudden power loss and long-term Flash wear were not covered. PM2.5/PM10 once reported MODBUS_READ_FAILED with no history points; the user confirmed PM was not connected and then changed the field slave to an address-8, 9600 Modbus stepper-motor controller. The public template has deleted the old PM mappings and no longer lists them as default pages, history sources, or pending faults.

COM8's follow-up work task stack measured a minimum of 1,456 bytes, with other samples 1,468-2,400 bytes; the old 60-byte fault is no longer a current issue. The field RGB was tested at 6, 12, and 16 MHz; the public template keeps the Arduino OPI reference of 12 MHz, and re-importing overwrites the field value. With H 10/8/50 and V 10/8/20, 6/12/16 MHz correspond to theoretical refresh rates of about 21.14/42.27/56.37 Hz. The user first reported worse left-right flicker at 16 MHz, then confirmed the 83c3985b… firmware still jittered left-right at 12 MHz; therefore a low refresh rate is not the only confirmed root cause, and raising PCLK is not an accepted fix either. The follow-up c64fb53d… candidate never completed a normal startup, cannot enter physical-display acceptance, and cannot borrow old timing or driver-runtime states as a stability conclusion. The field also disabled mDNS to save internal RAM — this is not a default requirement for all devices.

That stage's local verification included native 2364/2364, the early-release Python 567 items with 566 passed/1 skip/0 failures, the historical production service 8 tests/13 scenarios, contracts, and batched web specials. After the RGB cache-safe candidate deployment, COM15 additionally achieved desktop/mobile 14/14 and API 7/7 with zero HTTP/page/request errors, showing the same-stage S3 web did not regress. They correspond to their own evidence layers; physical functions still must be accepted with same-firmware device results. A generic first boot without a selected screen shows an empty page — the user must select a screen and use templates/layouts to produce visible content.

Among the earlier leftovers, COM4's dedicated web deployment and 14/14 menu retest were closed by the r7 records; COM16 r7 is still blocked by Wi-Fi association. COM8 r17's full web failure was closed by r18's short HTTP/API and desktop/mobile full-browser retests; r19 closed the weather-startup-retry data chain, but the current device recovery, complete styles, physical display/touch, and long-term operation are still not closed out. r16's short display observation, Seniverse weather API, and card bindings serve only as the pre-upgrade baseline; the final candidate still needs combined load, physical weather pictures, tap/swipe/navigation, layout across restarts, real remote control, and 24/72-hour long-term stability. The PM slave was not connected and the user excluded it from this round's tests; COM8's sensor is SHT30, not DHT. COM11/C6 has been removed and is not rebuilt or deployed.

The earlier 26b1de… / a5f035… results — COM15 all-menus pass, COM4 type-response truncation, COM16 MQTT 501, and COM8's 60-byte stack — are all historical stages. The current deployment status follows the next section's evening records, and historical browser results are only for comparison; do not let old successes override current pending-acceptance items, nor keep fixed old faults listed as current unfinished.

History: 2026-09-20 Diagnosis and Deployment Status ​

rgb-recovery-v1 is a historical recovery candidate that completed OTA receipt and postflight, SHA256 80b95195e2efb953e7eacf10b887f542e06ea25dd0a9b48b0ffc458a1707954b, BIN 3,865,088 B, sourceStable=true. It was once replaced by the rgb-active-cache-v1 in the next paragraph; after the r14 failure it was rolled back to again. In the r15 pre-OTA cold-power-cut baseline, the five-page revision=6, good temperature/humidity, and three HTTP 200s only proved the recovery version's short-term operation — the user still confirmed the picture automatically moved right-to-left and curled. The r16 deployment confirmed this recovery app0 was unchanged, with app1 as the current active slot.

COM8/COM9 once deployed the active-snapshot-cache candidate 29871bd27567369936526d9edb456f102dbddfeb451641809320cd218f04940c, BIN 3,858,672 B, sourceStable=true. OTA size/MD5 receipt and postflight passed, reason 3, five pages/24 cards revision=6, temperature/humidity ten points each kept, memory NORMAL. First-minute snapshot average/max 2,293/19,486 us, draw average/max 74,533/135,849 us, one layout build, stack margin 2,100 B; second-minute snapshot average 2,029 us, draw average 70,906 us. The user still reported automatic leftward sliding, horizontal and vertical curling, and unresponsive trend taps, though left/right gestures could switch pages — so display and tap acceptance failed. This candidate belongs to a historical stage and was later superseded by the post-rollback rgb-recovery-v1.

This candidate's first log-check report rgb-active-cache-v1-logging-runtime.json wrote Unexpected reboot, but actually the checker treated equal uptime in the system-state five-second cache as a failure; the four requests took only about three seconds, all 200, and the serial had no corresponding extra-restart evidence. The original report did not save before/after, so that round's exact old values cannot be claimed. The original report is kept, and the checker now waits 5.1 seconds on equal uptime; rgb-active-cache-v1-logging-runtime-cache-aware.json passed the retest with samples 165031 → 165031 → 172674, real fileLogging=true, log file present, memory NORMAL. That tool misjudgment is not a hardware restart, nor does it cover the earlier timeouts or watchdog history. Deployment evidence is in the firmware repository at artifacts/rgb-active-cache-v1-build.json, rgb-active-cache-v1-ota.json, rgb-active-cache-v1-postflight.json, rgb-active-cache-v1-usb.log.

The same-version browser panel special passed preview and appending a sixth page to the draft, with the save still five pages, zero writes, and zero page errors — see rgb-active-cache-v1-panel-browser/report.json; it does not cover the physical curling or trend-tap failures. In the three devices' latest full-menu reports, COM15 and COM4's 14/14 menus and the whole item passed; COM16 opened all 14 menus but the first-session endpoint still returned a low-memory 503, so the whole item failed — see active-cache-fleet-COM16-menus/report.json. Then the four devices' read-only latency baseline at current addresses completed 13/13 HTTP 200, with max requests about COM15 1.03 s, COM9 1.01 s, COM4 1.08 s, COM16 1.62 s; this is only short sequential reading — it does not rewrite the earlier browser failures as passes, nor mean the final version is deployed or long-term stable.

The previously running worker-diagnosis was eb4c6a49ee619407c32c6b5e6845f56228617408a71d4905306f0e0762b358a2, BIN 3,855,280 B. The build succeeded, sourceStable=true, OTA was HTTP 200, written=true, verified=true, with matching size and MD5. It kept FastBee's other background tasks and compared 90-second segments: A pauses snapshot/draw after the initial picture, B resumes snapshot only, C resumes snapshot/draw; A/B/C paused touch and restored the original page title and touch after 270 seconds. The serial recorded four switches at 0 / 90,010 / 180,005 / 270,013 ms.

The user reported by segment: A's picture was fixed but the right-side content rolled to the left end; B with snapshot-only still gradually slid right-to-left and curled; C's top content rolled to the bottom with horizontal curling. The old diagnosis only changed the page-title field while the renderer at the time did not display titles, so the screen actually had no A/B/C labels; the segments were confirmed by serial timing — do not write that the user judged by visible segment labels, and the NORMAL physical state was not separately reported. A is not normal display, and all three segments failed; specific feedback and limits are in artifacts/rgb-worker-isolation-v1-observation.json. The post-diagnosis 10 HTTP requests passed, with normal reason 3, five pages/24 cards revision=6 and temperature/humidity ten points each kept, memory NORMAL — this cannot cover the physical failures.

NORMAL only means the diagnostic firmware internally resumes ordinary operation and does not switch back to the original firmware; every restart or screen-runtime rebuild reruns A/B/C. The title is only temporarily overwritten in memory, and the layout was not written to disk because of segment titles. The source later added explicit A/B/C banners and passed local pixel-change and recovery tests; the code has been deployed with the current normal firmware, but FASTBEE_SCREEN_WORKER_ISOLATION stays off, so no banner is shown and the three segments do not rerun. Historical diagnostics cannot serve as current physical acceptance. Evidence is in the firmware repository at artifacts/rgb-worker-isolation-v1-build.json, rgb-worker-isolation-v1-ota.json, rgb-worker-isolation-v1-usb.log, rgb-worker-isolation-v1-postflight.json; the per-segment pictures come from this round's user feedback.

In the earlier file-logging isolation experiment, actually disabling fileLogging / logViewer and restarting made the user report only a slight jitter improvement with bottom content moving to the top. The layout did not change, and the experiment did not fix the problem. The recovery report's false field was the pre-modification state, not the final value; follow-up startup logs and feature flags confirmed re-enabling, and rgb-worker-isolation-v1-logging-runtime-retry.json passed by actually reading enabled=true, fileLogging=true via /api/logs/info, with the log file present and memory NORMAL. The first rgb-worker-isolation-v1-logging-runtime.json timed out after a 200 status request with passed=false and is independently preserved — it cannot be overwritten by the retry success. Other evidence is artifacts/panel-log-isolation-v1-check.json, panel-log-isolation-v1-observation.json, panel-log-isolation-v1-restore.json.

The active-page snapshot and draw optimizations were included in the cache candidate at the start of this section, reducing snapshot/comparison work and skipping lines, circles, and cards meeting the height condition that do not intersect the current stripe. Local font-raster 1 item, lifecycle 9 items, isolation-policy 2 items, and new pixel comparisons 6 items passed; the new tests use the real production renderer/U8g2 and compare pixel-by-pixel the full frame, 1/7/16/31-line stripes, and the uncropped baseline, covering components, card heights, rotation, out-of-bounds, last lines, and confirmation boxes. These prove the host rendering results stay consistent; the physical curling is still unsolved.

The following is the September 19 normal-firmware and standalone-display-comparison history. The 23:20 COM8 firmware was 7ae21b566a7e95903cafd4a033c78f378306c50670501d30b42365662e7c8b75. It only added an OTA-queued-response protection over the previous candidate, keeping the RGB on-demand-restart display policy, 12 MHz, single PSRAM framebuffer, and bounce=0. The new route completed the OTA again with the same hash, HTTP 200, size 3,853,856 B, MD5 e51c21ea2395fc71a98a123b0f348e68 matching the uploaded file, taking 44.434 seconds and reporting written=true, verified=true. What was confirmed is the OTA receipt and startup — no complete Flash readback or full-filesystem MD5 comparison was done.

The user then clearly reported this firmware still jittered left-right, and current physical-display acceptance has not passed; disabling the per-frame unconditional DMA restart did not solve the problem. From 23:54 to 23:58, a standalone static-display diagnosis was completed under the same SDK, 12 MHz, initialization, and pins: direct-PSRAM and dual-40-line internal-SRAM buffers each ran for 90 seconds, and the user reported "completely stable" for both phases. After the test automatically returned to the original firmware, the five-page revision 6, temperature/humidity ten points each, and web recovery were verified, and the user then reported "still jittering left-right". The focus therefore shifts to screen computation and background storage load in the full firmware; the specific trigger still needs grouped verification — do not conclude a specific task or hardware damage from this comparison alone.

The standalone diagnosis does not start FastBee's snapshot, network, collection, or file writes; its 40-line dual buffer needs 76,800 B of internal memory and cannot be copied directly into the full firmware with only about 26-32 KiB of internal margin. The result also does not prove the buffering approach is safe under Flash writes, network load, or long-term operation. Diagnosis, recovery, and user observation are recorded separately in the firmware repository at artifacts/rgb-isolation-v1-*.json and serial logs; it is currently not marked as a completed display fix.

The post-upgrade check passed=true, all 10 HTTP requests were 200, diagnosed as a normal Software restart (ESP.restart), reason 3, and OTA firmware upload completed, with no extra application startup loop; the five-pages/24-cards revision=6 content was the same as before the upgrade, SHT30 temperature/humidity had 10 points each, and memory was NORMAL. The panel-browser preview and unsaved-draft page-append tests passed with zero config writes and zero page errors. Evidence is in the firmware repository at artifacts/rgb-demand-uploadfix-com8-ota-confirmed.json, rgb-demand-uploadfix-com8-postflight-confirmed.json, rgb-demand-uploadfix-com8-panel-browser/report.json. The user then confirmed this firmware still jittered, and taps/swipes formed no same-version physical closure — do not claim a fix or a 24/72-hour long-term pass based on this.

A subsequent 120-second serial observation saw no Boot, panic, extra reboot, or SEVERE/CRITICAL, and SHT30 collection succeeded continuously; internal-free samples were 31,924 B and the largest block 18,420 B, with the lowest heap in that boot cycle at 15,228 B. GT911 polling grew from 7,398 to 11,126, readFail=1 did not grow, and press/release were both 0 — so there is no physical-touch verification result for this candidate. During panel preview memory was NORMAL with internal free 27,480 B and largest block 18,420 B; the final sequential HTTP 5/5 were 200, max 1,043.2 ms. Evidence is in the firmware repository at artifacts/rgb-demand-uploadfix-com9-final-runtime.log, rgb-demand-uploadfix-com8-http-final.json, and represents only this short window.

The current NTP was not in a normal sync state: the log recorded 10 consecutive sync failures entering a 30-minute cooldown. The clock card should show unsynced, and history points use the boot identifier, sequence, and uptime without posing as absolute time; clock-display acceptance must wait until real time sync recovers. Early NTP success records are kept only as history and do not cover this failure.

The first attempt's rgb-demand-uploadfix-com8-ota.json was canceled after a connection drop, with no OTA-success event; the follow-up paced upload then got an HTTP 400 from the old-route override, but the serial actually completed the OTA. After the first paced upgrade there was one reason-7 Other Watchdog reset, and rgb-demand-uploadfix-com8-postflight.json was passed=false; these failure records are kept and the causes still need investigation. The second same-hash OTA's normal reason 3 and successful checks cannot cover that failure, nor do they mean it cannot recur. A network OTA updates the OTA partition selection; subsequent serial deployments must re-verify the active partition — do not assume app0 and write 0x10000 directly.

The following keeps the 23:03-23:07 history of the previous d2994581… candidate: the serial recorded ota_success, the OTA-planned restart, and a complete initialization; the runtime endpoint sketchSize=3853856 matched the uploaded candidate, and the diagnosis lastRestartContext was OTA firmware upload completed. The post-deployment check passed=true, all 10 HTTP requests were 200, uptime grew, and memory was NORMAL; the five-page revision=5 config at the time was exactly the same as before the upgrade, with SHT30 at 22.7 C / 70.2 %RH and ten points each for temperature/humidity. Evidence is in the firmware repository at artifacts/rgb-demand-netfix-com8-postflight.json and rgb-demand-netfix-com9-runtime.log, and does not replace the current firmware or physical-screen acceptance.

From 23:05 to 23:07, the same firmware's desktop/mobile real-browser menus were 18/18 with 6 API-completeness items passing and zero HTTP, page-script, and request errors; the full login flow was 5,999 ms, pages 1,128-2,646 ms, the latter including a 1-second wait and screenshot. The panel API passed 19 requests covering auth, parameter validation, same-layout save, and the conflict 409; the same-layout save bumped the version from 5 to 6 without changing the config content. The current five-page config is revision=6. Evidence is in the firmware repository at artifacts/rgb-demand-netfix-com8-all-menus/report.json and rgb-demand-netfix-com8-api.json, and remains short-term web/API results.

That HTTP upload receipt was never received, and the original rgb-demand-netfix-com8-ota.json still keeps written=false, verified=false; the post-deployment report cross-confirmed via the serial success event, restart, normal startup, and the running image size, explicitly httpMd5ReceiptVerified=false. That round has no HTTP MD5-receipt or complete Flash-readback evidence, and the old filesystem MD5 is not carried over as that OTA's verification. The missing receipt was located to the client's multipart end-boundary and the server's completion-response handling; it was fixed and verified by the 7ae21b… same-hash OTA at the start of this section, but the old failure report cannot be rewritten as a pass, and physical-screen stability remains independently pending.

Before the upgrade, the user clearly stated the jitter interval was irregular, sometimes fast, sometimes slow. After temporarily switching to a "Display Stability Test" static home page, jitter was still observed; after the test, the original five pages and 24 cards were restored to revision=5 with no leftover test home page. This result cannot establish the 0.5-second snapshot polling, clock/uptime text, or dynamic-card repaints as the confirmed root cause, nor can it rule out the still-running background collection, snapshot, and bus load.

This round's first candidate b40e18c5d19a4969e12a99f2510dc277ba13d5af514c79a1740dc1a4858dfb7b only changed the RGB driver's restart policy: enabling FASTBEE_RGB_RESTART_ON_DEMAND=1 in the S3 F16R8 environment, disabling the per-VSYNC forced GDMA restart, keeping 12 MHz, single PSRAM framebuffer, bounce=0, the original IRQ/cache config, GDMA/HAL placement, and the original linker script; the follow-up d2994581… inherited this display change. A comment in the matching-version SDK notes that a late VSYNC restart may itself cause single-frame misalignment — that is the hypothesis under test. A real EDMA underrun may still cause persistent misalignment and must be verified with the physical screen plus web/Flash load; do not treat the policy change as a confirmed root cause.

That candidate built locally, BIN 3,853,744 B, sourceStable=true; 10 targeted tests (including 8 groups of real Xtensa C compilation/symbol/macro combinations) and the ELF/link-map review passed. The 22:48 OTA verified device identity and a successful begin, but the upload reported fetch failed and was then canceled, reporting written=false, verified=false; that round's upload and verification were not completed — it cannot be recorded as the candidate deployed or the physical screen solved, nor can a failure label alone prove nothing was written to the backup partition. The last firmware confirmed to boot normally that round was still 83c3985b…, and physical-display acceptance had not passed. Evidence is in the firmware repository at artifacts/panel-jitter-original-layout.json, panel-jitter-static-applied.json, panel-jitter-layout-restored.json, rgb-demand-candidate-build.json, rgb-demand-candidate-build.log, rgb-demand-candidate-release/firmware.map, rgb-demand-com8-ota.json; the pre-OTA layout was saved separately as rgb-demand-com8-layout-before.json.

The first-round OTA-interrupt log showed No HTTP requests for 4294967s after ota_start and reclaimed the connection. Source inspection located the cause: the maintenance loop subtracted the asynchronously-updated new-request timestamp from a stale clock value, causing an unsigned underflow that wrongly reclaimed active HTTP/OTA connections. The fix reads the request timestamp first and then the current clock, with a re-check before reclaiming; this network fix does not equal the physical-jitter root cause being determined. The merged-fix rgb-demand-netfix candidate d2994581bb2bf62d012ed004ad5b807a5026f4140523f08e3d368e080715ee08 built successfully at 22:57, BIN 3,853,856 B, sourceStable=true; the follow-up normal-startup OTA evidence is kept in this section, and that stage did not complete physical-display acceptance. Build evidence is in the firmware repository at artifacts/rgb-demand-com9-runtime.log, rgb-demand-netfix-build.json, and rgb-demand-netfix-build.log.

At 22:52, the other three devices' additional read-only checks were each 5/5 HTTP 200 with health NORMAL: COM15 .22 max 1,149 ms, COM4 .34 max 1,018.7 ms, COM16 .32 max 1,751.6 ms. Corresponding artifacts/rgb-demand-peer-COM15-latency.json, rgb-demand-peer-COM4-latency.json, rgb-demand-peer-COM16-latency.json. Short read passes do not exclude transient pressure between requests, nor do they equal long-term stability.

The following is the 22:11-22:20 IRAM experiment and rollback history. COM8's RGB IRAM candidate c64fb53d3ccc6e688978e4f6226394ad4bc7b8667e83240abd439dab98edf8c5 completed a firmware-only write and readback verification, but repeatedly showed Power-on reset in startup logs, never reaching display initialization, and .33 /api/health timed out. The first rollback was not written due to the serial port disappearing; the 22:20 rollback retry of 83c3985b… then succeeded, written=true, verified=true. The reset-reason label alone cannot determine the power supply or other hardware root cause.

The rollback kept the whole filesystem MD5 unchanged; after the watchdog reset, .33 read-only HTTP passed 5/5 with a max of 1,283 ms; a 55-second serial observation saw no panic/restart logs, and SHT30 read 22.7 C / 70.6-70.7 %RH. GT911 polled 2,459 times with 1 press and 1 release, and read-fail/ack-fail/invalid-frame were all 0. The browser panel preview passed with the saved page count of 5, and the unsaved-draft page-append test passed with no config writes or page errors; memory NORMAL, internal free 28,196 B, largest block 16,372 B. These confirm that stage's startup, web, and collection recovery — they do not represent physical jitter or touch-navigation passing; the follow-up static-page physical failure is recorded at the start of this section.

The IRAM candidate's compilation, IRAM/DRAM linking, and disassembly review passed — this is only pre-deployment evidence and does not represent startup or flicker-fix passing. The whole field filesystem MD5 before and after that serial update and rollback was f3e9da3a4248464a6f64d70b8247549c; web, configs, and boot/partition/NVS/OTA/PHY regions were not replaced by that firmware update; this does not apply to later network upgrades that update the OTA selection. COM15 kept 83c3985b4dec2a5b31df309a752dd18a265d2f6dc6151fdce44619f728cb685f and the matching S3 web; the other three devices' existing pass windows are unaffected by this COM8 candidate.

The RGB ISR-replacement experiment is now isolated in the source behind FASTBEE_RGB_ISR_IRAM_OVERRIDE defaulting to 0; the wrapper/hook must be explicitly set to 1 to enable, and 8 local isolation tests passed. The original c64fb53d… candidate archive is kept unchanged, and the device was restored to 83c3985b… via the actual rollback above — do not conflate source-level isolation with device deployment. The other three devices' additional read-only HTTP checks were all 5/5, with COM15 .22, COM4 .34, and COM16 .32 max request times of about 1.07, 0.89, and 1.43 seconds respectively — they cannot be extended into long-term-stability conclusions.

Historical device and address (not current access addresses)2026-09-20 deployment and measurements
COM15 / S3, 192.168.5.22canonical r8 and matching web formally written and verified; strict browser desktop/mobile 14 pages, 1,594 main-stylesheet rules readable, zero failures and zero writes; long-term stability per independent acceptance records
COM8 touch S3, 192.168.5.33r19 app1 and matching r8 web written and verified; 5/5 HTTP, 24/24 menus, revision 9 weather/system previews, NTP/SHT30/weather/ten-point history, and 26/26 rule bindings passed. The user still reported black-screen recovery and edge-curl/drift — physical display/touch/buzzer, combined load, and long-term stability pending
COM4 / C3, 192.168.5.34canonical r7 and matching web formally written and verified; strict browser desktop/mobile 14 pages, 1,594 main-stylesheet rules readable, zero failures and zero writes; long-term stability pending
COM16 / ESP32, 192.168.5.32 (diagnostic window)canonical r7 and matching web formally written and verified; the full-menu window rendered but had a low-memory 503 — cannot be listed as a smooth pass; needs resource diagnosis and long-term retest

COM8's address-8, 9600, 8-N-1 protocol, four single-register read tasks, collection rules, and forward/reverse/stop fixed-register rules have been saved via the formal API. All motor collection/control rules remain disabled, the control rules are not authorized for panel invocation, and no motion or parameter-modification commands were sent; with the hardware disconnected, to-be-collected placeholders are used and no fake data is shown. The public Rev4 template has deleted the old PM rules and tasks; PM is no longer a default page or this round's acceptance item. The Seniverse weather API and card bindings passed read-only joint debugging; physical weather visuals, a custom second JSON, abnormal paths, and remote switches/scenes still need independent acceptance.

The current strict-browser evidence for .22 and .34 is r8-COM15-web-styles/report.json and r7-COM4-web-styles/report.json; COM16's current diagnosis is r7-COM16-network-recheck-90s.json. COM8's current evidence includes r18's full short web pass, plus r19 build/deploy, weather-data pass, first-round browser content-length mismatch, missing styles in the functional retest, two r8 web-write connection failures, and still no serial data after a hard reset — these results must all be kept. The earlier r17-before-*, active-cache-fleet-*, panel-cache-preflight-*, and rgb-isolation-preflight-* are kept as history. Any short-term state does not prove no transient pressure between requests or long-term stability. COM11 C6 has been removed and is not included in the four devices this round.

COM8's standalone display, file-logging, and A/B/C grouping records belong to the pre-r16 fault-location history; the user observed r16 stable for a short time, but that cannot be migrated into r18/r19 physical conclusions. r18 closed r17's short web failure, and r19 fixed weather cold-start but the first-round browser again exposed intermittent content-length mismatch; taps/swipes and web/collection/history-write/config-save/Flash-activity load still need verification, keeping the first post-upgrade watchdog reset and USB observations, and completing 24/72-hour stability. The historical 16 MHz debug value is not the current config, and about 0.5 seconds is not a proven fixed fault period.

COM16's 180-second serial observation saw no panic or restart, with final internal free 25,208 B and largest block 13,300 B. During the window one SEVERE memory protection occurred and paused the PeriphExec workers/timers; recovery then completed, with the HTTP health state NORMAL, degraded=false, periphExecPaused=false, periphExecWorkerSuspended=false. This round therefore verified page access and one protection recovery; it does not prove there is never degradation under concurrent load.

The corresponding evidence is archived in the firmware repository artifacts: panel-general-com15-deploy.json, panel-general-com15-menus/report.json, panel-general-com8-deployment.json, panel-general-com8-api.json, panel-general-com4-web-deploy-20260919.json, panel-general-com4-web-menus-cancellation-20260919/report.json, panel-general-com4-web-latency-20260919.json, panel-general-com16-summary.json. Candidate-failure history is in rgb-iram-candidate-build.json, rgb-iram-link-audit.md, rgb-iram-com8-deployment.json, rgb-iram-com9-runtime.log, rgb-iram-com8-http-retry.json, rgb-iram-com8-rollback.json; the latest successful rollback and retests are in rgb-iram-com8-rollback-retry.json, rgb-iram-rollback-http.json, rgb-iram-rollback-runtime.log, rgb-iram-rollback-panel-browser/report.json. These are deployment and short-term evidence and do not represent 24/72-hour long-term stability; physical display/touch, real third-party services, and abnormal power-loss recovery still need separate acceptance.

Items Not Yet Closed ​

As of 2026-09-22, the whole extension plan cannot be marked complete. Touchscreen priority: COM8's r6 application and matching new web have been deployed; the same-version HTTP/menus, temperature/humidity consistency/strict freshness, restart ten-point recovery, and display-load rechecks still need completing. COM16 r4 still has resource timeouts and continues to be handled; the COM15/C3 new-web short-test passes still cannot replace long-term stability. All four devices' independent 24 hours are unfinished, and 72 hours is also unfinished. Physical display/touch and real business still need the closure evidence below; historical short-term successes of old versions do not replace final-version acceptance.

  • Physical interaction: direction/edges, brightness/sleep, wake-first-touch, 1,000 swipes without false actions; restart confirm, cancel, dedup, flush-failure, and OTA-busy feedback.
  • Generic numeric input has completed code, targeted, and final regressions and entered the canonical r7 and touch r17/r18/r19 builds/deployments; physical-screen operation acceptance is still needed, with at least two register tables proving pure-config reuse. Auto-scaling conversion, arbitrary RAW/scripts, or stepper-motor field-parameter input are currently not supported.
  • Real services: 13.584 seconds after the r19 cold start, Seniverse weather automatically recovered to ready — Beijing cloudy 26 °C — with NTP, SHT30, and both ten-point histories good; no credentials were re-injected or manually tested. Physical weather icons/text/layout still need visual acceptance, plus a second JSON, abnormal/throttled/offline paths, and log non-echoing. At least one remote switch and one scene still need the touch/readback closure; offline and unsynced degradation are still pending. PM is not accepted, and the disconnected motor is not trial-run.
  • Generic configuration and binding: two logical sizes/orientations, desktop and 360/390px narrow screens, template changes keeping bindings, drag/undo, re-login, import/export, and conflict drafts; value/status/unit and ten-point boundaries are rechecked in the final version.
  • Storage and compatibility: sudden power loss, sustained-write recovery, collection/exec preserved with the panel off, legacy peripheral/U8g2/Device Dashboard compatibility; the current COM4 DHT11 real readings are also not closed.
  • Release and resources: bin/map/web before and after the same-baseline toggle, internal RAM/PSRAM/contiguous-block/stack/queue and solid/gradient costs; COM16 has recovered Wi-Fi and obtained a new address, but the full browser still has low-memory 503s — the final normal firmware needs the four-device full web/OTA/memory regression, at least 24 hours of mixed load, and the pre-release 72-hour verification.

The item-by-item GP-01-GP-19 audit is saved in the firmware repository at artifacts/panel-plan-acceptance-audit-20260920.md. CAN drivers, additional controllers, arbitrary script-style UIs, a full chart editor, a long-term database, and the old dedicated-board plan's RTC/SD/battery are outside the current generic-panel core acceptance.

FastBee | fastbee.cn