Accessing and controlling a Nest thermostat through SDM API?

  • Platform information:
    • Hardware: Raspberry Pi 3
    • OS: OpenHABian
    • Java Runtime Environment: which java platform is used and what version
    • openHAB version: 3.0.2

I’m a complete newbie with OpenHAB, the Nest API, OAuth, and with non-windows environments in general. As such, I’m struggling a lot with figuring out the basics of how all this works and what I can do with it. I’ve been trying to look for examples of how to get started with using OpenHAB to interact with my Nest thermostats, but haven’t found anything that really makes sense to me yet. I have 2 Nest thermostats (upstairs and downstairs). I have OpenHAB 3.0.2 running on a Raspberry Pi 3, and I have already set up the Nest SDM Bindings with the OAuth credentials. The binding says it is “ONLINE”, which is good, but now I’m like “Ok, now what?”.

Here’s what I’m trying to do:
I want to be able to programatically retrieve information from the Nest thermostats (such as reading the current setpoint, temperature, or heating/cooling mode), and send some basic commands (such as changing the set point, or cycling the HVAC on/off). Do I do this using rules? Using scripts?

The goal is for the RPi to read some data (or receive push commands) from an external web server and then based on that external data, use OpenHAB to run some logic to tell one or both thermostats to pre-cool or turn off so that they are not both running at the same time. I’m hoping that I can write a java script in OpenHAB to query our external web server, but before I get that far, I need to figure out the basics of controlling the thermostats.

I’m looking for some examples of how to

  1. detect and communicate with the 2 thermostats,
  2. how to know which thermostat is which,
  3. how to read the current setpoint and temperature from each thermostat, and
  4. how to send a command to change the current setpoint of one or both thermostats.

I’m assuming that I can do all of this in java code…

If the concept of bindings and Things and Items don’t make sense to you yet, please review Getting Started - Introduction | openHAB and https://www.openhab.org/docs/concepts/. Please feel free to come back with specific questions after doing that and we will endeavor to answer or clear up confusion.

As you should see in the Getting Started tutorial, in particular Adding Things - Intermediate | openHAB, you need to discover the Things. Then you’ll need to create/link the relevant Channels on those Things to Items. Everything else in OH operates on Items. Don’t be mislead by the fact that it’s not showing the Nest binding in particular. The root of all of OH’s power is that it provides layers of abstraction so you don’t really have to care what technology you are dealing with. You’ve already created the SDM Thing. Now go discover the Things.

Why not use the HTTP binding or the sendHttpXRequest actions? You don’t need to code that sort of stuff manually and probably shouldn’t anyway.

OH also supports a REST API so your external server could POST or PUT commands and updates to Items in OH; no need to poll.

See the concepts and getting started tutorial

when discovered they will have a name which I believe matches the name of the device in the Nest app

There will be Channels. Link those Channels to Items. When the value changes the Item will update to the new value. Sending a command to a setpoint will update the setpoint on the device.

Lot’s of way depending on context. You can do it from the UI, from a Rule, the REST API, etc.

Exactly none of this requires you to write Java code.

I’m not sure if my confusion stems from not understanding what an OpenHAB “thing” is, or if it comes from the Google Device and Google Cloud stuff (which I’m also struggling to make heads or tails out of).

Here is an image of my Things page:

Both thermostats are linked to the same Google Home account, which is linked to the OAuth 2.0 Client ID in Google’s Cloud Platform following the procedures outlined in Nest-Bindings | openHAB #SDM Config Params. I assumed this Client Id and API credentials gave me access to that account and both thermostats, and that the “Nest SDM Account” bridge thing shown above represents access to that Google Home account (and therefore, both thermostats linked to it).

Am I wrong about that? Does the “Nest SDM Account” bridge refer to one specific thermostat? If so, did I set up the Google Device / Cloud stuff incorrectly? How do I get access to the other thermostat?

I had assumed that if I “Add a New Thing” > select the Nest binding > click “Scan”, that it would find my two thermostats. The RPi running OpenHAB is on the same local network as my 2 Nest thermostats, so they should be visible.

But the scan doesn’t find any devices. It just shows the same two “Add Manually” options shown in the image above, neither of which appears relevant, since I’ve already created a Nest SDM Account bridge.

Assuming that the Nest bridge refers to the account and not to the individual tstats, I moved onto the Adding Things - Advanced tutorial and tried setting up the thermostats as generic MQTT devices with the hostname/IP set to the same as the thermostats. However, the MQTT brokers both say “ERROR: COMM”.

Maybe I have the wrong port number? Is there a specific port that I should be using for a Nest tstat? Or am I doing this completely wrong?

You won’t get very far with openHAB without understanding it’s core concepts of Things, Channels, Links and Items. I see that none of the links I posted have been clicked on. So you’ve already read that information or are you just winging it? You won’t be successful with openHAB without the docs. This stuff is hard.

Assuming what you’ve said is correct than yes.

No, that one Thing represents your connection to that Google SDM account. According to the docs it should automatically discover all the supported Nest Things and a new Thing will be created for each device.

That is how it should work. It’s showing your account Thing as online so the account info should be set up properly. Do you see anything in the logs?

Being on the same network is irrelevant. All Nest communications between openHAB and your devices go through Google’s cloud servers.

MQTT is a completely and wholly separate and incompatible technology. OH supports over 350 of them and they all work differently. You can’t connect to Nest using MQTT any more than you could connect to WiFi using a walkie-talkie.

Mostly this at this point.

You need to figure out if there is an error or something else going wrong between the binding and Google that is preventing it from discovering the devices. The account Thing shows as online so the account stuff should be configured correctly. Something else must be going on but we need to see logs to figure that out.

I had the Getting Started tutorials open in a new tab already. I did somehow miss the Concepts tutorial though, so I’ll have a read through that. Thanks for posting it. Mostly, I was just lost because the Nest binding showed “online”, but I couldn’t seem to do anything with it.

In the meantime, I found the logs you mentioned (at /var/log/openhab/openhab.log) and fixed the issue preventing the binding from finding the 2 thermostats. The log showed some kind of authentication error. I followed the Nest - Bindings | openHAB guide as closely as I could. I’m not sure if I missed a step or if Google added an additional step, as if the process weren’t already complicated enough as is.

2021-06-28 22:47:52.879 [WARN ] [org.apache.felix.fileinstall        ] - Error while starting bundle: file:/usr/share/openhab/addons/org.openhab.binding.nest-3.1.0.20210530.jar
org.osgi.framework.BundleException: Could not resolve module: org.openhab.binding.nest [215]
  Unresolved requirement: Import-Package: javax.measure; version="[2.1.0,3.0.0)"

	at org.eclipse.osgi.container.Module.start(Module.java:444) ~[org.eclipse.osgi-3.12.100.jar:?]
	at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:383) ~[org.eclipse.osgi-3.12.100.jar:?]
	at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundle(DirectoryWatcher.java:1260) [bundleFile:3.6.4]
	at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundles(DirectoryWatcher.java:1233) [bundleFile:3.6.4]
	at org.apache.felix.fileinstall.internal.DirectoryWatcher.startAllBundles(DirectoryWatcher.java:1221) [bundleFile:3.6.4]
	at org.apache.felix.fileinstall.internal.DirectoryWatcher.doProcess(DirectoryWatcher.java:515) [bundleFile:3.6.4]
	at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:365) [bundleFile:3.6.4]
	at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:316) [bundleFile:3.6.4]
2021-06-29 22:45:11.396 [ERROR] [oauth2client.internal.OAuthConnector] - grant type authorization_code to URL https://accounts.google.com/o/oauth2/token failed with error code invalid_grant, description Bad Request
2021-07-01 22:31:48.860 [WARN ] [binding.nest.internal.sdm.api.SDMAPI] - SDM API error: Smart Device Management API has not been used in project 8xxxxxxxxxx9 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/smartdevicemanagement.googleapis.com/overview?project=8xxxxxxxxxx9 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.

I went to the URL cited and logged into my testing account. Now the API is activated (I guess), and OpenHAB is seeing the 2 thermostats, and they are labeled as ONLINE. Hooray! Progress! Hopefully now that openHAB can see my thermostats, I’ll be able to figure things out from here.

Is the missing javex.measure dependency going to become a problem?

I don’t know. If it persists you should file an issue on the add-on. How to file an Issue

This just happened to me.

https://console.developers.google.com/apis/api/smartdevicemanagement.googleapis.com/overview?project=YOUR_PROJECT_ID

Once you enable this GCP API, all your NEST devices will be scanned.

1 Like

This was my issue. Thanks!

The Bindings document says "You can monitor the SDM API using the Google Cloud Platform Console via API & Services > Smart Device Management API " and I assumed that visiting this link was optional. It’s not. You need to visit the link at least once to click [Enable API]