Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions packages/modules/vehicles/tesla/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,17 @@ def post_wake_up_command(vehicle: int, token: TeslaSocToken) -> str:
return response["response"]["state"]


def request_soc_range(vehicle: int, token: TeslaSocToken) -> Tuple[float, float, float]:
def request_data(vehicle: int, token: TeslaSocToken) -> Tuple[float, int, float, int]:
vehicle_id = __get_vehicle_id(vehicle, token)
data_part = f"vehicles/{vehicle_id}/vehicle_data"
response = __request_data(data_part, token)
response = json.loads(response)
soc = float(response["response"]["charge_state"]["battery_level"])
# convert miles to km
range = int(float(response["response"]["charge_state"]["battery_range"]) * 1.60934)
odometer = int(float(response["response"]["vehicle_state"]["odometer"]) * 1.60934)
soc_timestamp = float(response["response"]["charge_state"]["timestamp"]) / 1000
return soc, range, soc_timestamp
return soc, range, soc_timestamp, odometer


def validate_token(token: TeslaSocToken) -> TeslaSocToken:
Expand Down Expand Up @@ -144,7 +145,7 @@ def __refresh_token(token: TeslaSocToken) -> TeslaSocToken:
resp_json = resp.json()
token.refresh_token = resp_json["refresh_token"]
token.access_token = resp_json["access_token"]
token.created_at = time.time()
token.created_at = int(time.time())
token.expires_in = resp_json["expires_in"]
log.debug("Token Refresh succeeded")
return token
Expand Down
4 changes: 2 additions & 2 deletions packages/modules/vehicles/tesla/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def __init__(self,


class TeslaSocConfiguration:
def __init__(self, tesla_ev_num: int = 0, token: TeslaSocToken = None) -> None:
def __init__(self, tesla_ev_num: int = 0, token: Optional[TeslaSocToken] = None) -> None:
self.tesla_ev_num = tesla_ev_num
self.token = token or TeslaSocToken()

Expand All @@ -24,7 +24,7 @@ def __init__(self,
name: str = "Tesla",
type: str = "tesla",
official: bool = False,
configuration: TeslaSocConfiguration = None) -> None:
configuration: Optional[TeslaSocConfiguration] = None) -> None:
self.name = name
self.type = type
self.official = official
Expand Down
4 changes: 2 additions & 2 deletions packages/modules/vehicles/tesla/soc.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ def fetch(vehicle_config: TeslaSoc, vehicle_update_data: VehicleUpdateData) -> C
f"Fehler beim Aufwecken des Fahrzeugs: {e}\n"
"Der abgerufene SoC-Wert ist möglicherweise veraltet."
)
soc, range, soc_timestamp = api.request_soc_range(
soc, range, soc_timestamp, odometer = api.request_data(
vehicle=vehicle_config.configuration.tesla_ev_num, token=vehicle_config.configuration.token)
return CarState(soc=soc, range=range, soc_timestamp=soc_timestamp)
return CarState(soc=soc, range=range, soc_timestamp=soc_timestamp, odometer=odometer)


def _wake_up_car(vehicle_config: TeslaSoc):
Expand Down
15 changes: 10 additions & 5 deletions packages/modules/vehicles/tesla/soc_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ def set_up(self, monkeypatch):
self.mock_context_exit = Mock(return_value=True)
self.mock_validate_token = Mock(name="validate_token", return_value=self.token)
self.mock_post_wake_up_command = Mock(name="post_wake_up_command", return_value="online")
self.mock_request_soc_range = Mock(name="request_soc_range", return_value=(42.5, 438.2, 1652683252))
self.mock_request_data = Mock(name="request_data", return_value=(42.5, 438.2, 1652683252, 12345))
self.mock_value_store = Mock(name="value_store")
monkeypatch.setattr(api, "validate_token", self.mock_validate_token)
monkeypatch.setattr(api, "post_wake_up_command", self.mock_post_wake_up_command)
monkeypatch.setattr(api, "request_soc_range", self.mock_request_soc_range)
monkeypatch.setattr(api, "request_data", self.mock_request_data)
monkeypatch.setattr(store, "get_car_value_store", Mock(return_value=self.mock_value_store))
monkeypatch.setattr(SingleComponentUpdateContext, '__exit__', self.mock_context_exit)

Expand All @@ -32,10 +32,12 @@ def test_update_updates_value_store_no_chargepoint(self, monkeypatch):

# evaluation
self.assert_context_manager_called_with(None)
self.mock_request_soc_range.assert_called_once_with(vehicle=0, token=self.token)
self.mock_request_data.assert_called_once_with(vehicle=0, token=self.token)
assert self.mock_value_store.set.call_count == 1
assert self.mock_value_store.set.call_args[0][0].soc == 42.5
assert self.mock_value_store.set.call_args[0][0].range == 438.2
assert self.mock_value_store.set.call_args[0][0].soc_timestamp == 1652683252
assert self.mock_value_store.set.call_args[0][0].odometer == 12345

def test_update_updates_value_store_not_charging(self, monkeypatch):
# execution
Expand All @@ -44,15 +46,18 @@ def test_update_updates_value_store_not_charging(self, monkeypatch):

# evaluation
self.assert_context_manager_called_with(None)
self.mock_request_soc_range.assert_called_once_with(vehicle=0, token=self.token)
self.mock_request_data.assert_called_once_with(vehicle=0, token=self.token)

assert self.mock_value_store.set.call_count == 1
assert self.mock_value_store.set.call_args[0][0].soc == 42.5
assert self.mock_value_store.set.call_args[0][0].range == 438.2
assert self.mock_value_store.set.call_args[0][0].soc_timestamp == 1652683252
assert self.mock_value_store.set.call_args[0][0].odometer == 12345

def test_update_passes_errors_to_context(self, monkeypatch):
# setup
dummy_error = Exception("Der SoC kann nicht ausgelesen werden")
self.mock_request_soc_range.side_effect = dummy_error
self.mock_request_data.side_effect = dummy_error

# execution
create_vehicle(TeslaSoc(configuration=TeslaSocConfiguration(
Expand Down