summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barth <msbarth@us.ibm.com>2017-08-08 14:20:43 -0500
committerMatthew Barth <msbarth@us.ibm.com>2017-08-08 16:24:15 -0500
commit9af190cd94e68b378da4e25accb5c03258a2fb31 (patch)
tree4128541a247dbff19503f2c016d33a87ef8768b2
parentf6b76d8e8fbe71dbecad2189c28265ddff73c9ba (diff)
downloadphosphor-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.yaml62
-rwxr-xr-xcontrol/gen-fan-zone-defs.py139
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']
OpenPOWER on IntegriCloud