mirror of
https://opendev.org/x/pyghmi
synced 2026-03-29 14:23:32 +00:00
Merge "Handle non-linear and unrecognized linearizations"
This commit is contained in:
@@ -243,10 +243,11 @@ class SDREntry(object):
|
||||
external code to pay attention to this class.
|
||||
"""
|
||||
|
||||
def __init__(self, entrybytes, reportunsupported=False):
|
||||
def __init__(self, entrybytes, ipmicmd, reportunsupported=False):
|
||||
# ignore record id for now, we only care about the sensor number for
|
||||
# moment
|
||||
self.reportunsupported = reportunsupported
|
||||
self.ipmicmd = ipmicmd
|
||||
if entrybytes[2] != 0x51:
|
||||
# only recognize '1.5', the only version defined at time of writing
|
||||
raise NotImplementedError
|
||||
@@ -364,7 +365,7 @@ class SDREntry(object):
|
||||
# factors on the fly.
|
||||
# the formula could apply if we bother with nominal
|
||||
# reading interpretation
|
||||
self.decode_formula(entry)
|
||||
self.decode_formula(entry[19:25])
|
||||
|
||||
def _decode_state(self, state):
|
||||
mapping = ipmiconst.discrete_type_offsets
|
||||
@@ -451,55 +452,67 @@ class SDREntry(object):
|
||||
output['states'].append(upper + " non-recoverable threshold")
|
||||
return SensorReading(output, self.unit_suffix)
|
||||
|
||||
def _set_tmp_formula(self, value):
|
||||
rsp = self.ipmicmd.raw_command(netfn=4, command=0x23,
|
||||
data=(self.sensor_number, value))
|
||||
# skip next reading field, not used in on-demand situation
|
||||
self.decode_formula(rsp['data'][1:])
|
||||
|
||||
def decode_value(self, value):
|
||||
# Take the input value and return meaningful value
|
||||
if self.linearization == 0x70: # direct calling code to get factors
|
||||
#TODO(jbjohnso): implement get sensor reading factors support for
|
||||
#non linear sensor
|
||||
raise NotImplementedError("Need to do get sensor reading factors")
|
||||
linearization = self.linearization
|
||||
if linearization > 11: # direct calling code to get factors
|
||||
# for now, we will get the factors on demand
|
||||
# the facility is engineered such that at construction
|
||||
# time the entire BMC table should be fetchable in a reasonable
|
||||
# fashion. However for now opt for retrieving rows as needed
|
||||
# rather than tracking all that information for a relatively
|
||||
# rare behavior
|
||||
self._set_tmp_formula(value)
|
||||
linearization = 0
|
||||
# time to compute the pre-linearization value.
|
||||
decoded = float((value * self.m + self.b) *
|
||||
(10 ** self.resultexponent))
|
||||
if self.linearization == 0:
|
||||
if linearization == 0:
|
||||
return decoded
|
||||
elif self.linearization == 1:
|
||||
elif linearization == 1:
|
||||
return math.log(decoded)
|
||||
elif self.linearization == 2:
|
||||
elif linearization == 2:
|
||||
return math.log(decoded, 10)
|
||||
elif self.linearization == 3:
|
||||
elif linearization == 3:
|
||||
return math.log(decoded, 2)
|
||||
elif self.linearization == 4:
|
||||
elif linearization == 4:
|
||||
return math.exp(decoded)
|
||||
elif self.linearization == 5:
|
||||
elif linearization == 5:
|
||||
return 10 ** decoded
|
||||
elif self.linearization == 6:
|
||||
elif linearization == 6:
|
||||
return 2 ** decoded
|
||||
elif self.linearization == 7:
|
||||
elif linearization == 7:
|
||||
return 1 / decoded
|
||||
elif self.linearization == 8:
|
||||
elif linearization == 8:
|
||||
return decoded ** 2
|
||||
elif self.linearization == 9:
|
||||
elif linearization == 9:
|
||||
return decoded ** 3
|
||||
elif self.linearization == 10:
|
||||
elif linearization == 10:
|
||||
return math.sqrt(decoded)
|
||||
elif self.linearization == 11:
|
||||
elif linearization == 11:
|
||||
return decoded ** (1.0/3)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
def decode_formula(self, entry):
|
||||
self.m = \
|
||||
twos_complement(entry[19] + ((entry[20] & 0b11000000) << 2), 10)
|
||||
self.tolerance = entry[20] & 0b111111
|
||||
twos_complement(entry[0] + ((entry[1] & 0b11000000) << 2), 10)
|
||||
self.tolerance = entry[1] & 0b111111
|
||||
self.b = \
|
||||
twos_complement(entry[21] + ((entry[22] & 0b11000000) << 2), 10)
|
||||
self.accuracy = (entry[22] & 0b111111) + \
|
||||
(entry[23] & 0b11110000) << 2
|
||||
self.accuracyexp = (entry[23] & 0b1100) >> 2
|
||||
self.direction = entry[23] & 0b11
|
||||
twos_complement(entry[2] + ((entry[3] & 0b11000000) << 2), 10)
|
||||
self.accuracy = (entry[3] & 0b111111) + \
|
||||
(entry[4] & 0b11110000) << 2
|
||||
self.accuracyexp = (entry[4] & 0b1100) >> 2
|
||||
self.direction = entry[4] & 0b11
|
||||
#0 = n/a, 1 = input, 2 = output
|
||||
self.resultexponent = twos_complement((entry[24] & 0b11110000) >> 4, 4)
|
||||
bexponent = twos_complement(entry[24] & 0b1111, 4)
|
||||
self.resultexponent = twos_complement((entry[5] & 0b11110000) >> 4, 4)
|
||||
bexponent = twos_complement(entry[5] & 0b1111, 4)
|
||||
# might as well do the math to 'b' now rather than wait for later
|
||||
self.b = self.b * (10**bexponent)
|
||||
|
||||
@@ -651,7 +664,7 @@ class SDR(object):
|
||||
return self.sensors.iterkeys()
|
||||
|
||||
def add_sdr(self, sdrbytes):
|
||||
newent = SDREntry(sdrbytes)
|
||||
newent = SDREntry(sdrbytes, self.ipmicmd)
|
||||
if newent.sdrtype == TYPE_SENSOR:
|
||||
id = newent.sensor_number
|
||||
if id in self.sensors:
|
||||
|
||||
Reference in New Issue
Block a user