For those curious, below is the script library I have created so far for getting data back from my Nest thermostat. It requires walking through the first few steps of the guide @matthew.ayre posted in the sixth reply to this thread before you’re able to use it though. I have this saved as a script named ‘devices.nest’.
project_id = 'your-project-id-here'
client_id = 'your-client-id-here'
client_secret = 'your-client-secret-here'
redirect_uri = 'https://www.google.com'
device_id = 'your-device-id-here'
code = 'your-code-here'
scope = 'https://www.googleapis.com/auth/sdm.service'
basePath = '[default]Devices/Nest/'
accessTokenPath = basePath + 'Access Token'
refreshTokenPath = basePath + 'Refresh Token'
tokenTimePath = basePath + 'Token Timestamp'
namePath = basePath + 'Device Name'
humidityFbkPath = basePath + 'Current Humidity'
tempFbkPath = basePath + 'Current Temperature'
modeFbkPath = basePath + 'Current Mode'
stateFbkPath = basePath + 'Current State'
heatSpPath = basePath + 'Heat Setpoint'
coolSpPath = basePath + 'Cool Setpoint'
commsFbkPath = basePath + 'Comms'
# This can be called from the script console after configuring Google's security permissions to grant access to your Nest device
def getToken():
url = 'https://www.googleapis.com/oauth2/v4/token?client_id=' + client_id + '&client_secret=' + client_secret + '&code=' + code + '&grant_type=authorization_code&redirect_uri=' + redirect_uri
response = system.net.httpPost(url=url, postData={})
json = system.util.jsonEncode(response)
access_token = json['access_token']
refresh_token = json['refresh_token']
system.tag.writeAsync([accessTokenPath, refreshTokenPath], [access_token, refresh_token])
comments = """Access token: %d
Refresh token: %d""" % (access_token, refresh_token)
return comments
# Refresh the access token and write it to the Access Token memory tag
def refreshToken():
url = 'https://www.googleapis.com/oauth2/v4/token'
refresh_token = system.tag.readBlocking([refreshTokenPath])[0].value
postParams = {
'client_id' : client_id,
'client_secret' : client_secret,
'refresh_token' : refresh_token,
'grant_type' : 'refresh_token'
}
response = system.net.httpPost(url, postParams)
json = system.util.jsonDecode(response)
access_token = json['access_token']
timestamp = system.date.now()
system.tag.writeAsync([accessTokenPath, tokenTimePath], [access_token, timestamp])
comments = 'Access token: ' + access_token
return comments
# Build out the headerValues argument used in most of the system.net.httpGet() API calls
def getHeaders():
access_token = system.tag.readBlocking([accessTokenPath])[0].value
return {
'Content-Type' : 'application/json',
'Authorization' : 'Bearer ' + access_token,
}
# Convert celsius temperatures to fahrenheit
def cToF(temp):
return (temp * 9/5) + 32
# Convert fahrenheit temperatures to celsius
def fToC(temp):
return (temp - 32) * 5/9
# Write the current values return from the Nest API to my pre-defined tags.
def getCurrentValues():
deviceName = system.tag.readBlocking([namePath])[0].value
url = 'https://smartdevicemanagement.googleapis.com/v1/' + deviceName
headers = getHeaders()
response = system.util.jsonDecode(system.net.httpGet(url, headerValues=headers))
paths = [
humidityFbkPath,
tempFbkPath,
coolSpPath,
heatSpPath,
modeFbkPath,
stateFbkPath,
commsFbkPath
]
traits = response['traits']
sp = traits['sdm.devices.traits.ThermostatTemperatureSetpoint']
comms = False
if str(traits['sdm.devices.traits.Connectivity']['status']) == 'ONLINE':
comms = True
tempC = traits['sdm.devices.traits.Temperature']['ambientTemperatureCelsius']
coolSpC = sp['coolCelsius']
heatSpC = sp['heatCelsius']
values = [
traits['sdm.devices.traits.Humidity']['ambientHumidityPercent'],
cToF(tempC),
cToF(coolSpC),
cToF(heatSpC),
traits['sdm.devices.traits.ThermostatMode']['mode'],
traits['sdm.devices.traits.ThermostatHvac']['status'],
comms
]
system.tag.writeAsync(paths, values)
I am hardcoding my constant variables at the top of the script and anything else that could change in the future I’m writing to memory tags. I have all my Nest related memory tags kept in a folder at [default]Devices/Nest/, personally.
I update the values by simply using a gateway event timer script that runs once a minute that looks something like this:
try:
devices.nest.getCurrentValues()
except:
devices.nest.refreshToken()
So far, my script only handles reading values back from the Nest. Eventually I’ll bother with writing data back out to the API, but this is all I care to do at the moment while I fuss with connecting the rest of my smart things to this project.