1#!/usr/bin/env python 2 3import os 4import sys 5import yaml 6from argparse import ArgumentParser 7from mako.template import Template 8 9""" 10This script generates the data structures for the 11phosphor-fan-monitor application. 12 13A future improvement is to get the fan inventory names 14from a separate file, so just that file could be generated 15from the MRW. 16""" 17 18 19tmpl = '''/* This is a generated file. */ 20#include "fan_defs.hpp" 21#include "types.hpp" 22#include "groups.hpp" 23 24using namespace phosphor::fan::monitor; 25using namespace phosphor::fan::trust; 26 27const std::vector<FanDefinition> fanDefinitions 28{ 29%for fan_data in data.get('fans', {}): 30 FanDefinition{"${fan_data['inventory']}", 31 ${fan_data.get('functional_delay', 0)}, 32 ${fan_data['allowed_out_of_range_time']}, 33 ${fan_data['deviation']}, 34 ${fan_data['num_sensors_nonfunc_for_fan_nonfunc']}, 35 std::vector<SensorDefinition>{ 36 %for sensor in fan_data['sensors']: 37 <% 38 #has_target is a bool, and we need a true instead of True 39 has_target = str(sensor['has_target']).lower() 40 target_interface = sensor.get( 41 'target_interface', 42 'xyz.openbmc_project.Control.FanSpeed') 43 factor = sensor.get('factor', 1) 44 offset = sensor.get('offset', 0) 45 %> \ 46 SensorDefinition{"${sensor['name']}", 47 ${has_target}, 48 "${target_interface}", 49 ${factor}, 50 ${offset}}, 51 %endfor 52 }, 53 }, 54%endfor 55}; 56 57##Function to generate the group creation lambda. 58##If a group were to ever need a different constructor, 59##it could be handled here. 60<%def name="get_lambda_contents(group)"> 61 std::vector<GroupDefinition> group{ 62 %for member in group['group']: 63 <% 64 in_trust = str(member.get('in_trust', "true")).lower() 65 %> 66 GroupDefinition{"${member['name']}", ${in_trust}}, 67 %endfor 68 }; 69 return std::make_unique<${group['class']}>(group); 70</%def> 71const std::vector<CreateGroupFunction> trustGroups 72{ 73%for group in data.get('sensor_trust_groups', {}): 74 { 75 []() 76 {\ 77${get_lambda_contents(group)}\ 78 } 79 }, 80%endfor 81}; 82''' 83 84 85if __name__ == '__main__': 86 parser = ArgumentParser( 87 description="Phosphor fan monitor definition parser") 88 89 parser.add_argument('-m', '--monitor_yaml', dest='monitor_yaml', 90 default="example/monitor.yaml", 91 help='fan monitor definitional yaml') 92 parser.add_argument('-o', '--output_dir', dest='output_dir', 93 default=".", 94 help='output directory') 95 args = parser.parse_args() 96 97 if not args.monitor_yaml: 98 parser.print_usage() 99 sys.exit(-1) 100 101 with open(args.monitor_yaml, 'r') as monitor_input: 102 monitor_data = yaml.safe_load(monitor_input) or {} 103 104 #Do some minor input validation 105 for fan in monitor_data.get('fans', {}): 106 if ((fan['deviation'] < 0) or (fan['deviation'] > 100)): 107 sys.exit("Invalid deviation value " + str(fan['deviation'])) 108 109 output_file = os.path.join(args.output_dir, "fan_monitor_defs.cpp") 110 with open(output_file, 'w') as output: 111 output.write(Template(tmpl).render(data=monitor_data)) 112