HABApp 0.31.0

Good news everyone!

I just released HABApp 0.31.0!

This release brings lots of improvements the most notably full support for tags and groups and an easy option to search for items.


Item search

# This seaches for items that are in group 'my_group' and have the tags set
for item in self.get_items(groups='my_group', tags=['tag1', 'tag2']):
    print(item.tags)      # All tags are now on the OpenhabItem
    print(item.groups)    # All defined groups are accessable, too
# This returns all switch items
for item in self.get_items(type=SwitchItem):
    print(item.is_on())
# This returns all items who's name end with _battery
for item in self.get_items(name='_battery'):
    ...

Groups and Tags

group = GroupItem.get_item('My_Group')

# It's possible to get the defined children of a group directly
for item in group.members:
    item.value

# Items have the definition as a property
item.tags
item.groups
4 Likes

That sounds great. Then it should be possible tp create rules based on groups.

Did it get it right that this should work

for sensor in GroupItem.get_item('gCOL_PlantSensors').members:
    log.info(f'{sensor}')

Yes and sensor is the corresponding item, not the name of the item.
So HABApp does the item lookup for you.


As always - I recommend using a good naming scheme over groups because it’s much more flexible (e.g. Plant_Name_Sensor) and it allows changes in logic without having to edit the item definitions.

Another even better option is to pass the item names directly to the rule class

class MyRule(HABApp.Rule):
    def __init__(self, item1: str, item2: str):
        self.switch = SwitchItem.get_item(item1)
        self.sensor = NumberItem.get_item(item2)
        ...

MyRule('my_item1', 'my_next_item1')
MyRule('my_item2', 'my_next_item2')
MyRule('my_item3', 'my_next_item3')

That way you get error messages if an item is missing and/or has not the correct type.

Good news everyone!

I just released HABApp 0.31.1!

This release brings support for item metadata and EventListenerGroup

Changelog:

  • Added support for item metadata
  • Added possibility to search for items by metadata
  • Added EventListenerGroup to subscribe/cancel multiple listeners at once
  • Z-Wave table doesn’t show the linked items any more

Metadata

All openhab items have an additional member variable called metadata.
It contains the complete item metadata from the item definition.

*.items file

 SwitchItem MySwitch (MyGroup)  [MyTag]  {homekit="Valve" [MinTemp=12]}

Code:

from HABApp.openhab.items import SwitchItem

sw = SwitchItem.get_item('MySwitch')
sw.metadata['homekit'].value   # <-- 'Valve'
sw.metadata['homekit'].config  # <-- {'MinTemp': 12}

It’s also possible to search for items by metadata

class MyRule(HABApp.Rule):
    def __init__(self):
        super().__init__()

       # This returns all homekit items
       for homekit_item in self.get_items(metadata='homekit'):
           print(homekit_item)

       # This returns all homekit items which are a valve
       for homekit_valve in self.get_items(metadata='homekit', metadata_value='Valve'):
           print(homekit_valve)

EventListenerGroup
EventListenerGroup is a helper class which allows to subscribe to multiple items at once.
All subscriptions can be canceled together, too.
This is useful if e.g. something has to be done once after a sensor reports a value.

This is a rule which will turn on the lights once (!) in a room on the first movement in the morning.
The lights will only turn on after 4 and before 8 and two movement sensors are used to pick up movement.

    from datetime import time

    from HABApp import Rule
    from HABApp.core.events import ValueChangeEvent
    from HABApp.openhab.items import SwitchItem, NumberItem
    from HABApp.util import EventListenerGroup

    class EventListenerGroupExample(Rule):
        def __init__(self):
            super().__init__()
            self.lights = SwitchItem.get_item('RoomLights')
            self.sensor_move_1 = NumberItem.get_item('MovementSensor1')
            self.sensor_move_1 = NumberItem.get_item('MovementSensor2')

            # use the defaults so we don't have to pass the callback and event filter in add_listener
            self.group = EventListenerGroup(default_callback=self.sensor_changed, default_event_filter=ValueChangeEvent).\
                add_listener(self.sensor_move_1).add_listener(self.sensor_move_1)

            self.run.on_every_day(time(4), self.listen_sensors)
            self.run.on_every_day(time(8), self.sensors_cancel)

        def listen_sensors(self):
            self.group .listen()

        def sensors_cancel(self):
            self.group .cancel()

        def sensor_changed(self, event):
            self.group .cancel()
            self.lights.on()

    EventListenerGroupExample()
2 Likes

Good news everyone!

I just released HABApp 0.31.2!

This is a small release which brings a reworked EventListenerGroup, a small splash screen and better output in case of missing dependencies.

Changelog:

  • Added command line switch to display debug information
  • Display debug information on missing dependencies
  • Added a small splash screen when HABApp is started
  • May doc updates
  • Reworked EventListenerGroup

The EventListenerGroup now takes items as an iterable in .add_listener and the other functions.

    class EventListenerGroupExample(Rule):
        def __init__(self):
            super().__init__()
            self.lights = SwitchItem.get_item('RoomLights')
            self.sensor_move_1 = NumberItem.get_item('MovementSensor1')
            self.sensor_move_2 = NumberItem.get_item('MovementSensor2')

            # use the defaults so we don't have to pass the callback and event filter in add_listener
            self.group = EventListenerGroup().add_listener(
                [self.sensor_move_1, self.sensor_move_2], self.sensor_changed, ValueChangeEvent)

            self.run.on_every_day(time(4), self.listen_sensors)
            self.run.on_every_day(time(8), self.sensors_cancel)

        def listen_sensors(self):
            self.listeners.listen()

        def sensors_cancel(self):
            self.listeners.cancel()

        def sensor_changed(self, event):
            self.listeners.cancel()
            self.lights.on()
3 Likes