Skip to content

fix: add linux leds reset on app stop#98

Draft
beanrepo wants to merge 1 commit intoarduino:mainfrom
beanrepo:add-linux-led-reset-on-app-stop
Draft

fix: add linux leds reset on app stop#98
beanrepo wants to merge 1 commit intoarduino:mainfrom
beanrepo:add-linux-led-reset-on-app-stop

Conversation

@beanrepo
Copy link
Copy Markdown
Contributor

Summary

Add signal handling and system LED cleanup to the Python App framework so that LED1 and LED2 are properly restored when an app is stopped via SIGTERM.

Problem

When an app is stopped, LED1 and LED2 (MPU-controlled via sysfs) remain lit in whatever state the app left them. LED3 and LED4 (MCU-controlled) reset automatically because the MCU resets on app stop.

The Python App framework had no signal handling and no cleanup logic. When arduino-app-cli sends SIGTERM to the container, the process was killed immediately without restoring LED brightness or triggers.

Changes

app.py (framework)

  • Added SIGTERM/SIGINT signal handlers in App.run() with a _shutdown_requested flag
  • Added try/finally in App.run() to guarantee _cleanup_system_resources() runs after _stop_all_bricks()
  • _cleanup_system_resources() calls Leds.restore_system_control()

leds.py (framework)

  • Added save/restore pattern: first use of set_led1_color() or set_led2_color() saves the original state
  • LED1: saves and restores both trigger and brightness
  • LED2: saves brightness; restores brightness to 0 and explicitly restores known system triggers (bluetooth-power, phy0tx, none)
  • The LED2 system triggers are hardcoded as a temporary workaround for a bug in arduino-app-cli (see note below)

app.js (color-your-leds example PR on app-bricks-examples )

  • Added socket.on('connect') handler to re-sync all LED states on every socket reconnection, so the physical LEDs match the UI after an app restart without needing a browser refresh

Note on arduino-app-cli interaction

arduino-app-cli calls setStatusLeds(LedTriggerDefault) on app stop, which writes "default" to LED2 trigger files. In the Linux kernel LED subsystem, "default" maps to the default-on trigger driver — it does not restore the original triggers (bluetooth-power, phy0tx). This means system services (bluetoothd, WiFi driver) lose LED control after app stop.

This PR includes a workaround: leds.py hardcodes the known correct system triggers for LED2 and writes them during cleanup, overriding the incorrect "default" value. This is architecturally suboptimal because:

  1. Robustness: If the Python app crashes or is killed with SIGKILL, the cleanup never runs. arduino-app-cli on the host can always restore triggers after the container stops.
  2. Single source of truth: The trigger values are duplicated between arduino-app-cli (knows the paths) and leds.py (knows the correct values).
  3. Correct ordering: arduino-app-cli changes triggers before the container stops; the restore should happen after.

After that fix lands, leds.py can be simplified to remove _led2_system_triggers and only handle LED1 triggers + LED2 brightness reset. The current workaround is forward-compatible and will not conflict with the CLI fix.

@dsammaruga dsammaruga marked this pull request as draft March 3, 2026 13:31
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Mar 18, 2026

CLA assistant check
All committers have signed the CLA.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants