HABApp - Easy automation with openHAB

thanks!

I took a little look at HABApp a while ago, but couldnā€™t see an obvious way to have events triggered by multiple items or groups, and then identify the item that had triggered the event. Can that now be done?

Yes, that is possible. You get the name of the triggering item as part of the event

thanks - are there any examples of that anywhere? If not, Iā€™d be most grateful if you could post oneā€¦

Here you can see that the event passed into the callback contains the triggering item.
You can subscribe with the same callback to multiple items or create a rule that groups things logically.

e.g.

for name in ('MySwitch1', 'MySwitch2', 'MySwitch3'):
    SwitchItem.get_item(name).listen_event(self.my_callback, ValueChangeEvent)
    # or if its different items you can use the base class
    OpenhabItem.get_item(name).listen_event(self.my_callback, ValueChangeEvent)

Also HABApp allows you to trigger when an item is constant since last update/change for a certain ammount of time which makes so much timer stuff obsolete itā€™s mind blowing :wink:

Dan, it is good that Jython is working fine for you. It was mainly working for me as well, but there were a few annoying issues with the integration of the script engine and OH, and then there is the issue of the Jython implementation of Python itself. I wrote a post comparing the two at HABApp vs JSR223 Jython. Ultimately it is a personal choice :slight_smile: .

1 Like

Seb, is the use of authorization token on your radar (so that we donā€™t have to turn off authentication in OH 3)?

@yfaway Sort of:
Iā€™ve a small PR open since 11th of January that fixes the performance issues for basic auth in openhab but somehow the openhab maintainers are very selective of whom they want to contribute and refuse to review the PR (this is the second PR which got some improvements, the first PR was opened even earlier).
This would have been a quick fix for all the basic auth issues and make HABApp work with the expected speed again.

Using a token in the header is on my list, but I have to do some investigation first because Iā€™m using multiple libraries and I am currently worried that I have to implement the handling in one of them (SSE event listener) myself.


It definitely is.
On the one hand it adds additional complexity since itā€™s an additional tool and also not everything is exposed through the rest api (e.g. actions) so for very rare cases itā€™s necessary to work with proxy items.
On the other hand itā€™s a complete home automation rule engine written in python and while it does almost everything different than the build in rule engine it (imho) does everything better:
Error messages, timers, multiple ā€œexpiresā€ per item, time stamps for last_change and last_update of an item, dynamic rule creation, accessing item per name, parameter files, textual thing configuration etcā€¦

@dan12345
Itā€™s a steep learning curve but I really encourage you to try it out. Iā€™ve been on the jsr223 track since openhab 1.8 and after the first enthusiasm it almost killed my excitement for home automation.
You can install HABApp on your main PC and connect remotely to your openhab instance (if you want in listen_only mode so it doesnā€™t make changes). That way you can play around and try to get the hang of it without having to make changes to your installation.
This rule shows you that itā€™s possible to write very compact and readable code that covers a somewhat complex use case.

1 Like

Thanks - Iā€™d missed that postā€¦ itā€™s really helpful. When I have a spare weekend I should have a real think about transitioning.

I will do - thanks!

One question: How do i acces the members of a group?

self.openhab.get_item('group_name') will return the complete openhab item definition.
For groups there is an object ā€œmembersā€ which will contain all items.

Be aware that this is a sync call (a request which goes to openhab), so even though this shouldnā€™t take too long depending on the item it might add up.
If you use it to set up your rules or use the item names to create a list of items it should be no problem.

Thanks a lot. That exactly my intention. Put ally my thermostats in a group and use the groups to create the rules.

It would be great is rules are reloaded if the numer of members in the group changes, but i this that is not possible.

Thanks
Thomas

I am not sure but maybe openhab issues a ItemChangedEvent when you add/remove items to the group. You can trigger on it and then issue a FileReloadEvent which will make HABApp reload your rule file.
If you want to create rule classes you have to use HABApp.openhab.interface.get_item('group_name') to get the definition.

Two additional remarks:

  1. How often do you really add thermostats? Is it really work the effort to implement some logic or may it enough to touch the rule file when you added a thermostat to openhab?

  2. As always Iā€™ll recommend to use a good naming scheme or parameter files to setup rules instead of using groups. That way youā€™ll always have a defined set of rules and get error messages if your items do not exist instead of a rule just disappearing.

Thanks for your hints. On your remarks:

to 1: Yeah i see your point. But as always: It is good to know many possibilities to do things and i love to have thing totally automated. At the end: If have included all thermostats i will never touch the group again, because there are no places for new thermostats left :slight_smile:

to 2: Naming schemes are a difficult thing, but i think mine is OK. I see location of the things and within a class of thing the differnet item have the same extension like stae, temperature, ā€¦

Hi all,

again, canā€™t figure out what Iā€™m doing wrong. So maybe posting will help me solve it on my own (which often happens) or I get some generous help from the community.

Iā€™ve gotten HABApp installed. I can run the two test scripts and see output on the console, but if I try to interact with an OpenHAB item, I am unsuccessful:

import HABApp
from HABApp.core.items import Item

class MyFirstRule(HABApp.Rule):
    def __init__(self):
        super().__init__()
        # Get the item or create it if it does not exist
        self.my_item = Item.get_create_item('T_TestString')

        self.run_soon(self.say_something)

    def say_something(self):
        # Post updates to the item through the internal event bus
        self.my_item.post_value('Test')
        self.my_item.post_value('Change')

        # The item value can be used in comparisons through this shortcut ...
        if self.my_item == 'Change':
            print('Item value is "Change"')
        # ... which is the same as this:
        if self.my_item.value == 'Change':
            print('Item.value is "Change"')
 
print('hello')
MyFirstRule()

If I use an existing item in my OpenHAB environment, it failsā€¦ if I add a digit to the end of the name to make it a new item, the script works. From the error in the logs, it does look like it retrieves a value from T_TestString, however, before failing.

[2021-02-22 09:17:37,081] [             HABApp.Rules]    ERROR | File "/etc/openhab/habapp/rules/test.py", line 9, in __init__
[2021-02-22 09:17:37,081] [             HABApp.Rules]    ERROR |     6    def __init__(self):
[2021-02-22 09:17:37,081] [             HABApp.Rules]    ERROR |     7        super().__init__()
[2021-02-22 09:17:37,082] [             HABApp.Rules]    ERROR |     8        # Get the item or create it if it does not exist
[2021-02-22 09:17:37,082] [             HABApp.Rules]    ERROR | --> 9        self.my_item = Item.get_create_item('T_TestString')
[2021-02-22 09:17:37,082] [             HABApp.Rules]    ERROR |     10
[2021-02-22 09:17:37,082] [             HABApp.Rules]    ERROR |     ..................................................
[2021-02-22 09:17:37,082] [             HABApp.Rules]    ERROR |      self = </etc/openhab/habapp/rules/test.py.MyFirstRule object at 0xb236fad0>
[2021-02-22 09:17:37,083] [             HABApp.Rules]    ERROR |      self.my_item = # AttributeError
[2021-02-22 09:17:37,083] [             HABApp.Rules]    ERROR |           self = </etc/openhab/habapp/rules/test.py.MyFirstRule object at 0xb236fad0>
[2021-02-22 09:17:37,083] [             HABApp.Rules]    ERROR |     ..................................................
[2021-02-22 09:17:37,083] [             HABApp.Rules]    ERROR |
[2021-02-22 09:17:37,083] [             HABApp.Rules]    ERROR | File "/opt/habapp/lib/python3.7/site-packages/HABApp/core/items/item.py", line 24, in get_create_item
[2021-02-22 09:17:37,084] [             HABApp.Rules]    ERROR |     9    def get_create_item(cls, name: str, initial_value=None):
[2021-02-22 09:17:37,084] [             HABApp.Rules]    ERROR |  (...)
[2021-02-22 09:17:37,084] [             HABApp.Rules]    ERROR |     20       except HABApp.core.Items.ItemNotFoundException:
[2021-02-22 09:17:37,084] [             HABApp.Rules]    ERROR |     21           item = cls(name, initial_value)
[2021-02-22 09:17:37,085] [             HABApp.Rules]    ERROR |     22           HABApp.core.Items.add_item(item)
[2021-02-22 09:17:37,085] [             HABApp.Rules]    ERROR |     23
[2021-02-22 09:17:37,085] [             HABApp.Rules]    ERROR | --> 24       assert isinstance(item, cls), f'{cls} != {type(item)}'
[2021-02-22 09:17:37,085] [             HABApp.Rules]    ERROR |     25       return item
[2021-02-22 09:17:37,085] [             HABApp.Rules]    ERROR |     ..................................................
[2021-02-22 09:17:37,086] [             HABApp.Rules]    ERROR |      cls = <class 'HABApp.core.items.item.Item'>
[2021-02-22 09:17:37,086] [             HABApp.Rules]    ERROR |      name = 'T_TestString'
[2021-02-22 09:17:37,086] [             HABApp.Rules]    ERROR |      initial_value = None
[2021-02-22 09:17:37,086] [             HABApp.Rules]    ERROR |      HABApp.core.Items.ItemNotFoundException = <class 'HABApp.core.Items.ItemNotFoundException'>
[2021-02-22 09:17:37,087] [             HABApp.Rules]    ERROR |      item = <StringItem name: T_TestString, value: Hello!, last_change: 2021-02-22 09:14:16.396357, last_update: 2021-02-22 09:14:16.396357>

Not sure if I have something configured wrong or it is a failure of my understanding of how this is supposed to work.

Hi,

Item.get_create_item('T_TestString') does create a local item which only exists in HABApp.
You can use those to share stuff between rules/files and as general proxy items.
If you want to use the items from openhab you have to do it like this:

from HABApp.openhab.items import StringItem
....
self.my_item = StringItem.get_item('T_TestString')

It fails because you try to create a local item and for the same name there is already an existing openhab item.

Just an pointer from my battle ground - the SSE stuff required me to get cookie processing. Not sure which side of SSE you are (OH or middle ground) - but that was the way for OH to actually pass auth stuff.

1 Like

Hi Seb, I do not think HABapp supports event like this in Xtend ah?

Item PARTITION1_ARM_MODE received command 1

Is it a limitation of the OH REST API?

Of course itā€™s possible with HABApp.
Itā€™s even possible to listen to any part of the event and combine them as desired (see second part of events description).

For the most common events I have created convenience filters that provide type hints.
E.g.

  • ValueUpdateEventFilter and ValueChangeEventFilter
  • MqttValueUpdateEventFilter and MqttValueChangeEventFilter
  • ItemStateEventFilter and ItemStateChangedEventFilter