blob: f68e13261b47389f40408f7825859db697ca9afb [file] [log] [blame]
Lei YUa03e55e2018-08-03 17:43:25 +08001#!/usr/bin/env python3
2
3import yaml
4import argparse
5
Lei YUd4051652018-08-06 17:02:00 +08006from typing import NamedTuple
7
8
9class RptSensor(NamedTuple):
10 name: str
11 entityId: int
12 typeId: int
13 evtType: int
14 sensorId: int
15 fru: int
16 targetPath: str
17
18
Lei YUa03e55e2018-08-03 17:43:25 +080019entityIds = {
20 'dimm': 32,
21 'core': 208,
22 'cpu': 3,
Lei YU206f7c42018-08-07 15:12:19 +080023 'occ': 210,
Lei YUa03e55e2018-08-03 17:43:25 +080024 'gpu': 216,
25 'gpu_mem': 217,
26 'tpm': 3,
27 'state/host0': 33, # Different interfaces using different entity ID
28 # and this requires extra fix.
29 # {'state/host0', 34},
30 # {'state/host0', 35},
31 'turbo': 3,
32 'fan': 29,
33 'vdd_temp': 218,
34 'power': 10,
35 'voltage': 10,
36 'current': 10,
37 'temperature/pcie': 35,
38 'temperature/ambient': 64,
Lei YUa03e55e2018-08-03 17:43:25 +080039 'control/volatile': 33,
40}
41
42extraIds = {
43 'RebootPolicy': 33,
44 'Progress': 34,
45 'RebootAttempts': 34,
46 'OperatingSystem.Status': 35
47}
48
49
Lei YU206f7c42018-08-07 15:12:19 +080050sampleDimmTemp = {
51 'bExp': 0,
52 'entityID': 32,
53 'entityInstance': 2,
54 'interfaces': {
55 'xyz.openbmc_project.Sensor.Value': {
56 'Value': {
57 'Offsets': {
58 255: {
59 'type': 'int64_t'
60 }
61 }
62 }
63 }
64 },
65 'multiplierM': 1,
66 'mutability': 'Mutability::Write|Mutability::Read',
67 'offsetB': -127,
68 'path': '/xyz/openbmc_project/sensors/temperature/dimm0_temp',
69 'rExp': 0,
70 'readingType': 'readingData',
71 'scale': -3,
72 'sensorNamePattern': 'nameLeaf',
73 'sensorReadingType': 1,
74 'sensorType': 1,
75 'serviceInterface': 'org.freedesktop.DBus.Properties',
76 'unit': 'xyz.openbmc_project.Sensor.Value.Unit.DegreesC'
77}
78sampleCoreTemp = {
79 'bExp': 0,
80 'entityID': 208,
81 'entityInstance': 2,
82 'interfaces': {
83 'xyz.openbmc_project.Sensor.Value': {
84 'Value': {
85 'Offsets': {
86 255: {
87 'type': 'int64_t'
88 }
89 }
90 }
91 }
92 },
93 'multiplierM': 1,
94 'mutability': 'Mutability::Write|Mutability::Read',
95 'offsetB': -127,
96 'path': '/xyz/openbmc_project/sensors/temperature/p0_core0_temp',
97 'rExp': 0,
98 'readingType': 'readingData',
99 'scale': -3,
100 'sensorNamePattern': 'nameLeaf',
101 'sensorReadingType': 1,
102 'sensorType': 1,
103 'serviceInterface': 'org.freedesktop.DBus.Properties',
104 'unit': 'xyz.openbmc_project.Sensor.Value.Unit.DegreesC'
105}
106
107
Lei YUa03e55e2018-08-03 17:43:25 +0800108def openYaml(f):
109 return yaml.load(open(f))
110
111
Lei YUdf0c4172018-08-08 10:42:08 +0800112def saveYaml(y, f, safe=True):
113 if safe:
114 noaliasDumper = yaml.dumper.SafeDumper
115 noaliasDumper.ignore_aliases = lambda self, data: True
116 yaml.dump(y, open(f, "w"), default_flow_style=False,
117 Dumper=noaliasDumper)
118 else:
119 yaml.dump(y, open(f, "w"))
Lei YUa03e55e2018-08-03 17:43:25 +0800120
121
122def getEntityId(p, i):
123 for k, v in entityIds.items():
124 if k in p:
125 if k == 'state/host0':
126 # get id from extraIds
127 for ek, ev in extraIds.items():
128 if ek in i:
129 return ev
130 raise Exception("Unable to find entity id:", p, i)
131 else:
132 return v
133 raise Exception('Unable to find entity id:', p)
134
135
136# Global entity instances
137entityInstances = {}
138
139
140def getEntityInstance(id):
141 instanceId = entityInstances.get(id, 0)
142 instanceId = instanceId + 1
143 entityInstances[id] = instanceId
144 print("EntityId:", id, "InstanceId:", instanceId)
145 return instanceId
146
147
Lei YUd4051652018-08-06 17:02:00 +0800148def loadRpt(rptFile):
149 sensors = []
150 with open(rptFile) as f:
151 next(f)
152 next(f)
153 for line in f:
154 fields = line.strip().split('|')
155 fields = list(map(str.strip, fields))
156 sensor = RptSensor(
157 fields[0],
158 int(fields[2], 16) if fields[2] else None,
159 int(fields[3], 16) if fields[3] else None,
160 int(fields[4], 16) if fields[4] else None,
161 int(fields[5], 16) if fields[5] else None,
162 int(fields[7], 16) if fields[7] else None,
163 fields[9])
164 # print(sensor)
165 sensors.append(sensor)
166 return sensors
167
168
Lei YU206f7c42018-08-07 15:12:19 +0800169def getDimmTempPath(p):
170 # Convert path like: /sys-0/node-0/motherboard-0/dimmconn-0/dimm-0
171 # to: /xyz/openbmc_project/sensors/temperature/dimm0_temp
172 import re
173 dimmconn = re.search(r'dimmconn-\d+', p).group()
174 dimmId = re.search(r'\d+', dimmconn).group()
175 return '/xyz/openbmc_project/sensors/temperature/dimm{}_temp'.format(dimmId)
176
177
178def getCoreTempPath(p):
179 # Convert path like: /sys-0/node-0/motherboard-0/proc_socket-0/module-0/p9_proc_s/eq0/ex0/core0
180 # to: /xyz/openbmc_project/sensors/temperature/p0_core0_temp
181 import re
182 splitted = p.split('/')
183 socket = re.search(r'\d+', splitted[4]).group()
184 core = re.search(r'\d+', splitted[9]).group()
185 return '/xyz/openbmc_project/sensors/temperature/p{}_core{}_temp'.format(socket, core)
186
187
188def getDimmTempConfig(s):
189 r = sampleDimmTemp.copy()
190 r['entityInstance'] = getEntityInstance(r['entityID'])
191 r['path'] = getDimmTempPath(s.targetPath)
192 return r
193
194
195def getCoreTempConfig(s):
196 r = sampleCoreTemp.copy()
197 r['entityInstance'] = getEntityInstance(r['entityID'])
198 r['path'] = getCoreTempPath(s.targetPath)
199 return r
200
201
Lei YUa03e55e2018-08-03 17:43:25 +0800202def main():
203 parser = argparse.ArgumentParser(
204 description='Yaml tool for updating ipmi sensor yaml config')
205 parser.add_argument('-i', '--input', required=True, dest='input',
206 help='The ipmi sensor yaml config')
207 parser.add_argument('-o', '--output', required=True, dest='output',
208 help='The output yaml file')
209 parser.add_argument('-r', '--rpt', dest='rpt',
210 help='The .rpt file generated by op-build')
211 parser.add_argument('-e', '--entity', action='store_true',
212 help='Fix entities')
Lei YUdf0c4172018-08-08 10:42:08 +0800213 parser.add_argument('-g', '--generate', action='store_true',
214 help='Generate maps for entityID and sensorNamePattern')
Lei YUa03e55e2018-08-03 17:43:25 +0800215
216 args = parser.parse_args()
217 args = vars(args)
218
219 if args['input'] is None or args['output'] is None:
220 parser.print_help()
221 exit(1)
222
Lei YUa03e55e2018-08-03 17:43:25 +0800223 y = openYaml(args['input'])
224
Lei YUa03e55e2018-08-03 17:43:25 +0800225 if args['entity']:
226 # Fix entities
227 for i in y:
228 path = y[i]['path']
229 intf = list(y[i]['interfaces'].keys())[0]
230 entityId = getEntityId(path, intf)
231 y[i]['entityID'] = entityId
232 y[i]['entityInstance'] = getEntityInstance(entityId)
233 print(y[i]['path'], "id:", entityId,
234 "instance:", y[i]['entityInstance'])
235
Lei YU206f7c42018-08-07 15:12:19 +0800236 sensorIds = list(y.keys())
237 if args['rpt']:
238 rptSensors = loadRpt(args['rpt'])
239 for s in rptSensors:
240 if s.sensorId is not None and s.sensorId not in sensorIds:
241 print("Sensor ID", s.sensorId, "not in yaml:",
242 s.name, ", path:", s.targetPath)
243 if 'temp' in s.name.lower():
244 if 'dimm' in s.targetPath.lower():
245 y[s.sensorId] = getDimmTempConfig(s)
246 print('Added sensor id:', s.sensorId,
247 ', path:', y[s.sensorId]['path'])
248 if 'core' in s.targetPath.lower():
249 y[s.sensorId] = getCoreTempConfig(s)
250 print('Added sensor id:', s.sensorId,
251 ', path:', y[s.sensorId]['path'])
252
Lei YUdf0c4172018-08-08 10:42:08 +0800253 if args['generate']:
254 m = {}
255 for i in y:
256 path = y[i]['path']
257 intfs = tuple(sorted(list(y[i]['interfaces'].keys())))
258 entityId = y[i]['entityID']
259 sensorNamePattern = y[i]['sensorNamePattern']
260 m[(path, intfs)] = {'entityID': entityId,
261 'sensorNamePattern': sensorNamePattern}
262 y = m
263
264 safe = False if args['generate'] else True
265
266 saveYaml(y, args['output'], safe)
Lei YUa03e55e2018-08-03 17:43:25 +0800267
268
269if __name__ == "__main__":
270 main()