HABApp - Easy automation with openHAB

It seems I already did some work on it.

It has been and always will be ongoing and I am happy for everyone who is willing to help. :slight_smile:

Ah, excellent.

Yes, My guess; this is where the real work have to be done.

Should actually be pretty easy - just take the configuration of the thing, add the item name (after it was created) to linkedItems and post it to the thing/config endpoint again.

This would actually make a pretty nice feature:
AutoLink, where the thing-type gets specified and the items get created and linked automatically after the specified schema.

1 Like

Regarding the auto-link feature from a schema: this is basically what OpenHAB *.items files are in my opinion. That works great, but is somehow tedious. But creating those automatically without deeper knowledge of the device is hard I think.

For example: the automatically created item in OpenHAB for the DecalcificationTime had the Time type in OpenHAB, but it is just the number of minutes since midnight which fails parsing for a time of course.

I looked at the Api documentation and there is a links/ endpoint that allows working with links directly based on itemname and channelUID, both available already. Simple CRUD methods could be enough to be able to work with it in conjunction with get_thing.

1 Like

Yes, and probably varies on different use cases too.
In my case I need about 20 magnet sensors just for my livingroom heatpump.

Hi Guys I managed to send a command via habapp and turn on a switch :smiley: the following both worked for me as intended:

self.oh.send_command("testsw1","ON") 

myswitch = SwitchItem.get_item("testsw1")
        myswitch.on()

In the Habapp Log I see the following errors even though everything works as intended:

[2020-04-26 09:22:01,915] [                   HABApp]    ERROR | Error <class 'NoneType'> in on_sse_event:
[2020-04-26 09:22:01,915] [                   HABApp]    ERROR | Traceback (most recent call last):
[2020-04-26 09:22:01,915] [                   HABApp]    ERROR |   File "/Users/thomasbecker/PycharmProjects/PycharmProjects/Privat/HabApp/lib/python3.7/site-packages/HABApp/openhab/oh_connection.py", line 117, in on_sse_event
[2020-04-26 09:22:01,915] [                   HABApp]    ERROR |     event = get_event(event_dict)
[2020-04-26 09:22:01,916] [                   HABApp]    ERROR |   File "/Users/thomasbecker/PycharmProjects/PycharmProjects/Privat/HabApp/lib/python3.7/site-packages/HABApp/openhab/map_events.py", line 38, in get_event
[2020-04-26 09:22:01,916] [                   HABApp]    ERROR |     return __event_lookup[event_type].from_dict(topic, payload)
[2020-04-26 09:22:01,916] [                   HABApp]    ERROR |   File "/Users/thomasbecker/PycharmProjects/PycharmProjects/Privat/HabApp/lib/python3.7/site-packages/HABApp/openhab/events/item_events.py", line 19, in from_dict
[2020-04-26 09:22:01,916] [                   HABApp]    ERROR |     return cls(topic[16:-6], map_openhab_values(payload['type'], payload['value']))
[2020-04-26 09:22:01,916] [                   HABApp]    ERROR |   File "/Users/thomasbecker/PycharmProjects/PycharmProjects/Privat/HabApp/lib/python3.7/site-packages/HABApp/openhab/map_values.py", line 9, in map_openhab_values
[2020-04-26 09:22:01,916] [                   HABApp]    ERROR |     assert isinstance(openhab_value, str), type(openhab_value)
[2020-04-26 09:22:01,916] [                   HABApp]    ERROR | AssertionError: <class 'NoneType'>
[2020-04-26 09:22:01,942] [                   HABApp]    ERROR | Error <class 'NoneType'> in on_sse_event:
[2020-04-26 09:22:01,942] [                   HABApp]    ERROR | Traceback (most recent call last):
[2020-04-26 09:22:01,942] [                   HABApp]    ERROR |   File "/Users/thomasbecker/PycharmProjects/PycharmProjects/Privat/HabApp/lib/python3.7/site-packages/HABApp/openhab/oh_connection.py", line 117, in on_sse_event
[2020-04-26 09:22:01,942] [                   HABApp]    ERROR |     event = get_event(event_dict)
[2020-04-26 09:22:01,942] [                   HABApp]    ERROR |   File "/Users/thomasbecker/PycharmProjects/PycharmProjects/Privat/HabApp/lib/python3.7/site-packages/HABApp/openhab/map_events.py", line 38, in get_event
[2020-04-26 09:22:01,942] [                   HABApp]    ERROR |     return __event_lookup[event_type].from_dict(topic, payload)
[2020-04-26 09:22:01,942] [                   HABApp]    ERROR |   File "/Users/thomasbecker/PycharmProjects/PycharmProjects/Privat/HabApp/lib/python3.7/site-packages/HABApp/openhab/events/item_events.py", line 19, in from_dict
[2020-04-26 09:22:01,942] [                   HABApp]    ERROR |     return cls(topic[16:-6], map_openhab_values(payload['type'], payload['value']))
[2020-04-26 09:22:01,942] [                   HABApp]    ERROR |   File "/Users/thomasbecker/PycharmProjects/PycharmProjects/Privat/HabApp/lib/python3.7/site-packages/HABApp/openhab/map_values.py", line 9, in map_openhab_values
[2020-04-26 09:22:01,942] [                   HABApp]    ERROR |     assert isinstance(openhab_value, str), type(openhab_value)
[2020-04-26 09:22:01,943] [                   HABApp]    ERROR | AssertionError: <class 'NoneType'>

How can i correct those?

Hm, strange. Can you download the current Dev Branch from github and try it again?
You can just copy all files from the HABApp directory to
/Users/thomasbecker/PycharmProjects/PycharmProjects/Privat/HabApp/lib/python3.7/site-packages/HABApp

will do tomorrow

Thats weird i know get this:

[2020-04-28 11:58:08,544] [HABApp.openhab.Connection]     INFO | Updated 88 Things
[2020-04-28 11:58:11,942] [             HABApp.Rules]    ERROR | Error "name 'self' is not defined" in load:
[2020-04-28 11:58:11,942] [             HABApp.Rules]    ERROR | Could not load /Users/thomasbecker/PycharmProjects/PycharmProjects/Privat/HABApp/rules/Motion.py!
[2020-04-28 11:58:11,942] [             HABApp.Rules]    ERROR | File /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/runpy.py, line 263, in run_path
[2020-04-28 11:58:11,942] [             HABApp.Rules]    ERROR |     239  def run_path(path_name, init_globals=None, run_name=None):
[2020-04-28 11:58:11,942] [             HABApp.Rules]    ERROR |  (...)
[2020-04-28 11:58:11,942] [             HABApp.Rules]    ERROR |     259          # Not a valid sys.path entry, so run the code directly
[2020-04-28 11:58:11,942] [             HABApp.Rules]    ERROR |     260          # execfile() doesn't help as we want to allow compiled files
[2020-04-28 11:58:11,943] [             HABApp.Rules]    ERROR |     261          code, fname = _get_code_from_file(run_name, path_name)
[2020-04-28 11:58:11,943] [             HABApp.Rules]    ERROR |     262          return _run_module_code(code, init_globals, run_name,
[2020-04-28 11:58:11,943] [             HABApp.Rules]    ERROR | --> 263                                  pkg_name=pkg_name, script_name=fname)
[2020-04-28 11:58:11,943] [             HABApp.Rules]    ERROR |     264      else:
[2020-04-28 11:58:11,943] [             HABApp.Rules]    ERROR |     ..................................................
[2020-04-28 11:58:11,943] [             HABApp.Rules]    ERROR |      path_name = '/Users/thomasbecker/PycharmProjects/PycharmProjects/Privat/
[2020-04-28 11:58:11,943] [             HABApp.Rules]    ERROR |                   HABApp/rules/Motion.py'
[2020-04-28 11:58:11,943] [             HABApp.Rules]    ERROR |      init_globals = {'__HABAPP__RUNTIME__': <HABApp.runtime.runtime.Runtime obje
[2020-04-28 11:58:11,943] [             HABApp.Rules]    ERROR |                      ct at 0x106c96e10>,
[2020-04-28 11:58:11,943] [             HABApp.Rules]    ERROR |                      '__HABAPP__RULE_FILE__': <HABApp.rule_manager.rule_file.Rul
[2020-04-28 11:58:11,943] [             HABApp.Rules]    ERROR |                      eFile object at 0x108ddea20>,
[2020-04-28 11:58:11,943] [             HABApp.Rules]    ERROR |                      '__HABAPP__RULES': []}
[2020-04-28 11:58:11,943] [             HABApp.Rules]    ERROR |      run_name = '/Users/thomasbecker/PycharmProjects/PycharmProjects/Privat/
[2020-04-28 11:58:11,943] [             HABApp.Rules]    ERROR |                  HABApp/rules/Motion.py'

and so on. I didn’t change the code at all:

from HABApp.core.events import ValueUpdateEvent, ValueChangeEvent
from HABApp.openhab.events import ItemStateEvent, ItemCommandEvent, ItemStateChangedEvent
from HABApp.openhab.items import NumberItem
from HABApp.openhab.items import SwitchItem


class Motion(HABApp.Rule):
    
    def __init__(self):
        super().__init__()
        # Trigger on item updates
        self.listen_event('HueMotionEssbePresence', self.item_state_update, ValueUpdateEvent)
        
    def item_state_update(self, event):
        assert isinstance(event, ValueUpdateEvent)
        print(f'{event}')

       
        myswitch = SwitchItem.get_item("testsw1")
        myswitch.on()
        

Motion()

Hi @Tomibeck.

I copy-pasted your code and also received an error. Try adding import HABApp at the top.

Yes, its either

import HABApp

class Motion(HABApp.Rule):
....

or

from HABApp import Rule

class Motion(Rule):
....

Edit:

Protip
You should always create the items in __init__ and use them later in the rule.
This helps catching typos on file load and is generally less error prone:

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

class Motion(Rule):
    
    def __init__(self):
        super().__init__()
        # Trigger on item updates
        self.presence = NumberItem.get_item('HueMotionEssbePresence')
        self.presence.listen_event(self.item_state_update, ValueUpdateEvent)
        
        self.myswitch = SwitchItem.get_item("testsw1")
    
    def item_state_update(self, event: ValueUpdateEvent):
        if self.presence:
            self.myswitch.on()
        else:
            self.myswitch.off()


Motion()

Thats good stuff thanks. I will try this later. So its either creating all the Items in super init or directly interacting with the openhab itme for example via
self.oh.send_command(“testsw1”,“ON”)

I am not shure if this is out of place, but here goes:

I started to play around with the @noidea github rep,
and I could not find out how to extract all the Things.
I ended up copy/edit get_items into a get_things function.

Is there a list that includes all Things somewhere else i habapp?

I do not know the direction @Spaceman_Spiff intend to take HABApp in the future but with the Things I can write some cool rules just by looping thru the list:
A very generic battery status check
Get all offline Things
Get signal strength, neighbour and routing for Zigbee devices

The things and their status are already included in HABApp and loaded on connect.

import HABApp

for item in HABApp.core.Items.get_all_items():
    if isinstance(item, HABApp.openhab.items.Thing):
        print(f'{item.name}: {item.status}')

If you want further information like configuration you have to query openhab.
I’ll add a get_thing function in the dev branch

Edit:
Can you show an example how you would do a battery check?

Thank you! I look into that.

Hehe, no, on second tought, it would be better to just loop thru the Items :slight_smile:

On second thought on the second thought, I think I got it right the first time. One would need to see the “battery-level” part of the channel.

zwave:device:89aa3c34:node22:battery-level
hue:0106:1:SoveromNord_Lum:battery_level
zigbee:philips_sml001:01381602:0017880106f7e084:battery_level

And probably use the linked Item (if any) to read the battery level.

Some devices report a battery voltage. One could take some guesses about what a good voltage is.
Also, some devices have a battery alarm channel.

Devices can have channels for all 3 methods.

Im still reading into all the new-fangled things in Python, as I have not used it in 15 years or so.

If you have named your items properly it’s way easier to just iterate over all items and see if the end with “battery” (or however you have named them). I haven’t seen voltage yet, only percent.

Version 0.13.0


  • Textual configuration of Things can be spread out over multiple files
  • Extensive error messages and exception tracebacks with variable values
  • Rework of MultiModeItem:
    • moved into subpackage HABApp.util.multimode
    • create_mode is deprecated, modes get added by add_mode and can be subclassed
    • Added SwitchItemValueMode, a mode which can be enabled/disabled by a SwitchItem
  • added functions to work with OH rest/links/ endpoint (thx snpz)
  • added get_thing to the OpenhabInterface
  • BaseValueItem can be used in calculations (and subsequently all other item types, too),
    no more need to use the value property
    e.g.
    val = NumberItem('item1') + NumberItem('item2')
    is the same as val = NumberItem('item1').value + NumberItem('item2').value

Bugfix:

  • First call for scheduler with time of day for workday/weekend could have been wrong
  • ParamFiles get unloaded properly when file gets deleted

I really like the new SwitchItemValueMode:
With just one line of code I can disable all lower modes from the MultiModeItem from an openhab SwitchItem.
I use it to have the possibility disable my complex shutter rules and only allow manual movement of the shades. Example usage:

# use invert_switch to switch off, the next line does all the magic
automatic_off = SwitchItemValueMode('AutomaticOff', switch, invert_switch=True)
manual_mode = ValueMode('Manual')

item = MultiModeItem.get_create_item('MultiModeTestItem')
item.add_mode(100, automatic_off)
item.add_mode(101, manual_mode)
1 Like

I’m trying to install habapp but when I run the command “python3 -m pip install habapp” I have these errors:
ERROR: Could not find a version that satisfies the requirement astral==2.1
ERROR: Could not find a version that satisfies the requirement pydantic==1.5.1

What am I doing wrong?

Strange, I sucessfully installed it just yesterday.
Does the machine have proper internet access and can you install any package from pypi?