Non Native openHAB bridges (new binding: SMA inverter via bluetooth )

8th Nov update:
If anybody want to to test this, the .jar is on GitHub.
Also see:


Hi I’m developing a binding to fetch data from an SMA Solar inverter over Bluetooth. The SMA inverter uses a customer Bluetooth protocol.

As the Java BlueCove library is not maintained and likely not compatible with Java 21 or later, the development of a Bluetooth interface is better achieved using the Python pybluez module for low-level Bluetooth Classic (BR/EDR) socket communication.

I have already coded up a SMA Bluetooth CLI (Python) and have built a prototype binding that interfaces to it via the java.lang.Process Class.

My plan is to add this, when complete, to the growing number of openHAB bindings via a pull request.

  • Is it acceptable to use a none native CLI bridge (executable derived from Python) that requires separate installation as part of the solution ?
  • Assuming it is okay, where would the none native CLI bridge best be installed ?

I have come across some suggestions it could go here: $OPENHAB_HOME\userdata\files

  • Is that acceptable ?
  • Are there any permissions issues I need to be aware off ?
  • Any GOTYAs ?

Thanks in advance.

I don’t know the details of how this is done, but I think there are some others (at least one) that use GraalPy to integrate into OH.

“Anything” can talk to OH’s API, but that’s not enough to make a binding. I think it would be difficult to make a “pure Python” binding work, not to mention to handle installation etc.

I was not planning on making a binding in Python.

Here is what I plan

New normal Java binding as part of opeHAB
|
| commad set on command line
V
Pyhon compiled ‘CLI to Bluetooth’ executable
|
| Bluetooth to inverter
V
SMA Inverter
|
| Bluetooth to CLI
V
Pyhon compiled ‘CLI to Bluetooth’ executable
|
| JSON via stdout
V
New normal Java binding as part of opeHAB.

So where to put the ‘CLI to Bluetooth’ executable?

I can’t answer that, but be aware that Java Process is both relatively slow and has some pitfalls (deadlocks from mishandling pipes, different behavior/bugs on different platforms).

There is a BT a binding which does work in Java 21. What library does it use?

I know if no other binding that does this. As a marketplace add-on there won’t be any problem but as an official building there might be some concern.

You might look into the MQTT Home Assistant add-on though. It uses GraalVM Python as @Nadahar mentions, to run the HA MQTT library inside OH. That might be a viable approach.

Including the extension there are a mix of TinyB, BlueGiga and the unmaintained BlueCove

BlueGiga relies on a proprietary protocol (BGAPI) and communicates directly with specialized BlueGiga/Silabs dongles.

TinyB is unsuitable for the SMA custom Bluetooth project primarily because it:

  • Lacks Low-Level Access: As a high-level JNI wrapper for the BlueZ D-Bus API, it’s too restrictive for complex, custom, and proprietary protocols like SMA’s, which require granular, low-level control.
  • Is Platform-Dependent: It requires the Linux BlueZ stack and is inherently not a cross-platform solution.

I think Python pybluez CLI approach avoids the issues with TinyB.

There is already a significant body of work implemented in Python to implement the SMA custom protocol that would be considerably difficult to rework in Java even if a suitable library existed.

I thought as much, partly why I thought I would raise it. I’m happy whatever the community wants.

Maybe @ccutrer or @holger_hees can give you some advice for the graalvm route.

Having the user install these dependencies manually is probably a reason not to accept a PR.

1 Like

Is your Python you’re using an actual API, or or only a CLI? I would avoid using Process and pipes. Besides the dependency issues, there will almost certainly be reliability issues or bugs among different platforms. Hopefully it has actual APIs to call.

My recommendation would be to look at the Home Assistant binding (currently called org.openhab.binding.mqtt.homeassistant, but hopefully soon to be renamed to org.openhab.binding.homeassistant) for examples of how to embed both Python packages as well as unpackaged Python code. There’s a bit of boiler plate on the Java side to call Python methods, but you can hold on to references to Python objects and call any method. It just becomes a question of where you want to delineate the Python from the Java. I wouldn’t try to implement the ThingHandler in Python (or any other piece of a binding that needs to be exposed as an OSGi service and/or implement Java interface, though it might be possible - I do that sort of thing quite successfully from JRuby). You just treat the Python the same as many bindings that use a Java library for device communication wrapped by the ThingHandler. In Home Assistant I isolate all the Python to a HomeAssistantPythonBridge class. One thing you don’t want to do is instantiate multiple Graal Python engines. It takes a long time to start a new instance up, so you’ll want to keep it cached across all thing handler instances.

Finally, does your python have any native package dependencies? While theoretically GraalPy can handle that, I’ve specifically avoided it. Basically you have to build the JAR once on each platform then have a separate final step to combine them all together, which would involve extra work in our distro build that I didn’t want to get in to unless I absolutely had to.

1 Like

I am happy to see you are woking on this. For my understanding, is there a reason you would not use GitHub - SBFspot/SBFspot: Yet another tool to read power production of SMA® solar/battery inverters ? It does the bluetooth part well, runs on the common platforms and provides the output through MQTT, easily integrating with OH. I have this running for years without issues.

2 Likes

Thanks for the feedback @Mherwege and @ccutrer

I don’t use MQQT and I was not interested in setting up an SQLite database as openHAB can take care of the database, so in 2023 I produced SMA_Bluetooth_to_openHAB_REST which has been runnig on a seperate Linux machine, without issue, ever since. It was based on python-smadata2 but extended with the additional parameters (Spot power, ACVoltage and Temperature) form SBFSpot.
As Raspis are now more capable I wanted to move this and other …_to_openHAB_REST applications I have running onto the same Raspi and have them more closely coupled with openHAB.

There is no published Blootooth API for SMA inverters, it has been back engineered by the community.
The Python CLI Utility I have written, reuses some of the contributions discussed above to handle the connection to Bluetooth and the messaging to retrieve the inverter data, it takes a simple CLI command with only logon credentials to prompt a JSON response on stdout containing all the inverter data. The binding is then simple, it manages the credentials and deserialises the JSON to update channels.

Not sure my coding is quite up to this yet.

If I understand you correctly a native dependency is one written in C, for example, as opposed to Python. This is specifically why I went this route, pybluez has native dependencies and there is no suitable Java Class, see discussion earlier in the thread.

Thanks @lsiepel thats clear I’ll spare you the Pull Request. :smiley:

I think maybe you read that as more of “a rejection” than @lsiepel intended it to be. The point is that it must be packaged in a way that lets you install it from OH’s GUI to fit into “the standard add-on handling”, so that if that is possible to achieve, it’s better for everyone.

Thanks @Nadahar :+1:, I understood @lsiepel and it answered my original question and DM. :smiley:
I’m not sure I can avoid native Python dependencies and as there is no suitable Java Class (as discussed), I’m unable, perhaps its my knowledge or skill that are lacking, to comply.
I’m content and will probably add something to the openHAB marketplace. :smiley:

1 Like

No, I don’t mean at that level. I mean the Python-based CLI you’re using. I mean internal to the CLI, is it backed by a Python-level API that can be directly accessed by other Python code (like a Python-based binding).

Kind of. It’s a Python module written in C. It’s possible to have pure-Python code call out to other code that is native (like for example via executing a sub-process, doing an HTTP request, using pipes or DBus, MQTT, etc.) in such a way that it’s not a native module. But, pybluez definitely has C in its Python module itself, so counts as a native dependency.

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.