diff --git a/teslajsonpy/BatterySensor.py b/teslajsonpy/BatterySensor.py index 026a98b1..383f9a25 100644 --- a/teslajsonpy/BatterySensor.py +++ b/teslajsonpy/BatterySensor.py @@ -28,3 +28,43 @@ def has_battery(): def battery_level(self): return self.__battery_level + +class Range(VehicleDevice): + def __init__(self, data, controller): + super().__init__(data, controller) + self.__battery_range = 0 + self.__est_battery_range = 0 + self.__ideal_battery_range = 0 + self.type = 'range sensor' + self.__rated = True + self.measurement = 'LENGTH_MILES' + self.hass_type = 'sensor' + self.name = self._name() + self.uniq_name = self._uniq_name() + self.bin_type = 0xA + self.update() + + def update(self): + self._controller.update(self._id) + data = self._controller.get_charging_params(self._id) + if data: + self.__battery_range = data['battery_range'] + self.__est_battery_range = data['est_battery_range'] + self.__ideal_battery_range = data['ideal_battery_range'] + data = self._controller.get_gui_params(self._id) + if data: + if data['gui_distance_units'] == "mi/hr": + self.measurement = 'LENGTH_MILES' + else: #"km/hr" + self.measurement = 'LENGTH_KILOMETERS' + self.__rated = (data['gui_range_display'] == "Rated") + + @staticmethod + def has_battery(): + return False + + def range_level(self): + if self.__rated: + return self.__battery_range + else: + return self.__ideal_battery_range diff --git a/teslajsonpy/Charger.py b/teslajsonpy/Charger.py index d1f71c90..603e661d 100644 --- a/teslajsonpy/Charger.py +++ b/teslajsonpy/Charger.py @@ -43,3 +43,42 @@ def is_charging(self): @staticmethod def has_battery(): return False + +class RangeSwitch(VehicleDevice): + def __init__(self, data, controller): + super().__init__(data, controller) + self.__manual_update_time = 0 + self.__maxrange_state = False + self.type = 'maxrange switch' + self.hass_type = 'switch' + self.name = self._name() + self.uniq_name = self._uniq_name() + self.bin_type = 0x9 + self.update() + + def update(self): + self._controller.update(self._id) + data = self._controller.get_charging_params(self._id) + if data and (time.time() - self.__manual_update_time > 60): + self.__maxrange_state = data['charge_to_max_range'] + + def set_max(self): + if not self.__maxrange_state: + data = self._controller.command(self._id, 'charge_max_range') + if data['response']['result']: + self.__maxrange_state = True + self.__manual_update_time = time.time() + + def set_standard(self): + if self.__maxrange_state: + data = self._controller.command(self._id, 'charge_standard') + if data and data['response']['result']: + self.__maxrange_state = False + self.__manual_update_time = time.time() + + def is_maxrange(self): + return self.__maxrange_state + + @staticmethod + def has_battery(): + return False diff --git a/teslajsonpy/GPS.py b/teslajsonpy/GPS.py index 258079b6..82b9e2bf 100644 --- a/teslajsonpy/GPS.py +++ b/teslajsonpy/GPS.py @@ -38,3 +38,35 @@ def update(self): @staticmethod def has_battery(): return False + +class Odometer(VehicleDevice): + def __init__(self, data, controller): + super().__init__(data, controller) + self.__odometer = 0 + self.type = 'mileage sensor' + self.measurement = 'LENGTH_MILES' + self.hass_type = 'sensor' + self.name = self._name() + self.uniq_name = self._uniq_name() + self.bin_type = 0xB + self.update() + + def update(self): + self._controller.update(self._id) + data = self._controller.get_state_params(self._id) + if data: + self.__odometer = data['odometer'] + data = self._controller.get_gui_params(self._id) + if data: + if data['gui_distance_units'] == "mi/hr": + self.measurement = 'LENGTH_MILES' + else: #"km/hr" + self.measurement = 'LENGTH_KILOMETERS' + self.__rated = (data['gui_range_display'] == "Rated") + + @staticmethod + def has_battery(): + return False + + def mileage(self): + return self.__odometer diff --git a/teslajsonpy/__init__.py b/teslajsonpy/__init__.py index 440695e7..24a1e719 100644 --- a/teslajsonpy/__init__.py +++ b/teslajsonpy/__init__.py @@ -1,9 +1,9 @@ -from teslajsonpy.BatterySensor import Battery +from teslajsonpy.BatterySensor import (Battery, Range) from teslajsonpy.BinarySensor import (ChargerConnectionSensor, ParkingSensor) -from teslajsonpy.Charger import ChargerSwitch +from teslajsonpy.Charger import (ChargerSwitch, RangeSwitch) from teslajsonpy.Climate import (Climate, TempSensor) from teslajsonpy.controller import Controller from teslajsonpy.Exceptions import TeslaException -from teslajsonpy.GPS import GPS +from teslajsonpy.GPS import GPS, Odometer from teslajsonpy.Lock import Lock diff --git a/teslajsonpy/controller.py b/teslajsonpy/controller.py index 4ad3fd94..d81447f3 100644 --- a/teslajsonpy/controller.py +++ b/teslajsonpy/controller.py @@ -1,12 +1,12 @@ import time from multiprocessing import RLock from teslajsonpy.connection import Connection -from teslajsonpy.BatterySensor import Battery +from teslajsonpy.BatterySensor import Battery, Range from teslajsonpy.Lock import Lock from teslajsonpy.Climate import Climate, TempSensor from teslajsonpy.BinarySensor import ParkingSensor, ChargerConnectionSensor -from teslajsonpy.Charger import ChargerSwitch -from teslajsonpy.GPS import GPS +from teslajsonpy.Charger import ChargerSwitch, RangeSwitch +from teslajsonpy.GPS import GPS, Odometer class Controller: @@ -18,6 +18,7 @@ def __init__(self, email, password, update_interval): self.__charging = {} self.__state = {} self.__driving = {} + self.__gui = {} self.__last_update_time = {} self.__lock = RLock() cars = self.__connection.get('vehicles')['response'] @@ -26,12 +27,15 @@ def __init__(self, email, password, update_interval): self.update(car['id']) self.__vehicles.append(Climate(car, self)) self.__vehicles.append(Battery(car, self)) + self.__vehicles.append(Range(car, self)) self.__vehicles.append(TempSensor(car, self)) self.__vehicles.append(Lock(car, self)) self.__vehicles.append(ChargerConnectionSensor(car, self)) self.__vehicles.append(ChargerSwitch(car, self)) + self.__vehicles.append(RangeSwitch(car, self)) self.__vehicles.append(ParkingSensor(car, self)) self.__vehicles.append(GPS(car, self)) + self.__vehicles.append(Odometer(car, self)) def post(self, vehicle_id, command, data={}): return self.__connection.post('vehicles/%i/%s' % (vehicle_id, command), data) @@ -62,12 +66,14 @@ def update(self, car_id): self.__charging[car_id] = data['response']['charge_state'] self.__state[car_id] = data['response']['vehicle_state'] self.__driving[car_id] = data['response']['drive_state'] + self.__gui[car_id] = data['response']['gui_settings'] self.__last_update_time[car_id] = time.time() else: self.__climate[car_id] = False self.__charging[car_id] = False self.__state[car_id] = False self.__driving[car_id] = False + self.__gui[car_id] = False def get_climate_params(self, car_id): return self.__climate[car_id] @@ -80,3 +86,6 @@ def get_state_params(self, car_id): def get_drive_params(self, car_id): return self.__driving[car_id] + + def get_gui_params(self, car_id): + return self.__gui[car_id]