blob: d11ff35888b9a475ba761d4009ee5d7d564351f3 [file] [log] [blame]
Matt Spinlerd08dbe22017-04-11 13:52:54 -05001#!/usr/bin/env python
2
3"""
4This script reads in fan definition and zone definition YAML
5files and generates a set of structures for use by the fan control code.
6"""
7
8import os
9import sys
10import yaml
11from argparse import ArgumentParser
12from mako.template import Template
13
Matthew Barth7f272fd2017-09-12 16:16:56 -050014tmpl = '''
15<%!
16def indent(str, depth):
17 return ''.join(4*' '*depth+line for line in str.splitlines(True))
18%>
19<%def name="genSSE(event)" buffered="True">
20Group{
21%for member in event['group']:
22{
23 "${member['name']}",
24 {"${member['interface']}",
25 "${member['property']}"}
26},
27%endfor
28},
29std::vector<Action>{
30%for a in event['action']:
Matthew Barth4c04a012017-09-15 13:05:30 -050031%if len(a['parameters']) != 0:
Matthew Barth7f272fd2017-09-12 16:16:56 -050032make_action(action::${a['name']}(
Matthew Barth4c04a012017-09-15 13:05:30 -050033%else:
34make_action(action::${a['name']}
35%endif
Matthew Barth7f272fd2017-09-12 16:16:56 -050036%for i, p in enumerate(a['parameters']):
37%if (i+1) != len(a['parameters']):
38 static_cast<${p['type']}>(${p['value']}),
39%else:
Matthew Barth4c04a012017-09-15 13:05:30 -050040 static_cast<${p['type']}>(${p['value']}))
Matthew Barth7f272fd2017-09-12 16:16:56 -050041%endif
42%endfor
Matthew Barth4c04a012017-09-15 13:05:30 -050043),
Matthew Barth7f272fd2017-09-12 16:16:56 -050044%endfor
45},
46Timer{
47 ${event['timer']['interval']}
48},
49std::vector<PropertyChange>{
50%for s in event['signal']:
51 PropertyChange{
52 interfacesAdded("${s['obj_path']}"),
53 make_handler(objectSignal<${s['type']}>(
54 "${s['path']}",
55 "${s['interface']}",
56 "${s['property']}",
57 handler::setProperty<${s['type']}>(
58 "${s['path']}",
59 "${s['interface']}",
60 "${s['property']}"
61 )
62 ))
63 },
64 PropertyChange{
65 propertiesChanged(
66 "${s['path']}",
67 "${s['interface']}"),
68 make_handler(propertySignal<${s['type']}>(
69 "${s['interface']}",
70 "${s['property']}",
71 handler::setProperty<${s['type']}>(
72 "${s['path']}",
73 "${s['interface']}",
74 "${s['property']}"
75 )
76 ))
77 },
78%endfor
79}
80</%def>
81/* This is a generated file. */
Matthew Barth34f1bda2017-05-31 13:45:36 -050082#include <sdbusplus/bus.hpp>
Matt Spinlerd08dbe22017-04-11 13:52:54 -050083#include "manager.hpp"
Matthew Barthba102b32017-05-16 16:13:56 -050084#include "functor.hpp"
85#include "actions.hpp"
Matthew Barth7e527c12017-05-17 10:14:15 -050086#include "handlers.hpp"
Matthew Barth9af190c2017-08-08 14:20:43 -050087#include "preconditions.hpp"
Matt Spinlerd08dbe22017-04-11 13:52:54 -050088
89using namespace phosphor::fan::control;
Matthew Barth34f1bda2017-05-31 13:45:36 -050090using namespace sdbusplus::bus::match::rules;
Matt Spinlerd08dbe22017-04-11 13:52:54 -050091
Matt Spinleree7f6422017-05-09 11:03:14 -050092const unsigned int Manager::_powerOnDelay{${mgr_data['power_on_delay']}};
93
Matt Spinlerd08dbe22017-04-11 13:52:54 -050094const std::vector<ZoneGroup> Manager::_zoneLayouts
95{
96%for zone_group in zones:
Matthew Barth9c726672017-05-18 13:44:46 -050097 ZoneGroup{
Gunnar Millsee8a2812017-06-02 14:26:47 -050098 std::vector<Condition>{
99 %for condition in zone_group['conditions']:
100 Condition{
101 "${condition['type']}",
102 std::vector<ConditionProperty>{
103 %for property in condition['properties']:
104 ConditionProperty{
105 "${property['property']}",
106 "${property['interface']}",
107 "${property['path']}",
108 static_cast<${property['type']}>(${property['value']}),
109 },
110 %endfor
111 },
112 },
113 %endfor
114 },
Matthew Barth9c726672017-05-18 13:44:46 -0500115 std::vector<ZoneDefinition>{
116 %for zone in zone_group['zones']:
117 ZoneDefinition{
118 ${zone['num']},
119 ${zone['full_speed']},
Matthew Barth1de66622017-06-12 13:13:02 -0500120 ${zone['default_floor']},
Matthew Bartha9561842017-06-29 11:43:45 -0500121 ${zone['increase_delay']},
122 ${zone['decrease_interval']},
Matthew Barth9c726672017-05-18 13:44:46 -0500123 std::vector<FanDefinition>{
124 %for fan in zone['fans']:
125 FanDefinition{
126 "${fan['name']}",
127 std::vector<std::string>{
128 %for sensor in fan['sensors']:
129 "${sensor}",
130 %endfor
131 }
132 },
133 %endfor
134 },
135 std::vector<SetSpeedEvent>{
136 %for event in zone['events']:
Matthew Barth9af190c2017-08-08 14:20:43 -0500137 %if ('pc' in event) and \
138 (event['pc'] is not None):
139 SetSpeedEvent{
140 Group{
141 %for member in event['pc']['pcgrp']:
142 {
143 "${member['name']}",
144 {"${member['interface']}",
145 "${member['property']}"}
146 },
147 %endfor
148 },
Matthew Barth7f272fd2017-09-12 16:16:56 -0500149 std::vector<Action>{
150 %for i, a in enumerate(event['pc']['pcact']):
Matthew Barth4c04a012017-09-15 13:05:30 -0500151 %if len(a['params']) != 0:
Matthew Barth9af190c2017-08-08 14:20:43 -0500152 make_action(
Matthew Barth7f272fd2017-09-12 16:16:56 -0500153 precondition::${a['name']}(
Matthew Barth4c04a012017-09-15 13:05:30 -0500154 %else:
155 make_action(
156 precondition::${a['name']}
157 %endif
Matthew Barth7f272fd2017-09-12 16:16:56 -0500158 %for p in a['params']:
Matthew Barth9af190c2017-08-08 14:20:43 -0500159 ${p['type']}${p['open']}
160 %for j, v in enumerate(p['values']):
161 %if (j+1) != len(p['values']):
162 ${v['value']},
163 %else:
164 ${v['value']}
165 %endif
166 %endfor
167 ${p['close']},
168 %endfor
Matthew Barth7f272fd2017-09-12 16:16:56 -0500169 %if (i+1) != len(event['pc']['pcact']):
Matthew Barth4c04a012017-09-15 13:05:30 -0500170 %if len(a['params']) != 0:
Matthew Barth7f272fd2017-09-12 16:16:56 -0500171 )),
Matthew Barth4c04a012017-09-15 13:05:30 -0500172 %else:
173 ),
174 %endif
Matthew Barth9c726672017-05-18 13:44:46 -0500175 %endif
176 %endfor
Matthew Barth7f272fd2017-09-12 16:16:56 -0500177 std::vector<SetSpeedEvent>{
178 %for pcevt in event['pc']['pcevts']:
179 SetSpeedEvent{\
180 ${indent(genSSE(event=pcevt), 6)}\
181 },
182 %endfor
183 %else:
184 SetSpeedEvent{\
185 ${indent(genSSE(event=event), 6)}
186 %endif
Matthew Barth9af190c2017-08-08 14:20:43 -0500187 %if ('pc' in event) and (event['pc'] is not None):
188 }
Matthew Barth4c04a012017-09-15 13:05:30 -0500189 %if len(event['pc']['pcact'][-1]['params']) != 0:
Matthew Barth9af190c2017-08-08 14:20:43 -0500190 )),
Matthew Barth4c04a012017-09-15 13:05:30 -0500191 %else:
192 ),
193 %endif
Matthew Barth7f272fd2017-09-12 16:16:56 -0500194 },
Matthew Barth90149802017-08-15 10:51:37 -0500195 Timer{
196 ${event['pc']['pctime']['interval']}
197 },
Matthew Barth9af190c2017-08-08 14:20:43 -0500198 std::vector<PropertyChange>{
199 %for s in event['pc']['pcsig']:
200 PropertyChange{
201 interfacesAdded("${s['obj_path']}"),
202 make_handler(objectSignal<${s['type']}>(
203 "${s['path']}",
204 "${s['interface']}",
205 "${s['property']}",
206 handler::setProperty<${s['type']}>(
207 "${s['path']}",
208 "${s['interface']}",
209 "${s['property']}"
210 )
211 ))
212 },
213 PropertyChange{
Matthew Barthbe250832017-08-11 13:16:28 -0500214 propertiesChanged(
215 "${s['path']}",
216 "${s['interface']}"),
Matthew Barth9af190c2017-08-08 14:20:43 -0500217 make_handler(propertySignal<${s['type']}>(
218 "${s['interface']}",
219 "${s['property']}",
220 handler::setProperty<${s['type']}>(
221 "${s['path']}",
222 "${s['interface']}",
223 "${s['property']}"
224 )
225 ))
226 },
227 %endfor
228 }
229 %endif
Matthew Barth9c726672017-05-18 13:44:46 -0500230 },
231 %endfor
232 }
233 },
234 %endfor
235 }
Matt Spinler78498c92017-04-11 13:59:46 -0500236 },
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500237%endfor
238};
239'''
240
Matt Spinler78498c92017-04-11 13:59:46 -0500241
Matthew Barthbb12c922017-06-13 13:57:40 -0500242def convertToMap(listOfDict):
243 """
244 Converts a list of dictionary entries to a std::map initialization list.
245 """
246 listOfDict = listOfDict.replace('[', '{')
247 listOfDict = listOfDict.replace(']', '}')
248 listOfDict = listOfDict.replace(':', ',')
249 return listOfDict
250
251
Matthew Barth7f272fd2017-09-12 16:16:56 -0500252def getEvent(zone_num, zone_conditions, e, events_data):
253 """
254 Parses the sections of an event and populates the properties
255 that construct an event within the generated source.
256 """
257 event = {}
258 # Zone numbers are optional in the events yaml but skip if this
259 # zone's zone number is not in the event's zone numbers
260 if all('zones' in z and
261 z['zones'] is not None and
262 zone_num not in z['zones']
263 for z in e['zone_conditions']):
264 return
265
266 # Zone conditions are optional in the events yaml but skip
267 # if this event's condition is not in this zone's conditions
268 if all('name' in z and z['name'] is not None and
269 not any(c['name'] == z['name'] for c in zone_conditions)
270 for z in e['zone_conditions']):
271 return
272
273 # Add set speed event group
274 group = []
275 groups = next(g for g in events_data['groups']
276 if g['name'] == e['group'])
277 for member in groups['members']:
278 members = {}
279 members['obj_path'] = groups['type']
280 members['name'] = (groups['type'] +
281 member)
282 members['interface'] = e['interface']
283 members['property'] = e['property']['name']
284 group.append(members)
285 event['group'] = group
286
287 # Add set speed actions and function parameters
288 action = []
289 for eActions in e['actions']:
290 actions = {}
291 eAction = next(a for a in events_data['actions']
292 if a['name'] == eActions['name'])
293 actions['name'] = eAction['name']
294 params = []
Matthew Barth4c04a012017-09-15 13:05:30 -0500295 if ('parameters' in eAction) and \
296 (eAction['parameters'] is not None):
297 for p in eAction['parameters']:
298 param = {}
299 if type(eActions[p]) is not dict:
300 if p == 'property':
301 param['value'] = str(eActions[p]).lower()
302 param['type'] = str(
303 e['property']['type']).lower()
304 else:
305 # Default type to 'size_t' when not given
306 param['value'] = str(eActions[p]).lower()
307 param['type'] = 'size_t'
308 params.append(param)
Matthew Barth7f272fd2017-09-12 16:16:56 -0500309 else:
Matthew Barth4c04a012017-09-15 13:05:30 -0500310 param['type'] = str(eActions[p]['type']).lower()
311 if p != 'map':
312 param['value'] = str(
313 eActions[p]['value']).lower()
314 else:
315 emap = convertToMap(str(eActions[p]['value']))
316 param['value'] = param['type'] + emap
317 params.append(param)
Matthew Barth7f272fd2017-09-12 16:16:56 -0500318 actions['parameters'] = params
319 action.append(actions)
320 event['action'] = action
321
322 # Add property change signal handler
323 signal = []
324 for path in group:
325 signals = {}
326 signals['obj_path'] = path['obj_path']
327 signals['path'] = path['name']
328 signals['interface'] = e['interface']
329 signals['property'] = e['property']['name']
330 signals['type'] = e['property']['type']
331 signal.append(signals)
332 event['signal'] = signal
333
334 # Add optional action call timer
335 timer = {}
336 interval = "static_cast<std::chrono::seconds>"
337 if ('timer' in e) and \
338 (e['timer'] is not None):
339 timer['interval'] = (interval +
340 "(" +
341 str(e['timer']['interval']) +
342 ")")
343 else:
344 timer['interval'] = (interval +
345 "(" + str(0) + ")")
346 event['timer'] = timer
347
348 return event
349
350
351def addPrecondition(zNum, zCond, event, events_data):
Matthew Barth9af190c2017-08-08 14:20:43 -0500352 """
353 Parses the precondition section of an event and populates the necessary
354 structures to generate a precondition for a set speed event.
355 """
356 precond = {}
357 # Add set speed event precondition group
358 group = []
359 for grp in event['precondition']['groups']:
360 groups = next(g for g in events_data['groups']
361 if g['name'] == grp['name'])
362 for member in groups['members']:
363 members = {}
364 members['obj_path'] = groups['type']
365 members['name'] = (groups['type'] +
366 member)
367 members['interface'] = grp['interface']
368 members['property'] = grp['property']['name']
369 members['type'] = grp['property']['type']
370 members['value'] = grp['property']['value']
371 group.append(members)
372 precond['pcgrp'] = group
373
Matthew Barth7f272fd2017-09-12 16:16:56 -0500374 # Add set speed event precondition actions
375 pc = []
376 pcs = {}
377 pcs['name'] = event['precondition']['name']
378 epc = next(p for p in events_data['preconditions']
Matthew Barth9af190c2017-08-08 14:20:43 -0500379 if p['name'] == event['precondition']['name'])
380 params = []
Matthew Barth7f272fd2017-09-12 16:16:56 -0500381 for p in epc['parameters']:
Matthew Barth9af190c2017-08-08 14:20:43 -0500382 param = {}
383 if p == 'groups':
384 param['type'] = "std::vector<PrecondGroup>"
385 param['open'] = "{"
386 param['close'] = "}"
387 values = []
388 for pcgrp in group:
389 value = {}
390 value['value'] = (
391 "PrecondGroup{\"" +
392 str(pcgrp['name']) + "\",\"" +
393 str(pcgrp['interface']) + "\",\"" +
394 str(pcgrp['property']) + "\"," +
395 "static_cast<" +
396 str(pcgrp['type']).lower() + ">" +
397 "(" + str(pcgrp['value']).lower() + ")}")
398 values.append(value)
399 param['values'] = values
400 params.append(param)
Matthew Barth7f272fd2017-09-12 16:16:56 -0500401 pcs['params'] = params
402 pc.append(pcs)
Matthew Barth9af190c2017-08-08 14:20:43 -0500403 precond['pcact'] = pc
404
Matthew Barth7f272fd2017-09-12 16:16:56 -0500405 pcevents = []
406 for pce in event['precondition']['events']:
407 pcevent = getEvent(zNum, zCond, pce, events_data)
408 if not pcevent:
409 continue
410 pcevents.append(pcevent)
411 precond['pcevts'] = pcevents
412
Matthew Barth9af190c2017-08-08 14:20:43 -0500413 # Add precondition property change signal handler
414 signal = []
415 for member in group:
416 signals = {}
417 signals['obj_path'] = member['obj_path']
418 signals['path'] = member['name']
419 signals['interface'] = member['interface']
420 signals['property'] = member['property']
421 signals['type'] = member['type']
422 signal.append(signals)
423 precond['pcsig'] = signal
424
Matthew Barth90149802017-08-15 10:51:37 -0500425 # Add optional action call timer
426 timer = {}
427 interval = "static_cast<std::chrono::seconds>"
428 if ('timer' in event['precondition']) and \
429 (event['precondition']['timer'] is not None):
430 timer['interval'] = (interval +
431 "(" +
432 str(event['precondition']['timer']['interval']) +
433 ")")
434 else:
435 timer['interval'] = (interval +
436 "(" + str(0) + ")")
437 precond['pctime'] = timer
438
Matthew Barth9af190c2017-08-08 14:20:43 -0500439 return precond
440
441
Gunnar Millsb751f322017-06-06 15:14:11 -0500442def getEventsInZone(zone_num, zone_conditions, events_data):
Matthew Barthd4d0f082017-05-16 13:51:10 -0500443 """
444 Constructs the event entries defined for each zone using the events yaml
445 provided.
446 """
447 events = []
Matthew Barthba102b32017-05-16 16:13:56 -0500448
Matthew Barthd4d0f082017-05-16 13:51:10 -0500449 if 'events' in events_data:
450 for e in events_data['events']:
Matthew Barthd4d0f082017-05-16 13:51:10 -0500451 event = {}
Matthew Barth9af190c2017-08-08 14:20:43 -0500452 # Add precondition if given
453 if ('precondition' in e) and \
454 (e['precondition'] is not None):
Matthew Barth7f272fd2017-09-12 16:16:56 -0500455 event['pc'] = addPrecondition(zone_num,
456 zone_conditions,
457 e,
458 events_data)
Matthew Barth90149802017-08-15 10:51:37 -0500459 else:
Matthew Barth7f272fd2017-09-12 16:16:56 -0500460 event = getEvent(zone_num, zone_conditions, e, events_data)
461 if not event:
462 continue
Matthew Barthd4d0f082017-05-16 13:51:10 -0500463 events.append(event)
464
465 return events
466
467
Matt Spinler78498c92017-04-11 13:59:46 -0500468def getFansInZone(zone_num, profiles, fan_data):
469 """
470 Parses the fan definition YAML files to find the fans
471 that match both the zone passed in and one of the
472 cooling profiles.
473 """
474
475 fans = []
476
477 for f in fan_data['fans']:
478
479 if zone_num != f['cooling_zone']:
480 continue
481
Gunnar Mills67e95512017-06-02 14:35:18 -0500482 # 'cooling_profile' is optional (use 'all' instead)
Matt Spinler78498c92017-04-11 13:59:46 -0500483 if f.get('cooling_profile') is None:
484 profile = "all"
485 else:
486 profile = f['cooling_profile']
487
488 if profile not in profiles:
489 continue
490
491 fan = {}
492 fan['name'] = f['inventory']
493 fan['sensors'] = f['sensors']
494 fans.append(fan)
495
496 return fans
497
498
Gunnar Millsee8a2812017-06-02 14:26:47 -0500499def getConditionInZoneConditions(zone_condition, zone_conditions_data):
500 """
501 Parses the zone conditions definition YAML files to find the condition
502 that match both the zone condition passed in.
503 """
504
505 condition = {}
506
507 for c in zone_conditions_data['conditions']:
508
509 if zone_condition != c['name']:
510 continue
511 condition['type'] = c['type']
512 properties = []
513 for p in c['properties']:
514 property = {}
515 property['property'] = p['property']
516 property['interface'] = p['interface']
517 property['path'] = p['path']
518 property['type'] = p['type'].lower()
519 property['value'] = str(p['value']).lower()
520 properties.append(property)
521 condition['properties'] = properties
522
523 return condition
524
525
526def buildZoneData(zone_data, fan_data, events_data, zone_conditions_data):
Matt Spinler78498c92017-04-11 13:59:46 -0500527 """
528 Combines the zone definition YAML and fan
529 definition YAML to create a data structure defining
530 the fan cooling zones.
531 """
532
533 zone_groups = []
534
535 for group in zone_data:
536 conditions = []
Gunnar Millsee8a2812017-06-02 14:26:47 -0500537 # zone conditions are optional
538 if 'zone_conditions' in group and group['zone_conditions'] is not None:
539 for c in group['zone_conditions']:
540
541 if not zone_conditions_data:
Gunnar Millsb751f322017-06-06 15:14:11 -0500542 sys.exit("No zone_conditions YAML file but " +
Gunnar Millsee8a2812017-06-02 14:26:47 -0500543 "zone_conditions used in zone YAML")
544
545 condition = getConditionInZoneConditions(c['name'],
546 zone_conditions_data)
547
548 if not condition:
549 sys.exit("Missing zone condition " + c['name'])
550
551 conditions.append(condition)
Matt Spinler78498c92017-04-11 13:59:46 -0500552
553 zone_group = {}
554 zone_group['conditions'] = conditions
555
556 zones = []
557 for z in group['zones']:
558 zone = {}
559
Gunnar Mills67e95512017-06-02 14:35:18 -0500560 # 'zone' is required
561 if ('zone' not in z) or (z['zone'] is None):
Matt Spinler78498c92017-04-11 13:59:46 -0500562 sys.exit("Missing fan zone number in " + zone_yaml)
563
564 zone['num'] = z['zone']
565
566 zone['full_speed'] = z['full_speed']
567
Matthew Barth1de66622017-06-12 13:13:02 -0500568 zone['default_floor'] = z['default_floor']
569
Matthew Bartha9561842017-06-29 11:43:45 -0500570 # 'increase_delay' is optional (use 0 by default)
571 key = 'increase_delay'
572 zone[key] = z.setdefault(key, 0)
573
574 # 'decrease_interval' is optional (use 0 by default)
575 key = 'decrease_interval'
576 zone[key] = z.setdefault(key, 0)
577
Gunnar Mills67e95512017-06-02 14:35:18 -0500578 # 'cooling_profiles' is optional (use 'all' instead)
579 if ('cooling_profiles' not in z) or \
Matt Spinler78498c92017-04-11 13:59:46 -0500580 (z['cooling_profiles'] is None):
581 profiles = ["all"]
582 else:
583 profiles = z['cooling_profiles']
584
585 fans = getFansInZone(z['zone'], profiles, fan_data)
Gunnar Millsb751f322017-06-06 15:14:11 -0500586 events = getEventsInZone(z['zone'], group['zone_conditions'],
587 events_data)
Matt Spinler78498c92017-04-11 13:59:46 -0500588
589 if len(fans) == 0:
590 sys.exit("Didn't find any fans in zone " + str(zone['num']))
591
592 zone['fans'] = fans
Matthew Barthd4d0f082017-05-16 13:51:10 -0500593 zone['events'] = events
Matt Spinler78498c92017-04-11 13:59:46 -0500594 zones.append(zone)
595
596 zone_group['zones'] = zones
597 zone_groups.append(zone_group)
598
599 return zone_groups
600
601
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500602if __name__ == '__main__':
603 parser = ArgumentParser(
604 description="Phosphor fan zone definition parser")
605
606 parser.add_argument('-z', '--zone_yaml', dest='zone_yaml',
607 default="example/zones.yaml",
608 help='fan zone definitional yaml')
609 parser.add_argument('-f', '--fan_yaml', dest='fan_yaml',
610 default="example/fans.yaml",
611 help='fan definitional yaml')
Matthew Barthd4d0f082017-05-16 13:51:10 -0500612 parser.add_argument('-e', '--events_yaml', dest='events_yaml',
613 help='events to set speeds yaml')
Gunnar Millsee8a2812017-06-02 14:26:47 -0500614 parser.add_argument('-c', '--zone_conditions_yaml',
615 dest='zone_conditions_yaml',
616 help='conditions to determine zone yaml')
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500617 parser.add_argument('-o', '--output_dir', dest='output_dir',
618 default=".",
619 help='output directory')
620 args = parser.parse_args()
621
622 if not args.zone_yaml or not args.fan_yaml:
623 parser.print_usage()
624 sys.exit(-1)
625
626 with open(args.zone_yaml, 'r') as zone_input:
627 zone_data = yaml.safe_load(zone_input) or {}
628
629 with open(args.fan_yaml, 'r') as fan_input:
630 fan_data = yaml.safe_load(fan_input) or {}
631
Matthew Barthd4d0f082017-05-16 13:51:10 -0500632 events_data = {}
633 if args.events_yaml:
634 with open(args.events_yaml, 'r') as events_input:
635 events_data = yaml.safe_load(events_input) or {}
636
Gunnar Millsee8a2812017-06-02 14:26:47 -0500637 zone_conditions_data = {}
638 if args.zone_conditions_yaml:
639 with open(args.zone_conditions_yaml, 'r') as zone_conditions_input:
640 zone_conditions_data = yaml.safe_load(zone_conditions_input) or {}
641
Matt Spinleree7f6422017-05-09 11:03:14 -0500642 zone_config = buildZoneData(zone_data.get('zone_configuration', {}),
Gunnar Millsee8a2812017-06-02 14:26:47 -0500643 fan_data, events_data, zone_conditions_data)
Matt Spinleree7f6422017-05-09 11:03:14 -0500644
645 manager_config = zone_data.get('manager_configuration', {})
646
647 if manager_config.get('power_on_delay') is None:
648 manager_config['power_on_delay'] = 0
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500649
650 output_file = os.path.join(args.output_dir, "fan_zone_defs.cpp")
651 with open(output_file, 'w') as output:
Matt Spinleree7f6422017-05-09 11:03:14 -0500652 output.write(Template(tmpl).render(zones=zone_config,
653 mgr_data=manager_config))