1cf3c1e67SAndrew Jeffery#!/usr/bin/env python3
2cf3c1e67SAndrew Jeffery
3cf3c1e67SAndrew Jefferyimport argparse
4cf3c1e67SAndrew Jefferyfrom typing import NamedTuple
5cf3c1e67SAndrew Jeffery
6*a3db66b3SPatrick Williamsimport yaml
7*a3db66b3SPatrick Williams
8cf3c1e67SAndrew Jeffery
9cf3c1e67SAndrew Jefferyclass RptSensor(NamedTuple):
10cf3c1e67SAndrew Jeffery    name: str
11cf3c1e67SAndrew Jeffery    entityId: int
12cf3c1e67SAndrew Jeffery    typeId: int
13cf3c1e67SAndrew Jeffery    evtType: int
14cf3c1e67SAndrew Jeffery    sensorId: int
15cf3c1e67SAndrew Jeffery    fru: int
16cf3c1e67SAndrew Jeffery    targetPath: str
17cf3c1e67SAndrew Jeffery
18cf3c1e67SAndrew Jeffery
19cf3c1e67SAndrew JefferysampleDimmTemp = {
20*a3db66b3SPatrick Williams    "bExp": 0,
21*a3db66b3SPatrick Williams    "entityID": 32,
22*a3db66b3SPatrick Williams    "entityInstance": 2,
23*a3db66b3SPatrick Williams    "interfaces": {
24*a3db66b3SPatrick Williams        "xyz.openbmc_project.Sensor.Value": {
25*a3db66b3SPatrick Williams            "Value": {"Offsets": {255: {"type": "int64_t"}}}
26cf3c1e67SAndrew Jeffery        }
27cf3c1e67SAndrew Jeffery    },
28*a3db66b3SPatrick Williams    "multiplierM": 1,
29*a3db66b3SPatrick Williams    "mutability": "Mutability::Write|Mutability::Read",
30*a3db66b3SPatrick Williams    "offsetB": -127,
31*a3db66b3SPatrick Williams    "path": "/xyz/openbmc_project/sensors/temperature/dimm0_temp",
32*a3db66b3SPatrick Williams    "rExp": 0,
33*a3db66b3SPatrick Williams    "readingType": "readingData",
34*a3db66b3SPatrick Williams    "scale": -3,
35*a3db66b3SPatrick Williams    "sensorNamePattern": "nameLeaf",
36*a3db66b3SPatrick Williams    "sensorReadingType": 1,
37*a3db66b3SPatrick Williams    "sensorType": 1,
38*a3db66b3SPatrick Williams    "serviceInterface": "org.freedesktop.DBus.Properties",
39*a3db66b3SPatrick Williams    "unit": "xyz.openbmc_project.Sensor.Value.Unit.DegreesC",
40cf3c1e67SAndrew Jeffery}
41cf3c1e67SAndrew JefferysampleCoreTemp = {
42*a3db66b3SPatrick Williams    "bExp": 0,
43*a3db66b3SPatrick Williams    "entityID": 208,
44*a3db66b3SPatrick Williams    "entityInstance": 2,
45*a3db66b3SPatrick Williams    "interfaces": {
46*a3db66b3SPatrick Williams        "xyz.openbmc_project.Sensor.Value": {
47*a3db66b3SPatrick Williams            "Value": {"Offsets": {255: {"type": "int64_t"}}}
48cf3c1e67SAndrew Jeffery        }
49cf3c1e67SAndrew Jeffery    },
50*a3db66b3SPatrick Williams    "multiplierM": 1,
51*a3db66b3SPatrick Williams    "mutability": "Mutability::Write|Mutability::Read",
52*a3db66b3SPatrick Williams    "offsetB": -127,
53*a3db66b3SPatrick Williams    "path": "/xyz/openbmc_project/sensors/temperature/p0_core0_temp",
54*a3db66b3SPatrick Williams    "rExp": 0,
55*a3db66b3SPatrick Williams    "readingType": "readingData",
56*a3db66b3SPatrick Williams    "scale": -3,
57*a3db66b3SPatrick Williams    "sensorNamePattern": "nameLeaf",
58*a3db66b3SPatrick Williams    "sensorReadingType": 1,
59*a3db66b3SPatrick Williams    "sensorType": 1,
60*a3db66b3SPatrick Williams    "serviceInterface": "org.freedesktop.DBus.Properties",
61*a3db66b3SPatrick Williams    "unit": "xyz.openbmc_project.Sensor.Value.Unit.DegreesC",
62cf3c1e67SAndrew Jeffery}
63cf3c1e67SAndrew JefferysamplePower = {
64*a3db66b3SPatrick Williams    "bExp": 0,
65*a3db66b3SPatrick Williams    "entityID": 10,
66*a3db66b3SPatrick Williams    "entityInstance": 13,
67*a3db66b3SPatrick Williams    "interfaces": {
68*a3db66b3SPatrick Williams        "xyz.openbmc_project.Sensor.Value": {
69*a3db66b3SPatrick Williams            "Value": {"Offsets": {255: {"type": "int64_t"}}}
70cf3c1e67SAndrew Jeffery        }
71cf3c1e67SAndrew Jeffery    },
72*a3db66b3SPatrick Williams    "multiplierM": 2,
73*a3db66b3SPatrick Williams    "offsetB": 0,
74*a3db66b3SPatrick Williams    "path": "/xyz/openbmc_project/sensors/power/p0_power",
75*a3db66b3SPatrick Williams    "rExp": 0,
76*a3db66b3SPatrick Williams    "readingType": "readingData",
77*a3db66b3SPatrick Williams    "scale": -6,
78*a3db66b3SPatrick Williams    "sensorNamePattern": "nameLeaf",
79*a3db66b3SPatrick Williams    "sensorReadingType": 1,
80*a3db66b3SPatrick Williams    "sensorType": 8,
81*a3db66b3SPatrick Williams    "serviceInterface": "org.freedesktop.DBus.Properties",
82*a3db66b3SPatrick Williams    "unit": "xyz.openbmc_project.Sensor.Value.Unit.Watts",
83cf3c1e67SAndrew Jeffery}
84cf3c1e67SAndrew Jeffery
85cf3c1e67SAndrew JefferysampleDcmiSensor = {
86cf3c1e67SAndrew Jeffery    "instance": 1,
87cf3c1e67SAndrew Jeffery    "dbus": "/xyz/openbmc_project/sensors/temperature/p0_core0_temp",
88*a3db66b3SPatrick Williams    "record_id": 91,
89cf3c1e67SAndrew Jeffery}
90cf3c1e67SAndrew Jeffery
91cf3c1e67SAndrew Jeffery
92cf3c1e67SAndrew Jefferydef openYaml(f):
93cf3c1e67SAndrew Jeffery    return yaml.load(open(f))
94cf3c1e67SAndrew Jeffery
95cf3c1e67SAndrew Jeffery
96cf3c1e67SAndrew Jefferydef saveYaml(y, f, safe=True):
97cf3c1e67SAndrew Jeffery    if safe:
98cf3c1e67SAndrew Jeffery        noaliasDumper = yaml.dumper.SafeDumper
99cf3c1e67SAndrew Jeffery        noaliasDumper.ignore_aliases = lambda self, data: True
100*a3db66b3SPatrick Williams        yaml.dump(
101*a3db66b3SPatrick Williams            y, open(f, "w"), default_flow_style=False, Dumper=noaliasDumper
102*a3db66b3SPatrick Williams        )
103cf3c1e67SAndrew Jeffery    else:
104cf3c1e67SAndrew Jeffery        yaml.dump(y, open(f, "w"))
105cf3c1e67SAndrew Jeffery
106cf3c1e67SAndrew Jeffery
107cf3c1e67SAndrew Jefferydef getEntityIdAndNamePattern(p, intfs, m):
108cf3c1e67SAndrew Jeffery    key = (p, intfs)
109cf3c1e67SAndrew Jeffery    match = m.get(key, None)
110cf3c1e67SAndrew Jeffery    if match is None:
111cf3c1e67SAndrew Jeffery        # Workaround for P8's occ sensors, where the path look like
112cf3c1e67SAndrew Jeffery        # /org/open_power/control/occ_3_0050
113*a3db66b3SPatrick Williams        if (
114*a3db66b3SPatrick Williams            "/org/open_power/control/occ" in p
115*a3db66b3SPatrick Williams            and "org.open_power.OCC.Status" in intfs
116*a3db66b3SPatrick Williams        ):
117*a3db66b3SPatrick Williams            return (210, "nameLeaf")
118*a3db66b3SPatrick Williams        raise Exception("Unable to find sensor", key, "from map")
119*a3db66b3SPatrick Williams    return (m[key]["entityID"], m[key]["sensorNamePattern"])
120cf3c1e67SAndrew Jeffery
121cf3c1e67SAndrew Jeffery
122cf3c1e67SAndrew Jeffery# Global entity instances
123cf3c1e67SAndrew JefferyentityInstances = {}
124cf3c1e67SAndrew Jeffery
125cf3c1e67SAndrew Jeffery
126cf3c1e67SAndrew Jefferydef getEntityInstance(id):
127cf3c1e67SAndrew Jeffery    instanceId = entityInstances.get(id, 0)
128cf3c1e67SAndrew Jeffery    instanceId = instanceId + 1
129cf3c1e67SAndrew Jeffery    entityInstances[id] = instanceId
130cf3c1e67SAndrew Jeffery    print("EntityId:", id, "InstanceId:", instanceId)
131cf3c1e67SAndrew Jeffery    return instanceId
132cf3c1e67SAndrew Jeffery
133cf3c1e67SAndrew Jeffery
134cf3c1e67SAndrew Jefferydef loadRpt(rptFile):
135cf3c1e67SAndrew Jeffery    sensors = []
136cf3c1e67SAndrew Jeffery    with open(rptFile) as f:
137cf3c1e67SAndrew Jeffery        next(f)
138cf3c1e67SAndrew Jeffery        next(f)
139cf3c1e67SAndrew Jeffery        for line in f:
140*a3db66b3SPatrick Williams            fields = line.strip().split("|")
141cf3c1e67SAndrew Jeffery            fields = list(map(str.strip, fields))
142cf3c1e67SAndrew Jeffery            sensor = RptSensor(
143cf3c1e67SAndrew Jeffery                fields[0],
144cf3c1e67SAndrew Jeffery                int(fields[2], 16) if fields[2] else None,
145cf3c1e67SAndrew Jeffery                int(fields[3], 16) if fields[3] else None,
146cf3c1e67SAndrew Jeffery                int(fields[4], 16) if fields[4] else None,
147cf3c1e67SAndrew Jeffery                int(fields[5], 16) if fields[5] else None,
148cf3c1e67SAndrew Jeffery                int(fields[7], 16) if fields[7] else None,
149*a3db66b3SPatrick Williams                fields[9],
150*a3db66b3SPatrick Williams            )
151cf3c1e67SAndrew Jeffery            # print(sensor)
152cf3c1e67SAndrew Jeffery            sensors.append(sensor)
153cf3c1e67SAndrew Jeffery    return sensors
154cf3c1e67SAndrew Jeffery
155cf3c1e67SAndrew Jeffery
156cf3c1e67SAndrew Jefferydef getDimmTempPath(p):
157cf3c1e67SAndrew Jeffery    # Convert path like: /sys-0/node-0/motherboard-0/dimmconn-0/dimm-0
158cf3c1e67SAndrew Jeffery    # to: /xyz/openbmc_project/sensors/temperature/dimm0_temp
159cf3c1e67SAndrew Jeffery    import re
160*a3db66b3SPatrick Williams
161*a3db66b3SPatrick Williams    dimmconn = re.search(r"dimmconn-\d+", p).group()
162*a3db66b3SPatrick Williams    dimmId = re.search(r"\d+", dimmconn).group()
163*a3db66b3SPatrick Williams    return "/xyz/openbmc_project/sensors/temperature/dimm{}_temp".format(
164*a3db66b3SPatrick Williams        dimmId
165*a3db66b3SPatrick Williams    )
166cf3c1e67SAndrew Jeffery
167cf3c1e67SAndrew Jeffery
168cf3c1e67SAndrew Jefferydef getMembufTempPath(name):
169cf3c1e67SAndrew Jeffery    # Convert names like MEMBUF0_Temp or CENTAUR0_Temp
170cf3c1e67SAndrew Jeffery    # to: /xyz/openbmc_project/sensors/temperature/membuf0_temp
171cf3c1e67SAndrew Jeffery    # to: /xyz/openbmc_project/sensors/temperature/centaur0_temp
172*a3db66b3SPatrick Williams    return "/xyz/openbmc_project/sensors/temperature/{}".format(name.lower())
173cf3c1e67SAndrew Jeffery
174cf3c1e67SAndrew Jeffery
175cf3c1e67SAndrew Jefferydef getCoreTempPath(name, p):
176cf3c1e67SAndrew Jeffery    # For different rpts:
177cf3c1e67SAndrew Jeffery    # Convert path like:
178*a3db66b3SPatrick Williams    #   /sys-0/node-0/motherboard-0/proc_socket-0/module-0/p9_proc_s/eq0/ex0/core0 (for P9)  # noqa: E501
179cf3c1e67SAndrew Jeffery    # to: /xyz/openbmc_project/sensors/temperature/p0_core0_temp
180cf3c1e67SAndrew Jeffery    # or name like: CORE0_Temp (for P8)
181cf3c1e67SAndrew Jeffery    # to: /xyz/openbmc_project/sensors/temperature/core0_temp (for P8)
182cf3c1e67SAndrew Jeffery    import re
183*a3db66b3SPatrick Williams
184*a3db66b3SPatrick Williams    if "p9_proc" in p:
185*a3db66b3SPatrick Williams        splitted = p.split("/")
186*a3db66b3SPatrick Williams        socket = re.search(r"\d+", splitted[4]).group()
187*a3db66b3SPatrick Williams        core = re.search(r"\d+", splitted[9]).group()
188*a3db66b3SPatrick Williams        return (
189*a3db66b3SPatrick Williams            "/xyz/openbmc_project/sensors/temperature/p{}_core{}_temp".format(
190*a3db66b3SPatrick Williams                socket, core
191*a3db66b3SPatrick Williams            )
192*a3db66b3SPatrick Williams        )
193cf3c1e67SAndrew Jeffery    else:
194*a3db66b3SPatrick Williams        core = re.search(r"\d+", name).group()
195*a3db66b3SPatrick Williams        return "/xyz/openbmc_project/sensors/temperature/core{}_temp".format(
196*a3db66b3SPatrick Williams            core
197*a3db66b3SPatrick Williams        )
198cf3c1e67SAndrew Jeffery
199cf3c1e67SAndrew Jeffery
200cf3c1e67SAndrew Jefferydef getPowerPath(name):
201cf3c1e67SAndrew Jeffery    # Convert name like Proc0_Power
202cf3c1e67SAndrew Jeffery    # to: /xyz/openbmc_project/sensors/power/p0_power
203cf3c1e67SAndrew Jeffery    import re
204*a3db66b3SPatrick Williams
205*a3db66b3SPatrick Williams    r = re.search(r"\d+", name)
206cf3c1e67SAndrew Jeffery    if r:
207cf3c1e67SAndrew Jeffery        index = r.group()
208cf3c1e67SAndrew Jeffery    else:
209cf3c1e67SAndrew Jeffery        # Handle cases like IO_A_Power, Storage_Power_A
210*a3db66b3SPatrick Williams        r = re.search(r"_[A|B|C|D]", name).group()[-1]
211*a3db66b3SPatrick Williams        index = str(ord(r) - ord("A"))
212*a3db66b3SPatrick Williams    prefix = "p"
213cf3c1e67SAndrew Jeffery    m = None
214*a3db66b3SPatrick Williams    if "memory_proc" in name.lower():
215cf3c1e67SAndrew Jeffery        prefix = None
216*a3db66b3SPatrick Williams        m = "centaur"
217*a3db66b3SPatrick Williams    elif "pcie_proc" in name.lower():
218*a3db66b3SPatrick Williams        m = "pcie"
219*a3db66b3SPatrick Williams    elif "io" in name.lower():
220*a3db66b3SPatrick Williams        m = "io"
221*a3db66b3SPatrick Williams    elif "fan" in name.lower():
222*a3db66b3SPatrick Williams        m = "fan"
223*a3db66b3SPatrick Williams    elif "storage" in name.lower():
224*a3db66b3SPatrick Williams        m = "disk"
225*a3db66b3SPatrick Williams    elif "total" in name.lower():
226cf3c1e67SAndrew Jeffery        prefix = None
227*a3db66b3SPatrick Williams        m = "total"
228*a3db66b3SPatrick Williams    elif "proc" in name.lower():
229cf3c1e67SAndrew Jeffery        # Default
230cf3c1e67SAndrew Jeffery        pass
231cf3c1e67SAndrew Jeffery
232*a3db66b3SPatrick Williams    ret = "/xyz/openbmc_project/sensors/power/"
233cf3c1e67SAndrew Jeffery    if prefix:
234cf3c1e67SAndrew Jeffery        ret = ret + prefix + index
235cf3c1e67SAndrew Jeffery    if m:
236cf3c1e67SAndrew Jeffery        if prefix:
237*a3db66b3SPatrick Williams            ret = ret + "_" + m
238cf3c1e67SAndrew Jeffery        else:
239cf3c1e67SAndrew Jeffery            ret = ret + m
240cf3c1e67SAndrew Jeffery    if prefix is None:
241cf3c1e67SAndrew Jeffery        ret = ret + index
242*a3db66b3SPatrick Williams    ret = ret + "_power"
243cf3c1e67SAndrew Jeffery    return ret
244cf3c1e67SAndrew Jeffery
245cf3c1e67SAndrew Jeffery
246cf3c1e67SAndrew Jefferydef getDimmTempConfig(s):
247cf3c1e67SAndrew Jeffery    r = sampleDimmTemp.copy()
248*a3db66b3SPatrick Williams    r["entityInstance"] = getEntityInstance(r["entityID"])
249*a3db66b3SPatrick Williams    r["path"] = getDimmTempPath(s.targetPath)
250cf3c1e67SAndrew Jeffery    return r
251cf3c1e67SAndrew Jeffery
252cf3c1e67SAndrew Jeffery
253cf3c1e67SAndrew Jefferydef getMembufTempConfig(s):
254cf3c1e67SAndrew Jeffery    r = sampleDimmTemp.copy()
255*a3db66b3SPatrick Williams    r["entityID"] = 0xD1
256*a3db66b3SPatrick Williams    r["entityInstance"] = getEntityInstance(r["entityID"])
257*a3db66b3SPatrick Williams    r["path"] = getMembufTempPath(s.name)
258cf3c1e67SAndrew Jeffery    return r
259cf3c1e67SAndrew Jeffery
260cf3c1e67SAndrew Jeffery
261cf3c1e67SAndrew Jefferydef getCoreTempConfig(s):
262cf3c1e67SAndrew Jeffery    r = sampleCoreTemp.copy()
263*a3db66b3SPatrick Williams    r["entityInstance"] = getEntityInstance(r["entityID"])
264*a3db66b3SPatrick Williams    r["path"] = getCoreTempPath(s.name, s.targetPath)
265cf3c1e67SAndrew Jeffery    return r
266cf3c1e67SAndrew Jeffery
267cf3c1e67SAndrew Jeffery
268cf3c1e67SAndrew Jefferydef getPowerConfig(s):
269cf3c1e67SAndrew Jeffery    r = samplePower.copy()
270*a3db66b3SPatrick Williams    r["entityInstance"] = getEntityInstance(r["entityID"])
271*a3db66b3SPatrick Williams    r["path"] = getPowerPath(s.name)
272cf3c1e67SAndrew Jeffery    return r
273cf3c1e67SAndrew Jeffery
274cf3c1e67SAndrew Jeffery
275cf3c1e67SAndrew Jefferydef isCoreTemp(p):
276cf3c1e67SAndrew Jeffery    import re
277*a3db66b3SPatrick Williams
278*a3db66b3SPatrick Williams    m = re.search(r"p\d+_core\d+_temp", p)
279cf3c1e67SAndrew Jeffery    return m is not None
280cf3c1e67SAndrew Jeffery
281cf3c1e67SAndrew Jeffery
282cf3c1e67SAndrew Jefferydef getDcmiSensor(i, sensor):
283cf3c1e67SAndrew Jeffery    import re
284*a3db66b3SPatrick Williams
285*a3db66b3SPatrick Williams    path = sensor["path"]
286*a3db66b3SPatrick Williams    name = path.split("/")[-1]
287*a3db66b3SPatrick Williams    m = re.findall(r"\d+", name)
288cf3c1e67SAndrew Jeffery    socket, core = int(m[0]), int(m[1])
289cf3c1e67SAndrew Jeffery    instance = socket * 24 + core + 1
290cf3c1e67SAndrew Jeffery    r = sampleDcmiSensor.copy()
291*a3db66b3SPatrick Williams    r["instance"] = instance
292*a3db66b3SPatrick Williams    r["dbus"] = path
293*a3db66b3SPatrick Williams    r["record_id"] = i
294cf3c1e67SAndrew Jeffery    return r
295cf3c1e67SAndrew Jeffery
296cf3c1e67SAndrew Jeffery
297cf3c1e67SAndrew Jefferydef saveJson(data, f):
298cf3c1e67SAndrew Jeffery    import json
299*a3db66b3SPatrick Williams
300*a3db66b3SPatrick Williams    with open(f, "w") as outfile:
301cf3c1e67SAndrew Jeffery        json.dump(data, outfile, indent=4)
302cf3c1e67SAndrew Jeffery
303cf3c1e67SAndrew Jeffery
304cf3c1e67SAndrew Jefferydef main():
305cf3c1e67SAndrew Jeffery    parser = argparse.ArgumentParser(
306*a3db66b3SPatrick Williams        description="Yaml tool for updating ipmi sensor yaml config"
307*a3db66b3SPatrick Williams    )
308*a3db66b3SPatrick Williams    parser.add_argument(
309*a3db66b3SPatrick Williams        "-i",
310*a3db66b3SPatrick Williams        "--input",
311*a3db66b3SPatrick Williams        required=True,
312*a3db66b3SPatrick Williams        dest="input",
313*a3db66b3SPatrick Williams        help="The ipmi sensor yaml config",
314*a3db66b3SPatrick Williams    )
315*a3db66b3SPatrick Williams    parser.add_argument(
316*a3db66b3SPatrick Williams        "-o",
317*a3db66b3SPatrick Williams        "--output",
318*a3db66b3SPatrick Williams        required=True,
319*a3db66b3SPatrick Williams        dest="output",
320*a3db66b3SPatrick Williams        help="The output yaml file",
321*a3db66b3SPatrick Williams    )
322*a3db66b3SPatrick Williams    parser.add_argument(
323*a3db66b3SPatrick Williams        "-m",
324*a3db66b3SPatrick Williams        "--map",
325*a3db66b3SPatrick Williams        dest="map",
326*a3db66b3SPatrick Williams        default="sensor_map.yaml",
327*a3db66b3SPatrick Williams        help="The sample map yaml file",
328*a3db66b3SPatrick Williams    )
329*a3db66b3SPatrick Williams    parser.add_argument(
330*a3db66b3SPatrick Williams        "-r", "--rpt", dest="rpt", help="The .rpt file generated by op-build"
331*a3db66b3SPatrick Williams    )
332*a3db66b3SPatrick Williams    parser.add_argument(
333*a3db66b3SPatrick Williams        "-f",
334*a3db66b3SPatrick Williams        "--fix",
335*a3db66b3SPatrick Williams        action="store_true",
336*a3db66b3SPatrick Williams        help="Fix entities and sensorNamePattern",
337*a3db66b3SPatrick Williams    )
338cf3c1e67SAndrew Jeffery
339cf3c1e67SAndrew Jeffery    # -g expects output as yaml for mapping of entityID/sensorNamePattern
340cf3c1e67SAndrew Jeffery    # -d expects output as json config for dcmi sensors
341cf3c1e67SAndrew Jeffery    # Do not mess the output by enforcing only one argument is passed
342*a3db66b3SPatrick Williams    # TODO: -f and -r could be used together, and they are conflicted with
343*a3db66b3SPatrick Williams    #       -g or -d
344cf3c1e67SAndrew Jeffery    group = parser.add_mutually_exclusive_group()
345*a3db66b3SPatrick Williams    group.add_argument(
346*a3db66b3SPatrick Williams        "-g",
347*a3db66b3SPatrick Williams        "--generate",
348*a3db66b3SPatrick Williams        action="store_true",
349*a3db66b3SPatrick Williams        help="Generate maps for entityID and sensorNamePattern",
350*a3db66b3SPatrick Williams    )
351*a3db66b3SPatrick Williams    group.add_argument(
352*a3db66b3SPatrick Williams        "-d",
353*a3db66b3SPatrick Williams        "--dcmi",
354*a3db66b3SPatrick Williams        action="store_true",
355*a3db66b3SPatrick Williams        help="Generate dcmi sensors json config",
356*a3db66b3SPatrick Williams    )
357cf3c1e67SAndrew Jeffery
358cf3c1e67SAndrew Jeffery    args = parser.parse_args()
359cf3c1e67SAndrew Jeffery    args = vars(args)
360cf3c1e67SAndrew Jeffery
361*a3db66b3SPatrick Williams    if args["input"] is None or args["output"] is None:
362cf3c1e67SAndrew Jeffery        parser.print_help()
363cf3c1e67SAndrew Jeffery        exit(1)
364cf3c1e67SAndrew Jeffery
365*a3db66b3SPatrick Williams    y = openYaml(args["input"])
366cf3c1e67SAndrew Jeffery
367*a3db66b3SPatrick Williams    if args["fix"]:
368cf3c1e67SAndrew Jeffery        # Fix entities and sensorNamePattern
369*a3db66b3SPatrick Williams        m = openYaml(args["map"])
370cf3c1e67SAndrew Jeffery
371cf3c1e67SAndrew Jeffery        for i in y:
372*a3db66b3SPatrick Williams            path = y[i]["path"]
373*a3db66b3SPatrick Williams            intfs = tuple(sorted(list(y[i]["interfaces"].keys())))
374cf3c1e67SAndrew Jeffery            entityId, namePattern = getEntityIdAndNamePattern(path, intfs, m)
375*a3db66b3SPatrick Williams            y[i]["entityID"] = entityId
376*a3db66b3SPatrick Williams            y[i]["entityInstance"] = getEntityInstance(entityId)
377*a3db66b3SPatrick Williams            y[i]["sensorNamePattern"] = namePattern
378*a3db66b3SPatrick Williams            print(
379*a3db66b3SPatrick Williams                y[i]["path"],
380*a3db66b3SPatrick Williams                "id:",
381*a3db66b3SPatrick Williams                entityId,
382*a3db66b3SPatrick Williams                "instance:",
383*a3db66b3SPatrick Williams                y[i]["entityInstance"],
384*a3db66b3SPatrick Williams            )
385cf3c1e67SAndrew Jeffery
386cf3c1e67SAndrew Jeffery    sensorIds = list(y.keys())
387*a3db66b3SPatrick Williams    if args["rpt"]:
388cf3c1e67SAndrew Jeffery        unhandledSensors = []
389*a3db66b3SPatrick Williams        rptSensors = loadRpt(args["rpt"])
390cf3c1e67SAndrew Jeffery        for s in rptSensors:
391cf3c1e67SAndrew Jeffery            if s.sensorId is not None and s.sensorId not in sensorIds:
392*a3db66b3SPatrick Williams                print(
393*a3db66b3SPatrick Williams                    "Sensor ID",
394*a3db66b3SPatrick Williams                    s.sensorId,
395*a3db66b3SPatrick Williams                    "not in yaml:",
396*a3db66b3SPatrick Williams                    s.name,
397*a3db66b3SPatrick Williams                    ", path:",
398*a3db66b3SPatrick Williams                    s.targetPath,
399*a3db66b3SPatrick Williams                )
400cf3c1e67SAndrew Jeffery                isAdded = False
401*a3db66b3SPatrick Williams                if "temp" in s.name.lower():
402*a3db66b3SPatrick Williams                    if "dimm" in s.targetPath.lower():
403cf3c1e67SAndrew Jeffery                        y[s.sensorId] = getDimmTempConfig(s)
404cf3c1e67SAndrew Jeffery                        isAdded = True
405*a3db66b3SPatrick Williams                    elif "core" in s.targetPath.lower():
406cf3c1e67SAndrew Jeffery                        y[s.sensorId] = getCoreTempConfig(s)
407cf3c1e67SAndrew Jeffery                        isAdded = True
408*a3db66b3SPatrick Williams                    elif (
409*a3db66b3SPatrick Williams                        "centaur" in s.name.lower()
410*a3db66b3SPatrick Williams                        or "membuf" in s.name.lower()
411*a3db66b3SPatrick Williams                    ):
412cf3c1e67SAndrew Jeffery                        y[s.sensorId] = getMembufTempConfig(s)
413cf3c1e67SAndrew Jeffery                        isAdded = True
414*a3db66b3SPatrick Williams                elif s.name.lower().endswith("_power"):
415cf3c1e67SAndrew Jeffery                    y[s.sensorId] = getPowerConfig(s)
416cf3c1e67SAndrew Jeffery                    isAdded = True
417cf3c1e67SAndrew Jeffery
418cf3c1e67SAndrew Jeffery                if isAdded:
419*a3db66b3SPatrick Williams                    print(
420*a3db66b3SPatrick Williams                        "Added sensor id:",
421*a3db66b3SPatrick Williams                        s.sensorId,
422*a3db66b3SPatrick Williams                        ", path:",
423*a3db66b3SPatrick Williams                        y[s.sensorId]["path"],
424*a3db66b3SPatrick Williams                    )
425cf3c1e67SAndrew Jeffery                else:
426cf3c1e67SAndrew Jeffery                    unhandledSensors.append(s)
427cf3c1e67SAndrew Jeffery
428*a3db66b3SPatrick Williams        print("Unhandled sensors:")
429cf3c1e67SAndrew Jeffery        for s in unhandledSensors:
430cf3c1e67SAndrew Jeffery            print(s)
431cf3c1e67SAndrew Jeffery
432*a3db66b3SPatrick Williams    if args["generate"]:
433cf3c1e67SAndrew Jeffery        m = {}
434cf3c1e67SAndrew Jeffery        for i in y:
435*a3db66b3SPatrick Williams            path = y[i]["path"]
436*a3db66b3SPatrick Williams            intfs = tuple(sorted(list(y[i]["interfaces"].keys())))
437*a3db66b3SPatrick Williams            entityId = y[i]["entityID"]
438*a3db66b3SPatrick Williams            sensorNamePattern = y[i]["sensorNamePattern"]
439*a3db66b3SPatrick Williams            m[(path, intfs)] = {
440*a3db66b3SPatrick Williams                "entityID": entityId,
441*a3db66b3SPatrick Williams                "sensorNamePattern": sensorNamePattern,
442*a3db66b3SPatrick Williams            }
443cf3c1e67SAndrew Jeffery        y = m
444cf3c1e67SAndrew Jeffery
445*a3db66b3SPatrick Williams    if args["dcmi"]:
446cf3c1e67SAndrew Jeffery        d = []
447cf3c1e67SAndrew Jeffery        for i in y:
448*a3db66b3SPatrick Williams            if isCoreTemp(y[i]["path"]):
449cf3c1e67SAndrew Jeffery                s = getDcmiSensor(i, y[i])
450cf3c1e67SAndrew Jeffery                d.append(s)
451cf3c1e67SAndrew Jeffery                print(s)
452*a3db66b3SPatrick Williams        saveJson(d, args["output"])
453cf3c1e67SAndrew Jeffery        return
454cf3c1e67SAndrew Jeffery
455*a3db66b3SPatrick Williams    safe = False if args["generate"] else True
456*a3db66b3SPatrick Williams    saveYaml(y, args["output"], safe)
457cf3c1e67SAndrew Jeffery
458cf3c1e67SAndrew Jeffery
459cf3c1e67SAndrew Jefferyif __name__ == "__main__":
460cf3c1e67SAndrew Jeffery    main()
461