Add normalized temperature/power data for redfish
As has been done for IPMI, create hooks for popular sensor metrics that users want normalized across distinct models. This allows a client to request pertinent data without having to keep track of inconsistent sensor names across different systems. Change-Id: Idd1ac8222231f1a786a4f4af148e3fc3d1f6c89b
This commit is contained in:
parent
e2ba4f12fc
commit
3d4c5c7811
|
@ -74,10 +74,12 @@ class OEMHandler(object):
|
|||
except exc.IpmiException:
|
||||
continue
|
||||
tmplreading = reading
|
||||
readingvalues.append(reading.value)
|
||||
if reading.value is not None:
|
||||
readingvalues.append(float(reading.value))
|
||||
avgval = sum(readingvalues) / len(readingvalues)
|
||||
tmplreading.name = 'Average Processor Temperature'
|
||||
tmplreading.value = avgval
|
||||
tmplreading.unavailable = 0
|
||||
return tmplreading
|
||||
|
||||
|
||||
|
|
|
@ -142,6 +142,16 @@ class SensorReading(object):
|
|||
self.imprecision = None
|
||||
self.units = units
|
||||
self.unavailable = unavailable
|
||||
|
||||
def __repr__(self):
|
||||
return repr({
|
||||
'value': self.value,
|
||||
'state_ids': self.state_ids,
|
||||
'units': self.units,
|
||||
'imprecision': self.imprecision,
|
||||
'name': self.name,
|
||||
'unavailable': self.unavailable,
|
||||
})
|
||||
|
||||
|
||||
class Command(object):
|
||||
|
@ -509,6 +519,8 @@ class Command(object):
|
|||
def _do_web_request(self, url, payload=None, method=None, cache=True,
|
||||
etag=None):
|
||||
res = None
|
||||
if cache is True:
|
||||
cache = 30
|
||||
if cache and payload is None and method is None:
|
||||
res = self._get_cache(url, cache)
|
||||
if res:
|
||||
|
@ -652,6 +664,14 @@ class Command(object):
|
|||
for subchassis in chassisinfo.get('Links', {}).get('Contains', []):
|
||||
self._mapchassissensors(subchassis)
|
||||
|
||||
def _get_thermals(self, chassis):
|
||||
chassisurl = chassis['@odata.id']
|
||||
chassisinfo = self._do_web_request(chassisurl)
|
||||
thermurl = chassisinfo.get('Thermal', {}).get('@odata.id', '')
|
||||
if thermurl:
|
||||
therminf = self._do_web_request(thermurl, cache=1)
|
||||
return therminf.get('Temperatures', [])
|
||||
|
||||
@property
|
||||
def _bmcurl(self):
|
||||
if not self._varbmcurl:
|
||||
|
@ -1129,6 +1149,46 @@ class Command(object):
|
|||
log.get('Severity', 'Warning'), const.Health.Ok)
|
||||
yield record
|
||||
|
||||
def _get_chassis_env(self, chassis):
|
||||
chassisurl = chassis['@odata.id']
|
||||
chassisinfo = self._do_web_request(chassisurl)
|
||||
envurl = chassisinfo.get('EnvironmentMetrics', {}).get('@odata.id', '')
|
||||
envmetric = self._do_web_request(envurl, cache=1)
|
||||
retval = {
|
||||
'watts': envmetric.get('PowerWatts', {}).get('Reading', None),
|
||||
'inlet': envmetric.get('TemperatureCelsius', {}).get('Reading', None)
|
||||
}
|
||||
return retval
|
||||
|
||||
def get_average_processor_temperature(self):
|
||||
cputemps = []
|
||||
for chassis in self.sysinfo.get('Links', {}).get('Chassis', []):
|
||||
thermals = self._get_thermals(chassis)
|
||||
for temp in thermals:
|
||||
if temp.get('PhysicalContext', '') != 'CPU':
|
||||
continue
|
||||
if temp.get('ReadingCelsius', None) is None:
|
||||
continue
|
||||
cputemps.append(temp['ReadingCelsius'])
|
||||
avgtemp = sum(cputemps) / len(cputemps)
|
||||
return SensorReading(
|
||||
None, {'name': 'Average Processor Temperature'}, value=avgtemp, units='°C')
|
||||
|
||||
def get_system_power_watts(self):
|
||||
totalwatts = 0
|
||||
for chassis in self.sysinfo.get('Links', {}).get('Chassis', []):
|
||||
envinfo = self._get_chassis_env(chassis)
|
||||
totalwatts += envinfo['watts']
|
||||
return totalwatts
|
||||
|
||||
def get_inlet_temperature(self):
|
||||
inlets = []
|
||||
for chassis in self.sysinfo.get('Links', {}).get('Chassis', []):
|
||||
envinfo = self._get_chassis_env(chassis)
|
||||
inlets.append(envinfo['inlet'])
|
||||
val = sum(inlets) / len(inlets)
|
||||
return SensorReading(
|
||||
None, {'name': 'Inlet Temperature'}, value=val, units='°C')
|
||||
def get_sensor_descriptions(self):
|
||||
for sensor in natural_sort(self._sensormap):
|
||||
yield self._sensormap[sensor]
|
||||
|
|
Loading…
Reference in New Issue