Add screen brightness
[khatus.git] / bin / khatus_loop
1 #! /bin/bash
2
3 set -e
4
5 produce_screen_brightness() {
6 screen_brightness_device_path="$1"
7 echo "\
8 $(cat $screen_brightness_device_path/max_brightness) \
9 $(cat $screen_brightness_device_path/brightness)\
10 "
11 }
12
13 produce_volume() {
14 pactl list sinks \
15 | awk '
16 /^\tMute:/ {
17 printf("%s,", $0);
18 }
19 /^\tVolume:/ {
20 for (i=2; i<=NF; i++) printf(" %s", $i);
21 }' \
22 | awk -v RS=',' '
23 /^[ \t]*Mute:/ {mute = $2}
24 /^[ \t]*front-left:/ {left = $4}
25 /^[ \t]*front-right:/ {right = $4}
26 END {
27 if (mute == "yes") {
28 printf("x")
29 } else {
30 printf("%s %s", left, right)
31 }
32 }
33 '
34 }
35
36 produce_mpd_state() {
37 echo 'status' \
38 | nc 127.0.0.1 6600 \
39 | awk '
40 {
41 status[$1] = $2
42 }
43
44 /^time: +[0-9]+:[0-9]+$/ {
45 split($2, time, ":")
46 seconds_current = time[1]
47 seconds_total = time[2]
48
49 hours = int(seconds_current / 60 / 60);
50 secs_beyond_hours = seconds_current - (hours * 60 * 60);
51 mins = int(secs_beyond_hours / 60);
52 secs = secs_beyond_hours - (mins * 60);
53 if (hours > 0) {
54 current_time = sprintf("%d:%.2d:%.2d", hours, mins, secs)
55 } else {
56 current_time = sprintf("%.2d:%.2d", mins, secs)
57 }
58
59 if (seconds_total > 0) {
60 time_percentage = (seconds_current / seconds_total) * 100
61 current_percentage = sprintf("%d%%", time_percentage)
62 } else {
63 current_percentage = "~"
64 }
65 }
66
67 END {
68 state = status["state:"]
69
70 if (state == "play") {
71 symbol = "▶"
72 } else if (state == "pause") {
73 symbol = "❚❚"
74 } else if (state == "stop") {
75 symbol = "⬛"
76 } else {
77 symbol = "--"
78 }
79
80 printf(\
81 "%s %s %s",
82 status["state:"], current_time, current_percentage\
83 )
84 }
85 '
86 }
87
88 produce_mpd_song() {
89 echo 'currentsong' \
90 | nc 127.0.0.1 6600 \
91 | awk '
92 /^OK/ {
93 next
94 }
95
96 {
97 key = $1
98 sub("^" key " +", "")
99 val = $0
100 data[key] = val
101 }
102
103 END {
104 name = data["Name:"]
105 title = data["Title:"]
106 file = data["file:"]
107
108 if (name) {
109 out = name
110 } else if (title) {
111 out = title
112 } else if (file) {
113 last = split(file, parts, "/")
114 out = parts[last]
115 } else {
116 out = ""
117 }
118 print out
119 }
120 '
121 }
122
123 produce_weather() {
124 weather_station_id="$1"
125 metar -d "$weather_station_id" 2>&1 \
126 | awk '
127 /METAR pattern not found in NOAA data/ {
128 failures++
129 }
130
131 /^Temperature/ {
132 celsius = $3;
133 fahrenheit = (celsius * (9 / 5)) + 32;
134 temperature = fahrenheit
135 }
136
137 END {
138 if (failures > 0) {
139 temperature = "--"
140 }
141 print temperature "°F"
142 }'
143 }
144
145 produce_datetime() {
146 date +'%a %b %d %H:%M:%S'
147 }
148
149 consume() {
150 pipe="$1"
151 tail -f "$pipe" \
152 | stdbuf -o L awk \
153 -v opt_debug=0 \
154 -v opt_mpd_song_max_chars=10 \
155 '
156 /^in:SCREEN_BRIGHTNESS/\
157 {
158 split_msg_parts()
159 set_screen_brightness()
160 }
161
162 /^in:VOLUME/\
163 {
164 split_msg_parts()
165 db["volume"] = msg_body
166 }
167
168 /^in:MPD_STATE/\
169 {
170 split_msg_parts()
171 db["mpd_state"] = $1
172 db["mpd_curr_song_time"] = $2
173 db["mpd_curr_song_percent"] = $3
174 }
175
176 /^in:MPD_SONG/\
177 {
178 split_msg_parts()
179 db["mpd_curr_song_name"] = msg_body
180 }
181
182 /^in:WEATHER/\
183 {
184 split_msg_parts()
185 db["weather_temperature"] = msg_body
186 }
187
188 /^in:DATE_TIME/\
189 {
190 split_msg_parts()
191 db["datetime"] = msg_body
192 }
193
194 /^out:BAR/\
195 {
196 split_msg_parts()
197 print make_bar()
198 }
199
200
201 function set_screen_brightness( max, cur) {
202 max = $1
203 cur = $2
204 db["screen_brightness"] = (cur / max) * 100
205 }
206
207 function split_msg_parts() {
208 msg_head = $1
209 sub("^" msg_head " +", "")
210 msg_body = $0
211 debug(msg_head, msg_body)
212 }
213
214 function make_bar( position, bar, sep, i, j) {
215 position[++i] = sprintf("*%d%%", db["screen_brightness"])
216 position[++i] = sprintf("(%s)", db["volume"])
217 position[++i] = make_status_mpd()
218 position[++i] = db["weather_temperature"]
219 position[++i] = db["datetime"]
220 bar = ""
221 sep = ""
222 for (j = 1; j <= i; j++) {
223 bar = bar sep position[j]
224 sep = " "
225 }
226 return bar
227 }
228
229 function make_status_mpd( state, status) {
230 state = db["mpd_state"]
231
232 if (state == "play") {
233 status = make_status_mpd_state_known("▶")
234 } else if (state == "pause") {
235 status = make_status_mpd_state_known("❚❚")
236 } else if (state == "stop") {
237 status = make_status_mpd_state_known("⬛")
238 } else {
239 status = make_status_mpd_state_unknown("--")
240 }
241
242 return sprintf("[%s]", status)
243 }
244
245 function make_status_mpd_state_known(symbol) {
246 return sprintf(\
247 "%s %s %s %s",
248 symbol,
249 db["mpd_curr_song_time"],
250 db["mpd_curr_song_percent"],
251 substr(db["mpd_curr_song_name"], 1, opt_mpd_song_max_chars)\
252 )
253 }
254
255 function make_status_mpd_state_unknown(symbol) {
256 return sprintf("%s", symbol)
257 }
258
259 function debug(location, msg) {
260 if (opt_debug) {
261 print_error(location, msg)
262 }
263 }
264
265 function print_error(location, msg) {
266 print(location " ==> " msg) > "/dev/stderr"
267 }
268 '
269 }
270
271 produce_bar_req() {
272 echo ''
273 }
274
275 spawn() {
276 cmd="$1"
277 pipe="$2"
278 msg_head="$3"
279 interval="$4"
280 while true; do
281 echo "${msg_head} $($cmd)" > "$pipe"
282 sleep "$interval"
283 done &
284 }
285
286 main() {
287 # Defaults
288 dir_data="$HOME/.khatus"
289 weather_station_id='KJFK'
290 screen_brightness_device_name='acpi_video0'
291
292 # User-overrides
293 OPTS=$(
294 getopt \
295 -o '' \
296 -l data-dir:,weather-station:screen-device: \
297 -- "$@"
298 )
299 eval set -- "$OPTS"
300 while true
301 do
302 case "$1" in
303 --data-dir)
304 dir_data="$2"
305 shift 2
306 ;;
307 --weather-station)
308 weather_station_id="$2"
309 shift 2
310 ;;
311 --screen-device)
312 screen_brightness_device_name="$2"
313 shift 2
314 ;;
315 --)
316 shift
317 break
318 ;;
319 esac
320 done
321
322 pipe="$dir_data/khatus_data_pipe"
323 screen_brightness_device_path='/sys/class/backlight'
324 screen_brightness_device_path+="/$screen_brightness_device_name"
325
326 ( echo "Khatus starting with the following parameters:"
327 ( echo " dir_data|= $dir_data"
328 echo " pipe|= $pipe"
329 echo " screen_brightness_device_name|=$screen_brightness_device_name"
330 echo " screen_brightness_device_path|=$screen_brightness_device_path"
331 echo " weather_station_id|= $weather_station_id"
332 ) | column -ts\|
333 echo ''
334 ) >&2
335
336 mkdir -p "$dir_data"
337 rm -f "$pipe"
338 mkfifo "$pipe"
339
340 cmd_produce_screen_brightness='produce_screen_brightness'
341 cmd_produce_screen_brightness+=" $screen_brightness_device_path"
342 cmd_produce_weather="produce_weather $weather_station_id"
343
344 # TODO: Redirect each worker's stderr to a dedicated log file
345 spawn produce_datetime "$pipe" 'in:DATE_TIME' 1
346 spawn "$cmd_produce_screen_brightness" "$pipe" 'in:SCREEN_BRIGHTNESS' 1
347 spawn "$cmd_produce_weather" "$pipe" 'in:WEATHER' $(( 30 * 60 ))
348 spawn produce_mpd_state "$pipe" 'in:MPD_STATE' 1
349 spawn produce_mpd_song "$pipe" 'in:MPD_SONG' 1
350 spawn produce_volume "$pipe" 'in:VOLUME' 1
351 spawn produce_bar_req "$pipe" 'out:BAR' 1
352 consume "$pipe"
353 }
354
355 main $@
This page took 0.108705 seconds and 4 git commands to generate.