| Lei YU | a03e55e | 2018-08-03 17:43:25 +0800 | [diff] [blame] | 1 | #!/usr/bin/env python3 | 
|  | 2 |  | 
|  | 3 | import yaml | 
|  | 4 | import argparse | 
|  | 5 |  | 
| Lei YU | d405165 | 2018-08-06 17:02:00 +0800 | [diff] [blame] | 6 | from typing import NamedTuple | 
|  | 7 |  | 
|  | 8 |  | 
|  | 9 | class 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 YU | 206f7c4 | 2018-08-07 15:12:19 +0800 | [diff] [blame] | 19 | sampleDimmTemp = { | 
|  | 20 | 'bExp': 0, | 
|  | 21 | 'entityID': 32, | 
|  | 22 | 'entityInstance': 2, | 
|  | 23 | 'interfaces': { | 
|  | 24 | 'xyz.openbmc_project.Sensor.Value': { | 
|  | 25 | 'Value': { | 
|  | 26 | 'Offsets': { | 
|  | 27 | 255: { | 
|  | 28 | 'type': 'int64_t' | 
|  | 29 | } | 
|  | 30 | } | 
|  | 31 | } | 
|  | 32 | } | 
|  | 33 | }, | 
|  | 34 | 'multiplierM': 1, | 
|  | 35 | 'mutability': 'Mutability::Write|Mutability::Read', | 
|  | 36 | 'offsetB': -127, | 
|  | 37 | 'path': '/xyz/openbmc_project/sensors/temperature/dimm0_temp', | 
|  | 38 | 'rExp': 0, | 
|  | 39 | 'readingType': 'readingData', | 
|  | 40 | 'scale': -3, | 
|  | 41 | 'sensorNamePattern': 'nameLeaf', | 
|  | 42 | 'sensorReadingType': 1, | 
|  | 43 | 'sensorType': 1, | 
|  | 44 | 'serviceInterface': 'org.freedesktop.DBus.Properties', | 
|  | 45 | 'unit': 'xyz.openbmc_project.Sensor.Value.Unit.DegreesC' | 
|  | 46 | } | 
|  | 47 | sampleCoreTemp = { | 
|  | 48 | 'bExp': 0, | 
|  | 49 | 'entityID': 208, | 
|  | 50 | 'entityInstance': 2, | 
|  | 51 | 'interfaces': { | 
|  | 52 | 'xyz.openbmc_project.Sensor.Value': { | 
|  | 53 | 'Value': { | 
|  | 54 | 'Offsets': { | 
|  | 55 | 255: { | 
|  | 56 | 'type': 'int64_t' | 
|  | 57 | } | 
|  | 58 | } | 
|  | 59 | } | 
|  | 60 | } | 
|  | 61 | }, | 
|  | 62 | 'multiplierM': 1, | 
|  | 63 | 'mutability': 'Mutability::Write|Mutability::Read', | 
|  | 64 | 'offsetB': -127, | 
|  | 65 | 'path': '/xyz/openbmc_project/sensors/temperature/p0_core0_temp', | 
|  | 66 | 'rExp': 0, | 
|  | 67 | 'readingType': 'readingData', | 
|  | 68 | 'scale': -3, | 
|  | 69 | 'sensorNamePattern': 'nameLeaf', | 
|  | 70 | 'sensorReadingType': 1, | 
|  | 71 | 'sensorType': 1, | 
|  | 72 | 'serviceInterface': 'org.freedesktop.DBus.Properties', | 
|  | 73 | 'unit': 'xyz.openbmc_project.Sensor.Value.Unit.DegreesC' | 
|  | 74 | } | 
|  | 75 |  | 
|  | 76 |  | 
| Lei YU | a03e55e | 2018-08-03 17:43:25 +0800 | [diff] [blame] | 77 | def openYaml(f): | 
|  | 78 | return yaml.load(open(f)) | 
|  | 79 |  | 
|  | 80 |  | 
| Lei YU | df0c417 | 2018-08-08 10:42:08 +0800 | [diff] [blame] | 81 | def saveYaml(y, f, safe=True): | 
|  | 82 | if safe: | 
|  | 83 | noaliasDumper = yaml.dumper.SafeDumper | 
|  | 84 | noaliasDumper.ignore_aliases = lambda self, data: True | 
|  | 85 | yaml.dump(y, open(f, "w"), default_flow_style=False, | 
|  | 86 | Dumper=noaliasDumper) | 
|  | 87 | else: | 
|  | 88 | yaml.dump(y, open(f, "w")) | 
| Lei YU | a03e55e | 2018-08-03 17:43:25 +0800 | [diff] [blame] | 89 |  | 
|  | 90 |  | 
| Lei YU | 9f39403 | 2018-08-08 11:25:21 +0800 | [diff] [blame^] | 91 | def getEntityIdAndNamePattern(p, intfs, m): | 
|  | 92 | key = (p, intfs) | 
|  | 93 | match = m.get(key, None) | 
|  | 94 | if match is None: | 
|  | 95 | raise Exception('Unable to find sensor', key, 'from map') | 
|  | 96 | return (m[key]['entityID'], m[key]['sensorNamePattern']) | 
| Lei YU | a03e55e | 2018-08-03 17:43:25 +0800 | [diff] [blame] | 97 |  | 
|  | 98 |  | 
|  | 99 | # Global entity instances | 
|  | 100 | entityInstances = {} | 
|  | 101 |  | 
|  | 102 |  | 
|  | 103 | def getEntityInstance(id): | 
|  | 104 | instanceId = entityInstances.get(id, 0) | 
|  | 105 | instanceId = instanceId + 1 | 
|  | 106 | entityInstances[id] = instanceId | 
|  | 107 | print("EntityId:", id, "InstanceId:", instanceId) | 
|  | 108 | return instanceId | 
|  | 109 |  | 
|  | 110 |  | 
| Lei YU | d405165 | 2018-08-06 17:02:00 +0800 | [diff] [blame] | 111 | def loadRpt(rptFile): | 
|  | 112 | sensors = [] | 
|  | 113 | with open(rptFile) as f: | 
|  | 114 | next(f) | 
|  | 115 | next(f) | 
|  | 116 | for line in f: | 
|  | 117 | fields = line.strip().split('|') | 
|  | 118 | fields = list(map(str.strip, fields)) | 
|  | 119 | sensor = RptSensor( | 
|  | 120 | fields[0], | 
|  | 121 | int(fields[2], 16) if fields[2] else None, | 
|  | 122 | int(fields[3], 16) if fields[3] else None, | 
|  | 123 | int(fields[4], 16) if fields[4] else None, | 
|  | 124 | int(fields[5], 16) if fields[5] else None, | 
|  | 125 | int(fields[7], 16) if fields[7] else None, | 
|  | 126 | fields[9]) | 
|  | 127 | # print(sensor) | 
|  | 128 | sensors.append(sensor) | 
|  | 129 | return sensors | 
|  | 130 |  | 
|  | 131 |  | 
| Lei YU | 206f7c4 | 2018-08-07 15:12:19 +0800 | [diff] [blame] | 132 | def getDimmTempPath(p): | 
|  | 133 | # Convert path like: /sys-0/node-0/motherboard-0/dimmconn-0/dimm-0 | 
|  | 134 | # to: /xyz/openbmc_project/sensors/temperature/dimm0_temp | 
|  | 135 | import re | 
|  | 136 | dimmconn = re.search(r'dimmconn-\d+', p).group() | 
|  | 137 | dimmId = re.search(r'\d+', dimmconn).group() | 
|  | 138 | return '/xyz/openbmc_project/sensors/temperature/dimm{}_temp'.format(dimmId) | 
|  | 139 |  | 
|  | 140 |  | 
|  | 141 | def getCoreTempPath(p): | 
|  | 142 | # Convert path like: /sys-0/node-0/motherboard-0/proc_socket-0/module-0/p9_proc_s/eq0/ex0/core0 | 
|  | 143 | # to: /xyz/openbmc_project/sensors/temperature/p0_core0_temp | 
|  | 144 | import re | 
|  | 145 | splitted = p.split('/') | 
|  | 146 | socket = re.search(r'\d+', splitted[4]).group() | 
|  | 147 | core = re.search(r'\d+', splitted[9]).group() | 
|  | 148 | return '/xyz/openbmc_project/sensors/temperature/p{}_core{}_temp'.format(socket, core) | 
|  | 149 |  | 
|  | 150 |  | 
|  | 151 | def getDimmTempConfig(s): | 
|  | 152 | r = sampleDimmTemp.copy() | 
|  | 153 | r['entityInstance'] = getEntityInstance(r['entityID']) | 
|  | 154 | r['path'] = getDimmTempPath(s.targetPath) | 
|  | 155 | return r | 
|  | 156 |  | 
|  | 157 |  | 
|  | 158 | def getCoreTempConfig(s): | 
|  | 159 | r = sampleCoreTemp.copy() | 
|  | 160 | r['entityInstance'] = getEntityInstance(r['entityID']) | 
|  | 161 | r['path'] = getCoreTempPath(s.targetPath) | 
|  | 162 | return r | 
|  | 163 |  | 
|  | 164 |  | 
| Lei YU | a03e55e | 2018-08-03 17:43:25 +0800 | [diff] [blame] | 165 | def main(): | 
|  | 166 | parser = argparse.ArgumentParser( | 
|  | 167 | description='Yaml tool for updating ipmi sensor yaml config') | 
|  | 168 | parser.add_argument('-i', '--input', required=True, dest='input', | 
|  | 169 | help='The ipmi sensor yaml config') | 
|  | 170 | parser.add_argument('-o', '--output', required=True, dest='output', | 
|  | 171 | help='The output yaml file') | 
| Lei YU | 9f39403 | 2018-08-08 11:25:21 +0800 | [diff] [blame^] | 172 | parser.add_argument('-m', '--map', dest='map', default='sensor_map.yaml', | 
|  | 173 | help='The sample map yaml file') | 
| Lei YU | a03e55e | 2018-08-03 17:43:25 +0800 | [diff] [blame] | 174 | parser.add_argument('-r', '--rpt', dest='rpt', | 
|  | 175 | help='The .rpt file generated by op-build') | 
| Lei YU | 9f39403 | 2018-08-08 11:25:21 +0800 | [diff] [blame^] | 176 | parser.add_argument('-f', '--fix', action='store_true', | 
|  | 177 | help='Fix entities and sensorNamePattern') | 
| Lei YU | df0c417 | 2018-08-08 10:42:08 +0800 | [diff] [blame] | 178 | parser.add_argument('-g', '--generate', action='store_true', | 
|  | 179 | help='Generate maps for entityID and sensorNamePattern') | 
| Lei YU | a03e55e | 2018-08-03 17:43:25 +0800 | [diff] [blame] | 180 |  | 
|  | 181 | args = parser.parse_args() | 
|  | 182 | args = vars(args) | 
|  | 183 |  | 
|  | 184 | if args['input'] is None or args['output'] is None: | 
|  | 185 | parser.print_help() | 
|  | 186 | exit(1) | 
|  | 187 |  | 
| Lei YU | a03e55e | 2018-08-03 17:43:25 +0800 | [diff] [blame] | 188 | y = openYaml(args['input']) | 
|  | 189 |  | 
| Lei YU | 9f39403 | 2018-08-08 11:25:21 +0800 | [diff] [blame^] | 190 | if args['fix']: | 
|  | 191 | # Fix entities and sensorNamePattern | 
|  | 192 | m = openYaml(args['map']) | 
|  | 193 |  | 
| Lei YU | a03e55e | 2018-08-03 17:43:25 +0800 | [diff] [blame] | 194 | for i in y: | 
|  | 195 | path = y[i]['path'] | 
| Lei YU | 9f39403 | 2018-08-08 11:25:21 +0800 | [diff] [blame^] | 196 | intfs = tuple(sorted(list(y[i]['interfaces'].keys()))) | 
|  | 197 | entityId, namePattern = getEntityIdAndNamePattern(path, intfs, m) | 
| Lei YU | a03e55e | 2018-08-03 17:43:25 +0800 | [diff] [blame] | 198 | y[i]['entityID'] = entityId | 
|  | 199 | y[i]['entityInstance'] = getEntityInstance(entityId) | 
| Lei YU | 9f39403 | 2018-08-08 11:25:21 +0800 | [diff] [blame^] | 200 | y[i]['sensorNamePattern'] = namePattern | 
| Lei YU | a03e55e | 2018-08-03 17:43:25 +0800 | [diff] [blame] | 201 | print(y[i]['path'], "id:", entityId, | 
|  | 202 | "instance:", y[i]['entityInstance']) | 
|  | 203 |  | 
| Lei YU | 206f7c4 | 2018-08-07 15:12:19 +0800 | [diff] [blame] | 204 | sensorIds = list(y.keys()) | 
|  | 205 | if args['rpt']: | 
|  | 206 | rptSensors = loadRpt(args['rpt']) | 
|  | 207 | for s in rptSensors: | 
|  | 208 | if s.sensorId is not None and s.sensorId not in sensorIds: | 
|  | 209 | print("Sensor ID", s.sensorId, "not in yaml:", | 
|  | 210 | s.name, ", path:", s.targetPath) | 
|  | 211 | if 'temp' in s.name.lower(): | 
|  | 212 | if 'dimm' in s.targetPath.lower(): | 
|  | 213 | y[s.sensorId] = getDimmTempConfig(s) | 
|  | 214 | print('Added sensor id:', s.sensorId, | 
|  | 215 | ', path:', y[s.sensorId]['path']) | 
|  | 216 | if 'core' in s.targetPath.lower(): | 
|  | 217 | y[s.sensorId] = getCoreTempConfig(s) | 
|  | 218 | print('Added sensor id:', s.sensorId, | 
|  | 219 | ', path:', y[s.sensorId]['path']) | 
|  | 220 |  | 
| Lei YU | df0c417 | 2018-08-08 10:42:08 +0800 | [diff] [blame] | 221 | if args['generate']: | 
|  | 222 | m = {} | 
|  | 223 | for i in y: | 
|  | 224 | path = y[i]['path'] | 
|  | 225 | intfs = tuple(sorted(list(y[i]['interfaces'].keys()))) | 
|  | 226 | entityId = y[i]['entityID'] | 
|  | 227 | sensorNamePattern = y[i]['sensorNamePattern'] | 
|  | 228 | m[(path, intfs)] = {'entityID': entityId, | 
|  | 229 | 'sensorNamePattern': sensorNamePattern} | 
|  | 230 | y = m | 
|  | 231 |  | 
|  | 232 | safe = False if args['generate'] else True | 
|  | 233 |  | 
|  | 234 | saveYaml(y, args['output'], safe) | 
| Lei YU | a03e55e | 2018-08-03 17:43:25 +0800 | [diff] [blame] | 235 |  | 
|  | 236 |  | 
|  | 237 | if __name__ == "__main__": | 
|  | 238 | main() |