Commit | Line | Data |
---|---|---|
438d0d5f SK |
1 | #! /bin/bash |
2 | ||
4d314e0f SK |
3 | set -e |
4 | ||
75b08dad SK |
5 | produce_energy() { |
6 | upower -e \ | |
7 | | grep battery \ | |
8 | | xargs upower -i \ | |
9 | | awk ' | |
10 | /^ +percentage: +/ { percentage=$2 } | |
11 | /^ +state: +/ { state=$2 } | |
12 | END { print(state, percentage) } | |
13 | ' | |
14 | } | |
15 | ||
16 | ||
1fd3837f SK |
17 | produce_memory() { |
18 | free | awk '$1 == "Mem:" {print $2, $3}' | |
19 | } | |
20 | ||
b9bdec44 SK |
21 | produce_fan() { |
22 | fan_path="$1" | |
23 | cat "$fan_path" | |
24 | } | |
25 | ||
5dd1535a SK |
26 | produce_temperature() { |
27 | thermal_zone="$1" | |
28 | cat "/sys/class/thermal/thermal_zone${thermal_zone}/temp" | |
29 | } | |
30 | ||
d3d7d712 SK |
31 | produce_loadavg() { |
32 | cat /proc/loadavg | |
33 | } | |
34 | ||
cf698ca8 SK |
35 | produce_disk_io() { |
36 | disk_io_device="$1" | |
37 | awk ' | |
38 | { | |
39 | r = $3 | |
40 | w = $7 | |
41 | print w, r | |
42 | } | |
43 | ' "/sys/block/$disk_io_device/stat" | |
44 | } | |
45 | ||
c0e8473e SK |
46 | produce_disk_space() { |
47 | disk_space_device="$1" | |
48 | df --output=pcent "$disk_space_device" | awk 'NR == 2 {print $1}' | |
49 | } | |
50 | ||
2b221665 SK |
51 | produce_net_addr_io() { |
52 | ip -s addr \ | |
e70e90e1 | 53 | | awk ' |
2b221665 SK |
54 | BEGIN { |
55 | bytes_per_unit = 1024 * 1024 | |
56 | } | |
57 | ||
58 | /^[0-9]+:/ { | |
59 | sub(":$", "", $1) | |
60 | sub(":$", "", $2) | |
61 | sequence = $1 | |
62 | interface = $2 | |
63 | interfaces[sequence] = interface | |
64 | } | |
65 | ||
66 | /^ +inet [0-9]/ { | |
67 | sub("/[0-9]+", "", $2) | |
68 | addr = $2 | |
69 | addrs[interface] = addr | |
70 | } | |
71 | ||
72 | /^ +RX: / {transfer_direction = "r"} | |
73 | /^ +TX: / {transfer_direction = "w"} | |
74 | ||
75 | /^ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ *$/ { | |
76 | io[interface, transfer_direction] = $1; | |
77 | } | |
78 | ||
79 | END { | |
80 | for (seq=1; seq<=sequence; seq++) { | |
81 | interface = interfaces[seq] | |
82 | label = substr(interface, 1, 1) | |
83 | if (addrs[interface]) { | |
84 | curr_read = io[interface, "r"] | |
85 | curr_write = io[interface, "w"] | |
86 | print(interface, addrs[interface], curr_write, curr_read) | |
87 | } else { | |
88 | print(interface) | |
89 | } | |
90 | } | |
91 | }' | |
92 | } | |
93 | ||
0d116e88 SK |
94 | produce_net_wifi_status() { |
95 | nmcli \ | |
96 | -f ACTIVE,SSID,SIGNAL \ | |
97 | -t \ | |
98 | d wifi \ | |
99 | | awk \ | |
100 | -F ':' \ | |
101 | ' | |
102 | BEGIN {wifi_status = "--"} | |
103 | $1 == "yes" {wifi_status = $2 ":" $3 "%"} | |
104 | END {print wifi_status} | |
105 | ' | |
106 | } | |
107 | ||
ad0b3a5b SK |
108 | produce_bluetooth_power() { |
109 | echo -e 'show \n quit' \ | |
110 | | bluetoothctl \ | |
111 | | awk ' | |
112 | /^Controller / { | |
113 | controller = $2; | |
114 | controllers[++ctrl_count] = controller; | |
115 | } | |
116 | /^\t[A-Z][A-Za-z]+:/ { | |
117 | key = $1; | |
118 | sub(":$", "", key); | |
119 | val = $2; | |
120 | for (i=3; i<=NF; i++) { | |
121 | val = val " " $i}; | |
122 | data[controller, key] = val; | |
123 | } | |
124 | END { | |
125 | # Using the 1st seen controller. Should we select specific instead? | |
126 | power_status = data[controllers[1], "Powered"]; | |
127 | if (ctrl_count > 0) { | |
128 | if (power_status == "no") { | |
129 | power_status = "off" | |
130 | } else if (power_status == "yes") { | |
131 | power_status = "on" | |
132 | } else { | |
133 | printf("Unexpected bluetooth power status: %s\n", power_status)\ | |
134 | > "/dev/stderr"; | |
135 | power_status = "ERROR" | |
136 | } | |
137 | } else { | |
138 | power_status = "off" # TODO: Perhaps use differentiated marker? | |
139 | } | |
62aa4063 | 140 | printf("%s\n", power_status); |
ad0b3a5b SK |
141 | }' |
142 | } | |
143 | ||
bbb42518 SK |
144 | produce_screen_brightness() { |
145 | screen_brightness_device_path="$1" | |
146 | echo "\ | |
147 | $(cat $screen_brightness_device_path/max_brightness) \ | |
148 | $(cat $screen_brightness_device_path/brightness)\ | |
149 | " | |
150 | } | |
151 | ||
61e5a351 SK |
152 | produce_volume() { |
153 | pactl list sinks \ | |
154 | | awk ' | |
155 | /^\tMute:/ { | |
156 | printf("%s,", $0); | |
157 | } | |
158 | /^\tVolume:/ { | |
159 | for (i=2; i<=NF; i++) printf(" %s", $i); | |
160 | }' \ | |
161 | | awk -v RS=',' ' | |
162 | /^[ \t]*Mute:/ {mute = $2} | |
163 | /^[ \t]*front-left:/ {left = $4} | |
164 | /^[ \t]*front-right:/ {right = $4} | |
165 | END { | |
166 | if (mute == "yes") { | |
62aa4063 | 167 | print("x") |
61e5a351 | 168 | } else { |
62aa4063 | 169 | print("%s %s\n", left, right) |
61e5a351 SK |
170 | } |
171 | } | |
172 | ' | |
173 | } | |
174 | ||
365549a9 SK |
175 | produce_mpd_state() { |
176 | echo 'status' \ | |
177 | | nc 127.0.0.1 6600 \ | |
178 | | awk ' | |
179 | { | |
180 | status[$1] = $2 | |
181 | } | |
182 | ||
183 | /^time: +[0-9]+:[0-9]+$/ { | |
184 | split($2, time, ":") | |
185 | seconds_current = time[1] | |
186 | seconds_total = time[2] | |
187 | ||
188 | hours = int(seconds_current / 60 / 60); | |
189 | secs_beyond_hours = seconds_current - (hours * 60 * 60); | |
190 | mins = int(secs_beyond_hours / 60); | |
191 | secs = secs_beyond_hours - (mins * 60); | |
192 | if (hours > 0) { | |
193 | current_time = sprintf("%d:%.2d:%.2d", hours, mins, secs) | |
194 | } else { | |
195 | current_time = sprintf("%.2d:%.2d", mins, secs) | |
196 | } | |
197 | ||
198 | if (seconds_total > 0) { | |
199 | time_percentage = (seconds_current / seconds_total) * 100 | |
200 | current_percentage = sprintf("%d%%", time_percentage) | |
201 | } else { | |
202 | current_percentage = "~" | |
203 | } | |
204 | } | |
205 | ||
206 | END { | |
207 | state = status["state:"] | |
208 | ||
209 | if (state == "play") { | |
210 | symbol = "▶" | |
211 | } else if (state == "pause") { | |
212 | symbol = "❚❚" | |
213 | } else if (state == "stop") { | |
214 | symbol = "⬛" | |
215 | } else { | |
216 | symbol = "--" | |
217 | } | |
218 | ||
219 | printf(\ | |
62aa4063 | 220 | "%s %s %s\n", |
365549a9 SK |
221 | status["state:"], current_time, current_percentage\ |
222 | ) | |
223 | } | |
224 | ' | |
225 | } | |
226 | ||
227 | produce_mpd_song() { | |
228 | echo 'currentsong' \ | |
229 | | nc 127.0.0.1 6600 \ | |
230 | | awk ' | |
231 | /^OK/ { | |
232 | next | |
233 | } | |
234 | ||
235 | { | |
236 | key = $1 | |
237 | sub("^" key " +", "") | |
238 | val = $0 | |
239 | data[key] = val | |
240 | } | |
241 | ||
242 | END { | |
243 | name = data["Name:"] | |
244 | title = data["Title:"] | |
245 | file = data["file:"] | |
246 | ||
247 | if (name) { | |
248 | out = name | |
249 | } else if (title) { | |
250 | out = title | |
251 | } else if (file) { | |
252 | last = split(file, parts, "/") | |
253 | out = parts[last] | |
254 | } else { | |
255 | out = "" | |
256 | } | |
257 | print out | |
258 | } | |
259 | ' | |
260 | } | |
438d0d5f | 261 | |
6339a4f8 | 262 | produce_weather() { |
4d314e0f SK |
263 | weather_station_id="$1" |
264 | metar -d "$weather_station_id" 2>&1 \ | |
438d0d5f SK |
265 | | awk ' |
266 | /METAR pattern not found in NOAA data/ { | |
267 | failures++ | |
268 | } | |
269 | ||
270 | /^Temperature/ { | |
271 | celsius = $3; | |
272 | fahrenheit = (celsius * (9 / 5)) + 32; | |
273 | temperature = fahrenheit | |
274 | } | |
275 | ||
276 | END { | |
277 | if (failures > 0) { | |
278 | temperature = "--" | |
279 | } | |
280 | print temperature "°F" | |
281 | }' | |
282 | } | |
283 | ||
6339a4f8 | 284 | produce_datetime() { |
438d0d5f SK |
285 | date +'%a %b %d %H:%M:%S' |
286 | } | |
287 | ||
6339a4f8 | 288 | consume() { |
438d0d5f | 289 | pipe="$1" |
2b221665 SK |
290 | debug="$2" |
291 | prefixes_of_net_interfaces_to_show="$3" | |
438d0d5f SK |
292 | tail -f "$pipe" \ |
293 | | stdbuf -o L awk \ | |
2b221665 | 294 | -v opt_debug="$debug" \ |
365549a9 | 295 | -v opt_mpd_song_max_chars=10 \ |
2b221665 | 296 | -v opt_prefixes_of_net_interfaces_to_show="$prefixes_of_net_interfaces_to_show" \ |
438d0d5f | 297 | ' |
75b08dad SK |
298 | /^in:ENERGY/\ |
299 | { | |
300 | split_msg_parts() | |
301 | db["energy_state"] = $1 | |
302 | db["energy_percentage"] = $2 | |
303 | } | |
304 | ||
1fd3837f SK |
305 | /^in:MEMORY/\ |
306 | { | |
307 | split_msg_parts() | |
308 | db["memory_total"] = $1 | |
309 | db["memory_used"] = $2 | |
310 | } | |
311 | ||
b9bdec44 SK |
312 | /^in:FAN +status:/\ |
313 | { | |
314 | split_msg_parts() | |
315 | db["fan_status"] = $2 | |
316 | } | |
317 | ||
318 | /^in:FAN +speed:/\ | |
319 | { | |
320 | split_msg_parts() | |
321 | db["fan_speed"] = $2 | |
322 | } | |
323 | ||
324 | /^in:FAN +level:/\ | |
325 | { | |
326 | split_msg_parts() | |
327 | db["fan_level"] = $2 | |
328 | } | |
329 | ||
5dd1535a SK |
330 | /^in:TEMPERATURE/\ |
331 | { | |
332 | split_msg_parts() | |
333 | db["temperature"] = $1 | |
334 | } | |
335 | ||
d3d7d712 SK |
336 | /^in:LOAD_AVG/\ |
337 | { | |
338 | split_msg_parts() | |
339 | set_load_avg() | |
340 | } | |
341 | ||
cf698ca8 SK |
342 | /^in:DISK_IO/\ |
343 | { | |
344 | split_msg_parts() | |
345 | set_disk_io() | |
346 | } | |
347 | ||
c0e8473e SK |
348 | /^in:DISK_SPACE/\ |
349 | { | |
350 | split_msg_parts() | |
351 | db["disk_space_used"] = msg_body | |
352 | } | |
353 | ||
2b221665 SK |
354 | /^in:NET_ADDR_IO/\ |
355 | { | |
356 | split_msg_parts() | |
357 | set_net_addr_io() | |
358 | } | |
359 | ||
0d116e88 SK |
360 | /^in:NET_WIFI_STATUS/\ |
361 | { | |
362 | split_msg_parts() | |
363 | db["net_wifi_status"] = msg_body | |
364 | } | |
365 | ||
ad0b3a5b SK |
366 | /^in:BLUETOOTH_POWER/\ |
367 | { | |
368 | split_msg_parts() | |
369 | db["bluetooth_power"] = msg_body | |
370 | } | |
371 | ||
bbb42518 SK |
372 | /^in:SCREEN_BRIGHTNESS/\ |
373 | { | |
374 | split_msg_parts() | |
375 | set_screen_brightness() | |
376 | } | |
377 | ||
61e5a351 SK |
378 | /^in:VOLUME/\ |
379 | { | |
380 | split_msg_parts() | |
381 | db["volume"] = msg_body | |
382 | } | |
383 | ||
365549a9 SK |
384 | /^in:MPD_STATE/\ |
385 | { | |
386 | split_msg_parts() | |
387 | db["mpd_state"] = $1 | |
388 | db["mpd_curr_song_time"] = $2 | |
389 | db["mpd_curr_song_percent"] = $3 | |
390 | } | |
391 | ||
392 | /^in:MPD_SONG/\ | |
438d0d5f | 393 | { |
365549a9 SK |
394 | split_msg_parts() |
395 | db["mpd_curr_song_name"] = msg_body | |
438d0d5f SK |
396 | } |
397 | ||
365549a9 | 398 | /^in:WEATHER/\ |
438d0d5f | 399 | { |
365549a9 SK |
400 | split_msg_parts() |
401 | db["weather_temperature"] = msg_body | |
438d0d5f SK |
402 | } |
403 | ||
365549a9 | 404 | /^in:DATE_TIME/\ |
438d0d5f | 405 | { |
365549a9 SK |
406 | split_msg_parts() |
407 | db["datetime"] = msg_body | |
408 | } | |
409 | ||
410 | /^out:BAR/\ | |
411 | { | |
412 | split_msg_parts() | |
438d0d5f SK |
413 | print make_bar() |
414 | } | |
415 | ||
d3d7d712 SK |
416 | function set_load_avg( sched) { |
417 | split($4, sched, "/") | |
418 | db["load_avg_1min"] = $1 | |
419 | db["load_avg_5min"] = $2 | |
420 | db["load_avg_15min"] = $3 | |
421 | db["kern_sched_queue_runnable"] = sched[1] | |
422 | db["kern_sched_queue_total"] = sched[2] | |
423 | db["kern_sched_latest_pid"] = $5 | |
424 | } | |
365549a9 | 425 | |
cf698ca8 SK |
426 | function set_disk_io( curr_w, curr_r, prev_w, prev_r) { |
427 | curr_w = $1 | |
428 | curr_r = $2 | |
429 | prev_w = db["disk_io_curr_w"] | |
430 | prev_r = db["disk_io_curr_r"] | |
431 | db["disk_io_curr_w"] = curr_w | |
432 | db["disk_io_curr_r"] = curr_r | |
433 | db["disk_io_diff_w"] = curr_w - prev_w | |
434 | db["disk_io_diff_r"] = curr_r - prev_r | |
435 | } | |
436 | ||
2b221665 SK |
437 | function set_net_addr_io( \ |
438 | interface, address, io_curr_w, io_curr_r, io_prev_w, io_prev_r\ | |
439 | ) { | |
440 | interface = $1 | |
441 | address = $2 | |
442 | io_curr_w = $3 | |
443 | io_curr_r = $4 | |
444 | if (interface) { | |
445 | if (address && io_curr_w && io_curr_r) { | |
446 | # recalculate | |
447 | io_prev_w = net_io_curr_w[interface] | |
448 | io_prev_r = net_io_curr_r[interface] | |
449 | ||
450 | net_addr[interface] = address | |
451 | net_io_curr_w[interface] = io_curr_w | |
452 | net_io_curr_r[interface] = io_curr_r | |
453 | net_io_diff_w[interface] = io_curr_w - io_prev_w | |
454 | net_io_diff_r[interface] = io_curr_r - io_prev_r | |
455 | } else { | |
456 | # clear | |
457 | net_addr[interface] = "" | |
458 | net_io_curr_w[interface] = 0 | |
459 | net_io_curr_r[interface] = 0 | |
460 | net_io_diff_w[interface] = 0 | |
461 | net_io_diff_r[interface] = 0 | |
462 | } | |
463 | } | |
464 | } | |
465 | ||
bbb42518 SK |
466 | function set_screen_brightness( max, cur) { |
467 | max = $1 | |
468 | cur = $2 | |
469 | db["screen_brightness"] = (cur / max) * 100 | |
470 | } | |
471 | ||
365549a9 SK |
472 | function split_msg_parts() { |
473 | msg_head = $1 | |
474 | sub("^" msg_head " +", "") | |
475 | msg_body = $0 | |
476 | debug(msg_head, msg_body) | |
438d0d5f SK |
477 | } |
478 | ||
365549a9 | 479 | function make_bar( position, bar, sep, i, j) { |
75b08dad | 480 | position[++i] = make_status_energy() |
1fd3837f | 481 | position[++i] = make_status_mem() |
d3d7d712 | 482 | position[++i] = make_status_cpu() |
cf698ca8 | 483 | position[++i] = make_status_disk() |
0d116e88 | 484 | position[++i] = make_status_net() |
ad0b3a5b | 485 | position[++i] = sprintf("B=%s", db["bluetooth_power"]) |
bbb42518 | 486 | position[++i] = sprintf("*%d%%", db["screen_brightness"]) |
61e5a351 | 487 | position[++i] = sprintf("(%s)", db["volume"]) |
365549a9 | 488 | position[++i] = make_status_mpd() |
438d0d5f SK |
489 | position[++i] = db["weather_temperature"] |
490 | position[++i] = db["datetime"] | |
491 | bar = "" | |
492 | sep = "" | |
493 | for (j = 1; j <= i; j++) { | |
494 | bar = bar sep position[j] | |
495 | sep = " " | |
496 | } | |
497 | return bar | |
498 | } | |
365549a9 | 499 | |
75b08dad SK |
500 | function make_status_energy( state, direction_of_change) { |
501 | state = db["energy_state"] | |
502 | if (state == "discharging") { | |
503 | direction_of_change = "<" | |
504 | } else if (state == "charging") { | |
505 | direction_of_change = ">" | |
506 | } else { | |
507 | direction_of_change = "=" | |
508 | }; | |
509 | printf("E%s%s", direction_of_change, db["energy_percentage"]) | |
510 | } | |
511 | ||
1fd3837f SK |
512 | function make_status_mem( total, used, percent, status) { |
513 | total = db["memory_total"] | |
514 | used = db["memory_used"] | |
3739a112 | 515 | # To avoid division by zero when data is missing |
1fd3837f SK |
516 | if (total && used) { |
517 | percent = round((used / total) * 100) | |
518 | status = sprintf("%d%%", percent) | |
519 | } else { | |
520 | status = "__" | |
521 | } | |
522 | return sprintf("M=%s", status) | |
523 | } | |
524 | ||
b9bdec44 | 525 | function make_status_cpu( load, temp, fan) { |
d3d7d712 | 526 | load = db["load_avg_1min"] |
5dd1535a | 527 | temp = db["temperature"] / 1000 |
b9bdec44 SK |
528 | fan = db["fan_speed"] |
529 | return sprintf("C=[%4.2f %d°C %4drpm]", load, temp, fan) | |
d3d7d712 SK |
530 | } |
531 | ||
cf698ca8 SK |
532 | function make_status_disk( bytes_per_sector, bytes_per_mb, w, r) { |
533 | bytes_per_sector = 512 | |
534 | bytes_per_mb = 1024 * 1024 | |
535 | w = (db["disk_io_diff_w"] * bytes_per_sector) / bytes_per_mb | |
536 | r = (db["disk_io_diff_r"] * bytes_per_sector) / bytes_per_mb | |
537 | return \ | |
538 | sprintf("D=[%s %0.3f▲ %0.3f▼]", db["disk_space_used"], w, r) | |
539 | } | |
540 | ||
2b221665 SK |
541 | function make_status_net( \ |
542 | out, | |
543 | number_of_interfaces_to_show, | |
544 | n, | |
545 | array_of_prefixes_of_interfaces_to_show, | |
546 | prefix, | |
547 | interface, | |
548 | label, | |
549 | count_printed, | |
550 | sep, | |
551 | io_stat, | |
552 | dw, dr, | |
553 | bytes_per_unit\ | |
554 | ) { | |
555 | out = "" | |
556 | number_of_interfaces_to_show = \ | |
557 | split(\ | |
558 | opt_prefixes_of_net_interfaces_to_show,\ | |
559 | array_of_prefixes_of_interfaces_to_show,\ | |
560 | ","\ | |
561 | ) | |
562 | for (n = 1; n <= number_of_interfaces_to_show; n++) { | |
563 | prefix = array_of_prefixes_of_interfaces_to_show[n] | |
564 | for (interface in net_addr) { | |
565 | if (interface ~ ("^" prefix)) { | |
566 | label = substr(interface, 1, 1) | |
567 | if (net_addr[interface]) { | |
568 | bytes_per_mb = 1024 * 1024 # TODO: option | |
569 | dw = net_io_diff_w[interface] / bytes_per_mb | |
570 | dr = net_io_diff_r[interface] / bytes_per_mb | |
571 | io_stat = sprintf("%0.3f▲ %0.3f▼", dw, dr) | |
572 | } else { | |
573 | io_stat = "--" | |
574 | } | |
575 | if (interface ~ "^w") { | |
576 | label = label ":" db["net_wifi_status"] | |
577 | } | |
578 | if (++count_printed > 1) { | |
579 | sep = " " | |
580 | } else { | |
581 | sep = "" | |
582 | } | |
583 | out = out sep label ":" io_stat | |
584 | } | |
585 | } | |
586 | } | |
587 | return sprintf("N[%s]", out) | |
0d116e88 SK |
588 | } |
589 | ||
365549a9 SK |
590 | function make_status_mpd( state, status) { |
591 | state = db["mpd_state"] | |
592 | ||
593 | if (state == "play") { | |
594 | status = make_status_mpd_state_known("▶") | |
595 | } else if (state == "pause") { | |
596 | status = make_status_mpd_state_known("❚❚") | |
597 | } else if (state == "stop") { | |
598 | status = make_status_mpd_state_known("⬛") | |
599 | } else { | |
600 | status = make_status_mpd_state_unknown("--") | |
601 | } | |
602 | ||
603 | return sprintf("[%s]", status) | |
604 | } | |
605 | ||
606 | function make_status_mpd_state_known(symbol) { | |
607 | return sprintf(\ | |
608 | "%s %s %s %s", | |
609 | symbol, | |
610 | db["mpd_curr_song_time"], | |
611 | db["mpd_curr_song_percent"], | |
612 | substr(db["mpd_curr_song_name"], 1, opt_mpd_song_max_chars)\ | |
613 | ) | |
614 | } | |
615 | ||
616 | function make_status_mpd_state_unknown(symbol) { | |
617 | return sprintf("%s", symbol) | |
618 | } | |
619 | ||
1fd3837f SK |
620 | function round(n) { |
621 | return int(n + 0.5) | |
622 | } | |
623 | ||
365549a9 SK |
624 | function debug(location, msg) { |
625 | if (opt_debug) { | |
626 | print_error(location, msg) | |
627 | } | |
628 | } | |
629 | ||
630 | function print_error(location, msg) { | |
631 | print(location " ==> " msg) > "/dev/stderr" | |
632 | } | |
438d0d5f SK |
633 | ' |
634 | } | |
635 | ||
6339a4f8 | 636 | produce_bar_req() { |
438d0d5f SK |
637 | echo '' |
638 | } | |
639 | ||
640 | spawn() { | |
641 | cmd="$1" | |
642 | pipe="$2" | |
365549a9 | 643 | msg_head="$3" |
438d0d5f SK |
644 | interval="$4" |
645 | while true; do | |
2b221665 SK |
646 | $cmd | while read line; do |
647 | echo "${msg_head} $line" > "$pipe" | |
648 | done | |
649 | sleep "$interval" | |
438d0d5f SK |
650 | done & |
651 | } | |
652 | ||
653 | main() { | |
4d314e0f | 654 | # Defaults |
2b221665 | 655 | debug=0 |
b8e4c2fa | 656 | dir_data=$(mktemp -d) |
4d314e0f | 657 | weather_station_id='KJFK' |
bbb42518 | 658 | screen_brightness_device_name='acpi_video0' |
2b221665 | 659 | prefixes_of_net_interfaces_to_show='w' # comma-separated |
c0e8473e | 660 | disk_space_device='/' |
cf698ca8 | 661 | disk_io_device='sda' |
5dd1535a | 662 | thermal_zone=0 |
b9bdec44 | 663 | fan_path='/proc/acpi/ibm/fan' |
4d314e0f | 664 | |
3716523b SK |
665 | interval_inp_datetime=1 |
666 | interval_inp_brightness=1 | |
667 | interval_inp_weather=$(( 30 * 60)) # 30 minutes | |
668 | interval_inp_mpd_state=1 | |
669 | interval_inp_mpd_song=1 | |
670 | interval_inp_volume=1 | |
671 | interval_inp_bluetooth=5 | |
672 | interval_inp_net_wifi=5 | |
673 | interval_inp_net_io=1 | |
674 | interval_inp_disk_space=5 | |
675 | interval_inp_disk_io=1 | |
676 | interval_inp_loadavg=1 | |
677 | interval_inp_temp=1 | |
678 | interval_inp_fan=1 | |
679 | interval_inp_mem=1 | |
680 | interval_inp_energy=1 | |
681 | interval_outp_bar=1 | |
29b3b10d | 682 | |
4d314e0f | 683 | # User-overrides |
2b221665 SK |
684 | long_options='' |
685 | long_options+='debug' | |
1ad52d13 SK |
686 | long_options+=',data_dir:' |
687 | long_options+=',weather_station:' | |
688 | long_options+=',screen_device:' | |
2b221665 | 689 | long_options+=',prefixes_of_net_interfaces_to_show:' |
c0e8473e | 690 | long_options+=',disk_space_device:' |
8fe8971a | 691 | long_options+=',disk_io_device:' |
5dd1535a | 692 | long_options+=',thermal_zone:' |
b9bdec44 | 693 | long_options+=',fan_path:' |
3716523b SK |
694 | long_options+=',interval_inp_datetime:' |
695 | long_options+=',interval_inp_brightness:' | |
696 | long_options+=',interval_inp_weather:' | |
697 | long_options+=',interval_inp_mpd_state:' | |
698 | long_options+=',interval_inp_mpd_song:' | |
699 | long_options+=',interval_inp_volume:' | |
700 | long_options+=',interval_inp_bluetooth:' | |
701 | long_options+=',interval_inp_net_wifi:' | |
702 | long_options+=',interval_inp_net_io:' | |
703 | long_options+=',interval_inp_disk_space:' | |
704 | long_options+=',interval_inp_disk_io:' | |
705 | long_options+=',interval_inp_loadavg:' | |
706 | long_options+=',interval_inp_temp:' | |
707 | long_options+=',interval_inp_fan:' | |
708 | long_options+=',interval_inp_mem:' | |
709 | long_options+=',interval_inp_energy:' | |
710 | long_options+=',interval_outp_bar:' | |
4d314e0f SK |
711 | OPTS=$( |
712 | getopt \ | |
2b221665 SK |
713 | -o 'd' \ |
714 | -l $long_options \ | |
4d314e0f SK |
715 | -- "$@" |
716 | ) | |
717 | eval set -- "$OPTS" | |
718 | while true | |
719 | do | |
720 | case "$1" in | |
2b221665 SK |
721 | -d|--debug) |
722 | debug=1 | |
723 | shift | |
724 | ;; | |
1ad52d13 | 725 | --data_dir) |
4d314e0f SK |
726 | dir_data="$2" |
727 | shift 2 | |
728 | ;; | |
1ad52d13 | 729 | --weather_station) |
4d314e0f SK |
730 | weather_station_id="$2" |
731 | shift 2 | |
732 | ;; | |
1ad52d13 | 733 | --screen_device) |
bbb42518 SK |
734 | screen_brightness_device_name="$2" |
735 | shift 2 | |
736 | ;; | |
2b221665 SK |
737 | --prefixes_of_net_interfaces_to_show) |
738 | prefixes_of_net_interfaces_to_show="$2" | |
739 | shift 2 | |
740 | ;; | |
c0e8473e SK |
741 | --disk_space_device) |
742 | disk_space_device="$2" | |
743 | shift 2 | |
744 | ;; | |
cf698ca8 SK |
745 | --disk_io_device) |
746 | disk_io_device="$2" | |
747 | shift 2 | |
748 | ;; | |
5dd1535a SK |
749 | --thermal_zone) |
750 | thermal_zone="$2" | |
751 | shift 2 | |
752 | ;; | |
b9bdec44 SK |
753 | --fan_path) |
754 | fan_path="$2" | |
755 | shift 2 | |
756 | ;; | |
3716523b SK |
757 | --interval_inp_datetime) |
758 | interval_inp_datetime="$2" | |
29b3b10d SK |
759 | shift 2 |
760 | ;; | |
3716523b SK |
761 | --interval_inp_brightness) |
762 | interval_inp_brightness="$2" | |
29b3b10d SK |
763 | shift 2 |
764 | ;; | |
3716523b SK |
765 | --interval_inp_weather) |
766 | interval_inp_weather="$2" | |
29b3b10d SK |
767 | shift 2 |
768 | ;; | |
3716523b SK |
769 | --interval_inp_mpd_state) |
770 | interval_inp_mpd_state="$2" | |
29b3b10d SK |
771 | shift 2 |
772 | ;; | |
3716523b SK |
773 | --interval_inp_mpd_song) |
774 | interval_inp_mpd_song="$2" | |
29b3b10d SK |
775 | shift 2 |
776 | ;; | |
3716523b SK |
777 | --interval_inp_volume) |
778 | interval_inp_volume="$2" | |
29b3b10d SK |
779 | shift 2 |
780 | ;; | |
3716523b SK |
781 | --interval_inp_bluetooth) |
782 | interval_inp_bluetooth="$2" | |
29b3b10d SK |
783 | shift 2 |
784 | ;; | |
3716523b SK |
785 | --interval_inp_net_wifi) |
786 | interval_inp_net_wifi="$2" | |
29b3b10d SK |
787 | shift 2 |
788 | ;; | |
3716523b SK |
789 | --interval_inp_net_io) |
790 | interval_inp_net_io="$2" | |
29b3b10d SK |
791 | shift 2 |
792 | ;; | |
3716523b SK |
793 | --interval_inp_disk_space) |
794 | interval_inp_disk_space="$2" | |
29b3b10d SK |
795 | shift 2 |
796 | ;; | |
3716523b SK |
797 | --interval_inp_disk_io) |
798 | interval_inp_disk_io="$2" | |
29b3b10d SK |
799 | shift 2 |
800 | ;; | |
3716523b SK |
801 | --interval_inp_loadavg) |
802 | interval_inp_loadavg="$2" | |
29b3b10d SK |
803 | shift 2 |
804 | ;; | |
3716523b SK |
805 | --interval_inp_temp) |
806 | interval_inp_temp="$2" | |
29b3b10d SK |
807 | shift 2 |
808 | ;; | |
3716523b SK |
809 | --interval_inp_fan) |
810 | interval_inp_fan="$2" | |
29b3b10d SK |
811 | shift 2 |
812 | ;; | |
3716523b SK |
813 | --interval_inp_mem) |
814 | interval_inp_mem="$2" | |
29b3b10d SK |
815 | shift 2 |
816 | ;; | |
3716523b SK |
817 | --interval_inp_energy) |
818 | interval_inp_energy="$2" | |
29b3b10d SK |
819 | shift 2 |
820 | ;; | |
3716523b SK |
821 | --interval_outp_bar) |
822 | interval_outp_bar="$2" | |
29b3b10d SK |
823 | shift 2 |
824 | ;; | |
4d314e0f SK |
825 | --) |
826 | shift | |
827 | break | |
828 | ;; | |
829 | esac | |
830 | done | |
831 | ||
0c0ebbe1 | 832 | pipe="$dir_data/khatus_data_pipe" |
bbb42518 SK |
833 | screen_brightness_device_path='/sys/class/backlight' |
834 | screen_brightness_device_path+="/$screen_brightness_device_name" | |
0c0ebbe1 | 835 | |
4d314e0f | 836 | ( echo "Khatus starting with the following parameters:" |
2b221665 SK |
837 | ( echo " debug|= $debug" |
838 | echo " dir_data|= $dir_data" | |
0c0ebbe1 | 839 | echo " pipe|= $pipe" |
2b221665 SK |
840 | echo " screen_brightness_device_name|= $screen_brightness_device_name" |
841 | echo " screen_brightness_device_path|= $screen_brightness_device_path" | |
4d314e0f | 842 | echo " weather_station_id|= $weather_station_id" |
c0e8473e SK |
843 | echo " prefixes_of_net_interfaces_to_show|= $prefixes_of_net_interfaces_to_show" |
844 | echo " disk_space_device|= $disk_space_device" | |
cf698ca8 | 845 | echo " disk_io_device|= $disk_io_device" |
5dd1535a | 846 | echo " thermal_zone|= $thermal_zone" |
b9bdec44 | 847 | echo " fan_path|= $fan_path" |
4d314e0f SK |
848 | ) | column -ts\| |
849 | echo '' | |
850 | ) >&2 | |
851 | ||
4d314e0f | 852 | mkdir -p "$dir_data" |
438d0d5f SK |
853 | rm -f "$pipe" |
854 | mkfifo "$pipe" | |
855 | ||
bbb42518 SK |
856 | cmd_produce_screen_brightness='produce_screen_brightness' |
857 | cmd_produce_screen_brightness+=" $screen_brightness_device_path" | |
2b221665 | 858 | |
0c0ebbe1 SK |
859 | cmd_produce_weather="produce_weather $weather_station_id" |
860 | ||
c0e8473e SK |
861 | cmd_produce_disk_space="produce_disk_space $disk_space_device" |
862 | ||
cf698ca8 SK |
863 | cmd_produce_disk_io="produce_disk_io $disk_io_device" |
864 | ||
5dd1535a SK |
865 | cmd_produce_temperature="produce_temperature $thermal_zone" |
866 | ||
b9bdec44 SK |
867 | cmd_produce_fan="produce_fan $fan_path" |
868 | ||
4d314e0f | 869 | # TODO: Redirect each worker's stderr to a dedicated log file |
3716523b SK |
870 | spawn produce_datetime "$pipe" 'in:DATE_TIME' $interval_inp_datetime |
871 | spawn "$cmd_produce_screen_brightness" "$pipe" 'in:SCREEN_BRIGHTNESS' $interval_inp_brightness | |
872 | spawn "$cmd_produce_weather" "$pipe" 'in:WEATHER' $interval_inp_weather | |
873 | spawn produce_mpd_state "$pipe" 'in:MPD_STATE' $interval_inp_mpd_state | |
874 | spawn produce_mpd_song "$pipe" 'in:MPD_SONG' $interval_inp_mpd_song | |
875 | spawn produce_volume "$pipe" 'in:VOLUME' $interval_inp_volume | |
876 | spawn produce_bluetooth_power "$pipe" 'in:BLUETOOTH_POWER' $interval_inp_bluetooth | |
877 | spawn produce_net_wifi_status "$pipe" 'in:NET_WIFI_STATUS' $interval_inp_net_wifi | |
878 | spawn produce_net_addr_io "$pipe" 'in:NET_ADDR_IO' $interval_inp_net_io | |
879 | spawn "$cmd_produce_disk_space" "$pipe" 'in:DISK_SPACE' $interval_inp_disk_space | |
880 | spawn "$cmd_produce_disk_io" "$pipe" 'in:DISK_IO' $interval_inp_disk_io | |
881 | spawn produce_loadavg "$pipe" 'in:LOAD_AVG' $interval_inp_loadavg | |
882 | spawn "$cmd_produce_temperature" "$pipe" 'in:TEMPERATURE' $interval_inp_temp | |
883 | spawn "$cmd_produce_fan" "$pipe" 'in:FAN' $interval_inp_fan | |
884 | spawn produce_memory "$pipe" 'in:MEMORY' $interval_inp_mem | |
885 | spawn produce_energy "$pipe" 'in:ENERGY' $interval_inp_energy | |
886 | spawn produce_bar_req "$pipe" 'out:BAR' $interval_outp_bar | |
2b221665 SK |
887 | |
888 | consume \ | |
889 | "$pipe" \ | |
890 | "$debug" \ | |
891 | "$prefixes_of_net_interfaces_to_show" | |
438d0d5f SK |
892 | } |
893 | ||
894 | main $@ |