Conditional and combining events.
Description
This is the most complex of the event handlers at present, it enables you to perform conditional actions and combine events to produce new events. For example only allowing heating zone requests if the zone is command enabled or combining the two inputs from a garage door into a single garage door state value.
This event handler maintains a state table in memory that is updated by configured events, when this table is updated then the action defintions are checked to see whether an update to the state table should cause an action to be performed. In the future this state table may be totally or partially persisted through an WebBrick Gateway restart.
Configuration
The configuration for this handler is split into to four parts
- The first is our normal set of event source and type filters along with actions that are used to define local state updates,
these are local to this copy of thw Compound. Think of this as creating local short names for
event values.
The action elements contained within the event elements define updates to the local state table, the action has the following attributes
- name - the name of a local state value to update
- key - the name of a value within the triggering event other data, this becomes the new value for the local state
- value - this is the new value for the local state
- transient - if this attribute is present then the update to local state is discarded after the event has been processed, this is usefull for causing aactions to occur but not remembering the state, such that a later update causes the action to occur again, e.g. when the action is caused by a time event.
name must be present along with either key or value, the result is always an update to a local state value
There then may be 0 or more initialState values that set startup values for the local state, each has a name and value
There then may be 0 or more persistState values at present these are treated exactly the same as initialState, in the long term the named value will be loaded from persistant state and value used if it does not yet exist in the persistant state
- Finally there will be some compound elements, these define tests and actions against the locaal state
The compound element Each compound element consists of a params element which defines some tests against the local state store and some updates to the local state or new events to be generated. Refer to parameter filtering. for details of what goes in the Params element. The comound element may have the attribute redo, if this has the value 'yes' then each time the data is seen for this comound it is re-evaluated otherwise it only re-evaluates if the data changes value (default). NOTE: These tests are performed against the local state of this Compound interface.
The newEvent element This contains two attributes for the event type and source and possibly nested elements other_data and copy_other_data.
The newState element This contains updates to the element local state.
Logging
This handler uses the logging stream 'EventDespatch.Compound'.Debug
At startup the configured comound elements will be logged. An update to the local state will be logged as 'update name:value Transient(True|False)' On update all compounds that use the updated value and match the current state will be logged as 'cmp matches'Example 1
This example shows a garage door combination that is used where a garage door has two sensor outputs. In the case of this door one output shows that the door is closed and the other shows that the door is open. If the door is not open and not closed then it is a ajar, if the door is open and closed it is an error condition.| doorOpen | doorClosed | status |
|---|---|---|
| 0 | 0 | Ajar |
| 0 | 1 | Closed |
| 1 | 0 | Open |
| 1 | 1 | Error |
<eventInterfaces>
<eventInterface module='EventHandlers.Compound' name='Compound'>
<eventtype type="http://id.webbrick.co.uk/events/webbrick/DI">
<!-- Pick up webbrick events for inputs connected to the garage door -->
<eventsource source="webbrick/1/DI/10" >
<event>
<action name="GarageDoorIsClosed" key="state"/>
</event>
</eventsource>
<eventsource source="webbrick/1/DI/11" >
<event>
<action name="GarageDoorIsOpen" key="state"/>
</event>
</eventsource>
</eventtype>
<initialState name='GarageDoorIsClosed' value='0'/>
<initialState name='GarageDoorIsOpen' value='0'/>
<!-- the next four rules generate the event type http://id.webbrick.co.uk/events/state which
is cached by the Gateway web server for delivery to the browser based user interface -->
<compound>
<params>
<testEq name="GarageDoorIsClosed" value="0"/>
<testEq name="GarageDoorIsOpen" value="0"/>
</params>
<newEvent type="http://id.webbrick.co.uk/events/state" source="Garage/Door/1">
<other_data val='0'/>
</newEvent>
</compound>
<compound>
<params>
<testEq name="GarageDoorIsClosed" value="0"/>
<testEq name="GarageDoorIsOpen" value="1"/>
</params>
<newEvent type="http://id.webbrick.co.uk/events/state" source="Garage/Door/1">
<other_data val='1'/>
</newEvent>
</compound>
<compound>
<params>
<testEq name="GarageDoorIsClosed" value="1"/>
<testEq name="GarageDoorIsOpen" value="0"/>
</params>
<newEvent type="http://id.webbrick.co.uk/events/state" source="Garage/Door/1">
<other_data val='2'/>
</newEvent>
</compound>
<compound>
<params>
<testEq name="GarageDoorIsClosed" value="1"/>
<testEq name="GarageDoorIsOpen" value="1"/>
</params>
<newEvent type="http://id.webbrick.co.uk/events/state" source="Garage/Door/1">
<other_data val='3'/>
</newEvent>
</compound>
</eventInterface>
</eventInterfaces>
Example 2
This example shows a heating zone that is nominaally controlled by a temperature sensor but an event from a user interface can be used to disable the zone. Note we define temperature as transient in this and for the enable flag to be persisted. Define the events to listen too and the local state values to update.
<eventInterface module='EventHandlers.Compound' name='Compound'>
<eventtype type="">
<eventsource source="heating/zone/1enable/" >
<event>
<action name="Zone1Enabled" value="0"/>
</event>
</eventsource>
<eventsource source="heating/zone/1/disable" >
<event>
<action name="Zone1Enabled" value="1"/>
</event>
</eventsource>
</eventtype>
<eventtype type="http://id.webbrick.co.uk/events/webbrick/CT">
<eventsource source="webbrick/25/CT/1" >
<event>
<action name="Zone1Temp" state="val" transient/>
</event>
</eventsource>
</eventtype>
define initial values for the local state, zone 1 enabled
<persistState name="Zone1Enabled" value="1"/>
define the new event and values for each of the state combinations.
In this case only allow on if zone enabled, allow off always and on receiving zone disable
switch the zone off.
<compound>
<params>
<testEq name="Zone1Enabled" value="1"/<
<testLt name="Zone1Temp" value="18.0"/<
</params>
<newEvent type="internal" source="heating/zone/1/On">
</newEvent>
</compound>
<compound>
<params>
<testGt name="Zone1Temp" value="21.0"/<
</params>
<newEvent type="internal" source="heating/zone/1/Off">
</newEvent>
</compound>
<compound>
<params>
<testEq name="Zone1Enabled" value="0"/<
</params>
<newEvent type="internal" source="heating/zone/1/Off">
</newEvent>
</compound>
</eventInterface>
The events source of heating/zone/1/On or heating/zone/1/Off are user friendly names thaat wwould be translated
by another handler into the incantation required to switch the zone valve, i.e. HttpAction issuing a webbrick
command string.
