aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-03-13 02:49:33 +0100
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-03-13 02:52:46 +0100
commit4911e897496d92af6b2d5105a7581bee4da8c5bf (patch)
tree25ffe3fcb9af72bbfbcd8fb6440bd999e0ae6cd7
parentfe0369e835dadefb33616939627f28adfe937492 (diff)
Fork
-rw-r--r--sleepwalk232
1 files changed, 151 insertions, 81 deletions
diff --git a/sleepwalk b/sleepwalk
index eb4071c..a87fb41 100644
--- a/sleepwalk
+++ b/sleepwalk
@@ -1,121 +1,191 @@
#!/bin/bash
-SLEEP_SECS=600
-WAKE_SECS=30
+SLEEP_SECS_INIT=30
+SLEEP_SECS=$SLEEP_SECS_INIT
+SLEEP_STEP=180
+SLEEP_MAX_SECS=600
+WAKE_SECS=35
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() {
- led_sleep
- echo mem > /sys/power/state 2>/dev/null
- return $?
+ led_sleep
+
+ 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() {
- secs=$WAKE_SECS
- is_led_on=0
- while [ $secs -ge 0 ]; do
- sleep 1
- if [ $is_led_on == 0 ]; then
- led_wake
- is_led_on=1
- else
- led_disable
- is_led_on=0
- fi
-
- if is_screen_on_or_inhibitor_active; then
- break
- fi
- secs=$(($secs-1))
- done
- led_disable
+ secs=$WAKE_SECS
+ is_led_on=0
+ while [ $secs -ge 0 ]; do
+ sleep 1
+ if [ $is_led_on == 0 ]; then
+ led_wake
+ is_led_on=1
+ else
+ led_disable
+ is_led_on=0
+ fi
+
+ if is_screen_on; then
+ if is_charging; then
+ cpufreq-set -g conservative
+ else
+ cpufreq-set -g powersave
+ fi
+ set_cpu_online
+ break
+ fi
+ set_cpu_offline
+ secs=$(($secs-1))
+ done
+ led_disable
}
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() {
- led_wake
- > /sys/class/rtc/rtc0/wakealarm
+ led_wake
+ > /sys/class/rtc/rtc0/wakealarm
}
-is_screen_on_or_inhibitor_active() {
- INHIBITORS=$(systemd-inhibit --list --no-legend \
- | grep -e '[[:space:]]sleep[[:space:]]' \
- | grep -e 'lock$')
+is_charging() {
+ [ "$(cat /sys/class/power_supply/axp20x-usb/online)" = "1" ]
+}
+
+is_inhibitor_active() {
+ # 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)
+ # printf "%s\n" "$INHIBITORS"
+ INHIBITORS=$(systemd-inhibit --list --what=sleep --mode=block --no-legend \
+ | grep -e 'sleep')
- if [ "$INHIBITORS" != "" ]; then
- return 0
- fi
+ [ -n "$INHIBITORS" ]
+ # if [ "$INHIBITORS" = "No inhibitors" ]; then
+ # return 1
+ # fi
+
+ # return 0
+}
- return "$(cat /sys/class/backlight/backlight/bl_power)"
+is_screen_on() {
+ return "$(cat /sys/class/backlight/backlight/bl_power)"
+}
+
+can_suspend() {
+ ! ( is_inhibitor_active || is_screen_on || is_charging )
}
led_sleep() {
- echo 1 > /sys/class/leds/green\:indicator/brightness
- echo 0 > /sys/class/leds/red\:indicator/brightness
- echo 0 > /sys/class/leds/blue\:indicator/brightness
+ :
+ # echo 1 > /sys/class/leds/green\:indicator/brightness
+ # echo 0 > /sys/class/leds/red\:indicator/brightness
+ # echo 0 > /sys/class/leds/blue\:indicator/brightness
}
led_wake() {
- echo 0 > /sys/class/leds/green\:indicator/brightness
- echo 1 > /sys/class/leds/red\:indicator/brightness
- echo 0 > /sys/class/leds/blue\:indicator/brightness
+ :
+ # echo 0 > /sys/class/leds/green\:indicator/brightness
+ # echo 1 > /sys/class/leds/red\:indicator/brightness
+ # echo 0 > /sys/class/leds/blue\:indicator/brightness
}
led_disable() {
- echo 0 > /sys/class/leds/green\:indicator/brightness
- echo 0 > /sys/class/leds/red\:indicator/brightness
- echo 0 > /sys/class/leds/blue\:indicator/brightness
+ :
+ # echo 0 > /sys/class/leds/green\:indicator/brightness
+ # echo 0 > /sys/class/leds/red\:indicator/brightness
+ # echo 0 > /sys/class/leds/blue\:indicator/brightness
}
if [ $EUID -ne 0 ]; then
- echo "Needs root" >&2
- exit 1
+ echo "Needs root" >&2
+ exit 1
fi
if [ -z "$1" ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
- cat <<-EOF >&2
- Usage: sleepwalk [start/stop]
- Commands:
- start Start sleep cycle
- stop Stop sleep cycle
- EOF
- exit
+ cat <<-EOF >&2
+ Usage: sleepwalk [start/stop]
+ Commands:
+ start Start sleep cycle
+ stop Stop sleep cycle
+EOF
+ exit
fi
if [ "$1" == "start" ]; then
- if [ -d "$LOCK_DIR" ] || ! mkdir "$LOCK_DIR"; then
- echo "sleepwalk is already running - run 'sleepwalk stop' to stop it" >&2
- exit 1
- fi
- trap "$0 stop" EXIT
-
- while [ -d "$LOCK_DIR" ]; do
- while is_screen_on_or_inhibitor_active; do
- sleep 60
- 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 is_screen_on_or_inhibitor_active; then
- break
+ if [ -d "$LOCK_DIR" ] || ! mkdir "$LOCK_DIR"; then
+ echo "sleepwalk is already running - run 'sleepwalk stop' to stop it" >&2
+ exit 1
+ fi
+ trap "$0 stop" EXIT
+
+ while [ -d "$LOCK_DIR" ]; do
+ while ! can_suspend; do
+ set_cpu_online
+
+ if is_charging && is_screen_on; then
+ cpufreq-set -g conservative
+ else
+ cpufreq-set -g powersave
fi
- done
- wait_for_notifications
- done
+
+ sleep 10
+ 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
- reset_wake_time
- led_disable
- rmdir "$LOCK_DIR" 2>/dev/null
+ reset_wake_time
+ led_disable
+ rmdir "$LOCK_DIR" 2>/dev/null
else
- echo "Unknown command: $1" >&2
- exit 1
+ echo "Unknown command: $1" >&2
+ exit 1
fi