blob: e5aa39b8dee39a1e388228cac9b9400b8f711065 [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
Matthew Barth702c4a52018-02-28 16:23:11 -060013from mako.lookup import TemplateLookup
Matt Spinlerd08dbe22017-04-11 13:52:54 -050014
Matt Spinler78498c92017-04-11 13:59:46 -050015
Matthew Barthbb12c922017-06-13 13:57:40 -050016def convertToMap(listOfDict):
17 """
18 Converts a list of dictionary entries to a std::map initialization list.
19 """
Matthew Barth9a5b6992018-01-23 15:32:26 -060020 listOfDict = listOfDict.replace('\'', '\"')
Matthew Barthbb12c922017-06-13 13:57:40 -050021 listOfDict = listOfDict.replace('[', '{')
22 listOfDict = listOfDict.replace(']', '}')
23 listOfDict = listOfDict.replace(':', ',')
24 return listOfDict
25
26
Matthew Barth6c050692017-12-05 15:30:09 -060027def getGroups(zNum, zCond, edata, events):
28 """
29 Extract and construct the groups for the given event.
30 """
31 groups = []
32 for eGroups in edata['groups']:
33 if ('zone_conditions' in eGroups) and \
34 (eGroups['zone_conditions'] is not None):
35 # Zone conditions are optional in the events yaml but skip
36 # if this event's condition is not in this zone's conditions
37 if all('name' in z and z['name'] is not None and
38 not any(c['name'] == z['name'] for c in zCond)
39 for z in eGroups['zone_conditions']):
40 continue
41
42 # Zone numbers are optional in the events yaml but skip if this
43 # zone's zone number is not in the event's zone numbers
44 if all('zones' in z and z['zones'] is not None and
45 zNum not in z['zones']
46 for z in eGroups['zone_conditions']):
47 continue
48
49 eGroup = next(g for g in events['groups']
50 if g['name'] == eGroups['name'])
51
52 group = {}
53 members = []
54 group['name'] = eGroup['name']
55 for m in eGroup['members']:
56 member = {}
57 member['path'] = eGroup['type']
58 member['object'] = (eGroup['type'] + m)
59 member['interface'] = eGroups['interface']
60 member['property'] = eGroups['property']['name']
61 member['type'] = eGroups['property']['type']
62 # Add expected group member's property value if given
63 if ('value' in eGroups['property']) and \
64 (eGroups['property']['value'] is not None):
65 if isinstance(eGroups['property']['value'], str) or \
66 "string" in str(member['type']).lower():
67 member['value'] = (
68 "\"" + eGroups['property']['value'] + "\"")
69 else:
70 member['value'] = eGroups['property']['value']
71 members.append(member)
72 group['members'] = members
73 groups.append(group)
74 return groups
75
76
Matthew Barth9df74752017-10-11 14:39:31 -050077def getActions(edata, actions, events):
78 """
79 Extracts and constructs the make_action function call for
80 all the actions within the given event.
81 """
82 action = []
83 for eActions in actions['actions']:
84 actions = {}
85 eAction = next(a for a in events['actions']
86 if a['name'] == eActions['name'])
87 actions['name'] = eAction['name']
88 params = []
89 if ('parameters' in eAction) and \
90 (eAction['parameters'] is not None):
91 for p in eAction['parameters']:
92 param = "static_cast<"
93 if type(eActions[p]) is not dict:
94 if p == 'actions':
95 param = "std::vector<Action>{"
96 pActs = getActions(edata, eActions, events)
97 for a in pActs:
98 if (len(a['parameters']) != 0):
99 param += (
100 "make_action(action::" +
101 a['name'] +
102 "(\n")
103 for i, ap in enumerate(a['parameters']):
104 if (i+1) != len(a['parameters']):
105 param += (ap + ",")
106 else:
107 param += (ap + ")")
108 else:
109 param += ("make_action(action::" + a['name'])
110 param += "),"
111 param += "}"
112 elif p == 'property':
Matthew Barth9a5b6992018-01-23 15:32:26 -0600113 if isinstance(eActions[p], str) or \
Matthew Barth6c050692017-12-05 15:30:09 -0600114 "string" in str(eActions[p]['type']).lower():
Matthew Barth9a5b6992018-01-23 15:32:26 -0600115 param += (
Matthew Barth6c050692017-12-05 15:30:09 -0600116 str(eActions[p]['type']).lower() +
Matthew Barth9a5b6992018-01-23 15:32:26 -0600117 ">(\"" + str(eActions[p]) + "\")")
118 else:
119 param += (
Matthew Barth6c050692017-12-05 15:30:09 -0600120 str(eActions[p]['type']).lower() +
121 ">(" + str(eActions[p]['value']).lower() + ")")
Matthew Barth9df74752017-10-11 14:39:31 -0500122 else:
123 # Default type to 'size_t' when not given
124 param += ("size_t>(" + str(eActions[p]).lower() + ")")
125 else:
126 if p == 'timer':
127 param = (
128 "Timer{static_cast<std::chrono::seconds>(" +
129 str(eActions[p]['delay']) + "), " +
130 "util::Timer::TimerType::" +
131 str(eActions[p]['type']) + "}")
132 else:
133 param += (str(eActions[p]['type']).lower() + ">(")
134 if p != 'map':
Matthew Barth9a5b6992018-01-23 15:32:26 -0600135 if isinstance(eActions[p]['value'], str) or \
136 "string" in str(eActions[p]['type']).lower():
137 param += \
138 "\"" + str(eActions[p]['value']) + "\")"
139 else:
140 param += \
141 str(eActions[p]['value']).lower() + ")"
Matthew Barth9df74752017-10-11 14:39:31 -0500142 else:
143 param += (
144 str(eActions[p]['type']).lower() +
145 convertToMap(str(eActions[p]['value'])) + ")")
146 params.append(param)
147 actions['parameters'] = params
148 action.append(actions)
149 return action
150
151
Matthew Barth7f272fd2017-09-12 16:16:56 -0500152def getEvent(zone_num, zone_conditions, e, events_data):
153 """
154 Parses the sections of an event and populates the properties
155 that construct an event within the generated source.
156 """
157 event = {}
Matthew Barth7f272fd2017-09-12 16:16:56 -0500158
Matthew Barth6c050692017-12-05 15:30:09 -0600159 # Add set speed event groups
160 grps = getGroups(zone_num, zone_conditions, e, events_data)
161 if not grps:
Matthew Barth7f272fd2017-09-12 16:16:56 -0500162 return
Matthew Barth6c050692017-12-05 15:30:09 -0600163 event['groups'] = grps
Matthew Barth7f272fd2017-09-12 16:16:56 -0500164
Matthew Barthe3d1c4a2018-01-11 13:53:49 -0600165 # Add optional set speed actions and function parameters
166 event['action'] = []
167 if ('actions' in e) and \
168 (e['actions'] is not None):
169 event['action'] = getActions(e, e, events_data)
Matthew Barth7f272fd2017-09-12 16:16:56 -0500170
Matthew Barth67967f92017-09-22 12:43:57 -0500171 # Add signal handlers
172 signals = []
Matthew Barth6c050692017-12-05 15:30:09 -0600173 for group in event['groups']:
174 for member in group['members']:
175 for eMatches in e['matches']:
176 signal = {}
177 eMatch = next(m for m in events_data['matches']
178 if m['name'] == eMatches['name'])
179 signal['match'] = eMatch['name']
180 params = []
181 if ('parameters' in eMatch) and \
182 (eMatch['parameters'] is not None):
183 for p in eMatch['parameters']:
184 params.append(member[str(p)])
185 signal['mparams'] = params
Matthew Barthe7d87052018-03-21 13:58:31 -0500186 if ('parameters' in eMatch['signal']) and \
187 (eMatch['signal']['parameters'] is not None):
188 eSignal = eMatch['signal']
189 else:
190 eSignal = next(s for s in events_data['signals']
191 if s['name'] == eMatch['signal'])
Matthew Barth6c050692017-12-05 15:30:09 -0600192 signal['signal'] = eSignal['name']
193 sparams = {}
194 if ('parameters' in eSignal) and \
195 (eSignal['parameters'] is not None):
196 splist = []
197 for p in eSignal['parameters']:
198 sp = str(p)
199 if (sp != 'type'):
200 splist.append(sp)
201 if (sp != 'group'):
202 sparams[sp] = "\"" + member[sp] + "\""
203 else:
204 sparams[sp] = "Group{\n"
205 for m in group['members']:
206 sparams[sp] += (
207 "{\n" +
208 "\"" + str(m['object']) + "\",\n" +
209 "{\"" + str(m['interface']) + "\"," +
210 "\"" + str(m['property']) + "\"}\n" +
211 "},\n")
212 sparams[sp] += "}"
Matthew Barth9f964bf2017-10-02 15:07:00 -0500213 else:
Matthew Barth6c050692017-12-05 15:30:09 -0600214 sparams[sp] = member[sp]
215 sparams['params'] = splist
216 signal['sparams'] = sparams
217 # Add signal handler
218 eHandler = next(h for h in events_data['handlers']
219 if h['name'] == eSignal['handler'])
220 signal['handler'] = eHandler['name']
221 hparams = {}
222 if ('parameters' in eHandler) and \
223 (eHandler['parameters'] is not None):
224 hplist = []
225 for p in eHandler['parameters']:
226 hp = str(p)
227 if (hp != 'type'):
228 hplist.append(hp)
229 if (hp != 'group'):
230 hparams[hp] = "\"" + member[hp] + "\""
231 else:
232 hparams[hp] = "Group{\n"
233 for m in group['members']:
234 hparams[hp] += (
235 "{\n" +
236 "\"" + str(m['object']) + "\",\n" +
237 "{\"" + str(m['interface']) + "\"," +
238 "\"" + str(m['property']) + "\"}\n" +
239 "},\n")
240 hparams[hp] += "}"
Matthew Barth9f964bf2017-10-02 15:07:00 -0500241 else:
Matthew Barth6c050692017-12-05 15:30:09 -0600242 hparams[hp] = member[hp]
243 hparams['params'] = hplist
244 signal['hparams'] = hparams
245 signals.append(signal)
Matthew Barth67967f92017-09-22 12:43:57 -0500246 event['signals'] = signals
Matthew Barth7f272fd2017-09-12 16:16:56 -0500247
248 # Add optional action call timer
249 timer = {}
250 interval = "static_cast<std::chrono::seconds>"
251 if ('timer' in e) and \
252 (e['timer'] is not None):
253 timer['interval'] = (interval +
254 "(" +
255 str(e['timer']['interval']) +
256 ")")
257 else:
258 timer['interval'] = (interval +
259 "(" + str(0) + ")")
Matthew Barth7b7ceb82017-10-04 12:59:50 -0500260 timer['type'] = "util::Timer::TimerType::repeating"
Matthew Barth7f272fd2017-09-12 16:16:56 -0500261 event['timer'] = timer
262
263 return event
264
265
266def addPrecondition(zNum, zCond, event, events_data):
Matthew Barth9af190c2017-08-08 14:20:43 -0500267 """
268 Parses the precondition section of an event and populates the necessary
269 structures to generate a precondition for a set speed event.
270 """
271 precond = {}
272 # Add set speed event precondition group
Matthew Barth6c050692017-12-05 15:30:09 -0600273 grps = getGroups(zNum, zCond, event['precondition'], events_data)
274 if not grps:
275 return
276 precond['pcgrps'] = grps
Matthew Barth9af190c2017-08-08 14:20:43 -0500277
Matthew Barth7f272fd2017-09-12 16:16:56 -0500278 # Add set speed event precondition actions
279 pc = []
280 pcs = {}
281 pcs['name'] = event['precondition']['name']
282 epc = next(p for p in events_data['preconditions']
Matthew Barth9af190c2017-08-08 14:20:43 -0500283 if p['name'] == event['precondition']['name'])
284 params = []
Matthew Barth7f272fd2017-09-12 16:16:56 -0500285 for p in epc['parameters']:
Matthew Barth9af190c2017-08-08 14:20:43 -0500286 param = {}
287 if p == 'groups':
288 param['type'] = "std::vector<PrecondGroup>"
289 param['open'] = "{"
290 param['close'] = "}"
291 values = []
Matthew Barth6c050692017-12-05 15:30:09 -0600292 for group in precond['pcgrps']:
293 for pcgrp in group['members']:
294 value = {}
295 value['value'] = (
296 "PrecondGroup{\"" +
297 str(pcgrp['object']) + "\",\"" +
298 str(pcgrp['interface']) + "\",\"" +
299 str(pcgrp['property']) + "\"," +
300 "static_cast<" +
301 str(pcgrp['type']).lower() + ">")
302 if isinstance(pcgrp['value'], str) or \
303 "string" in str(pcgrp['type']).lower():
304 value['value'] += ("(" + str(pcgrp['value']) + ")}")
305 else:
306 value['value'] += \
307 ("(" + str(pcgrp['value']).lower() + ")}")
308 values.append(value)
Matthew Barth9af190c2017-08-08 14:20:43 -0500309 param['values'] = values
310 params.append(param)
Matthew Barth7f272fd2017-09-12 16:16:56 -0500311 pcs['params'] = params
312 pc.append(pcs)
Matthew Barth9af190c2017-08-08 14:20:43 -0500313 precond['pcact'] = pc
314
Matthew Barth7f272fd2017-09-12 16:16:56 -0500315 pcevents = []
316 for pce in event['precondition']['events']:
317 pcevent = getEvent(zNum, zCond, pce, events_data)
318 if not pcevent:
319 continue
320 pcevents.append(pcevent)
321 precond['pcevts'] = pcevents
322
Matthew Barth67967f92017-09-22 12:43:57 -0500323 # Add precondition signal handlers
324 signals = []
Matthew Barth6c050692017-12-05 15:30:09 -0600325 for group in precond['pcgrps']:
326 for member in group['members']:
327 for eMatches in event['precondition']['matches']:
328 signal = {}
329 eMatch = next(m for m in events_data['matches']
330 if m['name'] == eMatches['name'])
331 signal['match'] = eMatch['name']
332 params = []
333 if ('parameters' in eMatch) and \
334 (eMatch['parameters'] is not None):
335 for p in eMatch['parameters']:
336 params.append(member[str(p)])
337 signal['mparams'] = params
Matthew Barthe7d87052018-03-21 13:58:31 -0500338 if ('parameters' in eMatch['signal']) and \
339 (eMatch['signal']['parameters'] is not None):
340 eSignal = eMatch['signal']
341 else:
342 eSignal = next(s for s in events_data['signals']
343 if s['name'] == eMatch['signal'])
Matthew Barth6c050692017-12-05 15:30:09 -0600344 signal['signal'] = eSignal['name']
345 sparams = {}
346 if ('parameters' in eSignal) and \
347 (eSignal['parameters'] is not None):
348 splist = []
349 for p in eSignal['parameters']:
350 sp = str(p)
351 if (sp != 'type'):
352 splist.append(sp)
353 if (sp != 'group'):
354 sparams[sp] = "\"" + member[sp] + "\""
355 else:
356 sparams[sp] = "Group{\n"
357 for m in group:
358 sparams[sp] += (
359 "{\n" +
360 "\"" + str(m['object']) + "\",\n" +
361 "{\"" + str(m['interface']) + "\"," +
362 "\"" + str(m['property']) + "\"}\n" +
363 "},\n")
364 sparams[sp] += "}"
Matthew Barth9f964bf2017-10-02 15:07:00 -0500365 else:
Matthew Barth6c050692017-12-05 15:30:09 -0600366 sparams[sp] = member[sp]
367 sparams['params'] = splist
368 signal['sparams'] = sparams
369 # Add signal handler
370 eHandler = next(h for h in events_data['handlers']
371 if h['name'] == eSignal['handler'])
372 signal['handler'] = eHandler['name']
373 hparams = {}
374 if ('parameters' in eHandler) and \
375 (eHandler['parameters'] is not None):
376 hplist = []
377 for p in eHandler['parameters']:
378 hp = str(p)
379 if (hp != 'type'):
380 hplist.append(hp)
381 if (hp != 'group'):
382 hparams[hp] = "\"" + member[hp] + "\""
383 else:
384 hparams[hp] = "Group{\n"
385 for m in group:
386 hparams[hp] += (
387 "{\n" +
388 "\"" + str(m['object']) + "\",\n" +
389 "{\"" + str(m['interface']) + "\"," +
390 "\"" + str(m['property']) + "\"}\n" +
391 "},\n")
392 hparams[hp] += "}"
Matthew Barth9f964bf2017-10-02 15:07:00 -0500393 else:
Matthew Barth6c050692017-12-05 15:30:09 -0600394 hparams[hp] = member[hp]
395 hparams['params'] = hplist
396 signal['hparams'] = hparams
397 signals.append(signal)
Matthew Barth67967f92017-09-22 12:43:57 -0500398 precond['pcsigs'] = signals
Matthew Barth9af190c2017-08-08 14:20:43 -0500399
Matthew Barth90149802017-08-15 10:51:37 -0500400 # Add optional action call timer
401 timer = {}
402 interval = "static_cast<std::chrono::seconds>"
403 if ('timer' in event['precondition']) and \
404 (event['precondition']['timer'] is not None):
405 timer['interval'] = (interval +
406 "(" +
407 str(event['precondition']['timer']['interval']) +
408 ")")
409 else:
410 timer['interval'] = (interval +
411 "(" + str(0) + ")")
Matthew Barth7b7ceb82017-10-04 12:59:50 -0500412 timer['type'] = "util::Timer::TimerType::repeating"
Matthew Barth90149802017-08-15 10:51:37 -0500413 precond['pctime'] = timer
414
Matthew Barth9af190c2017-08-08 14:20:43 -0500415 return precond
416
417
Gunnar Millsb751f322017-06-06 15:14:11 -0500418def getEventsInZone(zone_num, zone_conditions, events_data):
Matthew Barthd4d0f082017-05-16 13:51:10 -0500419 """
420 Constructs the event entries defined for each zone using the events yaml
421 provided.
422 """
423 events = []
Matthew Barthba102b32017-05-16 16:13:56 -0500424
Matthew Barthd4d0f082017-05-16 13:51:10 -0500425 if 'events' in events_data:
426 for e in events_data['events']:
Matthew Barthd4d0f082017-05-16 13:51:10 -0500427 event = {}
Matthew Barth9af190c2017-08-08 14:20:43 -0500428 # Add precondition if given
429 if ('precondition' in e) and \
430 (e['precondition'] is not None):
Matthew Barth7f272fd2017-09-12 16:16:56 -0500431 event['pc'] = addPrecondition(zone_num,
432 zone_conditions,
433 e,
434 events_data)
Matthew Barth90149802017-08-15 10:51:37 -0500435 else:
Matthew Barth7f272fd2017-09-12 16:16:56 -0500436 event = getEvent(zone_num, zone_conditions, e, events_data)
437 if not event:
438 continue
Matthew Barthd4d0f082017-05-16 13:51:10 -0500439 events.append(event)
440
441 return events
442
443
Matt Spinler78498c92017-04-11 13:59:46 -0500444def getFansInZone(zone_num, profiles, fan_data):
445 """
446 Parses the fan definition YAML files to find the fans
447 that match both the zone passed in and one of the
448 cooling profiles.
449 """
450
451 fans = []
452
453 for f in fan_data['fans']:
454
455 if zone_num != f['cooling_zone']:
456 continue
457
Gunnar Mills67e95512017-06-02 14:35:18 -0500458 # 'cooling_profile' is optional (use 'all' instead)
Matt Spinler78498c92017-04-11 13:59:46 -0500459 if f.get('cooling_profile') is None:
460 profile = "all"
461 else:
462 profile = f['cooling_profile']
463
464 if profile not in profiles:
465 continue
466
467 fan = {}
468 fan['name'] = f['inventory']
469 fan['sensors'] = f['sensors']
Lei YU069e4402018-01-31 16:47:37 +0800470 fan['target_interface'] = f.get(
471 'target_interface',
472 'xyz.openbmc_project.Control.FanSpeed')
Matt Spinler78498c92017-04-11 13:59:46 -0500473 fans.append(fan)
474
475 return fans
476
477
Gunnar Millsee8a2812017-06-02 14:26:47 -0500478def getConditionInZoneConditions(zone_condition, zone_conditions_data):
479 """
480 Parses the zone conditions definition YAML files to find the condition
481 that match both the zone condition passed in.
482 """
483
484 condition = {}
485
486 for c in zone_conditions_data['conditions']:
487
488 if zone_condition != c['name']:
489 continue
490 condition['type'] = c['type']
491 properties = []
492 for p in c['properties']:
493 property = {}
494 property['property'] = p['property']
495 property['interface'] = p['interface']
496 property['path'] = p['path']
497 property['type'] = p['type'].lower()
498 property['value'] = str(p['value']).lower()
499 properties.append(property)
500 condition['properties'] = properties
501
502 return condition
503
504
505def buildZoneData(zone_data, fan_data, events_data, zone_conditions_data):
Matt Spinler78498c92017-04-11 13:59:46 -0500506 """
507 Combines the zone definition YAML and fan
508 definition YAML to create a data structure defining
509 the fan cooling zones.
510 """
511
512 zone_groups = []
513
514 for group in zone_data:
515 conditions = []
Gunnar Millsee8a2812017-06-02 14:26:47 -0500516 # zone conditions are optional
517 if 'zone_conditions' in group and group['zone_conditions'] is not None:
518 for c in group['zone_conditions']:
519
520 if not zone_conditions_data:
Gunnar Millsb751f322017-06-06 15:14:11 -0500521 sys.exit("No zone_conditions YAML file but " +
Gunnar Millsee8a2812017-06-02 14:26:47 -0500522 "zone_conditions used in zone YAML")
523
524 condition = getConditionInZoneConditions(c['name'],
525 zone_conditions_data)
526
527 if not condition:
528 sys.exit("Missing zone condition " + c['name'])
529
530 conditions.append(condition)
Matt Spinler78498c92017-04-11 13:59:46 -0500531
532 zone_group = {}
533 zone_group['conditions'] = conditions
534
535 zones = []
536 for z in group['zones']:
537 zone = {}
538
Gunnar Mills67e95512017-06-02 14:35:18 -0500539 # 'zone' is required
540 if ('zone' not in z) or (z['zone'] is None):
Matt Spinler78498c92017-04-11 13:59:46 -0500541 sys.exit("Missing fan zone number in " + zone_yaml)
542
543 zone['num'] = z['zone']
544
545 zone['full_speed'] = z['full_speed']
546
Matthew Barth1de66622017-06-12 13:13:02 -0500547 zone['default_floor'] = z['default_floor']
548
Matthew Bartha9561842017-06-29 11:43:45 -0500549 # 'increase_delay' is optional (use 0 by default)
550 key = 'increase_delay'
551 zone[key] = z.setdefault(key, 0)
552
553 # 'decrease_interval' is optional (use 0 by default)
554 key = 'decrease_interval'
555 zone[key] = z.setdefault(key, 0)
556
Gunnar Mills67e95512017-06-02 14:35:18 -0500557 # 'cooling_profiles' is optional (use 'all' instead)
558 if ('cooling_profiles' not in z) or \
Matt Spinler78498c92017-04-11 13:59:46 -0500559 (z['cooling_profiles'] is None):
560 profiles = ["all"]
561 else:
562 profiles = z['cooling_profiles']
563
564 fans = getFansInZone(z['zone'], profiles, fan_data)
Gunnar Millsb751f322017-06-06 15:14:11 -0500565 events = getEventsInZone(z['zone'], group['zone_conditions'],
566 events_data)
Matt Spinler78498c92017-04-11 13:59:46 -0500567
568 if len(fans) == 0:
569 sys.exit("Didn't find any fans in zone " + str(zone['num']))
570
571 zone['fans'] = fans
Matthew Barthd4d0f082017-05-16 13:51:10 -0500572 zone['events'] = events
Matt Spinler78498c92017-04-11 13:59:46 -0500573 zones.append(zone)
574
575 zone_group['zones'] = zones
576 zone_groups.append(zone_group)
577
578 return zone_groups
579
580
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500581if __name__ == '__main__':
582 parser = ArgumentParser(
583 description="Phosphor fan zone definition parser")
584
585 parser.add_argument('-z', '--zone_yaml', dest='zone_yaml',
586 default="example/zones.yaml",
587 help='fan zone definitional yaml')
588 parser.add_argument('-f', '--fan_yaml', dest='fan_yaml',
589 default="example/fans.yaml",
590 help='fan definitional yaml')
Matthew Barthd4d0f082017-05-16 13:51:10 -0500591 parser.add_argument('-e', '--events_yaml', dest='events_yaml',
592 help='events to set speeds yaml')
Gunnar Millsee8a2812017-06-02 14:26:47 -0500593 parser.add_argument('-c', '--zone_conditions_yaml',
594 dest='zone_conditions_yaml',
595 help='conditions to determine zone yaml')
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500596 parser.add_argument('-o', '--output_dir', dest='output_dir',
597 default=".",
598 help='output directory')
599 args = parser.parse_args()
600
601 if not args.zone_yaml or not args.fan_yaml:
602 parser.print_usage()
William A. Kennington III3e781062018-10-19 17:18:34 -0700603 sys.exit(1)
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500604
605 with open(args.zone_yaml, 'r') as zone_input:
606 zone_data = yaml.safe_load(zone_input) or {}
607
608 with open(args.fan_yaml, 'r') as fan_input:
609 fan_data = yaml.safe_load(fan_input) or {}
610
Matthew Barthd4d0f082017-05-16 13:51:10 -0500611 events_data = {}
612 if args.events_yaml:
613 with open(args.events_yaml, 'r') as events_input:
614 events_data = yaml.safe_load(events_input) or {}
615
Gunnar Millsee8a2812017-06-02 14:26:47 -0500616 zone_conditions_data = {}
617 if args.zone_conditions_yaml:
618 with open(args.zone_conditions_yaml, 'r') as zone_conditions_input:
619 zone_conditions_data = yaml.safe_load(zone_conditions_input) or {}
620
Matt Spinleree7f6422017-05-09 11:03:14 -0500621 zone_config = buildZoneData(zone_data.get('zone_configuration', {}),
Gunnar Millsee8a2812017-06-02 14:26:47 -0500622 fan_data, events_data, zone_conditions_data)
Matt Spinleree7f6422017-05-09 11:03:14 -0500623
624 manager_config = zone_data.get('manager_configuration', {})
625
626 if manager_config.get('power_on_delay') is None:
627 manager_config['power_on_delay'] = 0
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500628
Matthew Barth702c4a52018-02-28 16:23:11 -0600629 tmpls_dir = os.path.join(
630 os.path.dirname(os.path.realpath(__file__)),
631 "templates")
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500632 output_file = os.path.join(args.output_dir, "fan_zone_defs.cpp")
Matthew Barth702c4a52018-02-28 16:23:11 -0600633 if sys.version_info < (3, 0):
634 lkup = TemplateLookup(
635 directories=tmpls_dir.split(),
636 disable_unicode=True)
637 else:
638 lkup = TemplateLookup(
639 directories=tmpls_dir.split())
640 tmpl = lkup.get_template('fan_zone_defs.mako.cpp')
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500641 with open(output_file, 'w') as output:
Matthew Barth702c4a52018-02-28 16:23:11 -0600642 output.write(tmpl.render(zones=zone_config,
643 mgr_data=manager_config))