Record ten-profile variant consolidation qualification

This commit is contained in:
mikecarper committed 2026-10-18 20:46:43 -07:00
1 parent 5df3e4ae53
commit 515bb57cdf
4 files changed
+336

No files matched your search

+3
View File
@@ -356,6 +356,9 @@ verified canonical image can therefore replace the matching SuperIO or
non-shell recommendation. These accessory choices do not change the radio
hardware selection. See [optional screens](optional_screens.md).
The [variant consolidation validation](test-results/firmware_variant_consolidation.md)
records the qualified package hashes, controls checks and pending hardware tests.
Ordinary non-OTA roles also use one artifact for normal operation and USB
logging. On ESP32 1.17.1.5, run `set powersaving off` before `set usb.logging on`.
Select the saved mode with `set usb.logging off|on`; no `-logging-`
+4
View File
@@ -41,6 +41,10 @@ and `270`, including portrait/landscape dashboard changes without reflashing.
The stock R8 expansion board has no accelerometer for automatic orientation.
See the [rotation commands](cli_commands.md#set-display-rotation).
The [variant consolidation validation](test-results/firmware_variant_consolidation.md)
records the ten qualified packages, software checks and remaining physical tests
for R8 rotation, Muzi SuperIO and T-Echo Lite detection.
Full Wireless Tracker repeaters retain the board's 50-neighbor capacity, as
the V1.1 and V2 Full profiles already do. This preserves RAM for the screen,
GPS, MQTT and update services; the RAM admission limits remain unchanged.
@@ -0,0 +1,260 @@
{
"complete": true,
"profiles": [
{
"application_bytes": 902956,
"application_sha256": "246b07c54f5c76c9b6d1f8fc30ad4de34d74ae182a3e06822a14bd3b1293371e",
"available_internal_bytes": 75948,
"embedded_version": "v1.18.0.1-variants-b31d942b",
"files": {
"PicoW_companion_radio-v1.18.0.1-variants-b31d942b.bin": "246b07c54f5c76c9b6d1f8fc30ad4de34d74ae182a3e06822a14bd3b1293371e",
"PicoW_companion_radio-v1.18.0.1-variants-b31d942b.uf2": "71bb65c155bbaeeef069e9d6c5d89bfd0bfd19a918a46b8750b20ceea11f08d2"
},
"logical_target": "PicoW_companion_radio",
"markers": {
"companion.picow.combined": "meshcore.capability.companion.picow.combined.v1"
},
"ram_margin_bytes": 58540,
"required_heap_bytes": 17408,
"target": "PicoW_companion_radio",
"uf2_end": "0x100dc800",
"uf2_start": "0x10000000"
},
{
"application_bytes": 2287528,
"application_sha256": "19170cc8866b7bab7a66162513cb27e263275d71296e39cd7cdf6205c62dd148",
"available_internal_bytes": 231424,
"embedded_version": "v1.18.0.1-variants-b31d942b",
"files": {
"heltec_v4_r8_tft_companion_radio_full-v1.18.0.1-variants-b31d942b-merged.bin": "e41321b5bfe352cd06c383aa5d078dbdfa486466e1d2e581d7a56ebb98fd7cbb",
"heltec_v4_r8_tft_companion_radio_full-v1.18.0.1-variants-b31d942b.bin": "19170cc8866b7bab7a66162513cb27e263275d71296e39cd7cdf6205c62dd148"
},
"hardware": "heltec_v4_r8_tft",
"logical_target": "heltec_v4_r8_tft_companion_radio_full",
"markers": {
"display.autodetect": "meshcore.capability.display.autodetect.heltec_r8.v1",
"display.rotation.runtime": "meshcore.capability.display.rotation.heltec_r8.v1"
},
"ota_target": "0x0",
"ram_margin_bytes": 66528,
"required_heap_bytes": 164896,
"target": "heltec_v4_r8_tft_companion_radio_full"
},
{
"application_bytes": 2297368,
"application_sha256": "0837183ff0835e8c4c9d7893ae7cada540a6ed40f1e0c692c7dfc47e1ed611f1",
"available_internal_bytes": 202120,
"embedded_version": "v1.18.0.1-variants-observer-b31d942b",
"files": {
"heltec_v4_r8_tft_repeater_observer_mqtt-full-usb-wifi-ota-v1.18.0.1-variants-b31d942b-merged.bin": "c36b2b75fb6bfb1899c76986ce290d27357e1a2efe0c096341d0feecc7afc268",
"heltec_v4_r8_tft_repeater_observer_mqtt-full-usb-wifi-ota-v1.18.0.1-variants-b31d942b.bin": "0837183ff0835e8c4c9d7893ae7cada540a6ed40f1e0c692c7dfc47e1ed611f1"
},
"hardware": "heltec_v4_r8_tft",
"logical_target": "heltec_v4_r8_tft_repeater_observer_mqtt",
"markers": {
"display.autodetect": "meshcore.capability.display.autodetect.heltec_r8.v1",
"display.rotation.runtime": "meshcore.capability.display.rotation.heltec_r8.v1"
},
"ota_target": "0xdd39457b",
"ram_margin_bytes": 5736,
"required_heap_bytes": 196384,
"target": "heltec_v4_r8_tft_repeater"
},
{
"application_bytes": 2302648,
"application_sha256": "28ffdb3bd325ae4d9d4f513007de833bb9aeaf2543399aca2dd57e5ff8bff26f",
"available_internal_bytes": 197656,
"embedded_version": "v1.18.0.1-variants-observer-b31d942b",
"files": {
"heltec_v4_r8_tft_room_server_observer_mqtt-full-usb-wifi-ota-v1.18.0.1-variants-b31d942b-merged.bin": "9d0a42c13fa53153301e5c96c4825ba7bca08851787a112c96bfedc5b6fbfd08",
"heltec_v4_r8_tft_room_server_observer_mqtt-full-usb-wifi-ota-v1.18.0.1-variants-b31d942b.bin": "28ffdb3bd325ae4d9d4f513007de833bb9aeaf2543399aca2dd57e5ff8bff26f"
},
"hardware": "heltec_v4_r8_tft",
"logical_target": "heltec_v4_r8_tft_room_server_observer_mqtt",
"markers": {
"display.autodetect": "meshcore.capability.display.autodetect.heltec_r8.v1",
"display.rotation.runtime": "meshcore.capability.display.rotation.heltec_r8.v1"
},
"ota_target": "0x1d1c0d92",
"ram_margin_bytes": 7784,
"required_heap_bytes": 189872,
"target": "heltec_v4_r8_tft_room_server"
},
{
"application_bytes": 1590952,
"application_sha256": "064c4c98d2b6c20d366c2c5fc2a63dce2b6590dd6c70e9b112a1f17984bd3844",
"available_internal_bytes": 273872,
"embedded_version": "v1.18.0.1-variants-b31d942b",
"files": {
"heltec_v4_r8_tft_sensor-full-ota-v1.18.0.1-variants-b31d942b-merged.bin": "c8e154a76fe7a2960c18a6ddd3b34ea877c74f7e0936b48b6b2fa99a1a431bc0",
"heltec_v4_r8_tft_sensor-full-ota-v1.18.0.1-variants-b31d942b.bin": "064c4c98d2b6c20d366c2c5fc2a63dce2b6590dd6c70e9b112a1f17984bd3844"
},
"hardware": "heltec_v4_r8_tft",
"logical_target": "heltec_v4_r8_tft_sensor",
"markers": {
"display.autodetect": "meshcore.capability.display.autodetect.heltec_r8.v1",
"display.rotation.runtime": "meshcore.capability.display.rotation.heltec_r8.v1"
},
"ota_target": "0x5fc52bcb",
"ram_margin_bytes": 131472,
"required_heap_bytes": 142400,
"target": "heltec_v4_r8_tft_sensor"
},
{
"application_bytes": 2283496,
"application_sha256": "73ec156914e8f1302f42fddba02478951c3d0fd7a03cdb0d2ecff310bad02543",
"available_internal_bytes": 204336,
"embedded_version": "v1.18.0.1-variants-observer-b31d942b",
"files": {
"heltec_v4_repeater_observer_mqtt-full-usb-wifi-ota-v1.18.0.1-variants-b31d942b-merged.bin": "f4cce7eec6b06f0346cb904ec03f5728e023248eca226b946f536a93a86800e6",
"heltec_v4_repeater_observer_mqtt-full-usb-wifi-ota-v1.18.0.1-variants-b31d942b.bin": "73ec156914e8f1302f42fddba02478951c3d0fd7a03cdb0d2ecff310bad02543"
},
"hardware": "heltec_v4",
"logical_target": "heltec_v4_repeater_observer_mqtt",
"markers": {
"hardware.heltec_v4.oled_kit": "meshcore.capability.hardware.heltec_v4.oled_kit.v1"
},
"ota_target": "0xab74db9e",
"ram_margin_bytes": 5904,
"required_heap_bytes": 198432,
"target": "heltec_v4_repeater"
},
{
"application_bytes": 2281768,
"application_sha256": "85c2dcaa00e8b1fad223454328f855fc25b42498f335752bdd7850b19f27cb6e",
"available_internal_bytes": 233072,
"embedded_version": "v1.18.0.1-variants-b31d942b",
"files": {
"heltec_v4_tft_companion_radio_full_femon-v1.18.0.1-variants-b31d942b-merged.bin": "94ad5d1481a36714dbe7e39da15c8128b5c423ff3abcc8da4b25eb441329a088",
"heltec_v4_tft_companion_radio_full_femon-v1.18.0.1-variants-b31d942b.bin": "85c2dcaa00e8b1fad223454328f855fc25b42498f335752bdd7850b19f27cb6e"
},
"hardware": "heltec_v4_tft",
"logical_target": "heltec_v4_tft_companion_radio_full_femon",
"markers": {
"hardware.heltec_v4.tft_kit": "meshcore.capability.hardware.heltec_v4.tft_kit.v1"
},
"ota_target": "0x0",
"ram_margin_bytes": 68176,
"required_heap_bytes": 164896,
"target": "heltec_v4_tft_companion_radio_full_femon"
},
{
"application_bytes": 580640,
"application_sha256": "0d9fbe41f3eda4c1639ef0af36eff35d4f83779c7749c6aaf1bb89eab2daec16",
"available_internal_bytes": 89856,
"embedded_version": "v1.18.0.1-variants-b31d942b",
"files": {
"muzi_base_uno_companion_radio_full-v1.18.0.1-variants-b31d942b.uf2": "0860679f11b6c5d765a3075e6d45f685a35d88de299a16faa43659f7ff9c50f9",
"muzi_base_uno_companion_radio_full-v1.18.0.1-variants-b31d942b.zip": "5c649ab442a34b4e08f3cdbe57577132f279dc85c790517f7759915003729bb3"
},
"hardware": "muzi_base_uno",
"logical_target": "muzi_base_uno_companion_radio_full",
"markers": {
"display.autodetect": "meshcore.capability.display.autodetect.muzi_superio.v1"
},
"ota_target": "0x0",
"ram_margin_bytes": 32704,
"required_heap_bytes": 57152,
"target": "muzi_base_uno_companion_radio_full",
"uf2_end": "0xb3d00",
"uf2_start": "0x26000"
},
{
"application_bytes": 571792,
"application_sha256": "d5970c20227fe1b0de5ebe32abb31612609cec404e0fd818f49967a1906cd6fe",
"available_internal_bytes": 89936,
"embedded_version": "v1.18.0.1-variants-b31d942b",
"files": {
"muzi_base_duo_companion_radio_full-v1.18.0.1-variants-b31d942b.uf2": "ae9c52c008691e00e3790b39cbde8b58b8040dfc09b4e69fe1a71394276be126",
"muzi_base_duo_companion_radio_full-v1.18.0.1-variants-b31d942b.zip": "f4fa59ef3f403f609cef8dda521442d3363bd43ebbef3d11cea9cc3a8e79a7c5"
},
"hardware": "muzi_base_duo",
"logical_target": "muzi_base_duo_companion_radio_full",
"markers": {
"display.autodetect": "meshcore.capability.display.autodetect.muzi_superio.v1"
},
"ota_target": "0x0",
"ram_margin_bytes": 32784,
"required_heap_bytes": 57152,
"target": "muzi_base_duo_companion_radio_full",
"uf2_end": "0xb1a00",
"uf2_start": "0x26000"
},
{
"application_bytes": 595896,
"application_sha256": "91495097a5249ae422381642f9add59d881e8d5a25bb38886d461053cd78a7c8",
"available_internal_bytes": 81984,
"embedded_version": "v1.18.0.1-variants-b31d942b",
"files": {
"LilyGo_T-Echo-Lite_companion_radio_full-v1.18.0.1-variants-b31d942b.uf2": "ab7782e28dcb5db35b0eff64cd45a217c9c5546ba078874b4a3f0fc1f1a31eed",
"LilyGo_T-Echo-Lite_companion_radio_full-v1.18.0.1-variants-b31d942b.zip": "8338d5a1efa4c00118922e5039a66a2e5684f6bf9d25ded5986dfa5cf507e20a"
},
"hardware": "LilyGo_T-Echo-Lite",
"logical_target": "LilyGo_T-Echo-Lite_companion_radio_full",
"markers": {
"display.autodetect": "meshcore.capability.display.autodetect.techo_lite.v1"
},
"ota_target": "0x0",
"ram_margin_bytes": 28928,
"required_heap_bytes": 53056,
"target": "LilyGo_T-Echo-Lite_companion_radio_full",
"uf2_end": "0xb7800",
"uf2_start": "0x26000"
}
],
"schema_version": 1,
"scope": "Local packaged-firmware qualification and actual-package picker replay; physical hardware tests pending.",
"source": "b31d942b231360386fdfb92d0561f36095fdf011",
"validation": {
"native_suites": {
"test_heltec_r8_display_rotation.py": {
"methods": 4,
"passed": true,
"seconds": 4.502
},
"test_muzi_accessory_detection.py": {
"methods": 3,
"passed": true,
"seconds": 1.324
},
"test_techo_lite_display_detection.py": {
"methods": 4,
"passed": true,
"seconds": 3.115
}
},
"packages_verified": 10,
"physical_tests_performed": false,
"picker_browser": {
"checks": [
"default-and-advanced:default-full",
"default-and-advanced:advanced-default",
"default-and-advanced:advanced-reduced",
"default-and-advanced:select-reduced",
"default-and-advanced:reduced-download",
"default-and-advanced:uncheck-returns-full",
"default-and-advanced:reset-full",
"explicit-reduced-url:url-auto-advanced",
"explicit-reduced-url:url-reduced-selected",
"explicit-reduced-url:url-reduced-download",
"explicit-reduced-url:url-no-unavailable",
"old-metadata:old-two-configurations",
"old-metadata:old-both-choices",
"old-metadata:old-not-hidden"
],
"passed": true
},
"picker_qualified_profiles": 10,
"webconfig_browser": {
"methods": 25,
"passed": true,
"seconds": 10.37
},
"webconfig_source": {
"methods": 13,
"passed": true,
"seconds": 0.009
}
},
"version": "v1.18.0.1-variants"
}
@@ -0,0 +1,69 @@
<!-- meshcore-hosted-doc-link:start -->
<p class="meshcore-hosted-doc-link"><a href="https://mikecarper.github.io/MeshCore/test-results/firmware_variant_consolidation/">View this page on MeshCore Docs</a>.</p>
<!-- meshcore-hosted-doc-link:end -->
# Firmware variant consolidation validation
All ten packaged profiles passed. Firmware source:
[`b31d942b231360386fdfb92d0561f36095fdf011`](https://github.com/mikecarper/MeshCore/commit/b31d942b231360386fdfb92d0561f36095fdf011).
Version: `v1.18.0.1-variants-b31d942b`. PlatformIO builds ran one at a time.
The packages were built locally; physical testing of these combinations remains pending.
## Qualified behavior
- The Pico W combined Companion supplies USB, Bluetooth LE and WiFi in one image. It does not acquire a wireless self-updater from that transport combination.
- The base Heltec V4 OLED Repeater supports the matching OLED expansion kit. The original V4 TFT Full Companion supports the matching TFT kit and retains its 3,400 mV shutdown guard. TFT and OLED wiring remain distinct.
- V4 R8 TFT Companion, Repeater, Room Server and Sensor applications contain the optional-panel detection and runtime-rotation implementations. Saved `display.rotation` values select clockwise offsets of 0, 90, 180 or 270 degrees from the compiled board default without another portrait image. Zero restores that board orientation; `display.flip` adds 180 degrees. The stock expansion kit has no orientation sensor.
- Muzi Base Uno and Duo Full Companions detect their SuperIO SH1107 panel and handle optional GPS independently. Their SX1262 and LR1121 radio choices remain distinct.
- T-Echo Lite Full Companion checks the SSD1681 panel before initializing e-paper and supports the corresponding core-only assembly.
Future release selection retires an alternate choice only after its exact successor is qualified. Existing published binaries, filenames and update identities retain their original meaning. Switching between different target identities requires the documented local installation or an exact compatible update route.
## Packaged applications
| Profile | Application bytes | RAM admission margin (bytes) | Application SHA-256 prefix |
| --- | ---: | ---: | --- |
| Pico W combined Companion | 902,956 | 58,540 | `246b07c54f5c` |
| V4 R8 TFT Full Companion | 2,287,528 | 66,528 | `19170cc8866b` |
| V4 R8 TFT Full Repeater | 2,297,368 | 5,736 | `0837183ff083` |
| V4 R8 TFT Full Room Server | 2,302,648 | 7,784 | `28ffdb3bd325` |
| V4 R8 TFT Full Sensor | 1,590,952 | 131,472 | `064c4c98d2b6` |
| V4 OLED Full Repeater | 2,283,496 | 5,904 | `73ec156914e8` |
| V4 TFT Full Companion | 2,281,768 | 68,176 | `85c2dcaa00e8` |
| Muzi Base Uno Full Companion | 580,640 | 32,704 | `0d9fbe41f3ed` |
| Muzi Base Duo Full Companion | 571,792 | 32,784 | `d5970c20227f` |
| T-Echo Lite Full Companion | 595,896 | 28,928 | `91495097a524` |
The [machine-readable evidence](firmware_variant_consolidation.json) contains the full application SHA-256 values, hashes for every offered BIN/merged BIN/UF2/DFU ZIP, exact requested and packaged targets, source version, hardware/update identity where present, detection markers and RAM values. The application hash covers the ESP32 BIN, nRF52 DFU application's BIN, or decoded RP2040 flash application; container hashes are recorded separately.
RAM margins are linked capacity after the complete modeled heap requirement and transient reserve. They are admission results; runtime load and physical current were not measured.
The verifier checked every memory manifest's file bindings and RAM admission. It read the promised marker and exact firmware/source version from each uploadable application, compared ESP32 application bytes with their merged install, compared nRF52 DFU application bytes with decoded UF2, and required Pico W's decoded UF2 to match its BIN. UF2 headers, unused sector bytes and alignment padding cannot provide application capability evidence. Observer-named ESP32 packages retain their actual target and embedded observer version in the JSON.
## Software and browser checks
| Check | Result |
| --- | --- |
| Native R8 rotation, Muzi accessories and T-Echo Lite detection | PASS, 11 methods across three suites; production paths, sanitizers and negative controls |
| RP2040 application admission and existing capability checker | PASS, 11 RP2040 methods and 18 existing methods; malformed UF2, wrong family/address/layout, BIN mismatch and metadata-only proof rejected |
| Consolidation policy, release controls and legacy compatibility | PASS, focused Python suites; packaged marker/config/source gating, paired sensor policies and unchanged historical downloads |
| Picker JavaScript | PASS, five suites covering consolidation, Full defaults, explicit Reduced links, historical metadata and runtime directions |
| WebConfig source checks | PASS, 13 methods |
| WebConfig browser behavior | PASS, 25 methods in the real Chromium headless browser, including saved rotation load/change |
| Firmware picker browser behavior | PASS, 14 DOM checks across Full default/Advanced interaction, explicit Reduced links and stale metadata |
| Complete build-profile selection suite | PASS |
| Actual package controls and picker replay | PASS, 10 qualified profiles; R8 rotation commands offered for all four roles |
| Physical boards/accessories, sleep current and radio/transport load | Not performed |
The production controls generator and picker used release metadata assembled from these exact local files. Public firmware gains the new behavior when a matching qualified image is published. Full sensor support is the ordinary picker default; Advanced retains Reduced images and explicitly linked Reduced selections. Release policy keeps both Full and Reduced downloads and their exact update endpoints.
## Physical acceptance still pending
- **V4 R8 TFT:** cold USB/battery boots with the panel present and absent; all four angles, saved reboot persistence and `display.flip` interaction; dashboard geometry, touch wake/toggle behavior and sleep/wake at every angle; radio transmit/receive and GPS operation.
- **Muzi Base Uno/Duo:** cold boots with SuperIO present and absent; screen supply shutdown/wake, joystick and buzzer; GPS discovery and mode-switch changes; the power-button shutdown/wake sequence; radio operation throughout.
- **T-Echo Lite:** cold boots with the panel present and absent; real controller readback, BUSY settling and timeout behavior; e-paper refresh and sleep/wake; headless buttons, radio and GPS operation.
- **Pico W:** USB, Bluetooth LE and WiFi connections individually and concurrently, including frame delivery under normal radio receive/transmit load.
These checks are required before describing the hardware combinations as physically qualified.
The earlier [optional-screen record](../optional_screens.md#validation) covers separate RC32 and Tracker smoke packages; those are not part of this ten-profile matrix.