HABApp - Easy automation with openHAB

This looks really nice,

I have quite a few python servers all reading item states and forwarding then to various other devices, both into and out of OH.

They used to use websockets, until that was dropped, now they use complicated requests to get data from/to the REST interface.

One interface first discovers all items, then uses streaming to get updates and push the results as json to an iPad used as an interface.

All of this stuff would have been much easier with this library.

Suggestion, add a way of getting items and groups from OH, so that you can automate item discovery. Otherwise you constantly have to update item names in two locations (OH and HABapp application).

It’s fairly easy to do via REST, but parsing the massive dictionary you get back is a bit of a task.

I have 3 or 4 applications where I could use this immediately. I normally use mqtt because the REST interface is a pain. This looks like it may ease the pain.

If it uses asyncio, what version of python do you need (I use 3.6), and is it Thread safe?

Great work by the way. I will try this out tomorrow, I have a use for it right now!

Hi, first of all beware this is currently beta. Things might still change.
Currently HABApp requires Python 3.6 so you should be good to go.
Maybe it would be easier for you to get an MQTT server running so you can communicate between all your devices? HABApp works seamlessly with them.

This is already done and you can access the local cache with

self.item_exists(item_name)
self.item_state(item_name)

If I understand you correctly you want to subscribe to all changes so you can forward them.
I could add a function which just returns all items. You could use this to listen to all updates.
What do you think?

What do you mean with thread safe?

Hi,

while migrating my rules I found some bugs when creating invalid rules.
Bugfix is already available (0.0.5)

I have uploaded Version 0.1.1 which includes a couple of fixes and improvements.

Having migrated almost all of my rules I have to say I am very happy.
HABApp is really fast and easy on the system (< 35 MB RAM usage).
But most importantly writing rules is fun again! :slight_smile:

It would be really nice If someone else could try it out - I’d really love some feedback!

2 Likes

Is this meant to be an equivalent to Appdaemon in the Home Assistant world? My house is primarily z wave based, so I have often thought about trying out Openhab again, but I am pretty happy with appdaemon.

Perhaps a bit off topic, but how is you impression of the difference of the two systems and what makes z wave better on openhab in your opinion?

That’s exactly what it is! Although I tried to make it better (of course :wink: ).
The nice thing is that openhab runs Z-Wave under any OS, so you can just shut down your HassIO instance and boot openhab on your main computer and try stuff out. Once you are done you plug the z-wave stick back into your HassIO instance and everything is back to the way it was.
That’s actually how I do my migraion from openhab1 at the moment :slight_smile:

Z-Wave on openhab just runs - no need to fuddle around with openzwave, entity configuration. For Z-Wave to work I had very long restart times, I don’t have with openhab. Also inclusion/exclusion of devices and setting device configuration is much easier. Having to rename the automatically created entities was a pain, too. The energy consumption of devices did often not work, since the “senser_multilevel” instead “meter_w” command class is required. Also the automatically created entities did not always work properly (I have a heating controller that did not work with Hass).
Since it is possible to do textual configuration of the devices and things the Z-Wave configuration is persistent and nice again (although not as mighty as in openhab1).

I have uploaded Version 0.1.3. It includes fixes for

self.run_on_workdays
self.run_on_weekends

I have introduced some performance fixes and migrated almost all my rules to HABApp.
V0.2.3 runs very well: on average < 1% CPU and ~2% RAM usage on the Odroid C2.

1 Like

After major refactoring I added the possibility for parameter files in V0.3.0:

        self.p1 = self.get_rule_parameter('param_file', 'key')

        self.p1 < 10         # comparison works out of the box
        self.p1.get_value()  # custom data can be obtained through this function

this will automatically create (on first) run the param_file.yml in the param directory.

key: 10

The value will always be looked up during comparison, so this adds the possibility to change boundaries without having to reload any rules. The file contents are kept in sync through a file-watcher so parameter lookup is almost instant.

1 Like

Update 0.3.9

  • moved mqtt interaction to self.mqtt
  • moved openhab interaction to self.oh or self.openhab
  • more stable connection and error handling
  • items get updated from openhab after every reconnect
  • added some type hints
  • added more examples (e.g. how to mirror all openhab updates to mqtt)

Update 0.4.7

Also added a nice gif :wink:

3 Likes

@Spaceman_Spiff
Do you also have some complex ruleset for a complete house (your house? :wink: for example) ?

I am unsure how to structure the python code for a complete smart home with a lot of sensors and actuators. Temperature/Humidity, Window/Door contacts, Push Buttons, Power/Gas Metering (washing maschine, complete house, Heating), Lights, Blinds, Weather station (light, wind, temperature), Sonos, Hue, Motion Detectors, Smoke Detectors and Heating Control for each room, etc…

Ok, of course it depends on what I want to achieve…

Yes of course - I migrated all my rules.

I created subfolders with the room names and moved specific rules there (e.g. lights) and my general rules are placed directly in the rules folder.
Otherwise I log a lot of information (for debugging) and then it just grows naturally. :wink:

Ok.

Have you created python objects (e.g. with get/set) from the items and used those in the rule objects?
Or are your only objects just the rules? I hope you know what I mean…

BTW: If you can’t remember all the MQTT topics immediately, it is helpful to use a tool like MQTT.fx.
It has a builtin MQTT topics collector which scans for new topics and puts them in a list.
You can then simply right-click on the topic and copy the string to the editor where you edit your MQTT rules for HABapp.

Dream: it would be really cool, if Visual Studio Code would have an extension which autocompletes such MQTT topics or OpenHAB items while typing.

Update 0.4.8

  • Added the possibility to start external processes
  • Lots of documentation

Example

import HABApp

class MyExecutionRule(HABApp.Rule):

    def __init__(self):
        super().__init__()

        self.execute_subprocess( self.func_when_finished, 'path_to_program', 'arg1', capture_output=True)

    def func_when_finished(self, process_info):
        assert isinstance(process_info, HABApp.rule.FinishedProcessInfo)
        print(process_info)

MyExecutionRule()

Yes - I only use the rules because I can easily get the state with self.get_item_state and set it with self.set_item_state.
What I sometimes do is use another rule and its functions to keep small logical units properly abstracted, e.g.:

class RuleA:
    def do_sth_a():
       pass
MyRuleA = RuleA()

class RuleB:
    def do_sth_b():
       MyRuleA.do_sth_a()
RuleB()

Another question:
If I have each rule in its own file, can I instantiate each rule in some global file?
I assume that each rule runs in the same context, right?
Would it be possible to use global variable if needed?

It is not clear for me how all my created files are related to each other and related to HapAPP.
Are the rule files (normal Python files?) just collected and concatenated or how does it work?

There is the possibility to get a rule instance by name so there is no need for global variables.

Each python file you create is loaded independently as you can see in the HABApp.log.
So if you want to share Rule instances you can use the function to get it by name or put the rules that require each other in one file as I showed in the example above :slight_smile:

Update 0.4.9

  • Reconnect on SEE event error should now work as intended
  • Caught an error when connecting to Openhab and Openhab is not ready
  • Added possibility to wait before starting HABApp
  • Reformatted error traceback in rules
  • Added example for ValueNoChangeEvent