blob: 83dcbc088b687e5061eb39e70d95c68212f3c994 [file] [log] [blame]
Matt Spinler85be2e72017-04-28 15:16:48 -05001#!/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"
Matt Spinler35108a72017-09-28 13:02:32 -050022#include "groups.hpp"
Matt Spinler85be2e72017-04-28 15:16:48 -050023
24using namespace phosphor::fan::monitor;
Matt Spinler35108a72017-09-28 13:02:32 -050025using namespace phosphor::fan::trust;
Matt Spinler85be2e72017-04-28 15:16:48 -050026
27const std::vector<FanDefinition> fanDefinitions
28{
Matt Spinler35108a72017-09-28 13:02:32 -050029%for fan_data in data.get('fans', {}):
Matt Spinler85be2e72017-04-28 15:16:48 -050030 FanDefinition{"${fan_data['inventory']}",
Matthew Barth9396bcc2018-02-19 14:13:20 -060031 ${fan_data.get('functional_delay', 0)},
Matt Spinler85be2e72017-04-28 15:16:48 -050032 ${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()
Lei YU80f271b2018-01-31 15:24:46 +080040 target_interface = sensor.get(
41 'target_interface',
42 'xyz.openbmc_project.Control.FanSpeed')
Lei YU8e5d1972018-01-26 17:14:00 +080043 factor = sensor.get('factor', 1)
44 offset = sensor.get('offset', 0)
Matt Spinler85be2e72017-04-28 15:16:48 -050045 %> \
Lei YU8e5d1972018-01-26 17:14:00 +080046 SensorDefinition{"${sensor['name']}",
47 ${has_target},
Lei YU80f271b2018-01-31 15:24:46 +080048 "${target_interface}",
Lei YU8e5d1972018-01-26 17:14:00 +080049 ${factor},
50 ${offset}},
Matt Spinler85be2e72017-04-28 15:16:48 -050051 %endfor
52 },
53 },
54%endfor
55};
Matt Spinler35108a72017-09-28 13:02:32 -050056
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)">
Matthew Barth6f31d192018-01-30 13:06:27 -060061 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}},
Matt Spinler35108a72017-09-28 13:02:32 -050067 %endfor
68 };
Matthew Barth6f31d192018-01-30 13:06:27 -060069 return std::make_unique<${group['class']}>(group);
Matt Spinler35108a72017-09-28 13:02:32 -050070</%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};
Matt Spinler85be2e72017-04-28 15:16:48 -050082'''
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
Matt Spinler35108a72017-09-28 13:02:32 -0500105 for fan in monitor_data.get('fans', {}):
Matt Spinler85be2e72017-04-28 15:16:48 -0500106 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))