ANN: Python script (for Windows) accessing motherboard sensory data

Claudio Grondi claudio.grondi at freenet.de
Fri Apr 8 19:59:20 EDT 2005


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





More information about the Python-list mailing list