From c59a66022a9077cfaaab06a92b6573722d17bf53 Mon Sep 17 00:00:00 2001 From: eleksir Date: Sun, 8 Mar 2020 07:04:59 +0300 Subject: [PATCH] i3status-timers.dbus: use uttf8, add more info * Add capslock status * Add wlan0 status and ipaddr * Add cputemp * Add/stash cpu cores speed (more work required to represent it in compact mode) * More compact meminfo * Remove uptime, no usecase for desktop * Remove focused window string sub * Remove current locale indicator (xxkb shows it) * remove cron wrapper subs * Remove outdated comments * Remove alternative battery charge detection subs --- i3status-timers.dbus | 369 +++++++++++++++++++++++-------------------- 1 file changed, 194 insertions(+), 175 deletions(-) diff --git a/i3status-timers.dbus b/i3status-timers.dbus index 87c0a80..0bf6965 100644 --- a/i3status-timers.dbus +++ b/i3status-timers.dbus @@ -1,50 +1,27 @@ #!/usr/bin/perl -# vim: set ai noet ts=8 sw=8 sts=8 ft=perl : - -# set username -# set uptime -# set time -# set xtitle of focused window -# set list of windows for current tag -# set list of windows for all tags -# set la -# set current language -# set battery charge - -# main loop impl. : -# save cur. str and compare it with prev. if it differs - update - -# proposed: 3 types of loop: -# slow loop for batt charge, la -# 1 second loop for time, uptime - generally, it looks like we do not need poll every second -# timers if clock granularity set to 1 minute or even coarse -# main (fast) loop for window name, language, it looks like we have some room here for greater -# improvement, when it'll be more clear how get info directly from x server +# vim: set ai noet ts=4 sw=4 sts=4 ft=perl : use strict; use warnings "all"; use Fcntl qw(:seek); use Net::DBus; - +use 5.10.0; +use utf8; binmode STDOUT; binmode STDERR; -sub onesec_cron(); -sub slow_cron(); - sub gettimestr(); -sub getfocusedwidowtitlestr(); -sub getlangstr(); -sub getuptimestr(); sub getlastr(); -sub getbatterychargestr1(); -sub getbatterychargestr2(); sub getbatterychargestr3(); +sub to_hours($); sub meminfo(); -sub to_hours($); # translates seconds to HH:MM format - +sub ifaces(); +sub cpuspeed(); +sub cputemp(); +sub caps(); +sub caps_find(); my $slow_timer = 360; # 0.333 * 360 ~= 2 min my $onesec_timer = 3; # 0.333 * 3 ~= 1 sec @@ -56,43 +33,60 @@ my $pstr = ''; my $charge; my $la; -my $uptime; my $time; my $mem; +my $net; +my $cpuspeed; +my $cputemp; +# prep dee-boos connection my $bus = Net::DBus->system; my $upower = $bus->get_service("org.freedesktop.UPower"); my $properties = $upower->get_object("/org/freedesktop/UPower/devices/battery_BAT0", "org.freedesktop.DBus.Properties"); -my $UPTIMEHANDLE; +# find out caps lock indicator +my $CAPSPATH = &caps_find(); + my $LAHANDLE; my $MEMINFOHANDLE; +my @IFACE = qw (wlan0); +my %IFSTATE; +my %IFPSTATE; +my %IFADDR; + +# take a nap sleep 1; while (1) { if ($onesec_timer >= 3) { - onesec_cron(); +# $cpuspeed = cpuspeed(); + $cputemp = cputemp(); + $time = gettimestr(); + $mem = &meminfo(); + $net = &ifaces(); $onesec_timer = 0; } if ($slow_timer >= 360) { - slow_cron(); + $charge = getbatterychargestr3(); + $la = getlastr(); + $CAPSPATH = caps_find() unless (defined($CAPSPATH)); $slow_timer = 0; } - my $str = ''; -# $str .= getfocusedwidowtitlestr(); -# $str .= "$ENV{'USER'}"; - $str .= getlangstr(); - $str .= $uptime; +# my $str = $cpuspeed; + my $str = caps(); + $str .= $net; + $str .= $cputemp; $str .= $la; $str .= $mem; $str .= $charge; $str .= $time; + utf8::encode($str); if ($pstr ne $str) { - syswrite STDOUT, "$str\n"; + syswrite STDOUT, $str . "\n"; $pstr = $str; } @@ -104,68 +98,11 @@ while (1) { select(undef, undef, undef, 0.333); } -sub slow_cron() { - $charge = getbatterychargestr3(); - $la = getlastr(); -} - -sub onesec_cron() { - $uptime = getuptimestr(); - $time = gettimestr(); -# as we report time with precision of 1 minute, update 1/60 seconds - $mem = meminfo(); -} - - sub gettimestr() { my ($sec, $min, $hour, $mday, $mon, $year, $wday) = (localtime)[0,1,2,3,4,5,6]; $year = $year + 1900; - my $str .= sprintf(" | %s, %s %s %s %02s:%02s ", $wdays[$wday], $mday, $months[$mon], $year, $hour, $min); - return $str; -} - -sub getfocusedwidowtitlestr() { - my $str; - - if (-x '/usr/bin/xdotool') { - $str = `xdotool getactivewindow getwindowname`; - } elsif (-x '/usr/bin/xprop') { - $str = (split( / = /, `xprop -id \$(xprop -root _NET_ACTIVE_WINDOW | cut -d ' ' -f 5) _NET_WM_NAME`))[1]; - chop $str; chop $str; - } - - chomp($str); - - if (length($str) != 0) { - if (length($str) > 64){ - $str = '...' . substr($str, 0, -61); - } - $str = '['. $str .'] | '; - } else { - $str = '| '; - } - - return $str; -} - -sub getuptimestr() { - if (defined($UPTIMEHANDLE)) { - open $UPTIMEHANDLE, "/proc/uptime" if (tell($UPTIMEHANDLE) == -1); - } else { - open $UPTIMEHANDLE, "/proc/uptime"; - } - - my $u = <$UPTIMEHANDLE>; - seek $UPTIMEHANDLE, SEEK_SET, 0; - $u = (split(/ /, $u, 2))[0]; - my $days = int($u / 86400); # 86400 = 1 day - my $hours = int(($u - (86400 * $days)) / 3600); # 3600 = 1 hour - my $minutes = int(($u - (86400 * $days) - (3600 * $hours)) / 60); - my $seconds = int($u - (86400 * $days) - (3600 * $hours) - (60 * $minutes)); - my $str = sprintf(" | up: %sd,%02sh,%02sm ", $days, $hours, $minutes); - - return $str; + return sprintf(" | %s, %s %s %s %02s:%02s ", $wdays[$wday], $mday, $months[$mon], $year, $hour, $min); } sub getlastr() { @@ -175,61 +112,11 @@ sub getlastr() { open $LAHANDLE, "/proc/loadavg"; } - my $la = <$LAHANDLE>; + my $str = readline($LAHANDLE); seek $LAHANDLE, SEEK_SET, 0; - $la = (split(/ /, $la, 2))[0]; + $str = (split(/ /, $str, 2))[0]; - return (" | LA: $la "); -} - -sub getbatterychargestr1() { - my $str = ''; - - if (-f "/sys/class/power_supply/BAT0/present") { - open A, "/sys/class/power_supply/BAT0/present"; - my $P = ; - close A; - chomp($P); - - if ($P eq '1') { - open A, "/sys/class/power_supply/BAT0/energy_full"; - my $full_charge = ; - close A; - chomp($full_charge); - - open A, "/sys/class/power_supply/BAT0/energy_now"; - my $current_charge = ; - close A; - chomp($current_charge); - - $str .= sprintf(" | Bat: %03d%% ", int(($current_charge / $full_charge) * 100) ); - undef $current_charge; undef $full_charge; - } - } - - return $str; -} - -sub getbatterychargestr2() { - my $str .= " | Power: "; - open AC,"/sys/class/power_supply/ADP1/online"; - - if ( == 1) { - $str .= "AC"; - } else { - $str .= "DC"; - } - - close AC; # display % charge only if possible - - if (open DC,"/sys/class/power_supply/BAT0/capacity") { - $str .= ' '. ; - close DC; - chomp $str; - $str .= '%'; - } - - return $str; + return " | LA: $str"; } sub getbatterychargestr3() { @@ -252,51 +139,183 @@ sub getbatterychargestr3() { $state = '•'; } - $time = to_hours ($time); + $time = to_hours ($time) unless ($time eq '?'); - return sprintf(" | %s%% %s %s", $capacity, $state, $time); + return sprintf(" | ⚡ %s%% %s %s", $capacity, $state, $time); } -sub getlangstr() { - my $str .= " | Lang: "; +sub to_hours ($) { + my $sec = shift; - if (`xset -q` =~ /Group 2: on /o) { - $str .= "RU"; - } else { - $str .= "EN"; - } + my $hrs = $sec / (60 * 60); + $hrs = 0 if ( $hrs < 1 ); + my $min = ($sec - ($hrs * 60 * 60)) / 60; + $min = 0 if ( $min < 1 ); - return $str; + return sprintf("%02d:%02d", $hrs, $min); } sub meminfo() { if (defined($MEMINFOHANDLE)) { open ($MEMINFOHANDLE, "/proc/meminfo") if (tell($MEMINFOHANDLE) == -1); } else { - open ($MEMINFOHANDLE, "/proc/meminfo"); + open ($MEMINFOHANDLE, "/proc/meminfo"); + } + + my @mem; + + while ( ! eof($MEMINFOHANDLE) ) { + push @mem, readline($MEMINFOHANDLE); } - my @mem = <$MEMINFOHANDLE>; seek $MEMINFOHANDLE, SEEK_SET, 0; - @mem = map { substr($_, 0, -4) } @mem; - my $memavail = (split(/\s+/, $mem[2]))[1]; my $swaptotal = (split(/\s+/, $mem[14]))[1]; my $swapfree = (split(/\s+/, $mem[15]))[1]; return sprintf ( - " | mem: %s M | sw: %s M", + " | mem/sw: %s/%s M", int($memavail / 1024), int(($swaptotal - $swapfree) / 1024) ); } -sub to_hours ($) { - my $sec = shift; - my $hrs = $sec / (60 * 60); - $hrs = 0 if ( $hrs < 1 ); - my $min = ($sec - ($hrs * 60 * 60)) / 60; - $min = 0 if ( $min < 1 ); - return sprintf("%02d:%02d", $hrs, $min); +sub ifaces() { + my $str = ''; + + foreach my $if (@IFACE) { + my $addr = "no addr"; + my $link; + + open (I, "/sys/class/net/$if/operstate") or do { + $str .= " | ? $if: not exist"; + next; + }; + + $IFSTATE{$if} = readline(*I); + close I; + $IFPSTATE{$if} = $IFSTATE{$if} unless(defined($IFPSTATE{$if})); + + if ($IFSTATE{$if} eq "up\n") { + $link = '▲'; + } else { + $link = '▼'; + } + + if ($IFPSTATE{$if} ne $IFSTATE{$if}) { + $IFADDR{$if} = undef; + $IFPSTATE{$if} = $IFSTATE{$if} + } + + unless (defined($IFADDR{$if})) { + open(R, "/proc/self/net/route"); + my @route = ; + close R; + + foreach my $r (@route) { + if ((split(/\t/, $r, 2))[0] eq $if) { + $addr = (split(/\n/, `/sbin/ip address show dev $if`))[2]; + $addr =~ m/ inet (.+)\//; + $IFADDR{$if} = $1; + + last; + } + } + } + + unless (defined($IFADDR{$if})) { + $str .= sprintf(" | %s %s: %s", $link, $if, $addr); + } else { + $str .= sprintf(" | %s %s: %s", $link, $if, $IFADDR{$if}); + } + } + + return $str; +} + +sub cpuspeed() { + my $str = 'cpu:'; + + opendir(C, "/sys/devices/system/cpu/cpufreq") or do { + return ''; + }; + + while (readdir(C)) { + next if($_ eq '.'); + next if($_ eq '..'); + + open (S, "/sys/devices/system/cpu/cpufreq/$_/scaling_cur_freq") or do { next; }; + my $speed = readline(*S); + close S; + chomp $speed; + $speed = int($speed / 1000); + open (SM, "/sys/devices/system/cpu/cpufreq/$_/scaling_max_freq"); + my $speedmax = readline(*SM); + close SM; + chomp $speedmax; + $speedmax = int($speedmax / 1000); + $str .= sprintf(" %s/%s", $speed, $speedmax); + } + + closedir C; + + return $str . " MHz"; +} + +sub cputemp() { + open(T, "/sys/class/hwmon/hwmon0/temp1_input") or do { + return ''; + }; + + my $t = readline(*T); + close T; + chomp $t; + $t = int($t); + $t = int($t / 1000) if ($t > 1000); + + return sprintf(" | %s°", $t); +} + +sub caps() { + if (defined($CAPSPATH)) { + open(C, $CAPSPATH) or do { + $CAPSPATH = undef; + return "? caps"; + }; + + my $state = readline(*C); + close C; + chomp $state; + + if ($state eq '1') { + return '☒ caps'; + } else { + return '☐ caps'; + } + } +} + +sub caps_find() { + my $str; + opendir (C, "/sys/class/input"); + my $cnt = 0; + + while (readdir(C)) { + if (-f sprintf("/sys/class/input/%s/input0::capslock/brightness", $_)) { + $str = sprintf("/sys/class/input/%s/input0::capslock/brightness", $_); + last; + } + + if (-f sprintf("/sys/class/input/%s/input%s::capslock/brightness", $_, $cnt)) { + $str = sprintf("/sys/class/input/%s/input%s::capslock/brightness", $_, $cnt); + last; + } + + $cnt++; + } + + closedir C; + + return $str; }