-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsuspend-hybrid
executable file
·204 lines (167 loc) · 4.31 KB
/
suspend-hybrid
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#!/usr/bin/env bash
# ┏━┓╻ ╻┏━┓┏━┓┏━╸┏┓╻╺┳┓
# ┗━┓┃ ┃┗━┓┣━┛┣╸ ┃┗┫ ┃┃
# ┗━┛┗━┛┗━┛╹ ┗━╸╹ ╹╺┻┛
# script to hibernate/suspend with `zzz/ZZZ`
#
# this script sets timers and lock files.
# dependency: 'hibernate-loop' script
PROG="${0##*/}"
CURRENT_TIME=$(date +%s)
LOGGER="${LOGS_PATH:-$HOME/dcs/log}/suspend-hibernate.log"
# AC offline in minutes
HIBERNATE_DELAY=${HIBERNATE_DELAY:-60}
# AC online in minutes
HIBERNATE_DELAY_CHAR=${HIBERNATE_DELAY_CHAR:-90}
# lock files
LOCKS=$HOME
SUSPEND_LOCK="$LOCKS"/suspend.lock
HIBERNATE_LOCK="$LOCKS/hibernate.lock"
WAKEUP_LOCK="$LOCKS/wakeup.lock"
TIMER="/tmp/timer.log"
function usage {
echo "Usage: $PROG [suspend|resume]"
exit 1
}
function logger {
local now
if [[ ! -f "$LOGGER" ]]; then
create_file "$LOGGER"
fi
now=$(date '+%F %T')
echo "[${now}]::[$PROG]::$1" | tee -a "$LOGGER"
}
function line {
local w char
w="79"
char="-"
printf "%${w}s\n" | sed "s/ /$char/g"
}
function remove_file {
local file="$1"
if [[ ! -f "$file" ]]; then
return
fi
rm -f "$file" && logger "removing $file"
sleep 0.5
}
function set_timer {
local time
time="$1"
logger "setting a wake-up timer for $time min"
# [mode: no] Don’t suspend, only set the RTC wakeup time.
sudo rtcwake --mode no --date "+${time}min"
log_to "$((time * 60))" "$TIMER"
}
function disable_timer {
logger "disabling the wake-up timer"
sudo rtcwake --mode disable
}
function create_file {
local file="$1"
touch "$file"
logger "creating $file"
sleep 1
}
function battery_status {
local bat_status bat_charge
bat_charge=$(cat /sys/class/power_supply/BAT0/capacity)
bat_status=$(cat /sys/class/power_supply/BAT0/status)
echo "$bat_status::${bat_charge}%"
}
function is_hibernate_mode {
if [[ ! -f "$WAKEUP_LOCK" ]]; then
return 1
fi
return 0
}
function is_ac_online {
# /sys/class/power_supply/AC/online
# online == 1 | offline == 0
local status
status=$(cat /sys/class/power_supply/AC/online)
if [[ "$status" = "0" ]]; then
return 1
fi
return 0
}
function quit {
local code="$1"
line | tee -a "$LOGGER"
exit "$code"
}
function title {
local mode
mode=$(echo "$1" | tr '[:lower:]' '[:upper:]')
logger "::::::::::::MODE $mode:::::::::::::"
}
function log_to {
local data="$1"
local file="$2"
echo "$data" >"$file"
}
function manual_hibernate {
create_file "$HIBERNATE_LOCK"
logger "setting for manual hibernate..."
quit 0
}
function suspend_mode {
if is_hibernate_mode; then
logger "$WAKEUP_LOCK exists"
logger "hibernating..."
quit 0
fi
if is_ac_online; then
logger "AC is online, update timer to $HIBERNATE_DELAY_CHAR min"
HIBERNATE_DELAY=$HIBERNATE_DELAY_CHAR
fi
log_to "$CURRENT_TIME" "$SUSPEND_LOCK"
set_timer "$HIBERNATE_DELAY"
logger "entering suspend-mode..."
}
function resume_mode {
# Woke up from hibernate
if is_hibernate_mode; then
remove_file "$WAKEUP_LOCK"
logger "waking up from hibernate-mode...yawn"
quit 0
fi
# Woke up from suspend
suspend_time=$(cat "$SUSPEND_LOCK")
timediff=$((CURRENT_TIME - suspend_time))
hibernate_delay=$(cat "$TIMER")
remove_file "$TIMER"
logger "timediff = $timediff"
logger "hibernate delay $hibernate_delay seconds"
# Woke up from timer
if [[ "$timediff" -ge "$hibernate_delay" ]]; then
logger "waking up from timer"
logger "setting up for hibernate-mode"
remove_file "$SUSPEND_LOCK"
create_file "$HIBERNATE_LOCK"
exit 0
fi
# Woke up by user activity
logger "waking up by user activity"
logger "system suspended for $((timediff / 60)) min"
remove_file "$SUSPEND_LOCK"
disable_timer
logger "waking up from suspend-mode...yawn"
separator
}
function main {
local mode="$1"
if [[ ! "$mode" =~ ^(suspend|resume|manual)$ ]]; then
usage
fi
title "$mode"
logger "battery::$(battery_status)"
case "$mode" in
suspend) suspend_mode ;;
resume) resume_mode ;;
manual) manual_hibernate ;;
*) usage ;;
esac
quit 0
}
main "$@"