Add screen brightness
[khatus.git] / bin / khatus_loop
CommitLineData
438d0d5f
SK
1#! /bin/bash
2
4d314e0f
SK
3set -e
4
bbb42518
SK
5produce_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
61e5a351
SK
13produce_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
365549a9
SK
36produce_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
88produce_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}
438d0d5f 122
6339a4f8 123produce_weather() {
4d314e0f
SK
124 weather_station_id="$1"
125 metar -d "$weather_station_id" 2>&1 \
438d0d5f
SK
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
6339a4f8 145produce_datetime() {
438d0d5f
SK
146 date +'%a %b %d %H:%M:%S'
147}
148
6339a4f8 149consume() {
438d0d5f
SK
150 pipe="$1"
151 tail -f "$pipe" \
152 | stdbuf -o L awk \
365549a9
SK
153 -v opt_debug=0 \
154 -v opt_mpd_song_max_chars=10 \
438d0d5f 155 '
bbb42518
SK
156 /^in:SCREEN_BRIGHTNESS/\
157 {
158 split_msg_parts()
159 set_screen_brightness()
160 }
161
61e5a351
SK
162 /^in:VOLUME/\
163 {
164 split_msg_parts()
165 db["volume"] = msg_body
166 }
167
365549a9
SK
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/\
438d0d5f 177 {
365549a9
SK
178 split_msg_parts()
179 db["mpd_curr_song_name"] = msg_body
438d0d5f
SK
180 }
181
365549a9 182 /^in:WEATHER/\
438d0d5f 183 {
365549a9
SK
184 split_msg_parts()
185 db["weather_temperature"] = msg_body
438d0d5f
SK
186 }
187
365549a9 188 /^in:DATE_TIME/\
438d0d5f 189 {
365549a9
SK
190 split_msg_parts()
191 db["datetime"] = msg_body
192 }
193
194 /^out:BAR/\
195 {
196 split_msg_parts()
438d0d5f
SK
197 print make_bar()
198 }
199
365549a9 200
bbb42518
SK
201 function set_screen_brightness( max, cur) {
202 max = $1
203 cur = $2
204 db["screen_brightness"] = (cur / max) * 100
205 }
206
365549a9
SK
207 function split_msg_parts() {
208 msg_head = $1
209 sub("^" msg_head " +", "")
210 msg_body = $0
211 debug(msg_head, msg_body)
438d0d5f
SK
212 }
213
365549a9 214 function make_bar( position, bar, sep, i, j) {
bbb42518 215 position[++i] = sprintf("*%d%%", db["screen_brightness"])
61e5a351 216 position[++i] = sprintf("(%s)", db["volume"])
365549a9 217 position[++i] = make_status_mpd()
438d0d5f
SK
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 }
365549a9
SK
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 }
438d0d5f
SK
268 '
269}
270
6339a4f8 271produce_bar_req() {
438d0d5f
SK
272 echo ''
273}
274
275spawn() {
276 cmd="$1"
277 pipe="$2"
365549a9 278 msg_head="$3"
438d0d5f
SK
279 interval="$4"
280 while true; do
365549a9 281 echo "${msg_head} $($cmd)" > "$pipe"
438d0d5f
SK
282 sleep "$interval"
283 done &
284}
285
286main() {
4d314e0f
SK
287 # Defaults
288 dir_data="$HOME/.khatus"
289 weather_station_id='KJFK'
bbb42518 290 screen_brightness_device_name='acpi_video0'
4d314e0f
SK
291
292 # User-overrides
293 OPTS=$(
294 getopt \
295 -o '' \
bbb42518 296 -l data-dir:,weather-station:screen-device: \
4d314e0f
SK
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 ;;
bbb42518
SK
311 --screen-device)
312 screen_brightness_device_name="$2"
313 shift 2
314 ;;
4d314e0f
SK
315 --)
316 shift
317 break
318 ;;
319 esac
320 done
321
0c0ebbe1 322 pipe="$dir_data/khatus_data_pipe"
bbb42518
SK
323 screen_brightness_device_path='/sys/class/backlight'
324 screen_brightness_device_path+="/$screen_brightness_device_name"
0c0ebbe1 325
4d314e0f
SK
326 ( echo "Khatus starting with the following parameters:"
327 ( echo " dir_data|= $dir_data"
0c0ebbe1 328 echo " pipe|= $pipe"
bbb42518
SK
329 echo " screen_brightness_device_name|=$screen_brightness_device_name"
330 echo " screen_brightness_device_path|=$screen_brightness_device_path"
4d314e0f
SK
331 echo " weather_station_id|= $weather_station_id"
332 ) | column -ts\|
333 echo ''
334 ) >&2
335
4d314e0f 336 mkdir -p "$dir_data"
438d0d5f
SK
337 rm -f "$pipe"
338 mkfifo "$pipe"
339
bbb42518
SK
340 cmd_produce_screen_brightness='produce_screen_brightness'
341 cmd_produce_screen_brightness+=" $screen_brightness_device_path"
0c0ebbe1
SK
342 cmd_produce_weather="produce_weather $weather_station_id"
343
4d314e0f 344 # TODO: Redirect each worker's stderr to a dedicated log file
0c0ebbe1 345 spawn produce_datetime "$pipe" 'in:DATE_TIME' 1
bbb42518 346 spawn "$cmd_produce_screen_brightness" "$pipe" 'in:SCREEN_BRIGHTNESS' 1
0c0ebbe1
SK
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"
438d0d5f
SK
353}
354
355main $@
This page took 0.080876 seconds and 4 git commands to generate.