💾 Archived View for xavi92.privatedns.org › sleepwalk.sh captured on 2023-05-24 at 17:38:01.

View Raw

More Information

⬅️ Previous capture (2023-01-29)

➡️ Next capture (2023-09-08)

-=-=-=-=-=-=-

#!/bin/bash

SLEEP_SECS_INIT=30
SLEEP_SECS=$SLEEP_SECS_INIT
SLEEP_STEP=90
SLEEP_MAX_SECS=240
WAKE_SECS=60
LOCK_DIR="/tmp/sleepwalk"
CPU_STATE=1

set_cpu_offline() {
        return 0
        if [ $CPU_STATE -eq 1 ]; then
                echo "Powering off all CPU cores except cpu0"
                for i in $(seq 3); do
                        echo 0 > /sys/devices/system/cpu/cpu$i/online
                done
                CPU_STATE=0
        fi
}

set_cpu_online() {
        SLEEP_SECS=$SLEEP_SECS_INIT
        return 0
        if [ $CPU_STATE -eq 0 ]; then
                echo "Powering on all CPU cores except cpu0"
                for i in $(seq 3); do
                        echo 1 > /sys/devices/system/cpu/cpu$i/online
                done
                CPU_STATE=1
        fi
}

start_deep_sleep() {
        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; then
                        set_cpu_online
                        break
                fi
                set_cpu_offline
                secs=$(($secs-1))
        done
        led_disable
}

schedule_wake_time() {
        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
}

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')

        [ -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() {
        :
        # 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
}

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
}

if [ $EUID -ne 0 ]; then
        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
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 ! can_suspend; do
                        set_cpu_online
                        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
else
        echo "Unknown command: $1" >&2
        exit 1
fi