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:
Jarrod Johnson 2023-10-26 08:24:56 -04:00
parent e2ba4f12fc
commit 3d4c5c7811
2 changed files with 63 additions and 1 deletions

View File

@ -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

View File

@ -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]