7 df
--output=pcent
"$disk_space_device" |
awk 'NR == 2 {print $1}'
10 produce_net_addr_io
() {
14 bytes_per_unit = 1024 * 1024
22 interfaces[sequence] = interface
26 sub("/[0-9]+", "", $2)
28 addrs[interface] = addr
31 /^ +RX: / {transfer_direction = "r"}
32 /^ +TX: / {transfer_direction = "w"}
34 /^ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ *$/ {
35 io[interface, transfer_direction] = $1;
39 for (seq=1; seq<=sequence; seq++) {
40 interface = interfaces[seq]
41 label = substr(interface, 1, 1)
42 if (addrs[interface]) {
43 curr_read = io[interface, "r"]
44 curr_write = io[interface, "w"]
45 print(interface, addrs[interface], curr_write, curr_read)
53 produce_net_wifi_status
() {
55 -f ACTIVE
,SSID
,SIGNAL \
61 BEGIN {wifi_status = "--"}
62 $1 == "yes" {wifi_status = $2 ":" $3 "%"}
63 END {print wifi_status}
67 produce_bluetooth_power
() {
68 echo -e 'show \n quit' \
73 controllers[++ctrl_count] = controller;
75 /^\t[A-Z][A-Za-z]+:/ {
79 for (i=3; i<=NF; i++) {
81 data[controller, key] = val;
84 # Using the 1st seen controller. Should we select specific instead?
85 power_status = data[controllers[1], "Powered"];
87 if (power_status == "no") {
89 } else if (power_status == "yes") {
92 printf("Unexpected bluetooth power status: %s\n", power_status)\
94 power_status = "ERROR"
97 power_status = "off" # TODO: Perhaps use differentiated marker?
99 printf("%s\n", power_status);
103 produce_screen_brightness
() {
104 screen_brightness_device_path
="$1"
106 $(cat $screen_brightness_device_path/max_brightness) \
107 $(cat $screen_brightness_device_path/brightness)\
118 for (i=2; i<=NF; i++) printf(" %s", $i);
121 /^[ \t]*Mute:/ {mute = $2}
122 /^[ \t]*front-left:/ {left = $4}
123 /^[ \t]*front-right:/ {right = $4}
128 print("%s %s\n", left, right)
134 produce_mpd_state
() {
136 | nc
127.0.0.1 6600 \
142 /^time: +[0-9]+:[0-9]+$/ {
144 seconds_current = time[1]
145 seconds_total = time[2]
147 hours = int(seconds_current / 60 / 60);
148 secs_beyond_hours = seconds_current - (hours * 60 * 60);
149 mins = int(secs_beyond_hours / 60);
150 secs = secs_beyond_hours - (mins * 60);
152 current_time = sprintf("%d:%.2d:%.2d", hours, mins, secs)
154 current_time = sprintf("%.2d:%.2d", mins, secs)
157 if (seconds_total > 0) {
158 time_percentage = (seconds_current / seconds_total) * 100
159 current_percentage = sprintf("%d%%", time_percentage)
161 current_percentage = "~"
166 state = status["state:"]
168 if (state == "play") {
170 } else if (state == "pause") {
172 } else if (state == "stop") {
180 status["state:"], current_time, current_percentage\
188 | nc
127.0.0.1 6600 \
196 sub("^" key " +", "")
203 title = data["Title:"]
211 last = split(file, parts, "/")
222 weather_station_id
="$1"
223 metar
-d "$weather_station_id" 2>&1 \
225 /METAR pattern not found in NOAA data/ {
231 fahrenheit = (celsius * (9 / 5)) + 32;
232 temperature = fahrenheit
239 print temperature "°F"
244 date +'%a %b %d %H:%M:%S'
250 prefixes_of_net_interfaces_to_show
="$3"
253 -v opt_debug
="$debug" \
254 -v opt_mpd_song_max_chars
=10 \
255 -v opt_prefixes_of_net_interfaces_to_show
="$prefixes_of_net_interfaces_to_show" \
260 db["disk_space_used"] = msg_body
269 /^in:NET_WIFI_STATUS/\
272 db["net_wifi_status"] = msg_body
275 /^in:BLUETOOTH_POWER/\
278 db["bluetooth_power"] = msg_body
281 /^in:SCREEN_BRIGHTNESS/\
284 set_screen_brightness()
290 db["volume"] = msg_body
297 db["mpd_curr_song_time"] = $2
298 db["mpd_curr_song_percent"] = $3
304 db["mpd_curr_song_name"] = msg_body
310 db["weather_temperature"] = msg_body
316 db["datetime"] = msg_body
326 function set_net_addr_io( \
327 interface, address, io_curr_w, io_curr_r, io_prev_w, io_prev_r\
334 if (address && io_curr_w && io_curr_r) {
336 io_prev_w = net_io_curr_w[interface]
337 io_prev_r = net_io_curr_r[interface]
339 net_addr[interface] = address
340 net_io_curr_w[interface] = io_curr_w
341 net_io_curr_r[interface] = io_curr_r
342 net_io_diff_w[interface] = io_curr_w - io_prev_w
343 net_io_diff_r[interface] = io_curr_r - io_prev_r
346 net_addr[interface] = ""
347 net_io_curr_w[interface] = 0
348 net_io_curr_r[interface] = 0
349 net_io_diff_w[interface] = 0
350 net_io_diff_r[interface] = 0
355 function set_screen_brightness( max, cur) {
358 db["screen_brightness"] = (cur / max) * 100
361 function split_msg_parts() {
363 sub("^" msg_head " +", "")
365 debug(msg_head, msg_body)
368 function make_bar( position, bar, sep, i, j) {
369 position[++i] = sprintf("D=[%s]", db["disk_space_used"])
370 position[++i] = make_status_net()
371 position[++i] = sprintf("B=%s", db["bluetooth_power"])
372 position[++i] = sprintf("*%d%%", db["screen_brightness"])
373 position[++i] = sprintf("(%s)", db["volume"])
374 position[++i] = make_status_mpd()
375 position[++i] = db["weather_temperature"]
376 position[++i] = db["datetime"]
379 for (j = 1; j <= i; j++) {
380 bar = bar sep position[j]
386 function make_status_net( \
388 number_of_interfaces_to_show,
390 array_of_prefixes_of_interfaces_to_show,
401 number_of_interfaces_to_show = \
403 opt_prefixes_of_net_interfaces_to_show,\
404 array_of_prefixes_of_interfaces_to_show,\
407 for (n = 1; n <= number_of_interfaces_to_show; n++) {
408 prefix = array_of_prefixes_of_interfaces_to_show[n]
409 for (interface in net_addr) {
410 if (interface ~ ("^" prefix)) {
411 label = substr(interface, 1, 1)
412 if (net_addr[interface]) {
413 bytes_per_mb = 1024 * 1024 # TODO: option
414 dw = net_io_diff_w[interface] / bytes_per_mb
415 dr = net_io_diff_r[interface] / bytes_per_mb
416 io_stat = sprintf("%0.3f▲ %0.3f▼", dw, dr)
420 if (interface ~ "^w") {
421 label = label ":" db["net_wifi_status"]
423 if (++count_printed > 1) {
428 out = out sep label ":" io_stat
432 return sprintf("N[%s]", out)
435 function make_status_mpd( state, status) {
436 state = db["mpd_state"]
438 if (state == "play") {
439 status = make_status_mpd_state_known("▶")
440 } else if (state == "pause") {
441 status = make_status_mpd_state_known("❚❚")
442 } else if (state == "stop") {
443 status = make_status_mpd_state_known("⬛")
445 status = make_status_mpd_state_unknown("--")
448 return sprintf("[%s]", status)
451 function make_status_mpd_state_known(symbol) {
455 db["mpd_curr_song_time"],
456 db["mpd_curr_song_percent"],
457 substr(db["mpd_curr_song_name"], 1, opt_mpd_song_max_chars)\
461 function make_status_mpd_state_unknown(symbol) {
462 return sprintf("%s", symbol)
465 function debug(location, msg) {
467 print_error(location, msg)
471 function print_error(location, msg) {
472 print(location " ==> " msg) > "/dev/stderr"
487 $cmd |
while read line
; do
488 echo "${msg_head} $line" > "$pipe"
497 dir_data
="$HOME/.khatus"
498 weather_station_id
='KJFK'
499 screen_brightness_device_name
='acpi_video0'
500 prefixes_of_net_interfaces_to_show
='w' # comma-separated
501 disk_space_device
='/'
505 long_options
+='debug'
506 long_options
+=',data-dir:'
507 long_options
+=',weather-station:'
508 long_options
+=',screen-device:'
509 long_options
+=',prefixes_of_net_interfaces_to_show:'
510 long_options
+=',disk_space_device:'
530 weather_station_id
="$2"
534 screen_brightness_device_name
="$2"
537 --prefixes_of_net_interfaces_to_show)
538 prefixes_of_net_interfaces_to_show
="$2"
542 disk_space_device
="$2"
552 pipe
="$dir_data/khatus_data_pipe"
553 screen_brightness_device_path
='/sys/class/backlight'
554 screen_brightness_device_path
+="/$screen_brightness_device_name"
556 ( echo "Khatus starting with the following parameters:"
557 ( echo " debug|= $debug"
558 echo " dir_data|= $dir_data"
560 echo " screen_brightness_device_name|= $screen_brightness_device_name"
561 echo " screen_brightness_device_path|= $screen_brightness_device_path"
562 echo " weather_station_id|= $weather_station_id"
563 echo " prefixes_of_net_interfaces_to_show|= $prefixes_of_net_interfaces_to_show"
564 echo " disk_space_device|= $disk_space_device"
573 cmd_produce_screen_brightness
='produce_screen_brightness'
574 cmd_produce_screen_brightness
+=" $screen_brightness_device_path"
576 cmd_produce_weather
="produce_weather $weather_station_id"
578 cmd_produce_disk_space
="produce_disk_space $disk_space_device"
580 # TODO: Redirect each worker's stderr to a dedicated log file
581 spawn produce_datetime
"$pipe" 'in:DATE_TIME' 1
582 spawn
"$cmd_produce_screen_brightness" "$pipe" 'in:SCREEN_BRIGHTNESS' 1
583 spawn
"$cmd_produce_weather" "$pipe" 'in:WEATHER' $
(( 30 * 60 ))
584 spawn produce_mpd_state
"$pipe" 'in:MPD_STATE' 1
585 spawn produce_mpd_song
"$pipe" 'in:MPD_SONG' 1
586 spawn produce_volume
"$pipe" 'in:VOLUME' 1
587 spawn produce_bluetooth_power
"$pipe" 'in:BLUETOOTH_POWER' 5
588 spawn produce_net_wifi_status
"$pipe" 'in:NET_WIFI_STATUS' 5
589 spawn produce_net_addr_io
"$pipe" 'in:NET_ADDR_IO' 1
590 spawn
"$cmd_produce_disk_space" "$pipe" 'in:DISK_SPACE' 1
591 spawn produce_bar_req
"$pipe" 'out:BAR' 1
596 "$prefixes_of_net_interfaces_to_show"