#! /bin/bash
+set -e
+
+produce_net_wifi_status() {
+ nmcli \
+ -f ACTIVE,SSID,SIGNAL \
+ -t \
+ d wifi \
+ | awk \
+ -F ':' \
+ '
+ BEGIN {wifi_status = "--"}
+ $1 == "yes" {wifi_status = $2 ":" $3 "%"}
+ END {print wifi_status}
+ '
+}
+
+produce_bluetooth_power() {
+ echo -e 'show \n quit' \
+ | bluetoothctl \
+ | awk '
+ /^Controller / {
+ controller = $2;
+ controllers[++ctrl_count] = controller;
+ }
+ /^\t[A-Z][A-Za-z]+:/ {
+ key = $1;
+ sub(":$", "", key);
+ val = $2;
+ for (i=3; i<=NF; i++) {
+ val = val " " $i};
+ data[controller, key] = val;
+ }
+ END {
+ # Using the 1st seen controller. Should we select specific instead?
+ power_status = data[controllers[1], "Powered"];
+ if (ctrl_count > 0) {
+ if (power_status == "no") {
+ power_status = "off"
+ } else if (power_status == "yes") {
+ power_status = "on"
+ } else {
+ printf("Unexpected bluetooth power status: %s\n", power_status)\
+ > "/dev/stderr";
+ power_status = "ERROR"
+ }
+ } else {
+ power_status = "off" # TODO: Perhaps use differentiated marker?
+ }
+ printf("%s", power_status);
+ }'
+}
+
+produce_screen_brightness() {
+ screen_brightness_device_path="$1"
+ echo "\
+ $(cat $screen_brightness_device_path/max_brightness) \
+ $(cat $screen_brightness_device_path/brightness)\
+ "
+}
+
+produce_volume() {
+ pactl list sinks \
+ | awk '
+ /^\tMute:/ {
+ printf("%s,", $0);
+ }
+ /^\tVolume:/ {
+ for (i=2; i<=NF; i++) printf(" %s", $i);
+ }' \
+ | awk -v RS=',' '
+ /^[ \t]*Mute:/ {mute = $2}
+ /^[ \t]*front-left:/ {left = $4}
+ /^[ \t]*front-right:/ {right = $4}
+ END {
+ if (mute == "yes") {
+ printf("x")
+ } else {
+ printf("%s %s", left, right)
+ }
+ }
+ '
+}
+
produce_mpd_state() {
echo 'status' \
| nc 127.0.0.1 6600 \
}
produce_weather() {
- metar -d "$WEATHER_STATION_ID" 2>&1 \
+ weather_station_id="$1"
+ metar -d "$weather_station_id" 2>&1 \
| awk '
/METAR pattern not found in NOAA data/ {
failures++
-v opt_debug=0 \
-v opt_mpd_song_max_chars=10 \
'
+ /^in:NET_WIFI_STATUS/\
+ {
+ split_msg_parts()
+ db["net_wifi_status"] = msg_body
+ }
+
+ /^in:BLUETOOTH_POWER/\
+ {
+ split_msg_parts()
+ db["bluetooth_power"] = msg_body
+ }
+
+ /^in:SCREEN_BRIGHTNESS/\
+ {
+ split_msg_parts()
+ set_screen_brightness()
+ }
+
+ /^in:VOLUME/\
+ {
+ split_msg_parts()
+ db["volume"] = msg_body
+ }
+
/^in:MPD_STATE/\
{
split_msg_parts()
}
+ function set_screen_brightness( max, cur) {
+ max = $1
+ cur = $2
+ db["screen_brightness"] = (cur / max) * 100
+ }
+
function split_msg_parts() {
msg_head = $1
sub("^" msg_head " +", "")
}
function make_bar( position, bar, sep, i, j) {
+ position[++i] = make_status_net()
+ position[++i] = sprintf("B=%s", db["bluetooth_power"])
+ position[++i] = sprintf("*%d%%", db["screen_brightness"])
+ position[++i] = sprintf("(%s)", db["volume"])
position[++i] = make_status_mpd()
position[++i] = db["weather_temperature"]
position[++i] = db["datetime"]
return bar
}
+ function make_status_net() {
+ return sprintf("N[w:%s]", db["net_wifi_status"])
+ }
+
function make_status_mpd( state, status) {
state = db["mpd_state"]
}
main() {
- dir_bin="$1"
- dir_data="$2"
- pipe="$dir_data/pipe"
-
- WEATHER_STATION_ID='KJFK'
-
+ # Defaults
+ dir_data="$HOME/.khatus"
+ weather_station_id='KJFK'
+ screen_brightness_device_name='acpi_video0'
+
+ # User-overrides
+ OPTS=$(
+ getopt \
+ -o '' \
+ -l data-dir:,weather-station:screen-device: \
+ -- "$@"
+ )
+ eval set -- "$OPTS"
+ while true
+ do
+ case "$1" in
+ --data-dir)
+ dir_data="$2"
+ shift 2
+ ;;
+ --weather-station)
+ weather_station_id="$2"
+ shift 2
+ ;;
+ --screen-device)
+ screen_brightness_device_name="$2"
+ shift 2
+ ;;
+ --)
+ shift
+ break
+ ;;
+ esac
+ done
+
+ pipe="$dir_data/khatus_data_pipe"
+ screen_brightness_device_path='/sys/class/backlight'
+ screen_brightness_device_path+="/$screen_brightness_device_name"
+
+ ( echo "Khatus starting with the following parameters:"
+ ( echo " dir_data|= $dir_data"
+ echo " pipe|= $pipe"
+ echo " screen_brightness_device_name|=$screen_brightness_device_name"
+ echo " screen_brightness_device_path|=$screen_brightness_device_path"
+ echo " weather_station_id|= $weather_station_id"
+ ) | column -ts\|
+ echo ''
+ ) >&2
+
+ mkdir -p "$dir_data"
rm -f "$pipe"
mkfifo "$pipe"
- spawn produce_datetime "$pipe" 'in:DATE_TIME' 1
- spawn produce_weather "$pipe" 'in:WEATHER' $(( 30 * 60 ))
- spawn produce_mpd_state "$pipe" 'in:MPD_STATE' 1
- spawn produce_mpd_song "$pipe" 'in:MPD_SONG' 1
- spawn produce_bar_req "$pipe" 'out:BAR' 1
- consume "$pipe"
+ cmd_produce_screen_brightness='produce_screen_brightness'
+ cmd_produce_screen_brightness+=" $screen_brightness_device_path"
+ cmd_produce_weather="produce_weather $weather_station_id"
+
+ # TODO: Redirect each worker's stderr to a dedicated log file
+ spawn produce_datetime "$pipe" 'in:DATE_TIME' 1
+ spawn "$cmd_produce_screen_brightness" "$pipe" 'in:SCREEN_BRIGHTNESS' 1
+ spawn "$cmd_produce_weather" "$pipe" 'in:WEATHER' $(( 30 * 60 ))
+ spawn produce_mpd_state "$pipe" 'in:MPD_STATE' 1
+ spawn produce_mpd_song "$pipe" 'in:MPD_SONG' 1
+ spawn produce_volume "$pipe" 'in:VOLUME' 1
+ spawn produce_bluetooth_power "$pipe" 'in:BLUETOOTH_POWER' 5
+ spawn produce_net_wifi_status "$pipe" 'in:NET_WIFI_STATUS' 5
+ spawn produce_bar_req "$pipe" 'out:BAR' 1
+ consume "$pipe"
}
main $@