Skip to content

fix(companion_radio): apply persisted GPS enabled setting on boot for ui-orig devices#2018

Open
got-root wants to merge 1 commit intomeshcore-dev:devfrom
got-root:fix/companion-radio-gps-persistence
Open

fix(companion_radio): apply persisted GPS enabled setting on boot for ui-orig devices#2018
got-root wants to merge 1 commit intomeshcore-dev:devfrom
got-root:fix/companion-radio-gps-persistence

Conversation

@got-root
Copy link

Summary

  • Fixes GPS Mode setting not persisting across reboots for companion_radio builds using ui-orig (WisMesh Tag, RAK3112, T1000-E, Minewsemi ME25LS01)
  • Adds applyGpsPrefs() method to MyMesh and calls it from main.cpp after sensors.begin(), following the established pattern used in simple_repeater, simple_sensor, and simple_room_server
  • Completes the work started in Persist GPS enabled state to preferences #1156 which fixed this for ui-new devices but left ui-orig devices unaddressed

Fixes #989

Problem Description

Users reported that the "GPS Mode" setting (Disabled/Enabled) in the mobile app was not retained after reboot on companion_radio devices using ui-orig. The device always showed "Disabled" after reconnecting, regardless of the setting before reboot. This was confirmed by multiple users across different hardware (WisMesh Tag, Heltec V4, T1000-E, RAK4631) in issue #989.

What Was Working

The preference was being saved to flash correctly:

  • DataStore::savePrefs() writes gps_enabled to the /new_prefs file (offset 85)
  • DataStore::loadPrefs() reads it back into _prefs.gps_enabled on boot
  • CMD_SET_CUSTOM_VAR handler in MyMesh::handleCmdFrame() correctly updates _prefs.gps_enabled and calls savePrefs() when the app sends a GPS toggle

What Was Broken

The loaded _prefs.gps_enabled value was never applied to the EnvironmentSensorManager GPS hardware state after boot. The sensor manager's initBasicGPS() unconditionally sets gps_active = false (EnvironmentSensorManager.cpp:586), and nothing in the companion_radio boot sequence restored the persisted state afterward.

Root Cause Analysis

PR #1156 added GPS preference persistence for companion_radio, but the runtime state restoration was only added to ui-new/UITask.cpp::begin(). Devices using ui-orig (which has no equivalent code) were left without GPS state restoration.

Additionally, the initialization order in companion_radio/main.cpp differs from other examples:

Example Boot Order
simple_repeater sensors.begin()the_mesh.begin()applyGpsPrefs()
simple_sensor sensors.begin()the_mesh.begin()applyGpsPrefs()
simple_room_server sensors.begin()the_mesh.begin()applyGpsPrefs()
companion_radio the_mesh.begin()sensors.begin() ❌ (no applyGpsPrefs anywhere)

Because sensors.begin() runs after the_mesh.begin() in companion_radio, the GPS preference must be applied after sensors.begin() to avoid being overwritten by initBasicGPS().

Solution

Added applyGpsPrefs() method to MyMesh.h and call it from main.cpp after sensors.begin(), following the exact pattern used in the three other working examples:

MyMesh.h — new method (matches simple_repeater/MyMesh.h:161, simple_sensor/SensorMesh.h:158, simple_room_server/MyMesh.h:156):

#if ENV_INCLUDE_GPS == 1
  void applyGpsPrefs() {
    sensors.setSettingValue("gps", _prefs.gps_enabled ? "1" : "0");
  }
#endif

main.cpp — call after sensor initialization:

sensors.begin();

#if ENV_INCLUDE_GPS == 1
  the_mesh.applyGpsPrefs();
#endif

Impact on ui-new Devices

This change is safe for ui-new devices. On ui-new builds, applyGpsPrefs() is called from main.cpp after sensors.begin(), and then ui-new/UITask::begin() applies the same preference again from its own code (added in #1156). The GPS state is set twice to the same value — redundant but harmless.

Files Changed

  • examples/companion_radio/MyMesh.h — Added applyGpsPrefs() method
  • examples/companion_radio/main.cpp — Call applyGpsPrefs() after sensors.begin()

Testing

Hardware

  • Device: RAK WisMesh Tag (NRF52840 platform)
  • Build variant: RAK_WisMesh_Tag_companion_radio_ble
  • Mobile app: MeshCore Track (BLE connection)

Before Fix

Step Action Result
1 Enable GPS in app settings GPS: Enabled ✓
2 Reboot device (app command) Device restarts ✓
3 Reconnect and check setting GPS: Disabled ✗
4 Enable GPS, reboot via button hold (3+ sec) Device restarts ✓
5 Reconnect and check setting GPS: Disabled ✗

After Fix

Step Action Result
1 Flash patched firmware Boots, shows GPS: Enabled (from prior save) ✓
2 Disable GPS → reboot → reconnect GPS: Disabled ✓
3 Enable GPS → reboot → reconnect GPS: Enabled ✓
4 Reboot again → reconnect GPS: Enabled (persisted) ✓
5 Repeat enable/disable/reboot cycle 3x All states persist correctly ✓

Build Verification

Variant Status Flash Delta
RAK_WisMesh_Tag_companion_radio_ble ✅ SUCCESS +16 bytes
RAK_WisMesh_Tag_companion_radio_usb ✅ SUCCESS +16 bytes

Related Issues & PRs

The companion_radio example was not restoring the GPS enabled/disabled
preference from flash after reboot. The preference was being saved
correctly when toggled via the mobile app, but on boot,
sensors.begin() -> initBasicGPS() unconditionally sets gps_active=false
and nothing subsequently restored the persisted state.

Added applyGpsPrefs() (matching the pattern in simple_repeater,
simple_sensor, and simple_room_server) and call it from main.cpp
after sensors.begin() to ensure the GPS hardware is initialized
before the saved preference is applied.
@btcbobby
Copy link

Thank you! I was having the same problem. I love open source! 🦾

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants