1f24d7749SMatthew Barth#!/usr/bin/env python3 2d08dbe27SMatt Spinler 3d08dbe27SMatt Spinler""" 4d08dbe27SMatt SpinlerThis script reads in fan definition and zone definition YAML 5d08dbe27SMatt Spinlerfiles and generates a set of structures for use by the fan control code. 6d08dbe27SMatt Spinler""" 7d08dbe27SMatt Spinler 8d08dbe27SMatt Spinlerimport os 9d08dbe27SMatt Spinlerimport sys 10d08dbe27SMatt Spinlerfrom argparse import ArgumentParser 11*c7f68beeSPatrick Williams 12*c7f68beeSPatrick Williamsimport yaml 13702c4a55SMatthew Barthfrom mako.lookup import TemplateLookup 14d08dbe27SMatt Spinler 1578498c94SMatt Spinler 167883f58aSMatthew Barthdef parse_cpp_type(typeName): 177883f58aSMatthew Barth """ 187883f58aSMatthew Barth Take a list of dbus types from YAML and convert it to a recursive cpp 197883f58aSMatthew Barth formed data structure. Each entry of the original list gets converted 207883f58aSMatthew Barth into a tuple consisting of the type name and a list with the params 217883f58aSMatthew Barth for this type, 227883f58aSMatthew Barth e.g. 237883f58aSMatthew Barth ['dict', ['string', 'dict', ['string', 'int64']]] 247883f58aSMatthew Barth is converted to 257883f58aSMatthew Barth [('dict', [('string', []), ('dict', [('string', []), 267883f58aSMatthew Barth ('int64', [])]]] 277883f58aSMatthew Barth """ 287883f58aSMatthew Barth 297883f58aSMatthew Barth if not typeName: 307883f58aSMatthew Barth return None 317883f58aSMatthew Barth 327883f58aSMatthew Barth # Type names are _almost_ valid YAML. Insert a , before each [ 337883f58aSMatthew Barth # and then wrap it in a [ ] and it becomes valid YAML (assuming 347883f58aSMatthew Barth # the user gave us a valid typename). 357883f58aSMatthew Barth typeArray = yaml.safe_load("[" + ",[".join(typeName.split("[")) + "]") 367883f58aSMatthew Barth typeTuple = preprocess_yaml_type_array(typeArray).pop(0) 377883f58aSMatthew Barth return get_cpp_type(typeTuple) 387883f58aSMatthew Barth 397883f58aSMatthew Barth 407883f58aSMatthew Barthdef preprocess_yaml_type_array(typeArray): 417883f58aSMatthew Barth """ 427883f58aSMatthew Barth Flattens an array type into a tuple list that can be used to get the 437883f58aSMatthew Barth supported cpp type from each element. 447883f58aSMatthew Barth """ 457883f58aSMatthew Barth 467883f58aSMatthew Barth result = [] 477883f58aSMatthew Barth 487883f58aSMatthew Barth for i in range(len(typeArray)): 497883f58aSMatthew Barth # Ignore lists because we merge them with the previous element 507883f58aSMatthew Barth if type(typeArray[i]) is list: 517883f58aSMatthew Barth continue 527883f58aSMatthew Barth 537883f58aSMatthew Barth # If there is a next element and it is a list, merge it with the 547883f58aSMatthew Barth # current element. 557883f58aSMatthew Barth if i < len(typeArray) - 1 and type(typeArray[i + 1]) is list: 567883f58aSMatthew Barth result.append( 570f2588f2SPatrick Williams (typeArray[i], preprocess_yaml_type_array(typeArray[i + 1])) 580f2588f2SPatrick Williams ) 597883f58aSMatthew Barth else: 607883f58aSMatthew Barth result.append((typeArray[i], [])) 617883f58aSMatthew Barth 627883f58aSMatthew Barth return result 637883f58aSMatthew Barth 647883f58aSMatthew Barth 657883f58aSMatthew Barthdef get_cpp_type(typeTuple): 667883f58aSMatthew Barth """ 677883f58aSMatthew Barth Take a list of dbus types and perform validity checking, such as: 687883f58aSMatthew Barth [ variant [ dict [ int32, int32 ], double ] ] 697883f58aSMatthew Barth This function then converts the type-list into a C++ type string. 707883f58aSMatthew Barth """ 717883f58aSMatthew Barth 727883f58aSMatthew Barth propertyMap = { 730f2588f2SPatrick Williams "byte": {"cppName": "uint8_t", "params": 0}, 740f2588f2SPatrick Williams "boolean": {"cppName": "bool", "params": 0}, 750f2588f2SPatrick Williams "int16": {"cppName": "int16_t", "params": 0}, 760f2588f2SPatrick Williams "uint16": {"cppName": "uint16_t", "params": 0}, 770f2588f2SPatrick Williams "int32": {"cppName": "int32_t", "params": 0}, 780f2588f2SPatrick Williams "uint32": {"cppName": "uint32_t", "params": 0}, 790f2588f2SPatrick Williams "int64": {"cppName": "int64_t", "params": 0}, 800f2588f2SPatrick Williams "uint64": {"cppName": "uint64_t", "params": 0}, 810f2588f2SPatrick Williams "double": {"cppName": "double", "params": 0}, 820f2588f2SPatrick Williams "string": {"cppName": "std::string", "params": 0}, 830f2588f2SPatrick Williams "array": {"cppName": "std::vector", "params": 1}, 840f2588f2SPatrick Williams "dict": {"cppName": "std::map", "params": 2}, 850f2588f2SPatrick Williams } 867883f58aSMatthew Barth 877883f58aSMatthew Barth if len(typeTuple) != 2: 887883f58aSMatthew Barth raise RuntimeError("Invalid typeTuple %s" % typeTuple) 897883f58aSMatthew Barth 907883f58aSMatthew Barth first = typeTuple[0] 917883f58aSMatthew Barth entry = propertyMap[first] 927883f58aSMatthew Barth 930f2588f2SPatrick Williams result = entry["cppName"] 947883f58aSMatthew Barth 957883f58aSMatthew Barth # Handle 0-entry parameter lists. 960f2588f2SPatrick Williams if entry["params"] == 0: 970f2588f2SPatrick Williams if len(typeTuple[1]) != 0: 987883f58aSMatthew Barth raise RuntimeError("Invalid typeTuple %s" % typeTuple) 997883f58aSMatthew Barth else: 1007883f58aSMatthew Barth return result 1017883f58aSMatthew Barth 1027883f58aSMatthew Barth # Get the parameter list 1037883f58aSMatthew Barth rest = typeTuple[1] 1047883f58aSMatthew Barth 1057883f58aSMatthew Barth # Confirm parameter count matches. 1060f2588f2SPatrick Williams if (entry["params"] != -1) and (entry["params"] != len(rest)): 1070f2588f2SPatrick Williams raise RuntimeError("Invalid entry count for %s : %s" % (first, rest)) 1087883f58aSMatthew Barth 1097883f58aSMatthew Barth # Parse each parameter entry, if appropriate, and create C++ template 1107883f58aSMatthew Barth # syntax. 1110f2588f2SPatrick Williams result += "<" 1120f2588f2SPatrick Williams if entry.get("noparse"): 1137883f58aSMatthew Barth # Do not parse the parameter list, just use the first element 1147883f58aSMatthew Barth # of each tuple and ignore possible parameters 1157883f58aSMatthew Barth result += ", ".join([e[0] for e in rest]) 1167883f58aSMatthew Barth else: 117867a31cfSMatthew Barth result += ", ".join([get_cpp_type(e) for e in rest]) 1180f2588f2SPatrick Williams result += ">" 1197883f58aSMatthew Barth 1207883f58aSMatthew Barth return result 1217883f58aSMatthew Barth 1227883f58aSMatthew Barth 123bb12c926SMatthew Barthdef convertToMap(listOfDict): 124bb12c926SMatthew Barth """ 125bb12c926SMatthew Barth Converts a list of dictionary entries to a std::map initialization list. 126bb12c926SMatthew Barth """ 1270f2588f2SPatrick Williams listOfDict = listOfDict.replace("'", '"') 1280f2588f2SPatrick Williams listOfDict = listOfDict.replace("[", "{") 1290f2588f2SPatrick Williams listOfDict = listOfDict.replace("]", "}") 1300f2588f2SPatrick Williams listOfDict = listOfDict.replace(":", ",") 131bb12c926SMatthew Barth return listOfDict 132bb12c926SMatthew Barth 133bb12c926SMatthew Barth 134a1aef7a1SMatthew Barthdef genEvent(event): 135a1aef7a1SMatthew Barth """ 136a1aef7a1SMatthew Barth Generates the source code of an event and returns it as a string 137a1aef7a1SMatthew Barth """ 138a1aef7a1SMatthew Barth e = "SetSpeedEvent{\n" 1390f2588f2SPatrick Williams e += '"' + event["name"] + '",\n' 140a1aef7a1SMatthew Barth e += "Group{\n" 1410f2588f2SPatrick Williams for group in event["groups"]: 1420f2588f2SPatrick Williams for member in group["members"]: 1430f2588f2SPatrick Williams e += '{"' + member["object"] + '",\n' 1440f2588f2SPatrick Williams e += '"' + member["interface"] + '",\n' 1450f2588f2SPatrick Williams e += '"' + member["property"] + '"},\n' 146a1aef7a1SMatthew Barth e += "},\n" 147a1aef7a1SMatthew Barth 14806fa7817SMatthew Barth e += "ActionData{\n" 1490f2588f2SPatrick Williams for d in event["action"]: 15006fa7817SMatthew Barth e += "{Group{\n" 1510f2588f2SPatrick Williams for g in d["groups"]: 1520f2588f2SPatrick Williams for m in g["members"]: 1530f2588f2SPatrick Williams e += '{"' + m["object"] + '",\n' 1540f2588f2SPatrick Williams e += '"' + m["interface"] + '",\n' 1550f2588f2SPatrick Williams e += '"' + m["property"] + '"},\n' 15606fa7817SMatthew Barth e += "},\n" 157a1aef7a1SMatthew Barth e += "std::vector<Action>{\n" 1580f2588f2SPatrick Williams for a in d["actions"]: 1590f2588f2SPatrick Williams if len(a["parameters"]) != 0: 1600f2588f2SPatrick Williams e += "make_action(action::" + a["name"] + "(\n" 1618a697b68SMatthew Barth else: 1620f2588f2SPatrick Williams e += "make_action(action::" + a["name"] + "\n" 1630f2588f2SPatrick Williams for i, p in enumerate(a["parameters"]): 1640f2588f2SPatrick Williams if (i + 1) != len(a["parameters"]): 165a1aef7a1SMatthew Barth e += p + ",\n" 166a1aef7a1SMatthew Barth else: 16706fa7817SMatthew Barth e += p + "\n" 1680f2588f2SPatrick Williams if len(a["parameters"]) != 0: 16906fa7817SMatthew Barth e += ")),\n" 1708a697b68SMatthew Barth else: 1718a697b68SMatthew Barth e += "),\n" 17275d97350SMatthew Barth e += "}},\n" 17306fa7817SMatthew Barth e += "},\n" 174a1aef7a1SMatthew Barth 1751b4de26aSMatthew Barth e += "std::vector<Trigger>{\n" 1760f2588f2SPatrick Williams if ("timer" in event["triggers"]) and ( 1770f2588f2SPatrick Williams event["triggers"]["timer"] is not None 1780f2588f2SPatrick Williams ): 1791b4de26aSMatthew Barth e += "\tmake_trigger(trigger::timer(TimerConf{\n" 1800f2588f2SPatrick Williams e += "\t" + event["triggers"]["timer"]["interval"] + ",\n" 1810f2588f2SPatrick Williams e += "\t" + event["triggers"]["timer"]["type"] + "\n" 182016bd24cSMatthew Barth e += "\t})),\n" 183a1aef7a1SMatthew Barth 1840f2588f2SPatrick Williams if ("signals" in event["triggers"]) and ( 1850f2588f2SPatrick Williams event["triggers"]["signals"] is not None 1860f2588f2SPatrick Williams ): 1870f2588f2SPatrick Williams for s in event["triggers"]["signals"]: 188016bd24cSMatthew Barth e += "\tmake_trigger(trigger::signal(\n" 1890f2588f2SPatrick Williams e += "match::" + s["match"] + "(\n" 1900f2588f2SPatrick Williams for i, mp in enumerate(s["mparams"]["params"]): 1910f2588f2SPatrick Williams if (i + 1) != len(s["mparams"]["params"]): 1920f2588f2SPatrick Williams e += "\t\t\t" + s["mparams"][mp] + ",\n" 193a1aef7a1SMatthew Barth else: 1940f2588f2SPatrick Williams e += "\t\t\t" + s["mparams"][mp] + "\n" 195926df663SMatthew Barth e += "\t\t),\n" 196926df663SMatthew Barth e += "\t\tmake_handler<SignalHandler>(\n" 1970f2588f2SPatrick Williams if ("type" in s["sparams"]) and (s["sparams"]["type"] is not None): 1980f2588f2SPatrick Williams e += s["signal"] + "<" + s["sparams"]["type"] + ">(\n" 199a1aef7a1SMatthew Barth else: 2000f2588f2SPatrick Williams e += s["signal"] + "(\n" 2010f2588f2SPatrick Williams for sp in s["sparams"]["params"]: 2020f2588f2SPatrick Williams e += s["sparams"][sp] + ",\n" 2030f2588f2SPatrick Williams if ("type" in s["hparams"]) and (s["hparams"]["type"] is not None): 2040f2588f2SPatrick Williams e += ( 2050f2588f2SPatrick Williams "handler::" 2060f2588f2SPatrick Williams + s["handler"] 2070f2588f2SPatrick Williams + "<" 2080f2588f2SPatrick Williams + s["hparams"]["type"] 2090f2588f2SPatrick Williams + ">(\n" 2100f2588f2SPatrick Williams ) 211a1aef7a1SMatthew Barth else: 2120f2588f2SPatrick Williams e += "handler::" + s["handler"] + "(\n)" 2130f2588f2SPatrick Williams for i, hp in enumerate(s["hparams"]["params"]): 2140f2588f2SPatrick Williams if (i + 1) != len(s["hparams"]["params"]): 2150f2588f2SPatrick Williams e += s["hparams"][hp] + ",\n" 216a1aef7a1SMatthew Barth else: 2170f2588f2SPatrick Williams e += s["hparams"][hp] + "\n" 218a1aef7a1SMatthew Barth e += "))\n" 219926df663SMatthew Barth e += "\t\t)\n" 220016bd24cSMatthew Barth e += "\t)),\n" 221016bd24cSMatthew Barth 2220f2588f2SPatrick Williams if "init" in event["triggers"]: 2230f2588f2SPatrick Williams for i in event["triggers"]["init"]: 224cd3bfbc1SMatthew Barth e += "\tmake_trigger(trigger::init(\n" 2250f2588f2SPatrick Williams if "method" in i: 226926df663SMatthew Barth e += "\t\tmake_handler<MethodHandler>(\n" 2270f2588f2SPatrick Williams if ("type" in i["mparams"]) and ( 2280f2588f2SPatrick Williams i["mparams"]["type"] is not None 2290f2588f2SPatrick Williams ): 2300f2588f2SPatrick Williams e += i["method"] + "<" + i["mparams"]["type"] + ">(\n" 231926df663SMatthew Barth else: 2320f2588f2SPatrick Williams e += i["method"] + "(\n" 2330f2588f2SPatrick Williams for ip in i["mparams"]["params"]: 2340f2588f2SPatrick Williams e += i["mparams"][ip] + ",\n" 2350f2588f2SPatrick Williams if ("type" in i["hparams"]) and ( 2360f2588f2SPatrick Williams i["hparams"]["type"] is not None 2370f2588f2SPatrick Williams ): 2380f2588f2SPatrick Williams e += ( 2390f2588f2SPatrick Williams "handler::" 2400f2588f2SPatrick Williams + i["handler"] 2410f2588f2SPatrick Williams + "<" 2420f2588f2SPatrick Williams + i["hparams"]["type"] 2430f2588f2SPatrick Williams + ">(\n" 2440f2588f2SPatrick Williams ) 245cd3bfbc1SMatthew Barth else: 2460f2588f2SPatrick Williams e += "handler::" + i["handler"] + "(\n)" 2470f2588f2SPatrick Williams for i, hp in enumerate(i["hparams"]["params"]): 2480f2588f2SPatrick Williams if (i + 1) != len(i["hparams"]["params"]): 2490f2588f2SPatrick Williams e += i["hparams"][hp] + ",\n" 250cd3bfbc1SMatthew Barth else: 2510f2588f2SPatrick Williams e += i["hparams"][hp] + "\n" 252926df663SMatthew Barth e += "))\n" 253cd3bfbc1SMatthew Barth e += "\t\t)\n" 254cd3bfbc1SMatthew Barth e += "\t)),\n" 255cd3bfbc1SMatthew Barth 256a1aef7a1SMatthew Barth e += "},\n" 257a1aef7a1SMatthew Barth 258a1aef7a1SMatthew Barth e += "}" 259a1aef7a1SMatthew Barth 260a1aef7a1SMatthew Barth return e 261a1aef7a1SMatthew Barth 262a1aef7a1SMatthew Barth 2636c050693SMatthew Barthdef getGroups(zNum, zCond, edata, events): 2646c050693SMatthew Barth """ 2656c050693SMatthew Barth Extract and construct the groups for the given event. 2666c050693SMatthew Barth """ 2676c050693SMatthew Barth groups = [] 2680f2588f2SPatrick Williams if ("groups" in edata) and (edata["groups"] is not None): 2690f2588f2SPatrick Williams for eGroups in edata["groups"]: 2700f2588f2SPatrick Williams if ("zone_conditions" in eGroups) and ( 2710f2588f2SPatrick Williams eGroups["zone_conditions"] is not None 2720f2588f2SPatrick Williams ): 2736c050693SMatthew Barth # Zone conditions are optional in the events yaml but skip 2746c050693SMatthew Barth # if this event's condition is not in this zone's conditions 2750f2588f2SPatrick Williams if all( 2760f2588f2SPatrick Williams "name" in z 2770f2588f2SPatrick Williams and z["name"] is not None 2780f2588f2SPatrick Williams and not any(c["name"] == z["name"] for c in zCond) 2790f2588f2SPatrick Williams for z in eGroups["zone_conditions"] 2800f2588f2SPatrick Williams ): 2816c050693SMatthew Barth continue 2826c050693SMatthew Barth 2836c050693SMatthew Barth # Zone numbers are optional in the events yaml but skip if this 2846c050693SMatthew Barth # zone's zone number is not in the event's zone numbers 2850f2588f2SPatrick Williams if all( 2860f2588f2SPatrick Williams "zones" in z 2870f2588f2SPatrick Williams and z["zones"] is not None 2880f2588f2SPatrick Williams and zNum not in z["zones"] 2890f2588f2SPatrick Williams for z in eGroups["zone_conditions"] 2900f2588f2SPatrick Williams ): 2916c050693SMatthew Barth continue 2920f2588f2SPatrick Williams eGroup = next( 2930f2588f2SPatrick Williams g for g in events["groups"] if g["name"] == eGroups["name"] 2940f2588f2SPatrick Williams ) 2956c050693SMatthew Barth 2966c050693SMatthew Barth group = {} 2976c050693SMatthew Barth members = [] 2980f2588f2SPatrick Williams group["name"] = eGroup["name"] 2990f2588f2SPatrick Williams for m in eGroup["members"]: 3006c050693SMatthew Barth member = {} 3010f2588f2SPatrick Williams member["path"] = eGroup["type"] 3020f2588f2SPatrick Williams member["object"] = eGroup["type"] + m 3030f2588f2SPatrick Williams member["interface"] = eGroups["interface"] 3040f2588f2SPatrick Williams member["property"] = eGroups["property"]["name"] 3050f2588f2SPatrick Williams member["type"] = eGroups["property"]["type"] 30618c91030SMatthew Barth # Use defined service to note member on zone object 3070f2588f2SPatrick Williams if ("service" in eGroup) and (eGroup["service"] is not None): 3080f2588f2SPatrick Williams member["service"] = eGroup["service"] 3096c050693SMatthew Barth # Add expected group member's property value if given 3100f2588f2SPatrick Williams if ("value" in eGroups["property"]) and ( 3110f2588f2SPatrick Williams eGroups["property"]["value"] is not None 3120f2588f2SPatrick Williams ): 3130f2588f2SPatrick Williams if ( 3140f2588f2SPatrick Williams isinstance(eGroups["property"]["value"], str) 3150f2588f2SPatrick Williams or "string" in str(member["type"]).lower() 3160f2588f2SPatrick Williams ): 3170f2588f2SPatrick Williams member["value"] = ( 3180f2588f2SPatrick Williams '"' + eGroups["property"]["value"] + '"' 3190f2588f2SPatrick Williams ) 3206c050693SMatthew Barth else: 3210f2588f2SPatrick Williams member["value"] = eGroups["property"]["value"] 3226c050693SMatthew Barth members.append(member) 3230f2588f2SPatrick Williams group["members"] = members 3246c050693SMatthew Barth groups.append(group) 3256c050693SMatthew Barth return groups 3266c050693SMatthew Barth 3276c050693SMatthew Barth 328cd3bfbc1SMatthew Barthdef getParameters(member, groups, section, events): 32973379f99SMatthew Barth """ 330cd3bfbc1SMatthew Barth Extracts and constructs a section's parameters 33173379f99SMatthew Barth """ 332cd3bfbc1SMatthew Barth params = {} 3330f2588f2SPatrick Williams if ("parameters" in section) and (section["parameters"] is not None): 334cd3bfbc1SMatthew Barth plist = [] 3350f2588f2SPatrick Williams for sp in section["parameters"]: 336cd3bfbc1SMatthew Barth p = str(sp) 3370f2588f2SPatrick Williams if p != "type": 338cd3bfbc1SMatthew Barth plist.append(p) 3390f2588f2SPatrick Williams if p != "group": 3400f2588f2SPatrick Williams params[p] = '"' + member[p] + '"' 34173379f99SMatthew Barth else: 342cd3bfbc1SMatthew Barth params[p] = "Group\n{\n" 343cd3bfbc1SMatthew Barth for g in groups: 3440f2588f2SPatrick Williams for m in g["members"]: 345cd3bfbc1SMatthew Barth params[p] += ( 3460f2588f2SPatrick Williams '{"' 3470f2588f2SPatrick Williams + str(m["object"]) 3480f2588f2SPatrick Williams + '",\n' 3490f2588f2SPatrick Williams + '"' 3500f2588f2SPatrick Williams + str(m["interface"]) 3510f2588f2SPatrick Williams + '",\n' 3520f2588f2SPatrick Williams + '"' 3530f2588f2SPatrick Williams + str(m["property"]) 3540f2588f2SPatrick Williams + '"},\n' 3550f2588f2SPatrick Williams ) 356cd3bfbc1SMatthew Barth params[p] += "}" 35773379f99SMatthew Barth else: 358cd3bfbc1SMatthew Barth params[p] = member[p] 3590f2588f2SPatrick Williams params["params"] = plist 360cd3bfbc1SMatthew Barth else: 3610f2588f2SPatrick Williams params["params"] = [] 362cd3bfbc1SMatthew Barth return params 363cd3bfbc1SMatthew Barth 364cd3bfbc1SMatthew Barth 365cd3bfbc1SMatthew Barthdef getInit(eGrps, eTrig, events): 366cd3bfbc1SMatthew Barth """ 367cd3bfbc1SMatthew Barth Extracts and constructs an init trigger for the event's groups 368cd3bfbc1SMatthew Barth which are required to be of the same type. 369cd3bfbc1SMatthew Barth """ 370cd3bfbc1SMatthew Barth method = {} 371cd3bfbc1SMatthew Barth methods = [] 3720f2588f2SPatrick Williams if len(eGrps) > 0: 373cd3bfbc1SMatthew Barth # Use the first group member for retrieving the type 3740f2588f2SPatrick Williams member = eGrps[0]["members"][0] 3750f2588f2SPatrick Williams if ("method" in eTrig) and (eTrig["method"] is not None): 376cd3bfbc1SMatthew Barth # Add method parameters 3770f2588f2SPatrick Williams eMethod = next( 3780f2588f2SPatrick Williams m for m in events["methods"] if m["name"] == eTrig["method"] 3790f2588f2SPatrick Williams ) 3800f2588f2SPatrick Williams method["method"] = eMethod["name"] 3810f2588f2SPatrick Williams method["mparams"] = getParameters(member, eGrps, eMethod, events) 382cd3bfbc1SMatthew Barth 383cd3bfbc1SMatthew Barth # Add handler parameters 3840f2588f2SPatrick Williams eHandler = next( 3850f2588f2SPatrick Williams h for h in events["handlers"] if h["name"] == eTrig["handler"] 3860f2588f2SPatrick Williams ) 3870f2588f2SPatrick Williams method["handler"] = eHandler["name"] 3880f2588f2SPatrick Williams method["hparams"] = getParameters(member, eGrps, eHandler, events) 389cd3bfbc1SMatthew Barth 390cd3bfbc1SMatthew Barth methods.append(method) 391cd3bfbc1SMatthew Barth 392cd3bfbc1SMatthew Barth return methods 39373379f99SMatthew Barth 39473379f99SMatthew Barth 395a69465a1SMatthew Barthdef getSignal(eGrps, eTrig, events): 396a69465a1SMatthew Barth """ 397a69465a1SMatthew Barth Extracts and constructs for each group member a signal 398a69465a1SMatthew Barth subscription of each match listed in the trigger. 399a69465a1SMatthew Barth """ 400a69465a1SMatthew Barth signals = [] 401a69465a1SMatthew Barth for group in eGrps: 4020f2588f2SPatrick Williams for member in group["members"]: 403a69465a1SMatthew Barth signal = {} 404cd3bfbc1SMatthew Barth # Add signal parameters 4050f2588f2SPatrick Williams eSignal = next( 4060f2588f2SPatrick Williams s for s in events["signals"] if s["name"] == eTrig["signal"] 4070f2588f2SPatrick Williams ) 4080f2588f2SPatrick Williams signal["signal"] = eSignal["name"] 4090f2588f2SPatrick Williams signal["sparams"] = getParameters(member, eGrps, eSignal, events) 410cd3bfbc1SMatthew Barth 411a69465a1SMatthew Barth # If service not given, subscribe to signal match 4120f2588f2SPatrick Williams if "service" not in member: 413cd3bfbc1SMatthew Barth # Add signal match parameters 4140f2588f2SPatrick Williams eMatch = next( 4150f2588f2SPatrick Williams m 4160f2588f2SPatrick Williams for m in events["matches"] 4170f2588f2SPatrick Williams if m["name"] == eSignal["match"] 4180f2588f2SPatrick Williams ) 4190f2588f2SPatrick Williams signal["match"] = eMatch["name"] 4200f2588f2SPatrick Williams signal["mparams"] = getParameters( 4210f2588f2SPatrick Williams member, eGrps, eMatch, events 4220f2588f2SPatrick Williams ) 42373379f99SMatthew Barth 42473379f99SMatthew Barth # Add handler parameters 4250f2588f2SPatrick Williams eHandler = next( 4260f2588f2SPatrick Williams h for h in events["handlers"] if h["name"] == eTrig["handler"] 4270f2588f2SPatrick Williams ) 4280f2588f2SPatrick Williams signal["handler"] = eHandler["name"] 4290f2588f2SPatrick Williams signal["hparams"] = getParameters(member, eGrps, eHandler, events) 43073379f99SMatthew Barth 431a69465a1SMatthew Barth signals.append(signal) 432cd3bfbc1SMatthew Barth 433a69465a1SMatthew Barth return signals 434a69465a1SMatthew Barth 435a69465a1SMatthew Barth 436d0b90fc6SMatthew Barthdef getTimer(eTrig): 437d0b90fc6SMatthew Barth """ 438d0b90fc6SMatthew Barth Extracts and constructs the required parameters for an 439d0b90fc6SMatthew Barth event timer. 440d0b90fc6SMatthew Barth """ 441d0b90fc6SMatthew Barth timer = {} 4420f2588f2SPatrick Williams timer["interval"] = ( 4430f2588f2SPatrick Williams "static_cast<std::chrono::microseconds>" 4440f2588f2SPatrick Williams + "(" 4450f2588f2SPatrick Williams + str(eTrig["interval"]) 4460f2588f2SPatrick Williams + ")" 4470f2588f2SPatrick Williams ) 4480f2588f2SPatrick Williams timer["type"] = "TimerType::" + str(eTrig["type"]) 449d0b90fc6SMatthew Barth return timer 450d0b90fc6SMatthew Barth 451d0b90fc6SMatthew Barth 452a1aef7a1SMatthew Barthdef getActions(zNum, zCond, edata, actions, events): 4539df74750SMatthew Barth """ 4549df74750SMatthew Barth Extracts and constructs the make_action function call for 4559df74750SMatthew Barth all the actions within the given event. 4569df74750SMatthew Barth """ 4579df74750SMatthew Barth action = [] 4580f2588f2SPatrick Williams for eActions in actions["actions"]: 4599df74750SMatthew Barth actions = {} 4600f2588f2SPatrick Williams eAction = next( 4610f2588f2SPatrick Williams a for a in events["actions"] if a["name"] == eActions["name"] 4620f2588f2SPatrick Williams ) 4630f2588f2SPatrick Williams actions["name"] = eAction["name"] 4640f2588f2SPatrick Williams actions["groups"] = getGroups(zNum, zCond, eActions, events) 4659df74750SMatthew Barth params = [] 4660f2588f2SPatrick Williams if ("parameters" in eAction) and (eAction["parameters"] is not None): 4670f2588f2SPatrick Williams for p in eAction["parameters"]: 4689df74750SMatthew Barth param = "static_cast<" 4699df74750SMatthew Barth if type(eActions[p]) is not dict: 4700f2588f2SPatrick Williams if p == "actions": 4719df74750SMatthew Barth param = "std::vector<Action>{" 4720f2588f2SPatrick Williams pActs = getActions( 4730f2588f2SPatrick Williams zNum, zCond, edata, eActions, events 4740f2588f2SPatrick Williams ) 4759df74750SMatthew Barth for a in pActs: 4760f2588f2SPatrick Williams if len(a["parameters"]) != 0: 4779df74750SMatthew Barth param += ( 4780f2588f2SPatrick Williams "make_action(action::" + a["name"] + "(\n" 4790f2588f2SPatrick Williams ) 4800f2588f2SPatrick Williams for i, ap in enumerate(a["parameters"]): 4810f2588f2SPatrick Williams if (i + 1) != len(a["parameters"]): 4820f2588f2SPatrick Williams param += ap + "," 4839df74750SMatthew Barth else: 4840f2588f2SPatrick Williams param += ap + ")" 4859df74750SMatthew Barth else: 4860f2588f2SPatrick Williams param += "make_action(action::" + a["name"] 4879df74750SMatthew Barth param += ")," 4889df74750SMatthew Barth param += "}" 4890f2588f2SPatrick Williams elif p == "defevents" or p == "altevents" or p == "events": 490a1aef7a1SMatthew Barth param = "std::vector<SetSpeedEvent>{\n" 491a1aef7a1SMatthew Barth for i, e in enumerate(eActions[p]): 492a1aef7a1SMatthew Barth aEvent = getEvent(zNum, zCond, e, events) 493a1aef7a1SMatthew Barth if not aEvent: 494a1aef7a1SMatthew Barth continue 495a1aef7a1SMatthew Barth if (i + 1) != len(eActions[p]): 496a1aef7a1SMatthew Barth param += genEvent(aEvent) + ",\n" 497a1aef7a1SMatthew Barth else: 498a1aef7a1SMatthew Barth param += genEvent(aEvent) + "\n" 499a1aef7a1SMatthew Barth param += "\t}" 5000f2588f2SPatrick Williams elif p == "property": 5010f2588f2SPatrick Williams if ( 5020f2588f2SPatrick Williams isinstance(eActions[p], str) 5030f2588f2SPatrick Williams or "string" in str(eActions[p]["type"]).lower() 5040f2588f2SPatrick Williams ): 5059a5b6994SMatthew Barth param += ( 5060f2588f2SPatrick Williams str(eActions[p]["type"]).lower() 5070f2588f2SPatrick Williams + '>("' 5080f2588f2SPatrick Williams + str(eActions[p]) 5090f2588f2SPatrick Williams + '")' 5100f2588f2SPatrick Williams ) 5119a5b6994SMatthew Barth else: 5129df74750SMatthew Barth param += ( 5130f2588f2SPatrick Williams str(eActions[p]["type"]).lower() 5140f2588f2SPatrick Williams + ">(" 5150f2588f2SPatrick Williams + str(eActions[p]["value"]).lower() 5160f2588f2SPatrick Williams + ")" 5170f2588f2SPatrick Williams ) 5189df74750SMatthew Barth else: 5199df74750SMatthew Barth # Default type to 'size_t' when not given 5200f2588f2SPatrick Williams param += "size_t>(" + str(eActions[p]).lower() + ")" 5219df74750SMatthew Barth else: 5220f2588f2SPatrick Williams if p == "timer": 523d0b90fc6SMatthew Barth t = getTimer(eActions[p]) 5249df74750SMatthew Barth param = ( 5250f2588f2SPatrick Williams "TimerConf{" 5260f2588f2SPatrick Williams + t["interval"] 5270f2588f2SPatrick Williams + "," 5280f2588f2SPatrick Williams + t["type"] 5290f2588f2SPatrick Williams + "}" 5300f2588f2SPatrick Williams ) 5319df74750SMatthew Barth else: 5320f2588f2SPatrick Williams param += str(eActions[p]["type"]).lower() + ">(" 5330f2588f2SPatrick Williams if p != "map": 5340f2588f2SPatrick Williams if ( 5350f2588f2SPatrick Williams isinstance(eActions[p]["value"], str) 5360f2588f2SPatrick Williams or "string" in str(eActions[p]["type"]).lower() 5370f2588f2SPatrick Williams ): 5380f2588f2SPatrick Williams param += '"' + str(eActions[p]["value"]) + '")' 5399df74750SMatthew Barth else: 5409df74750SMatthew Barth param += ( 5410f2588f2SPatrick Williams str(eActions[p]["value"]).lower() + ")" 5420f2588f2SPatrick Williams ) 5430f2588f2SPatrick Williams else: 5440f2588f2SPatrick Williams param += ( 5450f2588f2SPatrick Williams str(eActions[p]["type"]).lower() 5460f2588f2SPatrick Williams + convertToMap(str(eActions[p]["value"])) 5470f2588f2SPatrick Williams + ")" 5480f2588f2SPatrick Williams ) 5499df74750SMatthew Barth params.append(param) 5500f2588f2SPatrick Williams actions["parameters"] = params 5519df74750SMatthew Barth action.append(actions) 5529df74750SMatthew Barth return action 5539df74750SMatthew Barth 5549df74750SMatthew Barth 5557f272fd0SMatthew Barthdef getEvent(zone_num, zone_conditions, e, events_data): 5567f272fd0SMatthew Barth """ 5577f272fd0SMatthew Barth Parses the sections of an event and populates the properties 5587f272fd0SMatthew Barth that construct an event within the generated source. 5597f272fd0SMatthew Barth """ 5607f272fd0SMatthew Barth event = {} 5617f272fd0SMatthew Barth 562621a5778SMatthew Barth # Add set speed event name 5630f2588f2SPatrick Williams event["name"] = e["name"] 564621a5778SMatthew Barth 5656c050693SMatthew Barth # Add set speed event groups 5660f2588f2SPatrick Williams event["groups"] = getGroups(zone_num, zone_conditions, e, events_data) 5677f272fd0SMatthew Barth 568e3d1c4a9SMatthew Barth # Add optional set speed actions and function parameters 5690f2588f2SPatrick Williams event["action"] = [] 5700f2588f2SPatrick Williams if ("actions" in e) and (e["actions"] is not None): 57106fa7817SMatthew Barth # List of dicts containing the list of groups and list of actions 57206fa7817SMatthew Barth sseActions = [] 57306fa7817SMatthew Barth eActions = getActions(zone_num, zone_conditions, e, e, events_data) 57406fa7817SMatthew Barth for eAction in eActions: 57506fa7817SMatthew Barth # Skip events that have no groups defined for the event or actions 5760f2588f2SPatrick Williams if not event["groups"] and not eAction["groups"]: 57706fa7817SMatthew Barth continue 57806fa7817SMatthew Barth # Find group in sseActions 57906fa7817SMatthew Barth grpExists = False 58006fa7817SMatthew Barth for sseDict in sseActions: 5810f2588f2SPatrick Williams if eAction["groups"] == sseDict["groups"]: 58206fa7817SMatthew Barth # Extend 'actions' list 5830f2588f2SPatrick Williams del eAction["groups"] 5840f2588f2SPatrick Williams sseDict["actions"].append(eAction) 58506fa7817SMatthew Barth grpExists = True 58606fa7817SMatthew Barth break 58706fa7817SMatthew Barth if not grpExists: 5880f2588f2SPatrick Williams grps = eAction["groups"] 5890f2588f2SPatrick Williams del eAction["groups"] 59006fa7817SMatthew Barth actList = [] 59106fa7817SMatthew Barth actList.append(eAction) 5920f2588f2SPatrick Williams sseActions.append({"groups": grps, "actions": actList}) 5930f2588f2SPatrick Williams event["action"] = sseActions 5947f272fd0SMatthew Barth 595a69465a1SMatthew Barth # Add event triggers 5960f2588f2SPatrick Williams event["triggers"] = {} 5970f2588f2SPatrick Williams for trig in e["triggers"]: 598a69465a1SMatthew Barth triggers = [] 5990f2588f2SPatrick Williams if trig["name"] == "timer": 6000f2588f2SPatrick Williams event["triggers"]["timer"] = getTimer(trig) 6010f2588f2SPatrick Williams elif trig["name"] == "signal": 6020f2588f2SPatrick Williams if "signals" not in event["triggers"]: 6030f2588f2SPatrick Williams event["triggers"]["signals"] = [] 6040f2588f2SPatrick Williams triggers = getSignal(event["groups"], trig, events_data) 6050f2588f2SPatrick Williams event["triggers"]["signals"].extend(triggers) 6060f2588f2SPatrick Williams elif trig["name"] == "init": 6070f2588f2SPatrick Williams triggers = getInit(event["groups"], trig, events_data) 6080f2588f2SPatrick Williams event["triggers"]["init"] = triggers 6097f272fd0SMatthew Barth 6107f272fd0SMatthew Barth return event 6117f272fd0SMatthew Barth 6127f272fd0SMatthew Barth 6137f272fd0SMatthew Barthdef addPrecondition(zNum, zCond, event, events_data): 6149af190cdSMatthew Barth """ 6159af190cdSMatthew Barth Parses the precondition section of an event and populates the necessary 6169af190cdSMatthew Barth structures to generate a precondition for a set speed event. 6179af190cdSMatthew Barth """ 6189af190cdSMatthew Barth precond = {} 619621a5778SMatthew Barth 620621a5778SMatthew Barth # Add set speed event precondition name 6210f2588f2SPatrick Williams precond["pcname"] = event["name"] 622621a5778SMatthew Barth 6239af190cdSMatthew Barth # Add set speed event precondition group 6240f2588f2SPatrick Williams precond["pcgrps"] = getGroups( 6250f2588f2SPatrick Williams zNum, zCond, event["precondition"], events_data 6260f2588f2SPatrick Williams ) 6279af190cdSMatthew Barth 6287f272fd0SMatthew Barth # Add set speed event precondition actions 6297f272fd0SMatthew Barth pc = [] 6307f272fd0SMatthew Barth pcs = {} 6310f2588f2SPatrick Williams pcs["name"] = event["precondition"]["name"] 6320f2588f2SPatrick Williams epc = next( 6330f2588f2SPatrick Williams p 6340f2588f2SPatrick Williams for p in events_data["preconditions"] 6350f2588f2SPatrick Williams if p["name"] == event["precondition"]["name"] 6360f2588f2SPatrick Williams ) 6379af190cdSMatthew Barth params = [] 6380f2588f2SPatrick Williams for p in epc["parameters"] or []: 6399af190cdSMatthew Barth param = {} 6400f2588f2SPatrick Williams if p == "groups": 6410f2588f2SPatrick Williams param["type"] = "std::vector<PrecondGroup>" 6420f2588f2SPatrick Williams param["open"] = "{" 6430f2588f2SPatrick Williams param["close"] = "}" 6449af190cdSMatthew Barth values = [] 6450f2588f2SPatrick Williams for group in precond["pcgrps"]: 6460f2588f2SPatrick Williams for pcgrp in group["members"]: 6479af190cdSMatthew Barth value = {} 6480f2588f2SPatrick Williams value["value"] = ( 6490f2588f2SPatrick Williams 'PrecondGroup{"' 6500f2588f2SPatrick Williams + str(pcgrp["object"]) 6510f2588f2SPatrick Williams + '","' 6520f2588f2SPatrick Williams + str(pcgrp["interface"]) 6530f2588f2SPatrick Williams + '","' 6540f2588f2SPatrick Williams + str(pcgrp["property"]) 6550f2588f2SPatrick Williams + '",' 6560f2588f2SPatrick Williams + "static_cast<" 6570f2588f2SPatrick Williams + str(pcgrp["type"]).lower() 6580f2588f2SPatrick Williams + ">" 6590f2588f2SPatrick Williams ) 6600f2588f2SPatrick Williams if ( 6610f2588f2SPatrick Williams isinstance(pcgrp["value"], str) 6620f2588f2SPatrick Williams or "string" in str(pcgrp["type"]).lower() 6630f2588f2SPatrick Williams ): 6640f2588f2SPatrick Williams value["value"] += "(" + str(pcgrp["value"]) + ")}" 6659a5b6994SMatthew Barth else: 6660f2588f2SPatrick Williams value["value"] += ( 6670f2588f2SPatrick Williams "(" + str(pcgrp["value"]).lower() + ")}" 6680f2588f2SPatrick Williams ) 6699af190cdSMatthew Barth values.append(value) 6700f2588f2SPatrick Williams param["values"] = values 6719af190cdSMatthew Barth params.append(param) 6720f2588f2SPatrick Williams pcs["params"] = params 6737f272fd0SMatthew Barth pc.append(pcs) 6740f2588f2SPatrick Williams precond["pcact"] = pc 6759af190cdSMatthew Barth 6767f272fd0SMatthew Barth pcevents = [] 6770f2588f2SPatrick Williams for pce in event["precondition"]["events"]: 6787f272fd0SMatthew Barth pcevent = getEvent(zNum, zCond, pce, events_data) 6797f272fd0SMatthew Barth if not pcevent: 6807f272fd0SMatthew Barth continue 6817f272fd0SMatthew Barth pcevents.append(pcevent) 6820f2588f2SPatrick Williams precond["pcevts"] = pcevents 6837f272fd0SMatthew Barth 684f20c321dSMatthew Barth # Add precondition event triggers 6850f2588f2SPatrick Williams precond["triggers"] = {} 6860f2588f2SPatrick Williams for trig in event["precondition"]["triggers"]: 687f20c321dSMatthew Barth triggers = [] 6880f2588f2SPatrick Williams if trig["name"] == "timer": 6890f2588f2SPatrick Williams precond["triggers"]["pctime"] = getTimer(trig) 6900f2588f2SPatrick Williams elif trig["name"] == "signal": 6910f2588f2SPatrick Williams if "pcsigs" not in precond["triggers"]: 6920f2588f2SPatrick Williams precond["triggers"]["pcsigs"] = [] 6930f2588f2SPatrick Williams triggers = getSignal(precond["pcgrps"], trig, events_data) 6940f2588f2SPatrick Williams precond["triggers"]["pcsigs"].extend(triggers) 6950f2588f2SPatrick Williams elif trig["name"] == "init": 6960f2588f2SPatrick Williams triggers = getInit(precond["pcgrps"], trig, events_data) 6970f2588f2SPatrick Williams precond["triggers"]["init"] = triggers 6989af190cdSMatthew Barth 6999af190cdSMatthew Barth return precond 7009af190cdSMatthew Barth 7019af190cdSMatthew Barth 702b751f32dSGunnar Millsdef getEventsInZone(zone_num, zone_conditions, events_data): 703d4d0f083SMatthew Barth """ 704d4d0f083SMatthew Barth Constructs the event entries defined for each zone using the events yaml 705d4d0f083SMatthew Barth provided. 706d4d0f083SMatthew Barth """ 707d4d0f083SMatthew Barth events = [] 708ba102b38SMatthew Barth 7090f2588f2SPatrick Williams if "events" in events_data: 7100f2588f2SPatrick Williams for e in events_data["events"]: 711d4d0f083SMatthew Barth event = {} 712621a5778SMatthew Barth 7139af190cdSMatthew Barth # Add precondition if given 7140f2588f2SPatrick Williams if ("precondition" in e) and (e["precondition"] is not None): 7150f2588f2SPatrick Williams event["pc"] = addPrecondition( 7160f2588f2SPatrick Williams zone_num, zone_conditions, e, events_data 7170f2588f2SPatrick Williams ) 718ba102b38SMatthew Barth else: 7197f272fd0SMatthew Barth event = getEvent(zone_num, zone_conditions, e, events_data) 720a6f75169SMatthew Barth # Remove empty events and events that have 721a6f75169SMatthew Barth # no groups defined for the event or any of the actions 7220f2588f2SPatrick Williams if not event or ( 7230f2588f2SPatrick Williams not event["groups"] 7240f2588f2SPatrick Williams and all(not a["groups"] for a in event["action"]) 7250f2588f2SPatrick Williams ): 7267f272fd0SMatthew Barth continue 727d4d0f083SMatthew Barth events.append(event) 728d4d0f083SMatthew Barth 729d4d0f083SMatthew Barth return events 730d4d0f083SMatthew Barth 731d4d0f083SMatthew Barth 73278498c94SMatt Spinlerdef getFansInZone(zone_num, profiles, fan_data): 73378498c94SMatt Spinler """ 73478498c94SMatt Spinler Parses the fan definition YAML files to find the fans 73578498c94SMatt Spinler that match both the zone passed in and one of the 73678498c94SMatt Spinler cooling profiles. 73778498c94SMatt Spinler """ 73878498c94SMatt Spinler 73978498c94SMatt Spinler fans = [] 74078498c94SMatt Spinler 7410f2588f2SPatrick Williams for f in fan_data["fans"]: 7420f2588f2SPatrick Williams if zone_num != f["cooling_zone"]: 74378498c94SMatt Spinler continue 74478498c94SMatt Spinler 74578498c94SMatt Spinler # 'cooling_profile' is optional (use 'all' instead) 7460f2588f2SPatrick Williams if f.get("cooling_profile") is None: 74778498c94SMatt Spinler profile = "all" 74878498c94SMatt Spinler else: 7490f2588f2SPatrick Williams profile = f["cooling_profile"] 75078498c94SMatt Spinler 75178498c94SMatt Spinler if profile not in profiles: 75278498c94SMatt Spinler continue 75378498c94SMatt Spinler 75478498c94SMatt Spinler fan = {} 7550f2588f2SPatrick Williams fan["name"] = f["inventory"] 7560f2588f2SPatrick Williams fan["sensors"] = f["sensors"] 7570f2588f2SPatrick Williams fan["target_interface"] = f.get( 7580f2588f2SPatrick Williams "target_interface", "xyz.openbmc_project.Control.FanSpeed" 7590f2588f2SPatrick Williams ) 7600f2588f2SPatrick Williams fan["target_path"] = f.get( 7610f2588f2SPatrick Williams "target_path", "/xyz/openbmc_project/sensors/fan_tach/" 7620f2588f2SPatrick Williams ) 76378498c94SMatt Spinler fans.append(fan) 76478498c94SMatt Spinler 76578498c94SMatt Spinler return fans 76678498c94SMatt Spinler 76778498c94SMatt Spinler 7687883f58aSMatthew Barthdef getIfacesInZone(zone_ifaces): 7697883f58aSMatthew Barth """ 7707883f58aSMatthew Barth Parse given interfaces for a zone for associating a zone with an interface 7717883f58aSMatthew Barth and set any properties listed to defined values upon fan control starting 7727883f58aSMatthew Barth on the zone. 7737883f58aSMatthew Barth """ 7747883f58aSMatthew Barth 7757883f58aSMatthew Barth ifaces = [] 7767883f58aSMatthew Barth for i in zone_ifaces: 7777883f58aSMatthew Barth iface = {} 7787883f58aSMatthew Barth # Interface name not needed yet for fan zones but 7797883f58aSMatthew Barth # may be necessary as more interfaces are extended by the zones 7800f2588f2SPatrick Williams iface["name"] = i["name"] 7817883f58aSMatthew Barth 7820f2588f2SPatrick Williams if ("properties" in i) and (i["properties"] is not None): 7837883f58aSMatthew Barth props = [] 7840f2588f2SPatrick Williams for p in i["properties"]: 7857883f58aSMatthew Barth prop = {} 7860f2588f2SPatrick Williams prop["name"] = p["name"] 7870f2588f2SPatrick Williams prop["func"] = str(p["name"]).lower() 7880f2588f2SPatrick Williams prop["type"] = parse_cpp_type(p["type"]) 7890f2588f2SPatrick Williams if "persist" in p: 7900f2588f2SPatrick Williams persist = p["persist"] 7910f2588f2SPatrick Williams if persist is not None: 7920f2588f2SPatrick Williams if isinstance(persist, bool): 7930f2588f2SPatrick Williams prop["persist"] = "true" if persist else "false" 79459096e50SMatthew Barth else: 7950f2588f2SPatrick Williams prop["persist"] = "false" 7967883f58aSMatthew Barth vals = [] 7970f2588f2SPatrick Williams for v in p["values"]: 7980f2588f2SPatrick Williams val = v["value"] 7990f2588f2SPatrick Williams if val is not None: 8000f2588f2SPatrick Williams if isinstance(val, bool): 8017883f58aSMatthew Barth # Convert True/False to 'true'/'false' 8020f2588f2SPatrick Williams val = "true" if val else "false" 8030f2588f2SPatrick Williams elif isinstance(val, str): 8047883f58aSMatthew Barth # Wrap strings with double-quotes 8050f2588f2SPatrick Williams val = '"' + val + '"' 8067883f58aSMatthew Barth vals.append(val) 8070f2588f2SPatrick Williams prop["values"] = vals 8087883f58aSMatthew Barth props.append(prop) 8090f2588f2SPatrick Williams iface["props"] = props 8107883f58aSMatthew Barth ifaces.append(iface) 8117883f58aSMatthew Barth 8127883f58aSMatthew Barth return ifaces 8137883f58aSMatthew Barth 8147883f58aSMatthew Barth 815ee8a2816SGunnar Millsdef getConditionInZoneConditions(zone_condition, zone_conditions_data): 816ee8a2816SGunnar Mills """ 817ee8a2816SGunnar Mills Parses the zone conditions definition YAML files to find the condition 818ee8a2816SGunnar Mills that match both the zone condition passed in. 819ee8a2816SGunnar Mills """ 820ee8a2816SGunnar Mills 821ee8a2816SGunnar Mills condition = {} 822ee8a2816SGunnar Mills 8230f2588f2SPatrick Williams for c in zone_conditions_data["conditions"]: 8240f2588f2SPatrick Williams if zone_condition != c["name"]: 825ee8a2816SGunnar Mills continue 8260f2588f2SPatrick Williams condition["type"] = c["type"] 827ee8a2816SGunnar Mills properties = [] 8280f2588f2SPatrick Williams for p in c["properties"]: 829ee8a2816SGunnar Mills property = {} 8300f2588f2SPatrick Williams property["property"] = p["property"] 8310f2588f2SPatrick Williams property["interface"] = p["interface"] 8320f2588f2SPatrick Williams property["path"] = p["path"] 8330f2588f2SPatrick Williams property["type"] = p["type"].lower() 8340f2588f2SPatrick Williams property["value"] = str(p["value"]).lower() 835ee8a2816SGunnar Mills properties.append(property) 8360f2588f2SPatrick Williams condition["properties"] = properties 837ee8a2816SGunnar Mills 838ee8a2816SGunnar Mills return condition 839ee8a2816SGunnar Mills 840ee8a2816SGunnar Mills 841ee8a2816SGunnar Millsdef buildZoneData(zone_data, fan_data, events_data, zone_conditions_data): 84278498c94SMatt Spinler """ 84378498c94SMatt Spinler Combines the zone definition YAML and fan 84478498c94SMatt Spinler definition YAML to create a data structure defining 84578498c94SMatt Spinler the fan cooling zones. 84678498c94SMatt Spinler """ 84778498c94SMatt Spinler 84878498c94SMatt Spinler zone_groups = [] 84978498c94SMatt Spinler 850005ff2ffSMatthew Barth # Allow zone_conditions to not be in yaml (since its optional) 851005ff2ffSMatthew Barth if not isinstance(zone_data, list) and zone_data != {}: 852005ff2ffSMatthew Barth zone_data = [zone_data] 85378498c94SMatt Spinler for group in zone_data: 85478498c94SMatt Spinler conditions = [] 855ee8a2816SGunnar Mills # zone conditions are optional 8560f2588f2SPatrick Williams if "zone_conditions" in group and group["zone_conditions"] is not None: 8570f2588f2SPatrick Williams for c in group["zone_conditions"]: 858ee8a2816SGunnar Mills if not zone_conditions_data: 8590f2588f2SPatrick Williams sys.exit( 8600f2588f2SPatrick Williams "No zone_conditions YAML file but " 8610f2588f2SPatrick Williams + "zone_conditions used in zone YAML" 8620f2588f2SPatrick Williams ) 863ee8a2816SGunnar Mills 8640f2588f2SPatrick Williams condition = getConditionInZoneConditions( 8650f2588f2SPatrick Williams c["name"], zone_conditions_data 8660f2588f2SPatrick Williams ) 867ee8a2816SGunnar Mills 868ee8a2816SGunnar Mills if not condition: 8690f2588f2SPatrick Williams sys.exit("Missing zone condition " + c["name"]) 870ee8a2816SGunnar Mills 871ee8a2816SGunnar Mills conditions.append(condition) 87278498c94SMatt Spinler 87378498c94SMatt Spinler zone_group = {} 8740f2588f2SPatrick Williams zone_group["conditions"] = conditions 87578498c94SMatt Spinler 87678498c94SMatt Spinler zones = [] 8770f2588f2SPatrick Williams for z in group["zones"]: 87878498c94SMatt Spinler zone = {} 87978498c94SMatt Spinler 88078498c94SMatt Spinler # 'zone' is required 8810f2588f2SPatrick Williams if ("zone" not in z) or (z["zone"] is None): 8820f2588f2SPatrick Williams sys.exit("Missing fan zone number in " + z) 88378498c94SMatt Spinler 8840f2588f2SPatrick Williams zone["num"] = z["zone"] 88578498c94SMatt Spinler 8860f2588f2SPatrick Williams zone["full_speed"] = z["full_speed"] 88778498c94SMatt Spinler 8880f2588f2SPatrick Williams zone["default_floor"] = z["default_floor"] 8891de66629SMatthew Barth 890a956184bSMatthew Barth # 'increase_delay' is optional (use 0 by default) 8910f2588f2SPatrick Williams key = "increase_delay" 892a956184bSMatthew Barth zone[key] = z.setdefault(key, 0) 893a956184bSMatthew Barth 894a956184bSMatthew Barth # 'decrease_interval' is optional (use 0 by default) 8950f2588f2SPatrick Williams key = "decrease_interval" 896a956184bSMatthew Barth zone[key] = z.setdefault(key, 0) 897a956184bSMatthew Barth 89878498c94SMatt Spinler # 'cooling_profiles' is optional (use 'all' instead) 8990f2588f2SPatrick Williams if ("cooling_profiles" not in z) or ( 9000f2588f2SPatrick Williams z["cooling_profiles"] is None 9010f2588f2SPatrick Williams ): 90278498c94SMatt Spinler profiles = ["all"] 90378498c94SMatt Spinler else: 9040f2588f2SPatrick Williams profiles = z["cooling_profiles"] 90578498c94SMatt Spinler 9067883f58aSMatthew Barth # 'interfaces' is optional (no default) 90764099cdbSMatthew Barth ifaces = [] 9080f2588f2SPatrick Williams if ("interfaces" in z) and (z["interfaces"] is not None): 9090f2588f2SPatrick Williams ifaces = getIfacesInZone(z["interfaces"]) 9107883f58aSMatthew Barth 9110f2588f2SPatrick Williams fans = getFansInZone(z["zone"], profiles, fan_data) 9120f2588f2SPatrick Williams events = getEventsInZone( 9130f2588f2SPatrick Williams z["zone"], group.get("zone_conditions", {}), events_data 9140f2588f2SPatrick Williams ) 91578498c94SMatt Spinler 91678498c94SMatt Spinler if len(fans) == 0: 9170f2588f2SPatrick Williams sys.exit("Didn't find any fans in zone " + str(zone["num"])) 91878498c94SMatt Spinler 9190f2588f2SPatrick Williams if ifaces: 9200f2588f2SPatrick Williams zone["ifaces"] = ifaces 9210f2588f2SPatrick Williams zone["fans"] = fans 9220f2588f2SPatrick Williams zone["events"] = events 92378498c94SMatt Spinler zones.append(zone) 92478498c94SMatt Spinler 9250f2588f2SPatrick Williams zone_group["zones"] = zones 92678498c94SMatt Spinler zone_groups.append(zone_group) 92778498c94SMatt Spinler 92878498c94SMatt Spinler return zone_groups 92978498c94SMatt Spinler 93078498c94SMatt Spinler 9310f2588f2SPatrick Williamsif __name__ == "__main__": 9320f2588f2SPatrick Williams parser = ArgumentParser(description="Phosphor fan zone definition parser") 933d08dbe27SMatt Spinler 9340f2588f2SPatrick Williams parser.add_argument( 9350f2588f2SPatrick Williams "-z", 9360f2588f2SPatrick Williams "--zone_yaml", 9370f2588f2SPatrick Williams dest="zone_yaml", 938d08dbe27SMatt Spinler default="example/zones.yaml", 9390f2588f2SPatrick Williams help="fan zone definitional yaml", 9400f2588f2SPatrick Williams ) 9410f2588f2SPatrick Williams parser.add_argument( 9420f2588f2SPatrick Williams "-f", 9430f2588f2SPatrick Williams "--fan_yaml", 9440f2588f2SPatrick Williams dest="fan_yaml", 945d08dbe27SMatt Spinler default="example/fans.yaml", 9460f2588f2SPatrick Williams help="fan definitional yaml", 9470f2588f2SPatrick Williams ) 9480f2588f2SPatrick Williams parser.add_argument( 9490f2588f2SPatrick Williams "-e", 9500f2588f2SPatrick Williams "--events_yaml", 9510f2588f2SPatrick Williams dest="events_yaml", 9520f2588f2SPatrick Williams help="events to set speeds yaml", 9530f2588f2SPatrick Williams ) 9540f2588f2SPatrick Williams parser.add_argument( 9550f2588f2SPatrick Williams "-c", 9560f2588f2SPatrick Williams "--zone_conditions_yaml", 9570f2588f2SPatrick Williams dest="zone_conditions_yaml", 9580f2588f2SPatrick Williams help="conditions to determine zone yaml", 9590f2588f2SPatrick Williams ) 9600f2588f2SPatrick Williams parser.add_argument( 9610f2588f2SPatrick Williams "-o", 9620f2588f2SPatrick Williams "--output_dir", 9630f2588f2SPatrick Williams dest="output_dir", 964d08dbe27SMatt Spinler default=".", 9650f2588f2SPatrick Williams help="output directory", 9660f2588f2SPatrick Williams ) 967d08dbe27SMatt Spinler args = parser.parse_args() 968d08dbe27SMatt Spinler 969d08dbe27SMatt Spinler if not args.zone_yaml or not args.fan_yaml: 970d08dbe27SMatt Spinler parser.print_usage() 9713e781064SWilliam A. Kennington III sys.exit(1) 972d08dbe27SMatt Spinler 9730f2588f2SPatrick Williams with open(args.zone_yaml, "r") as zone_input: 974d08dbe27SMatt Spinler zone_data = yaml.safe_load(zone_input) or {} 975d08dbe27SMatt Spinler 9760f2588f2SPatrick Williams with open(args.fan_yaml, "r") as fan_input: 977d08dbe27SMatt Spinler fan_data = yaml.safe_load(fan_input) or {} 978d08dbe27SMatt Spinler 979d4d0f083SMatthew Barth events_data = {} 980d4d0f083SMatthew Barth if args.events_yaml: 9810f2588f2SPatrick Williams with open(args.events_yaml, "r") as events_input: 982d4d0f083SMatthew Barth events_data = yaml.safe_load(events_input) or {} 983d4d0f083SMatthew Barth 984ee8a2816SGunnar Mills zone_conditions_data = {} 985ee8a2816SGunnar Mills if args.zone_conditions_yaml: 9860f2588f2SPatrick Williams with open(args.zone_conditions_yaml, "r") as zone_conditions_input: 987ee8a2816SGunnar Mills zone_conditions_data = yaml.safe_load(zone_conditions_input) or {} 988ee8a2816SGunnar Mills 9890f2588f2SPatrick Williams zone_config = buildZoneData( 9900f2588f2SPatrick Williams zone_data.get("zone_configuration", {}), 9910f2588f2SPatrick Williams fan_data, 9920f2588f2SPatrick Williams events_data, 9930f2588f2SPatrick Williams zone_conditions_data, 9940f2588f2SPatrick Williams ) 995ee7f6428SMatt Spinler 9960f2588f2SPatrick Williams manager_config = zone_data.get("manager_configuration", {}) 997ee7f6428SMatt Spinler 9980f2588f2SPatrick Williams if manager_config.get("power_on_delay") is None: 9990f2588f2SPatrick Williams manager_config["power_on_delay"] = 0 1000d08dbe27SMatt Spinler 1001702c4a55SMatthew Barth tmpls_dir = os.path.join( 10020f2588f2SPatrick Williams os.path.dirname(os.path.realpath(__file__)), "templates" 10030f2588f2SPatrick Williams ) 1004d08dbe27SMatt Spinler output_file = os.path.join(args.output_dir, "fan_zone_defs.cpp") 1005702c4a55SMatthew Barth if sys.version_info < (3, 0): 1006702c4a55SMatthew Barth lkup = TemplateLookup( 10070f2588f2SPatrick Williams directories=tmpls_dir.split(), disable_unicode=True 10080f2588f2SPatrick Williams ) 1009702c4a55SMatthew Barth else: 10100f2588f2SPatrick Williams lkup = TemplateLookup(directories=tmpls_dir.split()) 10110f2588f2SPatrick Williams tmpl = lkup.get_template("fan_zone_defs.mako.cpp") 10120f2588f2SPatrick Williams with open(output_file, "w") as output: 10130f2588f2SPatrick Williams output.write(tmpl.render(zones=zone_config, mgr_data=manager_config)) 1014