Supervising motherboard sensory data as fan speeds or CPU and board temperatures in Python can be done with help of the MBM 5 utility available at http://mbm.livewiredev.com/.
This utility exposes data got from the hardware sensors in a shared memory area for querying by another applications. The pyMBM.py script provided below prints excerpts of the content of the by MBM 5 in shared memory area provided data and can be used as a starting point for writing own scripts which need to query motherboard sensory data or as inspiration for creating an appropriate pyMBM Python module. Claudio Grondi print print ' pyMBM.py ver. 0.10 2005-04-08 ' print '*** ************************************************ ***' print '*** THIS code accesses shared memory area exposed by ***' print '*** MBM 5 (MotherBoard Monitor) ***' print '*** install and run MBM 5 before using this script ***' print '*** MBM 5 home: http://mbm.livewiredev.com ***' print '*** Port of the MBM API to Python by Claudio Grondi ***' print '*** http://www.python.org/moin/ClaudioGrondi ***' print '*** ************************************************ ***' # centralized settings for portability and upgradability SENSOR_INDEX_LENGTH = 10 SENSOR_INFO_LENGTH = 100 SENSOR_NAME_LEN = 12 TIME_STRING_LENGTH = 41 MBM_PATHNAME_LENGTH = 256 SMBUSNAME_STRING_LENGTH = 41 PADDING1_SIZE_BYTES = 3 PADDING2_SIZE_BYTES = 4 PADDING3_SIZE_BYTES = 8 #define BT_ISA "type_isa" #define BT_SMBUS "type_smbus" #define BT_VIA686ABUS "type_via686abus" #define BT_DIRECTIO "type_directio" #define BT_UNKNOWN "type_unknown" # typedef enum { btISA = 0, btSMBus, btVIA686ABus, btDirectIO } bus_t; bus_t = [ "ISA " # 0 ,"SMBus " # 1 ,"Via686aBus" # 2 ,"DirectIO " # 3 ] #define SMBT_INTEL "type_intel" #define SMBT_AMD "type_amd" #define SMBT_ALI "type_ali" #define SMBT_NFORCE "type_nforce" #define SMBT_SIS "type_sis" #define SMBT_UNK BT_UNKNOWN # typedef enum { smtSMBIntel = 0, smtSMBAMD, smtSMBALi, smtSMBNForce, smtSMBSIS } smb_t; smb_t = [ "Intel " # 0 ,"AMD " # 1 ,"Ali " # 2 ,"nForce" # 3 ,"sis " # 4 ] #define ST_UNKNOWN BT_UNKNOWN #define ST_TEMPERATURE "type_temperature" #define ST_VOLTAGE "type_voltage" #define ST_FAN "type_fan" #define ST_MHZ "type_mhz" #define ST_PERCENTAGE "type_percentage" # typedef enum { stUnknown = 0, stTemperature, stVoltage, stFan, stMhz, stPercentage } sensor_t; sensor_t = [ "unknown " # 0 ,"temperature" # 1 ,"voltage " # 2 ,"fan " # 3 ,"mhz " # 4 ,"percentage " # 5 ] from ctypes import * class index(Structure): _fields_ = [ ("_type" , c_int ) # type of sensor ,("_count" , c_int ) # number of sensor for that type ] class sensor(Structure): _fields_ = [ ("_type" , c_ubyte ) # type of sensor ,("_name" , c_ubyte * SENSOR_NAME_LEN ) # name of sensor ,("_padding1", c_ubyte * PADDING1_SIZE_BYTES ) # padding of 3 byte ,("_current" , c_double ) # current value ,("_low" , c_double ) # lowest readout ,("_high" , c_double ) # highest readout ,("_readout" , c_long ) # total number of readout ,("_padding2", c_ubyte * PADDING2_SIZE_BYTES ) # padding of 4 byte ,("_total" , c_double ) # actual a long double - total amout of all readouts ,("_padding3", c_ubyte * PADDING3_SIZE_BYTES ) # padding of 6 byte ,("_alarm1" , c_double ) # temp & fan: low alarm; voltage: % off; ,("_alarm2" , c_double ) # temp: high alarm ] class info(Structure): _fields_ = [ ("_smbBase" , c_short ) # SMBus base address ,("_smbType" , c_ubyte ) # bus_t variant of SMBus/Isa bus used to access chip # typedef enum {btISA=0,btSMBus,btVIA686ABus,btDirectIO} bus_t; ,("_smbCode" , c_ubyte ) # smb_t variant of SMBus sub type, Intel, AMD or ALi # typedef enum {smtSMBIntel=0,smtSMBAMD,smtSMBALi,smtSMBNForce,smtSMBSIS} smb_t; ,("_smbAddr" , c_ubyte ) # Address of sensor chip on SMBus ,("_smbName" , c_ubyte * SMBUSNAME_STRING_LENGTH ) # Nice name for SMBus ,("_isaBase" , c_short ) # ISA base address of sensor chip on ISA ,("_chipType" , c_int ) # Chip nr, connects with Chipinfo.ini ,("_voltageSubType", c_ubyte ) # Subvoltage option selected ] class data_t(Structure): _fields_ = [ ("_version", c_double ) # version number (example: 51090) ,("_index" , index * SENSOR_INDEX_LENGTH ) # Sensor index ,("_sensor" , sensor * SENSOR_INFO_LENGTH ) # sensor info ,("_info" , info ) # misc. info ,("_start" , c_ubyte * TIME_STRING_LENGTH ) # start time, TIME_STRING_LENGTH = 41 ,("_current", c_ubyte * TIME_STRING_LENGTH ) # current time ,("_path" , c_ubyte * MBM_PATHNAME_LENGTH ) # MBM path ] FILE_MAP_READ = 2 strNameOfSharedMemoryAreaToAccess = "$M$B$M$5$S$D$" handle = windll.kernel32.OpenFileMappingA(FILE_MAP_READ, 0, strNameOfSharedMemoryAreaToAccess) if not handle: raise WinError() addr = windll.kernel32.MapViewOfFile( handle ,FILE_MAP_READ ,0 ,0 ,0 ) if not addr: raise WinError() obj_data_t = data_t.from_address(addr) # obj_data_t holds the entire shared memory area content which can be accessed # now from within Python code like it is done below: if(__name__ == '__main__'): print print '_version ', obj_data_t._version print # print '_index ', obj_data_t._index itemCounter = 0 for item in obj_data_t._index: itemCounter += 1 print '_index[%2i]._type ='%itemCounter, sensor_t[item._type], '_index._count =',repr(item._count) print # print '_sensor ', obj_data_t._sensor itemCounter = 0 for item in obj_data_t._sensor: itemCounter += 1 print '_sensor[%3i]._type ='%itemCounter, sensor_t[item._type], strSensorName = '' for subitem in item._name: strSensorName += chr(subitem) print ' ._name =', strSensorName, print ' ._current = %7.2f'%item._current, ' ._low = %7.2f'%item._low, ' ._high = %7.2f'%item._high print # print '_info ', obj_data_t._info print '_info._smbType =', bus_t[obj_data_t._info._smbType] print '_info._smbCode =', smb_t[obj_data_t._info._smbCode] print print '_start ', strStart = '' for char in obj_data_t._start: strStart += chr(char) print strStart print '_current ', strCurrent = '' for char in obj_data_t._current: strCurrent += chr(char) print strCurrent, print print '_path ', strPath = '' for char in obj_data_t._path: strPath += chr(char) print strPath, windll.kernel32.UnmapViewOfFile(addr) windll.kernel32.CloseHandle(handle) print raw_input(' (exit with ENTER) #> OK? ') #:if -- http://mail.python.org/mailman/listinfo/python-list