gglockner wrote:Ha, someone found my Tesla JSON project! Indeed, I wrote it with the eventual intent of creating an Indigo plug-in, but I never made much progress because other things got in the way.
Unfortunately, your script needs some serious work. More importantly, it would be much better if it were a plug-in. If someone with UI experience wants to help me, I'm willing to collaborate on an open source project for a proper Tesla JSON plugin. Let me know.
Gusten wrote:Hi
Just Uninstalled my Nissan Leaf plugin and bought a Tesla
Have a question about this script, it runs perfectly and i get alot of variables, but is there any way to to get distance in KM insted of in Miles? a get all temperatures in Celsius
(I know i can convert veriable to a different variable, but was hoping not to)
Current version at end of thread.
Gusten wrote:Hi
Thanx
Is it possible to get the batteryrange as well in metric ?
Another question, i get the 10sec warning when running this script as embedded and it shuts down
(It changes the variables så it seems to be workning)
But it annoying, anyone else get this? Or do you run it as a file?
/Martin Gustafsson
""" 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, urlopen
except: # Python 2
from urllib import urlencode
from urllib2 import Request, urlopen
import json
from math import radians, cos, sin, asin, sqrt
import datetime
class Connection(object):
"""Connection to Tesla Motors API"""
def __init__(self,
email='',
password='',
access_token='',
url="https://owner-api.teslamotors.com",
api="/api/1/",
client_id = "e4a9949fcfa04068f59abb5a658f2bac0a3428e4652315490b659d5ab3f35a9e",
client_secret = "c75f14bbadc8bee3a7594412c31416f8300256d7668ea7e6e7f06727bfb9d220"):
"""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
url: base URL for the API
api: API string
client_id: API identifier
client_secret: Secret API identifier
"""
self.url = url
self.api = api
if not access_token:
oauth = {
"grant_type" : "password",
"client_id" : client_id,
"client_secret" : client_secret,
"email" : email,
"password" : password }
auth = self.__open("/oauth/token", data=oauth)
access_token = auth['access_token']
self.access_token = access_token
self.head = {"Authorization": "Bearer %s" % self.access_token}
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.__open("%s%s" % (self.api, command), headers=self.head)
def post(self, command, data={}):
"""Utility command to post data to API"""
return self.__open("%s%s" % (self.api, command), headers=self.head, data=data)
def __open(self, url, headers={}, data=None):
"""Raw urlopen command"""
req = Request("%s%s" % (self.url, url), headers=headers)
try:
req.data = urlencode(data).encode('utf-8') # Python 3
except:
try:
req.add_data(urlencode(data)) # Python 2
except:
pass
resp = urlopen(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):
"""Run the command for the vehicle"""
return self.post('command/%s' % name)
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):
"""Utility command to post data to API"""
return self.connection.post('vehicles/%i/%s' % (self['id'], command))
try:
indigo.variables.folder.create("Tesla") # Create Indigo variable folder if necessary
except ValueError:
pass
try:
indigo.variable.create("teslaUserName", value="Need Tesla Motors e-mail", folder=str("Tesla"))
except ValueError:
pass
try:
indigo.variable.create("teslaPassword", value="Need Tesla Motors password", folder=str("Tesla"))
except ValueError:
pass
c = Connection(indigo.variables["teslaUserName"].value, indigo.variables["teslaPassword"].value)
v = c.vehicles[0]
for k,i in v.items():
try:
indigo.variable.create(str(k), value=str(i), folder=str("Tesla"))
except ValueError:
indigo.variable.updateValue(str(k), value=str(i))
v.wake_up()
# for k,i in v.data_request('mobile_enabled').items():
# try:
# indigo.variable.create(str(k), value=str(i), folder=str("Tesla"))
# except ValueError:
# indigo.variable.updateValue(str(k), value=str(i))
try:
indigo.variables.folder.create("Tesla Charge") # Create Indigo variable folder if necessary
except ValueError:
pass
for k,i in v.data_request('charge_state').items():
try:
indigo.variable.create(str(k), value=str(i), folder=str("Tesla Charge"))
except ValueError:
indigo.variable.updateValue(str(k), value=str(i))
try:
indigo.variables.folder.create("Tesla Climate") # Create Indigo variable folder if necessary
except ValueError:
pass
for k,i in v.data_request('climate_state').items():
try:
indigo.variable.create(str(k), value=str(i), folder=str("Tesla Climate"))
except ValueError:
indigo.variable.updateValue(str(k), value=str(i))
try:
indigo.variables.folder.create("Tesla Drive") # Create Indigo variable folder if necessary
except ValueError:
pass
for k,i in v.data_request('drive_state').items():
try:
indigo.variable.create(str(k), value=str(i), folder=str("Tesla Drive"))
except ValueError:
indigo.variable.updateValue(str(k), value=str(i))
try:
indigo.variables.folder.create("Tesla GUI") # Create Indigo variable folder if necessary
except ValueError:
pass
for k,i in v.data_request('gui_settings').items():
try:
indigo.variable.create(str(k), value=str(i), folder=str("Tesla GUI"))
except ValueError:
indigo.variable.updateValue(str(k), value=str(i))
try:
indigo.variables.folder.create("Tesla Vehicle") # Create Indigo variable folder if necessary
except ValueError:
pass
for k,i in v.data_request('vehicle_state').items():
try:
indigo.variable.create(str(k), value=str(i), folder=str("Tesla Vehicle"))
except ValueError:
indigo.variable.updateValue(str(k), value=str(i))
#
# Create Metric vars
#
try:
speed = int(indigo.variables["speed"].value)
except ValueError:
speed = 0
odometer = float(indigo.variables["odometer"].value)
batteryRange = float(indigo.variables["battery_range"].value)
chargeMilesAddedIdeal = float(indigo.variables["charge_miles_added_ideal"].value)
chargeMilesAddedRated = float(indigo.variables["charge_miles_added_rated"].value)
estBatteryRange = float(indigo.variables["est_battery_range"].value)
idealBatteryRange = float(indigo.variables["ideal_battery_range"].value)
speedm = int(speed * 1.609344)
odometerm = odometer * 1.609344
batteryRangem = float(int(batteryRange * 1.609344 * 10) / 10)
chargeMilesAddedIdealm = float(int(chargeMilesAddedIdeal * 1.609344 * 10) / 10)
chargeMilesAddedRatedm = float(int(chargeMilesAddedRated * 1.609344 * 10) / 10)
estBatteryRangem = float(int(estBatteryRange * 1.609344 * 100) / 100)
idealBatteryRangem = float(int(idealBatteryRange * 1.609344 * 100) / 100)
try:
indigo.variable.create(str("speed"), value=str(speed), folder=str("Tesla Drive"))
except ValueError:
indigo.variable.updateValue(str("speed"), value=str(speed))
try:
indigo.variable.create(str("speedm"), value=str(speedm), folder=str("Tesla Drive"))
except ValueError:
indigo.variable.updateValue(str("speedm"), value=str(speedm))
try:
indigo.variable.create(str("odometerm"), value=str(odometerm), folder=str("Tesla Vehicle"))
except ValueError:
indigo.variable.updateValue(str("odometerm"), value=str(odometerm))
try:
indigo.variable.create(str("battery_rangem"), value=str(batteryRangem), folder=str("Tesla Charge"))
except ValueError:
indigo.variable.updateValue(str("battery_rangem"), value=str(batteryRangem))
try:
indigo.variable.create(str("charge_miles_added_idealm"), value=str(chargeMilesAddedIdealm), folder=str("Tesla Charge"))
except ValueError:
indigo.variable.updateValue(str("charge_miles_added_idealm"), value=str(chargeMilesAddedIdealm))
try:
indigo.variable.create(str("charge_miles_added_ratedm"), value=str(chargeMilesAddedRatedm), folder=str("Tesla Charge"))
except ValueError:
indigo.variable.updateValue(str("charge_miles_added_ratedm"), value=str(chargeMilesAddedRatedm))
try:
indigo.variable.create(str("est_battery_rangem"), value=str(estBatteryRangem), folder=str("Tesla Charge"))
except ValueError:
indigo.variable.updateValue(str("est_battery_rangem"), value=str(estBatteryRangem))
try:
indigo.variable.create(str("ideal_battery_rangem"), value=str(idealBatteryRangem), folder=str("Tesla Charge"))
except ValueError:
indigo.variable.updateValue(str("ideal_battery_rangem"), value=str(idealBatteryRangem))
#
# Calc distance from Tesla to Home and present in the owner's GUI preference.
#
lat2 = float(indigo.variables["homeLatitude"].value)
lon2 = float(indigo.variables["homeLongitude"].value)
lat1 = float(indigo.variables["latitude"].value)
lon1 = float(indigo.variables["longitude"].value)
# Calculate the great circle distance between two points
# on the earth (specified in decimal degrees)
# http://stackoverflow.com/posts/4913653/revisions
# convert decimal degrees to radians
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
# haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
if indigo.variables["gui_distance_units"].value == "mi/hr":
distFromHome = float(int(c * 3956 * 10)) / 10 # Nautical Miles to Miles
else:
distFromHome = float(int(dist * 6371 * 10)) / 10 # Nautical Miles to Kilometers
try:
indigo.variable.create(str("teslaDistanceFromHome"), value=str(distFromHome), folder=str("Tesla"))
except ValueError:
indigo.variable.updateValue(str("teslaDistanceFromHome"), value=str(distFromHome))
#
# Readable timestamp of last GPS update
#
timestamp = datetime.datetime.fromtimestamp(int(indigo.variables["gps_as_of"].value))
try:
indigo.variable.create(str("teslaLastGPSTime"), value=str(timestamp), folder=str("Tesla"))
except ValueError:
indigo.variable.updateValue(str("teslaLastGPSTime"), value=str(timestamp))
petematheson wrote:Any chance of turning this into a real plugin for Indigo?
Users browsing this forum: Google [Bot] and 0 guests