smbaker / pynest Goto Github PK
View Code? Open in Web Editor NEWpython API for talking to nest thermostat
python API for talking to nest thermostat
Add this patch to set your structure as away or not.
diff --git a/nest.py b/nest.py
index 7fcf863..01de92d 100755
--- a/nest.py
+++ b/nest.py
@@ -17,6 +17,7 @@
+import time
import urllib
import urllib2
import sys
@@ -131,6 +132,7 @@ class Nest:
def set_fan(self, state):
data = '{"fan_mode":"' + str(state) + '"}'
print data
req = urllib2.Request(self.transport_url + "/v2/put/device." + self.serial,
data,
{"user-agent":"Nest/1.1.0.10 CFNetwork/548.0.4",
+import time
import urllib
import urllib2
import sys
@@ -131,6 +132,7 @@ class Nest:
def set_fan(self, state):
data = '{"fan_mode":"' + str(state) + '"}'
print data
req = urllib2.Request(self.transport_url + "/v2/put/device." + self.serial,
data,
{"user-agent":"Nest/1.1.0.10 CFNetwork/548.0.4",
@@ -141,6 +143,24 @@ class Nest:
print res
def set_away(self, state):
time_since_epoch = time.time()
# time_since_epoch = 1345299535
if (state == "away"):
data = '{"away_timestamp":' + str(time_since_epoch) + ',"away":true,"away_setter":0}'
else:
data = '{"away_timestamp":' + str(time_since_epoch) + ',"away":false,"away_setter":0}'
print data
req = urllib2.Request(self.transport_url + "/v2/put/structure." + self.structure_id,
data,
{"user-agent":"Nest/1.1.0.10 CFNetwork/548.0.4",
"Authorization":"Basic " + self.access_token,
"X-nl-protocol-version": "1"})
res = urllib2.urlopen(req).read()
print res
def create_parser():
parser = OptionParser(usage="nest [options] command [command_options] [command_args]",
description="Commands: fan temp",
@@ -161,7 +181,6 @@ def create_parser():
parser.add_option("-i", "--index", dest="index", default=0, type="int",
help="optional, specify index number of nest to talk to")
there is no way to pick. Can you please add this functionality .
First of all, awesome! Thank you. I tried your script and I have 2 Nests on my account. Your commands only communicate with the first Nest it sees on the account. Can you add a parameter for the "name"?
We just started having an issue with our Nest Automation yesterday afternoon. It looks like the login endpoint is now returning a 406 error.
Reproduce:
curl -X POST \
https://home.nest.com/user/login \
-H 'Content-Type: application/json' \
-H 'cache-control: no-cache' \
-H 'user-agent: Nest/1.1.0.10 CFNetwork/548.0.4' \
-d '{"username" : "EMAIL", "password" : "PASs"}'
Response:
<html>
<head>
<title>406 Not Acceptable</title>
</head>
<body bgcolor="white">
<center>
<h1>406 Not Acceptable</h1>
</center>
<hr>
<center>nginx</center>
</body>
</html>
I had left a message on Error #13 and was asked to open a new issue. Here is the text I previously posted in that issue:
digilord,
I just tried to install your version of nest.py on my CentOS 5.10 server and got the below responses:
(root@myserver Linux)
(/root/nestdigilord/pynest-master)$ ll
Mon Apr 21 12:54:01 EDT 2014
total 24
-rw-r--r-- 1 root root 389 Apr 14 10:37 LICENSE.md
-rw-r--r-- 1 root root 37 Apr 14 10:37 MANIFEST.in
-rwxr-xr-x 1 root root 4023 Apr 14 10:37 nest.py*
drwxr-xr-x 2 root root 4096 Apr 14 10:37 nest_thermostat/
-rw-r--r-- 1 root root 1541 Apr 14 10:37 README.md
-rwxr-xr-x 1 root root 531 Apr 14 10:37 setup.py*
(root@myserver Linux)
(/root/nestdigilord/pynest-master)$ pip install ./nest_thermostat
Mon Apr 21 12:54:11 EDT 2014
Directory './nest_thermostat' is not installable. File 'setup.py' not found.
Storing complete log in /root/.pip/pip.log
I am not a python programmer but had been using the pynest project successfully until sometime in March when it suddenly stopped working.
Can you please help me get it working again?
Ron
Here is the current contents of the pip.log in its entirety:
/usr/bin/pip-python run on Mon Apr 21 12:54:11 2014
Directory './nest_thermostat' is not installable. File 'setup.py' not found.
Exception information:
Traceback (most recent call last):
File "/usr/lib/python2.4/site-packages/pip/basecommand.py", line 124, in main
self.run(options, args)
File "/usr/lib/python2.4/site-packages/pip/commands/install.py", line 169, in run
requirement_set.add_requirement(
File "/usr/lib/python2.4/site-packages/pip/req.py", line 89, in from_line
raise InstallationError("Directory %r is not installable. File 'setup.py' not found."
InstallationError: Directory './nest_thermostat' is not installable. File 'setup.py' not found.
It would be nice to be able to adjust the fan_control_state to True or False
I had everything running good, but now I get the following error when the script runs.
2014-03-15 21:11:16.621005: [debug] Calling notify [/usr/bin/notifynest.sh] with arg1 [away], arg2 [0], arg3 [0d 00:00:00]
2014-03-15 21:11:17.349267: #### BEGIN EXCEPTION #####
2014-03-15 21:11:17.349336: Command '['/usr/bin/notifynest.sh', 'away', '0', '0d 00:00:00']' returned non-zero exit status 1
2014-03-15 21:11:17.349359: Output from notify follows:
Updating Nest with away status: away
Property occupied for 0d 00:00:00 (0 seconds)
Traceback (most recent call last):
File "/usr/bin/nest.py", line 324, in
main()
File "/usr/bin/nest.py", line 280, in main
n.login()
File "/usr/bin/nest.py", line 96, in login
res = urllib2.urlopen(req).read()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 127, in urlopen
return _opener.open(url, data, timeout)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 410, in open
response = meth(req, response)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 523, in http_response
'http', request, response, code, msg, hdrs)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 448, in error
return self._call_chain(_args)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 382, in _call_chain
result = func(_args)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 531, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 403: FORBIDDEN
2014-03-15 21:11:17.349409: #### END EXCEPTION #####
Any help with this would be great.
With the May 2014 update, the protocol has been upgraded to protect against heartbleed. Additional tokens are needed, which I can see after the login step. I do not know how to update the authentication headers for the status request.
This looks like the same issue people are having in issue #13
New header information received:
"weave":{"service_config":"1QAADwABADYBFTABCEdYfNbKQ+Z8JAIENwMnEwEAAADuMLQYGCYERUgWGiYFRQb7STcGJxMBAAAA7jC0GBgkBwImCCUAWiMwCjkEFJtArVoBj0T+fpKZeV1TBT0osdlSUx1FRK1ZTcslNfDQSMUwiG3iH5tQjeGhrxbfr0kphGthRBA1gykBKQIYNYIpASQCYBg1gTACCEM09xLfX5HPGDWAMAIIQzT3Et9fkc8YNQwwAR0AlvB51cbUag/T//0P7EqwJNQATpT0hWNT7odJgzACHQCPTm4jL9hwiKnIKvpqXtz6LnCd0ifQrU9apo0jGBgVMAEIX3K9Q5O0VOYkAgQ3AywBBjQzNTgwORgmBF5WiBomBd5Qry03BiwBBjQzNTgwORgkBwImCCUAWiMwCjkEjUjE2bPPnq3l9PzZPlCVyuJZ0A4WdWR5hP4MqPuMyrQzwIB0jRKGnGfCDuEdu2kDPMRqoVORzRg1gykBGDWCKQEkAgUYNYQpATYCBAIEARgYNYEwAghN1iUtLJf3Phg1gDACCE3WJS0sl/c+GDUMMAEdAPc8ogkknI5dWI4ASNo5x8Ihanxb2034nZZtHqcwAhtPEn32dtoEZKGI9P2mcQyzl65D7ygpE7WrA8QYGBg1AicBAQAAAAIwtBg2AhUsARJmcm9udGRvb3IubmVzdC5jb20lAlcrGBgYGA==","pairing_token":"wu.wrG5K0ngGjFqrXFxguuqBw0XWuE5JEb+Negty0yhbbN1AdR5wSpsITa1tD3D7urLhPmTDoxaTmxMYWWIMRIvtVZEiYI=","access_token":"lQkANQEwAQhfcr1Dk7RU5iQCBDcDLAEGNDM1ODA5GCYEXlaIGiYF3lCvLTcGLAEGNDM1ODA5GCQHAiYIJQBaIzAKOQSNSMTZs8+ereX0/Nk+UJXK4lnQDhZ1ZHmE/gyo+4zKtDPAgHSNEoacZ8IO4R27aQM8xGqhU5HNGDWDKQEYNYIpASQCBRg1hCkBNgIEAgQBGBg1gTACCE3WJS0sl/c+GDWAMAIITdYlLSyX9z4YNQwwAR0A9zyiCSScjl1YjgBI2jnHwiFqfFvbTfidlm0epzACG08SffZ22gRkoYj0/aZxDLOXrkPvKCkTtasDxBgYNQImASUAWiMwAh0A2p7qx3JbS7MJZiKkrExVLrGRJwGG4Q3t8NjDZxgY"}}
Hello!
I just stumbled across pynest and it is exactly what I needed to track my nest thermostats, so thank you very much for it!
One peculiarity I came across is:
I use the "show" option to get all data and then grep from it what I need. The thermostat is set to use degrees Fahrenheit, but even without using the --celsius option I get the temperatures in Celsius. When I use the "curtemp" mode, it works as expected.
I could certainly implement a script to convert the celsius to fahrenheit, but as the thermostat is set to fahrenheit anyway, converting back and forth is kind of a dirty hack.
Thanks!
Sorry, this was a glitch in my code
This is more of a request. Can you add a line that checks for the version of Python and if it's 2.5 import simplejson as json ?
I am trying to periodically run with cron a script that will change my Nest from heat to cool and back based on logic using current set point and current temp.
I can read the current temp and change the set point with this code but cannot get the mode change working with the hacked code that I am trying. I have added this section to the code I downloaded:
def set_mode(self, state):
data = '{"target_change_pending":true,"target_temperature_type":"' + str(state) + '"}'
req = urllib2.Request(self.transport_url + "/v2/put/device." + self.serial,
data,
{"user-agent":"Nest/1.1.0.10 CFNetwork/548.0.4",
"Authorization":"Basic " + self.access_token,
"X-nl-protocol-version": "1"})
res = urllib2.urlopen(req).read()
print res
I get this when I try to run it from the command line on my CentOS box that does have curl installed as a module and with yum:
./nest.py --user [email protected] --password notmypassword setmode off
Traceback (most recent call last):
File "./nest.py", line 261, in ?
main()
File "./nest.py", line 245, in main
n.set_mode(args[1])
File "./nest.py", line 157, in set_mode
res = urllib2.urlopen(req).read()
File "/usr/lib64/python2.4/urllib2.py", line 130, in urlopen
return _opener.open(url, data)
File "/usr/lib64/python2.4/urllib2.py", line 364, in open
response = meth(req, response)
File "/usr/lib64/python2.4/urllib2.py", line 471, in http_response
response = self.parent.error(
File "/usr/lib64/python2.4/urllib2.py", line 402, in error
return self._call_chain(_args)
File "/usr/lib64/python2.4/urllib2.py", line 337, in _call_chain
result = func(_args)
File "/usr/lib64/python2.4/urllib2.py", line 480, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 400: Bad Request
Can you help me get this working from the command line please?
Ron
I wrote a program that relies on your script and recently (at 5:00 PM on 3/17) it stopped being able to get any data from the nest. The traceback is very similar to issue #12
Traceback (most recent call last):
File "/Users/scott/Desktop/nest.py", line 239, in <module>
main()
File "/Users/scott/Desktop/nest.py", line 214, in main
n.get_status()
File "/Users/scott/Desktop/nest.py", line 77, in get_status
res = urllib2.urlopen(req).read()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 127, in urlopen
return _opener.open(url, data, timeout)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 404, in open
response = self._open(req, data)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 422, in _open
'_open', req)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 382, in _call_chain
result = func(*args)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1222, in https_open
return self.do_open(httplib.HTTPSConnection, req)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1184, in do_open
raise URLError(err)
urllib2.URLError: \<urlopen error [Errno 8] _ssl.c:504: EOF occurred in violation of protocol>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.