teslajson - attach variable to command

Posted on
Wed Mar 13, 2019 12:34 pm
davinci offline
Posts: 249
Joined: Feb 14, 2015

teslajson - attach variable to command

Code: Select all
        command_check = v.command('honk_horn')
        command_result = command_check['response']["result"]


I know this works as described on this page:
https://tesla-api.timdorr.com/vehicle/commands/alerts

However, I don't know how to do this:
https://tesla-api.timdorr.com/vehicle/commands/trunk

I have to attach a variable (frunk or trunk).

How can I do this?

Thanks

Posted on
Wed Mar 13, 2019 12:48 pm
jay (support) offline
Site Admin
User avatar
Posts: 15153
Joined: Mar 19, 2008
Location: Austin, Texas

Re: teslajson - attach variable to command

We're missing something important here - what is v exactly?

And the follow-on, what exactly does the command() method do?

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Wed Mar 13, 2019 12:52 pm
davinci offline
Posts: 249
Joined: Feb 14, 2015

Re: teslajson - attach variable to command

Sorry, I missed that.

I'm using this python library:
https://github.com/gglockner/teslajson

Code: Select all
import teslajson
c = teslajson.Connection('youremail', 'yourpassword')
v = c.vehicles[0]
v.wake_up()
v.command('honk_horn')

Posted on
Wed Mar 13, 2019 5:29 pm
jay (support) offline
Site Admin
User avatar
Posts: 15153
Joined: Mar 19, 2008
Location: Austin, Texas

Re: teslajson - attach variable to command

Here's the command method definition:

Code: Select all
    def command(self, name, data={}):
        """Run the command for the vehicle"""
        return self.post('command/%s' % name, data)


It looks like you pass an optional data parameter which is a dictionary, so that's likely where you need to pass the extra data used by that API call.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Thu Mar 14, 2019 1:05 am
davinci offline
Posts: 249
Joined: Feb 14, 2015

Re: teslajson - attach variable to command

Thanks

Code: Select all
v.command('actuate_trunk',‘front‘)



This code does not work. But maybe I misunderstood you.

Posted on
Thu Mar 14, 2019 8:45 am
jay (support) offline
Site Admin
User avatar
Posts: 15153
Joined: Mar 19, 2008
Location: Austin, Texas

Re: teslajson - attach variable to command

I haven't fully read the API doc, so I don't really understand it. But, given the information about the parameters, I'd guess that you'd want to do:

Code: Select all
v.command('actuate_trunk', data={'which_trunk': ‘front‘})


since the data parameter to command is expecting a dictionary and based on that particular API description, I'm guessing that it's wanting the parameter name (which_trunk) as the key and the value (rear or front) as the value in the dictionary passed in. But just a guess of course - you'd really need to read through the API and the library you're using to fully understand it.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Thu Mar 14, 2019 12:04 pm
davinci offline
Posts: 249
Joined: Feb 14, 2015

Re: teslajson - attach variable to command

Thank you a lot - it works like that.

I have an additional question. Python crashes if the server returns error 500. Is there a way to handle this and retry instead?

Code: Select all
   
   Script Error                    tesla_connect.py: HTTP Error 500: Internal Server Error
   Script Error                    Exception Traceback (most recent call shown last):
  tesla_connect.py, line 17, at top level
     File "build/bdist.macosx-10.14-intel/egg/teslajson.py", line 72, in __init__
       self.vehicles = [Vehicle(v, self) for v in self.get('vehicles')['response']]
     File "build/bdist.macosx-10.14-intel/egg/teslajson.py", line 76, in get
       return self.post(command, None)
     File "build/bdist.macosx-10.14-intel/egg/teslajson.py", line 82, in post
       auth = self.__open("/oauth/token", data=self.oauth)
     File "build/bdist.macosx-10.14-intel/egg/teslajson.py", line 119, in __open
       resp = opener.open(req)
     File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 437, in open
       response = meth(req, response)
     File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 550, in http_response
       'http', request, response, code, msg, hdrs)
     File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 475, in error
       return self._call_chain(*args)
     File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
       result = func(*args)
     File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 558, in http_error_default
       raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
HTTPError: HTTP Error 500: Internal Server Error

Posted on
Thu Mar 14, 2019 1:13 pm
jay (support) offline
Site Admin
User avatar
Posts: 15153
Joined: Mar 19, 2008
Location: Austin, Texas

Re: teslajson - attach variable to command

That's not a crash - it's an uncaught exception. Read up on how to handle Python exceptions (that link is just one of many articles on the subject).

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Sat Mar 16, 2019 2:08 am
davinci offline
Posts: 249
Joined: Feb 14, 2015

Re: teslajson - attach variable to command

Thanks that was helpful!

Posted on
Sun Mar 17, 2019 11:15 am
davinci offline
Posts: 249
Joined: Feb 14, 2015

Re: teslajson - attach variable to command

Unfortunately this is not yet fixed.

The problem is that the exception is thrown by teslajson.py. So even if I use try end except it won't intercept this error.
Code: Select all
# Wake up Tesla and try a few times until it works

retriesAfterError = 30
counterError = 0
while True:
    counterError = counterError + 1
    try:
        wake_response = v.wake_up()
        wake_result = wake_response['response']['state']
    except ValueError:
        indigo.server.log("Connection failed, try again... " + counterError + " of + retriesAfterError")
    if counterError >= retriesAfterError:
        indigo.server.log("Connection failed, maximum retries reached: " + ValueError)
        break
    if wake_result == 'online':
        break
    time.sleep(5)


However I might be able to fix teslajson.py:
Any ideas?

Code: Select all
 """ Simple Python class to access the Tesla JSON API
https://github.com/gglockner/teslajson

The Tesla JSON API is described at:
http://docs.timdorr.apiary.io/

Example:

import teslajson
c = teslajson.Connection('youremail', 'yourpassword')
v = c.vehicles[0]
v.wake_up()
v.data_request('charge_state')
v.command('charge_start')
"""

try: # Python 3
    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
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

        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))
       

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)

Posted on
Mon Mar 18, 2019 10:58 am
howartp offline
Posts: 3387
Joined: Jan 09, 2014
Location: West Yorkshire, UK

Re: teslajson - attach variable to command

Davinci, are you the same person posting pull requests to my Tesla plugin on github?

Let’s work out the problem on my plugin forum instead of asking Jay random questions.


Sent from my iPhone using Tapatalk Pro

Posted on
Mon Mar 18, 2019 2:36 pm
davinci offline
Posts: 249
Joined: Feb 14, 2015

Re: teslajson - attach variable to command

Not directly on yours, but I agree.

Posted on
Mon Mar 18, 2019 3:35 pm
howartp offline
Posts: 3387
Joined: Jan 09, 2014
Location: West Yorkshire, UK

Re: teslajson - attach variable to command

Ok.

Some chap called ZachBenz is pulling requests but I haven't a clue who they are or if they're on this forum.

Posted on
Mon Mar 18, 2019 5:01 pm
lanbrown offline
Posts: 884
Joined: Sep 26, 2017

Re: teslajson - attach variable to command

howartp wrote:
Ok.

Some chap called ZachBenz is pulling requests but I haven't a clue who they are or if they're on this forum.


https://forums.indigodomo.com/memberlist.php?mode=viewprofile&u=4988

Posted on
Mon Mar 18, 2019 5:18 pm
howartp offline
Posts: 3387
Joined: Jan 09, 2014
Location: West Yorkshire, UK

Re: teslajson - attach variable to command

That could be the one.

He’s never posted in my plugin forum, to my recollection. :-)


Sent from my iPhone using Tapatalk Pro

Who is online

Users browsing this forum: No registered users and 1 guest