Skip to content

Commit

Permalink
Heaps more wake and scope fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Bre77 committed Feb 4, 2024
1 parent 869fb40 commit b7b5bb1
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 60 deletions.
1 change: 1 addition & 0 deletions custom_components/teslemetry/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,5 @@ def __init__(

async def async_press(self) -> None:
"""Press the button."""
await self.wake_up_if_asleep()
await self.entity_description.func(self.api)
42 changes: 21 additions & 21 deletions custom_components/teslemetry/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ async def async_setup_entry(
data = hass.data[DOMAIN][entry.entry_id]

async_add_entities(
TeslemetryClimateEntity(vehicle, TeslemetryClimateSide.DRIVER, data.scopes)
TeslemetryClimateEntity(vehicle, TeslemetryClimateSide.DRIVER, Scopes.VEHICLE_CMDS in data.scopes)
for vehicle in data.vehicles
)

Expand All @@ -48,13 +48,13 @@ def __init__(
self,
vehicle: TeslemetryVehicleData,
side: TeslemetryClimateSide,
scopes: Scopes,
scoped: bool,
) -> None:
"""Initialize the climate."""
super().__init__(vehicle, side)
self.scoped = scoped

# Require VEHICLE_CMDS to make changes
if Scopes.VEHICLE_CMDS not in scopes:
if not scoped:
self._attr_supported_features = ClimateEntityFeature(0)

@property
Expand Down Expand Up @@ -91,16 +91,16 @@ def preset_mode(self) -> str | None:

async def async_turn_on(self) -> None:
"""Set the climate state to on."""
with handle_command():
await self.wake_up_if_asleep()
await self.api.auto_conditioning_start()
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.auto_conditioning_start()
self.set(("climate_state_is_climate_on", True))

async def async_turn_off(self) -> None:
"""Set the climate state to off."""
with handle_command():
await self.wake_up_if_asleep()
await self.api.auto_conditioning_stop()
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.auto_conditioning_stop()
self.set(
("climate_state_is_climate_on", False),
("climate_state_climate_keeper_mode", "off"),
Expand All @@ -109,12 +109,12 @@ async def async_turn_off(self) -> None:
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set the climate temperature."""
temp = kwargs[ATTR_TEMPERATURE]
with handle_command():
await self.wake_up_if_asleep()
await self.api.set_temps(
driver_temp=temp,
passenger_temp=temp,
)
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.set_temps(
driver_temp=temp,
passenger_temp=temp,
)

self.set((f"climate_state_{self.key}_setting", temp))

Expand All @@ -127,11 +127,11 @@ async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:

async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set the climate preset mode."""
with handle_command():
await self.wake_up_if_asleep()
await self.api.set_climate_keeper_mode(
climate_keeper_mode=self._attr_preset_modes.index(preset_mode)
)
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.set_climate_keeper_mode(
climate_keeper_mode=self._attr_preset_modes.index(preset_mode)
)
self.set(
(
"climate_state_climate_keeper_mode",
Expand Down
56 changes: 36 additions & 20 deletions custom_components/teslemetry/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ async def async_setup_entry(
data = hass.data[DOMAIN][entry.entry_id]

async_add_entities(
klass(vehicle, data.scopes)
for klass in (
TeslemetryWindowEntity,
TeslemetryChargePortEntity,
TeslemetryFrontTrunkEntity,
TeslemetryRearTrunkEntity,
klass(vehicle, any(scope in data.scopes for scope in scopes))
for (klass, scopes) in (
(TeslemetryWindowEntity, [Scopes.VEHICLE_CMDS]),
(
TeslemetryChargePortEntity,
[Scopes.VEHICLE_CMDS, Scopes.VEHICLE_CHARGING_CMDS],
),
(TeslemetryFrontTrunkEntity, [Scopes.VEHICLE_CMDS]),
(TeslemetryRearTrunkEntity, [Scopes.VEHICLE_CMDS]),
)
for vehicle in data.vehicles
)
Expand All @@ -43,10 +46,11 @@ class TeslemetryWindowEntity(TeslemetryVehicleEntity, CoverEntity):
_attr_device_class = CoverDeviceClass.WINDOW
_attr_supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE

def __init__(self, vehicle: TeslemetryVehicleData, scopes: list[Scopes]) -> None:
def __init__(self, vehicle: TeslemetryVehicleData, scoped) -> None:
"""Initialize the sensor."""
super().__init__(vehicle, "windows")
if Scopes.VEHICLE_CMDS not in scopes:
self.scoped = scoped
if not scoped:
self._attr_supported_features = CoverEntityFeature(0)

@property
Expand All @@ -60,7 +64,9 @@ def is_closed(self) -> bool | None:
)

async def async_open_cover(self, **kwargs: Any) -> None:
"""Open windows."""
"""Vent windows."""
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.window_control(command=WindowCommands.VENT)
self.set(
("vehicle_state_fd_window", TeslemetryCoverStates.OPEN),
Expand All @@ -71,6 +77,8 @@ async def async_open_cover(self, **kwargs: Any) -> None:

async def async_close_cover(self, **kwargs: Any) -> None:
"""Close windows."""
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.window_control(command=WindowCommands.CLOSE)
self.set(
("vehicle_state_fd_window", TeslemetryCoverStates.CLOSED),
Expand All @@ -86,12 +94,11 @@ class TeslemetryChargePortEntity(TeslemetryVehicleEntity, CoverEntity):
_attr_device_class = CoverDeviceClass.DOOR
_attr_supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE

def __init__(self, vehicle: TeslemetryVehicleData, scopes: list[Scopes]) -> None:
def __init__(self, vehicle: TeslemetryVehicleData, scoped) -> None:
"""Initialize the sensor."""
super().__init__(vehicle, "charge_state_charge_port_door_open")

# Require VEHICLE_CMDS to make changes
if Scopes.VEHICLE_CMDS not in scopes:
self.scoped = scoped
if not scoped:
self._attr_supported_features = CoverEntityFeature(0)

@property
Expand All @@ -101,11 +108,15 @@ def is_closed(self) -> bool | None:

async def async_open_cover(self, **kwargs: Any) -> None:
"""Open windows."""
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.charge_port_door_open()
self.set((self.key, True))

async def async_close_cover(self, **kwargs: Any) -> None:
"""Close windows."""
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.charge_port_door_close()
self.set((self.key, False))

Expand All @@ -116,12 +127,12 @@ class TeslemetryFrontTrunkEntity(TeslemetryVehicleEntity, CoverEntity):
_attr_device_class = CoverDeviceClass.DOOR
_attr_supported_features = CoverEntityFeature.OPEN

def __init__(self, vehicle: TeslemetryVehicleData, scopes: list[Scopes]) -> None:
def __init__(self, vehicle: TeslemetryVehicleData, scoped) -> None:
"""Initialize the sensor."""
super().__init__(vehicle, "vehicle_state_ft")

# Require VEHICLE_CMDS to make changes
if Scopes.VEHICLE_CMDS not in scopes:
self.scoped = scoped
if not scoped:
self._attr_supported_features = CoverEntityFeature(0)

@property
Expand All @@ -131,6 +142,8 @@ def is_closed(self) -> bool | None:

async def async_open_cover(self, **kwargs: Any) -> None:
"""Open front trunk."""
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.actuate_trunk(which_trunk=Trunks.FRONT)
self.set((self.key, TeslemetryCoverStates.OPEN))

Expand All @@ -141,12 +154,11 @@ class TeslemetryRearTrunkEntity(TeslemetryVehicleEntity, CoverEntity):
_attr_device_class = CoverDeviceClass.DOOR
_attr_supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE

def __init__(self, vehicle: TeslemetryVehicleData, scopes: list[Scopes]) -> None:
def __init__(self, vehicle: TeslemetryVehicleData, scoped) -> None:
"""Initialize the sensor."""
super().__init__(vehicle, "vehicle_state_rt")

# Require VEHICLE_CMDS to make changes
if Scopes.VEHICLE_CMDS not in scopes:
self.scoped = scoped
if not scoped:
self._attr_supported_features = CoverEntityFeature(0)

@property
Expand All @@ -157,11 +169,15 @@ def is_closed(self) -> bool | None:
async def async_open_cover(self, **kwargs: Any) -> None:
"""Open rear trunk."""
if self.get() == TeslemetryCoverStates.CLOSED:
self.raise_for_scope()
await self.wake_up_if_asleep()
self.api.actuate_trunk(Trunks.REAR)
self.set((self.key, TeslemetryCoverStates.OPEN))

async def async_close_cover(self, **kwargs: Any) -> None:
"""Close rear trunk."""
if self.get() == TeslemetryCoverStates.OPEN:
self.raise_for_scope()
await self.wake_up_if_asleep()
self.api.actuate_trunk(Trunks.REAR)
self.set((self.key, TeslemetryCoverStates.CLOSED))
20 changes: 14 additions & 6 deletions custom_components/teslemetry/lock.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Lock platform for Teslemetry integration."""
from __future__ import annotations

from tesla_fleet_api.const import Scopes
from typing import Any

from homeassistant.components.lock import LockEntity
Expand All @@ -24,20 +24,22 @@ async def async_setup_entry(

async_add_entities(
klass(vehicle)
for klass in (TeslemetryLockEntity, TeslemetryCableLockEntity)
for klass in (
TeslemetryLockEntity,
TeslemetryCableLockEntity,
Scopes.VEHICLE_CMDS in data.scopes,
)
for vehicle in data.vehicles
)


class TeslemetryLockEntity(TeslemetryVehicleEntity, LockEntity):
"""Lock entity for Teslemetry."""

def __init__(
self,
vehicle: TeslemetryVehicleData,
) -> None:
def __init__(self, vehicle: TeslemetryVehicleData, scoped: bool) -> None:
"""Initialize the sensor."""
super().__init__(vehicle, "vehicle_state_locked")
self.scoped = scoped

@property
def is_locked(self) -> bool | None:
Expand All @@ -46,11 +48,15 @@ def is_locked(self) -> bool | None:

async def async_lock(self, **kwargs: Any) -> None:
"""Lock the doors."""
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.door_lock()
self.set((self.key, True))

async def async_unlock(self, **kwargs: Any) -> None:
"""Unlock the doors."""
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.door_unlock()
self.set((self.key, False))

Expand Down Expand Up @@ -80,5 +86,7 @@ async def async_lock(self, **kwargs: Any) -> None:

async def async_unlock(self, **kwargs: Any) -> None:
"""Unlock charge cable lock."""
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.charge_port_door_open()
self.set((self.key, TeslemetryChargeCableLockStates.DISENGAGED))
56 changes: 45 additions & 11 deletions custom_components/teslemetry/media_player.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Media Player platform for Teslemetry integration."""
from __future__ import annotations
from tesla_fleet_api.const import Scopes

from homeassistant.components.media_player import (
MediaPlayerDeviceClass,
Expand All @@ -11,7 +12,7 @@
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import DOMAIN, Scopes
from .const import DOMAIN
from .entity import (
TeslemetryVehicleEntity,
)
Expand Down Expand Up @@ -58,7 +59,12 @@ def __init__(
super().__init__(vehicle, "media")
self.scoped = scoped
if not scoped:
_attr_supported_features = MediaPlayerEntityFeature(0)
self._attr_supported_features = MediaPlayerEntityFeature(0)

@property
def max_volume(self) -> float:
"""Return the maximum volume level."""
return self.get("vehicle_state_media_info_audio_volume_max", MAX_VOLUME)

@property
def state(self) -> MediaPlayerState:
Expand All @@ -68,12 +74,19 @@ def state(self) -> MediaPlayerState:
MediaPlayerState.OFF,
)

@property
def volume_step(self) -> float:
"""Volume step size."""
return (
1.0
/ self.max_volume
/ self.get("vehicle_state_media_info_audio_volume_increment", 1.0 / 3)
)

@property
def volume_level(self) -> float:
"""Volume level of the media player (0..1)."""
return self.get("vehicle_state_media_info_audio_volume", 0) / self.get(
"vehicle_state_media_info_audio_volume_max", MAX_VOLUME
)
return self.get("vehicle_state_media_info_audio_volume", 0) / self.max_volume

@property
def media_duration(self) -> int | None:
Expand Down Expand Up @@ -119,9 +132,30 @@ async def async_set_volume_level(self, volume: float) -> None:
"""Set volume level, range 0..1."""
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.adjust_volume(
int(
volume
* self.get("vehicle_state_media_info_audio_volume_max", MAX_VOLUME)
)
)
await self.api.adjust_volume(int(volume * self.max_volume))

async def async_media_play(self) -> None:
"""Send play command."""
if self.state != MediaPlayerState.PLAYING:
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.media_toggle_playback()

async def async_media_pause(self) -> None:
"""Send pause command."""
if self.state == MediaPlayerState.PLAYING:
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.media_toggle_playback()

async def async_media_next_track(self) -> None:
"""Send next track command."""
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.media_next_track()

async def async_media_previous_track(self) -> None:
"""Send previous track command."""
self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.media_previous_track()
Loading

0 comments on commit b7b5bb1

Please sign in to comment.