@ -7,6 +7,7 @@
#
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
LC_NUMERIC = C
# Retrieve stats from FTL engine
pihole-FTL( ) {
@ -32,43 +33,74 @@ pihole-FTL() {
exec 3<& -
fi
else
echo -e " ${ COL_LIGHT_RED } FTL offline ${ COL_NC } "
echo "0 "
fi
}
# Print spaces to align right-side con ten t
# Print spaces to align right-side additional tex t
printFunc( ) {
txt_len = " ${# 2 } "
# Reduce string length when using colour code
[ " ${ 2 : 0 : 1 } " = = " " ] && txt_len = $(( txt_len-7))
if [ [ " $3 " = = "last" ] ] ; then
# Prevent final line from printing trailing newline
scr_size = ( $( stty size 2>/dev/null || echo 24 80) )
scr_width = " ${ scr_size [1] } "
title_len = " ${# 1 } "
spc_num = $(( ( scr_width - title_len) - txt_len ))
[ [ " $spc_num " -lt 0 ] ] && spc_num = "0"
spc = $( printf " % ${ spc_num } s " )
printf " %s%s $spc " " $1 " " $2 "
else
# Determine number of spaces for padding
spc_num = $(( 20 - txt_len ))
[ [ " $spc_num " -lt 0 ] ] && spc_num = "0"
spc = $( printf " % ${ spc_num } s " )
local text_last
# Print string (Max 20 characters, prevents overflow)
printf " %s%s $spc " " $1 " " ${ 2 : 0 : 20 } "
title = " $1 "
title_len = " ${# title } "
text_main = " $2 "
text_main_nocol = " $text_main "
if [ [ " ${ text_main : 0 : 1 } " = = " " ] ] ; then
text_main_nocol = $( sed 's/ \[[0-9;]\{1,5\}m//g' <<< " $text_main " )
fi
text_main_len = " ${# text_main_nocol } "
text_addn = " $3 "
if [ [ " $text_addn " = = "last" ] ] ; then
text_addn = ""
text_last = "true"
fi
# If there is additional text, define max length of text_main
if [ [ -n " $text_addn " ] ] ; then
case " $scr_cols " in
[ 0-9] | 1[ 0-9] | 2[ 0-9] | 3[ 0-9] | 4[ 0-4] ) text_main_max_len = "9" ; ;
4[ 5-9] ) text_main_max_len = "14" ; ;
*) text_main_max_len = "19" ; ;
esac
fi
[ [ -z " $text_addn " ] ] && text_main_max_len = " $(( scr_cols - title_len )) "
# Remove excess characters from main text
if [ [ " $text_main_len " -gt " $text_main_max_len " ] ] ; then
# Trim text without colours
text_main_trim = " ${ text_main_nocol : 0 : $text_main_max_len } "
# Replace with trimmed text
text_main = " ${ text_main / $text_main_nocol / $text_main_trim } "
fi
# Determine amount of spaces for each line
if [ [ -n " $text_last " ] ] ; then
# Move cursor to end of screen
spc_num = $(( scr_cols - ( title_len + text_main_len ) ))
else
spc_num = $(( text_main_max_len - text_main_len ))
fi
[ [ " $spc_num " -le 0 ] ] && spc_num = "0"
spc = $( printf " % ${ spc_num } s " )
#spc="${spc// /.}" # Debug: Visualise spaces
printf " %s%s $spc " " $title " " $text_main "
if [ [ -n " $text_addn " ] ] ; then
printf "%s(%s)%s\n" " $COL_NC $COL_DARK_GRAY " " $text_addn " " $COL_NC "
else
# Do not print trailing newline on final line
[ [ -z " $text_last " ] ] && printf "%s\n" " $COL_NC "
fi
}
# Perform on first Chrono run (not for JSON formatted string)
get_init_stats( ) {
LC_NUMERIC = C
calcFunc( ) { awk " BEGIN {print $* } " ; }
calcFunc( ) { awk " BEGIN {print $* } " 2> /dev/null; }
# Convert bytes to human-readable format
hrBytes( ) {
@ -90,33 +122,53 @@ get_init_stats() {
# Convert seconds to human-readable format
hrSecs( ) {
day = $(( $1 / 60 / 60 / 24 )) ; hrs = $(( $1 / 3600 % 24 )) ; mins = $(( ( $1 % 3600 ) / 60 )) ; secs = $(( $1 % 60 ))
day = $(( $1 / 60 / 60 / 24 )) ; hrs = $(( $1 / 3600 % 24 ))
mins = $(( ( $1 % 3600 ) / 60 )) ; secs = $(( $1 % 60 ))
[ [ " $day " -ge "2" ] ] && plu = "s"
[ [ " $day " -ge "1" ] ] && days = " $day day ${ plu } , " || days = ""
printf "%s%02d:%02d:%02d\n" " $days " " $hrs " " $mins " " $secs "
}
}
# Set Colour Codes
coltable = "/opt/pihole/COL_TABLE"
if [ [ -f " ${ coltable } " ] ] ; then
source ${ coltable }
else
COL_NC = ' [0m'
COL_DARK_GRAY = ' [1;30m'
COL_LIGHT_GREEN = ' [1;32m'
COL_LIGHT_BLUE = ' [1;34m'
COL_LIGHT_RED = ' [1;31m'
COL_YELLOW = ' [1;33m'
COL_LIGHT_RED = ' [1;31m'
COL_URG_RED = ' [39;41m'
COL_NC = " [0m"
COL_DARK_GRAY = " [1;30m"
COL_LIGHT_GREEN = " [1;32m"
COL_LIGHT_BLUE = " [1;34m"
COL_LIGHT_RED = " [1;31m"
COL_YELLOW = " [1;33m"
COL_LIGHT_RED = " [1;31m"
COL_URG_RED = " [39;41m"
fi
# Get RPi model number, or OS distro info
# Get RPi throttle state (RPi 3B only) & model number, or OS distro info
if command -v vcgencmd & > /dev/null; then
sys_rev = $( awk '/Revision/ {print $3}' < /proc/cpuinfo)
case " $sys_rev " in
local sys_throttle_raw
local sys_rev_raw
sys_throttle_raw = $( vgt = $( sudo vcgencmd get_throttled) ; echo " ${ vgt ##*x } " )
# Active Throttle Notice: http://bit.ly/2gnunOo
if [ [ " $sys_throttle_raw " != "0" ] ] ; then
case " $sys_throttle_raw " in
*0001) thr_type = " ${ COL_YELLOW } Under Voltage " ; ;
*0002) thr_type = " ${ COL_LIGHT_BLUE } Arm Freq Cap " ; ;
*0003) thr_type = " ${ COL_YELLOW } UV ${ COL_DARK_GRAY } , ${ COL_NC } ${ COL_LIGHT_BLUE } AFC " ; ;
*0004) thr_type = " ${ COL_LIGHT_RED } Throttled " ; ;
*0005) thr_type = " ${ COL_YELLOW } UV ${ COL_DARK_GRAY } , ${ COL_NC } ${ COL_LIGHT_RED } TT " ; ;
*0006) thr_type = " ${ COL_LIGHT_BLUE } AFC ${ COL_DARK_GRAY } , ${ COL_NC } ${ COL_LIGHT_RED } TT " ; ;
*0007) thr_type = " ${ COL_YELLOW } UV ${ COL_DARK_GRAY } , ${ COL_NC } ${ COL_LIGHT_BLUE } AFC ${ COL_DARK_GRAY } , ${ COL_NC } ${ COL_LIGHT_RED } TT " ; ;
esac
[ [ -n " $thr_type " ] ] && sys_throttle = " $thr_type ${ COL_DARK_GRAY } "
fi
sys_rev_raw = $( awk '/Revision/ {print $3}' < /proc/cpuinfo)
case " $sys_rev_raw " in
000[ 2-6] ) sys_model = " 1, Model B" ; ; # 256MB
000[ 7-9] ) sys_model = " 1, Model A" ; ; # 256MB
000[ 7-9] ) sys_model = " 1, Model A" ; ; # 256MB
000d| 000e| 000f) sys_model = " 1, Model B" ; ; # 512MB
0010| 0013) sys_model = " 1, Model B+" ; ; # 512MB
0012| 0015) sys_model = " 1, Model A+" ; ; # 256MB
@ -126,7 +178,7 @@ get_init_stats() {
90009[ 2-3] | 920093) sys_model = " Zero" ; ; # 512MB
9000c1) sys_model = " Zero W" ; ; # 512MB
a02082| a[ 2-3] 2082) sys_model = " 3, Model B" ; ; # 1GB
*) sys_model = "" ; ;
*) sys_model = "" ; ;
esac
sys_type = " Raspberry Pi $sys_model "
else
@ -137,7 +189,6 @@ get_init_stats() {
# Get core count
sys_cores = $( grep -c "^processor" /proc/cpuinfo)
[ [ " $sys_cores " -ne 1 ] ] && sys_cores_plu = "cores" || sys_cores_plu = "core"
# Test existence of clock speed file for ARM CPU
if [ [ -f "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" ] ] ; then
@ -168,80 +219,95 @@ get_sys_stats() {
# Update every 12 refreshes (Def: every 60s)
count = $(( count+1))
if [ [ " $count " = = "1" ] ] || ( ( " $count " % 12 = = 0 ) ) ; then
# Do not source setupVars if file does not exist
[ [ -n " $setupVars " ] ] && source " $setupVars "
ph_ver_raw = ( $( pihole -v -c 2> /dev/null | sed -n 's/^.* v/v/p' ) )
mapfile -t ph_ver_raw < <( pihole -v -c 2> /dev/null | sed -n 's/^.* v/v/p' )
if [ [ -n " ${ ph_ver_raw [0] } " ] ] ; then
ph_core_ver = " ${ ph_ver_raw [0] } "
ph_lte_ver = " ${ ph_ver_raw [1] } "
ph_ftl_ver = " ${ ph_ver_raw [2] } "
else
ph_core_ver = "${ COL_LIGHT_RED } API unavailable ${ COL_NC } "
ph_core_ver = "-1 "
fi
sys_name = $( hostname)
[ [ -n " $TEMPERATUREUNIT " ] ] && temp_unit = " $TEMPERATUREUNIT " || temp_unit = "c"
# Get storage stats for partition mounted on /
disk_raw = ( $( df -B1 / 2> /dev/null | awk 'END{ print $3,$2,$5 }' ) )
read -r -a disk_raw <<< " $( df -B1 / 2> /dev/null | awk 'END{ print $3,$2,$5 }' ) "
disk_used = " ${ disk_raw [0] } "
disk_total = " ${ disk_raw [1] } "
disk_perc = " ${ disk_raw [2] } "
net_gateway = $( route -n | awk '$4 == "UG" {print $2;exit}' )
# Get DHCP stats, if feature is enabled
if [ [ " $DHCP_ACTIVE " = = "true" ] ] ; then
ph_dhcp_eip = " ${ DHCP_END ##*. } "
ph_dhcp_max = $(( ${ DHCP_END ##*. } - ${ DHCP_START ##*. } + 1 ))
fi
# Get alt DNS server, or print total count of alt DNS servers
if [ [ -z " ${ PIHOLE_DNS_3 } " ] ] ; then
ph_alts = " ${ PIHOLE_DNS_2 } "
else
dns_count = "0"
[ [ -n " ${ PIHOLE_DNS_2 } " ] ] && dns_count = $(( dns_count+1))
[ [ -n " ${ PIHOLE_DNS_3 } " ] ] && dns_count = $(( dns_count+1))
[ [ -n " ${ PIHOLE_DNS_4 } " ] ] && dns_count = $(( dns_count+1))
[ [ -n " ${ PIHOLE_DNS_5 } " ] ] && dns_count = $(( dns_count+1))
[ [ -n " ${ PIHOLE_DNS_6 } " ] ] && dns_count = $(( dns_count+1))
[ [ -n " ${ PIHOLE_DNS_7 } " ] ] && dns_count = $(( dns_count+1))
[ [ -n " ${ PIHOLE_DNS_8 } " ] ] && dns_count = $(( dns_count+1))
[ [ -n " ${ PIHOLE_DNS_9 } " ] ] && dns_count = " $dns_count + "
ph_alts = " ${ dns_count } others "
fi
# Get DNS server count
dns_count = "0"
[ [ -n " ${ PIHOLE_DNS_1 } " ] ] && dns_count = $(( dns_count+1))
[ [ -n " ${ PIHOLE_DNS_2 } " ] ] && dns_count = $(( dns_count+1))
[ [ -n " ${ PIHOLE_DNS_3 } " ] ] && dns_count = $(( dns_count+1))
[ [ -n " ${ PIHOLE_DNS_4 } " ] ] && dns_count = $(( dns_count+1))
[ [ -n " ${ PIHOLE_DNS_5 } " ] ] && dns_count = $(( dns_count+1))
[ [ -n " ${ PIHOLE_DNS_6 } " ] ] && dns_count = $(( dns_count+1))
[ [ -n " ${ PIHOLE_DNS_7 } " ] ] && dns_count = $(( dns_count+1))
[ [ -n " ${ PIHOLE_DNS_8 } " ] ] && dns_count = $(( dns_count+1))
[ [ -n " ${ PIHOLE_DNS_9 } " ] ] && dns_count = " $ dns_count+ "
fi
# Get screen size
read -r -a scr_size <<< " $( stty size 2>/dev/null || echo 24 80) "
scr_lines = " ${ scr_size [0] } "
scr_cols = " ${ scr_size [1] } "
# Determine Chronometer size behaviour
if [ [ " $scr_cols " -ge 58 ] ] ; then
chrono_width = "large"
elif [ [ " $scr_cols " -gt 40 ] ] ; then
chrono_width = "medium"
else
chrono_width = "small"
fi
# Determine max length of divider string
scr_line_len = $(( scr_cols - 2 ))
[ [ " $scr_line_len " -ge 58 ] ] && scr_line_len = "58"
scr_line_str = $( printf " % ${ scr_line_len } s " )
scr_line_str = " ${ scr_line_str // /— } "
sys_uptime = $( hrSecs " $( cut -d. -f1 /proc/uptime) " )
sys_loadavg = $( cut -d " " -f1,2,3 /proc/loadavg)
# Get CPU usage, only counting processes over 1% CPU as active
# Get CPU usage, only counting processes over 1% as active
cpu_raw = $( ps -eo pcpu,rss --no-headers | grep -E -v " 0" )
cpu_tasks = $( wc -l <<< " $cpu_raw " )
cpu_taskact = $( sed -r "/(^ 0.)/d" <<< " $cpu_raw " | wc -l)
cpu_perc = $( awk '{sum+=$1} END {printf "%.0f\n", sum/' " $sys_cores " '}' <<< " $cpu_raw " )
# Get CPU clock speed
if [ [ -n " $scaling_freq_file " ] ] ; then
cpu_mhz = $(( $( < /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq) / 1000 ))
else
cpu_mhz = $( lscpu | awk -F "[ .]+ " '/MHz/ {print $4 ;exit}' )
cpu_mhz = $( lscpu | awk -F ": " '/MHz/ {print $2 ;exit}' )
cpu_mhz = $( printf "%.0f" " ${ cpu_mhz //[[ : space : ]]/ } " )
fi
# Determine correct string format for CPU clock speed
# Determine whether to display CPU clock speed as MHz or GHz
if [ [ -n " $cpu_mhz " ] ] ; then
[ [ " $cpu_mhz " -le "999" ] ] && cpu_freq = " $cpu_mhz MHz " || cpu_freq = " $( calcFunc " $cpu_mhz " /1000) Gh z "
[ [ -n " $cpu_freq " ] ] && cpu_freq_str = " @ $cpu_freq " || cpu_freq_str = ""
[ [ " $cpu_mhz " -le "999" ] ] && cpu_freq = " $cpu_mhz MHz " || cpu_freq = " $( calcFunc " $cpu_mhz " /1000) GH z "
fi
# Determine colour for temperature
if [ [ -n " $temp_file " ] ] ; then
if [ [ " $temp_unit " = = "C" ] ] ; then
cpu_temp = $( printf "%' .0fc\n" " $( calcFunc " $( < $temp_file ) / 1000 " ) " )
cpu_temp = $( printf "%.0fc\n" " $( calcFunc " $( < $temp_file ) / 1000 " ) " )
case " ${ cpu_temp : :- 1 } " in
-*| [ 0-9] | [ 1-3] [ 0-9] ) cpu_col = " $COL_LIGHT_BLUE " ; ;
4[ 0-9] ) cpu_col = "" ; ;
@ -249,13 +315,13 @@ get_sys_stats() {
6[ 0-9] ) cpu_col = " $COL_LIGHT_RED " ; ;
*) cpu_col = " $COL_URG_RED " ; ;
esac
# $COL_NC$COL_DARK_GRAY is needed for $COL_URG_RED
cpu_temp_str = " , $cpu_col $cpu_temp $COL_NC $COL_DARK_GRAY "
cpu_temp_str = " @ $cpu_col $cpu_temp $COL_NC $COL_DARK_GRAY "
elif [ [ " $temp_unit " = = "F" ] ] ; then
cpu_temp = $( printf "%' .0ff\n" " $( calcFunc " ( $( < $temp_file ) / 1000) * 9 / 5 + 32 " ) " )
cpu_temp = $( printf "%.0ff\n" " $( calcFunc " ( $( < $temp_file ) / 1000) * 9 / 5 + 32 " ) " )
case " ${ cpu_temp : :- 1 } " in
-*| [ 0-9] | [ 0-9] [ 0-9] ) cpu_col = " $COL_LIGHT_BLUE " ; ;
1[ 0-1] [ 0-9] ) cpu_col = "" ; ;
@ -263,132 +329,199 @@ get_sys_stats() {
1[ 4-5] [ 0-9] ) cpu_col = " $COL_LIGHT_RED " ; ;
*) cpu_col = " $COL_URG_RED " ; ;
esac
cpu_temp_str = " , $cpu_col $cpu_temp $COL_NC $COL_DARK_GRAY "
cpu_temp_str = " @ $cpu_col $cpu_temp $COL_NC $COL_DARK_GRAY "
else
cpu_temp_str = $( printf ", %' .0fk\n" " $( calcFunc " ( $( < $temp_file ) / 1000) + 273.15 " ) " )
cpu_temp_str = $( printf " @ %.0fk\n" " $( calcFunc " ( $( < $temp_file ) / 1000) + 273.15 " ) " )
fi
else
cpu_temp_str = ""
fi
ram_raw = ( $( awk '/MemTotal:/{total=$2} /MemFree:/{free=$2} /Buffers:/{buffers=$2} /^Cached:/{cached=$2} END {printf "%.0f %.0f %.0f", (total-free-buffers-cached)*100/total, (total-free-buffers-cached)*1024, total*1024}' /proc/meminfo) )
read -r -a ram_raw <<< " $( awk '/MemTotal:/{total=$2} /MemFree:/{free=$2} /Buffers:/{buffers=$2} /^Cached:/{cached=$2} END {printf "%.0f %.0f %.0f", (total-free-buffers-cached)*100/total, (total-free-buffers-cached)*1024, total*1024}' /proc/meminfo) "
ram_perc = " ${ ram_raw [0] } "
ram_used = " ${ ram_raw [1] } "
ram_total = " ${ ram_raw [2] } "
if [ [ " $( pihole status web 2> /dev/null) " = = "1" ] ] ; then
ph_status = " ${ COL_LIGHT_GREEN } Active "
else
ph_status = " ${ COL_LIGHT_RED } Inactiv e"
ph_status = " ${ COL_LIGHT_RED } Offlin e"
fi
if [ [ " $DHCP_ACTIVE " = = "true" ] ] ; then
ph_dhcp_num = $( wc -l 2> /dev/null < "/etc/pihole/dhcp.leases" )
local ph_dhcp_range
ph_dhcp_range = $( seq -s "|" -f " ${ DHCP_START %.* } .%g " " ${ DHCP_START ##*. } " " ${ DHCP_END ##*. } " )
# Count dynamic leases from available range, and not static leases
ph_dhcp_num = $( grep -cE " $ph_dhcp_range " "/etc/pihole/dhcp.leases" )
ph_dhcp_percent = $(( ph_dhcp_num * 100 / ph_dhcp_max ))
fi
}
get_ftl_stats( ) {
local stats_raw
stats_raw = ( $ ( pihole-FTL "stats" ) )
domains_being_blocked_raw = " ${ stats_raw [1] } "
dns_queries_today_raw = " ${ stats_raw [3] } "
ads_blocked_today_raw = " ${ stats_raw [5] } "
ads_percentage_today_raw = " ${ stats_raw [7] } "
mapfile -t stats_raw < < ( pihole-FTL "stats" )
domains_being_blocked_raw = " ${ stats_raw [1]#* } "
dns_queries_today_raw = " ${ stats_raw [3]#* } "
ads_blocked_today_raw = " ${ stats_raw [5]#* } "
ads_percentage_today_raw = " ${ stats_raw [7]#* } "
queries_forwarded_raw = " ${ stats_raw [11]#* } "
queries_cached_raw = " ${ stats_raw [13]#* } "
# Only retrieve these stats when not called from jsonFunc
if [ [ -z " $1 " ] ] ; then
local recent_blocked_raw
local top_ad_raw
local top_domain_raw
local top_client_raw
domains_being_blocked = $( printf "%' .0f\n" " ${ domains_being_blocked_raw } " )
dns_queries_today = $( printf "%' .0f\n" " ${ dns_queries_today_raw } " )
ads_blocked_today = $( printf "%' .0f\n" " ${ ads_blocked_today_raw } " )
domains_being_blocked = $( printf "%.0f\n" " ${ domains_being_blocked_raw } " )
dns_queries_today = $( printf "%.0f\n" " ${ dns_queries_today_raw } " )
ads_blocked_today = $( printf "%.0f\n" " ${ ads_blocked_today_raw } " )
ads_percentage_today = $( printf "%'.0f\n" " ${ ads_percentage_today_raw } " )
recent_blocked_raw = $( pihole-FTL recentBlocked)
top_ad_raw= ( $( pihole-FTL "top-ads (1)" ) )
top_domain_raw= ( $( pihole-FTL "top-domains (1)" ) )
top_client_raw= ( $( pihole-FTL "top-clients (1)" ) )
# Limit strings to 40 characters to prevent overflow
recent_blocked = " ${ recent_blocked_raw : 0 : 40 } "
top_ad = " ${ top_ad _raw [2 ] : 0 : 40 } "
top_domain = " ${ top_domain _raw [2] : 0 : 40 } "
[ [ " ${ top_client_raw [3] } " ] ] && top_client = " ${ top_client_raw [3] : 0 : 40 } " || top_client = " ${ top_client_raw [2] : 0 : 40 } "
queries_cached_percentage = $( printf "%.0f\n" " $( calcFunc " $queries_cached_raw * 100 / ( $queries_forwarded_raw + $queries_cached_raw ) " ) " )
recent_blocked = $( pihole-FTL recentBlocked)
read -r -a top_ad_raw <<< " $( pihole-FTL "top-ads (1)" ) "
read -r -a top_domain_raw <<< " $( pihole-FTL "top-domains (1)" ) "
read -r -a top_client_raw <<< " $( pihole-FTL "top-clients (1)" ) "
top_ad = " ${ top_ad_raw [2] } "
top_domain = " ${ top_domain_raw [2] } "
if [ [ " ${ top_client _raw [3 ] } " ] ] ; then
top_client = " ${ top_client _raw [3] } "
else
top_client = " ${ top_client_raw [2] } "
fi
fi
}
get_strings( ) {
# Expand or contract strings depending on screen size
if [ [ " $chrono_width " = = "large" ] ] ; then
phc_str = " ${ COL_DARK_GRAY } Pi-hole "
lte_str = " ${ COL_DARK_GRAY } Admin "
ftl_str = " ${ COL_DARK_GRAY } FTL "
api_str = " ${ COL_LIGHT_RED } API Offline "
host_info = " $sys_type "
sys_info = " $sys_throttle "
sys_info2 = " Active: $cpu_taskact of $cpu_tasks tasks "
used_str = "Used: "
leased_str = "Leased: "
domains_being_blocked = $( printf "%'.0f" " $domains_being_blocked " )
ph_info = " Blocking: $domains_being_blocked sites "
total_str = "Total: "
else
phc_str = " ${ COL_DARK_GRAY } PH "
lte_str = " ${ COL_DARK_GRAY } Web "
ftl_str = " ${ COL_DARK_GRAY } FTL "
api_str = " ${ COL_LIGHT_RED } API Down "
ph_info = " $domains_being_blocked blocked "
fi
[ [ " $sys_cores " -ne 1 ] ] && sys_cores_txt = " ${ sys_cores } x "
cpu_info = " $sys_cores_txt $cpu_freq $cpu_temp_str "
ram_info = " $used_str $( hrBytes " $ram_used " ) of $( hrBytes " $ram_total " ) "
disk_info = " $used_str $( hrBytes " $disk_used " ) of $( hrBytes " $disk_total " ) "
lan_info = " Gateway: $net_gateway "
dhcp_info = " $leased_str $ph_dhcp_num of $ph_dhcp_max "
ads_info = " $total_str $ads_blocked_today of $dns_queries_today "
dns_info = " $dns_count DNS servers "
[ [ " $recent_blocked " = = "0" ] ] && recent_blocked = " ${ COL_LIGHT_RED } FTL offline ${ COL_NC } "
}
chronoFunc( ) {
get_init_stats
for ( ( ; ; ) ) ; do
get_sys_stats
get_ftl_stats
# Do not print LTE/FTL strings if API is unavailable
ph_core_str = " ${ COL_DARK_GRAY } Pi-hole: $ph_core_ver ${ COL_NC } "
if [ [ -n " $ph_lte_ver " ] ] ; then
ph_lte_str = " ${ COL_DARK_GRAY } AdminLTE: $ph_lte_ver ${ COL_NC } "
ph_ftl_str = " ${ COL_DARK_GRAY } FTL: $ph_ftl_ver ${ COL_NC } "
fi
clear
echo -e " [0;1;31;91m|¯ [0;1;33;93m¯ [0;1;32;92m¯ [0;1;32;92m(¯ [0;1;36;96m)_ [0;1;34;94m_ [0;1;35;95m| [0;1;33;93m¯ [0;1;31;91m|_ [0;1;32;92m__ [0;1;36;96m_| [0;1;31;91m¯ [0;1;34;94m| [0;1;35;95m__ [0;1;31;91m_ [0m$ph_core_str
[0;1;33;93m| ¯ [0;1;32;92m_ [0;1;36;96m/¯ [0;1;34;94m|_ [0;1;35;95m_ [0;1;31;91m| [0;1;33;93m' [0;1;32;92m\/ [0;1;36;96m_ [0;1;34;94m\ [0;1;35;95m/ [0;1;31;91m- [0;1;33;93m_) [0m$ph_lte_str
[0;1;32;92m|_ [0;1;36;96m| [0;1;34;94m|_ [0;1;35;95m| [0;1;33;93m|_ [0;1;32;92m|| [0;1;36;96m_\ [0;1;34;94m__ [0;1;35;95m_/ [0;1;31;91m_\ [0;1;33;93m__ [0;1;32;92m_| [0m$ph_ftl_str
${ COL_DARK_GRAY } —————————————————————————————————————————————————————————— ${ COL_NC } "
get_strings
printFunc " Hostname: " " $sys_name "
[ -n " $sys_type " ] && printf "%s(%s)%s\n" " $COL_DARK_GRAY " " $sys_type " " $COL_NC " || printf "\n"
printf "%s\n" " Uptime: $sys_uptime "
printFunc " Task Load: " " $sys_loadavg "
printf "%s(%s)%s\n" " $COL_DARK_GRAY " " Active: $cpu_taskact of $cpu_tasks tasks " " $ COL_NC"
printFunc " CPU usage: " " $cpu_perc % "
printf "%s(%s)%s\n" " $COL_DARK_GRAY " " $sys_cores $sys_cores_plu $cpu_freq_str $cpu_temp_str " " $COL_NC "
printFunc " RAM usage: " " $ram_perc % "
printf "%s(%s)%s\n" " $COL_DARK_GRAY " " Used: $( hrBytes " $ram_used " ) of $( hrBytes " $ram_total " ) " " $COL_NC "
printFunc " HDD usage: " " $disk_perc "
printf "%s(%s)%s\n" " $COL_DARK_GRAY " " Used: $( hrBytes " $disk_used " ) of $( hrBytes " $disk_total " ) " " $COL_NC "
printFunc " LAN addr: " " ${ IPV4_ADDRESS / \/ */ } "
printf "%s(%s)%s\n" " $COL_DARK_GRAY " " Gateway: $net_gateway " " $COL_NC "
if [ [ " $DHCP_ACTIVE " = = "true" ] ] ; then
printFunc " DHCP: " " $DHCP_START to $ph_dhcp_eip "
printf "%s(%s)%s\n" " $COL_DARK_GRAY " " Leased: $ph_dhcp_num of $ph_dhcp_max " " $COL_NC "
# Strip excess development version numbers
if [ [ " $ph_core_ver " != "-1" ] ] ; then
phc_ver_str = " $phc_str : ${ ph_core_ver %-* } ${ COL_NC } "
lte_ver_str = " $lte_str : ${ ph_lte_ver %-* } ${ COL_NC } "
ftl_ver_str = " $ftl_str : ${ ph_ftl_ver %-* } ${ COL_NC } "
else
phc_ver_str = " $phc_str : $api_str ${ COL_NC } "
fi
printFunc " Pi-hole: " " $ph_status "
printf "%s(%s)%s\n" " $COL_DARK_GRAY " " Blocking: $domains_being_blocked sites " " $COL_NC "
printFunc " Ads Today: " " $ads_percentage_today % "
printf "%s(%s)%s\n" " $COL_DARK_GRAY " " $ads_blocked_today of $dns_queries_today queries " " $COL_NC "
printFunc " Fwd DNS: " " $PIHOLE_DNS_1 "
printf "%s(%s)%s\n" " $COL_DARK_GRAY " " Alt DNS: $ph_alts " " $COL_NC "
echo -e " ${ COL_DARK_GRAY } —————————————————————————————————————————————————————————— ${ COL_NC } "
echo " Recently blocked: $recent_blocked "
echo " Top Advertiser: $top_ad "
echo " Top Domain: $top_domain "
printFunc " Top Client: " " $top_client " "last"
if [ [ " $1 " = = "exit" ] ] ; then
# Get refresh number
if [ [ " $* " = = *"-r" * ] ] ; then
num = " $* "
num = " ${ num /*-r / } "
num = " ${ num / */ } "
num_str = " Refresh set for every $num seconds "
else
num_str = " "
fi
clear
# Remove exit message heading on third refresh
if [ [ " $count " -le 2 ] ] && [ [ " $* " != *"-e" * ] ] ; then
echo -e " ${ COL_LIGHT_GREEN } Pi-hole Chronometer ${ COL_NC }
$num_str
${ COL_LIGHT_RED } Press Ctrl-C to exit ${ COL_NC }
${ COL_DARK_GRAY } $scr_line_str ${ COL_NC } "
else
echo -e " [0;1;31;91m|¯ [0;1;33;93m¯ [0;1;32;92m¯ [0;1;32;92m(¯ [0;1;36;96m) [0;1;34;94m_ [0;1;35;95m| [0;1;33;93m¯ [0;1;31;91m|_ [0;1;32;92m__ [0;1;36;96m_| [0;1;31;91m¯ [0;1;34;94m| [0;1;35;95m__ [0;1;31;91m_ [0m$phc_ver_str
[0;1;33;93m| ¯ [0;1;32;92m_ [0;1;36;96m/¯ [0;1;34;94m| [0;1;35;95m_ [0;1;31;91m| [0;1;33;93m' [0;1;32;92m\/ [0;1;36;96m_ [0;1;34;94m\ [0;1;35;95m/ [0;1;31;91m- [0;1;33;93m_) [0m$lte_ver_str
[0;1;32;92m|_ [0;1;36;96m| [0;1;34;94m|_ [0;1;35;95m| [0;1;33;93m|_ [0;1;32;92m|| [0;1;36;96m_\ [0;1;34;94m__ [0;1;35;95m_/ [0;1;31;91m_\ [0;1;33;93m__ [0;1;32;92m_| [0m$ftl_ver_str
${ COL_DARK_GRAY } $scr_line_str ${ COL_NC } "
fi
printFunc " Hostname: " " $sys_name " " $host_info "
printFunc " Uptime: " " $sys_uptime " " $sys_info "
printFunc " Task Load: " " $sys_loadavg " " $sys_info2 "
printFunc " CPU usage: " " $cpu_perc % " " $cpu_info "
printFunc " RAM usage: " " $ram_perc % " " $ram_info "
printFunc " HDD usage: " " $disk_perc " " $disk_info "
if [ [ " $scr_lines " -gt 17 ] ] && [ [ " $chrono_width " != "small" ] ] ; then
printFunc " LAN addr: " " ${ IPV4_ADDRESS / \/ */ } " " $lan_info "
fi
if [ [ " $DHCP_ACTIVE " = = "true" ] ] ; then
printFunc "DHCP usage: " " $ph_dhcp_percent % " " $dhcp_info "
fi
printFunc " Pi-hole: " " $ph_status " " $ph_info "
printFunc " Ads Today: " " $ads_percentage_today % " " $ads_info "
printFunc "Local Qrys: " " $queries_cached_percentage % " " $dns_info "
printFunc " Blocked: " " $recent_blocked "
printFunc "Top Advert: " " $top_ad "
# Provide more stats on screens with more lines
if [ [ " $scr_lines " -eq 17 ] ] ; then
if [ [ " $DHCP_ACTIVE " = = "true" ] ] ; then
printFunc "Top Domain: " " $top_domain " "last"
else
print_client = "true"
fi
else
print_client = "true"
fi
if [ [ -n " $print_client " ] ] ; then
printFunc "Top Domain: " " $top_domain "
printFunc "Top Client: " " $top_client " "last"
fi
# Handle exit/refresh options
if [ [ " $* " = = *"-e" * ] ] ; then
exit 0
else
if [ [ -n " $1 " ] ] ; then
sleep " ${ 1 } "
if [ [ " $* " = = *"-r" * ] ] ; then
sleep " $num "
else
sleep 5
fi
@ -409,14 +542,14 @@ helpFunc() {
echo "Usage: pihole -c [options]
Example: 'pihole -c -j'
Calculates stats and displays to an LCD
Options:
-j, --json Output stats as JSON formatted string
-r, --refresh Set update frequency (in seconds)
-e, --exit Output stats and exit witout refreshing
-h, --help Display this help text"
fi
exit 0
}
@ -428,8 +561,8 @@ for var in "$@"; do
case " $var " in
"-j" | "--json" ) jsonFunc; ;
"-h" | "--help" ) helpFunc; ;
"-r" | "--refresh" ) chronoFunc " $2 " ; ;
"-e" | "--exit" ) chronoFunc "exit " ; ;
"-r" | "--refresh" ) chronoFunc " $@ " ; ;
"-e" | "--exit" ) chronoFunc "$@ " ; ;
* ) helpFunc "?" ; ;
esac
done