This commit is contained in:
biss committed 2026-09-08 20:01:03 +08:00
commit 645c461d2a
12 files changed
+886

No files matched your search

+223
View File
@@ -0,0 +1,223 @@
#!/bin/sh
CONFIG="led-scheduler"
SECTION="main"
LED_ROOT="/sys/class/leds"
CRON_FILE="/etc/crontabs/root"
CRON_BEGIN="# BEGIN luci-app-led-scheduler"
CRON_END="# END luci-app-led-scheduler"
log() { logger -t led-scheduler "$*"; }
uci_get() { uci -q get "${CONFIG}.${SECTION}.$1" 2>/dev/null; }
valid_led_name() {
case "$1" in
""|*/*|*".."*|*[!A-Za-z0-9:_.-]*) return 1 ;;
esac
return 0
}
available_led() {
valid_led_name "$1" || return 1
[ -d "${LED_ROOT}/$1" ]
}
configured_leds() {
local section sysfs
uci -q show system 2>/dev/null |
sed -n 's/^system\.\([^=]*\)=led$/\1/p' |
while IFS= read -r section; do
sysfs="$(uci -q get "system.${section}.sysfs" 2>/dev/null)"
[ -n "$sysfs" ] || continue
available_led "$sysfs" || continue
printf '%s\n' "$sysfs"
done |
awk '!seen[$0]++'
}
selected_leds() {
local all selected led
all="$(uci_get all_system_leds)"
[ -n "$all" ] || all="1"
if [ "$all" = "1" ]; then
configured_leds
return 0
fi
selected="$(uci_get led)"
for led in $selected; do
available_led "$led" || continue
printf '%s\n' "$led"
done | awk '!seen[$0]++'
}
restore_native() {
if [ -x /etc/init.d/led ]; then
/etc/init.d/led restart >/dev/null 2>&1
return $?
fi
echo "OpenWrt LED service /etc/init.d/led not found" >&2
return 1
}
turn_off() {
local led path
restore_native >/dev/null 2>&1 || true
selected_leds | while IFS= read -r led; do
available_led "$led" || continue
path="${LED_ROOT}/${led}"
[ -w "${path}/trigger" ] && printf '%s\n' none > "${path}/trigger" 2>/dev/null
[ -w "${path}/brightness" ] && printf '%s\n' 0 > "${path}/brightness" 2>/dev/null
done
log "selected LEDs turned off"
}
turn_on() {
if restore_native; then
log "native OpenWrt LED configuration restored"
return 0
fi
log "failed to restore native LED configuration"
return 1
}
validate_time() {
local t="$1" h m
case "$t" in [0-9][0-9]:[0-9][0-9]) ;; *) return 1 ;; esac
h="${t%:*}"; m="${t#*:}"
h="${h#0}"; m="${m#0}"
[ -n "$h" ] || h=0; [ -n "$m" ] || m=0
[ "$h" -ge 0 ] 2>/dev/null || return 1
[ "$h" -le 23 ] 2>/dev/null || return 1
[ "$m" -ge 0 ] 2>/dev/null || return 1
[ "$m" -le 59 ] 2>/dev/null || return 1
return 0
}
time_parts() {
local t="$1" h m
h="${t%:*}"; m="${t#*:}"
h="${h#0}"; m="${m#0}"
[ -n "$h" ] || h=0; [ -n "$m" ] || m=0
printf '%s %s\n' "$h" "$m"
}
strip_cron_block() {
local tmp="/tmp/led-scheduler-cron.$$"
mkdir -p "$(dirname "$CRON_FILE")"
touch "$CRON_FILE"
awk -v begin="$CRON_BEGIN" -v end="$CRON_END" '
$0 == begin { skip=1; next }
$0 == end { skip=0; next }
!skip { print }
' "$CRON_FILE" > "$tmp"
cat "$tmp" > "$CRON_FILE"
rm -f "$tmp"
}
reload_cron() { [ -x /etc/init.d/cron ] && /etc/init.d/cron restart >/dev/null 2>&1; }
clear_cron() {
strip_cron_block
reload_cron
log "cron entries removed"
}
sync_cron() {
local enabled off_time on_time off_h off_m on_h on_m
enabled="$(uci_get enabled)"; [ -n "$enabled" ] || enabled="0"
off_time="$(uci_get off_time)"; on_time="$(uci_get on_time)"
[ -n "$off_time" ] || off_time="23:00"
[ -n "$on_time" ] || on_time="07:00"
strip_cron_block
if [ "$enabled" != "1" ]; then reload_cron; log "scheduler disabled; cron entries removed"; return 0; fi
validate_time "$off_time" || { echo "Invalid off_time: $off_time" >&2; return 1; }
validate_time "$on_time" || { echo "Invalid on_time: $on_time" >&2; return 1; }
set -- $(time_parts "$off_time"); off_h="$1"; off_m="$2"
set -- $(time_parts "$on_time"); on_h="$1"; on_m="$2"
{
printf '%s\n' "$CRON_BEGIN"
printf '%s %s * * * /usr/bin/led-control off\n' "$off_m" "$off_h"
printf '%s %s * * * /usr/bin/led-control on\n' "$on_m" "$on_h"
printf '%s\n' "$CRON_END"
} >> "$CRON_FILE"
reload_cron
log "cron synchronized: off=${off_time}, on=${on_time}"
}
minutes_from_time() {
local t="$1" h m
set -- $(time_parts "$t"); h="$1"; m="$2"
echo $((h * 60 + m))
}
apply_current_state() {
local enabled off_time on_time now_h now_m now off on
enabled="$(uci_get enabled)"
if [ "$enabled" != "1" ]; then turn_on; return $?; fi
off_time="$(uci_get off_time)"; on_time="$(uci_get on_time)"
[ -n "$off_time" ] || off_time="23:00"
[ -n "$on_time" ] || on_time="07:00"
validate_time "$off_time" || return 1
validate_time "$on_time" || return 1
off="$(minutes_from_time "$off_time")"; on="$(minutes_from_time "$on_time")"
if [ "$off" -eq "$on" ]; then turn_on; return $?; fi
now_h="$(date +%H)"; now_m="$(date +%M)"
now_h="${now_h#0}"; now_m="${now_m#0}"
[ -n "$now_h" ] || now_h=0; [ -n "$now_m" ] || now_m=0
now=$((now_h * 60 + now_m))
if [ "$off" -lt "$on" ]; then
if [ "$now" -ge "$off" ] && [ "$now" -lt "$on" ]; then turn_off; else turn_on; fi
else
if [ "$now" -ge "$off" ] || [ "$now" -lt "$on" ]; then turn_off; else turn_on; fi
fi
}
list_configured() {
local section name sysfs trigger
uci -q show system 2>/dev/null |
sed -n 's/^system\.\([^=]*\)=led$/\1/p' |
while IFS= read -r section; do
name="$(uci -q get "system.${section}.name" 2>/dev/null)"
sysfs="$(uci -q get "system.${section}.sysfs" 2>/dev/null)"
trigger="$(uci -q get "system.${section}.trigger" 2>/dev/null)"
[ -n "$sysfs" ] || continue
printf '%s %s %s\n' "${name:-$sysfs}" "$sysfs" "${trigger:-unknown}"
done
}
status() {
echo "enabled=$(uci_get enabled)"
echo "off_time=$(uci_get off_time)"
echo "on_time=$(uci_get on_time)"
echo "all_system_leds=$(uci_get all_system_leds)"
echo "selected sysfs LEDs:"
selected_leds | sed 's/^/ - /'
}
usage() {
cat <<'EOF'
Usage: led-control COMMAND
Commands:
list List LEDs defined by OpenWrt System -> LED Configuration
selected List LEDs currently selected by LED Scheduler
off Turn selected LEDs off
on Restore OpenWrt native LED configuration
apply Apply the correct state for the current time
sync Synchronize cron entries from UCI configuration
clear-cron Remove this application's cron entries
status Show scheduler configuration
EOF
}
case "$1" in
list) list_configured ;;
selected) selected_leds ;;
off) turn_off ;;
on) turn_on ;;
apply) apply_current_state ;;
sync) sync_cron ;;
clear-cron) clear_cron ;;
status) status ;;
*) usage; exit 1 ;;
esac
@@ -0,0 +1,13 @@
{
"admin/system/led-scheduler": {
"title": "LED 定时",
"order": 91,
"action": {
"type": "view",
"path": "led-scheduler/main"
},
"depends": {
"acl": [ "luci-app-led-scheduler" ]
}
}
}
@@ -0,0 +1,19 @@
{
"luci-app-led-scheduler": {
"description": "Grant access to LED Scheduler",
"read": {
"uci": [
"led-scheduler",
"system"
]
},
"write": {
"file": {
"/usr/bin/led-control": [ "exec" ]
},
"uci": [
"led-scheduler"
]
}
}
}
Loaded 3 of 12 files, more files were not shown because too many files have changed in this diff. Show more