A while ago a few of us discussed about wrapping a layer above the Open Hab items. So instead of flat list of items, we would bind them into zones or rooms. A zone would contains one or more devices/sensors. Once the structure has been populated (into a ZoneManager that contains multiple zones), actions can be written to re-act on sensor events.
I’ve created a simple API to do that and applied to a number of rules for my house. It is not necessary better; it’s just a different approach than Python rules with its own pros and cons.
@Bruce_Osborne That’s interesting. I didn’t know Scott also tried to tackle this. Yes, the concept is similar, but the approach is quite different.
IMO, there are two aspects of this kind of systems: the front end and the back end.
The front end takes care of organizing flat items into an object hierarchy.
The back end exposes a set of API that allows querying the object hierchary to ask questions such as
Which zone am I being triggered in?
What other devices are there in the current zone, and what are their states?
What are the zones besides me?
Does the system has a device of specific type?
Scott’s approach tackles the front end by using the existing group concept and as such is easier for existing users to migrate over. The actions essentially operate directly on items. The big advantage is that there is no new concept to learn.
My framework focuses more on the backend to expose a set of APIs that actions can interface with. It is textbook example of Object Oriented design.
Actions do not operate on items; instead they operate on concrete objects that abstract away the items. It leaves open how you build up the object hierarchy; there are many way to do that. At the moment, I just parse my items based on certain naming pattern.
Here’s the main flow when building up from the beginning:
Construct a set of Zone objects, define neighbouring relationship between them and add them to the ZoneManager.
Construct a set of Device objects, and add them to the appropriate Zone objects.
Create a set of Action objects, and add them to the appropriate Zone.
A Python script will route OpenHab events --> ZoneManager --> Zone(s) --> Action(s).
Here’s the full code for the a simple action:
from aaa_modules.layout_model.zone import ZoneEvent
from aaa_modules.layout_model.neighbor import Neighbor, NeighborType
from aaa_modules.layout_model.devices.switch import Light
from aaa_modules.layout_model.action import Action
class TurnOffAdjacentZones(Action):
'''
Turn off the lights in the zones adjacent to the current zone if the
current zone's liht is on and if the adjacent zones are of the OPEN_SPACE
and OPEN_SPACE_SLAVE type.
'''
def getTriggeringEvents(self):
'''
:return: list of triggering events this action process.
:rtype: list(ZoneEvent)
'''
return [ZoneEvent.SWITCH_TURNED_ON]
def onAction(self, eventInfo):
events = eventInfo.getEventDispatcher()
zone = eventInfo.getZone()
zoneManager = eventInfo.getZoneManager()
if None == zoneManager:
raise ValueError('zoneManager must be specified')
lights = zone.getDevicesByType(Light)
if len(lights) == 0:
return False
adjacentZones = zone.getNeighborZones(zoneManager,
[NeighborType.OPEN_SPACE, NeighborType.OPEN_SPACE_SLAVE])
for z in adjacentZones:
if z.isLightOn():
z.turnOffLights(events)
return True
And here is a slightly more complicate rule to control light and fan switch:
Here’s an example of the object structure in my house: