LarsMichelsen / pmatic

Python API for Homematic. Easy to use.
https://larsmichelsen.github.io/pmatic/
GNU General Public License v2.0
34 stars 23 forks source link

Add Homegear (XML-API) support #12

Open danielperna84 opened 8 years ago

danielperna84 commented 8 years ago

From having a quick glance at this repository I believe, that pmatic is not capable of serving as an interface to Homegear. Implementing this could lead to a much bigger audience, since there are quite a few users running Homegear on Raspberry Pis together with the HM-CFG-LAN or USB inteface instead of using the CCU. Like the CCU, Homegear exposes a XML-RPC API on port 2001, but does not provide a web-based interface. Hence, everything has to be done through that API.

I have done that already as a separate package for another project, but from reading the documentation of pmatic I believe pmatic already has greater functionality and a more robust codebase. To me it would make more sense to integrate the XML-API usage into pmatic instead of further progressing with my current work.

If anyone is interested in doing this, my package is called pyhomematic. It's actually quite easy to use the API. I just don't have the time to look at how to get this into pmatic.

So, yeah, any thought on this? I suppose using the API could replace the existing remote-implementation, with the drawback, that the XML-API doesn't use any authentication.

LarsMichelsen commented 8 years ago

I really like the idea! I think it could be a great benefit for all of us to focus on one Python interface to Homematic and similar.

One goal of pmatic is to be able to be used directly on the CCU tied together with Python 2.7 but also from any other Linux/Windows/Mac system which has access to the CCU (Python 2.7 or 3.x).

When I started with pmatic I thought it would be a good idea to use the JSON API of the CCU when connecting from remote and the TCL scripts, which are realizing the JSON API, in a dedicated tclsh process when executing pmatic directly on the CCU.

Looks like using the XML API would have been a better idea. At least in terms of supporting more platforms.

During implementation of the pmatic manager (which hosts the web interface of pmatic) I added support for registering for and receiving events from the CCU via XML API. The manager opens it's own XML API and tells the CCU to send events to it via JSON API. So we already have basic XML RPC support from python on all platforms.

I am unsure whether or not the XML APIs have all features of the JSON API.

danielperna84 commented 8 years ago

I've seen, that receiving events is already done via XML-RPC, so yes, that part already is implemented. The only thing missing would be to send data from the client to the CCU (or Homegear).

I don't know if you already had a look at my code. Sending messages to the CCU is done with a so called "Proxy". This is available for Python 2.7 as well as >3 with the same syntax. You just import it differently for Python 2.7, which I didn't take care of in my project. Just a small Python 3 sample on how to flip a switch, or in this case set the position of a Jalousie-Aktor:

import xmlrpc.client
proxy = xmlrpc.client.ServerProxy("http://%s:%s" % ('127.0.0.1', 2001)) # Connecting to homegear, could also be a remote CCU
proxy.getValue('KEQ123456:1', "LEVEL") # Get the current level of a Jalousie-Aktor
proxy.setValue('KEQ123456:1', "LEVEL", 0.5) # Set the Jalousie-Aktor to 50% open
proxy.putParamset('KEQ123456:1', "VALUES", {'LEVEL':1.0}) # Opening again, alternative way

In Python 2.7 it would be:

import xmlrpclib
proxy = xmlrpclib.ServerProxy("http://%s:%s" % ('127.0.0.1', 2001))
...

It's really easy, but as you already mentioned, the XML-RPC API is not as feature-rich as the JSON-RPC API. In general, the XML-API provides most of what is available via JSON-RPC that starts with Interface. So Interface.setValue, Interface.getDeviceDescription etc. You can get that information from the API-reference I linked to in the starting post.

My suggestion would be, that when using pmatic you can set a flag ccu=False (default) to True. The default when using pmatic remotely would be to use the XML-API (which will work for everybody), and if set to True the JSON-RPC would be used to provide more features. But this is exactly the point where I am unsure how deeply pmatic already relies on functions that may only be available through JSON-RPC.

One important note: When using XML-RPC, we have to take care of threading. My package is the one that's currently used to bring greater Homematic support to Home Assistant. My implementation is already doing the job, but in the long run it could be replaced to add more features. If anyone is interested, the current progress can be found here. The current implementation already supports pretty much all Jalousie-Aktors, a lot of switches, Door- and Window-contacts, Thermostats. Anyhow, Home Assistant is threaded, which means pyhomematic had to be thread-safe. That's why I'm subclassing the Proxy-Class to use locking. If that's not done, setting multiple devices to state X can result in unexpected states, where switches have to be pressed manually before the CCU is able to communicate with them again.

So basically the only question right now would be, if pmatic would still be able to provide most of it's functionality when adding XML-RPC as an additional protocol. I wouldn't strip out JSON-RPC, since features such as rooms etc. aren't available via XML-API. But when using pmatic just as a library to get and set states of devices (that's all pyhomeatic really does), a lot of these features would be obsolete. Thinking of it, it might make sense to devide pmatic itself into two parts: a lightweight performant core-library to just handle communication between client and CCU / Homegear, and a pmatic-extension-package that actually makes use of the core, like pmatic seems to do no pretty well.

One more thing: I am such a guy who doesn't have a CCU, just HM-CFG-LAN + Homegear. Which is why I only know what pmatic does from reading the docs and can't actually explore it myself. :-(