New OH2 binding for Venstar Colortouch thermostats

Hi all,

I’m in the process or putting together a binding for Venstar Colortouch WiFi enabled thermostats, and thought I’d share the first cut, in case anyone else is interested.

A snapshot build that you can install (I’ve tested this against a snapshot download of OpenHAB2) by dropping into your addons folder[1] is available at https://bitbucket.org/hww3/openhab2-addons/downloads/org.openhab.binding.venstarthermostat-2.0.0-SNAPSHOT.jar and the code (in it’s current sorry state) is available from the same location.

The binding will auto-detect any thermostats on the network and will display the sensor readings and system state. The heat and cooling setpoints are adjustable. I haven’t yet added support for operating mode (heat/cool/off) but that’s in the plan.

Note that you’ll need to enable the local API on the thermostat. The binding currently insists on using authentication, which in the thermostat configuration mandates SSL (which isn’t such a bad idea), so you will need to enable it.

I think that’s about it; if anyone has any suggestions or comments, I’d love to hear them.

Bill

[1] My OpenHAB install didn’t have a usable version of the Apache HTTP components, so you might have trouble when you try to enable the binding. Here are the commands I used in the OpenHAB console to fire the binding up after I installing the binding in the addons/ directory:

bundle:install http://central.maven.org/maven2/org/apache/httpcomponents/httpclient-osgi/4.3.4/httpclient-osgi-4.3.4.jar
bundle:install http://central.maven.org/maven2/org/apache/httpcomponents/httpcore-osgi/4.3.3/httpcore-osgi-4.3.3.jar
bundle:list // (to get the BundleId of the venstarthermostat binding)
bundle:restart BundleId
1 Like

Why not using org.eclipse.smarthome.io.net.http.HttpUtil which uses jetty http client ?

Two reasons, really… first, the HTTPS server in the thermostat uses a generic, self-signed cert so I have to use a custom client.

Second, the UPnP implementation in the thermostat is non-standard so I can’t use jupnp and needed to use Apache HTTP to parse discovery results. I suppose it would be possible to use a non-system jetty client for the first part, but I’m less sure about the second.

Don’t know about the fist part, but for the second, I had the same UPnP issues when writing the WeMo binding. There are possibilities within JUPnP to “patch” non standard responses. This is handled within RecoveryUDA10DeviceDescriptor and RecoveryUDA10ServiceDescriptor.
If you need support in using this, just ping me.

Hi… I initially tried to use JUPnP and spent a few hours digging into the code. In the end, I decided that it wasn’t worth the effort because one problem wasn’t easily solvable (the thermostat UPnP stack requires the request headers to be in a particular order).

Hmm, I just had a short glimpse on your code and only saw, that you use a defined ST search. This can be achieved with JUPnP as well, as I have to trigger a RootDevice search for WeMo devices.

Ah, yes… I actually studied your code looking for clues… the UPnP support in these devices is pretty broken. I managed to work around all but problem 1.

  1. The headers must be in a particular order
  2. The header names must be presented in a particular (non-standard) capitalization
  3. Certain standard headers must not be present
  4. Only a certain search term may be used (the device wont reply to a ssdp:all search)

In the end, it was more straightforward to write my own discovery service and just send the specific request string exactly as the vendor lists in their API reference.

Hi Bill! Does work continue on the Venstar binding? Is the jar file linked to in the first post the one to use?

Thanks in advance!

~Mark

Hi Mark,

I’m in the process of upgrading to the official 2.0 release of OpenHAB and should have some more up-to-date results later this week. I don’t see why it wouldn’t work, though; feel free to give it a shot. If you run into any problems let me know!

Bill

Hey Bill, thanks for the update! I’m currently running OH2 release. I went ahead and installed the binding. In PaperUI it finds the thermostat and creates the channels. However, it always shows as ‘UNINITIALIZED - HANDLER_CONFIGURATION_PENDING’.

Any ideas? I created an items file and created a single item for temperature but no go.

String	InsideTemperature		"Temperature"	{channel="venstarthermostat:colorTouchThermostat:00aefabb372c:temperature"}

Thanks,

~Mark

Hi Mark,

Have you by chance set the username/password for the thermostat in the
Thing configuration? I seem to recall that you have to enable HTTPS on
the thermostat in order to be able to specify a password… odd, but
true.

Bill

OK, progress. I managed to get the password set on the thermostat, but now I’m getting this error:

Status: OFFLINE - COMMUNICATION_ERROR Failed to connect to URL (http://10.0.0.156/): Connection refused (Connection refused)

I’m seeing this in the log:

2017-03-02 18:41:28.640 [INFO ] [al.VenstarThermostatDiscoveryService] - got buffer
2017-03-02 18:41:28.640 [INFO ] [al.VenstarThermostatDiscoveryService] - unable to parse response: Not a valid protocol version: M-SEARCH * HTTP/1.1

Thoughts?

Thanks in advance,

~Mark

try adding an “S” to the url

httpS://10.0.0.156/

Hey David, the URL is generated by the binding. I don’t believe it’s something I can change.

Bill, should the tstat have a static IP? Right now it’s using DHCP, not sure if it makes a difference or not.

Thanks,

~Mark

That log output is normal (that’s the discovery agent seeing its own
request on the multicast socket). Once everything is known to be
working, I’ll eliminate the “mandatory debug” output.

Bill

It’s correct that the URL is generated from the binding (actually, it’s
pulled from the discovery response from the thermostat itself). If you
delete the thing and let it be rediscovered, it should have the correct
URL. I don’t have the code in front of me, so I’m not sure if that’s
updated automatically when the thermostat sends its discovery
announcements. But it consider it a bug/oversight if it isn’t…

My goal is that the binding should be able to deal automatically with
address changes: the binding should detect the SSDP notifications from
the thermostat and update accordingly. That’s actually something I’m
hoping to verify this weekend as my thermostat got a new address
recently but OpenHAB doesn’t seem to have detected that. I think,
though, that might be a firewall issue with my OpenHAB box and not the
binding. I should have an answer in a day or two.

Bill

Hey Bill, I dropped the tstat thing and let the binding find it again. Now I’m getting this message:

Status: OFFLINE - CONFIGURATION_ERROR Invalid device URL: no protocol:

I can’t seem to catch a break! (Par for course of late.)

Thanks,

~Mark

Hi Mark,

That’s a pretty unusual error; it means that the binding can’t parse the URL to the local API endpoint. Since that value should be generated by the thermostat itself, that really shouldn’t ever happen. Have you edited your configuration in some way that the value might not be correct any more? You can see the value it’s trying to use by clicking on “View properties” under the thermostat’s Thing configuration.

Every 5-7 minutes the binding attempts discovery and should update the URL of any thermostat it finds assuming the UUID of the thermostat doesn’t change. I’m trying to get mine to change address and am not having much luck.

I have an updated version of the binding that I tested out here; perhaps you might have better luck? This version is a little smarter and more thorough about how it does discovery. I’ve tested it here and it successfully discovers and works against my local thermostat. It should also make less noise in the log file as it works.

http://bill.welliver.org/dist/openhab/org.openhab.binding.venstarthermostat-2.1.0-SNAPSHOT.jar

Alas, no luck with the new binding. Same message in paperUI:

Status: OFFLINE - CONFIGURATION_ERROR Invalid device URL: no protocol: 

This is what I see in the event log:

2017-03-05 12:49:48.530 [ThingAddedEvent           ] - Thing 'venstarthermostat:colorTouchThermostat:7bb69d63' has been added.
2017-03-05 12:49:48.595 [hingStatusInfoChangedEvent] - 'venstarthermostat:colorTouchThermostat:7bb69d63' changed from UNINITIALIZED to INITIALIZING
2017-03-05 12:49:48.606 [hingStatusInfoChangedEvent] - 'venstarthermostat:colorTouchThermostat:7bb69d63' changed from INITIALIZING to OFFLINE (CONFIGURATION_ERROR): Invalid device URL: no protocol: 

This is what I see in the openhab log:

2017-03-05 12:48:17.812 [INFO ] [al.VenstarThermostatDiscoveryService] - got buffer
2017-03-05 12:48:17.812 [INFO ] [al.VenstarThermostatDiscoveryService] - unable to parse response: Not a valid protocol version: M-SEARCH * HTTP/1.1
2017-03-05 12:48:19.813 [INFO ] [al.VenstarThermostatDiscoveryService] - got buffer
2017-03-05 12:48:19.813 [INFO ] [al.VenstarThermostatDiscoveryService] - unable to parse response: Not a valid protocol version: M-SEARCH * HTTP/1.1

I’ve double checked my thermostat, Local API is enabled, protocol is HTTPS and both login and password are set.

Both properties (uuid and url) are blank.

Could something be cached somewhere? It found it before I had set up a login and password while the local API was enabled but still set to HTTP. Once I changed it to HTTPS and set up credentials it seems to hang. I do have mysql persistence running as well.

Thanks again for the help, I do appreciate it. Like my dad told me once, if I didn’t have bad luck I wouldn’t have any luck at all.

~Mark

OK, I spun up a new install of OH2, installed the Apache stuff and copied the new binding into the addons directory. Things are looking much better. The uuid and url properties are populated. In PaperUI I see this now:

 Status: UNINITIALIZED - HANDLER_CONFIGURATION_PENDING

The channels are all linked, which is new.

opnehab log:

2017-03-05 13:31:37.671 [INFO ] [al.VenstarThermostatDiscoveryService] - parsing response in venstar
2017-03-05 13:31:37.671 [INFO ] [al.VenstarThermostatDiscoveryService] - Waiting for response.

These two lines appear over and over.

This is progress I guess! Any ideas?