Skip to content

Instantly share code, notes, and snippets.

@Gussak
Last active February 6, 2024 03:08
Show Gist options
  • Save Gussak/108eaecb8b0a74bddd252036c2f12657 to your computer and use it in GitHub Desktop.
Save Gussak/108eaecb8b0a74bddd252036c2f12657 to your computer and use it in GitHub Desktop.
REALLY LIGHT WEIGHT systray gnome extension with critical system information for old computers
#!/bin/bash
# Copyright 2023 Gussak<https://github.com/Gussak>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# this script is a cfg for https://extensions.gnome.org/extension/2826/generic-monitor/
# feel free to improve it, and tell me, thx!
#help #000 REALLY LIGHT WEIGHT systray gnome extension with critical system information for old computers
#help #010
#help #020 The problem: Apparently, every time any other fancy extension refreshed, it caused trouble with the Window Manager (on ubuntu 22.04) or the CPU. I tested it by holding a key in terminal, and instead of it being quickly repeated smoothly, it would freeze for 2s and suddenly dump about 20+ repeated letters every short delay about 5s. That problem also happened with ctrl+v, in browsers etc. The keyboard was causing a lot of trouble! The mouse also wouldn't move for a few seconds! And other apps would also freeze for a short time. I think I had many other problems also related to that.
#help #023
#help #025 To improve this script read the Syntax at https://forge.soutade.fr/soutade/GnomeShellGenericMonitor
#help #030
egrep "[#]help" "$0" |sed -r -e 's@[#]help@@' -e 's@\s*: [$][{]@\t\t@' -e 's@:=@=@' -e 's@}@\t@' |sort |sed -r -e 's@#[0-9]{3}@@'
if [[ "$1" == --help ]];then exit 0;fi
set -Eeu
#help #040 Environment Options with default values:
function FUNCfixPerc() {
local lnPerc="$1"
if ! [[ "$lnPerc" =~ ^[0-9]*$ ]];then
#lnPerc=$((lnPerc/10))
#else
#echo "fail: lnPerc='$lnPerc'" >&2
lnPerc=0 #--
fi
echo "$lnPerc"
};export -f FUNCfixPerc
: ${strGraph:="_,.-~='\"^\`"} #help 8 chars. 100/8=12%
: ${nHistSize:=10} #help how many chars as graph history to show
strInit="$(printf "%0${nHistSize}d" 0 |sed "s@0@${strGraph:0:1}@g")"
declare -A astrHistGraph
astrHistGraph[idIOWait]="$strInit"
astrHistGraph[idRAM]="$strInit"
astrHistGraph[idSwap]="$strInit"
astrHistGraph[idCPUt]="$strInit"
declare -A astrNm
astrNm[idIOWait]="IOWait "
astrNm[idRAM]="RAM "
astrNm[idSwap]="Swap "
astrNm[idCPUt]="CPUt "
declare -A astrNmShort
astrNmShort[idIOWait]="IO "
astrNmShort[idRAM]="R "
astrNmShort[idSwap]="S "
astrNmShort[idCPUt]=""
declare -A astrInfo
: ${bShortName:=true} #help
function FUNCnm() {
if $bShortName;then
echo "${astrNmShort[$1]}"
else
echo "${astrNm[$1]}"
fi
};export -f FUNCnm
function FUNCgraph() { # FUNCgraph idRAM $perc
# percent is 0 to 100 (not 0.0 to 1.0)
echo "FUNCgraph:params:$@"
local lstrGrID="$1";shift
local lnPerc="$(FUNCfixPerc "$1")";shift
local lnGraphNow=$((lnPerc/${#strGraph}))
declare -p lstrGrID lnPerc lnGraphNow
#astrHistGraph[$lstrGrID]="${astrHistGraph[$lstrGrID]:1}${strGraph:$lnGraphNow:1}"
astrHistGraph[$lstrGrID]+="${strGraph:$lnGraphNow:1}"
if((${#astrHistGraph[$lstrGrID]} > nHistSize));then
astrHistGraph[$lstrGrID]="${astrHistGraph[$lstrGrID]:1}"
fi
};export -f FUNCgraph
function FUNCinfoAdd() {
local lbGraph=true;if [[ "$1" == --nograph ]];then lbGraph=false;shift;fi
astrInfo[$1]=" [`FUNCnm $1`${2}${3-%}"
if $lbGraph;then if $bGraph;then astrInfo[$1]+="${astrHistGraph[$1]}";fi;fi
astrInfo[$1]+="]"
};export -f FUNCinfoAdd
function FUNCcolor() {
: ${bColorByPerc:=true} #help color based on percent good,normal,warn,critical:green,blue,yellow,red. otherwise is a fixed color per type
if $bColorByPerc;then
case "$1" in
idCPUt) FUNCcolorByTemperature "$2" ;;
idIOWait|idRAM|idSwap) FUNCcolorByPerc "$2" ;;
esac
else
case "$1" in
idCPUt) echo '#FFFF00' ;;
idIOWait) echo '#FF0000' ;;
idRAM) echo '#00FF00' ;;
idSwap) echo '#C100FF' ;;
esac
fi
}
function FUNCcolorByPerc() {
if(($1< 25 ));then echo "#00FF00";return;fi
if(($1>=25 && $1<50));then echo "#00D1FF";return;fi
if(($1>=50 && $1<75));then echo "#FFFF00";return;fi
if(($1>=75 ));then echo "#FF0000";return;fi
}
: ${strTemperatures:="60 75 95"} #help this string will become an array. set like being normal high critical temperatures
if [[ -n "$strTemperatures" ]];then astrTList=($strTemperatures);fi
function FUNCcolorByTemperature() {
if(( $1 < ${astrTList[0]} ));then echo "#00FF00";return;fi
if(( $1 >= ${astrTList[0]} && $1 < ${astrTList[1]} ));then echo "#00D1FF";return;fi
if(( $1 >= ${astrTList[1]} && $1 < ${astrTList[2]} ));then echo "#FFFF00";return;fi
if(( $1 >= ${astrTList[2]} ));then echo "#FF0000";return;fi
}
: ${strFont:="Latin Modern Mono Light Cond;font-size:large"} #help other suggestions "Latin Modern Mono" "Ubuntu Condensed" "Latin Modern Mono Light Cond" "Liberation Sans Narrow, Bold"
function FUNCsection() { # sectionName text color
#TODO:colors: [{"name":"1","text":"a","style":"color:#00FF00"},{"name":"2","text":"a","style":"color:#0000FF"}]
case "$1" in
idDate) echo '{"name":"section'"${1}"'","text":"'"${strDate}"'","style":"color:'"#FFFFFF"';font-family:'"${strFont}"'"}';;
idExitB) echo '{"name":"section'"${1}"'","text":"'"${strExitBegin}"'","style":"color:'"#FFFF00"';font-family:'"${strFont}"'"}';;
idExitE) echo '{"name":"section'"${1}"'","text":"'"${strExitEnd}"'","style":"color:'"#FFFF00"';font-family:'"${strFont}"'"}';;
idIOWait) echo '{"name":"section'"${1}"'","text":"'"${astrInfo[$1]}"'","style":"color:'"$(FUNCcolor idIOWait $nIOWaitPerc)"';font-family:'"${strFont}"'"}';;
idRAM) echo '{"name":"section'"${1}"'","text":"'"${astrInfo[$1]}"'","style":"color:'"$(FUNCcolor idRAM $nMPerc)"';font-family:'"${strFont}"'"}';;
idSwap) echo '{"name":"section'"${1}"'","text":"'"${astrInfo[$1]}"'","style":"color:'"$(FUNCcolor idSwap $nSPerc)"';font-family:'"${strFont}"'"}';;
idCPUt) echo '{"name":"section'"${1}"'","text":"'"${astrInfo[$1]}"'","style":"color:'"$(FUNCcolor idCPUt $nCPUTemperature)"';font-family:'"${strFont}"'"}';;
esac
}
function FUNCshow() {
: ${bColors:=true} #help
if $bColors;then
strShow='{"group":"new","items":['"$(FUNCsection idDate),$(FUNCsection idExitB),$(FUNCsection idIOWait),$(FUNCsection idRAM),$(FUNCsection idSwap),$(FUNCsection idCPUt),$(FUNCsection idExitE)"']}'
else
strShow='{"group":"new","items":[{"name":"first","text":"'"${strExitBegin}${strInfo}${strExitEnd}"'","style":"color:white;font-family:'"${strFont}"'"}]}'
fi
declare -p strShow
gdbus call \
--session \
--dest org.gnome.Shell \
--object-path /com/soutade/GenericMonitor \
--method com.soutade.GenericMonitor.notify \
"$strShow"
};export -f FUNCshow
strExitBegin=" "
strExitEnd=" "
function FUNCclear() { gdbus call --session --dest org.gnome.Shell --object-path /com/soutade/GenericMonitor --method com.soutade.GenericMonitor.deleteGroups '{"groups":["new"]}'; }
trap 'FUNCclear' EXIT # trap 'strExitBegin="Exit!>";strExitEnd="<!Exit";FUNCshow' EXIT
strMem="`free`"
nMTot="`echo "$strMem" |grep Mem |awk '{print $2}'`"
nSTot="`echo "$strMem" |grep Swap |awk '{print $2}'`"
strCPU="$(sensors)"
bChkCoresMode=false
nCPUCores="$(echo "$strCPU" |egrep Core |wc -l)"
if((nCPUCores>0));then bChkCoresMode=true;fi
: ${bCPUTemperatureAverage:=false} #help if false will show max temperature
: ${strDateFmt:="%Y"} #help "%A, %Hh%Mm - %d %B (%m/%Y)" #you can use this if you disable sys clock
: ${bGraph:=true} #help show txt simulated graph
: ${nDelay:=3} #help update rate
while true;do
strMem="`free`"
nMUsed="`echo "$strMem" |grep Mem |awk '{print $3}'`"
nMPerc=$(( nMUsed / (nMTot/100) ))
declare -p nMUsed nMTot nMPerc
nSUsed="`echo "$strMem" |grep Swap |awk '{print $3}'`"
nSPerc=$(( nSUsed / (nSTot/100) ))
declare -p nSUsed nSTot nSPerc
strCPU="$(sensors)"
if $bCPUTemperatureAverage;then
#help you may need to run this: sensors-detect; service kmod start #you may need to reboot too, dont know why yet tho.
if $bChkCoresMode;then
nCPUTemperature="$(echo "$strCPU" |egrep Core |awk '{print $3}' |tr -d '+.°C' |tr '\n' '+')0"
nCPUTemperature="$((nCPUTemperature/10/nCPUCores))"
else
#nCPUTemperature="$(echo "$strCPU" |egrep "°C" |awk '{print $2}' |tr -d '+.°C' |tr '\n' '+')0"
nCPUTemperature="$(echo "$strCPU" |egrep "Tctl:" |awk '{print $2}' |tr -d '+.°C' |tr '\n' '+')0"
fi
else #max temperature
nCPUTemperature=0
if $bChkCoresMode;then
IFS=$'\n' read -d '' -r -a anCTx10List < <(echo "$strCPU" |egrep Core |awk '{print $3}' |tr -d '+.°C')&&:
else
#IFS=$'\n' read -d '' -r -a anCTx10List < <(echo "$strCPU" |egrep "°C" |awk '{print $2}' |tr -d '+.°C')&&:
IFS=$'\n' read -d '' -r -a anCTx10List < <(echo "$strCPU" |egrep "Tctl:" |awk '{print $2}' |tr -d '+.°C')&&:
fi
for nCTx10 in "${anCTx10List[@]}";do
declare -p nCTx10
if((nCTx10>nCPUTemperature));then nCPUTemperature=$nCTx10;fi
done
nCPUTemperature="$((nCPUTemperature/10))"
fi
declare -p nCPUTemperature
#nIOWaitPerc="$(iostat -c |egrep -v "^$" |tail -n 1 |awk '{print $4}')"
#nIOWaitPerc="$(top -b -n 1 -p 1 |grep "%Cpu" |awk '{print $10}' |tr -d '.')"&&:
nIOWaitPerc="$(top -b -n 1 -p 1 |grep "%Cpu" |awk '{print $10}' |sed -r 's@(.*)([.])(.*)@\1@')"
nIOWaitPerc="`FUNCfixPerc "$nIOWaitPerc"`"
#if [[ "$nIOWaitPerc" =~ ^[0-9]*$ ]];then
#nIOWaitPerc=$((nIOWaitPerc/10))&&:
#else
#echo "fail: nIOWaitPerc='$nIOWaitPerc'" >&2
#nIOWaitPerc="0" #--
#fi
declare -p nIOWaitPerc
strDate="`date +"${strDateFmt}"`"
declare -p strDateFmt strDate
#if $bGraph;then
#strInfo="${strDate} IOwait($(FUNCgraph idIOWait ${nIOWaitPerc})) RAM($(FUNCgraph idRAM ${nMPerc})) Swap($(FUNCgraph idSwap ${nSPerc})) CPU(${nCPUTemperature}°C)";
FUNCgraph idIOWait ${nIOWaitPerc}
FUNCgraph idRAM ${nMPerc}
FUNCgraph idSwap ${nSPerc}
strInfo="${strDate}"
#strInfo+=" [`FUNCnm idIOWait`${nIOWaitPerc}%${astrHistGraph[idIOWait]}]"
#strInfo+=" [`FUNCnm idRAM`${nMPerc}%${astrHistGraph[idRAM]}]"
#strInfo+=" [`FUNCnm idSwap`${nSPerc}%${astrHistGraph[idSwap]}]"
#strInfo+=" [`FUNCnm idCPUt`${nCPUTemperature}°C]"
FUNCinfoAdd idIOWait "`printf %2d ${nIOWaitPerc}`"
FUNCinfoAdd idRAM "`printf %2d ${nMPerc}`"
FUNCinfoAdd idSwap "`printf %2d ${nSPerc}`"
FUNCinfoAdd --nograph idCPUt "`printf %2d ${nCPUTemperature}`" "°C"
#else
#strInfo="${strDate} IOwait(${nIOWaitPerc}%) RAM(${nMPerc}%) Swap(${nSPerc}%) CPU(${nCPUTemperature}°C)";
#fi
FUNCshow
sleep ${nDelay}
done
@Gussak
Copy link
Author

Gussak commented Dec 8, 2023

color by percent or temperature level
image

if you want a fixed color by type instead, try this bColorByPerc=false customSystrayText.sh
image

TODO (by priority):

  • allow each history graph to happen less often than the default update time, so IO could remain x1, but ram could be x3 and swap x10
  • use a color for each history level

DONE:

  • colors for history graphs: IO:red , RAM:green , Swap:purple , temperature:yellow ; OR use colors to indicate low, normal, high and critical values instead
  • use mono spaced narrow font

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment