#!/bin/bash
#
# Monitor System 
# Copyright Daniel Mehrmann (Akusari) 2020-2023
#

#
# configuration
#

# global
report="/tmp/report.$$"
disk_error="/tmp/disk_error.$$"
maxsize=1024768
headline="System monitor: WARNING"
use_dmesg="no"
pump_damage="/var/tmp/pump_damage.lock"

#
# init
#
/usr/bin/touch $report || { echo "Can't create temp file!" |systemd-cat -p err -t "$(basename "$0")"; exit 255; }

#
# Check for hidden FS
#
is_mounted() {
    /usr/bin/mount | awk -v DIR="$1" '{ if ($3 == DIR) { exit 0 } } ENDFILE{exit -1}'
}

#
# Alert bell
#

send_alert() {
   echo -e '\a' > /dev/console
   sleep 1
   echo -e '\a' > /dev/console
   sleep 1
   echo -e '\a' > /dev/console
   sleep 1
   echo -e '\a' > /dev/console
   sleep 1
   echo -e '\a' > /dev/console 
}

#
# disk usage
#

## TODO: Don't do this every 12 nminutes!
#if ! is_mounted "/backup"; then
#   mount /backup || exit 255
#fi
 
/usr/bin/df -Ph |grep -vE '^Filesystem|tmpfs' |awk '{ print $5,$1 }' |while read -r output; do

  # skip loop devices
  if echo "$output" | grep -iq "loop"; then
    echo "Skipping loop devices..."
    continue
  fi
 
  # skip cdrom devices
  if echo "$output" | grep -iq "sr[0-9]"; then
    echo "Skipping cdrom devices..."
    continue
  fi
 
  used=$(($(echo "$output" |awk '{ print $1 }' |sed s/%//g)))
  filesystem=$(echo "$output" |awk '{ print $2 }')
 
  if [ $used -ge 85 ]; then
     echo "Filesystem of \"$filesystem\" reached usage limit: $used%" >> $report
     echo "Details:" >> $report
     dusage=$(df -Ph |grep "$filesystem" |sed s/%//g |awk '{ print $0 }')
     echo "$dusage" >> $report
     printf '\n\n' >> $report

  fi
done

## TODO: Don't do this every 12 minutes
#if is_mounted "/backup"; then
#   umount /backup || exit 255
#fi

#
# disk errors
#

if [ "$use_dmesg" == "yes" ]; then
   /usr/bin/dmesg |grep -E 'ata[0-1].00: failed|ata[0-3].00: error|FAILED|Sense Key|Unrecovered|read error|sector' |grep -v multi |while read -r output; do
      echo "$output" >> $report
      echo "Found error" > $disk_error
   done
else
   echo "Running user friendly dmesg..."
   /usr/bin/journalctl --since=-12min --dmesg -o short-monotonic --no-hostname --no-pager |grep -E 'ata[0-1].00: failed|ata[0-3].00: error|FAILED|Sense Key|Unrecovered|read error|sector' |grep -v multi |while read -r output; do
      echo "$output" >> $report
      echo "Found error" > $disk_error
   done
fi

if [ -f $disk_error ]; then
   if [ "$use_dmesg" == "yes" ]; then 
      /usr/bin/dmesg --clear
   fi 
   printf '\n\n' >> $report
   echo "Harddrive error(s) found!" |systemd-cat -p warning -t "$(basename "$0")"
fi
    
#
# memory
#

used=$(free -m | awk 'NR==2 { printf "%.0f%%\t\t", $3*100/$2 }')
# shellcheck disable=SC2001
used_int=$(($(echo "$used" | sed s/%//g)))

if [ $used_int -ge 95 ]; then
   echo "Memory usage is very high: $used" >> $report
   echo "Memory usage is very high: $used" |systemd-cat -p warning -t "$(basename "$0")"
fi

#
# sensors
#

if [ -f /usr/bin/sensors ]; then
   /usr/bin/sensors | while read -r output; do
      line=$(echo "$output" |awk '{ print $1,$2 }')
      
      case $line in

      "Front Fan:")
      rpm=$(($(echo "$output" |awk '{ print $3 }')))
      if [ $rpm -lt 500 ]; then
         echo "Front fan reached threshold: Current: $rpm Threshold: 500" >> $report 
         echo "Front fan reached threshold: Current: $rpm Threshold: 500" |systemd-cat -p warning -t "$(basename "$0")" 
      fi
      ;;

      "R280 Top")
      # shellcheck disable=SC2046
      if [ $(echo "$output" |grep -c "power") -eq 0 ]; then
         rpm=$(($(echo "$output" |awk '{ print $4 }'))) 
         if [ $rpm -lt 300 ]; then
            echo "Fan of Top radiator reached threshold: Current: $rpm Threshold: 300" >> $report
            echo "Fan of Top radiator reached threshold: Current: $rpm Threshold: 300" |systemd-cat -p warning -t "$(basename "$0")"  
         fi
      fi 
      ;;

      "R120 Backend")
      # shellcheck disable=SC2046
      if [ $(echo "$output" |grep -c "power") -eq 0 ]; then
         rpm=$(($(echo "$output" |awk '{ print $4 }')))
         if [ $rpm -lt 300 ]; then
            echo "Fan of Backend radiator reached threshold: Current: $rpm Threshold: 300" >> $report
            echo "Fan of Backend radiator reached threshold: Current: $rpm Threshold: 300" |systemd-cat -p warning -t "$(basename "$0")" 
         fi
      fi
      ;; 

      "Water Pump:")
      rpm=$(($(echo "$output" |awk '{ print $3 }')))
      if [ $rpm -lt 2000 ]; then
         echo "Water pump reached threshold: Current: $rpm Threshold: 2000" >> $report
         send_alert
         echo "Waterpump seems buggy!" |systemd-cat -p emerg -t "$(basename "$0")"
         if [ -f "$pump_damage" ]; then
            echo "Shutting down system..." |systemd-cat -p emerg -t "$(basename "$0")"
            /usr/bin/sudo poweroff
         else
            touch "$pump_damage" || echo "Can't create lockfile" |systemd-cat -p warning -t "$(basename "$0")"
         fi
      fi
      ;;

      "Water Temp:")
      celcius=$(($(echo "$output" |awk -F '+' '{ print substr($2,1,2) }')))
      if [ $celcius -gt 39 ]; then
         echo "Water tempature reached threshold: Current: $celcius Threshold: >= 40" >> $report
         send_alert
         echo "Water tempature reached maximum threshold!" |systemd-cat -p warning -t "$(basename "$0")"
      fi
      ;;
 
      *)
      continue
      ;;

      esac
   done
else 
   echo "No sensors tool detected!" |systemd-cat -p warning -t "$(basename "$0")"
fi

#
# Send report
#

# Check file size
filesize=$(stat -c%s "${report}")

# Check content
if ((filesize == 0)); then
   rm $report
   rm $disk_error 2>/dev/null
   echo "$(basename "$0") found nothing :-)" |systemd-cat -p info -t "$(basename "$0")" 
   exit 0
fi

# create mail
if ((filesize > maxsize)); then 
  gzip -c $report > ${report}.gz && echo "See attachment for details" |mail -Ssendwait -s "$(hostname) ${headline}" -a ${report}.gz root@localhost
  rm ${report}.gz
else
  cat $report | mail -Ssendwait -s "$(hostname) ${headline}" root@localhost
fi

rm $report
rm $disk_error 2>/dev/null

echo "$(basename "$0") finished." |systemd-cat -p info -t "$(basename "$0")"

exit 0
