From 6489767e4d5c4a3045a30155ed8fefd624b1517d Mon Sep 17 00:00:00 2001 From: Mirko Curtolo Date: Wed, 12 Nov 2025 14:40:50 +0100 Subject: [PATCH 1/9] Add leds utils --- src/arduino/app_utils/__init__.py | 3 +- src/arduino/app_utils/leds.py | 55 +++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/arduino/app_utils/leds.py diff --git a/src/arduino/app_utils/__init__.py b/src/arduino/app_utils/__init__.py index f7aca94d..b4594b6b 100644 --- a/src/arduino/app_utils/__init__.py +++ b/src/arduino/app_utils/__init__.py @@ -12,7 +12,7 @@ from .jsonparser import * from .logger import * from .slidingwindowbuffer import * -from .userinput import * +from .leds import * __all__ = [ "App", @@ -31,4 +31,5 @@ "SineGenerator", "SlidingWindowBuffer", "UserTextInput", + "Leds", ] diff --git a/src/arduino/app_utils/leds.py b/src/arduino/app_utils/leds.py new file mode 100644 index 00000000..f4e16c3a --- /dev/null +++ b/src/arduino/app_utils/leds.py @@ -0,0 +1,55 @@ +from arduino.app_utils import Logger, Bridge + +logger = Logger(__name__) + +LED_IDS = [1, 2, 3, 4] # Supported LED IDs + +LED_BRIGHTNESS_FILES = [ + "/sys/class/leds/red:user/brightness", + "/sys/class/leds/green:user/brightness", + "/sys/class/leds/blue:user/brightness", + "/sys/class/leds/red:panic/brightness", + "/sys/class/leds/green:wlan/brightness", + "/sys/class/leds/blue:bt/brightness", +] + +def set_led1_color(r, g, b): + write_led_file(LED_BRIGHTNESS_FILES[0], r) + write_led_file(LED_BRIGHTNESS_FILES[1], g) + write_led_file(LED_BRIGHTNESS_FILES[2], b) + +def set_led2_color(r, g, b): + write_led_file(LED_BRIGHTNESS_FILES[3], r) + write_led_file(LED_BRIGHTNESS_FILES[4], g) + write_led_file(LED_BRIGHTNESS_FILES[5], b) + +def write_led_file(led_file, color): + try: + with open(led_file, "w") as f: + f.write(f"{color}\n") + except Exception as e: + print(f"Error writing to {led_file}: {e}") + +class Leds: + @staticmethod + def set_led_color(ledid: int, rgb_color: dict): + try: + if ledid not in LED_IDS: + raise ValueError(f"Unknown led '{ledid}'") + + if not rgb_color or not all(k in rgb_color for k in ("r", "g", "b")): + raise ValueError("Color must be an object with 'r', 'g', 'b' keys") + + # Led 1 and 2 are controlled by Python code directly (MPU), while Led 3 and 4 are controlled via Bridge (MCU) + match ledid: + case 1: + set_led1_color(rgb_color['r'], rgb_color['g'], rgb_color['b']) + case 2: + set_led2_color(rgb_color['r'], rgb_color['g'], rgb_color['b']) + case 3 | 4: + Bridge.call("set_led_color", ledid, rgb_color['r'], rgb_color['g'], rgb_color['b']) + + except Exception as e: + Logger(__name__).error(f"LED color set error: {e}") + +Leds = Leds() \ No newline at end of file From 5b6fd71b0fe681a8ada58d822c5cdab50ce09aaf Mon Sep 17 00:00:00 2001 From: Mirko Curtolo Date: Wed, 12 Nov 2025 14:58:18 +0100 Subject: [PATCH 2/9] Run license task --- src/arduino/app_utils/leds.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/arduino/app_utils/leds.py b/src/arduino/app_utils/leds.py index f4e16c3a..6c4dada7 100644 --- a/src/arduino/app_utils/leds.py +++ b/src/arduino/app_utils/leds.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: Copyright (C) 2025 ARDUINO SA +# +# SPDX-License-Identifier: MPL-2.0 + from arduino.app_utils import Logger, Bridge logger = Logger(__name__) From 044fb0a0b5e44dd3b2fce2b9ec0f0b92f66ba04c Mon Sep 17 00:00:00 2001 From: Mirko Curtolo Date: Wed, 12 Nov 2025 16:28:37 +0100 Subject: [PATCH 3/9] format --- src/arduino/app_utils/leds.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/arduino/app_utils/leds.py b/src/arduino/app_utils/leds.py index 6c4dada7..c08ba800 100644 --- a/src/arduino/app_utils/leds.py +++ b/src/arduino/app_utils/leds.py @@ -17,16 +17,19 @@ "/sys/class/leds/blue:bt/brightness", ] + def set_led1_color(r, g, b): write_led_file(LED_BRIGHTNESS_FILES[0], r) write_led_file(LED_BRIGHTNESS_FILES[1], g) write_led_file(LED_BRIGHTNESS_FILES[2], b) + def set_led2_color(r, g, b): write_led_file(LED_BRIGHTNESS_FILES[3], r) write_led_file(LED_BRIGHTNESS_FILES[4], g) write_led_file(LED_BRIGHTNESS_FILES[5], b) + def write_led_file(led_file, color): try: with open(led_file, "w") as f: @@ -34,6 +37,7 @@ def write_led_file(led_file, color): except Exception as e: print(f"Error writing to {led_file}: {e}") + class Leds: @staticmethod def set_led_color(ledid: int, rgb_color: dict): @@ -47,13 +51,14 @@ def set_led_color(ledid: int, rgb_color: dict): # Led 1 and 2 are controlled by Python code directly (MPU), while Led 3 and 4 are controlled via Bridge (MCU) match ledid: case 1: - set_led1_color(rgb_color['r'], rgb_color['g'], rgb_color['b']) + set_led1_color(rgb_color["r"], rgb_color["g"], rgb_color["b"]) case 2: - set_led2_color(rgb_color['r'], rgb_color['g'], rgb_color['b']) + set_led2_color(rgb_color["r"], rgb_color["g"], rgb_color["b"]) case 3 | 4: - Bridge.call("set_led_color", ledid, rgb_color['r'], rgb_color['g'], rgb_color['b']) + Bridge.call("set_led_color", ledid, rgb_color["r"], rgb_color["g"], rgb_color["b"]) except Exception as e: Logger(__name__).error(f"LED color set error: {e}") -Leds = Leds() \ No newline at end of file + +Leds = Leds() From d8796d0602e0ad9c06cd4ec5ed9fbeeeac2974ce Mon Sep 17 00:00:00 2001 From: Mirko Curtolo Date: Thu, 13 Nov 2025 12:25:14 +0100 Subject: [PATCH 4/9] Refactor --- src/arduino/app_utils/leds.py | 41 ++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/arduino/app_utils/leds.py b/src/arduino/app_utils/leds.py index c08ba800..8c7344cd 100644 --- a/src/arduino/app_utils/leds.py +++ b/src/arduino/app_utils/leds.py @@ -18,18 +18,6 @@ ] -def set_led1_color(r, g, b): - write_led_file(LED_BRIGHTNESS_FILES[0], r) - write_led_file(LED_BRIGHTNESS_FILES[1], g) - write_led_file(LED_BRIGHTNESS_FILES[2], b) - - -def set_led2_color(r, g, b): - write_led_file(LED_BRIGHTNESS_FILES[3], r) - write_led_file(LED_BRIGHTNESS_FILES[4], g) - write_led_file(LED_BRIGHTNESS_FILES[5], b) - - def write_led_file(led_file, color): try: with open(led_file, "w") as f: @@ -40,6 +28,7 @@ def write_led_file(led_file, color): class Leds: @staticmethod + # Led 1 and 2 are controlled by directly (MPU), while Led 3 and 4 are controlled via Bridge (MCU) def set_led_color(ledid: int, rgb_color: dict): try: if ledid not in LED_IDS: @@ -48,17 +37,33 @@ def set_led_color(ledid: int, rgb_color: dict): if not rgb_color or not all(k in rgb_color for k in ("r", "g", "b")): raise ValueError("Color must be an object with 'r', 'g', 'b' keys") - # Led 1 and 2 are controlled by Python code directly (MPU), while Led 3 and 4 are controlled via Bridge (MCU) match ledid: case 1: - set_led1_color(rgb_color["r"], rgb_color["g"], rgb_color["b"]) + Leds.set_led1_color(rgb_color["r"], rgb_color["g"], rgb_color["b"]) case 2: - set_led2_color(rgb_color["r"], rgb_color["g"], rgb_color["b"]) - case 3 | 4: - Bridge.call("set_led_color", ledid, rgb_color["r"], rgb_color["g"], rgb_color["b"]) + Leds.set_led2_color(rgb_color["r"], rgb_color["g"], rgb_color["b"]) + case 3: + Leds.set_led3_color(rgb_color["r"], rgb_color["g"], rgb_color["b"]) + case 4: + Leds.set_led4_color(rgb_color["r"], rgb_color["g"], rgb_color["b"]) except Exception as e: Logger(__name__).error(f"LED color set error: {e}") + @staticmethod + def set_led1_color(r, g, b): + write_led_file(LED_BRIGHTNESS_FILES[0], r) + write_led_file(LED_BRIGHTNESS_FILES[1], g) + write_led_file(LED_BRIGHTNESS_FILES[2], b) + + @staticmethod + def set_led2_color(r, g, b): + write_led_file(LED_BRIGHTNESS_FILES[3], r) + write_led_file(LED_BRIGHTNESS_FILES[4], g) + write_led_file(LED_BRIGHTNESS_FILES[5], b) + + def set_led3_color(r, g, b): + Bridge.call("set_led_color", 3, r, g, b) -Leds = Leds() + def set_led4_color(r, g, b): + Bridge.call("set_led_color", 4, r, g, b) From 5d40ced079bac1137db7cea3f659b81a0aa8742d Mon Sep 17 00:00:00 2001 From: Mirko Curtolo Date: Fri, 21 Nov 2025 12:27:41 +0100 Subject: [PATCH 5/9] Remove led 3 and 4 from utils since they need a specific sketch --- src/arduino/app_utils/__init__.py | 1 + src/arduino/app_utils/leds.py | 78 +++++++++++-------------------- 2 files changed, 27 insertions(+), 52 deletions(-) diff --git a/src/arduino/app_utils/__init__.py b/src/arduino/app_utils/__init__.py index b4594b6b..02e234d9 100644 --- a/src/arduino/app_utils/__init__.py +++ b/src/arduino/app_utils/__init__.py @@ -12,6 +12,7 @@ from .jsonparser import * from .logger import * from .slidingwindowbuffer import * +from .userinput import * from .leds import * __all__ = [ diff --git a/src/arduino/app_utils/leds.py b/src/arduino/app_utils/leds.py index 8c7344cd..d0aa60b4 100644 --- a/src/arduino/app_utils/leds.py +++ b/src/arduino/app_utils/leds.py @@ -2,68 +2,42 @@ # # SPDX-License-Identifier: MPL-2.0 -from arduino.app_utils import Logger, Bridge +from arduino.app_utils import Logger logger = Logger(__name__) -LED_IDS = [1, 2, 3, 4] # Supported LED IDs - -LED_BRIGHTNESS_FILES = [ - "/sys/class/leds/red:user/brightness", - "/sys/class/leds/green:user/brightness", - "/sys/class/leds/blue:user/brightness", - "/sys/class/leds/red:panic/brightness", - "/sys/class/leds/green:wlan/brightness", - "/sys/class/leds/blue:bt/brightness", -] - - -def write_led_file(led_file, color): - try: - with open(led_file, "w") as f: - f.write(f"{color}\n") - except Exception as e: - print(f"Error writing to {led_file}: {e}") - class Leds: + _led_ids = [1, 2] # Supported LED IDs (Led 3 and 4 can't be controlled directly by MPU but only by MCU via Bridge) + + _led1_brightness_files = [ + "/sys/class/leds/red:user/brightness", + "/sys/class/leds/green:user/brightness", + "/sys/class/leds/blue:user/brightness", + ] + _led2_brightness_files = [ + "/sys/class/leds/red:panic/brightness", + "/sys/class/leds/green:wlan/brightness", + "/sys/class/leds/blue:bt/brightness", + ] + @staticmethod - # Led 1 and 2 are controlled by directly (MPU), while Led 3 and 4 are controlled via Bridge (MCU) - def set_led_color(ledid: int, rgb_color: dict): + def _write_led_file(led_file, value: bool): try: - if ledid not in LED_IDS: - raise ValueError(f"Unknown led '{ledid}'") - - if not rgb_color or not all(k in rgb_color for k in ("r", "g", "b")): - raise ValueError("Color must be an object with 'r', 'g', 'b' keys") - - match ledid: - case 1: - Leds.set_led1_color(rgb_color["r"], rgb_color["g"], rgb_color["b"]) - case 2: - Leds.set_led2_color(rgb_color["r"], rgb_color["g"], rgb_color["b"]) - case 3: - Leds.set_led3_color(rgb_color["r"], rgb_color["g"], rgb_color["b"]) - case 4: - Leds.set_led4_color(rgb_color["r"], rgb_color["g"], rgb_color["b"]) - + with open(led_file, "w") as f: + f.write(f"{int(value)}\n") except Exception as e: - Logger(__name__).error(f"LED color set error: {e}") + print(f"Error writing to {led_file}: {e}") @staticmethod - def set_led1_color(r, g, b): - write_led_file(LED_BRIGHTNESS_FILES[0], r) - write_led_file(LED_BRIGHTNESS_FILES[1], g) - write_led_file(LED_BRIGHTNESS_FILES[2], b) + def set_led1_color(r: bool, g: bool, b: bool): + Leds._write_led_file(Leds._led1_brightness_files[0], r) + Leds._write_led_file(Leds._led1_brightness_files[1], g) + Leds._write_led_file(Leds._led1_brightness_files[2], b) @staticmethod - def set_led2_color(r, g, b): - write_led_file(LED_BRIGHTNESS_FILES[3], r) - write_led_file(LED_BRIGHTNESS_FILES[4], g) - write_led_file(LED_BRIGHTNESS_FILES[5], b) - - def set_led3_color(r, g, b): - Bridge.call("set_led_color", 3, r, g, b) + def set_led2_color(r: bool, g: bool, b: bool): + Leds._write_led_file(Leds._led2_brightness_files[0], r) + Leds._write_led_file(Leds._led2_brightness_files[1], g) + Leds._write_led_file(Leds._led2_brightness_files[2], b) - def set_led4_color(r, g, b): - Bridge.call("set_led_color", 4, r, g, b) From 589305080699cdd38cd3ab263a59b2ae62c5cae8 Mon Sep 17 00:00:00 2001 From: Mirko Curtolo Date: Fri, 21 Nov 2025 15:01:06 +0100 Subject: [PATCH 6/9] fmt --- src/arduino/app_utils/leds.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/arduino/app_utils/leds.py b/src/arduino/app_utils/leds.py index d0aa60b4..27a9e07b 100644 --- a/src/arduino/app_utils/leds.py +++ b/src/arduino/app_utils/leds.py @@ -40,4 +40,3 @@ def set_led2_color(r: bool, g: bool, b: bool): Leds._write_led_file(Leds._led2_brightness_files[0], r) Leds._write_led_file(Leds._led2_brightness_files[1], g) Leds._write_led_file(Leds._led2_brightness_files[2], b) - From ec3e268cc77775dea9efc73d4af0368d2985d56f Mon Sep 17 00:00:00 2001 From: Mirko Curtolo Date: Fri, 21 Nov 2025 15:52:55 +0100 Subject: [PATCH 7/9] Fix copyright note --- src/arduino/app_utils/leds.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/arduino/app_utils/leds.py b/src/arduino/app_utils/leds.py index 27a9e07b..ba4babc8 100644 --- a/src/arduino/app_utils/leds.py +++ b/src/arduino/app_utils/leds.py @@ -1,4 +1,5 @@ # SPDX-FileCopyrightText: Copyright (C) 2025 ARDUINO SA +# SPDX-FileCopyrightText: Copyright (C) ARDUINO SRL (http://www.arduino.cc) # # SPDX-License-Identifier: MPL-2.0 From a086ea61242e9ae25b0dbd461dd9260fbd6ec205 Mon Sep 17 00:00:00 2001 From: Mirko Curtolo Date: Fri, 21 Nov 2025 16:01:10 +0100 Subject: [PATCH 8/9] Add doc --- src/arduino/app_utils/leds.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/arduino/app_utils/leds.py b/src/arduino/app_utils/leds.py index ba4babc8..3c85a8e5 100644 --- a/src/arduino/app_utils/leds.py +++ b/src/arduino/app_utils/leds.py @@ -9,6 +9,28 @@ class Leds: + """ + A utility class for controlling LED colors on Arduino hardware. + + This class provides static methods to control two RGB LEDs by writing to system + brightness files. LED1 and LED2 can be controlled directly by the MPU, while + LED3 and LED4 require MCU control via Bridge. + + Attributes: + _led_ids (list): List of supported LED IDs [1, 2]. + _led1_brightness_files (list): System file paths for LED1 RGB channels + (red:user, green:user, blue:user). + _led2_brightness_files (list): System file paths for LED2 RGB channels + (red:panic, green:wlan, blue:bt). + + Methods: + set_led1_color(r, g, b): Set the RGB color state for LED1. + set_led2_color(r, g, b): Set the RGB color state for LED2. + + Example: + >>> Leds.set_led1_color(True, False, True) # LED1 shows magenta + >>> Leds.set_led2_color(False, True, False) # LED2 shows green + """ _led_ids = [1, 2] # Supported LED IDs (Led 3 and 4 can't be controlled directly by MPU but only by MCU via Bridge) _led1_brightness_files = [ From 1b02f7d15a8b53da2f2a6d9980da5fe9f2bc688b Mon Sep 17 00:00:00 2001 From: Mirko Curtolo Date: Fri, 21 Nov 2025 17:00:19 +0100 Subject: [PATCH 9/9] fmt --- src/arduino/app_utils/leds.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/arduino/app_utils/leds.py b/src/arduino/app_utils/leds.py index 3c85a8e5..3ca2036c 100644 --- a/src/arduino/app_utils/leds.py +++ b/src/arduino/app_utils/leds.py @@ -31,6 +31,7 @@ class Leds: >>> Leds.set_led1_color(True, False, True) # LED1 shows magenta >>> Leds.set_led2_color(False, True, False) # LED2 shows green """ + _led_ids = [1, 2] # Supported LED IDs (Led 3 and 4 can't be controlled directly by MPU but only by MCU via Bridge) _led1_brightness_files = [