mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 00:37:53 +00:00
Refactor helpers and bump Teslemetry (#119246)
This commit is contained in:
parent
04c8a5574a
commit
4a9ebd9af1
@ -102,6 +102,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: TeslemetryConfigEntry) -
|
||||
manufacturer="Tesla",
|
||||
configuration_url="https://teslemetry.com/console",
|
||||
name=product.get("site_name", "Energy Site"),
|
||||
serial_number=str(site_id),
|
||||
)
|
||||
|
||||
energysites.append(
|
||||
|
@ -14,6 +14,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import TeslemetryConfigEntry
|
||||
from .entity import TeslemetryVehicleEntity
|
||||
from .helpers import handle_vehicle_command
|
||||
from .models import TeslemetryVehicleData
|
||||
|
||||
|
||||
@ -84,4 +85,4 @@ class TeslemetryButtonEntity(TeslemetryVehicleEntity, ButtonEntity):
|
||||
"""Press the button."""
|
||||
await self.wake_up_if_asleep()
|
||||
if self.entity_description.func:
|
||||
await self.handle_command(self.entity_description.func(self))
|
||||
await handle_vehicle_command(self.entity_description.func(self))
|
||||
|
@ -26,6 +26,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from . import TeslemetryConfigEntry
|
||||
from .const import DOMAIN, TeslemetryClimateSide
|
||||
from .entity import TeslemetryVehicleEntity
|
||||
from .helpers import handle_vehicle_command
|
||||
from .models import TeslemetryVehicleData
|
||||
|
||||
DEFAULT_MIN_TEMP = 15
|
||||
@ -114,7 +115,7 @@ class TeslemetryClimateEntity(TeslemetryVehicleEntity, ClimateEntity):
|
||||
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.auto_conditioning_start())
|
||||
await handle_vehicle_command(self.api.auto_conditioning_start())
|
||||
|
||||
self._attr_hvac_mode = HVACMode.HEAT_COOL
|
||||
self.async_write_ha_state()
|
||||
@ -124,7 +125,7 @@ class TeslemetryClimateEntity(TeslemetryVehicleEntity, ClimateEntity):
|
||||
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.auto_conditioning_stop())
|
||||
await handle_vehicle_command(self.api.auto_conditioning_stop())
|
||||
|
||||
self._attr_hvac_mode = HVACMode.OFF
|
||||
self._attr_preset_mode = self._attr_preset_modes[0]
|
||||
@ -135,7 +136,7 @@ class TeslemetryClimateEntity(TeslemetryVehicleEntity, ClimateEntity):
|
||||
|
||||
if temp := kwargs.get(ATTR_TEMPERATURE):
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(
|
||||
await handle_vehicle_command(
|
||||
self.api.set_temps(
|
||||
driver_temp=temp,
|
||||
passenger_temp=temp,
|
||||
@ -159,7 +160,7 @@ class TeslemetryClimateEntity(TeslemetryVehicleEntity, ClimateEntity):
|
||||
async def async_set_preset_mode(self, preset_mode: str) -> None:
|
||||
"""Set the climate preset mode."""
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(
|
||||
await handle_vehicle_command(
|
||||
self.api.set_climate_keeper_mode(
|
||||
climate_keeper_mode=self._attr_preset_modes.index(preset_mode)
|
||||
)
|
||||
@ -261,7 +262,7 @@ class TeslemetryCabinOverheatProtectionEntity(TeslemetryVehicleEntity, ClimateEn
|
||||
)
|
||||
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.set_cop_temp(cop_mode))
|
||||
await handle_vehicle_command(self.api.set_cop_temp(cop_mode))
|
||||
self._attr_target_temperature = temp
|
||||
|
||||
if mode := kwargs.get(ATTR_HVAC_MODE):
|
||||
@ -271,15 +272,15 @@ class TeslemetryCabinOverheatProtectionEntity(TeslemetryVehicleEntity, ClimateEn
|
||||
|
||||
async def _async_set_cop(self, hvac_mode: HVACMode) -> None:
|
||||
if hvac_mode == HVACMode.OFF:
|
||||
await self.handle_command(
|
||||
await handle_vehicle_command(
|
||||
self.api.set_cabin_overheat_protection(on=False, fan_only=False)
|
||||
)
|
||||
elif hvac_mode == HVACMode.COOL:
|
||||
await self.handle_command(
|
||||
await handle_vehicle_command(
|
||||
self.api.set_cabin_overheat_protection(on=True, fan_only=False)
|
||||
)
|
||||
elif hvac_mode == HVACMode.FAN_ONLY:
|
||||
await self.handle_command(
|
||||
await handle_vehicle_command(
|
||||
self.api.set_cabin_overheat_protection(on=True, fan_only=True)
|
||||
)
|
||||
|
||||
|
@ -17,6 +17,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import TeslemetryConfigEntry
|
||||
from .entity import TeslemetryVehicleEntity
|
||||
from .helpers import handle_vehicle_command
|
||||
from .models import TeslemetryVehicleData
|
||||
|
||||
OPEN = 1
|
||||
@ -88,7 +89,9 @@ class TeslemetryWindowEntity(TeslemetryVehicleEntity, CoverEntity):
|
||||
"""Vent windows."""
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.window_control(command=WindowCommand.VENT))
|
||||
await handle_vehicle_command(
|
||||
self.api.window_control(command=WindowCommand.VENT)
|
||||
)
|
||||
self._attr_is_closed = False
|
||||
self.async_write_ha_state()
|
||||
|
||||
@ -96,7 +99,9 @@ class TeslemetryWindowEntity(TeslemetryVehicleEntity, CoverEntity):
|
||||
"""Close windows."""
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.window_control(command=WindowCommand.CLOSE))
|
||||
await handle_vehicle_command(
|
||||
self.api.window_control(command=WindowCommand.CLOSE)
|
||||
)
|
||||
self._attr_is_closed = True
|
||||
self.async_write_ha_state()
|
||||
|
||||
@ -127,7 +132,7 @@ class TeslemetryChargePortEntity(TeslemetryVehicleEntity, CoverEntity):
|
||||
"""Open charge port."""
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.charge_port_door_open())
|
||||
await handle_vehicle_command(self.api.charge_port_door_open())
|
||||
self._attr_is_closed = False
|
||||
self.async_write_ha_state()
|
||||
|
||||
@ -135,7 +140,7 @@ class TeslemetryChargePortEntity(TeslemetryVehicleEntity, CoverEntity):
|
||||
"""Close charge port."""
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.charge_port_door_close())
|
||||
await handle_vehicle_command(self.api.charge_port_door_close())
|
||||
self._attr_is_closed = True
|
||||
self.async_write_ha_state()
|
||||
|
||||
@ -162,7 +167,7 @@ class TeslemetryFrontTrunkEntity(TeslemetryVehicleEntity, CoverEntity):
|
||||
"""Open front trunk."""
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.actuate_trunk(Trunk.FRONT))
|
||||
await handle_vehicle_command(self.api.actuate_trunk(Trunk.FRONT))
|
||||
self._attr_is_closed = False
|
||||
self.async_write_ha_state()
|
||||
|
||||
@ -198,7 +203,7 @@ class TeslemetryRearTrunkEntity(TeslemetryVehicleEntity, CoverEntity):
|
||||
if self.is_closed is not False:
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.actuate_trunk(Trunk.REAR))
|
||||
await handle_vehicle_command(self.api.actuate_trunk(Trunk.REAR))
|
||||
self._attr_is_closed = False
|
||||
self.async_write_ha_state()
|
||||
|
||||
@ -207,6 +212,6 @@ class TeslemetryRearTrunkEntity(TeslemetryVehicleEntity, CoverEntity):
|
||||
if self.is_closed is not True:
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.actuate_trunk(Trunk.REAR))
|
||||
await handle_vehicle_command(self.api.actuate_trunk(Trunk.REAR))
|
||||
self._attr_is_closed = True
|
||||
self.async_write_ha_state()
|
||||
|
@ -1,22 +1,21 @@
|
||||
"""Teslemetry parent entity class."""
|
||||
|
||||
from abc import abstractmethod
|
||||
import asyncio
|
||||
from typing import Any
|
||||
|
||||
from tesla_fleet_api import EnergySpecific, VehicleSpecific
|
||||
from tesla_fleet_api.exceptions import TeslaFleetError
|
||||
|
||||
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
||||
from homeassistant.exceptions import ServiceValidationError
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .const import DOMAIN, LOGGER, TeslemetryState
|
||||
from .const import DOMAIN
|
||||
from .coordinator import (
|
||||
TeslemetryEnergySiteInfoCoordinator,
|
||||
TeslemetryEnergySiteLiveCoordinator,
|
||||
TeslemetryVehicleDataCoordinator,
|
||||
)
|
||||
from .helpers import wake_up_vehicle
|
||||
from .models import TeslemetryEnergyData, TeslemetryVehicleData
|
||||
|
||||
|
||||
@ -76,15 +75,6 @@ class TeslemetryEntity(
|
||||
"""Return True if a specific value is in coordinator data."""
|
||||
return self.key in self.coordinator.data
|
||||
|
||||
async def handle_command(self, command) -> dict[str, Any]:
|
||||
"""Handle a command."""
|
||||
try:
|
||||
result = await command
|
||||
except TeslaFleetError as e:
|
||||
raise HomeAssistantError(f"Teslemetry command failed, {e.message}") from e
|
||||
LOGGER.debug("Command result: %s", result)
|
||||
return result
|
||||
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle updated data from the coordinator."""
|
||||
self._async_update_attrs()
|
||||
@ -113,7 +103,7 @@ class TeslemetryVehicleEntity(TeslemetryEntity):
|
||||
"""Initialize common aspects of a Teslemetry entity."""
|
||||
|
||||
self._attr_unique_id = f"{data.vin}-{key}"
|
||||
self._wakelock = data.wakelock
|
||||
self.vehicle = data
|
||||
|
||||
self._attr_device_info = data.device
|
||||
super().__init__(data.coordinator, data.api, key)
|
||||
@ -125,44 +115,7 @@ class TeslemetryVehicleEntity(TeslemetryEntity):
|
||||
|
||||
async def wake_up_if_asleep(self) -> None:
|
||||
"""Wake up the vehicle if its asleep."""
|
||||
async with self._wakelock:
|
||||
times = 0
|
||||
while self.coordinator.data["state"] != TeslemetryState.ONLINE:
|
||||
try:
|
||||
if times == 0:
|
||||
cmd = await self.api.wake_up()
|
||||
else:
|
||||
cmd = await self.api.vehicle()
|
||||
state = cmd["response"]["state"]
|
||||
except TeslaFleetError as e:
|
||||
raise HomeAssistantError(str(e)) from e
|
||||
self.coordinator.data["state"] = state
|
||||
if state != TeslemetryState.ONLINE:
|
||||
times += 1
|
||||
if times >= 4: # Give up after 30 seconds total
|
||||
raise HomeAssistantError("Could not wake up vehicle")
|
||||
await asyncio.sleep(times * 5)
|
||||
|
||||
async def handle_command(self, command) -> dict[str, Any]:
|
||||
"""Handle a vehicle command."""
|
||||
result = await super().handle_command(command)
|
||||
if (response := result.get("response")) is None:
|
||||
if error := result.get("error"):
|
||||
# No response with error
|
||||
raise HomeAssistantError(error)
|
||||
# No response without error (unexpected)
|
||||
raise HomeAssistantError(f"Unknown response: {response}")
|
||||
if (result := response.get("result")) is not True:
|
||||
if reason := response.get("reason"):
|
||||
if reason in ("already_set", "not_charging", "requested"):
|
||||
# Reason is acceptable
|
||||
return result
|
||||
# Result of false with reason
|
||||
raise HomeAssistantError(reason)
|
||||
# Result of false without reason (unexpected)
|
||||
raise HomeAssistantError("Command failed with no reason")
|
||||
# Response with result of true
|
||||
return result
|
||||
await wake_up_vehicle(self.vehicle)
|
||||
|
||||
|
||||
class TeslemetryEnergyLiveEntity(TeslemetryEntity):
|
||||
|
63
homeassistant/components/teslemetry/helpers.py
Normal file
63
homeassistant/components/teslemetry/helpers.py
Normal file
@ -0,0 +1,63 @@
|
||||
"""Teslemetry helper functions."""
|
||||
|
||||
import asyncio
|
||||
from typing import Any
|
||||
|
||||
from tesla_fleet_api.exceptions import TeslaFleetError
|
||||
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
||||
from .const import LOGGER, TeslemetryState
|
||||
|
||||
|
||||
async def wake_up_vehicle(vehicle) -> None:
|
||||
"""Wake up a vehicle."""
|
||||
async with vehicle.wakelock:
|
||||
times = 0
|
||||
while vehicle.coordinator.data["state"] != TeslemetryState.ONLINE:
|
||||
try:
|
||||
if times == 0:
|
||||
cmd = await vehicle.api.wake_up()
|
||||
else:
|
||||
cmd = await vehicle.api.vehicle()
|
||||
state = cmd["response"]["state"]
|
||||
except TeslaFleetError as e:
|
||||
raise HomeAssistantError(str(e)) from e
|
||||
vehicle.coordinator.data["state"] = state
|
||||
if state != TeslemetryState.ONLINE:
|
||||
times += 1
|
||||
if times >= 4: # Give up after 30 seconds total
|
||||
raise HomeAssistantError("Could not wake up vehicle")
|
||||
await asyncio.sleep(times * 5)
|
||||
|
||||
|
||||
async def handle_command(command) -> dict[str, Any]:
|
||||
"""Handle a command."""
|
||||
try:
|
||||
result = await command
|
||||
except TeslaFleetError as e:
|
||||
raise HomeAssistantError(f"Teslemetry command failed, {e.message}") from e
|
||||
LOGGER.debug("Command result: %s", result)
|
||||
return result
|
||||
|
||||
|
||||
async def handle_vehicle_command(command) -> dict[str, Any]:
|
||||
"""Handle a vehicle command."""
|
||||
result = await handle_command(command)
|
||||
if (response := result.get("response")) is None:
|
||||
if error := result.get("error"):
|
||||
# No response with error
|
||||
raise HomeAssistantError(error)
|
||||
# No response without error (unexpected)
|
||||
raise HomeAssistantError(f"Unknown response: {response}")
|
||||
if (result := response.get("result")) is not True:
|
||||
if reason := response.get("reason"):
|
||||
if reason in ("already_set", "not_charging", "requested"):
|
||||
# Reason is acceptable
|
||||
return result
|
||||
# Result of false with reason
|
||||
raise HomeAssistantError(reason)
|
||||
# Result of false without reason (unexpected)
|
||||
raise HomeAssistantError("Command failed with no reason")
|
||||
# Response with result of true
|
||||
return result
|
@ -14,6 +14,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from . import TeslemetryConfigEntry
|
||||
from .const import DOMAIN
|
||||
from .entity import TeslemetryVehicleEntity
|
||||
from .helpers import handle_vehicle_command
|
||||
from .models import TeslemetryVehicleData
|
||||
|
||||
ENGAGED = "Engaged"
|
||||
@ -52,7 +53,7 @@ class TeslemetryVehicleLockEntity(TeslemetryVehicleEntity, LockEntity):
|
||||
"""Lock the doors."""
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.door_lock())
|
||||
await handle_vehicle_command(self.api.door_lock())
|
||||
self._attr_is_locked = True
|
||||
self.async_write_ha_state()
|
||||
|
||||
@ -60,7 +61,7 @@ class TeslemetryVehicleLockEntity(TeslemetryVehicleEntity, LockEntity):
|
||||
"""Unlock the doors."""
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.door_unlock())
|
||||
await handle_vehicle_command(self.api.door_unlock())
|
||||
self._attr_is_locked = False
|
||||
self.async_write_ha_state()
|
||||
|
||||
@ -95,6 +96,6 @@ class TeslemetryCableLockEntity(TeslemetryVehicleEntity, LockEntity):
|
||||
"""Unlock charge cable lock."""
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.charge_port_door_open())
|
||||
await handle_vehicle_command(self.api.charge_port_door_open())
|
||||
self._attr_is_locked = False
|
||||
self.async_write_ha_state()
|
||||
|
@ -6,5 +6,5 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/teslemetry",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["tesla-fleet-api"],
|
||||
"requirements": ["tesla-fleet-api==0.5.12"]
|
||||
"requirements": ["tesla-fleet-api==0.6.1"]
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import TeslemetryConfigEntry
|
||||
from .entity import TeslemetryVehicleEntity
|
||||
from .helpers import handle_vehicle_command
|
||||
from .models import TeslemetryVehicleData
|
||||
|
||||
STATES = {
|
||||
@ -114,7 +115,7 @@ class TeslemetryMediaEntity(TeslemetryVehicleEntity, MediaPlayerEntity):
|
||||
"""Set volume level, range 0..1."""
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(
|
||||
await handle_vehicle_command(
|
||||
self.api.adjust_volume(int(volume * self._volume_max))
|
||||
)
|
||||
self._attr_volume_level = volume
|
||||
@ -125,7 +126,7 @@ class TeslemetryMediaEntity(TeslemetryVehicleEntity, MediaPlayerEntity):
|
||||
if self.state != MediaPlayerState.PLAYING:
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.media_toggle_playback())
|
||||
await handle_vehicle_command(self.api.media_toggle_playback())
|
||||
self._attr_state = MediaPlayerState.PLAYING
|
||||
self.async_write_ha_state()
|
||||
|
||||
@ -134,7 +135,7 @@ class TeslemetryMediaEntity(TeslemetryVehicleEntity, MediaPlayerEntity):
|
||||
if self.state == MediaPlayerState.PLAYING:
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.media_toggle_playback())
|
||||
await handle_vehicle_command(self.api.media_toggle_playback())
|
||||
self._attr_state = MediaPlayerState.PAUSED
|
||||
self.async_write_ha_state()
|
||||
|
||||
@ -142,10 +143,10 @@ class TeslemetryMediaEntity(TeslemetryVehicleEntity, MediaPlayerEntity):
|
||||
"""Send next track command."""
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.media_next_track())
|
||||
await handle_vehicle_command(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.handle_command(self.api.media_prev_track())
|
||||
await handle_vehicle_command(self.api.media_prev_track())
|
||||
|
@ -23,6 +23,7 @@ from homeassistant.helpers.icon import icon_for_battery_level
|
||||
|
||||
from . import TeslemetryConfigEntry
|
||||
from .entity import TeslemetryEnergyInfoEntity, TeslemetryVehicleEntity
|
||||
from .helpers import handle_command, handle_vehicle_command
|
||||
from .models import TeslemetryEnergyData, TeslemetryVehicleData
|
||||
|
||||
|
||||
@ -163,7 +164,7 @@ class TeslemetryVehicleNumberEntity(TeslemetryVehicleEntity, NumberEntity):
|
||||
value = int(value)
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.entity_description.func(self.api, value))
|
||||
await handle_vehicle_command(self.entity_description.func(self.api, value))
|
||||
self._attr_native_value = value
|
||||
self.async_write_ha_state()
|
||||
|
||||
@ -198,6 +199,6 @@ class TeslemetryEnergyInfoNumberSensorEntity(TeslemetryEnergyInfoEntity, NumberE
|
||||
"""Set new value."""
|
||||
value = int(value)
|
||||
self.raise_for_scope()
|
||||
await self.handle_command(self.entity_description.func(self.api, value))
|
||||
await handle_command(self.entity_description.func(self.api, value))
|
||||
self._attr_native_value = value
|
||||
self.async_write_ha_state()
|
||||
|
@ -14,6 +14,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import TeslemetryConfigEntry
|
||||
from .entity import TeslemetryEnergyInfoEntity, TeslemetryVehicleEntity
|
||||
from .helpers import handle_command, handle_vehicle_command
|
||||
from .models import TeslemetryEnergyData, TeslemetryVehicleData
|
||||
|
||||
OFF = "off"
|
||||
@ -146,8 +147,8 @@ class TeslemetrySeatHeaterSelectEntity(TeslemetryVehicleEntity, SelectEntity):
|
||||
level = self._attr_options.index(option)
|
||||
# AC must be on to turn on seat heater
|
||||
if level and not self.get("climate_state_is_climate_on"):
|
||||
await self.handle_command(self.api.auto_conditioning_start())
|
||||
await self.handle_command(
|
||||
await handle_vehicle_command(self.api.auto_conditioning_start())
|
||||
await handle_vehicle_command(
|
||||
self.api.remote_seat_heater_request(self.entity_description.position, level)
|
||||
)
|
||||
self._attr_current_option = option
|
||||
@ -191,8 +192,8 @@ class TeslemetryWheelHeaterSelectEntity(TeslemetryVehicleEntity, SelectEntity):
|
||||
level = self._attr_options.index(option)
|
||||
# AC must be on to turn on steering wheel heater
|
||||
if level and not self.get("climate_state_is_climate_on"):
|
||||
await self.handle_command(self.api.auto_conditioning_start())
|
||||
await self.handle_command(
|
||||
await handle_vehicle_command(self.api.auto_conditioning_start())
|
||||
await handle_vehicle_command(
|
||||
self.api.remote_steering_wheel_heat_level_request(level)
|
||||
)
|
||||
self._attr_current_option = option
|
||||
@ -224,7 +225,7 @@ class TeslemetryOperationSelectEntity(TeslemetryEnergyInfoEntity, SelectEntity):
|
||||
async def async_select_option(self, option: str) -> None:
|
||||
"""Change the selected option."""
|
||||
self.raise_for_scope()
|
||||
await self.handle_command(self.api.operation(option))
|
||||
await handle_command(self.api.operation(option))
|
||||
self._attr_current_option = option
|
||||
self.async_write_ha_state()
|
||||
|
||||
@ -254,7 +255,7 @@ class TeslemetryExportRuleSelectEntity(TeslemetryEnergyInfoEntity, SelectEntity)
|
||||
async def async_select_option(self, option: str) -> None:
|
||||
"""Change the selected option."""
|
||||
self.raise_for_scope()
|
||||
await self.handle_command(
|
||||
await handle_command(
|
||||
self.api.grid_import_export(customer_preferred_export_rule=option)
|
||||
)
|
||||
self._attr_current_option = option
|
||||
|
@ -19,6 +19,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import TeslemetryConfigEntry
|
||||
from .entity import TeslemetryEnergyInfoEntity, TeslemetryVehicleEntity
|
||||
from .helpers import handle_command, handle_vehicle_command
|
||||
from .models import TeslemetryEnergyData, TeslemetryVehicleData
|
||||
|
||||
|
||||
@ -156,7 +157,7 @@ class TeslemetryVehicleSwitchEntity(TeslemetryVehicleEntity, TeslemetrySwitchEnt
|
||||
"""Turn on the Switch."""
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.entity_description.on_func(self.api))
|
||||
await handle_vehicle_command(self.entity_description.on_func(self.api))
|
||||
self._attr_is_on = True
|
||||
self.async_write_ha_state()
|
||||
|
||||
@ -164,7 +165,7 @@ class TeslemetryVehicleSwitchEntity(TeslemetryVehicleEntity, TeslemetrySwitchEnt
|
||||
"""Turn off the Switch."""
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.entity_description.off_func(self.api))
|
||||
await handle_vehicle_command(self.entity_description.off_func(self.api))
|
||||
self._attr_is_on = False
|
||||
self.async_write_ha_state()
|
||||
|
||||
@ -205,7 +206,7 @@ class TeslemetryChargeFromGridSwitchEntity(
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn on the Switch."""
|
||||
self.raise_for_scope()
|
||||
await self.handle_command(
|
||||
await handle_command(
|
||||
self.api.grid_import_export(
|
||||
disallow_charge_from_grid_with_solar_installed=False
|
||||
)
|
||||
@ -216,7 +217,7 @@ class TeslemetryChargeFromGridSwitchEntity(
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn off the Switch."""
|
||||
self.raise_for_scope()
|
||||
await self.handle_command(
|
||||
await handle_command(
|
||||
self.api.grid_import_export(
|
||||
disallow_charge_from_grid_with_solar_installed=True
|
||||
)
|
||||
@ -247,13 +248,13 @@ class TeslemetryStormModeSwitchEntity(
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn on the Switch."""
|
||||
self.raise_for_scope()
|
||||
await self.handle_command(self.api.storm_mode(enabled=True))
|
||||
await handle_command(self.api.storm_mode(enabled=True))
|
||||
self._attr_is_on = True
|
||||
self.async_write_ha_state()
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn off the Switch."""
|
||||
self.raise_for_scope()
|
||||
await self.handle_command(self.api.storm_mode(enabled=False))
|
||||
await handle_command(self.api.storm_mode(enabled=False))
|
||||
self._attr_is_on = False
|
||||
self.async_write_ha_state()
|
||||
|
@ -12,6 +12,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import TeslemetryConfigEntry
|
||||
from .entity import TeslemetryVehicleEntity
|
||||
from .helpers import handle_vehicle_command
|
||||
from .models import TeslemetryVehicleData
|
||||
|
||||
AVAILABLE = "available"
|
||||
@ -102,6 +103,6 @@ class TeslemetryUpdateEntity(TeslemetryVehicleEntity, UpdateEntity):
|
||||
"""Install an update."""
|
||||
self.raise_for_scope()
|
||||
await self.wake_up_if_asleep()
|
||||
await self.handle_command(self.api.schedule_software_update(offset_sec=60))
|
||||
await handle_vehicle_command(self.api.schedule_software_update(offset_sec=60))
|
||||
self._attr_in_progress = True
|
||||
self.async_write_ha_state()
|
||||
|
@ -2707,7 +2707,7 @@ temperusb==1.6.1
|
||||
# tensorflow==2.5.0
|
||||
|
||||
# homeassistant.components.teslemetry
|
||||
tesla-fleet-api==0.5.12
|
||||
tesla-fleet-api==0.6.1
|
||||
|
||||
# homeassistant.components.powerwall
|
||||
tesla-powerwall==0.5.2
|
||||
|
@ -2105,7 +2105,7 @@ temescal==0.5
|
||||
temperusb==1.6.1
|
||||
|
||||
# homeassistant.components.teslemetry
|
||||
tesla-fleet-api==0.5.12
|
||||
tesla-fleet-api==0.6.1
|
||||
|
||||
# homeassistant.components.powerwall
|
||||
tesla-powerwall==0.5.2
|
||||
|
@ -23,7 +23,7 @@
|
||||
'model': 'Powerwall 2, Tesla Backup Gateway 2',
|
||||
'name': 'Energy Site',
|
||||
'name_by_user': None,
|
||||
'serial_number': None,
|
||||
'serial_number': '123456',
|
||||
'suggested_area': None,
|
||||
'sw_version': None,
|
||||
'via_device_id': None,
|
||||
|
@ -343,7 +343,7 @@ async def test_asleep_or_offline(
|
||||
mock_wake_up.return_value = WAKE_UP_ASLEEP
|
||||
mock_vehicle.return_value = WAKE_UP_ASLEEP
|
||||
with (
|
||||
patch("homeassistant.components.teslemetry.entity.asyncio.sleep"),
|
||||
patch("homeassistant.components.teslemetry.helpers.asyncio.sleep"),
|
||||
pytest.raises(HomeAssistantError) as error,
|
||||
):
|
||||
await hass.services.async_call(
|
||||
|
Loading…
x
Reference in New Issue
Block a user