#!/bin/bash
#
#    30-sysinfo - generate the system information
#    Copyright (c) 2015-2017 Igor Pecovnik

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

THIS_SCRIPT="sysinfo"
MOTD_DISABLE=""

[[ -f /etc/default/armbian-motd ]] && . /etc/default/armbian-motd

for f in $MOTD_DISABLE; do
        [[ $f == $THIS_SCRIPT ]] && exit 0
done

# define which hard drive you want to monitor
storage=/dev/sda1

# don't edit below here

function display() {
        # $1=name $2=value $3=red_limit $4=minimal_show_limit $5=unit $6=after $7=acs/desc{
        # battery red color is opposite, lower number
        if [[ "$1" == "Battery" ]]; then local great="<"; else local great=">"; fi
        if [[ -n "$2" && "$2" > "0" && (( "${2%.*}" -ge "$4" )) ]]; then
        printf "%-14s%s" "$1:"
                if awk "BEGIN{exit ! ($2 $great $3)}"; then echo -ne "\e[0;91m $2"; else echo -ne "\e[0;92m $2"; fi
                printf "%-1s%s\x1B[0m" "$5"
                printf "%-11s%s\t" "$6"
                return 1
        fi
} # display

function getboardtemp() {
        if [ -f /etc/armbianmonitor/datasources/soctemp ]; then
                read raw_temp </etc/armbianmonitor/datasources/soctemp
                if [ ${raw_temp} -le 200 ]; then
                        # Allwinner legacy kernels output degree C
                        board_temp=${raw_temp}
                else
                        # Marvell gets special treatment for whatever reasons
                        grep -qi Marvell /proc/cpuinfo && \
                                board_temp=$(( $(awk '{printf("%d",$1/1000)}' <<<${raw_temp}) - 20 )) || \
                                board_temp=$(awk '{printf("%d",$1/1000)}' <<<${raw_temp})
                fi
        elif [ -f /etc/armbianmonitor/datasources/pmictemp ]; then
                # fallback to PMIC temperature
                board_temp=$(awk '{printf("%d",$1/1000)}' </etc/armbianmonitor/datasources/pmictemp)
        fi
} # getboardtemp

function batteryinfo() {
        # Battery info for Allwinner
        mainline_dir="/sys/power/axp_pmu"
        legacy_dir="/sys/class/power_supply"
        if [[ -e "$mainline_dir" ]]; then
                read status_battery_connected < $mainline_dir/battery/connected
                if [[ "$status_battery_connected" == "1" ]]; then
                        read status_battery_charging < $mainline_dir/charger/charging
                        read status_ac_connect < $mainline_dir/ac/connected
                        read battery_percent< $mainline_dir/battery/capacity
                        # dispay charging / percentage
                        if [[ "$status_ac_connect" == "1" && "$battery_percent" -lt "100" ]]; then
                                status_battery_text=" charging"
                        elif [[ "$status_ac_connect" == "1" && "$battery_percent" -eq "100" ]]; then
                                status_battery_text=" charged"
                        else
                                status_battery_text=" discharging"
                        fi
                fi
        elif [[ -e "$legacy_dir/battery" ]]; then
                if [[ (("$(cat $legacy_dir/battery/voltage_now)" -gt "5" )) ]]; then
                        status_battery_text=" "$(awk '{print tolower($0)}' < $legacy_dir/battery/status)
                        read battery_percent <$legacy_dir/battery/capacity
                fi
        fi
} # batteryinfo

function ambienttemp() {
        # read ambient temperature from USB device if available
        amb_temp=$(temper -c 2>/dev/null)
        case ${amb_temp} in
                *"find the USB device"*)
                        echo ""
                        ;;
                *)
                        amb_temp=$(awk '{print $NF}' <<<$amb_temp |  sed 's/C//g')
                        echo -n "scale=1;${amb_temp}/1" | grep -oE "\-?[[:digit:]]+.[[:digit:]]"
        esac
} # ambienttemp

function get_ip_addresses() {
        # return up to 2 IPv4 address(es) comma separated
        hostname -I | tr " " "\n" | \
                grep -E "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$" | \
                tail -n2 | sed ':a;N;$!ba;s/\n/,/g'
} # get_ip_addresses

function storage_info() {
        # storage info
        RootInfo=$(df -h /)
        root_usage=$(awk '/\// {print $(NF-1)}' <<<${RootInfo} | sed 's/%//g')
        root_total=$(awk '/\// {print $(NF-4)}' <<<${RootInfo})
        StorageInfo=$(df -h $storage 2>/dev/null | grep $storage)
        if [ -n "${StorageInfo}" ]; then
                storage_usage=$(awk '/\// {print $(NF-1)}' <<<${StorageInfo} | sed 's/%//g')
                storage_total=$(awk '/\// {print $(NF-4)}' <<<${StorageInfo})
                [[ "$storage" == */sd* ]] && hdd_temp=$(hddtemp -u C -nq $storage)
        fi
} # storage_info

# query various systems and send some stuff to the background for overall faster execution.
# Works only with ambienttemp and batteryinfo since A20 is slow enough :)
amb_temp=$(ambienttemp &)
ip_address=$(get_ip_addresses &)
batteryinfo
storage_info
getboardtemp
critical_load=$(( 1 + $(grep -c processor /proc/cpuinfo) / 2 ))

# get uptime, logged in users and load in one take
UptimeString=$(uptime | tr -d ',')
time=$(awk -F" " '{print $3" "$4}' <<<"${UptimeString}")
load="$(awk -F"average: " '{print $2}'<<<"${UptimeString}")"
users="$(awk -F" user" '{print $1}'<<<"${UptimeString}")"
case ${time} in
        1:*) # 1-2 hours
                time=$(awk -F" " '{print $3" hour"}' <<<"${UptimeString}")
                ;;
        *:*) # 2-24 hours
                time=$(awk -F" " '{print $3" hours"}' <<<"${UptimeString}")
                ;;
esac

# memory and swap
mem_info=$(LANG=en_US.UTF-8 free -w 2>/dev/null | grep "^Mem" || LANG=en_US.UTF-8 free | grep "^Mem")
memory_usage=$(awk '{printf("%.0f",(($2-($4+$6+$7))/$2) * 100)}' <<<${mem_info})
memory_total=$(awk '{printf("%d",$2/1024)}' <<<${mem_info})
swap_info=$(LANG=en_US.UTF-8 free -m | grep "^Swap")
swap_usage=$( (awk '/Swap/ { printf("%3.0f", $3/$2*100) }' <<<${swap_info} 2>/dev/null || echo 0) | tr -c -d '[:digit:]')
swap_total=$(awk '{print $(2)}' <<<${swap_info})

# display info
display "System load" "${load%% *}" "${critical_load}" "0" "" "${load#* }"
printf "Up time:       \x1B[92m%s\x1B[0m\t\t" "$time"
display "Local users" "${users##* }" "3" "2" ""
echo "" # fixed newline
display "Memory usage" "$memory_usage" "70" "0" " %" " of ${memory_total}MB"
display "Swap usage" "$swap_usage" "10" "0" " %" " of $swap_total""Mb"
printf "IP:            "
printf "\x1B[92m%s\x1B[0m" "$ip_address"
echo "" # fixed newline
a=0;b=0;c=0
display "CPU temp" "$board_temp" "45" "0" "°C" "" ; a=$?
display "HDD temp" "$hdd_temp" "45" "0" "°C" "" ; b=$?
display "Ambient temp" "$amb_temp" "40" "0" "°C" "" ; c=$?
(( ($a+$b+$c) >0 )) && echo "" # new line only if some value is displayed
display "Usage of /" "$root_usage" "90" "1" "%" " of $root_total"
display "storage/" "$storage_usage" "90" "1" "%" " of $storage_total"
display "Battery" "$battery_percent" "20" "1" "%" "$status_battery_text"
echo ""
echo ""
