FreeBSD provides modules for reading motherboard temperatures on late model Intel (Core Duo) and AMD CPUs. The modules can be found in /boot/kernel as coretemp.ko and amdtemp.ko respectfully. Use kdload to install the appropriate module and sysctl to access the temperature values.
$> kldload coretemp # amdtemp
$> sysctl -a | grep -i temperature
For my motherboard I need to go a little more old school and use mbmon (MotherBoard Monitor). pfSense does not include the mbmon package by default so we need to install it. Unfortunately I got the following error when I tried installing mbmon:
$> pkg_add -r mbmon
Error: Unable to get ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-8.1-release/Latest/mbmon.tbz: File unavailable (e.g., file not found, no access)
pkg_add: unable to fetch 'ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-8.1-release/Latest/mbmon.tbz' by URL
Looks like 8.1-release is no longer maintained on the main FreeBSD package site. A little quick reading and I found the answer in the pfSense documentation.
$> pkg_add -r ftp://ftp-archive.freebsd.org/pub/FreeBSD-Archive/ports/i386/packages-8.1-release/Latest/mbmon.tbz
$> rehash
$> mbmon
ioctl(smb0:open): No such file or directory
No Hardware Monitor found!!
InitMBInfo: Bad file descriptor
The "No Hardware Monitor found!!!" indicates that I don't have some needed modules loaded for it to be able to read the hardware. I found the modules in /boot/kernel and loaded them.
$> kldload ichsmb
$> kldload smbus
$> kldstat
Id Refs Address Size Name
1 8 0xc0400000 117c18c kernel
3 2 0xc5350000 2000 smbus.ko
5 1 0xc5355000 3000 smb.ko
6 1 0xc535e000 4000 ichsmb.ko
$> mbmon -r -c1
Temp.= 21.0, 26.2, 22.5; Rot.= 0, 1380, 0
Vcore = 1.50, 1.48; Volt. = 3.36, 5.15, 12.07, 0.00, 0.00
Success!
To get the modules to load automatically on boot add the following to /boot/loader.conf.local. Using loader.conf.local will allow the changes to persist after a pfSense update.
ichsmb_load="YES"
smb_load="YES"
Searching through pfSense php files I noticed that the framework for handling temperature is already there, we just need to provide the implementation.
Open /usr/local/www/includes/functions.inc.php, search for the function has_temp() and modify it to return true.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function has_temp() { | |
return true; | |
} |
Replace the contents of get_temp() with:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function get_temp() { | |
exec("/usr/local/bin/mbmon -c1 -T1", $dfout); | |
return trim($dfout[0]); | |
} |
Now save the file and go to the pfSense dashboard in your browser
![]() |
System Information widget w/ Temperature |
Not too shabby, but with a few modifications, we can show all the temperature values returned from mbmon.
Modify the get_temp() function to be
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function get_temp() { | |
exec("/usr/local/bin/mbmon -r -c1 | /usr/bin/grep TEMP | /usr/bin/awk '{ print $3 }'", $temps); | |
return $temps; | |
} |
Then edit /usr/local/www/widgets/widgets/system_information.widget.php and search for where has_temp() is called. The code snippet will look similar to the following depending on your pfSense version:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
if(has_temp()): | |
?> | |
<tr> | |
<td width='25%' class='vncellt'>Temperature</td> | |
<td width='75%' class='listr'> | |
<?php $temp = get_temp(); ?> | |
<img src="./themes/<?= $g["theme"]; ?>/images/misc/bar_left.gif" height="15" width="4" border="0" align="middle" alt="left bar" /><img src="./themes/<?= $g["theme"]; ?>/images/misc/bar_blue.gif" height="15" name="tempwidtha" id="tempwidtha" width="<?= $temp; ?>" border="0" align="middle" alt="red bar" /><img src="./themes/<?= $g["theme"]; ?>/images/misc/bar_gray.gif" height="15" name="tempwidthb" id="tempwidthb" width="<?= (100 - $temp); ?>" border="0" align="middle" alt="gray bar" /><img src="./themes/<?= $g["theme"]; ?>/images/misc/bar_right.gif" height="15" width="5" border="0" align="middle" alt="right bar" /> | |
| |
<input style="border: 0px solid white;" size="30" name="tempmeter" id="tempmeter" value="<?= $temp."C"; ?>" /> | |
</td> | |
</tr> | |
<?php endif; ?> |
Change it to be
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
if(has_temp()): | |
$temps = get_temp(); | |
foreach ($temps as &$temp) { | |
?> | |
<tr> | |
<td width='25%' class='vncellt'>Temperature</td> | |
<td width='75%' class='listr'> | |
<img src="./themes/<?= $g["theme"]; ?>/images/misc/bar_left.gif" height="15" width="4" border="0" align="middle" alt="left bar" /><img src="./themes/<?= $g["theme"]; ?>/images/misc/bar_blue.gif" height="15" name="tempwidtha" id="tempwidtha" width="<?= $temp; ?>" border="0" align="middle" alt="red bar" /><img src="./themes/<?= $g["theme"]; ?>/images/misc/bar_gray.gif" height="15" name="tempwidthb" id="tempwidthb" width="<?= (100 - $temp); ?>" border="0" align="middle" alt="gray bar" /><img src="./themes/<?= $g["theme"]; ?>/images/misc/bar_right.gif" height="15" width="5" border="0" align="middle" alt="right bar" /> | |
| |
<input style="border: 0px solid white;" size="30" name="tempmeter" id="tempmeter" value="<?= $temp."C"; ?>" /> | |
</td> | |
</tr> | |
<?php | |
} | |
endif; | |
?> |
I simply added a foreach to loop through the returned temperature array.
![]() |
System Information widget w/ multiple Temperatures |
Enjoy!
nice article.. thanks for taking time to post this. i was able to use amdtemp, and version 2.1 just required returning true for 'has_temp'.
ReplyDeleteThanks for that tip!
ReplyDeletepfsense 2.2.* has "Thermal Sensors" widget. You can use it for display temperature information from mbmon with minimal change. You must change in file /usr/local/www/widgets/include/thermal_sensors.inc function for this:
function getThermalSensorsData() {
//$_gb = exec("/sbin/sysctl -a | grep temperature", $dfout);
$_gb = exec("/usr/local/bin/mbmon -r -c1 | grep TEMP", $dfout);
$thermalSensorsData = join("|", $dfout);
return $thermalSensorsData;
}
...and after that standard "Thermal Sensors" widget will show you temperature values from mbmon.