diff options
Diffstat (limited to 'pyipmi/sel.py')
-rw-r--r-- | pyipmi/sel.py | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/pyipmi/sel.py b/pyipmi/sel.py new file mode 100644 index 0000000..0a6fa5b --- /dev/null +++ b/pyipmi/sel.py @@ -0,0 +1,171 @@ +# Copyright (c) 2012, Calxeda Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of Calxeda Inc. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. + + +from datetime import datetime +import re + +from pyipmi import IpmiError + +TIME_FORMAT = '%m/%d/%Y %H:%M:%S' + +class SEL(object): + """A class to represent a SEL""" + + def __init__(self, bmc): + self.bmc = bmc + self._info = self.bmc.sel_info() + self._alloc_info = self.bmc.sel_alloc_info() + + @property + def entries(self): + return self.bmc.sel_info().entries + + @property + def size(self): + return self._alloc_info.num_alloc_units + + @property + def size_bytes(self): + return self.size * self._alloc_info.alloc_unit_size + + +class SELRecord(object): + """A class to represent a SEL event record""" + + def __init__(self, record_id=0, record_type=2, timestamp='', + generator_id=0, evm_rev=4, sensor_type=0, + sensor_number=0, event_type=0, event_direction=0, + event_data=(0, 0, 0)): + self.record_id = record_id + self.record_type = record_type + self.timestamp = timestamp + self.generator_id = generator_id + self.evm_rev = evm_rev + self.sensor_type = sensor_type + self.sensor_number = sensor_number + self.event_type = event_type + self.event_direction = event_direction + self.event_data = event_data + + def __eq__(self, other): + return (self.record_type == other.record_type and + self.generator_id == other.generator_id and + self.evm_rev == other.evm_rev and + self.sensor_type == other.sensor_type and + self.sensor_number == other.sensor_number and + self.event_type == other.event_type and + self.event_direction == other.event_direction and + self.event_data == other.event_data) + + sensor_types = {'Reserved': 0} + event_types = {'Unspecified': 0} + + def normalize(self): + #TODO: replace this with something better + try: + int(self.sensor_type) + except ValueError: + self.sensor_type = self.sensor_types[self.sensor_type] + + try: + int(self.event_type) + except ValueError: + self.event_type = self.event_types[self.event_type] + + +class OEMSELRecord(object): + """A class to represent an OEM SEL record type C0h-DFh""" + + +class TimestampedOEMSELRecord(OEMSELRecord): + """A class to represent an OEM SEL record type E0h-FFh""" + + +class SELTimestamp(object): + """A class to represent a Timestamp""" + + parser = re.compile('%s/%s/%s %s:%s:%s' % ( + '(?P<mon>\d{2})', '(?P<day>\d{2})', '(?P<year>\d{4})', + '(?P<hour>\d{2})', '(?P<min>\d{2})', '(?P<sec>\d{2})')) + default_time = parser.match('01/01/1970 00:00:00') + + def __init__(self, timestamp=''): + match = self.parser.match(timestamp) + if match is None: + match = self.default_time + + mdict = dict((k, int(v)) for k, v in match.groupdict().iteritems()) + self.time = datetime(mdict['year'], mdict['mon'], mdict['day'], + mdict['hour'], mdict['min'], mdict['sec']) + + @property + def timestamp(self): + return repr(self) + + def __repr__(self): + return self.time.strftime(TIME_FORMAT) + + def __str__(self): + return str(self.time) + + def __eq__(self, other): + return self.time == other.time + + def __ne__(self, other): + return self.time != other.time + + def __lt__(self, other): + return self.time < other.time + + def __le__(self, other): + return self.time <= other.time + + def __gt__(self, other): + return self.time > other.time + + def __ge__(self, other): + return self.time >= other.time + + +class SELInfo(object): + """A class to represent SEL info""" + + +class SELAllocInfo(object): + """A class to represent SEL allocation info""" + + +class SELOverflowError(IpmiError): + """An error that is thrown when the SEL is full""" + + +class SELTimestampError(IpmiError): + """An error thrown with invalid timestamps""" |