Skip to content

Commit

Permalink
added nest connector
Browse files Browse the repository at this point in the history
  • Loading branch information
sud335 committed Aug 19, 2016
1 parent 449dc3c commit 919ed43
Show file tree
Hide file tree
Showing 3 changed files with 279 additions and 0 deletions.
12 changes: 12 additions & 0 deletions config/nest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"credentials": {
"PIN": "NBCFUAG4",
"Product_id": "89d2d205-3297-419f-9405-9115c33e7881",
"Product_secret": "01XrOHyiXTLzgCX0e5VTcebGe",
"access_token": "c.Msbr1TYGaNit1p6qPdklCuAH4usOM64JWH8hgKrEIByEdOzpDyesA5JiEU12m4NmGSaJ0IOldRzcY6qdOieCX54bC51tqAcFGaSCQiPgLdbvudy5WvAjjSd01u4QKP5nUeJY0gbhbatD4og6"
},
"url": {
"_AUTH_REQ": "https://api.home.nest.com/oauth2/access_token",
"_DEVICELIST_REQ": "https://developer-api.nest.com/devices?auth="
}
}
267 changes: 267 additions & 0 deletions nest/NEST-CLASS.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
import json
import requests
from bd_connect.connect_bd import get_json
from config.setting import Setting
from pprint import pprint

'''
About:
This module is a connector that connects any Nest device to the
Building DepotV3.1 with the help of the bd connect program.
Configuration:
To be able to have the program access your Nest data, you have
to register your program as a Nest app in your Netatmo account at
https://develper.nest.com. You have to go on create new product, choose
the appropriate permissions and enter the required details in the
nest_config.json file. The pin code can be received by clicking on
the authorization url.
'''

class ClientAuth(object):
'''
Class definition to get the access token, it does not need to be
refreshed
'''
def __init__(self, credentials_file = "nest"):
'''
Recieves the credentials from the config file and executes the
setup function to get the access token
Args:
credentials_file: The json file containing the Product ID, Product
Secret, PIN and the access token (which is
obtained from the other information if not
present). It is in the config folder with the
default name "nest".
'''
self.credentials_file = credentials_file
self.setup()

def setup(self):
'''
Obtains the access token if present and calls the access_token()
function if the access_token is not present, using the Product Id,
Product Secret, and PIN.
Args as Data:
Product_id: #product id of the registered product
Product_secret: #product secret of the registered product
PIN: #generated by clicking on the authorization url,
must be updated after every use
access_token: #needed for access. If it is not present, the
other three args are used to generate it.
'''
credentials = Setting(self.credentials_file)
self.urls = credentials.setting["url"]
self._accessToken = credentials.setting["credentials"]["access_token"]
# get the access token

if (self._accessToken == ""):
# generate access token if it is not present
self.code, self.client_id, self.client_secret = (
credentials.setting["credentials"]["PIN"],
credentials.setting["credentials"]["Product_id"],
credentials.setting["credentials"]["Product_secret"])
self.access_token()
self.devices = dict() # generate an empty dictionary for all NEST
# devices linked to the account

def access_token(self):
'''
Update the access_token if it is not present in the config file
'''

url = self.urls["_AUTH_REQ"]
params = {"code": self.code, "client_id": self.client_id,
"client_secret": self.client_secret,
"grant_type": "authorization_code"}

response = requests.post(url, params = params)
try:
self._accessToken = response.json()["access_token"]
except:
self._accessToken = None
print(response)

class DeviceList(object):
'''
Class definition of Nest to obtain the Nest device data and
update the data in the Building depot.
'''

def __init__(self, authData):
'''
Initilize the auth token and obtain the device modules data
of NEST
Args as data:
"authData": class object of ClientAuth provides
access token.
'''
self.getAuthToken = authData._accessToken
url = (authData.urls["_DEVICELIST_REQ"] + self.getAuthToken)
header = {"Authorization": "Bearer " + self.getAuthToken}
response = requests.get(url, headers = header, allow_redirects=True)
try:
self.devices = response.json()
except:
print(response)

def deviceByType(self, deviceType = "smoke_co_alarms"):
'''
Find the Nest data by device type (eg. thermostats,
smoke_co_alarms). If none given finds all the data of the each
Nest device connected to the given account
Args as data:
"deviceType": device type (eg. thermostats, smoke_co_alarms)
'''
if deviceType == None: return self.devices
try:
return self.devices[deviceType]
except:
print("No devices of such type")
return None

def deviceByID(self, deviceType = "smoke_co_alarms", deviceID = None):
'''
Find the Nest data by device ID, i.e. a specific device.
If none given finds all the data of the each
Nest device connected to the given account
Args as data:
"deviceType": device type
"deviceID": unique ID to identify the device
'''
if deviceType == None or deviceID == None: return self.devices
try:
return self.devices[deviceType][deviceID]
except:
print("Device ID does not exist or is not connected to this \
account")
return None

def deviceByName(self, deviceName = None):
'''
Find the Nest data by device Name, i.e. the name give to
a specific Nest Device.If none given finds all the data of the each
Nest device connected to the given account.
Nest has two names, name_long and name, we recommend using
name_long as multiple devices of different types can have the
same name.
Args as data:
"deviceName": Name given to the specific device
'''
if deviceName == None: return self.devices
for deviceType in self.devices:
typeList = self.devices[deviceType]
for deviceID in typeList:
deviceData = typeList[deviceID]
if (deviceData["name"] == deviceName or
deviceData["name_long"] == deviceName):
return deviceData
print("No devices with given name")
return None

def get_device_data(self, deviceType = "smoke_co_alarms",
deviceID = None, deviceName = None):
'''
Obtain the data of all NEST devices of a particular device in the
form of a dictionary.
Args as data:
deviceType: the type of nest device (eg. thermostats,
smoke_co_alarms)
deviceID: unique ID of the device. The device type must be
that of the device.
deviceName: Name given to the device.
Returns:
{
u"co_alarm_state": #whether the state is ok or not.
u"smoke_alarm_state": #whether the state is ok or not
U"battery_health": #whether the state is ok or not
}
'''

if (deviceID != None and deviceType != None):
data = self.deviceByID(deviceType, deviceID)
elif (deviceName != None):
data = self.deviceByName(deviceName)
else:
print("Please enter a valid deviceID or deviceName")
data = None

if (data == None):
return

nest_data = {}
nest_data["co_alarm_state"] = data["co_alarm_state"]
nest_data["smoke_alarm_state"] = data["smoke_alarm_state"]
nest_data["battery_health"] = data["battery_health"]
nest_data["mac_id"] = data["device_id"]
return nest_data

def post_to_bd(self, deviceData):
"""
Post json object information to BD_Connect in this format
data={"sensor_data":{<all sensor data>}}
Args as data:
{<netatmo station data>}
Returns:
{
"success": "True"
"HTTP Error 400": "Bad Request"
}
"""
data = {'sensor_data': {}}
data['sensor_data'].update(deviceData)
response = get_json(json.dumps(data))
return response

if __name__ == "__main__":
"""
Reads the data from Nest Protect Devices and writes it to the building
depot.
Returns:
{
"success": "True"
"HTTP Error 400": "Bad Request"
}
else
{
"Error in Device Connection"
}
"""
from sys import exit, stderr

try:
auth = ClientAuth() # Get authentication key
if (auth._accessToken == None):
stderr.write("Please Enter the valid credentials to get\
the access token")
exit(1)

devList = DeviceList(auth) # Obtain the DEVICELIST
nest_data = devList.deviceByType() # Get the data for the type of
# devices
for device_id in nest_data:
try:
device_data = devList.get_device_data(deviceID = device_id)
resp = devList.post_to_bd(device_data)
# Send Data to the BuildingDepot
print "Response from connect_bd.py:\n", resp
except Exception as e:
print "Error in Sending data to connect_bd.py", e

except Exception as e:
print "Error in Device Connection", e
Empty file added nest/__init__.py
Empty file.

0 comments on commit 919ed43

Please sign in to comment.