diff options
author | Matthew Barth <msbarth@us.ibm.com> | 2017-08-08 14:20:43 -0500 |
---|---|---|
committer | Matthew Barth <msbarth@us.ibm.com> | 2017-08-08 16:24:15 -0500 |
commit | 9af190cd94e68b378da4e25accb5c03258a2fb31 (patch) | |
tree | 4128541a247dbff19503f2c016d33a87ef8768b2 | |
parent | f6b76d8e8fbe71dbecad2189c28265ddff73c9ba (diff) | |
download | phosphor-fan-presence-9af190cd94e68b378da4e25accb5c03258a2fb31.tar.gz phosphor-fan-presence-9af190cd94e68b378da4e25accb5c03258a2fb31.zip |
Update parser to support optional preconditions
Set speed events are now allowed to have preconditions defined within
the event where those preconditions must be met before the set speed
event is enabled and active. The supported precondition added is against
a list of groups and their properties matching a given value.
The parser generates a precondition with the same layout as a set speed
event where the event is nested as the last parameter to the
precondition function. Having the set speed event as the last input
parameter to precondition functions is required.
Resolves openbmc/openbmc#1835
Change-Id: I7a247e7eb2d6b31ba9a60da1bc321a35edda9b24
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
-rw-r--r-- | control/example/events.yaml | 62 | ||||
-rwxr-xr-x | control/gen-fan-zone-defs.py | 139 |
2 files changed, 189 insertions, 12 deletions
diff --git a/control/example/events.yaml b/control/example/events.yaml index ed62ce6..b2c22cf 100644 --- a/control/example/events.yaml +++ b/control/example/events.yaml @@ -32,7 +32,7 @@ #groups: # - name: zone0_fans # description: Group of fan inventory objects for zone 0 -# type: inventory +# type: /xyz/openbmc_project/inventory # members: # - /system/chassis/motherboard/fan0 # - /system/chassis/motherboard/fan1 @@ -40,9 +40,22 @@ # - /system/chassis/motherboard/fan3 # - name: zone0_ambient # description: Group of ambient temperature sensors for zone 0 -# type: sensors +# type: /xyz/openbmc_project/sensors # members: # - /temperature/ambient +# - name: occ0_object +# description: Dbus object containing OCC0 properties +# type: /org/open_power/control +# members: +# - /occ0 +# +#preconditions: +# - name: property_states_match +# description: > +# All defined properties must match the values given to +# enable a set speed event otherwise fan speeds are set to full +# parameters: +# - groups # #actions: # - name: count_state_before_speed @@ -88,10 +101,10 @@ # name: set_floor_from_average_sensor_value # map: # value: -# - 25: 3500 -# - 30: 4600 -# - 35: 5200 -# - 40: 5800 +# - 25000: 3500 +# - 30000: 4600 +# - 35000: 5200 +# - 40000: 5800 # type: std::map<int64_t, uint64_t> # - name: update_water_cooled_floor_speed_based_on_ambient # zone_conditions: @@ -107,8 +120,37 @@ # name: set_floor_from_average_sensor_value # map: # value: -# - 25: 2500 -# - 30: 3600 -# - 35: 4200 -# - 40: 4800 +# - 25000: 2500 +# - 30000: 3600 +# - 35000: 4200 +# - 40000: 4800 +# type: std::map<int64_t, uint64_t> +# - name: update_ceiling_speed_based_on_ambient +# zone_conditions: +# - name: air_cooled_chassis +# zones: +# - 0 +# - name: water_and_air_cooled_chassis +# zones: +# - 0 +# precondition: +# name: property_states_match +# groups: +# - name: occ0_object +# interface: org.open_power.OCC.Status +# property: +# name: OccActive +# type: bool +# value: true +# group: zone0_ambient +# interface: xyz.openbmc_project.Sensor.Value +# property: +# name: Value +# type: int64_t +# action: +# name: set_ceiling_from_average_sensor_value +# map: +# value: +# - 25000: 7200 +# - 27000: 10500 # type: std::map<int64_t, uint64_t> diff --git a/control/gen-fan-zone-defs.py b/control/gen-fan-zone-defs.py index 177bfe0..ea05a0f 100755 --- a/control/gen-fan-zone-defs.py +++ b/control/gen-fan-zone-defs.py @@ -17,6 +17,7 @@ tmpl = '''/* This is a generated file. */ #include "functor.hpp" #include "actions.hpp" #include "handlers.hpp" +#include "preconditions.hpp" using namespace phosphor::fan::control; using namespace sdbusplus::bus::match::rules; @@ -66,6 +67,32 @@ const std::vector<ZoneGroup> Manager::_zoneLayouts }, std::vector<SetSpeedEvent>{ %for event in zone['events']: + %if ('pc' in event) and \ + (event['pc'] is not None): + SetSpeedEvent{ + Group{ + %for member in event['pc']['pcgrp']: + { + "${member['name']}", + {"${member['interface']}", + "${member['property']}"} + }, + %endfor + }, + make_action( + precondition::${event['pc']['pcact']['name']}( + %for i, p in enumerate(event['pc']['pcact']['params']): + ${p['type']}${p['open']} + %for j, v in enumerate(p['values']): + %if (j+1) != len(p['values']): + ${v['value']}, + %else: + ${v['value']} + %endif + %endfor + ${p['close']}, + %endfor + %endif SetSpeedEvent{ Group{ %for member in event['group']: @@ -105,6 +132,43 @@ const std::vector<ZoneGroup> Manager::_zoneLayouts }, %endfor } + %if ('pc' in event) and (event['pc'] is not None): + } + )), + std::vector<PropertyChange>{ + %for s in event['pc']['pcsig']: + PropertyChange{ + interfacesAdded("${s['obj_path']}"), + make_handler(objectSignal<${s['type']}>( + "${s['path']}", + "${s['interface']}", + "${s['property']}", + handler::setProperty<${s['type']}>( + "${s['path']}", + "${s['interface']}", + "${s['property']}" + ) + )) + }, + PropertyChange{ + interface("org.freedesktop.DBus.Properties") + + member("PropertiesChanged") + + type::signal() + + path("${s['path']}") + + arg0namespace("${s['interface']}"), + make_handler(propertySignal<${s['type']}>( + "${s['interface']}", + "${s['property']}", + handler::setProperty<${s['type']}>( + "${s['path']}", + "${s['interface']}", + "${s['property']}" + ) + )) + }, + %endfor + } + %endif }, %endfor } @@ -127,6 +191,73 @@ def convertToMap(listOfDict): return listOfDict +def addPrecondition(event, events_data): + """ + Parses the precondition section of an event and populates the necessary + structures to generate a precondition for a set speed event. + """ + precond = {} + # Add set speed event precondition group + group = [] + for grp in event['precondition']['groups']: + groups = next(g for g in events_data['groups'] + if g['name'] == grp['name']) + for member in groups['members']: + members = {} + members['obj_path'] = groups['type'] + members['name'] = (groups['type'] + + member) + members['interface'] = grp['interface'] + members['property'] = grp['property']['name'] + members['type'] = grp['property']['type'] + members['value'] = grp['property']['value'] + group.append(members) + precond['pcgrp'] = group + + # Add set speed event precondition action + pc = {} + pc['name'] = event['precondition']['name'] + pcs = next(p for p in events_data['preconditions'] + if p['name'] == event['precondition']['name']) + params = [] + for p in pcs['parameters']: + param = {} + if p == 'groups': + param['type'] = "std::vector<PrecondGroup>" + param['open'] = "{" + param['close'] = "}" + values = [] + for pcgrp in group: + value = {} + value['value'] = ( + "PrecondGroup{\"" + + str(pcgrp['name']) + "\",\"" + + str(pcgrp['interface']) + "\",\"" + + str(pcgrp['property']) + "\"," + + "static_cast<" + + str(pcgrp['type']).lower() + ">" + + "(" + str(pcgrp['value']).lower() + ")}") + values.append(value) + param['values'] = values + params.append(param) + pc['params'] = params + precond['pcact'] = pc + + # Add precondition property change signal handler + signal = [] + for member in group: + signals = {} + signals['obj_path'] = member['obj_path'] + signals['path'] = member['name'] + signals['interface'] = member['interface'] + signals['property'] = member['property'] + signals['type'] = member['type'] + signal.append(signals) + precond['pcsig'] = signal + + return precond + + def getEventsInZone(zone_num, zone_conditions, events_data): """ Constructs the event entries defined for each zone using the events yaml @@ -151,6 +282,11 @@ def getEventsInZone(zone_num, zone_conditions, events_data): continue event = {} + # Add precondition if given + if ('precondition' in e) and \ + (e['precondition'] is not None): + event['pc'] = addPrecondition(e, events_data) + # Add set speed event group group = [] groups = next(g for g in events_data['groups'] @@ -158,8 +294,7 @@ def getEventsInZone(zone_num, zone_conditions, events_data): for member in groups['members']: members = {} members['type'] = groups['type'] - members['name'] = ("/xyz/openbmc_project/" + - groups['type'] + + members['name'] = (groups['type'] + member) members['interface'] = e['interface'] members['property'] = e['property']['name'] |