#!/bin/bash { #//////////////////////////////////// # DietPi Cloudshell # #//////////////////////////////////// # Created by Daniel Knight / daniel.knight@dietpi.com / dietpi.com # #//////////////////////////////////// # # Info: # - System Stats for Cloudshell (or monitor/terminal) # # Usage: # dietpi-cloudshell = Config Menu # dietpi-cloudshell 1 = Run # dietpi-cloudshell 2 = Run + Skip intro #//////////////////////////////////// #Grab Input (valid interger) INPUT=0 if [[ $1 =~ ^-?[0-9]+$ ]]; then INPUT=$1 fi #Import DietPi-Globals --------------------------------------------------------------- . /DietPi/dietpi/func/dietpi-globals G_CHECK_ROOT_USER export G_PROGRAM_NAME='DietPi-Cloudshell' #Import DietPi-Globals --------------------------------------------------------------- #Version DIETPI_CLOUDSHELL_VERSION=9 #/tmp/.* files used throughout this script. FP_TEMP="/tmp/dietpi-cloudshell" PROGRAM_NAME="DietPi-Cloudshell" BLANK_SCREEN_ACTIVE=0 BLANK_SCREEN_AT_SPECIFIC_TIME_ENABLED=0 BLANK_SCREEN_TIME_HOUR_START=0 BLANK_SCREEN_TIME_HOUR_END=0 #This will only work if dietpi-cloudshell was started by autostart (login script), as the setterm power options can only be applied when the command originates from the same terminal (no redirects). RUN_BLANK_SCREEN_AT_SPECIFIC_TIME(){ local current_hour=$(date +%-H) #Turn screen off if (( ! $BLANK_SCREEN_ACTIVE )); then if (( $BLANK_SCREEN_TIME_HOUR_START == $current_hour )); then clear echo -e "\n\nScreen will be powered down in under 1 minute\n" setterm --blank 1 --powersave on &> /dev/tty1 #blank after 1 minute as force requires a poke to bring it back up. BLANK_SCREEN_ACTIVE=1 fi #Turn screen on elif (( $BLANK_SCREEN_TIME_HOUR_END == $current_hour )); then setterm --blank poke &> /dev/tty1 setterm --reset &> /dev/tty1 setterm --blank 0 --powersave off &> /dev/tty1 BLANK_SCREEN_ACTIVE=0 fi } #BC does not allow for printing leading zeros. BC_ADD_LEADING_ZERO(){ #$1 = string input local return_value=$1 #BC - Add leading zero to start of .* string. # +0 if [ "${return_value:0:1}" = "." ]; then return_value="0$return_value" # -0 elif [ "${return_value:0:2}" = "-." ]; then return_value=$(echo -e "$return_value" | sed 's/^-./-0./') fi echo "$return_value" } #Converts a byte int to string, in human readable byte format. BYTE_PRINT_CONVERSION(){ local return_value=0 local decimal_count=1 #$1=byte value # - KB if (( $1 < 1048576 )); then #return_value="$(( $1 / 1024 )) KB" return_value="$(echo "scale=$decimal_count; $1 / 1024" | bc -l ) KB" # - MB elif (( $1 < 1073741824 )); then #return_value="$(( $1 / 1024 / 1024 )) MB" return_value="$(echo "scale=$decimal_count; $1 / 1024 / 1024" | bc -l ) MB" # - GB else #return_value="$(( $1 / 1024 / 1024 / 1024 )) GB" return_value="$(echo "scale=$decimal_count; $1 / 1024 / 1024 / 1024" | bc -l ) GB" fi #BC - Add leading zero to start of .* string. return_value=$(BC_ADD_LEADING_ZERO "$return_value") echo "$return_value" } #Converts a byte int to string, in human readable bit format. # - for network data transmission rate (LAN, WLAN, ...) # - 1MB = 8Mbit | 1Mbit = 0.125MB BIT_PRINT_CONVERSION(){ local return_value=0 local decimal_count=1 #$1=byte value # - Kbit if (( $1 < 1000000 )); then #return_value="$(( $1 * 8 / 1000 )) Kbit" return_value="$(echo "scale=$decimal_count; $1 * 8 / 1000" | bc -l) Kbit" # - MBit elif (( $1 < 1000000000 )); then #return_value="$(( $1 * 8 / 1000 / 1000 )) Mbit" return_value="$(echo "scale=$decimal_count; $1 * 8 / 1000 / 1000" | bc -l) Mbit" # - GBit else #return_value="$(( $1 * 8 / 1000 / 1000 / 1000 )) Gbit" return_value="$(echo "scale=$decimal_count; $1 * 8 / 1000 / 1000 / 1000" | bc -l) Gbit" fi #BC - Add leading zero to start of .* string. return_value=$(BC_ADD_LEADING_ZERO "$return_value") echo "$return_value" } #Apply fonts Enable_Term_Options(){ # - Set large font 1st (480x320+) setfont /usr/share/consolefonts/Uni3-TerminusBold32x16 # - set small font if insufficent number of lines (320x240) if (( $(tput lines) < 10 )); then setfont /usr/share/consolefonts/Uni3-TerminusBold24x12.psf fi } #///////////////////////////////////////////////////////////////////////////////////// # Colours #///////////////////////////////////////////////////////////////////////////////////// C_RESET="\e[0m" C_REVERSE="\e[7m" #C_BOLD makes normal text "brighter" C_BOLD="\e[1m" #Colour array #0 WHITE #1 RED #2 GREEN #3 YELLOW #4 BLUE #5 PURPLE #6 CYAN #7 TEST aCOLOUR=( "\e[39m" "\e[31m" "\e[32m" "\e[33m" "\e[34m" "\e[35m" "\e[36m" "\e[93m" ) #user colour USER_COLOUR_INDEX=3 C_PERCENT_GRAPH=0 Percent_To_Graph(){ #$1 = int/float 0-100 #$C_PERCENT_GRAPH = return text #Convert to int local input_value=$(echo $1 | cut -d. -f1) #Cap input value if (( $input_value > 100 )); then input_value=100 elif (( $input_value < 0 )); then input_value=0 fi #Work out a percentage based graph #18 step split (18 / 100) if (( $input_value >= 95 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[1]}------WARNING-----$C_RESET]" elif (( $input_value >= 90 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[1]}-----------------$C_RESET-]" elif (( $input_value >= 88 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[1]}----------------$C_RESET--]" elif (( $input_value >= 82 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[1]}---------------$C_RESET---]" elif (( $input_value >= 76 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[3]}--------------$C_RESET----]" elif (( $input_value >= 70 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[3]}-------------$C_RESET-----]" elif (( $input_value >= 64 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[3]}------------$C_RESET------]" elif (( $input_value >= 56 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[3]}-----------$C_RESET-------]" elif (( $input_value >= 50 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[3]}----------$C_RESET--------]" elif (( $input_value >= 44 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[3]}---------$C_RESET---------]" elif (( $input_value >= 38 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[2]}--------$C_RESET----------]" elif (( $input_value >= 32 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[2]}-------$C_RESET-----------]" elif (( $input_value >= 26 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[2]}------$C_RESET------------]" elif (( $input_value >= 20 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[2]}-----$C_RESET-------------]" elif (( $input_value >= 15 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[2]}----$C_RESET--------------]" elif (( $input_value >= 10 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[2]}---$C_RESET---------------]" elif (( $input_value >= 5 )); then C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[2]}--$C_RESET----------------]" else C_PERCENT_GRAPH=" $input_value% [$C_REVERSE${aCOLOUR[2]}-$C_RESET-----------------]" fi } #///////////////////////////////////////////////////////////////////////////////////// # Obtain Stat Data #///////////////////////////////////////////////////////////////////////////////////// TEMPERATURE_CONVERSION_VALUE=0 Obtain_Temperature_Conversion(){ if (( $TEMPERATURE_OUTPUT_TYPE == 0 )); then TEMPERATURE_CONVERSION_VALUE=$(awk "BEGIN {printf \"%.0f\",$TEMPERATURE_CONVERSION_VALUE * 1.8 + 32"}) TEMPERATURE_CONVERSION_VALUE+="'f" else TEMPERATURE_CONVERSION_VALUE+="'c" fi } DATE_TIME=0 Obtain_DATE_TIME(){ DATE_TIME=$(date +"%a %x - %R") } UPTIME=0 Obtain_UPTIME(){ local fSeconds=$(cat /proc/uptime | awk '{print $1}') local seconds=${fSeconds%.*} local minutes=0 local hours=0 local days=0 while (( $seconds >= 60 )); do ((minutes++)) seconds=$(( $seconds - 60 )) done while (( $minutes >= 60 )); do ((hours++)) minutes=$(( $minutes - 60 )) done while (( $hours >= 24 )); do ((days++)) hours=$(( $hours - 24 )) done UPTIME="Uptime: $days Day, $hours Hour" } #CPU CPU_GOV=0 CPU_TEMP=0 C_CPUTEMP=0 CPU_FREQ_1=0 CPU_FREQ_2=0 CPU_USAGE=0 CPU_TOTALPROCESSES=0 Obtain_CPU(){ CPU_TOTALPROCESSES=$(( $(ps --ppid 2 -p 2 --deselect | wc -l) - 2 )) # - ps process and descriptions. CPU_GOV=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor) CPU_TEMP=$(G_OBTAIN_CPU_TEMP) if [[ $CPU_TEMP =~ ^-?[0-9]+$ ]]; then #Obtain colour for temps if (( $CPU_TEMP >= 65 )); then C_CPUTEMP=${aCOLOUR[1]} elif (( $CPU_TEMP >= 50 )); then C_CPUTEMP=${aCOLOUR[3]} elif (( $CPU_TEMP >= 35 )); then C_CPUTEMP=${aCOLOUR[2]} else C_CPUTEMP=${aCOLOUR[4]} fi #Set 'c or 'f output TEMPERATURE_CONVERSION_VALUE=$CPU_TEMP Obtain_Temperature_Conversion CPU_TEMP=$TEMPERATURE_CONVERSION_VALUE fi CPU_FREQ_1=$(( $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq) / 1000 )) CPU_FREQ_2="N/A" #Unique additional freq readout for Odroid XU4 (octo, 2nd quad set) if (( $G_HW_MODEL == 11 )); then CPU_FREQ_2=$(( $(cat /sys/devices/system/cpu/cpu4/cpufreq/scaling_cur_freq) / 1000 )) fi CPU_USAGE=0 FP_TEMP="/tmp/.cpu_usage" # PS (inaccurate) ps -axo %cpu | sed '1d' | sed 's/ //' > "$FP_TEMP" while read -r line do CPU_USAGE=$( echo "scale=1;$CPU_USAGE + $line" | bc -l ) done < $FP_TEMP #ps returns usage of each core, so we devide the total by #n cores CPU_USAGE=$(echo "scale=0;$CPU_USAGE / $G_HW_CPU_CORES" | bc -l ) # TOP (accurate) # Fails to output in low screen res (https://github.com/Fourdee/DietPi/issues/203#issuecomment-189711968) # CPU_USAGE=$(BC_ADD_LEADING_ZERO "$(echo "scale=1; 100 - $(top -b -n 1 | grep '%Cpu(s):' | awk '{print $8}')" | bc -l)") #convert to interger and graph it Percent_To_Graph $CPU_USAGE CPU_USAGE=$C_PERCENT_GRAPH } #Storage # - array MAX_STORAGE=6 STORAGE_TOTAL=() STORAGE_USED=() STORAGE_FREE=() STORAGE_PERCENT=() STORAGE_PATH=() STORAGE_NAME=() Init_STORAGE(){ for ((i=0; i<$MAX_STORAGE; i++)) do STORAGE_TOTAL[$i]='N/A' STORAGE_USED[$i]='N/A' STORAGE_FREE[$i]='N/A' STORAGE_PERCENT[$i]=' Not installed' STORAGE_NAME[$i]=0 # 0 reserved for flash storage if (( $i == 0 )); then STORAGE_PATH[$i]='/' STORAGE_NAME[$i]='Flash/RootFS Storage: ' else STORAGE_PATH[$i]="/mnt/usb_$i" STORAGE_NAME[$i]="Storage $i: " fi done } Destroy_STORAGE(){ unset STORAGE_TOTAL unset STORAGE_USED unset STORAGE_FREE unset STORAGE_PERCENT unset STORAGE_PATH unset STORAGE_NAME } # $1 $2 = Range of indexs to update (eg: 0-1) Obtain_STORAGE(){ local index_start=$1 local index_end=$2 FP_TEMP="/tmp/.df" rm "$FP_TEMP" #df will endless hang when NFS server is down: https://github.com/Fourdee/DietPi/issues/395 # - So lets run it as another thread so we can kill it if it hangs. local df_failed=0 df -Ph > $FP_TEMP & local pid=$(echo $!) # - Wait X seconds before terminating the df thread local max_seconds=4 local current_seconds=0 while (( $(ps aux | awk '{print $2}' | grep -ci -m1 "$pid$") )) # ! -f may exist, but no data at time of scrape, causing 'mount not found'. so lets wait for process to exit. do if (( $current_seconds >= $max_seconds )); then #kill G_DIETPI-NOTIFY 1 "DF failed, unable to obtain drive data" sleep 2 kill $pid df_failed=1 echo -e "$(date) | df failed to respond" >> /var/log/dietpi-cloudshell.log break else sleep 1 ((current_seconds++)) fi done if (( $df_failed )); then for ((i=$index_start; i<=$index_end; i++)) do STORAGE_PERCENT[$i]="${STORAGE_PATH[$i]}" STORAGE_FREE[$i]='DF failed' done else for ((i=$index_start; i<=$index_end; i++)) do if (( $(cat $FP_TEMP | grep -ci -m1 "${STORAGE_PATH[$i]}$") )); then STORAGE_TOTAL[$i]=$(cat $FP_TEMP | grep -m1 "${STORAGE_PATH[$i]}$" | awk '{print $2}'); STORAGE_TOTAL[$i]+='B' STORAGE_USED[$i]=$(cat $FP_TEMP | grep -m1 "${STORAGE_PATH[$i]}$" | awk '{print $3}'); STORAGE_USED[$i]+='B' STORAGE_FREE[$i]=$(cat $FP_TEMP | grep -m1 "${STORAGE_PATH[$i]}$" | awk '{print $4}'); STORAGE_FREE[$i]+='B' STORAGE_PERCENT[$i]=$(cat $FP_TEMP | grep -m1 "${STORAGE_PATH[$i]}$" | awk '{print $5}' | sed 's/%//g') Percent_To_Graph ${STORAGE_PERCENT[$i]} STORAGE_PERCENT[$i]=$C_PERCENT_GRAPH #DEBUG John: echo -e "Results success:\n" >> /var/log/dietpi-cloudshell.log echo -e " - Index = $i" >> /var/log/dietpi-cloudshell.log echo -e " - Path = ${STORAGE_PATH[$i]}" >> /var/log/dietpi-cloudshell.log echo -e " - Total = ${STORAGE_TOTAL[$i]}" >> /var/log/dietpi-cloudshell.log else STORAGE_PERCENT[$i]="${STORAGE_PATH[$i]}" STORAGE_FREE[$i]='Mount not active' #DEBUG John: echo -e "$(date) | Mount not found:\n" >> /var/log/dietpi-cloudshell.log echo -e " - Index = $i" >> /var/log/dietpi-cloudshell.log echo -e " - Path = ${STORAGE_PATH[$i]}\n" >> /var/log/dietpi-cloudshell.log cat "$FP_TEMP" >> /var/log/dietpi-cloudshell.log echo -e "\n" >> /var/log/dietpi-cloudshell.log fi done fi } #DietPi DIETPI_VERSION_CURRENT=0 DIETPI_UPDATE_AVAILABLE=0 DIETPI_WEBSITE='dietpi.com' DIETPI_TWITTER="@dietpi_" DIETPI_HW_DESCRIPTION="N/A" Obtain_DIETPIINFO(){ #DietPi version DIETPI_VERSION_CURRENT="${aCOLOUR[2]}$(sed -n 1p /DietPi/dietpi/.version).$(sed -n 2p /DietPi/dietpi/.version)$C_RESET" #Current HW DIETPI_HW_DESCRIPTION=$(sed -n 2p /DietPi/dietpi/.hw_model) #DietPi-Update available? DIETPI_UPDATE_AVAILABLE="N/A" if [ -f /DietPi/dietpi/.update_available ]; then #Set current version to red DIETPI_VERSION_CURRENT="${aCOLOUR[1]}$(sed -n 1p /DietPi/dietpi/.version).$(sed -n 2p /DietPi/dietpi/.version)$C_RESET" local update_version=$(cat /DietPi/dietpi/.update_available) if [ "$update_version" = '-1' ]; then DIETPI_UPDATE_AVAILABLE="${aCOLOUR[2]}New Image$C_RESET" else DIETPI_UPDATE_AVAILABLE="${aCOLOUR[2]}$update_version$C_RESET" fi fi } #Network Details NETWORK_DETAILS_ADAPTER='eth0' NETWORK_DETAILS_IP_INT=0 NETWORK_DETAILS_MAC_ADDRESS=0 NETWORK_DETAILS_SIGNAL_STRENGTH=0 NETWORK_DETAILS_DUPLEXSPEED=0 NETWORK_DETAILS_HOSTNAME=0 NETWORK_DETAILS_MODE=0 #1=dhcp, 0=static Obtain_NETWORK_DETAILS(){ FP_TEMP="/tmp/.ifconfig" #Hostname NETWORK_DETAILS_HOSTNAME=$(hostname) #Active network adapater. NETWORK_DETAILS_ADAPTER=$(sed -n 3p /DietPi/dietpi/.network) #Mode (dhcp/static) if (( $(cat /etc/network/interfaces | grep -ci -m1 "iface $NETWORK_DETAILS_ADAPTER inet dhcp") )); then NETWORK_DETAILS_MODE="Dhcp" else NETWORK_DETAILS_MODE="Static" fi #Ifconfig to /tmp ifconfig $NETWORK_DETAILS_ADAPTER > $FP_TEMP #IP / MAC addresses NETWORK_DETAILS_IP_INT=$(cat "$FP_TEMP" | grep -m1 'inet '| cut -d: -f2 | awk '{ print $1}') NETWORK_DETAILS_MAC_ADDRESS=$(cat /sys/class/net/$NETWORK_DETAILS_ADAPTER/address) #Speed/Strength #Wifi if (( $(echo $NETWORK_DETAILS_ADAPTER | grep -ci -m1 'wlan') == 1 )); then NETWORK_DETAILS_SIGNAL_STRENGTH="$(iwconfig $NETWORK_DETAILS_ADAPTER | grep -m1 'Signal level=' | awk '{ print $4 }' | sed 's/level=//g' | cut -f1 -d "/")%" NETWORK_DETAILS_DUPLEXSPEED="$(iwconfig $NETWORK_DETAILS_ADAPTER | grep -m1 'Bit Rate:' | awk '{ print $2 }' | sed 's/Rate://g')Mbit" #Lan else NETWORK_DETAILS_DUPLEXSPEED="$(cat /sys/class/net/$NETWORK_DETAILS_ADAPTER/speed) Mbit" #NETWORK_DETAILS_DUPLEXSPEED=$(mii-tool | awk '{print $3}') NETWORK_DETAILS_SIGNAL_STRENGTH="N/A" fi } #Network Usage (all values are in bytes) NETWORK_USAGE_TOTAL_CURRENT_SENT=0 NETWORK_USAGE_TOTAL_CURRENT_RECIEVED=0 NETWORK_USAGE_NOW_CURRENT_SENT=0 NETWORK_USAGE_NOW_CURRENT_RECIEVED=0 NETWORK_USAGE_NOW_INIT=0 NETWORK_USAGE_SECONDS_SINCE_LAST_UPDATE=0 NETWORK_USAGE_DAY_CURRENT_SENT=0 NETWORK_USAGE_DAY_CURRENT_RECIEVED=0 NETWORK_USAGE_DAY_PREVIOUS_SENT=0 NETWORK_USAGE_DAY_PREVIOUS_RECIEVED=0 NETWORK_USAGE_DAY_OF_MONTH=-1 Obtain_NETWORK_USAGE(){ #Check for valid integer scrapes from netstat, before running calculations: http://dietpi.com/phpbb/viewtopic.php?f=11&t=441&p=1927#p1927 | https://github.com/Fourdee/DietPi/issues/355 local run_update=1 local mtu_size=$(netstat -N -i | grep "$NETWORK_DETAILS_ADAPTER" | awk '{print $2}') if [[ ! $mtu_size =~ ^-?[0-9]+$ ]]; then run_update=0 fi local network_usage_current_recieved=$(netstat -N -i | grep "$NETWORK_DETAILS_ADAPTER" | awk '{print $4}') if [[ ! $network_usage_current_recieved =~ ^-?[0-9]+$ ]]; then run_update=0 fi local network_usage_current_sent=$(netstat -N -i | grep "$NETWORK_DETAILS_ADAPTER" | awk '{print $8}') if [[ ! $network_usage_current_sent =~ ^-?[0-9]+$ ]]; then run_update=0 fi if (( $run_update == 1 )); then #Store previous totals local total_previous_sent=$NETWORK_USAGE_TOTAL_CURRENT_SENT local total_previous_recieved=$NETWORK_USAGE_TOTAL_CURRENT_RECIEVED #Update current totals NETWORK_USAGE_TOTAL_CURRENT_RECIEVED=$(( $network_usage_current_recieved * $mtu_size )) NETWORK_USAGE_TOTAL_CURRENT_SENT=$(( $network_usage_current_sent * $mtu_size )) #Current usage # - Work out seconds since last update local seconds_since_last_update=$(( $(date +%s) - $NETWORK_USAGE_SECONDS_SINCE_LAST_UPDATE )) # - Init - Override current usage to 0, on first run of scene. if (( $NETWORK_USAGE_NOW_INIT == 0 )); then NETWORK_USAGE_NOW_CURRENT_SENT=0 NETWORK_USAGE_NOW_CURRENT_RECIEVED=0 NETWORK_USAGE_NOW_INIT=1 # - Obtain current usage else NETWORK_USAGE_NOW_CURRENT_SENT=$(( ( $NETWORK_USAGE_TOTAL_CURRENT_SENT - $total_previous_sent ) / $seconds_since_last_update )) NETWORK_USAGE_NOW_CURRENT_RECIEVED=$(( ( $NETWORK_USAGE_TOTAL_CURRENT_RECIEVED - $total_previous_recieved ) / $seconds_since_last_update )) fi # - Update timestamp NETWORK_USAGE_SECONDS_SINCE_LAST_UPDATE=$(date +%s) # - Ifconfig to /tmp #ifconfig $NETWORK_DETAILS_ADAPTER > $FP_TEMP #/sys/class/net/ values are being reset by system/kernel when they reach X size. Some sort of "cap". #NETWORK_USAGE_TOTAL_CURRENT_SENT=$(( $(cat /sys/class/net/$NETWORK_DETAILS_ADAPTER/statistics/tx_bytes) / 1024 / 1024 )) #NETWORK_USAGE_TOTAL_CURRENT_RECIEVED=$(( $(cat /sys/class/net/$NETWORK_DETAILS_ADAPTER/statistics/rx_bytes) / 1024 / 1024 )) #Usage today # - Has the day changed? Also runs on init. # String if statement, to prevent "leading zero integer error" from $(date): https://github.com/Fourdee/DietPi/issues/272 local dayofmonth=$(date +"%d") if [ "$NETWORK_USAGE_DAY_OF_MONTH" != "$dayofmonth" ]; then #Update previous day values to current NETWORK_USAGE_DAY_PREVIOUS_SENT=$NETWORK_USAGE_TOTAL_CURRENT_SENT NETWORK_USAGE_DAY_PREVIOUS_RECIEVED=$NETWORK_USAGE_TOTAL_CURRENT_RECIEVED NETWORK_USAGE_DAY_OF_MONTH=$dayofmonth fi # - Work out todays usage NETWORK_USAGE_DAY_CURRENT_SENT=$(( $NETWORK_USAGE_TOTAL_CURRENT_SENT - $NETWORK_USAGE_DAY_PREVIOUS_SENT )) NETWORK_USAGE_DAY_CURRENT_RECIEVED=$(( $NETWORK_USAGE_TOTAL_CURRENT_RECIEVED - $NETWORK_USAGE_DAY_PREVIOUS_RECIEVED )) fi } #Memory MEMORY_TOTAL=0 MEMORY_FREE=0 MEMORY_USED=0 MEMORY_CACHED=0 MEMORY_PERCENT=0 MEMORY_SWAPTOTAL=0 MEMORY_SWAPUSED=0 MEMORY_SWAPFREE=0 MEMORY_SWAPERCENT=0 Obtain_MEMORY(){ #Write to temp FP_TEMP="/tmp/.mem" free -m > $FP_TEMP #RAM MB MEMORY_TOTAL=$(cat $FP_TEMP | grep -m1 'Mem: ' | awk '{print $2}') #Grab values and seperate cache from "used and free" results. MEMORY_CACHED=$(cat $FP_TEMP | grep -m1 'Mem: ' | awk '{print $7}') MEMORY_USED=$(( $(cat $FP_TEMP | grep -m1 'Mem: ' | awk '{print $3}') - $MEMORY_CACHED )) MEMORY_FREE=$(( $(cat $FP_TEMP | grep -m1 'Mem: ' | awk '{print $4}') + $MEMORY_CACHED )) MEMORY_PERCENT=$(echo | awk "{print $MEMORY_USED / $MEMORY_TOTAL * 100}") #convert to interger and graph it Percent_To_Graph $MEMORY_PERCENT MEMORY_PERCENT=$C_PERCENT_GRAPH #SWAP MB MEMORY_SWAPTOTAL=$(cat $FP_TEMP | grep -m1 'Swap: ' | awk '{print $2}') # - Swap available and active if (( $MEMORY_SWAPTOTAL > 0 )); then MEMORY_SWAPUSED=$(cat $FP_TEMP | grep -m1 'Swap: ' | awk '{print $3}') MEMORY_SWAPFREE=$(cat $FP_TEMP | grep -m1 'Swap: ' | awk '{print $4}') MEMORY_SWAPERCENT=$( echo | awk "{print $MEMORY_SWAPUSED / $MEMORY_SWAPTOTAL * 100}") #convert to interger and graph it Percent_To_Graph $MEMORY_SWAPERCENT MEMORY_SWAPERCENT=$C_PERCENT_GRAPH else MEMORY_SWAPERCENT=" Disabled" fi } #PI-HOLE STATS! PIHOLE_QUERY_COUNT=0 PIHOLE_TOTAL_ADS=0 PIHOLE_PERCENT_ADS=0 PIHOLE_TOTAL_DOMAINS=0 PIHOLE_LAST_DOMAIN_BLOCKED=0 Obtain_PIHOLE(){ local pihole_log_file="/var/log/pihole.log" #Lets pull the total number of blocked domains only once during 1st run, its quite cpu intensive. if (( $PIHOLE_TOTAL_DOMAINS == 0 )); then if [ -f /etc/pihole/gravity.list ]; then PIHOLE_TOTAL_DOMAINS=$(wc -l /etc/pihole/gravity.list | awk '{print $1}') else PIHOLE_TOTAL_DOMAINS="Not Installed" fi fi local today=$(date +'%b %e') PIHOLE_QUERY_COUNT=$(cat "$pihole_log_file" | grep "$today" | awk '/query/ {print $7}' | wc -l) #Prevent / 0 on percentage if (( $PIHOLE_QUERY_COUNT <= 0 )); then PIHOLE_QUERY_COUNT=1 fi PIHOLE_TOTAL_ADS=$(cat "$pihole_log_file" | grep "$today" | awk '/\/etc\/pihole\/gravity.list/ {print $7}' | wc -l) PIHOLE_PERCENT_ADS=$(echo | awk "{print $PIHOLE_TOTAL_ADS / $PIHOLE_QUERY_COUNT * 100}") #convert to interger and graph it Percent_To_Graph $PIHOLE_PERCENT_ADS PIHOLE_PERCENT_ADS=$C_PERCENT_GRAPH #Get last blocked domain if (( $PIHOLE_TOTAL_ADS == 0 )); then PIHOLE_LAST_DOMAIN_BLOCKED="None" else PIHOLE_LAST_DOMAIN_BLOCKED=$(tac /var/log/pihole.log | grep -m1 'gravity.list' | awk '{print $6}' | cut -c 1-24 ) fi } #///////////////////////////////////////////////////////////////////////////////////// # Scene Settings #///////////////////////////////////////////////////////////////////////////////////// RUN_INTRO=0 if (( $INPUT == 1 )); then RUN_INTRO=1 fi #SCENE INDEXS SCENE_CURRENT=2 MAX_SCENES=9 #Refresh rate (every X seconds) REFRESH_RATE=5 #0='f | 1='c TEMPERATURE_OUTPUT_TYPE=1 #0=bit (Mbit) | 1=byte (MB) NETWORK_USAGE_CURRENT_OUTPUT_TYPE=0 #Enabled Scenes aEnabledScenes=() for ((i=0; i<$MAX_SCENES; i++)) do aEnabledScenes[$i]=1 done #///////////////////////////////////////////////////////////////////////////////////// # Scene Print / Update #///////////////////////////////////////////////////////////////////////////////////// Run_Intro(){ #'--------------------------' clear local aAnimation=( ' ' 'i - c' 'P i - c l' 't P i - c l o' 'e t P i- c l o u' 'i e t Pi- c l o u d s' 'D i etPi- c l o u d s h' ' D ietPi-c l o u d s h e' ' DietPi-cl o u d s h e ' ' DietPi-clou d s h e l ' ' DietPi-clouds h e l l ' ' DietPi-cloudshe l l ' ' DietPi-cloudshell ' ) local aBar=( ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ) for ((i=0; i<${#aAnimation[@]}; i++)) do clear echo -e "$C_RESET" echo -e "" echo -e "" echo -e "" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}${aAnimation[$i]}" echo -e "$C_RESET v$DIETPI_CLOUDSHELL_VERSION" echo -e "" echo -e " Loading..." echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE${aBar[$i]}" sleep 0.2 done #delete[] array unset aAnimation unset aBar sleep 0.1 } #Top banner BANNER_PRINT=0 BANNER_MODE=0 Update_Banner(){ #Banner Modes if (( $BANNER_MODE == 0 )); then BANNER_PRINT="DietPi - Cloudshell v$DIETPI_CLOUDSHELL_VERSION" elif (( $BANNER_MODE == 1 )); then Obtain_DATE_TIME BANNER_PRINT=$DATE_TIME elif (( $BANNER_MODE == 2 )); then Obtain_UPTIME BANNER_PRINT=$UPTIME fi #Set next index ((BANNER_MODE++)) #Cap if (( $BANNER_MODE >= 3 )); then BANNER_MODE=0 fi } #CPU Update_Scene_0(){ #Update data Obtain_CPU #Clear screen clear #Banner echo -e "$C_RESET $BANNER_PRINT" # echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE CPU Usage: " echo -e "$C_RESET$CPU_USAGE" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE CPU Stats: " echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Temp ${aCOLOUR[$USER_COLOUR_INDEX]}:$C_RESET $C_CPUTEMP$CPU_TEMP" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Processes ${aCOLOUR[$USER_COLOUR_INDEX]}:$C_RESET $CPU_TOTALPROCESSES" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Governor ${aCOLOUR[$USER_COLOUR_INDEX]}:$C_RESET $CPU_GOV" #XU3/4 unique octo quad sets if (( $G_HW_MODEL == 11 )); then echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Freq 0-3 ${aCOLOUR[$USER_COLOUR_INDEX]}:$C_RESET $CPU_FREQ_1 mhz" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Freq 4-7 ${aCOLOUR[$USER_COLOUR_INDEX]}:$C_RESET $CPU_FREQ_2 mhz" #Generic CPU hardware else echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Freq ${aCOLOUR[$USER_COLOUR_INDEX]}:$C_RESET $CPU_FREQ_1 mhz" fi } #$1 $2 = Storage index's to update and display (must be a range of 1 , eg: 0-1 1-2 3-4) Update_Scene_1(){ local index_1=$1 local index_2=$2 #Update data Obtain_STORAGE $index_1 $index_2 #Clear screen clear #Banner echo -e "$C_RESET $BANNER_PRINT" # echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE ${STORAGE_NAME[$index_1]}" echo -e "$C_RESET${STORAGE_PERCENT[$index_1]}" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Used: $C_RESET${STORAGE_USED[$index_1]} / ${STORAGE_TOTAL[$index_1]}" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Free: $C_RESET${STORAGE_FREE[$index_1]}" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE ${STORAGE_NAME[$index_2]}" echo -e "$C_RESET${STORAGE_PERCENT[$index_2]}" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Used: $C_RESET${STORAGE_USED[$index_2]} / ${STORAGE_TOTAL[$index_2]}" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Free: $C_RESET${STORAGE_FREE[$index_2]}" } #DietPi Update_Scene_4(){ #Update data Obtain_DIETPIINFO #Clear screen clear #Banner echo -e "$C_RESET $BANNER_PRINT" # echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE DietPi: " echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Version ${aCOLOUR[$USER_COLOUR_INDEX]}:$C_RESET $DIETPI_VERSION_CURRENT" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Updates ${aCOLOUR[$USER_COLOUR_INDEX]}:$C_RESET $DIETPI_UPDATE_AVAILABLE" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Web ${aCOLOUR[$USER_COLOUR_INDEX]}:$C_RESET $DIETPI_WEBSITE" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Twitter ${aCOLOUR[$USER_COLOUR_INDEX]}:$C_RESET $DIETPI_TWITTER" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE Device: " echo -e "$C_RESET $DIETPI_HW_DESCRIPTION" } #NETWORK DETAILS Update_Scene_5(){ #Update data Obtain_NETWORK_DETAILS #Clear screen clear #Banner echo -e "$C_RESET $BANNER_PRINT" # echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE Network Details: " echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} IP : $C_RESET$NETWORK_DETAILS_IP_INT" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Mode : $C_RESET$NETWORK_DETAILS_MODE" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Adapter : $C_RESET$NETWORK_DETAILS_ADAPTER" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Duplex : $C_RESET$NETWORK_DETAILS_DUPLEXSPEED" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Signal : $C_RESET$NETWORK_DETAILS_SIGNAL_STRENGTH" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Hostname: $C_RESET$NETWORK_DETAILS_HOSTNAME" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} MAC: $C_RESET$NETWORK_DETAILS_MAC_ADDRESS" } #NETWORK USAGE Update_Scene_6(){ #Update data Obtain_NETWORK_USAGE # - Convert usage values into human readable format. Run before clearing screen due to additional processing (delay) local total_sent_output=$( BYTE_PRINT_CONVERSION $NETWORK_USAGE_TOTAL_CURRENT_SENT ) local total_recieved_output=$( BYTE_PRINT_CONVERSION $NETWORK_USAGE_TOTAL_CURRENT_RECIEVED ) local today_sent_output=$( BYTE_PRINT_CONVERSION $NETWORK_USAGE_DAY_CURRENT_SENT ) local today_recieved_output=$( BYTE_PRINT_CONVERSION $NETWORK_USAGE_DAY_CURRENT_RECIEVED ) local now_sent_output=0 local now_recieved_output0 if (( $NETWORK_USAGE_CURRENT_OUTPUT_TYPE == 0 )); then now_sent_output=$( BIT_PRINT_CONVERSION $NETWORK_USAGE_NOW_CURRENT_SENT ) now_recieved_output=$( BIT_PRINT_CONVERSION $NETWORK_USAGE_NOW_CURRENT_RECIEVED ) else now_sent_output=$( BYTE_PRINT_CONVERSION $NETWORK_USAGE_NOW_CURRENT_SENT ) now_recieved_output=$( BYTE_PRINT_CONVERSION $NETWORK_USAGE_NOW_CURRENT_RECIEVED ) fi #Clear screen clear #Banner # - Banner does not fit this scene (>= 9 lines) #echo -e "$C_RESET $BANNER_PRINT" # echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE Network Usage (TOTAL): " echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Sent : $C_RESET$total_sent_output" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Recieved : $C_RESET$total_recieved_output" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE Network Usage (TODAY): " echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Sent : $C_RESET$today_sent_output" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Recieved : $C_RESET$today_recieved_output" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE Network Usage (CURRENT): " echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Sent : $C_RESET$now_sent_output/s" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Recieved : $C_RESET$now_recieved_output/s" } #Memory Update_Scene_7(){ #Update data Obtain_MEMORY #Clear screen clear #Banner echo -e "$C_RESET $BANNER_PRINT" # echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE Memory Usage (RAM): " echo -e "$C_RESET$MEMORY_PERCENT" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Used: $C_RESET$MEMORY_USED MB / $MEMORY_TOTAL MB" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Free: $C_RESET$MEMORY_FREE MB" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE Memory Usage (SWAP): " echo -e "$C_RESET$MEMORY_SWAPERCENT" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Used: $C_RESET$MEMORY_SWAPUSED MB / $MEMORY_SWAPTOTAL MB" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Free: $C_RESET$MEMORY_SWAPFREE MB" } #Pi-hole Update_Scene_8(){ #Update data Obtain_PIHOLE #Clear screen clear #Banner echo -e "$C_RESET $BANNER_PRINT" # echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE Pi-hole stats (TODAY): " echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Ads Blocked: $C_RESET$PIHOLE_TOTAL_ADS" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} DNS Queries: $C_RESET$PIHOLE_QUERY_COUNT" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]} Blocked Domains: $C_RESET$PIHOLE_TOTAL_DOMAINS" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE % of traffic = Ads: " echo -e "$C_RESET$PIHOLE_PERCENT_ADS" echo -e "$C_RESET${aCOLOUR[$USER_COLOUR_INDEX]}$C_REVERSE Last domain blocked: " echo -e "$C_RESET $PIHOLE_LAST_DOMAIN_BLOCKED" } #///////////////////////////////////////////////////////////////////////////////////// # Settings File #///////////////////////////////////////////////////////////////////////////////////// #Define Location FILEPATH_SETTINGS="/DietPi/dietpi/.dietpi-cloudshell" Read_Settings_File(){ if [ -f "$FILEPATH_SETTINGS" ]; then . "$FILEPATH_SETTINGS" fi } Write_Settings_File(){ cat << _EOF_ > "$FILEPATH_SETTINGS" REFRESH_RATE=$REFRESH_RATE USER_COLOUR_INDEX=$USER_COLOUR_INDEX TEMPERATURE_OUTPUT_TYPE=$TEMPERATURE_OUTPUT_TYPE OUTPUT_DISPLAY_INDEX=$OUTPUT_DISPLAY_INDEX NETWORK_USAGE_CURRENT_OUTPUT_TYPE=$NETWORK_USAGE_CURRENT_OUTPUT_TYPE BLANK_SCREEN_AT_SPECIFIC_TIME_ENABLED=$BLANK_SCREEN_AT_SPECIFIC_TIME_ENABLED BLANK_SCREEN_TIME_HOUR_START=$BLANK_SCREEN_TIME_HOUR_START BLANK_SCREEN_TIME_HOUR_END=$BLANK_SCREEN_TIME_HOUR_END _EOF_ #Add enabled scenes for ((i=0; i<$MAX_SCENES; i++)) do echo -e "aEnabledScenes[$i]=${aEnabledScenes[$i]}" >> $FILEPATH_SETTINGS done #Add Drive Paths and Names for ((i=0; i<$MAX_STORAGE; i++)) do echo -e "STORAGE_PATH[$i]='${STORAGE_PATH[$i]}'" >> $FILEPATH_SETTINGS echo -e "STORAGE_NAME[$i]='${STORAGE_NAME[$i]}'" >> $FILEPATH_SETTINGS done } #///////////////////////////////////////////////////////////////////////////////////// # Init #///////////////////////////////////////////////////////////////////////////////////// Init(){ #-------------------------------------------------------------------------------- #Storage array Init_STORAGE #-------------------------------------------------------------------------------- #Load Settings file. Read_Settings_File #-------------------------------------------------------------------------------- #VM disable CPU scene if (( $G_HW_MODEL == 20 )); then aEnabledScenes[0]=0 fi #-------------------------------------------------------------------------------- #Check and disable scenes if software is not installed: # 6 Pi-hole if [ ! -f /etc/pihole/gravity.list ]; then aEnabledScenes[8]=0 fi #-------------------------------------------------------------------------------- #Ensure we have at least 1 Scene enabled in the settings file. local enabled_scene=0 for ((i=0; i<$MAX_SCENES; i++)) do if (( ${aEnabledScenes[$i]} )); then enabled_scene=1 break fi done #No Scenes selected! Override user setting and enable at least 1 scene (dietpi) if (( $enabled_scene == 0 )); then aEnabledScenes[4]=1 SCENE_CURRENT=4 fi #-------------------------------------------------------------------------------- #Update DietPi network shared data: https://github.com/Fourdee/DietPi/issues/359 /DietPi/dietpi/func/obtain_network_details } #///////////////////////////////////////////////////////////////////////////////////// # Start/Stop Control for Menu #///////////////////////////////////////////////////////////////////////////////////// #0=tty1 1=current OUTPUT_DISPLAY_INDEX=0 Stop(){ #Service if started. systemctl stop dietpi-cloudshell #Kill all , excluding Menu. ps ax | grep '[d]ietpi-cloudshell [1-9]' | awk '{print $1}' > "$FP_TEMP" while read -r line do kill $line &> /dev/null done < $FP_TEMP } Start(){ #Are we starting on the current screen? (eg: from tty1) local output_current_screen=0 if [ "$(tty)" = "/dev/tty1" ]; then output_current_screen=1 elif (( $OUTPUT_DISPLAY_INDEX == 1 )); then output_current_screen=1 fi #Inform user to press CTRL+C to exit if (( $output_current_screen == 1 )); then clear echo -e "$C_RESET" read -p "Use CTRL+C to exit. Press any key to launch $PROGRAM_NAME..." fi #Launch in blocking mode if (( $output_current_screen == 1 )); then /DietPi/dietpi/dietpi-cloudshell 1 #Launch as service on main screen else systemctl start dietpi-cloudshell fi sleep 0.1 } #///////////////////////////////////////////////////////////////////////////////////// # Menu System #///////////////////////////////////////////////////////////////////////////////////// WHIP_BACKTITLE=0 WHIP_TITLE=0 WHIP_QUESTION=0 CHOICE=0 TARGETMENUID=0 LASTSELECTED_ITEM="" Menu_Exit(){ WHIP_TITLE="Exit $PROGRAM_NAME" WHIP_QUESTION="Exit $PROGRAM_NAME configuration tool?" whiptail --title "$WHIP_TITLE" --yesno "$WHIP_QUESTION" --backtitle "$WHIP_TITLE" --yes-button "Ok" --no-button "Back" --defaultno 9 55 CHOICE=$? if (( $CHOICE == 0 )); then #Save changes Write_Settings_File #exit TARGETMENUID=-1 else #Return to Main Menu TARGETMENUID=0 fi } #TARGETMENUID=0 Menu_Main(){ TARGETMENUID=0 WHIP_BACKTITLE="- $PROGRAM_NAME v$DIETPI_CLOUDSHELL_VERSION -" WHIP_TITLE="- $PROGRAM_NAME -" local temp_output_text="Fahrenheit" if (( $TEMPERATURE_OUTPUT_TYPE == 1 )); then temp_output_text="Celsius" fi local target_output_text="Main Screen (tty1)" if (( $OUTPUT_DISPLAY_INDEX == 1 )); then target_output_text="Current screen or terminal" fi local bitbyte_output_text="Bit (Kbit, Mbit, Gbit)" if (( $NETWORK_USAGE_CURRENT_OUTPUT_TYPE == 1 )); then bitbyte_output_text="Byte (KB, MB, GB)" fi local autoscreenoff="Disabled" if (( $BLANK_SCREEN_AT_SPECIFIC_TIME_ENABLED )); then autoscreenoff="Enabled" fi OPTION=$(whiptail --title "$WHIP_TITLE" --backtitle "$WHIP_BACKTITLE" --menu "" --cancel-button "Exit" --default-item "$LASTSELECTED_ITEM" 17 75 10 \ "Colour" "Setting: Change the colour scheme." \ "Update Rate" "Setting: Control the time between screen updates." \ "Scenes" "Setting: Toggle which scenes are shown." \ "Storage" "Setting: Set mount locations used for storage stats" \ "Temperature" "Setting: Output = $temp_output_text" \ "Net Usage Current" "Setting: Output = $bitbyte_output_text" \ "Output Display" "Setting: $target_output_text." \ "Auto screen off" "Setting: $autoscreenoff | Start $BLANK_SCREEN_TIME_HOUR_START h | End $BLANK_SCREEN_TIME_HOUR_END h" \ "Start / Restart" "Apply settings. Launch on $target_output_text." \ "Stop" "Stops $PROGRAM_NAME." 3>&1 1>&2 2>&3) CHOICE=$? if (( $CHOICE == 0 )); then LASTSELECTED_ITEM="$OPTION" case "$OPTION" in "Storage") TARGETMENUID=5 ;; "Auto screen off") TARGETMENUID=4 ;; "Net Usage Current") ((NETWORK_USAGE_CURRENT_OUTPUT_TYPE++)) if (( $NETWORK_USAGE_CURRENT_OUTPUT_TYPE > 1 )); then NETWORK_USAGE_CURRENT_OUTPUT_TYPE=0 fi ;; Temperature) ((TEMPERATURE_OUTPUT_TYPE++)) if (( $TEMPERATURE_OUTPUT_TYPE > 1 )); then TEMPERATURE_OUTPUT_TYPE=0 fi ;; "Output Display") ((OUTPUT_DISPLAY_INDEX++)) if (( $OUTPUT_DISPLAY_INDEX > 1 )); then OUTPUT_DISPLAY_INDEX=0 fi ;; "Start / Restart") Write_Settings_File Stop Start ;; "Stop") Stop ;; Colour) TARGETMENUID=1 ;; "Update Rate") TARGETMENUID=2 ;; Scenes) TARGETMENUID=3 ;; esac else Menu_Exit fi } #TARGETMENUID=1 Menu_Colour(){ #Return to main menu TARGETMENUID=0 #Colour array #0 WHITE #1 RED #2 GREEN #3 YELLOW #4 BLUE #5 PURPLE #6 CYAN WHIP_TITLE='- Options : Colour -' WHIP_QUESTION='Select your colour scheme.' OPTION=$(whiptail --title "$WHIP_TITLE" --backtitle "$WHIP_BACKTITLE" --menu "$WHIP_QUESTION" --cancel-button "Back" --default-item "$USER_COLOUR_INDEX" 15 45 7 \ "0" "White" \ "1" "Red" \ "2" "Green" \ "3" "Yellow (Default)" \ "4" "Blue" \ "5" "Purple" \ "6" "Cyan" 3>&1 1>&2 2>&3) CHOICE=$? if (( $CHOICE == 0 )); then USER_COLOUR_INDEX=$OPTION fi } #TARGETMENUID=2 Menu_UpdateRate(){ #Return to main menu TARGETMENUID=0 WHIP_TITLE='- Options : Update Rate -' WHIP_QUESTION='Change the delay between scene changes and updates.' OPTION=$(whiptail --title "$WHIP_TITLE" --backtitle "$WHIP_BACKTITLE" --menu "$WHIP_QUESTION" --cancel-button "Back" --default-item "$REFRESH_RATE" 15 55 7 \ "1" "Second" \ "3" "Seconds" \ "5" "Seconds (Default)" \ "10" "Seconds" \ "15" "Seconds" \ "20" "Seconds" \ "30" "Seconds" \ "45" "Seconds" \ "60" "Seconds" 3>&1 1>&2 2>&3) CHOICE=$? if (( $CHOICE == 0 )); then REFRESH_RATE=$OPTION fi } #TARGETMENUID=3 Menu_SceneSelection(){ #Return to main menu TARGETMENUID=0 FP_TEMP="/tmp/.dietpi-cloudshell_scenelist" #Get on/off whilptail status local aWhiptailArray=() local aWhip_OnOff_Status=() for ((i=0; i<$MAX_SCENES; i++)) do #On/Off status aWhip_OnOff_Status[$i]='on' if (( ! ${aEnabledScenes[$i]} )); then aWhip_OnOff_Status[$i]='off' fi done #Define options local index=0 index=0;aWhiptailArray+=("$index" "CPU: Temperatures, Usage, frequency and more." "${aWhip_OnOff_Status[$index]}") index=1;aWhiptailArray+=("$index" "Storage: Usage information for Flash and USB drives" "${aWhip_OnOff_Status[$index]}") index=2;aWhiptailArray+=("$index" " - Additional Storage (USB_2/3)" "${aWhip_OnOff_Status[$index]}") index=3;aWhiptailArray+=("$index" " - Additional Storage (USB_4/5)" "${aWhip_OnOff_Status[$index]}") index=4;aWhiptailArray+=("$index" "DietPi: Information, stats and updates for DietPi." "${aWhip_OnOff_Status[$index]}") index=5;aWhiptailArray+=("$index" "Network Details: Ip address, Speeds, Signal and more." "${aWhip_OnOff_Status[$index]}") index=6;aWhiptailArray+=("$index" "Network Usage: Bandwidth usage (sent / recieved)." "${aWhip_OnOff_Status[$index]}") index=7;aWhiptailArray+=("$index" "Memory: Stats for RAM and Swapfile usage." "${aWhip_OnOff_Status[$index]}") index=8;aWhiptailArray+=("$index" "Pi-hole: Stats for Pi-hole. Total Ads blocked etc." "${aWhip_OnOff_Status[$index]}") WHIP_TITLE='- Options : Scene Selection -' WHIP_QUESTION='Please use the spacebar to toggle which scenes are active.' whiptail --title "$WHIP_TITLE" --checklist "$WHIP_QUESTION" --backtitle "$WHIP_TITLE" --separate-output 16 75 9 "${aWhiptailArray[@]}" 2> "$FP_TEMP" CHOICE=$? #Delete[] array unset aWhiptailArray unset aWhip_OnOff_Status # - Reset all scenes to 0 if (( $CHOICE == 0 )); then for ((i=0; i<$MAX_SCENES; i++)) do aEnabledScenes[$i]=0 done fi # - Enable required scenes while read -r line do aEnabledScenes[$line]=1 done < "$FP_TEMP" } #TARGETMENUID=4 Menu_BlankScreenAtTime(){ #Return to main menu TARGETMENUID=0 #generate 24 hour array local aWhipHour=() for ((i=0; i<24; i++)) do aWhipHour+=("$i" "Hour") done local blank_screen_at_specific_time_enabled_text='Disabled' if (( $BLANK_SCREEN_AT_SPECIFIC_TIME_ENABLED )); then blank_screen_at_specific_time_enabled_text='Enabled' fi WHIP_TITLE='- Options : Auto screen off -' WHIP_QUESTION='Automatically power down the screen and disable DietPi-Cloudshell processing during a specific time.\n\nNB: This feature will only work if DietPi-Cloudshell was launched with the DietPi-Autostart option, or, launched from the main screen (tty1).' OPTION=$(whiptail --title "$WHIP_TITLE" --backtitle "$WHIP_BACKTITLE" --menu "$WHIP_QUESTION" --cancel-button "Back" --default-item "$REFRESH_RATE" 16 60 3 \ "Toggle" "$blank_screen_at_specific_time_enabled_text" \ "Start time" "Set which hour to power off screen ($BLANK_SCREEN_TIME_HOUR_START)." \ "End time" "Set which hour to power on screen ($BLANK_SCREEN_TIME_HOUR_END)." 3>&1 1>&2 2>&3) CHOICE=$? if (( $CHOICE == 0 )); then if [ "$OPTION" = "Toggle" ];then ((BLANK_SCREEN_AT_SPECIFIC_TIME_ENABLED++)) if (( $BLANK_SCREEN_AT_SPECIFIC_TIME_ENABLED > 1 )); then BLANK_SCREEN_AT_SPECIFIC_TIME_ENABLED=0 fi elif [ "$OPTION" = "Start time" ];then WHIP_QUESTION='Please select which hour (24h) you would like the screen to power off.' OPTION=$(whiptail --title "$WHIP_TITLE" --menu "$WHIP_QUESTION" --default-item "$BLANK_SCREEN_TIME_HOUR_START" --backtitle "$WHIP_BACKTITLE" 16 55 7 "${aWhipHour[@]}" 3>&1 1>&2 2>&3) CHOICE=$? if (( $CHOICE == 0 )); then BLANK_SCREEN_TIME_HOUR_START=$OPTION fi elif [ "$OPTION" = "End time" ];then WHIP_QUESTION='Please select which hour (24h) you would like the screen to power on.' OPTION=$(whiptail --title "$WHIP_TITLE" --menu "$WHIP_QUESTION" --default-item "$BLANK_SCREEN_TIME_HOUR_END" --backtitle "$WHIP_BACKTITLE" 16 55 7 "${aWhipHour[@]}" 3>&1 1>&2 2>&3) CHOICE=$? if (( $CHOICE == 0 )); then BLANK_SCREEN_TIME_HOUR_END=$OPTION fi fi TARGETMENUID=4 fi unset aWhipHour } #TARGETMENUID=5 Menu_Storage(){ #Return to main menu TARGETMENUID=0 local aWhiptailArray=() for ((i=1; i<$MAX_STORAGE; i++)) do #aWhiptailArray+=("Name $i" "${STORAGE_NAME[$i]}.") aWhiptailArray+=("$i" ": Drive $i | ${STORAGE_PATH[$i]}") done WHIP_TITLE='- Options : Storage Device Mount Location -' WHIP_QUESTION='DietPi-Cloudshell pulls the storage stats from the drive mount location. If you have custom drives/mounts, please set them here to be displayed during storage scene updates.\n\n - Drive 1 = Displayed during main storage scene\n - Drive 2/3 = Displayed during additional storage scene\n - Drive 4/5 = Displayed during additional storage scene' OPTION=$(whiptail --title "$WHIP_TITLE" --backtitle "$PROGRAM_NAME" --menu "$WHIP_QUESTION" --cancel-button "Back" 19 75 5 "${aWhiptailArray[@]}" 3>&1 1>&2 2>&3) CHOICE=$? unset aWhiptailArray if (( $CHOICE == 0 )); then local index=$OPTION /DietPi/dietpi/dietpi-drive_manager 1 local return_string="$(cat /tmp/dietpi-drive_manager_selmnt)" if [ -n "$return_string" ]; then STORAGE_PATH[$index]="$return_string" fi TARGETMENUID=5 fi } #///////////////////////////////////////////////////////////////////////////////////// # MAIN #///////////////////////////////////////////////////////////////////////////////////// #----------------------------------------------------------------------------------- #Init Init #----------------------------------------------------------------------------------- #Run menu if (( $INPUT == 0 )); then #Start Menu while (( $TARGETMENUID >= 0 )); do clear if (( $TARGETMENUID == 0 )); then Menu_Main elif (( $TARGETMENUID == 1 )); then Menu_Colour elif (( $TARGETMENUID == 2 )); then Menu_UpdateRate elif (( $TARGETMENUID == 3 )); then Menu_SceneSelection elif (( $TARGETMENUID == 4 )); then Menu_BlankScreenAtTime elif (( $TARGETMENUID == 5 )); then Menu_Storage fi done #----------------------------------------------------------------------------------- #Run DietPi-Cloudshell elif (( $INPUT >= 1 )); then Enable_Term_Options #Start Intro if (( $RUN_INTRO )); then Run_Intro fi #Set Nice to +10 (not critical) renice -n 10 $$ &> /dev/null #Start display updates while true do if (( $BLANK_SCREEN_AT_SPECIFIC_TIME_ENABLED )); then RUN_BLANK_SCREEN_AT_SPECIFIC_TIME fi #Disable updates when screen is blanked if (( $BLANK_SCREEN_ACTIVE )); then sleep 60 #Update enabled scenes else if (( ${aEnabledScenes[$SCENE_CURRENT]} )); then Update_Banner # - Input mode scene update (storage array) if (( $SCENE_CURRENT == 1 )); then Update_Scene_1 0 1 # - Input mode scene update (storage array) elif (( $SCENE_CURRENT == 2 )); then Update_Scene_1 2 3 # - Input mode scene update (storage array) elif (( $SCENE_CURRENT == 3 )); then Update_Scene_1 4 5 # - Normal scene update else Update_Scene_$SCENE_CURRENT fi #Apply refresh rate delay sleep $REFRESH_RATE fi #Scene Switcher ((SCENE_CURRENT++)) #Cap if (( $SCENE_CURRENT >= $MAX_SCENES )); then SCENE_CURRENT=0 fi fi done fi #----------------------------------------------------------------------------------- #Clean up temp files rm "$FP_TEMP" &> /dev/null #----------------------------------------------------------------------------------- #Delete[] Global arrays unset aCOLOUR unset aEnabledScenes Destroy_STORAGE #----------------------------------------------------------------------------------- exit #----------------------------------------------------------------------------------- }