| #!/usr/bin/env python |
| |
| """ |
| This script parses the given fan presence definition yaml file and generates |
| a header file based on the defined methods for determining when a fan is |
| present. |
| """ |
| |
| import os |
| import sys |
| import yaml |
| from argparse import ArgumentParser |
| # TODO Convert to using a mako template |
| |
| |
| def get_filename(): |
| """ |
| Constructs and returns the fully qualified header filename. |
| """ |
| script_dir = os.path.dirname(os.path.abspath(__file__)) |
| header_file = os.path.join(script_dir, "fan_detect_defs.cpp") |
| |
| return header_file |
| |
| |
| def create_and_add_header(header_file): |
| """ |
| Creates the header file based on the header filename value given within. |
| The associated fan presence detection application includes this header. |
| |
| Parameter descriptions: |
| header_file Header filename to create |
| """ |
| with open(header_file, 'w') as ofile: |
| ofile.write("/* WARNING: This header contains code generated ") |
| ofile.write("by " + __file__ + " */\n") |
| ofile.write("/* !!! DO NOT EDIT THIS FILE BY HAND !!! */\n") |
| ofile.write("#include \"fan_detect_defs.hpp\"\n\n") |
| ofile.write("const std::map<std::string, ") |
| ofile.write("std::set<phosphor::fan::Properties>>") |
| ofile.write("\nfanDetectMap = {\n") |
| |
| |
| def add_detect(header_fd, dmethod): |
| """ |
| Adds the detection method map entry for listing the fan(s) that should be |
| detected using the supported method. |
| |
| Parameter descriptions: |
| header_fd Header file to add the detection method to |
| dmethod The detection method to be added |
| """ |
| header_fd.write(" {\"" + dmethod + "\",{\n") |
| |
| |
| def add_fan(header_fd, fan_info): |
| """ |
| Adds each fan's yaml entry presence detection information to the |
| corresponding header file for the defined detection method |
| |
| Parameter descriptions: |
| header_fd Header file to add fan information to |
| fan_info Fan presence detection information |
| """ |
| tab = ' ' * 4 |
| header_fd.write(tab * 2 + "std::make_tuple(\"" + |
| fan_info['Inventory'] + "\",\n") |
| header_fd.write(tab * 6 + "\"" +fan_info['Description'] + "\",\n") |
| header_fd.write(tab * 6 + "std::vector<std::string>({") |
| for sensors in fan_info['Sensors']: |
| if sensors != fan_info['Sensors'][-1]: |
| header_fd.write("\"" + sensors + "\",") |
| else: |
| header_fd.write("\"" + sensors + "\"})),\n") |
| |
| |
| def close_detect(header_fd): |
| """ |
| Closes the current detection method map entry. |
| |
| Parameter descriptions: |
| header_fd Header file to add detection method closing to |
| """ |
| header_fd.write(" }},\n") |
| |
| |
| def add_closing(header_fd): |
| """ |
| Appends final closing tags to the header file given. This essentially |
| ends writing to the header file generated. |
| |
| Parameter descriptions: |
| header_fd Header file to add closing tags to |
| """ |
| header_fd.write("};\n") |
| |
| |
| def parse_yaml(yaml_file): |
| """ |
| Parse the given yaml file, creating a header file for each 'Detection' |
| types found to be included within the app supporting presence detection |
| by that type. |
| |
| Parameter descriptions: |
| yaml_file File to be parsed for fan presences definitions |
| """ |
| with open(yaml_file, 'r') as input_file: |
| yaml_input = yaml.safe_load(input_file) |
| header_file = get_filename() |
| create_and_add_header(header_file) |
| header_fd = open(header_file, 'a') |
| if yaml_input: |
| for detect in yaml_input: |
| for dmethod in detect: |
| add_detect(header_fd, dmethod.replace(" ", "-").lower()) |
| for fan in detect[dmethod]: |
| add_fan(header_fd, fan) |
| close_detect(header_fd) |
| add_closing(header_fd) |
| header_fd.close() |
| |
| |
| if __name__ == '__main__': |
| parser = ArgumentParser() |
| # Input yaml containing how each fan's presence detection should be done |
| parser.add_argument("-y", "--yaml", dest="pres_yaml", |
| default= |
| "example/fan-detect.yaml", |
| help= |
| "Input fan presences definition yaml file to parse") |
| args = parser.parse_args(sys.argv[1:]) |
| |
| # Verify given yaml file exists |
| yaml_file = os.path.abspath(args.pres_yaml) |
| if not os.path.isfile(yaml_file): |
| print "Unable to find input yaml file " + yaml_file |
| exit(1) |
| |
| parse_yaml(yaml_file) |