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