Python module for easily accessing the openHAB REST API

Quite some time ago I wrote a simple python library for interacting with openHAB1, which I am still using in various scripts for updating item states and sending commands etc.

Since I have recently switched to openHAB2, I have updated and considerably reworked and polished the library.

In case anybody is interested in using python for openHAB2 automation, give it a try:
https://github.com/sim0nx/python-openhab

The main purpose of the library is to interact with items, thus that is currently the only part which is implemented.
Work is in progress and any comments or requests are more than welcome.

Cheerz

6 Likes

Is this supporting post update?

/Mike

Both put and post are supported

Hi sim0nx,

I tried your code and I am receiving the following error when using
items = openhab.fetch_all_items()

>>> ================================ RESTART ================================
>>> 

Traceback (most recent call last):
  File "/Users/Guest/Public/python-openhab-master/test.py", line 34, in <module>
    items = openhab.fetch_all_items()
  File "/Users/Guest/Public/python-openhab-master/openhab/openhab.py", line 145, in fetch_all_items
    items[i['name']] = self.json_to_item(i)
  File "/Users/Guest/Public/python-openhab-master/openhab/openhab.py", line 180, in json_to_item
    return NumberItem(self, json_data)
  File "/Users/Guest/Public/python-openhab-master/openhab/items.py", line 45, in __init__
    self.init_from_json(json_data)
  File "/Users/Guest/Public/python-openhab-master/openhab/items.py", line 57, in init_from_json
    self.__set_state(json_data['state'])
  File "/Users/Guest/Public/python-openhab-master/openhab/items.py", line 100, in __set_state
    self._state = self._parse_rest(value)
  File "/Users/Guest/Public/python-openhab-master/openhab/items.py", line 198, in _parse_rest
    return float(value)
ValueError: could not convert string to float: gruen

The item probably causing this error has the following json representation.

    "link": "http://nac:8080/rest/items/Alarm_scharf_Diode",
    "state": "gruen",
    "stateDescription": {
      "pattern": "",
      "readOnly": false,
      "options": []
    },
    "type": "Number",
    "name": "Alarm_scharf_Diode",
    "label": "Alarm scharf",
    "category": "shield",
    "tags": [],
    "groupNames": [
      "Diodendisplay"
    ]
  },

I am using a transformation file containing the following contents

0=aus
1=rot
2=gruen
3=orange
NULL=NULL

It seems that the json file is containing the transformed value and not the numerical value which is 2 in my example

Hi Marty56,

I agree with your observation. Though I don’t quite understand why openhab is doing this, that doesn’t make sense to me.
I try to be somewhat “smart” by mapping openhab types to python types… which is also used for input validation.

That behavior of openhab breaks this.

To be hones I don’t see how I could work around this :-/

Don’t you have an identical item with real values ?

Hi sim0nx,

I have been using a pretty simple approach which seems to be working for string items.

import requests

#write String Item
data = 'some data'
requests.put('http://<ip o f OH of >:8080/rest/items/<item name>/state', data=data)

# retrieve String item
r = requests.get('http://<ip o f OH of >:8080/rest/items/<item name>/state')
data = r.content
1 Like

Hi All
(my first post)

@sim0nx I like your work.
I’m a noob but I’d like to learn this module.
Can you give some exemples for switch and contact?
I’m running openhab2 on raspberry pi 2 and I try to turn on/off a led.

My wrong code is

Items
Switch led "Led" (Lights) { gpio="pin:16" }

python-openhab

from openhab import openHAB
base_url = 'http://localhost:8080/rest'
openhab = openHAB(base_url)
# fetch all items
items = openhab.fetch_all_items()

gg = items.get('led')
print(gg.state)
gg.on()

OH2 printe OFF state and turn ON my switch but don’t turn ON my led
events.log
[ItemStateChangedEvent ] - led changed from OFF to ON

When I switch through BasicUI or Android app led turn ON
events.log

[ItemCommandEvent          ] - Item 'led' received command ON
[ItemStateChangedEvent     ] - led changed from OFF to ON

…and led works.

Someone can help me?

Hi @KataPi thanks and sorry for the delay!

Feel free to open issues for any problems you encounter on my github page (i tend to be quicker to respond there):

The problem of what you are seeing is that there are two ways to change a state.

  1. sending a command
  2. updating the state

on() indeed just updated the state, which was working fine for me, which is why I did not realise that this is a bug.
I have fixed it to send a command (as happens when you use the basicui / android app), so the latest version of the library (2.2) should work fine for you.

I also added a few more examples.

Could you please give it a try and let me know ?

Marty56,

I really like your solution. I can update text in String items, receive the text state of String items and other items (Dimmer, DateTime, Number, etc).

But I can’t send a command with this approach. Have you any suggestions for sending commands with this approach?

I am afraid no. This functionality was removed from OH 2.0 as far as I recall.
But I could be wrong. I am not using OH anymore.

@rbpaul, have a look at my library https://github.com/sim0nx/python-openhab … it’s a wrapper for the OH API. You can send updates as well as commands easily…which is of course still supported by the API.

Georges,

Thank you for providing the python-openhab module. It’s been very helpful for a project I’m working on which is a basic watchdog/monitor for openHAB using a Pi Zero W. When I started testing various scenarios where openHAB is disconnected (host powered off or service stopped), I notice that fairly often the Python application hangs. I’ve caught a couple of stack traces using gbd and they each look a little different. In Python 2.7 the hang is in a socket receive in socket.py. In Python 3.5.3, the hang is in acquiring a lock in threading.py. Have you seen anything like this before? Are there any timeout settings I can experiment with?

Thank You,

Aaron.

1 Like

Turns out this is simply because timeouts aren’t being used on requests, so they may hang indefinitely. I submitted a PR that fixes this issue for me: https://github.com/sim0nx/python-openhab/pull/3

I think the hang in threading.py was due to a separate issue in my code. In Python 3.5, I would more often get socket hangs.

1 Like

Hi Aaron, I am glad you like library :slight_smile: and it is of use :slight_smile:
I have merged your PR thanks for that! Nice catch btw

If there are any features you might be missing or you have any feedback, please let me know. I am not always super responsive but I am happy to implement / fix whatever is requested.
For the moment the lib works for what I need it for that’s why there are some parts missing (like item types)… but they should be fairly easy to add.

cheers

1 Like

It it just what I needed for my application. Sure, I could have just made the HTTP transactions myself, but this takes care of that for me. Maybe some day I’ll come up with another need, but until then this module is perfect.

Continuing the discussion from Python module for easily accessing the openHAB REST API:

Hi sim0nx!
I am having trouble with sending a command/update/state to a number item in openhab.
I can read the state of the item perfectly fine and print it in python.
When i try to send the data to change the number item it complains about the data type.
i tried the following commands:

temperature.command(temp)
temperature.update(temp)
temperature.state = temp
temperature.state(temp)

And i tried casting the number temp into str, float and int.
What is the correct way to do this?

Hi Soren,

Could you please open an issue over at github (https://github.com/sim0nx/python-openhab) and share a bit more of your code (e.g. the real value you used) as well as the openhab item definition for me to be able to re-produce it ?

Thanks

Maybe I’m missing something, but why not use Jython and the new rule engine for this? Seems to me like a much easier way to interface with OH than through the REST API. To each his own, but maybe this possibility wasn’t considered?

For my part I use the library for integrating external devices and services, but also for simple scheduling which is in my case easier to do in a python script and a cron job than to run it in a rule. More so that this does not involve reloading or restarting OH.

BTW thnx for the reminder, I wasn’t aware this was released already.

It’s been a couple years, but it’s still called Experimental Rule Engine. Just need more volunteers to use/test it so that it bcomes mainstream. My rules are all migrated to Jython and they’ve been running great. The ESH guys are pretty quick to resolve any issues too. I also have a nice update for the rule decorators that really simplifies rule creation. Just want to get one more thing fixed up before posting in the forum.

It sounds like everything your doing could be done in the rule engine. No need to stop OH to make changes to a script, and there are a lot of scheduling options. With your Python experience, I would think you’d love to get away from the Rules DSL and into Jython.

1 Like