I was recently looking into creating a small fan controller script and needed to get reliable access to the current CPU temperature. After a bit of research I came up with the following code that takes advantage of data published (via shared memory) by the popular SpeedFan program..
from ctypes import *
import mmap
class SFMemory(Structure):
_pack_ = 1
_fields_ = [
('version', c_short),
('flags', c_short),
('MemSize', c_int),
('handle', c_int),
('NumTemps', c_short),
('NumFans', c_short),
('NumVolts', c_short),
('temps', c_int*32),
('fans', c_int*32),
('volts', c_int*32),
]
# Open the shared memory area that contains the SpeedFan data..
size = sizeof(SFMemory)
buf = mmap.mmap(0, size, "SFSharedMemory_ALM", mmap.ACCESS_READ)
# Read the memory area and cast to our custom ctypes struct..
buf.seek(0)
mem = buf.read(size)
sfm = cast(mem, POINTER(SFMemory)).contents
# Check the header details..
print "Version: %u Flags: %u, MemSize: %u, Handle: 0x%08X" % (sfm.version, sfm.flags, sfm.MemSize, sfm.handle)
assert(sfm.version == 1)
assert(sfm.MemSize == size)
# Process the data into a friendly form..
temps = map(lambda t: t / 100.0, sfm.temps[:sfm.NumTemps])
fans = map(lambda t: t, sfm.fans[:sfm.NumFans])
volts = map(lambda t: t / 100.0, sfm.volts[:sfm.NumVolts])
# Print out the values..
print "Temps: " + str(temps)
print "Fans: " + str(fans)
print "Volts: " + str(volts)
One obvious issue here is that SpeedFan doesn't tell us which values are associated with which bits of hardware so you'll likely have to customise anything you do with this to the current machine.
Anyway, feel free to use this for whatever you like.Read more...