This commit is contained in:
Xavier Del Campo Romero 2023-03-13 02:49:33 +01:00
parent fe0369e835
commit 4911e89749
Signed by: xavi
GPG Key ID: 84FF3612A9BF43F2
1 changed files with 148 additions and 78 deletions

226
sleepwalk
View File

@ -1,121 +1,191 @@
#!/bin/bash #!/bin/bash
SLEEP_SECS=600 SLEEP_SECS_INIT=30
WAKE_SECS=30 SLEEP_SECS=$SLEEP_SECS_INIT
SLEEP_STEP=180
SLEEP_MAX_SECS=600
WAKE_SECS=35
LOCK_DIR="/tmp/sleepwalk" LOCK_DIR="/tmp/sleepwalk"
CPU_STATE=1
set_cpu_offline() {
if [ $CPU_STATE -eq 1 ]; then
echo "Powering off all CPU cores except cpu0"
for i in $(seq 2); do
echo 0 > /sys/devices/system/cpu/cpu$i/online
done
CPU_STATE=0
fi
}
set_cpu_online() {
SLEEP_SECS=$SLEEP_SECS_INIT
if [ $CPU_STATE -eq 0 ]; then
echo "Powering on all CPU cores except cpu0"
for i in $(seq 2); do
echo 1 > /sys/devices/system/cpu/cpu$i/online
done
CPU_STATE=1
fi
}
start_deep_sleep() { start_deep_sleep() {
led_sleep led_sleep
echo mem > /sys/power/state 2>/dev/null
return $? if [ $((SLEEP_SECS + $SLEEP_STEP)) -lt $SLEEP_MAX_SECS ]; then
SLEEP_SECS=$((SLEEP_SECS + SLEEP_STEP))
else
SLEEP_SECS=$SLEEP_MAX_SECS
fi
sleep 5 # Give some extra time for pending output data
if [ can_suspend ]; then
echo mem > /sys/power/state 2>/dev/null
fi
return $?
} }
wait_for_notifications() { wait_for_notifications() {
secs=$WAKE_SECS secs=$WAKE_SECS
is_led_on=0 is_led_on=0
while [ $secs -ge 0 ]; do while [ $secs -ge 0 ]; do
sleep 1 sleep 1
if [ $is_led_on == 0 ]; then if [ $is_led_on == 0 ]; then
led_wake led_wake
is_led_on=1 is_led_on=1
else else
led_disable led_disable
is_led_on=0 is_led_on=0
fi fi
if is_screen_on_or_inhibitor_active; then if is_screen_on; then
break if is_charging; then
fi cpufreq-set -g conservative
secs=$(($secs-1)) else
done cpufreq-set -g powersave
led_disable fi
set_cpu_online
break
fi
set_cpu_offline
secs=$(($secs-1))
done
led_disable
} }
schedule_wake_time() { schedule_wake_time() {
rtcwake -m no --date "+${SLEEP_SECS}s" 2>&1 >/dev/null echo "Sleeping for ${SLEEP_SECS}s"
rtcwake -m no --date "+${SLEEP_SECS}s" 2>&1 >/dev/null
} }
reset_wake_time() { reset_wake_time() {
led_wake led_wake
> /sys/class/rtc/rtc0/wakealarm > /sys/class/rtc/rtc0/wakealarm
} }
is_screen_on_or_inhibitor_active() { is_charging() {
INHIBITORS=$(systemd-inhibit --list --no-legend \ [ "$(cat /sys/class/power_supply/axp20x-usb/online)" = "1" ]
| grep -e '[[:space:]]sleep[[:space:]]' \ }
| grep -e 'lock$')
if [ "$INHIBITORS" != "" ]; then is_inhibitor_active() {
return 0 # INHIBITORS=$(sudo -u "$(cat /proc/$(pidof -s gnome-session-ctl)/environ | grep -z USER | sed 's,\x0,,;s,USER=,,')" DBUS_SESSION_BUS_ADDRESS=$(cat /proc/$(pidof -s gnome-session-ctl)/environ | grep -z DBUS_SESSION_BUS_ADDRESS | sed "s,\x0,,;s,DBUS_SESSION_BUS_ADDRESS=,,") gnome-session-inhibit --list)
fi # printf "%s\n" "$INHIBITORS"
INHIBITORS=$(systemd-inhibit --list --what=sleep --mode=block --no-legend \
| grep -e 'sleep')
return "$(cat /sys/class/backlight/backlight/bl_power)" [ -n "$INHIBITORS" ]
# if [ "$INHIBITORS" = "No inhibitors" ]; then
# return 1
# fi
# return 0
}
is_screen_on() {
return "$(cat /sys/class/backlight/backlight/bl_power)"
}
can_suspend() {
! ( is_inhibitor_active || is_screen_on || is_charging )
} }
led_sleep() { led_sleep() {
echo 1 > /sys/class/leds/green\:indicator/brightness :
echo 0 > /sys/class/leds/red\:indicator/brightness # echo 1 > /sys/class/leds/green\:indicator/brightness
echo 0 > /sys/class/leds/blue\:indicator/brightness # echo 0 > /sys/class/leds/red\:indicator/brightness
# echo 0 > /sys/class/leds/blue\:indicator/brightness
} }
led_wake() { led_wake() {
echo 0 > /sys/class/leds/green\:indicator/brightness :
echo 1 > /sys/class/leds/red\:indicator/brightness # echo 0 > /sys/class/leds/green\:indicator/brightness
echo 0 > /sys/class/leds/blue\:indicator/brightness # echo 1 > /sys/class/leds/red\:indicator/brightness
# echo 0 > /sys/class/leds/blue\:indicator/brightness
} }
led_disable() { led_disable() {
echo 0 > /sys/class/leds/green\:indicator/brightness :
echo 0 > /sys/class/leds/red\:indicator/brightness # echo 0 > /sys/class/leds/green\:indicator/brightness
echo 0 > /sys/class/leds/blue\:indicator/brightness # echo 0 > /sys/class/leds/red\:indicator/brightness
# echo 0 > /sys/class/leds/blue\:indicator/brightness
} }
if [ $EUID -ne 0 ]; then if [ $EUID -ne 0 ]; then
echo "Needs root" >&2 echo "Needs root" >&2
exit 1 exit 1
fi fi
if [ -z "$1" ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then if [ -z "$1" ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
cat <<-EOF >&2 cat <<-EOF >&2
Usage: sleepwalk [start/stop] Usage: sleepwalk [start/stop]
Commands: Commands:
start Start sleep cycle start Start sleep cycle
stop Stop sleep cycle stop Stop sleep cycle
EOF EOF
exit exit
fi fi
if [ "$1" == "start" ]; then if [ "$1" == "start" ]; then
if [ -d "$LOCK_DIR" ] || ! mkdir "$LOCK_DIR"; then if [ -d "$LOCK_DIR" ] || ! mkdir "$LOCK_DIR"; then
echo "sleepwalk is already running - run 'sleepwalk stop' to stop it" >&2 echo "sleepwalk is already running - run 'sleepwalk stop' to stop it" >&2
exit 1 exit 1
fi fi
trap "$0 stop" EXIT trap "$0 stop" EXIT
while [ -d "$LOCK_DIR" ]; do while [ -d "$LOCK_DIR" ]; do
while is_screen_on_or_inhibitor_active; do while ! can_suspend; do
sleep 60 set_cpu_online
done
reset_wake_time if is_charging && is_screen_on; then
schedule_wake_time cpufreq-set -g conservative
else
while ! start_deep_sleep; do cpufreq-set -g powersave
reset_wake_time
echo "Failed going to sleep, try again in $WAKE_SECS seconds ..." >&2
wait_for_notifications
schedule_wake_time
if is_screen_on_or_inhibitor_active; then
break
fi fi
done
wait_for_notifications sleep 10
done done
reset_wake_time
schedule_wake_time
while ! start_deep_sleep; do
reset_wake_time
echo "Failed going to sleep, try again in $WAKE_SECS seconds ..." >&2
wait_for_notifications
schedule_wake_time
if ! can_suspend; then
break
fi
done
wait_for_notifications
done
elif [ "$1" == "stop" ]; then elif [ "$1" == "stop" ]; then
reset_wake_time reset_wake_time
led_disable led_disable
rmdir "$LOCK_DIR" 2>/dev/null rmdir "$LOCK_DIR" 2>/dev/null
else else
echo "Unknown command: $1" >&2 echo "Unknown command: $1" >&2
exit 1 exit 1
fi fi