HABApp - Easy automation with openHAB

HABApp 0.30.1 is out!

@domoticaundici
The new version fixes your issue, it was just with the generated file, the item was created correctly.

1 Like

hello @Spaceman_Spiff ! many many thanks! it works great now

Troubles installing HABapp.
Iā€™m trying to give HABApp a try but I am unable to install it. I am using OH3 on a raspberry pi 3 v1.2 with an openhabian image. I upgraded through openhabian-config to version 3.1 milestone 4. The openhabian script updated itself today. I also performed an update of raspberry-pi os, always through the openhabian interface

Installing HABApp always give an error. I set the debug log to maximum and it turns out that there is an error when performing pip install habapp. I therefore tried to issue directly the command

 sudo  python3 -m pip install  habapp

But it always end up with an error about a directory not found. Maybe it is a silly mistake but I canā€™t figure out how to proceed. I would like to avoid starting completely fresh with a new openhabian install, if possible.
The output of the pip command is the following

 sudo  python3 -m pip install  habapp
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting habapp
  Using cached https://files.pythonhosted.org/packages/b3/71/6947575f5004c5abd6badf07f4b05edbb7c10cce1ce626552a132dd42017/HABApp-0.30.1-py3-none-any.whl
Collecting pendulum==2.1.2 (from habapp)
  Using cached https://files.pythonhosted.org/packages/db/15/6e89ae7cde7907118769ed3d2481566d05b5fd362724025198bb95faf599/pendulum-2.1.2.tar.gz
  Installing build dependencies ... done
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/usr/lib/python3.7/tokenize.py", line 447, in open
        buffer = _builtin_open(filename, 'rb')
    FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pip-install-dbvsk_wj/pendulum/setup.py'

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-dbvsk_wj/pendulum/
o

Can you give some hint?
Thank you

The version of pip is too old - you have to upgrade it first:

python -m pip install --upgrade pip
1 Like

Thanks for your answer. I actually had to use a slightly different syntax

python3 -m pip install --upgrade pip

But then the openhabian menu to install hab app still give the same error.
Strange enough if I issue the install command directly,

 python3 -m pip install --upgrade habapp

it installs everything.
I am wondering wether there is some issue with openhbian installing packages as superuser.

At the end of the installation as normal user, I get some warnings,

  WARNING: The script watchmedo is installed in '/home/openhabian/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
  WARNING: The script habapp is installed in '/home/openhabian/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.

Are these warnings significant?

1 Like

I was under the impression that you are working with the instruction and are working in the venv.
If you follow the instructions there will be no warning and everything works fine!
Please donā€™t try anythign else!

I followed instructions and the warnings are gone. Thanks

create_channel_link geves an error. trying to execute

itemName=ā€œadessoā€
if not HABApp.openhab.interface.item_exists(itemName):
HABApp.openhab.interface.create_item(ā€œDateTimeā€, itemName, label=ā€˜Data e oraā€™, category=ā€˜timeā€™, tags=[], groups=[], group_type=ā€™ā€™, group_function=ā€™ā€™, group_function_params=[])if HABApp.openhab.interface.item_exists(itemName) and not HABApp.openhab.interface.channel_link_exists(ā€œntp:ntp:local:dateTimeā€, itemName):
HABApp.openhab.interface.create_channel_link(ā€œntp:ntp:local:dateTimeā€, itemName)

unable to create items with starting capital

HABApp.openhab.interface.create_item(ā€˜Numberā€™, ā€˜HABApp_Pingā€™, label=ā€˜HABApp_Pingā€™, category=ā€™ā€™, tags=[], groups=[], group_type=ā€™ā€™, group_function=ā€™ā€™, group_function_params=[])

replacing HABApp_Ping with habAppPing (also in config.yml) works perfectly

This definitely works, there is probably something else wrong.
Can you please use proper code fences, post the complete rule and the corresponding log entries?
Posting just the snippets makes me think that you try to run these themselves wich you should not.

when habAppPing was HABApp_Ping didnā€™t worked for me :thinking:

  • There is no need to modify sys.path - donā€™t do it!
  • You have not used Backticks ``` as a code fence, this is a screenshot
  • You have not shown the log entry, if there is an error HABApp will generate a log entry.
    How am I supposed to see what is wrong from a screenshot?
  • In a rule you use self.oh or self.openhab instead of HABApp.openhab.interface

Yes, Sir :slight_smile: i will improve my coding skills. iā€™ve started some days ago with habapp and is very useful. thanks for your work! anyway go straight to the problem

when i issue the command
HABApp.openhab.interface.create_item(ā€˜Numberā€™, ā€˜HABApp_Pingā€™, label=ā€˜HABApp_Pingā€™, category=ā€˜ā€™, tags=, groups=, group_type=ā€˜ā€™, group_function=ā€˜ā€™, group_function_params=)

log says

2021-05-13 16:48:56.972 [WARN ] [rest.core.internal.item.ItemResource] - Received HTTP PUT request at ā€˜items/HABApp_Ping/ā€™ with an invalid item name ā€˜HABApp_Pingā€™.

For me this works:

self.openhab.create_item('Number', 'HABApp_Ping')

Are you sure there arenā€™t any special characters?
Also please check the HABApp.log

copy/paste of your line ā†’ same result
==> /var/log/openhab/openhab.log <==

2021-05-13 17:37:34.837 [WARN ] [rest.core.internal.item.ItemResource] - Received HTTP PUT request at ā€˜items/HABApp_Ping/ā€™ with an invalid item name ā€˜HABApp_Pingā€™.

You are looking in the openhab.log, not the HABApp.log.
Maybe the item already exists (my guess) or there is an non ascii character you are entering.

nope, iā€™ve added HABApp.log in frontail. anyway is not blocking for me. thank you anyway

I have a few rules that take a couple of seconds complete, because e.g. theyā€™re polling an external website which is slow to respond. That makes HABApp complain about how slow the rule is running, so Iā€™ve stopped this by having the HABApp rule launch a separate thread that polls the website.

For example:

class ReadBins(HABApp.Rule):

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

        self.run.on_every_day(datetime.time(9, 00), self.bins) 
        self.run.on_every_day(datetime.time(12, 30), self.bins) 
        self.run.on_every_day(datetime.time(21, 00), self.bins) 

    
    def bins(self): 
        
        log("BINS: Checking bin dates...")
        threading.Thread(target=BinThread).start()
       

Question is: is this a bad idea? Am I risking trouble by having rules launch independent threads? Will the new thread count towards the maximum 10 threads that HABApp permits?

@Spaceman_Spiff, Iā€™d be grateful for your thoughts!

thanks,

Dan

Yes and totally unnecessary. While it does not account to the 10 threads things might not work as expected e.g. when error occurs or when rules get reloaded.

There are other more elegant ways to do it:

You can run it as an async function (but make sure your logic is non-blocking, e.g. no (IO) wait!!):

    async def bins(self):
        resp = await self.async_http.get('http://slow.website/bla')
        assert resp.status == 200
        data = await resp.json()
        
        # Process, but pay attention to only use non-blocking function
        # Ensure that there are no blocking library calls, when in 
        # doubt rather use the next option.
        # Blocking calls will prevent HABApp from working properly.
        for d in data:
            print(d)
            
        # If you are unsure just process the data with the worker
        # All processing is done in the process_bin() function so it doesn't matter
        # if it is blocking
        self.run.soon(self.process_bin, data)

    def process_bin(self, data: dict):
        # blocking is okay here
        time.sleep(0.3)

Another way would be to run it as a subprocess. That way you have a real subprocess and can do cpu bound operations which can run in parallel:

import ast, sys

    def bins(self):
        self.execute_subprocess(self.process_bin, sys.executable, 'c:/folder/my_script.py')

    def process_bin(self, data):
        assert data.returncode == 0
        _dict = ast.literal_eval(data.stdout)
        print(_dict)        
2 Likes

thanks - I will do that!