diff --git a/teslajson.py b/teslajson.py index 4055e05..ec4284a 100644 --- a/teslajson.py +++ b/teslajson.py @@ -15,144 +15,144 @@ """ try: # Python 3 - from urllib.parse import urlencode - from urllib.request import Request, build_opener - from urllib.request import ProxyHandler, HTTPBasicAuthHandler, HTTPHandler + from urllib.parse import urlencode + from urllib.request import Request, build_opener + from urllib.request import ProxyHandler, HTTPBasicAuthHandler, HTTPHandler except: # Python 2 - from urllib import urlencode - from urllib2 import Request, build_opener - from urllib2 import ProxyHandler, HTTPBasicAuthHandler, HTTPHandler + from urllib import urlencode + from urllib2 import Request, build_opener + from urllib2 import ProxyHandler, HTTPBasicAuthHandler, HTTPHandler import json import datetime import calendar class Connection(object): - """Connection to Tesla Motors API""" - def __init__(self, - email='', - password='', - access_token='', - proxy_url = '', - proxy_user = '', - proxy_password = ''): - """Initialize connection object - - Sets the vehicles field, a list of Vehicle objects - associated with your account + """Connection to Tesla Motors API""" + def __init__(self, + email='', + password='', + access_token='', + proxy_url = '', + proxy_user = '', + proxy_password = ''): + """Initialize connection object + + Sets the vehicles field, a list of Vehicle objects + associated with your account - Required parameters: - email: your login for teslamotors.com - password: your password for teslamotors.com - - Optional parameters: - access_token: API access token - proxy_url: URL for proxy server - proxy_user: username for proxy server - proxy_password: password for proxy server - """ - self.proxy_url = proxy_url - self.proxy_user = proxy_user - self.proxy_password = proxy_password - tesla_client = self.__open("/raw/0a8e0xTJ", baseurl="http://pastebin.com") - current_client = tesla_client['v1'] - self.baseurl = current_client['baseurl'] - if not self.baseurl.startswith('https:') or not self.baseurl.endswith(('.teslamotors.com','.tesla.com')): - raise IOError("Unexpected URL (%s) from pastebin" % self.baseurl) - self.api = current_client['api'] - if access_token: - self.__sethead(access_token) - else: - self.oauth = { - "grant_type" : "password", - "client_id" : current_client['id'], - "client_secret" : current_client['secret'], - "email" : email, - "password" : password } - self.expiration = 0 # force refresh - self.vehicles = [Vehicle(v, self) for v in self.get('vehicles')['response']] - - def get(self, command): - """Utility command to get data from API""" - return self.post(command, None) - - def post(self, command, data={}): - """Utility command to post data to API""" - now = calendar.timegm(datetime.datetime.now().timetuple()) - if now > self.expiration: - auth = self.__open("/oauth/token", data=self.oauth) - self.__sethead(auth['access_token'], - auth['created_at'] + auth['expires_in'] - 86400) - return self.__open("%s%s" % (self.api, command), headers=self.head, data=data) - - def __sethead(self, access_token, expiration=float('inf')): - """Set HTTP header""" - self.access_token = access_token - self.expiration = expiration - self.head = {"Authorization": "Bearer %s" % access_token} - - def __open(self, url, headers={}, data=None, baseurl=""): - """Raw urlopen command""" - if not baseurl: - baseurl = self.baseurl - req = Request("%s%s" % (baseurl, url), headers=headers) - try: - req.data = urlencode(data).encode('utf-8') # Python 3 - except: - try: - req.add_data(urlencode(data)) # Python 2 - except: - pass + Required parameters: + email: your login for teslamotors.com + password: your password for teslamotors.com + + Optional parameters: + access_token: API access token + proxy_url: URL for proxy server + proxy_user: username for proxy server + proxy_password: password for proxy server + """ + self.proxy_url = proxy_url + self.proxy_user = proxy_user + self.proxy_password = proxy_password + tesla_client = self.__open("/raw/0a8e0xTJ", baseurl="http://pastebin.com") + current_client = tesla_client['v1'] + self.baseurl = current_client['baseurl'] + if not self.baseurl.startswith('https:') or not self.baseurl.endswith(('.teslamotors.com','.tesla.com')): + raise IOError("Unexpected URL (%s) from pastebin" % self.baseurl) + self.api = current_client['api'] + if access_token: + self.__sethead(access_token) + else: + self.oauth = { + "grant_type" : "password", + "client_id" : current_client['id'], + "client_secret" : current_client['secret'], + "email" : email, + "password" : password } + self.expiration = 0 # force refresh + self.vehicles = [Vehicle(v, self) for v in self.get('vehicles')['response']] + + def get(self, command): + """Utility command to get data from API""" + return self.post(command, None) + + def post(self, command, data={}): + """Utility command to post data to API""" + now = calendar.timegm(datetime.datetime.now().timetuple()) + if now > self.expiration: + auth = self.__open("/oauth/token", data=self.oauth) + self.__sethead(auth['access_token'], + auth['created_at'] + auth['expires_in'] - 86400) + return self.__open("%s%s" % (self.api, command), headers=self.head, data=data) + + def __sethead(self, access_token, expiration=float('inf')): + """Set HTTP header""" + self.access_token = access_token + self.expiration = expiration + self.head = {"Authorization": "Bearer %s" % access_token} + + def __open(self, url, headers={}, data=None, baseurl=""): + """Raw urlopen command""" + if not baseurl: + baseurl = self.baseurl + req = Request("%s%s" % (baseurl, url), headers=headers) + try: + req.data = urlencode(data).encode('utf-8') # Python 3 + except: + try: + req.add_data(urlencode(data)) # Python 2 + except: + pass - # Proxy support - if self.proxy_url: - if self.proxy_user: - proxy = ProxyHandler({'https': 'https://%s:%s@%s' % (self.proxy_user, - self.proxy_password, - self.proxy_url)}) - auth = HTTPBasicAuthHandler() - opener = build_opener(proxy, auth, HTTPHandler) - else: - handler = ProxyHandler({'https': self.proxy_url}) - opener = build_opener(handler) - else: - opener = build_opener() - resp = opener.open(req) - charset = resp.info().get('charset', 'utf-8') - return json.loads(resp.read().decode(charset)) - + # Proxy support + if self.proxy_url: + if self.proxy_user: + proxy = ProxyHandler({'https': 'https://%s:%s@%s' % (self.proxy_user, + self.proxy_password, + self.proxy_url)}) + auth = HTTPBasicAuthHandler() + opener = build_opener(proxy, auth, HTTPHandler) + else: + handler = ProxyHandler({'https': self.proxy_url}) + opener = build_opener(handler) + else: + opener = build_opener() + resp = opener.open(req) + charset = resp.info().get('charset', 'utf-8') + return json.loads(resp.read().decode(charset)) + class Vehicle(dict): - """Vehicle class, subclassed from dictionary. - - There are 3 primary methods: wake_up, data_request and command. - data_request and command both require a name to specify the data - or command, respectively. These names can be found in the - Tesla JSON API.""" - def __init__(self, data, connection): - """Initialize vehicle class - - Called automatically by the Connection class - """ - super(Vehicle, self).__init__(data) - self.connection = connection - - def data_request(self, name): - """Get vehicle data""" - result = self.get('data_request/%s' % name) - return result['response'] - - def wake_up(self): - """Wake the vehicle""" - return self.post('wake_up') - - def command(self, name, data={}): - """Run the command for the vehicle""" - return self.post('command/%s' % name, data) - - def get(self, command): - """Utility command to get data from API""" - return self.connection.get('vehicles/%i/%s' % (self['id'], command)) - - def post(self, command, data={}): - """Utility command to post data to API""" - return self.connection.post('vehicles/%i/%s' % (self['id'], command), data) + """Vehicle class, subclassed from dictionary. + + There are 3 primary methods: wake_up, data_request and command. + data_request and command both require a name to specify the data + or command, respectively. These names can be found in the + Tesla JSON API.""" + def __init__(self, data, connection): + """Initialize vehicle class + + Called automatically by the Connection class + """ + super(Vehicle, self).__init__(data) + self.connection = connection + + def data_request(self, name): + """Get vehicle data""" + result = self.get('data_request/%s' % name) + return result['response'] + + def wake_up(self): + """Wake the vehicle""" + return self.post('wake_up') + + def command(self, name, data={}): + """Run the command for the vehicle""" + return self.post('command/%s' % name, data) + + def get(self, command): + """Utility command to get data from API""" + return self.connection.get('vehicles/%i/%s' % (self['id'], command)) + + def post(self, command, data={}): + """Utility command to post data to API""" + return self.connection.post('vehicles/%i/%s' % (self['id'], command), data)