aboutsummaryrefslogtreecommitdiff
path: root/dotfiles/hyprland/.local/bin/airplane-mode
blob: 4f5ed9c1ec32a0780d0afd0c2f8d991d52f96f6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/bin/sh
# airplane-mode — toggle a low-power "airplane" state for a laptop.
#
# Engage: record the current state of each lever, then apply low-power values:
#   - wifi off (nmcli; bluetooth is left alone, on purpose — earbuds)
#   - CPU energy-performance preference -> power (intel_pstate, via sysfs)
#   - display brightness dimmed
#   - stop network-only services (VPNs, sync, discovery, inbound SSH)
# Disengage: read the recorded state and restore exactly what was there. A
# lever already in its low-power position before engaging (e.g. wifi already
# off, a service already stopped) is left untouched on disengage.
#
# State lives at $XDG_RUNTIME_DIR/airplane-state as key=value lines. The
# waybar-airplane indicator reads `mode` from it.
#
# Env knobs (defaults are the real system; tests override them):
#   AIRPLANE_EPP_GLOB        glob of EPP sysfs files
#   AIRPLANE_BRIGHTNESS_LOW  brightnessctl target while engaged
#   AIRPLANE_SYSTEM_SERVICES system units to stop (sudo)
#   AIRPLANE_USER_SERVICES   --user units to stop

STATE_FILE="${XDG_RUNTIME_DIR:-/tmp}/airplane-state"
SUDO="${AIRPLANE_SUDO:-sudo}"
EPP_GLOB="${AIRPLANE_EPP_GLOB:-/sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference}"
BRIGHTNESS_LOW="${AIRPLANE_BRIGHTNESS_LOW:-35%}"
SYSTEM_SERVICES="${AIRPLANE_SYSTEM_SERVICES:-tailscaled.service proton.VPN.service avahi-daemon.service cups.service wsdd.service geoclue.service sshd.service fail2ban.service}"
USER_SERVICES="${AIRPLANE_USER_SERVICES:-syncthing.service}"

read_key() { sed -n "s/^$1=//p" "$STATE_FILE" 2>/dev/null | head -n1; }

set_epp() {
    # Write $1 to every EPP file. Needs root; glob expands inside the subshell.
    $SUDO sh -c "for f in $EPP_GLOB; do [ -e \"\$f\" ] && echo $1 > \"\$f\"; done" 2>/dev/null
}

first_epp() {
    for f in $EPP_GLOB; do
        [ -e "$f" ] && { cat "$f"; return; }
    done
}

engage() {
    # --- record current state ---
    wifi_was=$(nmcli radio wifi 2>/dev/null)
    epp_was=$(first_epp)
    bright_was=$(brightnessctl get 2>/dev/null)

    stopped_system=""
    for s in $SYSTEM_SERVICES; do
        if systemctl is-active --quiet "$s" 2>/dev/null; then
            $SUDO systemctl stop "$s" 2>/dev/null && stopped_system="$stopped_system $s"
        fi
    done
    stopped_user=""
    for s in $USER_SERVICES; do
        if systemctl --user is-active --quiet "$s" 2>/dev/null; then
            systemctl --user stop "$s" 2>/dev/null && stopped_user="$stopped_user $s"
        fi
    done

    # --- apply low-power settings ---
    nmcli radio wifi off 2>/dev/null
    set_epp power
    brightnessctl set "$BRIGHTNESS_LOW" >/dev/null 2>&1

    # --- persist what we recorded ---
    {
        echo "mode=on"
        echo "wifi=$wifi_was"
        echo "epp=$epp_was"
        echo "brightness=$bright_was"
        echo "stopped_system=$stopped_system"
        echo "stopped_user=$stopped_user"
    } > "$STATE_FILE"

    notify info "Airplane mode" "ON — wifi off, low power" 2>/dev/null
}

disengage() {
    wifi_was=$(read_key wifi)
    epp_was=$(read_key epp)
    bright_was=$(read_key brightness)
    stopped_system=$(read_key stopped_system)
    stopped_user=$(read_key stopped_user)

    # Only restore a lever that was NOT already in its low-power state.
    [ "$wifi_was" = "enabled" ] && nmcli radio wifi on 2>/dev/null
    [ -n "$epp_was" ] && set_epp "$epp_was"
    [ -n "$bright_was" ] && brightnessctl set "$bright_was" >/dev/null 2>&1

    for s in $stopped_system; do
        $SUDO systemctl start "$s" 2>/dev/null
    done
    for s in $stopped_user; do
        systemctl --user start "$s" 2>/dev/null
    done

    echo "mode=off" > "$STATE_FILE"
    notify info "Airplane mode" "OFF — settings restored" 2>/dev/null
}

case "$(read_key mode)" in
    on) disengage ;;
    *)  engage ;;
esac

# Refresh the waybar indicator immediately (custom/airplane listens on signal 10).
pkill -RTMIN+10 waybar 2>/dev/null

exit 0