fix(picker): preserve GPS-free RAK UART1 firmware

This commit is contained in:
mikecarper committed 2026-10-08 01:54:17 -07:00
1 parent c07d16e398
commit 396474bf9c
4 files changed
+27 -10

No files matched your search

+9 -2
View File
@@ -614,9 +614,14 @@
const sensorSuffix = (target.match(/-(?:full|reduced)$/) || [""])[0];
const baseTarget = sensorSuffix ? target.slice(0, -sensorSuffix.length) : target;
const rs232Replacement = mergedRs232Targets[baseTarget];
// Qualified RAK Full/Reduced images retain powered WisBlock GPS and
// reserve UART1 even when its bounded probe saw no receiver. The exact
// GPS-free Serial1 image remains a distinct, usable hardware choice.
const reservedRakUart1 = sensorSuffix &&
/^rak_4631_repeater_bridge_rs232_serial1(?:_lora_ota_no_external_sensors)?$/.test(baseTarget);
// Preserve the exact sensor policy: a Full image does not replace a
// missing Reduced image, or an older unsuffixed compatibility image.
const replacedRs232 = Boolean(rs232Replacement &&
const replacedRs232 = Boolean(!reservedRakUart1 && rs232Replacement &&
[].concat(rs232Replacement).some(function (replacement) {
return targets.has(replacement + sensorSuffix);
}));
@@ -1677,7 +1682,9 @@
if (info.rs232 && infrastructure) {
const mode = chosen.mode;
const uartNote = /^RAK_4631_repeater_unified_lora_ota-(?:full|reduced)$/i.test(profile.target) && profile.sensorProfile
? "Use the UART and pin map for this exact board. Unified RAK4631 supports set bridge.uart 1 or set bridge.uart 2 while the bridge is stopped. UART1 pauses UART GPS while the bridge runs and restores it when stopped."
? "Unified RAK4631 uses UART2 for the RS-232 bridge; select it with set bridge.uart 2 while the bridge is stopped. GPS safety guards reserve UART1 even when no GPS was detected. Use the separate GPS-free Serial1 image for UART1, with no powered UART GPS or header-connected W25 flash on those pins."
: /^RAK_4631_repeater_bridge_rs232_serial1(?:_lora_ota_no_external_sensors)?-(?:full|reduced)$/i.test(profile.target)
? "This GPS-free Serial1 image uses UART1. Do not fit a powered UART GPS or header-connected W25 flash on the same UART1 pins. Use the unified UART2 image when those pins are occupied."
: "Use the UART and pin map for this exact board. Canonical GPS-enabled RAK4631 uses UART2; select it with set bridge.uart 2 while the bridge is stopped. UART1 needs a compatible GPS-free image.";
// MQTT images keep the historical bridge.enabled ESP-NOW alias.
// Their independently saved UART uses the transport-specific controls.
+4 -2
View File
@@ -28,8 +28,10 @@ or storage differences when a choice between different images is needed.
RAK3401 and RAK4631 repeaters use one unified image per sensor policy for
supported internal and external OTA storage. **Full** and **Reduced** choose
optional sensor drivers; they do not select a storage module. The unified
RAK4631 image also includes runtime RS-232 UART selection. Ethernet remains
a separate RAK4631 hardware image. LoRa OTA still requires the matching
RAK4631 image also includes RS-232 on UART2. A GPS-free Serial1 image remains
separate because the unified image reserves UART1 for potentially powered
GPS hardware. Header-connected W25 flash also occupies UART1 pins. Ethernet
remains a separate RAK4631 hardware image. LoRa OTA still requires the matching
OTAFIX bootloader and a package compatible with the installed target.
The picker reads public release metadata from GitHub. It does not upload device
+1 -1
View File
@@ -127,7 +127,7 @@ extra_javascript:
- _javascript/hosted_doc_links.js?v=20261007-1
- _javascript/notification_builder.js?v=20261006-channel9
- https://unpkg.com/leaflet@1.9.4/dist/leaflet.js
- _javascript/firmware_picker.js?v=20261008-rak-combined-1
- _javascript/firmware_picker.js?v=20261008-rak-combined-2
- _javascript/telemetry_decoder.js?v=20261007-hosted-form
- _javascript/management_decoder.js
- _javascript/filter_tool.js?v=20261002-hashbytes-2plus
+13 -5
View File
@@ -1177,14 +1177,15 @@ const currentCatalog = picker.buildCatalog([
assert.strictEqual(currentCatalog.rows.length, currentAssets.length);
assert(currentCatalog.profiles.every(profile => profile.controls && profile.chipFamily !== 'unknown'));
for (const [hardware, bases] of [
['RAK_4631', ['RAK_4631_repeater_unified_lora_ota', 'RAK_4631_repeater_ethernet']],
['RAK_4631', ['RAK_4631_repeater_unified_lora_ota', 'RAK_4631_repeater_ethernet',
'RAK_4631_repeater_bridge_rs232_serial1_lora_ota_no_external_sensors']],
['RAK_3401', ['RAK_3401_repeater_unified_lora_ota']],
]) {
const context = {hardware, role: 'repeater'};
const expected = bases.flatMap(base => ['full', 'reduced'].map(policy => base + '-' + policy));
const visible = currentCatalog.profiles.filter(profile => picker.profileMatchesFacets(profile, context));
assert.deepStrictEqual(visible.map(profile => profile.target).sort(), expected.sort(),
hardware + ' must recommend only combined storage/bridge images and genuine Ethernet variants');
hardware + ' must retain only combined storage/UART2 images, GPS-free UART1 and Ethernet variants');
const choices = picker.firmwareProfileChoices(currentCatalog.profiles, context);
assert.strictEqual(choices.length, expected.length, hardware + ' must have one choice per real image');
assert.strictEqual(new Set(choices.map(choice => choice.label)).size, choices.length,
@@ -1195,12 +1196,19 @@ for (const [hardware, bases] of [
if (hardware === 'RAK_4631') {
const bridge = picker.runtimeDirections(profile, {mode: 'rs232'})
.find(section => section.title.startsWith('RS232 bridge'));
assert(bridge && bridge.note.includes('set bridge.uart 1') && bridge.note.includes('pauses UART GPS'),
'Both combined sensor policies must explain runtime UART selection and GPS sharing');
assert(!bridge.note.includes('GPS-free image'));
assert(bridge && bridge.note.includes('set bridge.uart 2') && bridge.note.includes('reserve UART1'),
'Both combined sensor policies must explain the powered-GPS UART1 restriction');
assert(!bridge.note.includes('pauses UART GPS'));
}
}
}
for (const policy of ['full', 'reduced']) {
const serial1 = currentCatalog.profiles.find(profile => profile.target ===
'RAK_4631_repeater_bridge_rs232_serial1_lora_ota_no_external_sensors-' + policy);
assert(serial1 && serial1.controls.gps === false,
'The UART1 image must remain usable without the combined image\'s GPS reservation');
assert(!picker.runtimeDirections(serial1, {mode: 'rs232'}).some(section => section.title === 'GPS'));
}
const rakBridgeBase = 'RAK_4631_repeater_bridge_rs232_serial1_lora_ota_no_external_sensors';
const rakPartialAssets = currentAssets.filter(file =>
file.name.startsWith('RAK_4631_repeater_unified_lora_ota-full-') ||