Nest Thermostat Integration - Ready for newbies?

Would you mind sending me a DM with the JSON you are pasting? Seems like the code is unable to parse it...

This integration is very detail oriented. I have my Nest thermostat controlled from Hubitat and the complexity is mostly on the Google side. I can try and help others, but as pointed out, there are a lot of trivial details that have to align to make this work

Were you able to resolve the error? I'm getting a similar error: groovy.json.internal.Exceptions$JsonInternalException: unexpected character k on line 191 (mainPage)

1 Like

Double-check that your credentials file is valid JSON. If you're not sure, you can DM me the contents and I would be happy to double-check it.

1 Like

Just circling back with an answer for any who may come later - in DMs we identified that the full JSON file had not been pasted in the input field (only a part), which led to this error

1 Like

So, I got everything installed no errors, everything looks good, but it isn't actually altering the state of my thermostat. I have the new 2020 Google thermostat, I am wondering if maybe it's a driver issue. Do you happen to know anything about it? Thank you by the way, super complicated process but your readme made it very easy!

Is the issue that device changes in Hubitat don't actually adjust the physical thermostat, or that the thermostat changes don't update in Hubitat?

If the latter, it sounds like an issue with the Google event subscription. Enabling debug logs from the App page will log each event as it is received - you should get one for each change on the thermostat, e.g. setpoint changes, ambient temperature, active cooling/heating/idle.

If not, then from the App page, click on debug buttons, then subscribe to events. This is executed automatically during authorization but may have failed. After invoking the debug button check the logs for any errors that may have been generated.

Thank you! I'll work on it and see what I can figure out.

I've followed the excellent instructions and it seems to work mostly. I can turn the thermostat on and off, but manually or programatically setting a temperature doesn't seem to work at all.

My thermostat is only controlling heat, no cooling, and so if I go to SetHeatingSetpoint and punch in a temp and click the button, the Nest app on my phone doesn't reflect that temperature change.

I can turn the heater on and off from there though. Any thoughts?

For any commands that are failing, can you make sure debug logs are enabled for both the Device and App, run the attempted command, and capture the relevant logs?

well it's weird I turned on logging but there's nothing there, although the data is shown in the thermostats status. I currently have a Rule Machine 5 rule that's supposed to trip when the thermostat temp dips below 40, it's at 39.5 now and it hasn't run. So I'm trying to figure out what went wrong.

Next I turned it on for Google SDM API and now I'm getting somwehre it says that I don't have Cloud Pub/Sub API has not been used or is disabled and gives me a URL. This was the one part of the instructions that didn't seem to line up, there was only a setting which said "Enable" near Pub/Sub and I made sure it was on (it was by default) the other instructions around this didn't match anything there so I thought it was okay.

clicking the URL I've now set up permissions so we'll see if it works. Weirdly I was able to trip most functions manually from the controls on the device, so I thought this was working. I did not even get the notification from my Rule that the temp had fallen.

After waiting a bit I see the pub/sub subscription has occurred. no error, just debug and info now so I think that end is working, waiting to see if the next temp event causes this to run or not?

Pretty sure this was the problem with the events though because now I see log events from the thermostats that I wasn't seeing before. Will further debug the temp set point thing not working in a bit. Thank you for this awesome work!

Yes, it sounds like the pub/sub api was the missing link - commands function when run, but rules that trigger on events never ran becaue the events were not received from Google. If you run into any other issues, don't hesitate to post - there is also a lengthy thread for the App/Drivers that you can search through for tips: [Beta] Google SDM API - Nest integration

The pub/sub has 2 sides, in the Device Access project, to enable the topic to publish the events in Google Cloud, but also in the GCP project, to enable the API so that the Hubitat App can create the subscription (telling Google how to send those events to your hub)

1 Like

Okay once again it didn't seem to set the heat set point I see the error message "Cannot setHeatingSetpoint in thermostatMode:off" which makes total sense, except I didn't try and do that.

The code reads

Thermostats:Shop Far -->Mode:heat -->Heat:65.0
delay 0:01:00
Thermostat:Shop Far -->Heat:65.0

so either way it should be on right?

Here are the SDM logs from that time frame:

app:2902021-12-29 10:47:28.858 am debug{ "eventId": "bd4b6801-df46-4b1f-8452-c2c08edc512a", "timestamp": "2021-12-29T18:47:20.200Z", "resourceUpdate": { "name": "enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEudHiuIEKQWB49t7DqWtU4dqCpmkToWdIcgEFhpoUwoUsyK1lnsCOMtwY60RxTcRgYTdGvZ6Bq3ba6qbdPRU3yLvA", "traits": { "sdm.devices.traits.ThermostatHvac": { "status": "HEATING" } } }, "userId": "AVPHwEv6dqZAvtGa8hvYGnG5mxmUt1A8V6GkIasiW6_M", "resourceGroup": ["enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEudHiuIEKQWB49t7DqWtU4dqCpmkToWdIcgEFhpoUwoUsyK1lnsCOMtwY60RxTcRgYTdGvZ6Bq3ba6qbdPRU3yLvA"]}
app:2902021-12-29 10:47:28.856 am debugEvent received from Google pub/sub
app:2902021-12-29 10:47:21.184 am debug{ "eventId": "44fe0712-9642-4b23-abc5-ab1dc30341ef", "timestamp": "2021-12-29T18:47:15.901Z", "resourceUpdate": { "name": "enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA", "traits": { "sdm.devices.traits.ThermostatHvac": { "status": "HEATING" } } }, "userId": "AVPHwEv6dqZAvtGa8hvYGnG5mxmUt1A8V6GkIasiW6_M", "resourceGroup": ["enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA"]}
app:2902021-12-29 10:47:21.182 am debugEvent received from Google pub/sub
app:2902021-12-29 10:47:20.828 am debug{ "eventId": "e4dc5588-3999-4485-82df-967ed0a27055", "timestamp": "2021-12-29T18:47:15.174Z", "resourceUpdate": { "name": "enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA", "traits": { "sdm.devices.traits.Temperature": { "ambientTemperatureCelsius": 5.68999 } } }, "userId": "AVPHwEv6dqZAvtGa8hvYGnG5mxmUt1A8V6GkIasiW6_M", "resourceGroup": ["enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA"]}
app:2902021-12-29 10:47:20.826 am debugEvent received from Google pub/sub
app:2902021-12-29 10:47:17.543 am debug{ "eventId": "7b8c748d-3534-49b9-bd87-0667afa557e3", "timestamp": "2021-12-29T18:47:16.716Z", "resourceUpdate": { "name": "enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEudHiuIEKQWB49t7DqWtU4dqCpmkToWdIcgEFhpoUwoUsyK1lnsCOMtwY60RxTcRgYTdGvZ6Bq3ba6qbdPRU3yLvA", "traits": { "sdm.devices.traits.Temperature": { "ambientTemperatureCelsius": 5.42 } } }, "userId": "AVPHwEv6dqZAvtGa8hvYGnG5mxmUt1A8V6GkIasiW6_M", "resourceGroup": ["enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEudHiuIEKQWB49t7DqWtU4dqCpmkToWdIcgEFhpoUwoUsyK1lnsCOMtwY60RxTcRgYTdGvZ6Bq3ba6qbdPRU3yLvA"]}
app:2902021-12-29 10:47:17.541 am debugEvent received from Google pub/sub
app:2902021-12-29 10:47:17.373 am debug{ "eventId": "aa989c9e-ba58-4790-bd25-89b348f048bc", "timestamp": "2021-12-29T18:47:12.725Z", "resourceUpdate": { "name": "enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEudHiuIEKQWB49t7DqWtU4dqCpmkToWdIcgEFhpoUwoUsyK1lnsCOMtwY60RxTcRgYTdGvZ6Bq3ba6qbdPRU3yLvA", "traits": { "sdm.devices.traits.ThermostatMode": { "mode": "HEAT", "availableModes": ["HEAT", "OFF"] }, "sdm.devices.traits.ThermostatEco": { "availableModes": ["OFF", "MANUAL_ECO"], "mode": "OFF", "heatCelsius": 4.44444, "coolCelsius": 24.44444 }, "sdm.devices.traits.ThermostatTemperatureSetpoint": { "heatCelsius": 12.777778 } } }, "userId": "AVPHwEv6dqZAvtGa8hvYGnG5mxmUt1A8V6GkIasiW6_M", "resourceGroup": ["enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEudHiuIEKQWB49t7DqWtU4dqCpmkToWdIcgEFhpoUwoUsyK1lnsCOMtwY60RxTcRgYTdGvZ6Bq3ba6qbdPRU3yLvA"]}
app:2902021-12-29 10:47:17.371 am debugEvent received from Google pub/sub
app:2902021-12-29 10:47:14.341 am debug{ "eventId": "1cb2a242-e0f5-4c1d-89bd-a9e7041ef85b", "timestamp": "2021-12-29T18:47:12.704Z", "resourceUpdate": { "name": "enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA", "traits": { "sdm.devices.traits.ThermostatMode": { "mode": "HEAT", "availableModes": ["HEAT", "OFF"] }, "sdm.devices.traits.ThermostatEco": { "availableModes": ["OFF", "MANUAL_ECO"], "mode": "OFF", "heatCelsius": 4.44444, "coolCelsius": 24.44444 }, "sdm.devices.traits.ThermostatTemperatureSetpoint": { "heatCelsius": 12.777778 } } }, "userId": "AVPHwEv6dqZAvtGa8hvYGnG5mxmUt1A8V6GkIasiW6_M", "resourceGroup": ["enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA"]}
app:2902021-12-29 10:47:14.338 am debugEvent received from Google pub/sub
app:2902021-12-29 10:47:11.953 am infoSending sdm.devices.commands.ThermostatMode.SetMode to Shop Kayak with params: [mode:HEAT]
app:2902021-12-29 10:47:11.934 am infoSending sdm.devices.commands.ThermostatMode.SetMode to Shop Far with params: [mode:HEAT]

Don't have a timestamp from the Thermostat device error, but looking at the App logs, you may need to increase the delay before sending the setpoint command - the code waits for the event from Google confirming the new state before updating Hubitat.

Looks like in this case it took about 2.5 seconds from sending the command to get the event - so at least 3 second delay?

So from my code above I have a 1 minute delay before sending although I’m setting two thermostats at once could that be the issue?

Sorry, misread the delay as 1s. Re-reading above, you're setting the heat setpoint twice, once immediately after the mode change, then again after the delay? I expect the second attempt should be successful. If not, please post the logs from App and Device, with timestamps, covering the full minute+ of the execution period. A screenshot of the rule (if using Rule Machine) may be helpful to confirm the sequence being executed.

Wouldn't expect manipulation of multiple devices in sequence to cause any issues, unless you're hitting an API rate-limit on Google's side (if so, this should be logged)

No probelem, Just so I get it right which logs do you want? The SDM logs from the timeframe are in the post above, I can snag the thermostat logs as well if that’s what you want.

Yes, both. SDM logs above only cover about 20 seconds, so we don't see the full 1m delay period.

Ah yeah, sorry there was nothing 1 minute past that in the log.

I just tried running it again and, changing my delay from 1 minute to 10 seconds, It appears to function correctly at the moment, so I'll monitor and report back with the logs again if it fails.

For reference here's a few lines above and below the previous logs:

app:2902021-12-29 11:00:21.375 am debugEvent received from Google pub/sub app:2902021-12-29 10:58:35.378 am debugAuthorized scopes: https://www.googleapis.com/auth/pubsub https://www.googleapis.com/auth/sdm.service app:2902021-12-29 10:58:35.042 am infoRefreshing access_token from Google app:2902021-12-29 10:47:28.858 am debug{ "eventId": "bd4b6801-df46-4b1f-8452-c2c08edc512a", "timestamp": "2021-12-29T18:47:20.200Z", "resourceUpdate": { "name": "enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEudHiuIEKQWB49t7DqWtU4dqCpmkToWdIcgEFhpoUwoUsyK1lnsCOMtwY60RxTcRgYTdGvZ6Bq3ba6qbdPRU3yLvA", "traits": { "sdm.devices.traits.ThermostatHvac": { "status": "HEATING" } } }, "userId": "AVPHwEv6dqZAvtGa8hvYGnG5mxmUt1A8V6GkIasiW6_M", "resourceGroup": ["enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEudHiuIEKQWB49t7DqWtU4dqCpmkToWdIcgEFhpoUwoUsyK1lnsCOMtwY60RxTcRgYTdGvZ6Bq3ba6qbdPRU3yLvA"]} app:2902021-12-29 10:47:28.856 am debugEvent received from Google pub/sub app:2902021-12-29 10:47:21.184 am debug{ "eventId": "44fe0712-9642-4b23-abc5-ab1dc30341ef", "timestamp": "2021-12-29T18:47:15.901Z", "resourceUpdate": { "name": "enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA", "traits": { "sdm.devices.traits.ThermostatHvac": { "status": "HEATING" } } }, "userId": "AVPHwEv6dqZAvtGa8hvYGnG5mxmUt1A8V6GkIasiW6_M", "resourceGroup": ["enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA"]} app:2902021-12-29 10:47:21.182 am debugEvent received from Google pub/sub app:2902021-12-29 10:47:20.828 am debug{ "eventId": "e4dc5588-3999-4485-82df-967ed0a27055", "timestamp": "2021-12-29T18:47:15.174Z", "resourceUpdate": { "name": "enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA", "traits": { "sdm.devices.traits.Temperature": { "ambientTemperatureCelsius": 5.68999 } } }, "userId": "AVPHwEv6dqZAvtGa8hvYGnG5mxmUt1A8V6GkIasiW6_M", "resourceGroup": ["enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA"]} app:2902021-12-29 10:47:20.826 am debugEvent received from Google pub/sub app:2902021-12-29 10:47:17.543 am debug{ "eventId": "7b8c748d-3534-49b9-bd87-0667afa557e3", "timestamp": "2021-12-29T18:47:16.716Z", "resourceUpdate": { "name": "enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEudHiuIEKQWB49t7DqWtU4dqCpmkToWdIcgEFhpoUwoUsyK1lnsCOMtwY60RxTcRgYTdGvZ6Bq3ba6qbdPRU3yLvA", "traits": { "sdm.devices.traits.Temperature": { "ambientTemperatureCelsius": 5.42 } } }, "userId": "AVPHwEv6dqZAvtGa8hvYGnG5mxmUt1A8V6GkIasiW6_M", "resourceGroup": ["enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEudHiuIEKQWB49t7DqWtU4dqCpmkToWdIcgEFhpoUwoUsyK1lnsCOMtwY60RxTcRgYTdGvZ6Bq3ba6qbdPRU3yLvA"]} app:2902021-12-29 10:47:17.541 am debugEvent received from Google pub/sub app:2902021-12-29 10:47:17.373 am debug{ "eventId": "aa989c9e-ba58-4790-bd25-89b348f048bc", "timestamp": "2021-12-29T18:47:12.725Z", "resourceUpdate": { "name": "enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEudHiuIEKQWB49t7DqWtU4dqCpmkToWdIcgEFhpoUwoUsyK1lnsCOMtwY60RxTcRgYTdGvZ6Bq3ba6qbdPRU3yLvA", "traits": { "sdm.devices.traits.ThermostatMode": { "mode": "HEAT", "availableModes": ["HEAT", "OFF"] }, "sdm.devices.traits.ThermostatEco": { "availableModes": ["OFF", "MANUAL_ECO"], "mode": "OFF", "heatCelsius": 4.44444, "coolCelsius": 24.44444 }, "sdm.devices.traits.ThermostatTemperatureSetpoint": { "heatCelsius": 12.777778 } } }, "userId": "AVPHwEv6dqZAvtGa8hvYGnG5mxmUt1A8V6GkIasiW6_M", "resourceGroup": ["enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEudHiuIEKQWB49t7DqWtU4dqCpmkToWdIcgEFhpoUwoUsyK1lnsCOMtwY60RxTcRgYTdGvZ6Bq3ba6qbdPRU3yLvA"]} app:2902021-12-29 10:47:17.371 am debugEvent received from Google pub/sub app:2902021-12-29 10:47:14.341 am debug{ "eventId": "1cb2a242-e0f5-4c1d-89bd-a9e7041ef85b", "timestamp": "2021-12-29T18:47:12.704Z", "resourceUpdate": { "name": "enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA", "traits": { "sdm.devices.traits.ThermostatMode": { "mode": "HEAT", "availableModes": ["HEAT", "OFF"] }, "sdm.devices.traits.ThermostatEco": { "availableModes": ["OFF", "MANUAL_ECO"], "mode": "OFF", "heatCelsius": 4.44444, "coolCelsius": 24.44444 }, "sdm.devices.traits.ThermostatTemperatureSetpoint": { "heatCelsius": 12.777778 } } }, "userId": "AVPHwEv6dqZAvtGa8hvYGnG5mxmUt1A8V6GkIasiW6_M", "resourceGroup": ["enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA"]} app:2902021-12-29 10:47:14.338 am debugEvent received from Google pub/sub app:2902021-12-29 10:47:11.953 am infoSending sdm.devices.commands.ThermostatMode.SetMode to Shop Kayak with params: [mode:HEAT] app:2902021-12-29 10:47:11.934 am infoSending sdm.devices.commands.ThermostatMode.SetMode to Shop Far with params: [mode:HEAT] app:2902021-12-29 10:28:01.053 am debug{ "eventId": "4a0751db-0f09-44f5-950a-06829ea43396", "timestamp": "2021-12-29T18:27:57.137Z", "resourceUpdate": { "name": "enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA", "traits": { "sdm.devices.traits.Temperature": { "ambientTemperatureCelsius": 6.09999 } } }, "userId": "AVPHwEv6dqZAvtGa8hvYGnG5mxmUt1A8V6GkIasiW6_M", "resourceGroup": ["enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA"]} app:2902021-12-29 10:28:01.050 am debugEvent received from Google pub/sub app:2902021-12-29 10:27:58.109 am debug{ "eventId": "1e7049df-21f6-4997-959f-ebe1be882820", "timestamp": "2021-12-29T18:27:56.519Z", "resourceUpdate": { "name": "enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA", "traits": { "sdm.devices.traits.Humidity": { "ambientHumidityPercent": 47.0 } } }, "userId": "AVPHwEv6dqZAvtGa8hvYGnG5mxmUt1A8V6GkIasiW6_M", "resourceGroup": ["enterprises/503a503c-ab6e-4c7e-ae97-8125ff3ffc7e/devices/AVPHwEvsSS2Uf1nobtxUxOwtp4bo4voXp9S5avzNDmBXGT0V306G4JkdRLVITHeWAuy-K6gVclMJ7LcKO1nxIafVnvtUSA"]}

Download the Hubitat app