-
-
Save stefaang/0a23a25460f65086cbec0db526e87b03 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# | |
# Post-init script for FreeNAS on Western Digital PR2100/PR4100 | |
# wdhws v1.0 by TFL | |
# | |
# BSD 3 LICENSE | |
# | |
# thanks unix stackexchange question 231975 | |
setup_tty() { | |
tty=/dev/cuau3 | |
exec 4<$tty 5>$tty | |
} | |
setup_i2c() { | |
# load kernel modules required for the temperature sensor on the RAM modules | |
kldload -n iicbus smbus smb ichsmb | |
} | |
send() { | |
setup_tty | |
# send a command to the PMC module and echo the answer | |
echo -ne "$1\r" >&5 | |
read ans <&4 | |
if [ "$ans" = "ALERT" ]; then | |
echo -ne ALERT >&2 | |
exit 2 | |
else | |
# keep this for debugging failing commands | |
if [ "$ans" = "ERR" ] || [ -z "$ans" ]; then | |
echo "CMD $1 gives ERR at $2" >&2 | |
send_empty | |
ans=$(send "$1" $(($2 + 1))) | |
#exit 1 | |
fi | |
fi | |
# only echo the result for retries ($2 not empty) | |
if [ ! -z $2 ]; then | |
echo "CMD $1 gives '$ans' at $2" >&2 | |
fi | |
echo $ans | |
send_empty | |
# deconstruct tty file pointers, otherwise this script breaks on sleep | |
exec 4<&- 5>&- | |
} | |
send_empty() { | |
# send a empty command to clear the output | |
echo -ne "\r" >&5 | |
read ignore <&4 | |
} | |
get_ncpu() { | |
# get the number of CPUs | |
sysctl -n hw.ncpu | |
} | |
get_coretemp() { | |
# get the CPU temperature and strip of the Celsius | |
sysctl -n dev.cpu.$1.temperature | cut -d'.' -f1 | |
} | |
get_disktemp() { | |
# get the disk $i temperature only if it is spinning | |
smartctl -n standby -A /dev/ada$1 | grep Temperature_Celsius | awk '{print $NF}' | |
} | |
get_ramtemp() { | |
# get the memory temperature from the I2C sensor | |
smbmsg -s 0x98 -c 0x0$1 -i 1 -F %d | |
} | |
get_pmc() { | |
# get a value from the PMC | |
# e.g. TMP returns TMP=25 --> 25 | |
send $1 | cut -d'=' -f2 | |
} | |
init() { | |
setup_tty | |
setup_i2c | |
echo "get system status and firmware" | |
send VER | |
send CFG | |
send STA | |
show_welcome | |
stop_powerled | |
} | |
show_welcome() { | |
# set welcome message | |
# maximum "xxx xxx xxx xxx " | |
send "LN1= FreeNAS " | |
send "LN2= go go go go go " | |
} | |
stop_powerled() { | |
# stop blinking power LED | |
send PLS=00 | |
send LED=00 # set to 01 to enable it | |
send BLK=00 | |
} | |
show_ip() { | |
send "LN1=Interface re$1" | |
ip=$(ifconfig re$1 | grep inet | awk '{printf $2}') | |
send "LN2=$ip" | |
} | |
monitor() { | |
lvl="COOL" | |
# check RPM (fan may get stuck) and convert hex to dec | |
fan=$(get_pmc FAN) | |
rpm=$((0x$(get_pmc RPM))) | |
echo "Got rpm $rpm" | |
if [ "$rpm" != ERR ]; then | |
if [ "$rpm" -lt 400 ]; then | |
echo "WARNING: low RPM - $rpm - clean dust!" | |
fi | |
fi | |
# check pmc | |
tmp=$((0x$(get_pmc TMP))) | |
if [ "$tmp" -gt 64 ]; then | |
lvl="HOT" | |
fi | |
# check disks [adjust this for PR2100!!] | |
for i in 0 1 2 3 ; do | |
tmp=$(get_disktemp $i) | |
echo "disk $i is $tmp" | |
if [ ! -z $tmp ] && [ "$tmp" -gt 40 ]; then | |
echo "Disk $i temperature is $tmp" | |
lvl="HOT" | |
fi | |
done | |
# check cpu | |
for i in $(seq $(get_ncpu)); do | |
tmp=$(get_coretemp $((i-1))) | |
echo "cpu $i is $tmp" | |
if [ "$tmp" -gt 50 ]; then | |
echo "CPU $i temperature is $tmp" | |
lvl="HOT" | |
fi | |
done | |
# check ram | |
for i in 0 1; do | |
tmp=$(get_ramtemp $i) | |
echo "ram temp is $tmp for $i" | |
if [ "$tmp" -gt 40 ]; then | |
echo "RAM $i temperature is $tmp" | |
lvl="HOT" | |
fi | |
done | |
echo "Temperature LVL is $lvl" | |
if [ "$lvl" == HOT ] ; then | |
if [ "$fan" != 40 ]; then | |
send FAN=40 | |
fi | |
else | |
if [ "$fan" != 20 ]; then | |
send FAN=20 | |
fi | |
fi | |
} | |
check_btn_pressed() { | |
btn=$(get_pmc ISR) | |
#echo "Btn is .$btn." | |
case $btn in | |
20*) | |
echo "Button up pressed!" | |
menu=$(( ($menu + 1) % 3 )) | |
;; | |
40*) | |
echo "Button down pressed!" | |
menu=$(( ($menu + 2) % 3 )) | |
;; | |
*) | |
return | |
esac | |
case "$menu" in | |
0) | |
show_welcome | |
;; | |
1) | |
show_ip 0 | |
;; | |
2) | |
show_ip 1 | |
;; | |
# if you add menu items here, update mod 3 uses above | |
esac | |
} | |
# initial setup | |
init | |
while true; do | |
# adjust fan speed every 30 seconds | |
monitor | |
# check for button presses | |
for i in $(seq 30); do | |
sleep 1 | |
check_btn_pressed | |
done | |
done |
hello stefaang
Can you elaborate? Or is there a guide? Sorry, I don't have experience in this area.
Hi, Stefaang!
Thank you very much for script, it does a great job!
Something changed in smartctl command, and get_disktemp gives something like 24/55 (it is minimum and maximum lifetime temperature)
I changed script line 65 a little and it worked well by now:
smartctl -n standby -A /dev/ada$1 | grep Temperature_Celsius | cut -d'/' -f37 | awk '{print $NF}'
I don't have a bash scripting experience at all, please correct if needed.
edit:corrected by forum post
use for dsm 6.1.7
I think you'll need another tty port, but yes.
Can anyone explain how to do this? I am running dsm7.1 on a pr4100, and would love to use this script.... please help
Can anyone explain how to do this? I am running dsm7.1 on a pr4100, and would love to use this script.... please help
You should find tty, which used by pr4100 screen, and correct script in row 11.
How to find correct tty (or at least limiting the results)
https://stackoverflow.com/questions/2530096/how-to-find-all-serial-devices-ttys-ttyusb-on-linux-without-opening-them
Can anyone explain how to do this? I am running dsm7.1 on a pr4100, and would love to use this script.... please help
You should find tty, which used by pr4100 screen, and correct script in row 11. How to find correct tty (or at least limiting the results) https://stackoverflow.com/questions/2530096/how-to-find-all-serial-devices-ttys-ttyusb-on-linux-without-opening-them
root@PR4100:/# ll /sys/class/tty/*/device/driver
lrwxrwxrwx 1 root root 0 Apr 19 03:57 /sys/class/tty/ttyS0/device/driver -> ../../../bus/platform/drivers/serial8250
lrwxrwxrwx 1 root root 0 Apr 19 03:57 /sys/class/tty/ttyS1/device/driver -> ../../../bus/platform/drivers/serial8250
lrwxrwxrwx 1 root root 0 Apr 19 03:57 /sys/class/tty/ttyS2/device/driver -> ../../../bus/pci/drivers/serial
lrwxrwxrwx 1 root root 0 Apr 19 03:57 /sys/class/tty/ttyS3/device/driver -> ../../../bus/pci/drivers/serial
How do I know which one is talking to the screen?
Hey stefan! Thank you for your post on the forum and this script!
Running TrueNAS-13.0-U4, I had to change line 65 to
smartctl -n standby -A /dev/ada$1 | grep Temperature_Celsius | awk '{print $NF-1}'
In order to get the correct value for disk temperature
Hey Everyone, have any of you moved to Scale from Core? If so, how did you handle hardware as this script appears to no longer work.
FYI for anyone looking for the Scale answer, Scale is now Debian Linux instead of FreeBSD. TrueNAS Core is FreeBSD. In any event, I had to change the tty from tty=/dev/cuau3 to tty=/dev/ttyS2. That appears to the correct setting for Linux on the PR4100.
The value needs hex2decimal conversion.
Sorry for the late reply, I didn't get a notification of the warning.