Grab addresses and rates from single source: ip
[khatus.git] / bin / khatus_show
1 #! /bin/bash
2
3 set -e
4
5 BIN=$HOME/bin
6 STATUS_DIR=$HOME/var/run/status
7 STATUS_FILE__WIFI=$STATUS_DIR/wifi
8 STATUS_FILE__ENERGY_NOTIFIED_BELLOW_HALF=$STATUS_DIR/notified_energy_bellow_half
9
10 load=$(awk '{printf("%4.2f", $1)}' /proc/loadavg)
11
12 fan=$(awk '/^speed:/ {printf "%4d", $2}' /proc/acpi/ibm/fan)
13
14 cpu=$($BIN/khatus_cpu_usage_from_proc_since_last_check)
15
16 memory=$(
17 free \
18 | awk '
19 function round(n) {return int(n + 0.5)}
20
21 $1 == "Mem:" {
22 total=$2;
23 used=$3;
24 cache=$6;
25 prev_file = "/home/siraaj/var/run/status/memory_used_percentage";
26 curr = round(used / total * 100);
27 getline prev < prev_file;
28 print curr > prev_file;
29 if (curr > prev) {
30 direction = ">";
31 } else if (curr < prev) {
32 direction = "<";
33 } else {
34 direction = "=";
35 }
36 printf("%s%d%%", direction, curr);
37 }')
38
39 temp=$(awk 'NR == 1 {print $1 / 1000}' /sys/class/thermal/thermal_zone0/temp)
40
41 disk_io=$(
42 awk '
43 {
44 bytes_per_sector = 512
45 bytes_per_unit = 1024 * 1024
46
47 curr_sectors_read = $3
48 curr_sectors_write = $7
49
50 prev_file_prefix = "/home/siraaj/var/run/status/disk_io"
51 prev_sectors_read_file = prev_file_prefix "_sectors_read"
52 prev_sectors_write_file = prev_file_prefix "_sectors_write"
53
54 getline prev_sectors_read < prev_sectors_read_file
55 getline prev_sectors_write < prev_sectors_write_file
56
57 diff_read_sectors = (curr_sectors_read - prev_sectors_read)
58 diff_write_sectors = (curr_sectors_write - prev_sectors_write)
59
60 diff_read_bytes = diff_read_sectors * bytes_per_sector
61 diff_write_bytes = diff_write_sectors * bytes_per_sector
62
63 diff_read = diff_read_bytes / bytes_per_unit
64 diff_write = diff_write_bytes / bytes_per_unit
65
66 print curr_sectors_read > prev_sectors_read_file
67 print curr_sectors_write > prev_sectors_write_file
68
69 printf("%0.3f▲ %0.3f▼\n", diff_write, diff_read);
70
71 }
72 ' /sys/block/dm-1/stat
73 )
74
75 disk=$(
76 df \
77 | awk -v disk_io="$disk_io" '
78 function round(n) {return int(n + 0.5)}
79
80 $1 == "/dev/mapper/kubuntu--vg-root" {
81 curr_perc = $5; sub("%$", "", curr_perc);
82 prev_perc_file = "/home/siraaj/var/run/status/disk_space_used";
83 getline prev_perc < prev_perc_file;
84 print curr_perc > prev_perc_file;
85 if (curr_perc > prev_perc) {
86 direction = ">";
87 } else if (curr_perc < prev_perc) {
88 direction = "<";
89 } else {
90 direction = "=";
91 }
92 printf("%s[%d%% %s]", direction, curr_perc, disk_io);
93 }')
94
95 network=$(
96 ip -s addr \
97 | awk -v wifi_conn=$(cat $STATUS_FILE__WIFI) '
98 BEGIN {
99 bytes_per_unit = 1024 * 1024
100 }
101
102 /^[0-9]/ {
103 sub(":$", "", $1)
104 sub(":$", "", $2)
105 sequence = $1
106 interface = $2
107 interfaces[sequence] = interface
108 }
109
110 /^ +inet [0-9]/ {
111 sub("/[0-9]+", "", $2)
112 addr = $2
113 addrs[interface] = addr
114 }
115
116 /^ +RX: / {transfer_direction = "r"}
117 /^ +TX: / {transfer_direction = "w"}
118
119 /^ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ *$/ {
120 io[interface, transfer_direction] = $1;
121 }
122
123 END {
124 for (i=1; i<=sequence; i++) {
125 interface = interfaces[i]
126 if (addrs[interface]) {
127 curr_read = io[interface, "r"]
128 curr_write = io[interface, "w"]
129
130 prefix = "/home/siraaj/var/run/status/io_net_" interface
131 prev_read_file = prefix "_read"
132 prev_write_file = prefix "_write"
133
134 getline prev_read < prev_read_file
135 getline prev_write < prev_write_file
136
137 diff_r = (curr_read - prev_read ) / bytes_per_unit
138 diff_w = (curr_write - prev_write) / bytes_per_unit
139
140 print curr_read > prev_read_file
141 print curr_write > prev_write_file
142
143 if (interface == "wlp3s0") {
144 label = wifi_conn
145 } else {
146 label = interface
147 }
148
149 if (i == sequence) {
150 sep = ""
151 } else {
152 sep = " | "
153 }
154
155 printf("%s %0.3f▲ %0.3f▼%s", label, diff_w, diff_r, sep)
156 }
157 }
158 }'
159 )
160
161 energy=$(
162 upower -e \
163 | grep battery \
164 | xargs upower -i \
165 | awk '
166 /^ +percentage: +/ {percentage=$2}
167 /^ +state: +/ {state=$2}
168 END {
169 if (state == "discharging") {
170 direction_of_change = "<"
171 } else if (state == "charging") {
172 direction_of_change = ">"
173 } else {
174 direction_of_change = "="
175 };
176 printf("%s%s", direction_of_change, percentage)
177 }')
178
179 datetime=$(date +'%a, %b %d, %H:%M:%S')
180
181 #volume_amixer=$(
182 # amixer get Master \
183 # | tail -1 \
184 # | awk '
185 # {
186 # level = $4;
187 # sub("^\\[", "", level);
188 # sub("\\]$", "", level);
189 # print level;
190 # }' \
191 # )
192
193 #volume_amixer=$(
194 # amixer get Master \
195 # | tail -n 1 \
196 # | awk '{print $4}' \
197 # | tr -d '[]'
198 #)
199
200 volume_pactl=$(
201 pactl list sinks \
202 | awk '
203 /^\tMute:/ {
204 printf("%s,", $0);
205 }
206 /^\tVolume:/ {
207 for (i=2; i<=NF; i++) printf(" %s", $i);
208 }' \
209 | awk -v RS=',' '
210 /^[ \t]*Mute:/ {mute = $2}
211 /^[ \t]*front-left:/ {left = $4}
212 /^[ \t]*front-right:/ {right = $4}
213 END {
214 if (mute == "yes") {
215 printf("x")
216 } else {
217 printf("%s %s", left, right)
218 }
219 }
220 '
221 )
222
223 volume="[$volume_pactl]"
224
225 screen_brightness=$(
226 max=$(cat /sys/class/backlight/acpi_video0/max_brightness)
227 cur=$(cat /sys/class/backlight/acpi_video0/brightness)
228 awk -v max=$max -v cur=$cur 'BEGIN {printf("%d%%", cur/max*100)}'
229 )
230
231 #bluetooth_status=$(
232 # grep '^status:' /proc/acpi/ibm/bluetooth \
233 # | awk '
234 # $2 == "disabled" {printf "off"}
235 # $2 == "enabled" {printf "on"}
236 # '
237 #)
238
239 bluetooth_power=$(
240 echo -e 'show \n quit' \
241 | bluetoothctl \
242 | awk '
243 /^Controller / {
244 controller = $2;
245 controllers[++ctrl_count] = controller;
246 }
247 /^\t[A-Z][A-Za-z]+:/ {
248 key = $1;
249 sub(":$", "", key);
250 val = $2;
251 for (i=3; i<=NF; i++) {
252 val = val " " $i};
253 data[controller, key] = val;
254 }
255 END {
256 # Using the 1st seen controller. Should we select specific instead?
257 power_status = data[controllers[1], "Powered"];
258 if (ctrl_count > 0) {
259 if (power_status == "no") {
260 power_status = "off"
261 } else if (power_status == "yes") {
262 power_status = "on"
263 } else {
264 printf("Unexpected bluetooth power status: %s\n", power_status)\
265 > "/dev/stderr";
266 power_status = "ERROR"
267 }
268 } else {
269 power_status = "off" # TODO: Perhaps use differentiated marker?
270 }
271 printf("%s", power_status);
272 }'
273 )
274
275 #touchpad_status=$(
276 # xinput list-props 12 \
277 # | awk '
278 # /^\tDevice Enabled \([0-9]+\):/ {
279 # status = $4;
280 # printf("%s", status);
281 # }'
282 #)
283
284 #color_off='\033[0m'
285 #color_on_bg_gray='\033[m\033[40m'
286
287 energy_direction=$(echo "$energy" | cut -b 1)
288 energy_percentage=$(echo "$energy" | tr -d '<>=%')
289 if [[ "$energy_direction" = '<' ]]
290 then
291 if [[ $energy_percentage -le 5 ]]
292 then
293 DISPLAY=:0.0 notify-send \
294 -u critical \
295 "Energy CRITICALLY low: $energy" \
296 'CHARGE NOW!!! GO GO GO!!!'
297 elif [[ $energy_percentage -le 10 ]]
298 then
299 DISPLAY=:0.0 notify-send \
300 -u critical \
301 "Energy VERY low: $energy" \
302 'Plug it in ASAP.'
303 elif [[ $energy_percentage -le 15 ]]
304 then
305 DISPLAY=:0.0 notify-send \
306 -u critical \
307 "Energy low: $energy" \
308 'Get the charger.'
309 elif [[ $energy_percentage -le 50 ]]
310 then
311 if [[ ! -a "$STATUS_FILE__ENERGY_NOTIFIED_BELLOW_HALF" ]]
312 then
313 DISPLAY=:0.0 notify-send \
314 -u normal \
315 "Energy bellow half: $energy" \
316 'Where is the charger?'
317 touch "$STATUS_FILE__ENERGY_NOTIFIED_BELLOW_HALF"
318 fi
319 fi
320 else
321 rm -f "$STATUS_FILE__ENERGY_NOTIFIED_BELLOW_HALF"
322 fi
323
324 weather=$(awk 'NR == 1 {printf("%d°F", $1)}' ~/var/run/metar-KJFK-decoded-temp-fahrenheit)
325
326 signal_last_msg_age=$(
327 ls -lt --time-style=+%s $HOME/var/lib/signal/latest_message.json \
328 | awk -v now_seconds=$(date +%s) \
329 '{
330 mtime_seconds = $6;
331 seconds = now_seconds - mtime_seconds;
332 minutes = seconds / 60;
333 hours = minutes / 60;
334 days = hours / 24;
335 weeks = days / 7;
336 months = days / 30;
337 #fmt = "%.1f";
338 fmt = "%d";
339 printf(fmt " s\n", seconds);
340 printf(fmt " m\n", minutes);
341 printf(fmt " h\n", hours);
342 printf(fmt " d\n", days);
343 printf(fmt " w\n", weeks);
344 printf(fmt " mo\n", months);
345 }' \
346 | awk '$1 >= 1' \
347 | sort -n -k 1 \
348 | head -1 \
349 | tr -d ' '
350 )
351
352 mpd_state=$(
353 echo 'status' \
354 | nc 127.0.0.1 6600 \
355 | awk '
356 {
357 status[$1] = $2
358 }
359
360 END {
361 state = status["state:"]
362 symbol = "-"
363 if (state == "play") {
364 symbol = "▶"
365 } else if (state == "pause") {
366 symbol = "❚❚"
367 } else if (state == "stop") {
368 symbol = "⬛"
369 }
370 printf("%s", symbol)
371 }
372 '
373 )
374
375 mpd_current=$(
376 echo 'currentsong' \
377 | nc 127.0.0.1 6600 \
378 | awk -v max_chars=10 '
379 /^OK/ {
380 next
381 }
382
383 {
384 key = $1
385 val = $2
386 for (i=3; i<=NF; i++) {val = val " " $i}
387 data[key] = val
388 }
389
390 END {
391 if (data["Name:"]) {
392 out = data["Name:"]
393 } else {
394 file = data["file:"]
395 last = split(file, parts, "/")
396 out = parts[last]
397 }
398 printf("%s", substr(out, 1, max_chars))
399 }
400 '
401 )
402
403 graphics_card=$(
404 nvidia-smi \
405 --format=csv,noheader,nounits \
406 --query-gpu=memory.total,memory.used,temperature.gpu \
407 | awk -F ',' '
408 {
409 mem_total = $1;
410 mem_used = $2;
411 temp = $3;
412 mem_used_percent = (100 * mem_used) / mem_total;
413 printf("[%d%% %dC]", mem_used_percent, temp);
414 }
415 '
416 )
417
418 echo \
419 "\
420 E$energy\
421 \
422 \
423 G=$graphics_card\
424 \
425 \
426 M$memory\
427 \
428 \
429 C=[$cpu ${temp}°C ${fan}rpm]\
430 \
431 \
432 L=$load\
433 \
434 \
435 D$disk\
436 \
437 \
438 N:[$network]\
439 \
440 \
441 B:$bluetooth_power\
442 \
443 \
444 S=$screen_brightness\
445 \
446 \
447 V=$volume\
448 \
449 [$mpd_state $mpd_current]\
450 \
451 $signal_last_msg_age\
452 \
453 $weather\
454 \
455 $datetime \
456 "
This page took 0.143169 seconds and 4 git commands to generate.