#!/bin/bash

##########################################################
# Copyright (c) 2001-2026 Alexey Kuryakin daqgroup@mail.ru
##########################################################

##########################################################
# Utility to view hardware monitor temperature sensors.
##########################################################
# Temperature sensors information located in:
# /sys/class/hwmon/hwmon0/name        - mon0 source name
# /sys/class/hwmon/hwmon0/temp1_label - mon0 sensor1 label
# /sys/class/hwmon/hwmon0/temp1_input - mon0 sensor1 value
# Temperature values given in milli-Celcius (factor 1000).
##########################################################

################################
# Current script identification.
################################
readonly scriptfile="${BASH_SOURCE[0]}";
readonly scriptname="$(basename $scriptfile)";

function fatal(){
 1>&2 echo -ne "\n$2\n\n";
 exit $1;
};

function do_version(){
 echo "$scriptname version 1.0";
};

function do_print_help(){
 do_version;
cat<<EOF
$scriptname Copyright (c) 2026 Alexey Kuryakin daqgroup@mail.ru
Utility to view hardware monitor temperature sensors.
Usage:
 $scriptname [-options] [s1 s2 …]
Options:
 --version    - print version
 -h,--help    - print help screen
 -l,--list    - print list of hardware monitor sensors
 -s,--short   - print short (no names, only values)
 -r,--raw     - print raw values (not scaled)
 -0,--0       - format values as XX       ( integer )
 -1,--1       - format values as XX.X     ( default )
 -2,--2       - format values as XX.XX    ( 12.34   )
 -3,--3       - format values as XX.XXX   ( 12.345  )
Parameters:
 s1 s2 …      - name(s) of sensor(s)
Examples:
 $scriptname --help       # print help screen
 $scriptname --version    # print version
 $scriptname              # print sensor names & values
 $scriptname --list       # print sensor names  only
 $scriptname --short      # print sensor values only
 $scriptname -s -r        # print sensor raw values
 $scriptname amdgpu/edge  # print sensor by name
EOF
};

############################
# Program internal variables
############################
declare -i scale=1;        # precision for bc
declare -i optraw=0;       # option --raw
declare -i optshort=0;     # option --short
declare -i hwsensors=0;    # sensor counter
declare -a hwlabfile=();   # sensor label file
declare -a hwlabname=();   # sensor name/label array

#########################################
# List all hwmon temperature label files.
#########################################
function list_hwmon_label_files(){
 find /sys/class/hwmon/hwmon*/temp*_label | xargs;
};

#####################################
# Inialize hwmon temperature sensors:
# array name/label and label file(s).
#####################################
function init_hwmon(){
 if [[ $hwsensors -eq 0 ]]; then
  for fn in $(list_hwmon_label_files); do
   hwlabname+=("$(cat $(dirname $fn)/name)/$(cat $fn)");
   hwlabfile+=("$fn");
   let hwsensors++;
  done;
 fi;
};

##########################################
# Print list of known temperature sensors.
##########################################
function list_hwmon_sensors(){
 init_hwmon;
 for sen in "${hwlabname[@]}"; do
  echo "$sen";
 done;
};

#######################################
# Get raw temperature by label file $1.
#######################################
function getlabtemp(){
 if [[ -n $1 ]]; then
  local temp="$(cat ${1/label/input})";
  if [[ -n $temp ]]; then
   echo "$temp";
  fi;
 fi;
};

###################################
# Print list of sensor name: value.
# Sensor name/label passed in "$@".
###################################
function print_sensors(){
 init_hwmon;
 for sen in "$@"; do
  local -i ind=0; local -i suc=0;
  for sor in "${hwlabname[@]}"; do
   if [[ $sen = $sor ]]; then
    if [[ $suc -eq 0 ]]; then
     if [[ $optshort = 0 ]]; then
      printf "%-20s " "$sen:";
     fi;
     if [[ $optraw = 0 ]]; then
      local lab="${hwlabfile[$ind]}";
      echo "scale=$scale; $(getlabtemp $lab)/1000" | bc;
     else
      local lab="${hwlabfile[$ind]}";
      echo "$(getlabtemp $lab)";
     fi;
    fi;
    let suc++;
   fi;
   let ind++;
  done;
  if [[ $suc -eq 0 ]]; then
   if [[ $optshort = 0 ]]; then
    printf "%-20s " "$sen:";
   fi;
   local val="00000";
   if [[ $optraw = 0 ]]; then
    echo "scale=$scale; $val/1000" | bc;
   else
    echo "$val";
   fi;
  fi;
 done;
};

function main(){
 while [[ -n $1 ]]; do
  case $1 in
   --version)         do_version; return 0; ;;
   -h|-help|--help)   do_print_help; return 0; ;;
   -l|-list|--list)   list_hwmon_sensors; return 0; ;;
   -s|-short|--short) let optshort=1; ;;
   -r|-raw|--raw)     let optraw=1; ;;
   -0|--0)            let scale=0; ;;
   -1|--1)            let scale=1; ;;
   -2|--2)            let scale=2; ;;
   -3|--3)            let scale=3; ;;
   -*)                fatal 1 "Error: bad option $1"; ;;
   *)                 break; ;;
  esac;
  shift;
 done;
 init_hwmon;
 if [[ -n $1 ]]; then
  print_sensors "$@";
 else
  print_sensors "${hwlabname[@]}";
 fi;
};

main "$@";

##############
## END OF FILE
##############
