Skip to content

Commit

Permalink
Lots of scope fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Bre77 committed Feb 4, 2024
1 parent 5830431 commit 8a5cc5a
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 12 deletions.
7 changes: 6 additions & 1 deletion custom_components/teslemetry/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.exceptions import HomeAssistantError
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError

from .const import DOMAIN, MODELS, TeslemetryState
from .coordinator import (
Expand Down Expand Up @@ -46,6 +46,11 @@ def has(self, key: str | None = None):
"""Check if a key exists in the coordinator data."""
return (key or self.key) in self.coordinator.data

def raise_for_scope(self):
"""Raise an error if a scope is not available."""
if not self.scoped:
raise ServiceValidationError(f"Missing required scope: {' or '.join(self.entity_description.scopes)}")

class TeslemetryVehicleEntity(TeslemetryEntity, CoordinatorEntity[TeslemetryVehicleDataCoordinator]):
"""Parent class for Teslemetry Vehicle entities."""

Expand Down
17 changes: 13 additions & 4 deletions custom_components/teslemetry/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import DOMAIN
from .const import DOMAIN, Scopes
from .entity import (
TeslemetryVehicleEntity,
)
Expand All @@ -21,7 +21,7 @@
"Paused": MediaPlayerState.PAUSED,
"Stopped": MediaPlayerState.IDLE,
}

MAX_VOLUME = 11.0

async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
Expand All @@ -30,7 +30,7 @@ async def async_setup_entry(
data = hass.data[DOMAIN][entry.entry_id]

async_add_entities(
TeslemetryMediaEntity(vehicle) for vehicle in data.vehicles
TeslemetryMediaEntity(vehicle, Scopes.VEHICLE_CMDS in data.scopes) for vehicle in data.vehicles
)


Expand All @@ -42,9 +42,11 @@ class TeslemetryMediaEntity(TeslemetryVehicleEntity, MediaPlayerEntity):
def __init__(
self,
vehicle: TeslemetryVehicleData,
scoped: bool,
) -> None:
"""Initialize the media player entity."""
super().__init__(vehicle, "media")
self.scoped = scoped

@property
def state(self) -> MediaPlayerState:
Expand All @@ -58,7 +60,7 @@ def state(self) -> MediaPlayerState:
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", 10.333333
"vehicle_state_media_info_audio_volume_max", MAX_VOLUME
)

@property
Expand Down Expand Up @@ -100,3 +102,10 @@ def media_playlist(self) -> str | None:
def source(self) -> str | None:
"""Name of the current input source."""
return self.get("vehicle_state_media_info_now_playing_source")

async def async_set_volume_level(self, volume: float) -> None:
"""Set volume level, range 0..1."""
await 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)))

6 changes: 5 additions & 1 deletion custom_components/teslemetry/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ async def async_setup_entry(
data = hass.data[DOMAIN][entry.entry_id]

async_add_entities(
TeslemetryNumberEntity(vehicle, description)
TeslemetryNumberEntity(vehicle, description, any(scope in data.scopes for scope in description.scopes))
for vehicle in data.vehicles
for description in VEHICLE_DESCRIPTIONS
)
Expand All @@ -115,9 +115,11 @@ def __init__(
self,
vehicle: TeslemetryVehicleData,
description: TeslemetryNumberEntityDescription,
scoped: bool
) -> None:
"""Initialize the Number entity."""
super().__init__(vehicle, description.key)
self.scoped = scoped
self.entity_description = description

@property
Expand All @@ -144,5 +146,7 @@ def native_max_value(self) -> float:

async def async_set_native_value(self, value: float) -> None:
"""Set new value."""
await self.raise_for_scope()
await self.wake_up_if_asleep()
await self.entity_description.func(self.api, value)
self.set((self.key, value))
11 changes: 9 additions & 2 deletions custom_components/teslemetry/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import DOMAIN, TeslemetrySeatHeaterOptions
from .const import DOMAIN, TeslemetrySeatHeaterOptions, Scopes
from .entity import (
TeslemetryVehicleEntity,
)
Expand All @@ -30,7 +30,7 @@ async def async_setup_entry(
data = hass.data[DOMAIN][entry.entry_id]

async_add_entities(
TeslemetrySeatHeaterSelectEntity(vehicle, key)
TeslemetrySeatHeaterSelectEntity(vehicle, key, Scopes.VEHICLE_CMDS in data.scopes)
for vehicle in data.vehicles
for key in SEAT_HEATERS
)
Expand All @@ -46,6 +46,11 @@ class TeslemetrySeatHeaterSelectEntity(TeslemetryVehicleEntity, SelectEntity):
TeslemetrySeatHeaterOptions.HIGH,
]

def __init__(self, vehicle, key, scoped: bool) -> None:
"""Initialize the select."""
super().__init__(vehicle, key)
self.scoped = scoped

@property
def available(self) -> bool:
"""Return if sensor is available."""
Expand All @@ -58,6 +63,8 @@ def current_option(self) -> str | None:

async def async_select_option(self, option: str) -> None:
"""Change the selected option."""
await self.raise_for_scope()
await self.wake_up_if_asleep()
level = self._attr_options.index(option)
await self.api.remote_seat_heater_request(SEAT_HEATERS[self.key], level)
self.set((self.key, level))
8 changes: 7 additions & 1 deletion custom_components/teslemetry/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ async def async_setup_entry(

async_add_entities(
[
TeslemetrySwitchEntity(vehicle, description)
TeslemetrySwitchEntity(vehicle, description, any(scope in data.scopes for scope in description.scopes))
for vehicle in data.vehicles
for description in DESCRIPTIONS
]
Expand All @@ -97,10 +97,12 @@ def __init__(
self,
vehicle: TeslemetryVehicleData,
description: TeslemetrySwitchEntityDescription,
scoped: bool
) -> None:
"""Initialize the Switch."""
super().__init__(vehicle, description.key)
self.entity_description = description
self.scoped = scoped

@property
def available(self) -> bool:
Expand All @@ -114,10 +116,14 @@ def is_on(self) -> bool:

async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on the Switch."""
await self.raise_for_scope()
await self.wake_up_if_asleep()
await self.entity_description.on_func(self.api)
self.set((self.entity_description.key, True))

async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off the Switch."""
await self.raise_for_scope()
await self.wake_up_if_asleep()
await self.entity_description.off_func(self.api)
self.set((self.entity_description.key, False))
8 changes: 5 additions & 3 deletions custom_components/teslemetry/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async def async_setup_entry(
data = hass.data[DOMAIN][entry.entry_id]

async_add_entities(
TeslemetryUpdateEntity(vehicle, data.scopes) for vehicle in data.vehicles
TeslemetryUpdateEntity(vehicle, Scopes.VEHICLE_CMDS in data.scopes) for vehicle in data.vehicles
)


Expand All @@ -34,11 +34,11 @@ class TeslemetryUpdateEntity(TeslemetryVehicleEntity, UpdateEntity):
def __init__(
self,
vehicle: TeslemetryVehicleData,
scopes: list[Scopes],
scoped: bool,
) -> None:
"""Initialize the Update."""
super().__init__(vehicle, "update")
self.can_update = Scopes.VEHICLE_CMDS in scopes
self.scoped = scoped

@property
def available(self) -> bool:
Expand Down Expand Up @@ -88,6 +88,8 @@ async def async_install(
self, version: str | None, backup: bool, **kwargs: Any
) -> None:
"""Install an update."""
await self.raise_for_scope()
await self.wake_up_if_asleep()
await self.api.schedule_software_update(0)
self.set(
("vehicle_state_software_update_status", TeslemetryUpdateStatus.INSTALLING)
Expand Down

0 comments on commit 8a5cc5a

Please sign in to comment.