Add battery monitoring and LED control features

- Implemented a battery-monitor service to track battery capacity and charging status, controlling LEDs accordingly.
- Created a battery status page in LuCI to display voltage, status, health, and estimated capacity.
- Added hotplug scripts to trigger battery status updates on power button presses and modem interface changes.
- Developed LED control scripts for modem and WiFi status indicators.
- Configured UCI defaults to enable WiFi and set up a modem interface with appropriate settings.
- Introduced a utility script for LED control with various actions (on, off, blink).
- Added a power button script for double-click shutdown functionality.
This commit is contained in:
Miguel Fuertes committed 2025-10-22 11:30:28 +02:00
1 parent 6bc2d6feba
commit 104145900b
19 files changed
+341 -272

No files matched your search

+4 -4
View File
@@ -33,7 +33,7 @@ define Device/yiming-uz801v3
DEVICE_VENDOR := YiMing
DEVICE_MODEL := uz801v3
FILESYSTEMS := squashfs
DEVICE_PACKAGES := configs-uz801 wpad-basic-wolfssl rmtfs uci-usb-gadget \
DEVICE_PACKAGES := configs-dongle wpad-basic-wolfssl rmtfs uci-usb-gadget \
block-mount f2fs-tools prepare-rootfs-data \
msm-firmware-dumper ledcontrol
endef
@@ -44,7 +44,7 @@ define Device/generic-uf02
DEVICE_VENDOR := Generic
DEVICE_MODEL := UF02 (250605 V0S)
FILESYSTEMS := squashfs
DEVICE_PACKAGES := configs-uz801 wpad-basic-wolfssl rmtfs uci-usb-gadget \
DEVICE_PACKAGES := configs-dongle wpad-basic-wolfssl rmtfs uci-usb-gadget \
block-mount f2fs-tools prepare-rootfs-data \
msm-firmware-dumper ledcontrol
endef
@@ -57,7 +57,7 @@ define Device/generic-mf68e
DEVICE_MODEL := MF68E
FILESYSTEMS := squashfs
CMDLINE := "earlycon console=ttyMSM0,115200 quiet loglevel=0 vt.global_cursor_default=0 vt.cur_default=0 root=/dev/mmcblk0p14 rootfstype=squashfs rootwait nowatchdog"
DEVICE_PACKAGES := configs-mf68e wpad-basic-wolfssl rmtfs uci-usb-gadget \
DEVICE_PACKAGES := configs-mifi wpad-basic-wolfssl rmtfs uci-usb-gadget \
block-mount f2fs-tools prepare-rootfs-data \
msm-firmware-dumper kmod-fbtft-gc9107 router-display
endef
@@ -68,7 +68,7 @@ define Device/generic-m9s
DEVICE_VENDOR := Generic
DEVICE_MODEL := M9S
FILESYSTEMS := squashfs
DEVICE_PACKAGES := configs-mf68e wpad-basic-wolfssl rmtfs uci-usb-gadget \
DEVICE_PACKAGES := configs-mifi wpad-basic-wolfssl rmtfs uci-usb-gadget \
block-mount f2fs-tools prepare-rootfs-data \
msm-firmware-dumper ledcontrol
endef
@@ -1,6 +1,6 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=configs-uz801
PKG_NAME:=configs-dongle
PKG_VERSION:=1.0
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
@@ -10,13 +10,13 @@ include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=Utilities
CATEGORY:=Utilities
TITLE:=Default Settings For uz801v3
DEPENDS:=+PACKAGE_luci:luci-proto-modemmanager
TITLE:=Default Settings For Dongles
DEPENDS:=+PACKAGE_luci:luci-proto-modemmanager +ledcontrol +kmod-button-hotplug +inotifywait
endef
# Optional description
define Package/$(PKG_NAME)/description
Tweaks and defaults for uz801v3, including cleanup of problematic APK feeds.
Tweaks and defaults for Dongles, including cleanup of problematic APK feeds.
endef
define Build/Configure
@@ -32,6 +32,12 @@ define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/root/
$(INSTALL_BIN) ./files/luci-app-tailscale*.apk $(1)/root/
$(INSTALL_DIR) $(1)/etc/hotplug.d/ieee80211
$(INSTALL_DATA) ./files/99-wifi-led $(1)/etc/hotplug.d/ieee80211/
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
$(INSTALL_DATA) ./files/99-modem-led $(1)/etc/hotplug.d/iface/
endef
define Package/$(PKG_NAME)/postinst
@@ -4,13 +4,11 @@
case "$ACTION:$INTERFACE" in
ifup:modem)
ledcontrol wan red off 2>/dev/null || true
ledcontrol wan on
ledcontrol green:wan on
logger -t modem-led "Modem UP - Green LED ON"
;;
ifdown:modem)
ledcontrol wan red on 2>/dev/null || true
ledcontrol wan off
ledcontrol green:wan off
logger -t modem-led "Modem DOWN - Green LED OFF"
;;
esac
@@ -12,17 +12,17 @@ case "$ACTION" in
sta_status=$(ip link show phy0-sta0 2>/dev/null | grep -c "state UP")
if [ "$ap_status" -gt 0 ] || [ "$sta_status" -gt 0 ]; then
ledcontrol wlan on
ledcontrol blue:wlan on
logger -t wifi-led "phy0 interface UP, blue LED ON"
else
ledcontrol wlan off
ledcontrol blue:wlan off
logger -t wifi-led "No phy0 interface UP, blue LED OFF"
fi
fi
;;
remove)
if [ "$DEVICENAME" = "phy0" ]; then
ledcontrol wlan off
ledcontrol blue:wlan off
logger -t wifi-led "phy0 removed, blue LED OFF"
fi
;;
@@ -1,6 +1,6 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=configs-mf68e
PKG_NAME:=configs-mifi
PKG_VERSION:=1.0
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
@@ -10,13 +10,13 @@ include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=Utilities
CATEGORY:=Utilities
TITLE:=Default Settings For mf68e
DEPENDS:=+PACKAGE_luci:luci-proto-modemmanager
TITLE:=Default Settings For MiFis
DEPENDS:=+PACKAGE_luci:luci-proto-modemmanager +ledcontrol +kmod-button-hotplug +inotifywait
endef
# Optional description
define Package/$(PKG_NAME)/description
Tweaks and defaults for mf68e, including cleanup of problematic APK feeds and LuCI battery widget.
Tweaks and defaults for MiFis, including cleanup of problematic APK feeds and LuCI battery widget.
endef
define Build/Prepare
@@ -55,6 +55,18 @@ define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/view/admin_status/index
$(INSTALL_DATA) ./files/battery.htm $(1)/usr/lib/lua/luci/view/admin_status/index/20_battery.htm
$(INSTALL_DIR) $(1)/etc/hotplug.d/ieee80211
$(INSTALL_DATA) ./files/hotplugs/99-wifi-led $(1)/etc/hotplug.d/ieee80211/
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
$(INSTALL_DATA) ./files/hotplugs/99-modem-led $(1)/etc/hotplug.d/iface/
$(INSTALL_DIR) $(1)/etc/hotplug.d/button
$(INSTALL_DATA) ./files/hotplugs/50-battery-show $(1)/etc/hotplug.d/button/
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/battery-monitor.init $(1)/etc/init.d/battery-monitor
endef
define Package/$(PKG_NAME)/postinst
@@ -0,0 +1,179 @@
#!/bin/sh /etc/rc.common
# /etc/init.d/battery-monitor
START=99
STOP=01
CHARGER_FILE="/sys/class/power_supply/pm8916-lbc-chgr/online"
BMS_PATH="/sys/class/power_supply/pm8916-bms-vm"
# Required LEDs
LED_RED="red:charging"
LED_GREEN="green:charging"
# Check if required LEDs exist
check_leds() {
local missing=""
if [ ! -d "/sys/class/leds/$LED_RED" ]; then
missing="$missing $LED_RED"
fi
if [ ! -d "/sys/class/leds/$LED_GREEN" ]; then
missing="$missing $LED_GREEN"
fi
if [ -n "$missing" ]; then
logger -t battery-monitor "LEDs not found, service disabled:$missing"
return 1
fi
return 0
}
get_capacity() {
local voltage=$(cat $BMS_PATH/voltage_now 2>/dev/null)
local vmax=$(cat $BMS_PATH/voltage_max_design 2>/dev/null)
local vmin=$(cat $BMS_PATH/voltage_min_design 2>/dev/null)
if [ -n "$voltage" ] && [ -n "$vmax" ] && [ -n "$vmin" ]; then
awk -v v="$voltage" -v vmax="$vmax" -v vmin="$vmin" \
'BEGIN {pct = ((v - vmin) / (vmax - vmin)) * 100;
if (pct < 0) pct = 0;
if (pct > 100) pct = 100;
printf "%.0f", pct}'
else
echo "50"
fi
}
show_battery_temp() {
local capacity=$(get_capacity)
ledcontrol $LED_RED off 2>/dev/null
ledcontrol $LED_GREEN off 2>/dev/null
if [ "$capacity" -lt 20 ]; then
ledcontrol $LED_RED on 2>/dev/null
elif [ "$capacity" -lt 50 ]; then
ledcontrol $LED_RED on 2>/dev/null
ledcontrol $LED_GREEN on 2>/dev/null
else
ledcontrol $LED_GREEN on 2>/dev/null
fi
logger -t battery-monitor "SIGUSR1: Showing ${capacity}%"
sleep 2
update_led
}
update_led() {
local charging=$(cat $CHARGER_FILE 2>/dev/null || echo 0)
if [ "$charging" = "1" ]; then
local capacity=$(get_capacity)
ledcontrol $LED_RED off 2>/dev/null
ledcontrol $LED_GREEN off 2>/dev/null
if [ "$capacity" -ge 95 ]; then
ledcontrol $LED_GREEN on 2>/dev/null
logger -t battery-monitor "Charging complete: ${capacity}%"
elif [ "$capacity" -ge 50 ]; then
ledcontrol $LED_RED blink 2>/dev/null &
ledcontrol $LED_GREEN blink 2>/dev/null &
logger -t battery-monitor "Charging: ${capacity}%"
else
ledcontrol $LED_RED blink 2>/dev/null
logger -t battery-monitor "Charging low: ${capacity}%"
fi
else
ledcontrol $LED_RED off 2>/dev/null
ledcontrol $LED_GREEN off 2>/dev/null
fi
}
# Main monitoring loop (runs in background)
monitor_loop() {
# Set up signal handler
trap 'show_battery_temp' USR1
# Get initial state
local last_state=$(cat $CHARGER_FILE 2>/dev/null || echo 0)
update_led
# Poll charger state
while true; do
local current_state=$(cat $CHARGER_FILE 2>/dev/null || echo 0)
if [ "$current_state" != "$last_state" ]; then
logger -t battery-monitor "Charger state changed: $last_state -> $current_state"
last_state=$current_state
sleep 1
update_led
fi
# Poll every 2 seconds
sleep 2
done
}
start() {
# Exit silently if LEDs don't exist
check_leds || return 0
# Check if already running
if [ -f /var/run/battery-monitor.pid ] && kill -0 $(cat /var/run/battery-monitor.pid) 2>/dev/null; then
logger -t battery-monitor "Already running"
return 0
fi
logger -t battery-monitor "Starting with LEDs: $LED_RED, $LED_GREEN"
# Start monitoring loop in background
monitor_loop &
echo $! > /var/run/battery-monitor.pid
logger -t battery-monitor "Service started (PID: $!)"
}
stop() {
if [ -f /var/run/battery-monitor.pid ]; then
local pid=$(cat /var/run/battery-monitor.pid)
if kill -0 $pid 2>/dev/null; then
kill $pid 2>/dev/null
# Wait for process to die
local timeout=5
while [ $timeout -gt 0 ] && kill -0 $pid 2>/dev/null; do
sleep 1
timeout=$((timeout - 1))
done
# Force kill if still alive
kill -9 $pid 2>/dev/null
logger -t battery-monitor "Service stopped (PID: $pid)"
fi
rm -f /var/run/battery-monitor.pid
fi
# Only try to control LEDs if they exist
if check_leds 2>/dev/null; then
ledcontrol $LED_GREEN off 2>/dev/null
ledcontrol $LED_RED blink 2>/dev/null
logger -t battery-monitor "Shutdown: Red LED blinking"
fi
return 0
}
restart() {
stop
sleep 1
start
}
@@ -0,0 +1,16 @@
#!/bin/sh
# /etc/hotplug.d/iface/99-modem-led
# Modem LED control based on interface status
case "$ACTION:$INTERFACE" in
ifup:modem)
ledcontrol red:wan off 2>/dev/null || true
ledcontrol green:wan on 2>/dev/null || true
logger -t modem-led "Modem UP - Green LED ON"
;;
ifdown:modem)
ledcontrol red:wan on 2>/dev/null || true
ledcontrol green:wan off 2>/dev/null || true
logger -t modem-led "Modem DOWN - Green LED OFF"
;;
esac
@@ -0,0 +1,32 @@
#!/bin/sh
# /etc/hotplug.d/ieee80211/99-wifi-led
# WiFi LED control based on phy0 status
case "$ACTION" in
add)
if [ "$DEVICENAME" = "phy0" ]; then
sleep 5
# Check interface status
ap_status=$(ip link show phy0-ap0 2>/dev/null | grep -c "state UP")
sta_status=$(ip link show phy0-sta0 2>/dev/null | grep -c "state UP")
if [ "$ap_status" -gt 0 ] || [ "$sta_status" -gt 0 ]; then
ledcontrol red:wlan on 2>/dev/null || true
ledcontrol green:wlan on 2>/dev/null || true
logger -t wifi-led "phy0 interface UP, blue LED ON"
else
ledcontrol red:wlan on 2>/dev/null || true
ledcontrol green:wlan off 2>/dev/null || true
logger -t wifi-led "No phy0 interface UP, blue LED OFF"
fi
fi
;;
remove)
if [ "$DEVICENAME" = "phy0" ]; then
ledcontrol red:wlan off 2>/dev/null || true
ledcontrol green:wlan off 2>/dev/null || true
logger -t wifi-led "phy0 removed, blue LED OFF"
fi
;;
esac
+4 -16
View File
@@ -11,12 +11,12 @@ define Package/ledcontrol
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Simple LED control utility
DEPENDS:=+kmod-button-hotplug +inotifywait
DEPENDS:=
endef
define Package/ledcontrol/description
Simple utility to control device LEDs via sysfs
Usage: ledcontrol <color> <on|off|blink|blink_fast>
Usage: ledcontrol <color:function> <on|off|blink|blink_fast>
Includes hotplug scripts for WiFi and modem LED management
endef
@@ -24,20 +24,8 @@ define Build/Compile
endef
define Package/ledcontrol/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) ./files/ledcontrol.sh $(1)/usr/sbin/ledcontrol
$(INSTALL_DIR) $(1)/etc/hotplug.d/ieee80211
$(INSTALL_DATA) ./files/99-wifi-led $(1)/etc/hotplug.d/ieee80211/
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
$(INSTALL_DATA) ./files/99-modem-led $(1)/etc/hotplug.d/iface/
$(INSTALL_DIR) $(1)/etc/hotplug.d/button
$(INSTALL_DATA) ./files/50-battery-show $(1)/etc/hotplug.d/button/
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DATA) ./files/battery-monitor.init $(1)/etc/init.d/battery-monitor
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) ./ledcontrol.sh $(1)/usr/bin/ledcontrol
endef
$(eval $(call BuildPackage,ledcontrol))
@@ -1,101 +0,0 @@
#!/bin/sh /etc/rc.common
# /etc/init.d/battery-monitor
START=99
STOP=01
CHARGER_FILE="/sys/class/power_supply/pm8916-lbc-chgr/online"
BMS_PATH="/sys/class/power_supply/pm8916-bms-vm"
get_capacity() {
local voltage=$(cat $BMS_PATH/voltage_now 2>/dev/null)
local vmax=$(cat $BMS_PATH/voltage_max_design 2>/dev/null)
local vmin=$(cat $BMS_PATH/voltage_min_design 2>/dev/null)
if [ -n "$voltage" ] && [ -n "$vmax" ] && [ -n "$vmin" ]; then
awk -v v="$voltage" -v vmax="$vmax" -v vmin="$vmin" \
'BEGIN {pct = ((v - vmin) / (vmax - vmin)) * 100;
if (pct < 0) pct = 0;
if (pct > 100) pct = 100;
printf "%.0f", pct}'
else
echo "50"
fi
}
show_battery_temp() {
local capacity=$(get_capacity)
ledcontrol charging red off 2>/dev/null
ledcontrol charging green off 2>/dev/null
if [ "$capacity" -lt 20 ]; then
ledcontrol charging red on 2>/dev/null
elif [ "$capacity" -lt 50 ]; then
ledcontrol charging red on 2>/dev/null
ledcontrol charging green on 2>/dev/null
else
ledcontrol charging green on 2>/dev/null
fi
logger -t battery-monitor "SIGUSR1: Showing ${capacity}%"
sleep 2
update_led
}
update_led() {
local charging=$(cat $CHARGER_FILE 2>/dev/null || echo 0)
if [ "$charging" = "1" ]; then
local capacity=$(get_capacity)
ledcontrol charging red off 2>/dev/null
ledcontrol charging green off 2>/dev/null
if [ "$capacity" -ge 95 ]; then
ledcontrol charging green on 2>/dev/null
logger -t battery-monitor "Charging complete: ${capacity}%"
elif [ "$capacity" -ge 50 ]; then
ledcontrol charging red blink 2>/dev/null &
ledcontrol charging green blink 2>/dev/null &
logger -t battery-monitor "Charging: ${capacity}%"
else
ledcontrol charging red blink 2>/dev/null
logger -t battery-monitor "Charging low: ${capacity}%"
fi
else
ledcontrol charging red off 2>/dev/null
ledcontrol charging green off 2>/dev/null
fi
}
start() {
update_led
(
trap 'show_battery_temp' USR1
while true; do
inotifywait -qq -e modify $CHARGER_FILE 2>/dev/null
sleep 1
update_led
done
) &
echo $! > /var/run/battery-monitor.pid
}
stop() {
[ -f /var/run/battery-monitor.pid ] && {
kill $(cat /var/run/battery-monitor.pid) 2>/dev/null
rm -f /var/run/battery-monitor.pid
}
ledcontrol charging green off 2>/dev/null
ledcontrol charging red blink 2>/dev/null
logger -t shutdown-led "BAT LED blinking - shutdown"
return 0
}
-136
View File
@@ -1,136 +0,0 @@
#!/bin/sh
# LED Control Utility for OpenWrt
# Usage: ledcontrol <function> [color] <on|off|blink|blink_fast>
# Examples:
# ledcontrol wan on (MiFi with green:wan)
# ledcontrol wlan on (MiFi with green:wlan)
# ledcontrol blue on (Dongle with blue LED)
# ledcontrol wan green on (Explicit color override)
set -e
# Parse arguments (support both 2 and 3 arg syntax)
if [ $# -eq 2 ]; then
# 2 args: <function_or_color> <action>
SEARCH_KEY="$1"
COLOR=""
ACTION="$2"
elif [ $# -eq 3 ]; then
# 3 args: <function> <color> <action>
SEARCH_KEY="$1"
COLOR="$2"
ACTION="$3"
else
echo "Usage: ledcontrol <function|color> <on|off|blink|blink_fast>" >&2
echo " or: ledcontrol <function> <color> <on|off|blink|blink_fast>" >&2
echo "" >&2
echo "Examples:" >&2
echo " ledcontrol wan on # Auto-detect color (green:wan or blue)" >&2
echo " ledcontrol wlan off # Auto-detect color (green:wlan or blue)" >&2
echo " ledcontrol blue blink # Specific color LED" >&2
echo " ledcontrol wan green on # Explicit function+color" >&2
echo "" >&2
echo "Available LEDs:" >&2
ls -1 /sys/class/leds 2>/dev/null | grep -v "^mmc" | sed 's/^/ /' >&2
exit 1
fi
LED_BASE="/sys/class/leds"
# Find LED with smart matching
find_led() {
local search="$1"
local color="$2"
local led_path
# Priority 1: Exact match with color prefix (green:wan, red:wlan)
if [ -n "$color" ]; then
led_path=$(find "$LED_BASE" -maxdepth 1 -type l -name "${color}:${search}" 2>/dev/null | head -n 1)
if [ -n "$led_path" ]; then
echo "$led_path"
return 0
fi
fi
# Priority 2: Function-based match (wan, wlan, charging)
# Prefer green for status, fallback to any color
for clr in green blue red amber; do
led_path=$(find "$LED_BASE" -maxdepth 1 -type l -name "${clr}:${search}" 2>/dev/null | head -n 1)
if [ -n "$led_path" ]; then
echo "$led_path"
return 0
fi
done
# Priority 3: Color-only match (blue, green, red)
led_path=$(find "$LED_BASE" -maxdepth 1 -type l -name "${search}" 2>/dev/null | head -n 1)
if [ -n "$led_path" ]; then
echo "$led_path"
return 0
fi
# Priority 4: Case-insensitive partial match
led_path=$(find "$LED_BASE" -maxdepth 1 -type l | grep -i "${search}" | grep -v "mmc" | head -n 1)
if [ -n "$led_path" ]; then
echo "$led_path"
return 0
fi
logger -t ledcontrol "LED '$search' not found"
echo "[!] LED '$search' not found" >&2
echo "[*] Available LEDs:" >&2
ls -1 "$LED_BASE" 2>/dev/null | grep -v "^mmc" | sed 's/^/ /' >&2
return 1
}
# Set LED state
set_led() {
local led_path="$1"
local action="$2"
case "$action" in
on)
echo none > "$led_path/trigger" 2>/dev/null || true
echo 1 > "$led_path/brightness"
;;
off)
echo none > "$led_path/trigger" 2>/dev/null || true
echo 0 > "$led_path/brightness"
;;
blink)
echo timer > "$led_path/trigger" 2>/dev/null || {
echo "[!] Blink not supported, setting ON" >&2
echo 1 > "$led_path/brightness"
return 0
}
echo 500 > "$led_path/delay_on" 2>/dev/null || true
echo 500 > "$led_path/delay_off" 2>/dev/null || true
;;
blink_fast)
echo timer > "$led_path/trigger" 2>/dev/null || {
echo "[!] Blink not supported, setting ON" >&2
echo 1 > "$led_path/brightness"
return 0
}
echo 100 > "$led_path/delay_on" 2>/dev/null || true
echo 100 > "$led_path/delay_off" 2>/dev/null || true
;;
*)
logger -t ledcontrol "Invalid action: $action"
echo "[!] Invalid action: $action" >&2
echo "[*] Valid actions: on, off, blink, blink_fast" >&2
return 1
;;
esac
}
# Main
LED_PATH=$(find_led "$SEARCH_KEY" "$COLOR") || exit 1
LED_NAME=$(basename "$LED_PATH")
if set_led "$LED_PATH" "$ACTION"; then
logger -t ledcontrol "LED '$LED_NAME' set to '$ACTION'"
echo "[+] LED '$LED_NAME' set to '$ACTION'"
else
exit 1
fi
+75
View File
@@ -0,0 +1,75 @@
#!/bin/sh
# LED Control Utility for OpenWrt
# Usage: ledcontrol <color:function> <on|off|blink|blink_fast>
# Examples:
# ledcontrol green:wan on
# ledcontrol blue:wlan blink
# ledcontrol red:charging off
set -e
# Parse arguments
if [ $# -ne 2 ]; then
echo "Usage: ledcontrol <color:function> <on|off|blink|blink_fast>" >&2
echo "" >&2
echo "Examples:" >&2
echo " ledcontrol green:wan on" >&2
echo " ledcontrol blue:wlan blink" >&2
echo " ledcontrol red:charging off" >&2
echo "" >&2
echo "Available LEDs:" >&2
ls -1 /sys/class/leds 2>/dev/null | grep -v "^mmc" | sed 's/^/ /' >&2
exit 1
fi
LED_NAME="$1"
ACTION="$2"
LED_PATH="/sys/class/leds/$LED_NAME"
# Check if LED exists
if [ ! -d "$LED_PATH" ]; then
echo "[!] LED '$LED_NAME' not found" >&2
echo "[*] Available LEDs:" >&2
ls -1 /sys/class/leds 2>/dev/null | grep -v "^mmc" | sed 's/^/ /' >&2
exit 1
fi
# Set LED state
case "$ACTION" in
on)
echo none > "$LED_PATH/trigger" 2>/dev/null || true
echo 1 > "$LED_PATH/brightness"
;;
off)
echo none > "$LED_PATH/trigger" 2>/dev/null || true
echo 0 > "$LED_PATH/brightness"
;;
blink)
echo timer > "$LED_PATH/trigger" 2>/dev/null || {
echo "[!] Blink not supported, setting ON" >&2
echo 1 > "$LED_PATH/brightness"
exit 0
}
echo 500 > "$LED_PATH/delay_on" 2>/dev/null || true
echo 500 > "$LED_PATH/delay_off" 2>/dev/null || true
;;
blink_fast)
echo timer > "$LED_PATH/trigger" 2>/dev/null || {
echo "[!] Blink not supported, setting ON" >&2
echo 1 > "$LED_PATH/brightness"
exit 0
}
echo 100 > "$LED_PATH/delay_on" 2>/dev/null || true
echo 100 > "$LED_PATH/delay_off" 2>/dev/null || true
;;
*)
echo "[!] Invalid action: $ACTION" >&2
echo "[*] Valid actions: on, off, blink, blink_fast" >&2
exit 1
;;
esac
logger -t ledcontrol "LED '$LED_NAME' set to '$ACTION'"
# Only print to stdout if running interactively (not from a script/service)
[ -t 1 ] && echo "[+] LED '$LED_NAME' set to '$ACTION'"