blob: 6d04bbd375054d611b93c6c1b07be525fcecc6f6 [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{
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{
52 ${s['match']}(
53 %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}
82</%def>
83/* This is a generated file. */
Matthew Barth34f1bda2017-05-31 13:45:36 -050084#include <sdbusplus/bus.hpp>
Matt Spinlerd08dbe22017-04-11 13:52:54 -050085#include "manager.hpp"
Matthew Barthba102b32017-05-16 16:13:56 -050086#include "functor.hpp"
87#include "actions.hpp"
Matthew Barth7e527c12017-05-17 10:14:15 -050088#include "handlers.hpp"
Matthew Barth9af190c2017-08-08 14:20:43 -050089#include "preconditions.hpp"
Matt Spinlerd08dbe22017-04-11 13:52:54 -050090
91using namespace phosphor::fan::control;
Matthew Barth34f1bda2017-05-31 13:45:36 -050092using namespace sdbusplus::bus::match::rules;
Matt Spinlerd08dbe22017-04-11 13:52:54 -050093
Matt Spinleree7f6422017-05-09 11:03:14 -050094const unsigned int Manager::_powerOnDelay{${mgr_data['power_on_delay']}};
95
Matt Spinlerd08dbe22017-04-11 13:52:54 -050096const std::vector<ZoneGroup> Manager::_zoneLayouts
97{
98%for zone_group in zones:
Matthew Barth9c726672017-05-18 13:44:46 -050099 ZoneGroup{
Gunnar Millsee8a2812017-06-02 14:26:47 -0500100 std::vector<Condition>{
101 %for condition in zone_group['conditions']:
102 Condition{
103 "${condition['type']}",
104 std::vector<ConditionProperty>{
105 %for property in condition['properties']:
106 ConditionProperty{
107 "${property['property']}",
108 "${property['interface']}",
109 "${property['path']}",
110 static_cast<${property['type']}>(${property['value']}),
111 },
112 %endfor
113 },
114 },
115 %endfor
116 },
Matthew Barth9c726672017-05-18 13:44:46 -0500117 std::vector<ZoneDefinition>{
118 %for zone in zone_group['zones']:
119 ZoneDefinition{
120 ${zone['num']},
121 ${zone['full_speed']},
Matthew Barth1de66622017-06-12 13:13:02 -0500122 ${zone['default_floor']},
Matthew Bartha9561842017-06-29 11:43:45 -0500123 ${zone['increase_delay']},
124 ${zone['decrease_interval']},
Matthew Barth9c726672017-05-18 13:44:46 -0500125 std::vector<FanDefinition>{
126 %for fan in zone['fans']:
127 FanDefinition{
128 "${fan['name']}",
129 std::vector<std::string>{
130 %for sensor in fan['sensors']:
131 "${sensor}",
132 %endfor
133 }
134 },
135 %endfor
136 },
137 std::vector<SetSpeedEvent>{
138 %for event in zone['events']:
Matthew Barth9af190c2017-08-08 14:20:43 -0500139 %if ('pc' in event) and \
140 (event['pc'] is not None):
141 SetSpeedEvent{
142 Group{
143 %for member in event['pc']['pcgrp']:
144 {
Matthew Barth67967f92017-09-22 12:43:57 -0500145 "${member['object']}",
Matthew Barth9af190c2017-08-08 14:20:43 -0500146 {"${member['interface']}",
147 "${member['property']}"}
148 },
149 %endfor
150 },
Matthew Barth7f272fd2017-09-12 16:16:56 -0500151 std::vector<Action>{
152 %for i, a in enumerate(event['pc']['pcact']):
Matthew Barth4c04a012017-09-15 13:05:30 -0500153 %if len(a['params']) != 0:
Matthew Barth9af190c2017-08-08 14:20:43 -0500154 make_action(
Matthew Barth7f272fd2017-09-12 16:16:56 -0500155 precondition::${a['name']}(
Matthew Barth4c04a012017-09-15 13:05:30 -0500156 %else:
157 make_action(
158 precondition::${a['name']}
159 %endif
Matthew Barth7f272fd2017-09-12 16:16:56 -0500160 %for p in a['params']:
Matthew Barth9af190c2017-08-08 14:20:43 -0500161 ${p['type']}${p['open']}
162 %for j, v in enumerate(p['values']):
163 %if (j+1) != len(p['values']):
164 ${v['value']},
165 %else:
166 ${v['value']}
167 %endif
168 %endfor
169 ${p['close']},
170 %endfor
Matthew Barth7f272fd2017-09-12 16:16:56 -0500171 %if (i+1) != len(event['pc']['pcact']):
Matthew Barth4c04a012017-09-15 13:05:30 -0500172 %if len(a['params']) != 0:
Matthew Barth7f272fd2017-09-12 16:16:56 -0500173 )),
Matthew Barth4c04a012017-09-15 13:05:30 -0500174 %else:
175 ),
176 %endif
Matthew Barth9c726672017-05-18 13:44:46 -0500177 %endif
178 %endfor
Matthew Barth7f272fd2017-09-12 16:16:56 -0500179 std::vector<SetSpeedEvent>{
180 %for pcevt in event['pc']['pcevts']:
181 SetSpeedEvent{\
182 ${indent(genSSE(event=pcevt), 6)}\
183 },
184 %endfor
185 %else:
186 SetSpeedEvent{\
187 ${indent(genSSE(event=event), 6)}
188 %endif
Matthew Barth9af190c2017-08-08 14:20:43 -0500189 %if ('pc' in event) and (event['pc'] is not None):
190 }
Matthew Barth4c04a012017-09-15 13:05:30 -0500191 %if len(event['pc']['pcact'][-1]['params']) != 0:
Matthew Barth9af190c2017-08-08 14:20:43 -0500192 )),
Matthew Barth4c04a012017-09-15 13:05:30 -0500193 %else:
194 ),
195 %endif
Matthew Barth7f272fd2017-09-12 16:16:56 -0500196 },
Matthew Barth90149802017-08-15 10:51:37 -0500197 Timer{
198 ${event['pc']['pctime']['interval']}
199 },
Matthew Barth67967f92017-09-22 12:43:57 -0500200 std::vector<Signal>{
201 %for s in event['pc']['pcsigs']:
202 Signal{
203 ${s['match']}(
204 %for i, mp in enumerate(s['mparams']):
205 %if (i+1) != len(s['mparams']):
206 "${mp}",
207 %else:
208 "${mp}"
209 %endif
210 %endfor
211 ),
212 make_handler(
213 %if ('type' in s['sparams']) and \
214 (s['sparams']['type'] is not None):
215 ${s['signal']}<${s['sparams']['type']}>(
216 %else:
217 ${s['signal']}(
218 %endif
219 %for spk, spv in s['sparams'].iteritems():
220 %if spk != 'type':
221 "${spv}",
222 %endif
223 %endfor
Matthew Barth9af190c2017-08-08 14:20:43 -0500224 handler::setProperty<${s['type']}>(
Matthew Barth67967f92017-09-22 12:43:57 -0500225 "${s['object']}",
Matthew Barth9af190c2017-08-08 14:20:43 -0500226 "${s['interface']}",
227 "${s['property']}"
228 )
229 ))
230 },
231 %endfor
232 }
233 %endif
Matthew Barth9c726672017-05-18 13:44:46 -0500234 },
235 %endfor
236 }
237 },
238 %endfor
239 }
Matt Spinler78498c92017-04-11 13:59:46 -0500240 },
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500241%endfor
242};
243'''
244
Matt Spinler78498c92017-04-11 13:59:46 -0500245
Matthew Barthbb12c922017-06-13 13:57:40 -0500246def convertToMap(listOfDict):
247 """
248 Converts a list of dictionary entries to a std::map initialization list.
249 """
250 listOfDict = listOfDict.replace('[', '{')
251 listOfDict = listOfDict.replace(']', '}')
252 listOfDict = listOfDict.replace(':', ',')
253 return listOfDict
254
255
Matthew Barth7f272fd2017-09-12 16:16:56 -0500256def getEvent(zone_num, zone_conditions, e, events_data):
257 """
258 Parses the sections of an event and populates the properties
259 that construct an event within the generated source.
260 """
261 event = {}
262 # Zone numbers are optional in the events yaml but skip if this
263 # zone's zone number is not in the event's zone numbers
264 if all('zones' in z and
265 z['zones'] is not None and
266 zone_num not in z['zones']
267 for z in e['zone_conditions']):
268 return
269
270 # Zone conditions are optional in the events yaml but skip
271 # if this event's condition is not in this zone's conditions
272 if all('name' in z and z['name'] is not None and
273 not any(c['name'] == z['name'] for c in zone_conditions)
274 for z in e['zone_conditions']):
275 return
276
277 # Add set speed event group
278 group = []
279 groups = next(g for g in events_data['groups']
280 if g['name'] == e['group'])
281 for member in groups['members']:
282 members = {}
Matthew Barth67967f92017-09-22 12:43:57 -0500283 members['object'] = (groups['type'] +
284 member)
Matthew Barth7f272fd2017-09-12 16:16:56 -0500285 members['interface'] = e['interface']
286 members['property'] = e['property']['name']
Matthew Barth67967f92017-09-22 12:43:57 -0500287 members['type'] = e['property']['type']
Matthew Barth7f272fd2017-09-12 16:16:56 -0500288 group.append(members)
289 event['group'] = group
290
291 # Add set speed actions and function parameters
292 action = []
293 for eActions in e['actions']:
294 actions = {}
295 eAction = next(a for a in events_data['actions']
296 if a['name'] == eActions['name'])
297 actions['name'] = eAction['name']
298 params = []
Matthew Barth4c04a012017-09-15 13:05:30 -0500299 if ('parameters' in eAction) and \
300 (eAction['parameters'] is not None):
301 for p in eAction['parameters']:
302 param = {}
303 if type(eActions[p]) is not dict:
304 if p == 'property':
305 param['value'] = str(eActions[p]).lower()
306 param['type'] = str(
307 e['property']['type']).lower()
308 else:
309 # Default type to 'size_t' when not given
310 param['value'] = str(eActions[p]).lower()
311 param['type'] = 'size_t'
312 params.append(param)
Matthew Barth7f272fd2017-09-12 16:16:56 -0500313 else:
Matthew Barth4c04a012017-09-15 13:05:30 -0500314 param['type'] = str(eActions[p]['type']).lower()
315 if p != 'map':
316 param['value'] = str(
317 eActions[p]['value']).lower()
318 else:
319 emap = convertToMap(str(eActions[p]['value']))
320 param['value'] = param['type'] + emap
321 params.append(param)
Matthew Barth7f272fd2017-09-12 16:16:56 -0500322 actions['parameters'] = params
323 action.append(actions)
324 event['action'] = action
325
Matthew Barth67967f92017-09-22 12:43:57 -0500326 # Add signal handlers
327 signals = []
328 for member in group:
329 for eMatches in e['matches']:
330 signal = {}
331 eMatch = next(m for m in events_data['matches']
332 if m['name'] == eMatches['name'])
333 signal['match'] = eMatch['name']
334 params = []
335 if ('parameters' in eMatch) and \
336 (eMatch['parameters'] is not None):
337 for p in eMatch['parameters']:
338 params.append(member[str(p)])
339 signal['mparams'] = params
340 eSignal = next(s for s in events_data['signals']
341 if s['name'] == eMatch['signal'])
342 signal['signal'] = eSignal['name']
343 sparams = {}
344 if ('parameters' in eSignal) and \
345 (eSignal['parameters'] is not None):
346 for p in eSignal['parameters']:
347 sparams[str(p)] = member[str(p)]
348 signal['sparams'] = sparams
349 # Add member attributes
350 signal['object'] = member['object']
351 signal['interface'] = member['interface']
352 signal['property'] = member['property']
353 signal['type'] = member['type']
354 signals.append(signal)
355 event['signals'] = signals
Matthew Barth7f272fd2017-09-12 16:16:56 -0500356
357 # Add optional action call timer
358 timer = {}
359 interval = "static_cast<std::chrono::seconds>"
360 if ('timer' in e) and \
361 (e['timer'] is not None):
362 timer['interval'] = (interval +
363 "(" +
364 str(e['timer']['interval']) +
365 ")")
366 else:
367 timer['interval'] = (interval +
368 "(" + str(0) + ")")
369 event['timer'] = timer
370
371 return event
372
373
374def addPrecondition(zNum, zCond, event, events_data):
Matthew Barth9af190c2017-08-08 14:20:43 -0500375 """
376 Parses the precondition section of an event and populates the necessary
377 structures to generate a precondition for a set speed event.
378 """
379 precond = {}
380 # Add set speed event precondition group
381 group = []
382 for grp in event['precondition']['groups']:
383 groups = next(g for g in events_data['groups']
384 if g['name'] == grp['name'])
385 for member in groups['members']:
386 members = {}
Matthew Barth67967f92017-09-22 12:43:57 -0500387 members['object'] = (groups['type'] +
388 member)
Matthew Barth9af190c2017-08-08 14:20:43 -0500389 members['interface'] = grp['interface']
390 members['property'] = grp['property']['name']
391 members['type'] = grp['property']['type']
392 members['value'] = grp['property']['value']
393 group.append(members)
394 precond['pcgrp'] = group
395
Matthew Barth7f272fd2017-09-12 16:16:56 -0500396 # Add set speed event precondition actions
397 pc = []
398 pcs = {}
399 pcs['name'] = event['precondition']['name']
400 epc = next(p for p in events_data['preconditions']
Matthew Barth9af190c2017-08-08 14:20:43 -0500401 if p['name'] == event['precondition']['name'])
402 params = []
Matthew Barth7f272fd2017-09-12 16:16:56 -0500403 for p in epc['parameters']:
Matthew Barth9af190c2017-08-08 14:20:43 -0500404 param = {}
405 if p == 'groups':
406 param['type'] = "std::vector<PrecondGroup>"
407 param['open'] = "{"
408 param['close'] = "}"
409 values = []
410 for pcgrp in group:
411 value = {}
412 value['value'] = (
413 "PrecondGroup{\"" +
Matthew Barth67967f92017-09-22 12:43:57 -0500414 str(pcgrp['object']) + "\",\"" +
Matthew Barth9af190c2017-08-08 14:20:43 -0500415 str(pcgrp['interface']) + "\",\"" +
416 str(pcgrp['property']) + "\"," +
417 "static_cast<" +
418 str(pcgrp['type']).lower() + ">" +
419 "(" + str(pcgrp['value']).lower() + ")}")
420 values.append(value)
421 param['values'] = values
422 params.append(param)
Matthew Barth7f272fd2017-09-12 16:16:56 -0500423 pcs['params'] = params
424 pc.append(pcs)
Matthew Barth9af190c2017-08-08 14:20:43 -0500425 precond['pcact'] = pc
426
Matthew Barth7f272fd2017-09-12 16:16:56 -0500427 pcevents = []
428 for pce in event['precondition']['events']:
429 pcevent = getEvent(zNum, zCond, pce, events_data)
430 if not pcevent:
431 continue
432 pcevents.append(pcevent)
433 precond['pcevts'] = pcevents
434
Matthew Barth67967f92017-09-22 12:43:57 -0500435 # Add precondition signal handlers
436 signals = []
Matthew Barth9af190c2017-08-08 14:20:43 -0500437 for member in group:
Matthew Barth67967f92017-09-22 12:43:57 -0500438 for eMatches in event['precondition']['matches']:
439 signal = {}
440 eMatch = next(m for m in events_data['matches']
441 if m['name'] == eMatches['name'])
442 signal['match'] = eMatch['name']
443 params = []
444 if ('parameters' in eMatch) and \
445 (eMatch['parameters'] is not None):
446 for p in eMatch['parameters']:
447 params.append(member[str(p)])
448 signal['mparams'] = params
449 eSignal = next(s for s in events_data['signals']
450 if s['name'] == eMatch['signal'])
451 signal['signal'] = eSignal['name']
452 sparams = {}
453 if ('parameters' in eSignal) and \
454 (eSignal['parameters'] is not None):
455 for p in eSignal['parameters']:
456 sparams[str(p)] = member[str(p)]
457 signal['sparams'] = sparams
458 # Add member attributes
459 signal['object'] = member['object']
460 signal['interface'] = member['interface']
461 signal['property'] = member['property']
462 signal['type'] = member['type']
463 signals.append(signal)
464 precond['pcsigs'] = signals
Matthew Barth9af190c2017-08-08 14:20:43 -0500465
Matthew Barth90149802017-08-15 10:51:37 -0500466 # Add optional action call timer
467 timer = {}
468 interval = "static_cast<std::chrono::seconds>"
469 if ('timer' in event['precondition']) and \
470 (event['precondition']['timer'] is not None):
471 timer['interval'] = (interval +
472 "(" +
473 str(event['precondition']['timer']['interval']) +
474 ")")
475 else:
476 timer['interval'] = (interval +
477 "(" + str(0) + ")")
478 precond['pctime'] = timer
479
Matthew Barth9af190c2017-08-08 14:20:43 -0500480 return precond
481
482
Gunnar Millsb751f322017-06-06 15:14:11 -0500483def getEventsInZone(zone_num, zone_conditions, events_data):
Matthew Barthd4d0f082017-05-16 13:51:10 -0500484 """
485 Constructs the event entries defined for each zone using the events yaml
486 provided.
487 """
488 events = []
Matthew Barthba102b32017-05-16 16:13:56 -0500489
Matthew Barthd4d0f082017-05-16 13:51:10 -0500490 if 'events' in events_data:
491 for e in events_data['events']:
Matthew Barthd4d0f082017-05-16 13:51:10 -0500492 event = {}
Matthew Barth9af190c2017-08-08 14:20:43 -0500493 # Add precondition if given
494 if ('precondition' in e) and \
495 (e['precondition'] is not None):
Matthew Barth7f272fd2017-09-12 16:16:56 -0500496 event['pc'] = addPrecondition(zone_num,
497 zone_conditions,
498 e,
499 events_data)
Matthew Barth90149802017-08-15 10:51:37 -0500500 else:
Matthew Barth7f272fd2017-09-12 16:16:56 -0500501 event = getEvent(zone_num, zone_conditions, e, events_data)
502 if not event:
503 continue
Matthew Barthd4d0f082017-05-16 13:51:10 -0500504 events.append(event)
505
506 return events
507
508
Matt Spinler78498c92017-04-11 13:59:46 -0500509def getFansInZone(zone_num, profiles, fan_data):
510 """
511 Parses the fan definition YAML files to find the fans
512 that match both the zone passed in and one of the
513 cooling profiles.
514 """
515
516 fans = []
517
518 for f in fan_data['fans']:
519
520 if zone_num != f['cooling_zone']:
521 continue
522
Gunnar Mills67e95512017-06-02 14:35:18 -0500523 # 'cooling_profile' is optional (use 'all' instead)
Matt Spinler78498c92017-04-11 13:59:46 -0500524 if f.get('cooling_profile') is None:
525 profile = "all"
526 else:
527 profile = f['cooling_profile']
528
529 if profile not in profiles:
530 continue
531
532 fan = {}
533 fan['name'] = f['inventory']
534 fan['sensors'] = f['sensors']
535 fans.append(fan)
536
537 return fans
538
539
Gunnar Millsee8a2812017-06-02 14:26:47 -0500540def getConditionInZoneConditions(zone_condition, zone_conditions_data):
541 """
542 Parses the zone conditions definition YAML files to find the condition
543 that match both the zone condition passed in.
544 """
545
546 condition = {}
547
548 for c in zone_conditions_data['conditions']:
549
550 if zone_condition != c['name']:
551 continue
552 condition['type'] = c['type']
553 properties = []
554 for p in c['properties']:
555 property = {}
556 property['property'] = p['property']
557 property['interface'] = p['interface']
558 property['path'] = p['path']
559 property['type'] = p['type'].lower()
560 property['value'] = str(p['value']).lower()
561 properties.append(property)
562 condition['properties'] = properties
563
564 return condition
565
566
567def buildZoneData(zone_data, fan_data, events_data, zone_conditions_data):
Matt Spinler78498c92017-04-11 13:59:46 -0500568 """
569 Combines the zone definition YAML and fan
570 definition YAML to create a data structure defining
571 the fan cooling zones.
572 """
573
574 zone_groups = []
575
576 for group in zone_data:
577 conditions = []
Gunnar Millsee8a2812017-06-02 14:26:47 -0500578 # zone conditions are optional
579 if 'zone_conditions' in group and group['zone_conditions'] is not None:
580 for c in group['zone_conditions']:
581
582 if not zone_conditions_data:
Gunnar Millsb751f322017-06-06 15:14:11 -0500583 sys.exit("No zone_conditions YAML file but " +
Gunnar Millsee8a2812017-06-02 14:26:47 -0500584 "zone_conditions used in zone YAML")
585
586 condition = getConditionInZoneConditions(c['name'],
587 zone_conditions_data)
588
589 if not condition:
590 sys.exit("Missing zone condition " + c['name'])
591
592 conditions.append(condition)
Matt Spinler78498c92017-04-11 13:59:46 -0500593
594 zone_group = {}
595 zone_group['conditions'] = conditions
596
597 zones = []
598 for z in group['zones']:
599 zone = {}
600
Gunnar Mills67e95512017-06-02 14:35:18 -0500601 # 'zone' is required
602 if ('zone' not in z) or (z['zone'] is None):
Matt Spinler78498c92017-04-11 13:59:46 -0500603 sys.exit("Missing fan zone number in " + zone_yaml)
604
605 zone['num'] = z['zone']
606
607 zone['full_speed'] = z['full_speed']
608
Matthew Barth1de66622017-06-12 13:13:02 -0500609 zone['default_floor'] = z['default_floor']
610
Matthew Bartha9561842017-06-29 11:43:45 -0500611 # 'increase_delay' is optional (use 0 by default)
612 key = 'increase_delay'
613 zone[key] = z.setdefault(key, 0)
614
615 # 'decrease_interval' is optional (use 0 by default)
616 key = 'decrease_interval'
617 zone[key] = z.setdefault(key, 0)
618
Gunnar Mills67e95512017-06-02 14:35:18 -0500619 # 'cooling_profiles' is optional (use 'all' instead)
620 if ('cooling_profiles' not in z) or \
Matt Spinler78498c92017-04-11 13:59:46 -0500621 (z['cooling_profiles'] is None):
622 profiles = ["all"]
623 else:
624 profiles = z['cooling_profiles']
625
626 fans = getFansInZone(z['zone'], profiles, fan_data)
Gunnar Millsb751f322017-06-06 15:14:11 -0500627 events = getEventsInZone(z['zone'], group['zone_conditions'],
628 events_data)
Matt Spinler78498c92017-04-11 13:59:46 -0500629
630 if len(fans) == 0:
631 sys.exit("Didn't find any fans in zone " + str(zone['num']))
632
633 zone['fans'] = fans
Matthew Barthd4d0f082017-05-16 13:51:10 -0500634 zone['events'] = events
Matt Spinler78498c92017-04-11 13:59:46 -0500635 zones.append(zone)
636
637 zone_group['zones'] = zones
638 zone_groups.append(zone_group)
639
640 return zone_groups
641
642
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500643if __name__ == '__main__':
644 parser = ArgumentParser(
645 description="Phosphor fan zone definition parser")
646
647 parser.add_argument('-z', '--zone_yaml', dest='zone_yaml',
648 default="example/zones.yaml",
649 help='fan zone definitional yaml')
650 parser.add_argument('-f', '--fan_yaml', dest='fan_yaml',
651 default="example/fans.yaml",
652 help='fan definitional yaml')
Matthew Barthd4d0f082017-05-16 13:51:10 -0500653 parser.add_argument('-e', '--events_yaml', dest='events_yaml',
654 help='events to set speeds yaml')
Gunnar Millsee8a2812017-06-02 14:26:47 -0500655 parser.add_argument('-c', '--zone_conditions_yaml',
656 dest='zone_conditions_yaml',
657 help='conditions to determine zone yaml')
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500658 parser.add_argument('-o', '--output_dir', dest='output_dir',
659 default=".",
660 help='output directory')
661 args = parser.parse_args()
662
663 if not args.zone_yaml or not args.fan_yaml:
664 parser.print_usage()
665 sys.exit(-1)
666
667 with open(args.zone_yaml, 'r') as zone_input:
668 zone_data = yaml.safe_load(zone_input) or {}
669
670 with open(args.fan_yaml, 'r') as fan_input:
671 fan_data = yaml.safe_load(fan_input) or {}
672
Matthew Barthd4d0f082017-05-16 13:51:10 -0500673 events_data = {}
674 if args.events_yaml:
675 with open(args.events_yaml, 'r') as events_input:
676 events_data = yaml.safe_load(events_input) or {}
677
Gunnar Millsee8a2812017-06-02 14:26:47 -0500678 zone_conditions_data = {}
679 if args.zone_conditions_yaml:
680 with open(args.zone_conditions_yaml, 'r') as zone_conditions_input:
681 zone_conditions_data = yaml.safe_load(zone_conditions_input) or {}
682
Matt Spinleree7f6422017-05-09 11:03:14 -0500683 zone_config = buildZoneData(zone_data.get('zone_configuration', {}),
Gunnar Millsee8a2812017-06-02 14:26:47 -0500684 fan_data, events_data, zone_conditions_data)
Matt Spinleree7f6422017-05-09 11:03:14 -0500685
686 manager_config = zone_data.get('manager_configuration', {})
687
688 if manager_config.get('power_on_delay') is None:
689 manager_config['power_on_delay'] = 0
Matt Spinlerd08dbe22017-04-11 13:52:54 -0500690
691 output_file = os.path.join(args.output_dir, "fan_zone_defs.cpp")
692 with open(output_file, 'w') as output:
Matt Spinleree7f6422017-05-09 11:03:14 -0500693 output.write(Template(tmpl).render(zones=zone_config,
694 mgr_data=manager_config))