185be2e70SMatt Spinler#!/usr/bin/env python 285be2e70SMatt Spinler 385be2e70SMatt Spinlerimport os 485be2e70SMatt Spinlerimport sys 585be2e70SMatt Spinlerimport yaml 685be2e70SMatt Spinlerfrom argparse import ArgumentParser 785be2e70SMatt Spinlerfrom mako.template import Template 885be2e70SMatt Spinler 985be2e70SMatt Spinler""" 1085be2e70SMatt SpinlerThis script generates the data structures for the 1185be2e70SMatt Spinlerphosphor-fan-monitor application. 1285be2e70SMatt Spinler 1385be2e70SMatt SpinlerA future improvement is to get the fan inventory names 1485be2e70SMatt Spinlerfrom a separate file, so just that file could be generated 1585be2e70SMatt Spinlerfrom the MRW. 1685be2e70SMatt Spinler""" 1785be2e70SMatt Spinler 1885be2e70SMatt Spinler 1985be2e70SMatt Spinlertmpl = '''/* This is a generated file. */ 2085be2e70SMatt Spinler#include "fan_defs.hpp" 2185be2e70SMatt Spinler#include "types.hpp" 2235108a77SMatt Spinler#include "groups.hpp" 2385be2e70SMatt Spinler 2485be2e70SMatt Spinlerusing namespace phosphor::fan::monitor; 2535108a77SMatt Spinlerusing namespace phosphor::fan::trust; 2685be2e70SMatt Spinler 2785be2e70SMatt Spinlerconst std::vector<FanDefinition> fanDefinitions 2885be2e70SMatt Spinler{ 2935108a77SMatt Spinler%for fan_data in data.get('fans', {}): 3085be2e70SMatt Spinler FanDefinition{"${fan_data['inventory']}", 3185be2e70SMatt Spinler ${fan_data['allowed_out_of_range_time']}, 3285be2e70SMatt Spinler ${fan_data['deviation']}, 3385be2e70SMatt Spinler ${fan_data['num_sensors_nonfunc_for_fan_nonfunc']}, 3485be2e70SMatt Spinler std::vector<SensorDefinition>{ 3585be2e70SMatt Spinler %for sensor in fan_data['sensors']: 3685be2e70SMatt Spinler <% 3785be2e70SMatt Spinler #has_target is a bool, and we need a true instead of True 3885be2e70SMatt Spinler has_target = str(sensor['has_target']).lower() 39*80f271b2SLei YU target_interface = sensor.get( 40*80f271b2SLei YU 'target_interface', 41*80f271b2SLei YU 'xyz.openbmc_project.Control.FanSpeed') 428e5d197bSLei YU factor = sensor.get('factor', 1) 438e5d197bSLei YU offset = sensor.get('offset', 0) 4485be2e70SMatt Spinler %> \ 458e5d197bSLei YU SensorDefinition{"${sensor['name']}", 468e5d197bSLei YU ${has_target}, 47*80f271b2SLei YU "${target_interface}", 488e5d197bSLei YU ${factor}, 498e5d197bSLei YU ${offset}}, 5085be2e70SMatt Spinler %endfor 5185be2e70SMatt Spinler }, 5285be2e70SMatt Spinler }, 5385be2e70SMatt Spinler%endfor 5485be2e70SMatt Spinler}; 5535108a77SMatt Spinler 5635108a77SMatt Spinler##Function to generate the group creation lambda. 5735108a77SMatt Spinler##If a group were to ever need a different constructor, 5835108a77SMatt Spinler##it could be handled here. 5935108a77SMatt Spinler<%def name="get_lambda_contents(group)"> 6035108a77SMatt Spinler std::vector<std::string> names{ 6135108a77SMatt Spinler %for sensor in group['sensors']: 6235108a77SMatt Spinler "${sensor['name']}", 6335108a77SMatt Spinler %endfor 6435108a77SMatt Spinler }; 6535108a77SMatt Spinler return std::make_unique<${group['class']}>(names); 6635108a77SMatt Spinler</%def> 6735108a77SMatt Spinlerconst std::vector<CreateGroupFunction> trustGroups 6835108a77SMatt Spinler{ 6935108a77SMatt Spinler%for group in data.get('sensor_trust_groups', {}): 7035108a77SMatt Spinler { 7135108a77SMatt Spinler []() 7235108a77SMatt Spinler {\ 7335108a77SMatt Spinler${get_lambda_contents(group)}\ 7435108a77SMatt Spinler } 7535108a77SMatt Spinler }, 7635108a77SMatt Spinler%endfor 7735108a77SMatt Spinler}; 7885be2e70SMatt Spinler''' 7985be2e70SMatt Spinler 8085be2e70SMatt Spinler 8185be2e70SMatt Spinlerif __name__ == '__main__': 8285be2e70SMatt Spinler parser = ArgumentParser( 8385be2e70SMatt Spinler description="Phosphor fan monitor definition parser") 8485be2e70SMatt Spinler 8585be2e70SMatt Spinler parser.add_argument('-m', '--monitor_yaml', dest='monitor_yaml', 8685be2e70SMatt Spinler default="example/monitor.yaml", 8785be2e70SMatt Spinler help='fan monitor definitional yaml') 8885be2e70SMatt Spinler parser.add_argument('-o', '--output_dir', dest='output_dir', 8985be2e70SMatt Spinler default=".", 9085be2e70SMatt Spinler help='output directory') 9185be2e70SMatt Spinler args = parser.parse_args() 9285be2e70SMatt Spinler 9385be2e70SMatt Spinler if not args.monitor_yaml: 9485be2e70SMatt Spinler parser.print_usage() 9585be2e70SMatt Spinler sys.exit(-1) 9685be2e70SMatt Spinler 9785be2e70SMatt Spinler with open(args.monitor_yaml, 'r') as monitor_input: 9885be2e70SMatt Spinler monitor_data = yaml.safe_load(monitor_input) or {} 9985be2e70SMatt Spinler 10085be2e70SMatt Spinler #Do some minor input validation 10135108a77SMatt Spinler for fan in monitor_data.get('fans', {}): 10285be2e70SMatt Spinler if ((fan['deviation'] < 0) or (fan['deviation'] > 100)): 10385be2e70SMatt Spinler sys.exit("Invalid deviation value " + str(fan['deviation'])) 10485be2e70SMatt Spinler 10585be2e70SMatt Spinler output_file = os.path.join(args.output_dir, "fan_monitor_defs.cpp") 10685be2e70SMatt Spinler with open(output_file, 'w') as output: 10785be2e70SMatt Spinler output.write(Template(tmpl).render(data=monitor_data)) 108