blob: 38f45bd57dcac26b43a2e0df8036c2feaf5e94e3 [file] [log] [blame]
#!/usr/bin/env python3
import yaml
import argparse
from typing import NamedTuple
class RptSensor(NamedTuple):
name: str
entityId: int
typeId: int
evtType: int
sensorId: int
fru: int
targetPath: str
entityIds = {
'dimm': 32,
'core': 208,
'cpu': 3,
'occ': 210,
'gpu': 216,
'gpu_mem': 217,
'tpm': 3,
'state/host0': 33, # Different interfaces using different entity ID
# and this requires extra fix.
# {'state/host0', 34},
# {'state/host0', 35},
'turbo': 3,
'fan': 29,
'vdd_temp': 218,
'power': 10,
'voltage': 10,
'current': 10,
'temperature/pcie': 35,
'temperature/ambient': 64,
'control/volatile': 33,
}
extraIds = {
'RebootPolicy': 33,
'Progress': 34,
'RebootAttempts': 34,
'OperatingSystem.Status': 35
}
sampleDimmTemp = {
'bExp': 0,
'entityID': 32,
'entityInstance': 2,
'interfaces': {
'xyz.openbmc_project.Sensor.Value': {
'Value': {
'Offsets': {
255: {
'type': 'int64_t'
}
}
}
}
},
'multiplierM': 1,
'mutability': 'Mutability::Write|Mutability::Read',
'offsetB': -127,
'path': '/xyz/openbmc_project/sensors/temperature/dimm0_temp',
'rExp': 0,
'readingType': 'readingData',
'scale': -3,
'sensorNamePattern': 'nameLeaf',
'sensorReadingType': 1,
'sensorType': 1,
'serviceInterface': 'org.freedesktop.DBus.Properties',
'unit': 'xyz.openbmc_project.Sensor.Value.Unit.DegreesC'
}
sampleCoreTemp = {
'bExp': 0,
'entityID': 208,
'entityInstance': 2,
'interfaces': {
'xyz.openbmc_project.Sensor.Value': {
'Value': {
'Offsets': {
255: {
'type': 'int64_t'
}
}
}
}
},
'multiplierM': 1,
'mutability': 'Mutability::Write|Mutability::Read',
'offsetB': -127,
'path': '/xyz/openbmc_project/sensors/temperature/p0_core0_temp',
'rExp': 0,
'readingType': 'readingData',
'scale': -3,
'sensorNamePattern': 'nameLeaf',
'sensorReadingType': 1,
'sensorType': 1,
'serviceInterface': 'org.freedesktop.DBus.Properties',
'unit': 'xyz.openbmc_project.Sensor.Value.Unit.DegreesC'
}
def openYaml(f):
return yaml.load(open(f))
def saveYaml(y, f):
noaliasDumper = yaml.dumper.SafeDumper
noaliasDumper.ignore_aliases = lambda self, data: True
yaml.dump(y, open(f, "w"), default_flow_style=False, Dumper=noaliasDumper)
def getEntityId(p, i):
for k, v in entityIds.items():
if k in p:
if k == 'state/host0':
# get id from extraIds
for ek, ev in extraIds.items():
if ek in i:
return ev
raise Exception("Unable to find entity id:", p, i)
else:
return v
raise Exception('Unable to find entity id:', p)
# Global entity instances
entityInstances = {}
def getEntityInstance(id):
instanceId = entityInstances.get(id, 0)
instanceId = instanceId + 1
entityInstances[id] = instanceId
print("EntityId:", id, "InstanceId:", instanceId)
return instanceId
def loadRpt(rptFile):
sensors = []
with open(rptFile) as f:
next(f)
next(f)
for line in f:
fields = line.strip().split('|')
fields = list(map(str.strip, fields))
sensor = RptSensor(
fields[0],
int(fields[2], 16) if fields[2] else None,
int(fields[3], 16) if fields[3] else None,
int(fields[4], 16) if fields[4] else None,
int(fields[5], 16) if fields[5] else None,
int(fields[7], 16) if fields[7] else None,
fields[9])
# print(sensor)
sensors.append(sensor)
return sensors
def getDimmTempPath(p):
# Convert path like: /sys-0/node-0/motherboard-0/dimmconn-0/dimm-0
# to: /xyz/openbmc_project/sensors/temperature/dimm0_temp
import re
dimmconn = re.search(r'dimmconn-\d+', p).group()
dimmId = re.search(r'\d+', dimmconn).group()
return '/xyz/openbmc_project/sensors/temperature/dimm{}_temp'.format(dimmId)
def getCoreTempPath(p):
# Convert path like: /sys-0/node-0/motherboard-0/proc_socket-0/module-0/p9_proc_s/eq0/ex0/core0
# to: /xyz/openbmc_project/sensors/temperature/p0_core0_temp
import re
splitted = p.split('/')
socket = re.search(r'\d+', splitted[4]).group()
core = re.search(r'\d+', splitted[9]).group()
return '/xyz/openbmc_project/sensors/temperature/p{}_core{}_temp'.format(socket, core)
def getDimmTempConfig(s):
r = sampleDimmTemp.copy()
r['entityInstance'] = getEntityInstance(r['entityID'])
r['path'] = getDimmTempPath(s.targetPath)
return r
def getCoreTempConfig(s):
r = sampleCoreTemp.copy()
r['entityInstance'] = getEntityInstance(r['entityID'])
r['path'] = getCoreTempPath(s.targetPath)
return r
def main():
parser = argparse.ArgumentParser(
description='Yaml tool for updating ipmi sensor yaml config')
parser.add_argument('-i', '--input', required=True, dest='input',
help='The ipmi sensor yaml config')
parser.add_argument('-o', '--output', required=True, dest='output',
help='The output yaml file')
parser.add_argument('-r', '--rpt', dest='rpt',
help='The .rpt file generated by op-build')
parser.add_argument('-e', '--entity', action='store_true',
help='Fix entities')
args = parser.parse_args()
args = vars(args)
if args['input'] is None or args['output'] is None:
parser.print_help()
exit(1)
y = openYaml(args['input'])
if args['entity']:
# Fix entities
for i in y:
path = y[i]['path']
intf = list(y[i]['interfaces'].keys())[0]
entityId = getEntityId(path, intf)
y[i]['entityID'] = entityId
y[i]['entityInstance'] = getEntityInstance(entityId)
print(y[i]['path'], "id:", entityId,
"instance:", y[i]['entityInstance'])
sensorIds = list(y.keys())
if args['rpt']:
rptSensors = loadRpt(args['rpt'])
for s in rptSensors:
if s.sensorId is not None and s.sensorId not in sensorIds:
print("Sensor ID", s.sensorId, "not in yaml:",
s.name, ", path:", s.targetPath)
if 'temp' in s.name.lower():
if 'dimm' in s.targetPath.lower():
y[s.sensorId] = getDimmTempConfig(s)
print('Added sensor id:', s.sensorId,
', path:', y[s.sensorId]['path'])
if 'core' in s.targetPath.lower():
y[s.sensorId] = getCoreTempConfig(s)
print('Added sensor id:', s.sensorId,
', path:', y[s.sensorId]['path'])
saveYaml(y, args['output'])
if __name__ == "__main__":
main()