blob: 061c3141acafd4b281af910b53770b4c55807754 [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 Barth336f18a2017-09-26 09:15:56 -050014tmpl = '''\
Matthew Barth7f272fd2017-09-12 16:16:56 -050015<%!
16def indent(str, depth):
17 return ''.join(4*' '*depth+line for line in str.splitlines(True))
Matthew Barth336f18a2017-09-26 09:15:56 -050018%>\
Matthew Barth7f272fd2017-09-12 16:16:56 -050019<%def name="genSSE(event)" buffered="True">
20Group{
21%for member in event['group']:
22{
Matthew Barth67967f92017-09-22 12:43:57 -050023 "${member['object']}",
Matthew Barth7f272fd2017-09-12 16:16:56 -050024 {"${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},
Matthew Barth67967f92017-09-22 12:43:57 -050049std::vector<Signal>{
50%for s in event['signals']:
51 Signal{
Matthew Barth336f18a2017-09-26 09:15:56 -050052 match::${s['match']}(
Matthew Barth67967f92017-09-22 12:43:57 -050053 %for i, mp in enumerate(s['mparams']):
54 %if (i+1) != len(s['mparams']):
55 "${mp}",
56 %else:
57 "${mp}"
58 %endif
59 %endfor
60 ),
61 make_handler(
62 %if ('type' in s['sparams']) and \
63 (s['sparams']['type'] is not None):
64 ${s['signal']}<${s['sparams']['type']}>(
65 %else:
66 ${s['signal']}(
67 %endif
68 %for spk, spv in s['sparams'].iteritems():
69 %if spk != 'type':
70 "${spv}",
71 %endif
72 %endfor
Matthew Barth7f272fd2017-09-12 16:16:56 -050073 handler::setProperty<${s['type']}>(
Matthew Barth67967f92017-09-22 12:43:57 -050074 "${s['object']}",
Matthew Barth7f272fd2017-09-12 16:16:56 -050075 "${s['interface']}",
76 "${s['property']}"
77 )
78 ))
79 },
80%endfor
81}
Matthew Barth336f18a2017-09-26 09:15:56 -050082</%def>\
Matthew Barth7f272fd2017-09-12 16:16:56 -050083/* This is a generated file. */
Matt Spinlerd08dbe22017-04-11 13:52:54 -050084#include "manager.hpp"
Matthew Barthba102b32017-05-16 16:13:56 -050085#include "functor.hpp"
86#include "actions.hpp"
Matthew Barth7e527c12017-05-17 10:14:15 -050087#include "handlers.hpp"
Matthew Barth9af190c2017-08-08 14:20:43 -050088#include "preconditions.hpp"
Matthew Barth336f18a2017-09-26 09:15:56 -050089#include "matches.hpp"
Matt Spinlerd08dbe22017-04-11 13:52:54 -050090
91using namespace phosphor::fan::control;
92
Matt Spinleree7f6422017-05-09 11:03:14 -050093const unsigned int Manager::_powerOnDelay{${mgr_data['power_on_delay']}};
94
Matt Spinlerd08dbe22017-04-11 13:52:54 -050095const std::vector<ZoneGroup> Manager::_zoneLayouts
96{
97%for zone_group in zones:
Matthew Barth9c726672017-05-18 13:44:46 -050098 ZoneGroup{
Gunnar Millsee8a2812017-06-02 14:26:47 -050099 std::vector<Condition>{
100 %for condition in zone_group['conditions']:
101 Condition{
102 "${condition['type']}",
103 std::vector<ConditionProperty>{
104 %for property in condition['properties']:
105 ConditionProperty{
106 "${property['property']}",
107 "${property['interface']}",
108 "${property['path']}",
109 static_cast<${property['type']}>(${property['value']}),
110 },
111 %endfor
112 },
113 },
114 %endfor
115 },
Matthew Barth9c726672017-05-18 13:44:46 -0500116 std::vector<ZoneDefinition>{
117 %for zone in zone_group['zones']:
118 ZoneDefinition{
119 ${zone['num']},
120 ${zone['full_speed']},
Matthew Barth1de66622017-06-12 13:13:02 -0500121 ${zone['default_floor']},
Matthew Bartha9561842017-06-29 11:43:45 -0500122 ${zone['increase_delay']},
123 ${zone['decrease_interval']},
Matthew Barth9c726672017-05-18 13:44:46 -0500124 std::vector<FanDefinition>{
125 %for fan in zone['fans']:
126 FanDefinition{
127 "${fan['name']}",
128 std::vector<std::string>{
129 %for sensor in fan['sensors']:
130 "${sensor}",
131 %endfor
132 }
133 },
134 %endfor
135 },
136 std::vector<SetSpeedEvent>{
137 %for event in zone['events']:
Matthew Barth9af190c2017-08-08 14:20:43 -0500138 %if ('pc' in event) and \
139 (event['pc'] is not None):
140 SetSpeedEvent{
141 Group{
142 %for member in event['pc']['pcgrp']:
143 {
Matthew Barth67967f92017-09-22 12:43:57 -0500144 "${member['object']}",
Matthew Barth9af190c2017-08-08 14:20:43 -0500145 {"${member['interface']}",
146 "${member['property']}"}
147 },
148 %endfor
149 },
Matthew Barth7f272fd2017-09-12 16:16:56 -0500150 std::vector<Action>{
151 %for i, a in enumerate(event['pc']['pcact']):
Matthew Barth4c04a012017-09-15 13:05:30 -0500152 %if len(a['params']) != 0:
Matthew Barth9af190c2017-08-08 14:20:43 -0500153 make_action(
Matthew Barth7f272fd2017-09-12 16:16:56 -0500154 precondition::${a['name']}(
Matthew Barth4c04a012017-09-15 13:05:30 -0500155 %else:
156 make_action(
157 precondition::${a['name']}
158 %endif
Matthew Barth7f272fd2017-09-12 16:16:56 -0500159 %for p in a['params']:
Matthew Barth9af190c2017-08-08 14:20:43 -0500160 ${p['type']}${p['open']}
161 %for j, v in enumerate(p['values']):
162 %if (j+1) != len(p['values']):
163 ${v['value']},
164 %else:
165 ${v['value']}
166 %endif
167 %endfor
168 ${p['close']},
169 %endfor
Matthew Barth7f272fd2017-09-12 16:16:56 -0500170 %if (i+1) != len(event['pc']['pcact']):
Matthew Barth4c04a012017-09-15 13:05:30 -0500171 %if len(a['params']) != 0:
Matthew Barth7f272fd2017-09-12 16:16:56 -0500172 )),
Matthew Barth4c04a012017-09-15 13:05:30 -0500173 %else:
174 ),
175 %endif
Matthew Barth9c726672017-05-18 13:44:46 -0500176 %endif
177 %endfor
Matthew Barth7f272fd2017-09-12 16:16:56 -0500178 std::vector<SetSpeedEvent>{
179 %for pcevt in event['pc']['pcevts']:
180 SetSpeedEvent{\
181 ${indent(genSSE(event=pcevt), 6)}\
182 },
183 %endfor
184 %else:
185 SetSpeedEvent{\
186 ${indent(genSSE(event=event), 6)}
187 %endif
Matthew Barth9af190c2017-08-08 14:20:43 -0500188 %if ('pc' in event) and (event['pc'] is not None):
189 }
Matthew Barth4c04a012017-09-15 13:05:30 -0500190 %if len(event['pc']['pcact'][-1]['params']) != 0:
Matthew Barth9af190c2017-08-08 14:20:43 -0500191 )),
Matthew Barth4c04a012017-09-15 13:05:30 -0500192 %else:
193 ),
194 %endif
Matthew Barth7f272fd2017-09-12 16:16:56 -0500195 },
Matthew Barth90149802017-08-15 10:51:37 -0500196 Timer{
197 ${event['pc']['pctime']['interval']}
198 },
Matthew Barth67967f92017-09-22 12:43:57 -0500199 std::vector<Signal>{
200 %for s in event['pc']['pcsigs']:
201 Signal{
Matthew Barth336f18a2017-09-26 09:15:56 -0500202 match::${s['match']}(
Matthew Barth67967f92017-09-22 12:43:57 -0500203 %for i, mp in enumerate(s['mparams']):
204 %if (i+1) != len(s['mparams']):
205 "${mp}",
206 %else:
207 "${mp}"
208 %endif
209 %endfor
210 ),
211 make_handler(
212 %if ('type' in s['sparams']) and \
213 (s['sparams']['type'] is not None):
214 ${s['signal']}<${s['sparams']['type']}>(
215 %else:
216 ${s['signal']}(
217 %endif
218 %for spk, spv in s['sparams'].iteritems():
219 %if spk != 'type':
220 "${spv}",
221 %endif
222 %endfor
Matthew Barth9af190c2017-08-08 14:20:43 -0500223 handler::setProperty<${s['type']}>(
Matthew Barth67967f92017-09-22 12:43:57 -0500224 "${s['object']}",
Matthew Barth9af190c2017-08-08 14:20:43 -0500225 "${s['interface']}",
226 "${s['property']}"
227 )
228 ))
229 },
230 %endfor
231 }
232 %endif
Matthew Barth9c726672017-05-18 13:44:46 -0500233 },
234 %endfor
235 }
236 },
237 %endfor
238 }
Matt Spinler78498c92017-04-11 13:59:46 -0500239 },
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500240%endfor
241};
242'''
243
Matt Spinler78498c92017-04-11 13:59:46 -0500244
Matthew Barthbb12c922017-06-13 13:57:40 -0500245def convertToMap(listOfDict):
246 """
247 Converts a list of dictionary entries to a std::map initialization list.
248 """
249 listOfDict = listOfDict.replace('[', '{')
250 listOfDict = listOfDict.replace(']', '}')
251 listOfDict = listOfDict.replace(':', ',')
252 return listOfDict
253
254
Matthew Barth7f272fd2017-09-12 16:16:56 -0500255def getEvent(zone_num, zone_conditions, e, events_data):
256 """
257 Parses the sections of an event and populates the properties
258 that construct an event within the generated source.
259 """
260 event = {}
261 # Zone numbers are optional in the events yaml but skip if this
262 # zone's zone number is not in the event's zone numbers
263 if all('zones' in z and
264 z['zones'] is not None and
265 zone_num not in z['zones']
266 for z in e['zone_conditions']):
267 return
268
269 # Zone conditions are optional in the events yaml but skip
270 # if this event's condition is not in this zone's conditions
271 if all('name' in z and z['name'] is not None and
272 not any(c['name'] == z['name'] for c in zone_conditions)
273 for z in e['zone_conditions']):
274 return
275
276 # Add set speed event group
277 group = []
278 groups = next(g for g in events_data['groups']
279 if g['name'] == e['group'])
280 for member in groups['members']:
281 members = {}
Matthew Barth67967f92017-09-22 12:43:57 -0500282 members['object'] = (groups['type'] +
283 member)
Matthew Barth7f272fd2017-09-12 16:16:56 -0500284 members['interface'] = e['interface']
285 members['property'] = e['property']['name']
Matthew Barth67967f92017-09-22 12:43:57 -0500286 members['type'] = e['property']['type']
Matthew Barth7f272fd2017-09-12 16:16:56 -0500287 group.append(members)
288 event['group'] = group
289
290 # Add set speed actions and function parameters
291 action = []
292 for eActions in e['actions']:
293 actions = {}
294 eAction = next(a for a in events_data['actions']
295 if a['name'] == eActions['name'])
296 actions['name'] = eAction['name']
297 params = []
Matthew Barth4c04a012017-09-15 13:05:30 -0500298 if ('parameters' in eAction) and \
299 (eAction['parameters'] is not None):
300 for p in eAction['parameters']:
301 param = {}
302 if type(eActions[p]) is not dict:
303 if p == 'property':
304 param['value'] = str(eActions[p]).lower()
305 param['type'] = str(
306 e['property']['type']).lower()
307 else:
308 # Default type to 'size_t' when not given
309 param['value'] = str(eActions[p]).lower()
310 param['type'] = 'size_t'
311 params.append(param)
Matthew Barth7f272fd2017-09-12 16:16:56 -0500312 else:
Matthew Barth4c04a012017-09-15 13:05:30 -0500313 param['type'] = str(eActions[p]['type']).lower()
314 if p != 'map':
315 param['value'] = str(
316 eActions[p]['value']).lower()
317 else:
318 emap = convertToMap(str(eActions[p]['value']))
319 param['value'] = param['type'] + emap
320 params.append(param)
Matthew Barth7f272fd2017-09-12 16:16:56 -0500321 actions['parameters'] = params
322 action.append(actions)
323 event['action'] = action
324
Matthew Barth67967f92017-09-22 12:43:57 -0500325 # Add signal handlers
326 signals = []
327 for member in group:
328 for eMatches in e['matches']:
329 signal = {}
330 eMatch = next(m for m in events_data['matches']
331 if m['name'] == eMatches['name'])
332 signal['match'] = eMatch['name']
333 params = []
334 if ('parameters' in eMatch) and \
335 (eMatch['parameters'] is not None):
336 for p in eMatch['parameters']:
337 params.append(member[str(p)])
338 signal['mparams'] = params
339 eSignal = next(s for s in events_data['signals']
340 if s['name'] == eMatch['signal'])
341 signal['signal'] = eSignal['name']
342 sparams = {}
343 if ('parameters' in eSignal) and \
344 (eSignal['parameters'] is not None):
345 for p in eSignal['parameters']:
346 sparams[str(p)] = member[str(p)]
347 signal['sparams'] = sparams
348 # Add member attributes
349 signal['object'] = member['object']
350 signal['interface'] = member['interface']
351 signal['property'] = member['property']
352 signal['type'] = member['type']
353 signals.append(signal)
354 event['signals'] = signals
Matthew Barth7f272fd2017-09-12 16:16:56 -0500355
356 # Add optional action call timer
357 timer = {}
358 interval = "static_cast<std::chrono::seconds>"
359 if ('timer' in e) and \
360 (e['timer'] is not None):
361 timer['interval'] = (interval +
362 "(" +
363 str(e['timer']['interval']) +
364 ")")
365 else:
366 timer['interval'] = (interval +
367 "(" + str(0) + ")")
368 event['timer'] = timer
369
370 return event
371
372
373def addPrecondition(zNum, zCond, event, events_data):
Matthew Barth9af190c2017-08-08 14:20:43 -0500374 """
375 Parses the precondition section of an event and populates the necessary
376 structures to generate a precondition for a set speed event.
377 """
378 precond = {}
379 # Add set speed event precondition group
380 group = []
381 for grp in event['precondition']['groups']:
382 groups = next(g for g in events_data['groups']
383 if g['name'] == grp['name'])
384 for member in groups['members']:
385 members = {}
Matthew Barth67967f92017-09-22 12:43:57 -0500386 members['object'] = (groups['type'] +
387 member)
Matthew Barth9af190c2017-08-08 14:20:43 -0500388 members['interface'] = grp['interface']
389 members['property'] = grp['property']['name']
390 members['type'] = grp['property']['type']
391 members['value'] = grp['property']['value']
392 group.append(members)
393 precond['pcgrp'] = group
394
Matthew Barth7f272fd2017-09-12 16:16:56 -0500395 # Add set speed event precondition actions
396 pc = []
397 pcs = {}
398 pcs['name'] = event['precondition']['name']
399 epc = next(p for p in events_data['preconditions']
Matthew Barth9af190c2017-08-08 14:20:43 -0500400 if p['name'] == event['precondition']['name'])
401 params = []
Matthew Barth7f272fd2017-09-12 16:16:56 -0500402 for p in epc['parameters']:
Matthew Barth9af190c2017-08-08 14:20:43 -0500403 param = {}
404 if p == 'groups':
405 param['type'] = "std::vector<PrecondGroup>"
406 param['open'] = "{"
407 param['close'] = "}"
408 values = []
409 for pcgrp in group:
410 value = {}
411 value['value'] = (
412 "PrecondGroup{\"" +
Matthew Barth67967f92017-09-22 12:43:57 -0500413 str(pcgrp['object']) + "\",\"" +
Matthew Barth9af190c2017-08-08 14:20:43 -0500414 str(pcgrp['interface']) + "\",\"" +
415 str(pcgrp['property']) + "\"," +
416 "static_cast<" +
417 str(pcgrp['type']).lower() + ">" +
418 "(" + str(pcgrp['value']).lower() + ")}")
419 values.append(value)
420 param['values'] = values
421 params.append(param)
Matthew Barth7f272fd2017-09-12 16:16:56 -0500422 pcs['params'] = params
423 pc.append(pcs)
Matthew Barth9af190c2017-08-08 14:20:43 -0500424 precond['pcact'] = pc
425
Matthew Barth7f272fd2017-09-12 16:16:56 -0500426 pcevents = []
427 for pce in event['precondition']['events']:
428 pcevent = getEvent(zNum, zCond, pce, events_data)
429 if not pcevent:
430 continue
431 pcevents.append(pcevent)
432 precond['pcevts'] = pcevents
433
Matthew Barth67967f92017-09-22 12:43:57 -0500434 # Add precondition signal handlers
435 signals = []
Matthew Barth9af190c2017-08-08 14:20:43 -0500436 for member in group:
Matthew Barth67967f92017-09-22 12:43:57 -0500437 for eMatches in event['precondition']['matches']:
438 signal = {}
439 eMatch = next(m for m in events_data['matches']
440 if m['name'] == eMatches['name'])
441 signal['match'] = eMatch['name']
442 params = []
443 if ('parameters' in eMatch) and \
444 (eMatch['parameters'] is not None):
445 for p in eMatch['parameters']:
446 params.append(member[str(p)])
447 signal['mparams'] = params
448 eSignal = next(s for s in events_data['signals']
449 if s['name'] == eMatch['signal'])
450 signal['signal'] = eSignal['name']
451 sparams = {}
452 if ('parameters' in eSignal) and \
453 (eSignal['parameters'] is not None):
454 for p in eSignal['parameters']:
455 sparams[str(p)] = member[str(p)]
456 signal['sparams'] = sparams
457 # Add member attributes
458 signal['object'] = member['object']
459 signal['interface'] = member['interface']
460 signal['property'] = member['property']
461 signal['type'] = member['type']
462 signals.append(signal)
463 precond['pcsigs'] = signals
Matthew Barth9af190c2017-08-08 14:20:43 -0500464
Matthew Barth90149802017-08-15 10:51:37 -0500465 # Add optional action call timer
466 timer = {}
467 interval = "static_cast<std::chrono::seconds>"
468 if ('timer' in event['precondition']) and \
469 (event['precondition']['timer'] is not None):
470 timer['interval'] = (interval +
471 "(" +
472 str(event['precondition']['timer']['interval']) +
473 ")")
474 else:
475 timer['interval'] = (interval +
476 "(" + str(0) + ")")
477 precond['pctime'] = timer
478
Matthew Barth9af190c2017-08-08 14:20:43 -0500479 return precond
480
481
Gunnar Millsb751f322017-06-06 15:14:11 -0500482def getEventsInZone(zone_num, zone_conditions, events_data):
Matthew Barthd4d0f082017-05-16 13:51:10 -0500483 """
484 Constructs the event entries defined for each zone using the events yaml
485 provided.
486 """
487 events = []
Matthew Barthba102b32017-05-16 16:13:56 -0500488
Matthew Barthd4d0f082017-05-16 13:51:10 -0500489 if 'events' in events_data:
490 for e in events_data['events']:
Matthew Barthd4d0f082017-05-16 13:51:10 -0500491 event = {}
Matthew Barth9af190c2017-08-08 14:20:43 -0500492 # Add precondition if given
493 if ('precondition' in e) and \
494 (e['precondition'] is not None):
Matthew Barth7f272fd2017-09-12 16:16:56 -0500495 event['pc'] = addPrecondition(zone_num,
496 zone_conditions,
497 e,
498 events_data)
Matthew Barth90149802017-08-15 10:51:37 -0500499 else:
Matthew Barth7f272fd2017-09-12 16:16:56 -0500500 event = getEvent(zone_num, zone_conditions, e, events_data)
501 if not event:
502 continue
Matthew Barthd4d0f082017-05-16 13:51:10 -0500503 events.append(event)
504
505 return events
506
507
Matt Spinler78498c92017-04-11 13:59:46 -0500508def getFansInZone(zone_num, profiles, fan_data):
509 """
510 Parses the fan definition YAML files to find the fans
511 that match both the zone passed in and one of the
512 cooling profiles.
513 """
514
515 fans = []
516
517 for f in fan_data['fans']:
518
519 if zone_num != f['cooling_zone']:
520 continue
521
Gunnar Mills67e95512017-06-02 14:35:18 -0500522 # 'cooling_profile' is optional (use 'all' instead)
Matt Spinler78498c92017-04-11 13:59:46 -0500523 if f.get('cooling_profile') is None:
524 profile = "all"
525 else:
526 profile = f['cooling_profile']
527
528 if profile not in profiles:
529 continue
530
531 fan = {}
532 fan['name'] = f['inventory']
533 fan['sensors'] = f['sensors']
534 fans.append(fan)
535
536 return fans
537
538
Gunnar Millsee8a2812017-06-02 14:26:47 -0500539def getConditionInZoneConditions(zone_condition, zone_conditions_data):
540 """
541 Parses the zone conditions definition YAML files to find the condition
542 that match both the zone condition passed in.
543 """
544
545 condition = {}
546
547 for c in zone_conditions_data['conditions']:
548
549 if zone_condition != c['name']:
550 continue
551 condition['type'] = c['type']
552 properties = []
553 for p in c['properties']:
554 property = {}
555 property['property'] = p['property']
556 property['interface'] = p['interface']
557 property['path'] = p['path']
558 property['type'] = p['type'].lower()
559 property['value'] = str(p['value']).lower()
560 properties.append(property)
561 condition['properties'] = properties
562
563 return condition
564
565
566def buildZoneData(zone_data, fan_data, events_data, zone_conditions_data):
Matt Spinler78498c92017-04-11 13:59:46 -0500567 """
568 Combines the zone definition YAML and fan
569 definition YAML to create a data structure defining
570 the fan cooling zones.
571 """
572
573 zone_groups = []
574
575 for group in zone_data:
576 conditions = []
Gunnar Millsee8a2812017-06-02 14:26:47 -0500577 # zone conditions are optional
578 if 'zone_conditions' in group and group['zone_conditions'] is not None:
579 for c in group['zone_conditions']:
580
581 if not zone_conditions_data:
Gunnar Millsb751f322017-06-06 15:14:11 -0500582 sys.exit("No zone_conditions YAML file but " +
Gunnar Millsee8a2812017-06-02 14:26:47 -0500583 "zone_conditions used in zone YAML")
584
585 condition = getConditionInZoneConditions(c['name'],
586 zone_conditions_data)
587
588 if not condition:
589 sys.exit("Missing zone condition " + c['name'])
590
591 conditions.append(condition)
Matt Spinler78498c92017-04-11 13:59:46 -0500592
593 zone_group = {}
594 zone_group['conditions'] = conditions
595
596 zones = []
597 for z in group['zones']:
598 zone = {}
599
Gunnar Mills67e95512017-06-02 14:35:18 -0500600 # 'zone' is required
601 if ('zone' not in z) or (z['zone'] is None):
Matt Spinler78498c92017-04-11 13:59:46 -0500602 sys.exit("Missing fan zone number in " + zone_yaml)
603
604 zone['num'] = z['zone']
605
606 zone['full_speed'] = z['full_speed']
607
Matthew Barth1de66622017-06-12 13:13:02 -0500608 zone['default_floor'] = z['default_floor']
609
Matthew Bartha9561842017-06-29 11:43:45 -0500610 # 'increase_delay' is optional (use 0 by default)
611 key = 'increase_delay'
612 zone[key] = z.setdefault(key, 0)
613
614 # 'decrease_interval' is optional (use 0 by default)
615 key = 'decrease_interval'
616 zone[key] = z.setdefault(key, 0)
617
Gunnar Mills67e95512017-06-02 14:35:18 -0500618 # 'cooling_profiles' is optional (use 'all' instead)
619 if ('cooling_profiles' not in z) or \
Matt Spinler78498c92017-04-11 13:59:46 -0500620 (z['cooling_profiles'] is None):
621 profiles = ["all"]
622 else:
623 profiles = z['cooling_profiles']
624
625 fans = getFansInZone(z['zone'], profiles, fan_data)
Gunnar Millsb751f322017-06-06 15:14:11 -0500626 events = getEventsInZone(z['zone'], group['zone_conditions'],
627 events_data)
Matt Spinler78498c92017-04-11 13:59:46 -0500628
629 if len(fans) == 0:
630 sys.exit("Didn't find any fans in zone " + str(zone['num']))
631
632 zone['fans'] = fans
Matthew Barthd4d0f082017-05-16 13:51:10 -0500633 zone['events'] = events
Matt Spinler78498c92017-04-11 13:59:46 -0500634 zones.append(zone)
635
636 zone_group['zones'] = zones
637 zone_groups.append(zone_group)
638
639 return zone_groups
640
641
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500642if __name__ == '__main__':
643 parser = ArgumentParser(
644 description="Phosphor fan zone definition parser")
645
646 parser.add_argument('-z', '--zone_yaml', dest='zone_yaml',
647 default="example/zones.yaml",
648 help='fan zone definitional yaml')
649 parser.add_argument('-f', '--fan_yaml', dest='fan_yaml',
650 default="example/fans.yaml",
651 help='fan definitional yaml')
Matthew Barthd4d0f082017-05-16 13:51:10 -0500652 parser.add_argument('-e', '--events_yaml', dest='events_yaml',
653 help='events to set speeds yaml')
Gunnar Millsee8a2812017-06-02 14:26:47 -0500654 parser.add_argument('-c', '--zone_conditions_yaml',
655 dest='zone_conditions_yaml',
656 help='conditions to determine zone yaml')
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500657 parser.add_argument('-o', '--output_dir', dest='output_dir',
658 default=".",
659 help='output directory')
660 args = parser.parse_args()
661
662 if not args.zone_yaml or not args.fan_yaml:
663 parser.print_usage()
664 sys.exit(-1)
665
666 with open(args.zone_yaml, 'r') as zone_input:
667 zone_data = yaml.safe_load(zone_input) or {}
668
669 with open(args.fan_yaml, 'r') as fan_input:
670 fan_data = yaml.safe_load(fan_input) or {}
671
Matthew Barthd4d0f082017-05-16 13:51:10 -0500672 events_data = {}
673 if args.events_yaml:
674 with open(args.events_yaml, 'r') as events_input:
675 events_data = yaml.safe_load(events_input) or {}
676
Gunnar Millsee8a2812017-06-02 14:26:47 -0500677 zone_conditions_data = {}
678 if args.zone_conditions_yaml:
679 with open(args.zone_conditions_yaml, 'r') as zone_conditions_input:
680 zone_conditions_data = yaml.safe_load(zone_conditions_input) or {}
681
Matt Spinleree7f6422017-05-09 11:03:14 -0500682 zone_config = buildZoneData(zone_data.get('zone_configuration', {}),
Gunnar Millsee8a2812017-06-02 14:26:47 -0500683 fan_data, events_data, zone_conditions_data)
Matt Spinleree7f6422017-05-09 11:03:14 -0500684
685 manager_config = zone_data.get('manager_configuration', {})
686
687 if manager_config.get('power_on_delay') is None:
688 manager_config['power_on_delay'] = 0
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500689
690 output_file = os.path.join(args.output_dir, "fan_zone_defs.cpp")
691 with open(output_file, 'w') as output:
Matt Spinleree7f6422017-05-09 11:03:14 -0500692 output.write(Template(tmpl).render(zones=zone_config,
693 mgr_data=manager_config))