Skip to content

Commit

Permalink
fix: reduce entity creation code
Browse files Browse the repository at this point in the history
followup to alandtse#670
  • Loading branch information
bdraco committed Jul 21, 2023
1 parent 79eea25 commit 246bca1
Show file tree
Hide file tree
Showing 14 changed files with 128 additions and 169 deletions.
35 changes: 10 additions & 25 deletions custom_components/tesla_custom/base.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"""Support for Tesla cars and energy sites."""
from homeassistant.core import HomeAssistant, callback

from homeassistant.core import callback
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.util import slugify
from homeassistant.util.unit_system import METRIC_SYSTEM, US_CUSTOMARY_SYSTEM
from teslajsonpy.car import TeslaCar
from teslajsonpy.const import RESOURCE_TYPE_BATTERY
from teslajsonpy.energy import EnergySite
Expand All @@ -12,22 +12,14 @@
from .const import ATTRIBUTION, DOMAIN


class TeslaBaseEntity(CoordinatorEntity):
class TeslaBaseEntity(CoordinatorEntity[TeslaDataUpdateCoordinator]):
"""Representation of a Tesla device."""

type: str
_attr_attribution = ATTRIBUTION
_attr_has_entity_name = True
_enabled_by_default: bool = True
type: str

def __init__(
self, hass: HomeAssistant, coordinator: TeslaDataUpdateCoordinator
) -> None:
"""Initialise the Tesla device."""
super().__init__(coordinator)
self._coordinator: TeslaDataUpdateCoordinator = coordinator
self.hass = hass
self._memorized_unique_id = None
_memorized_unique_id: str | None = None

@callback
def refresh(self) -> None:
Expand Down Expand Up @@ -60,18 +52,12 @@ class TeslaCarEntity(TeslaBaseEntity):

def __init__(
self,
hass: HomeAssistant,
car: TeslaCar,
coordinator: TeslaDataUpdateCoordinator,
) -> None:
"""Initialise the Tesla car device."""
super().__init__(hass, coordinator)
super().__init__(coordinator)
self._car = car
self._unit_system = (
METRIC_SYSTEM
if self.hass.config.units is METRIC_SYSTEM
else US_CUSTOMARY_SYSTEM
)

async def update_controller(
self, *, wake_if_asleep: bool = False, force: bool = True, blocking: bool = True
Expand All @@ -90,10 +76,10 @@ async def update_controller(
)
return

await self._coordinator.controller.update(
await self.coordinator.controller.update(
self._car.id, wake_if_asleep=wake_if_asleep, force=force
)
await self._coordinator.async_refresh()
await self.coordinator.async_refresh()

@property
def vehicle_name(self) -> str:
Expand Down Expand Up @@ -128,7 +114,7 @@ def device_info(self) -> DeviceInfo:
def assumed_state(self) -> bool:
"""Return whether the data is from an online vehicle."""
vin = self._car.vin
controller = self._coordinator.controller
controller = self.coordinator.controller
return not controller.is_car_online(vin=vin) and (
controller.get_last_update_time(vin=vin)
- controller.get_last_wake_up_time(vin=vin)
Expand All @@ -141,12 +127,11 @@ class TeslaEnergyEntity(TeslaBaseEntity):

def __init__(
self,
hass: HomeAssistant,
energysite: EnergySite,
coordinator: TeslaDataUpdateCoordinator,
) -> None:
"""Initialise the Tesla energy device."""
super().__init__(hass, coordinator)
super().__init__(coordinator)
self._energysite = energysite

@property
Expand Down
52 changes: 26 additions & 26 deletions custom_components/tesla_custom/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,22 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie

for vin, car in cars.items():
coordinator = coordinators[vin]
entities.append(TeslaCarParkingBrake(hass, car, coordinator))
entities.append(TeslaCarOnline(hass, car, coordinator))
entities.append(TeslaCarAsleep(hass, car, coordinator))
entities.append(TeslaCarChargerConnection(hass, car, coordinator))
entities.append(TeslaCarCharging(hass, car, coordinator))
entities.append(TeslaCarDoors(hass, car, coordinator))
entities.append(TeslaCarWindows(hass, car, coordinator))
entities.append(TeslaCarScheduledCharging(hass, car, coordinator))
entities.append(TeslaCarScheduledDeparture(hass, car, coordinator))
entities.append(TeslaCarUserPresent(hass, car, coordinator))
entities.append(TeslaCarParkingBrake(car, coordinator))
entities.append(TeslaCarOnline(car, coordinator))
entities.append(TeslaCarAsleep(car, coordinator))
entities.append(TeslaCarChargerConnection(car, coordinator))
entities.append(TeslaCarCharging(car, coordinator))
entities.append(TeslaCarDoors(car, coordinator))
entities.append(TeslaCarWindows(car, coordinator))
entities.append(TeslaCarScheduledCharging(car, coordinator))
entities.append(TeslaCarScheduledDeparture(car, coordinator))
entities.append(TeslaCarUserPresent(car, coordinator))

for energy_site_id, energysite in energysites.items():
coordinator = coordinators[energy_site_id]
if energysite.resource_type == RESOURCE_TYPE_BATTERY:
entities.append(TeslaEnergyBatteryCharging(hass, energysite, coordinator))
entities.append(TeslaEnergyGridStatus(hass, energysite, coordinator))
entities.append(TeslaEnergyBatteryCharging(energysite, coordinator))
entities.append(TeslaEnergyGridStatus(energysite, coordinator))

async_add_entities(entities, update_before_add=True)

Expand Down Expand Up @@ -180,9 +180,7 @@ def extra_state_attributes(self):

def _open_or_closed(self, door):
"""Return string of 'Open' or 'Closed' when passed a door integer state."""
if door:
return "Open"
return "Closed"
return "Open" if door else "Closed"


class TeslaCarWindows(TeslaCarEntity, BinarySensorEntity):
Expand All @@ -201,11 +199,12 @@ def is_on(self):
@property
def extra_state_attributes(self):
"""Return device state attributes."""
car = self._car
return {
"Driver Front": self._open_or_closed(self._car.window_fd),
"Driver Rear": self._open_or_closed(self._car.window_rd),
"Passenger Front": self._open_or_closed(self._car.window_fp),
"Passenger Rear": self._open_or_closed(self._car.window_rp),
"Driver Front": self._open_or_closed(car.window_fd),
"Driver Rear": self._open_or_closed(car.window_rd),
"Passenger Front": self._open_or_closed(car.window_fp),
"Passenger Rear": self._open_or_closed(car.window_rp),
}

def _open_or_closed(self, window):
Expand Down Expand Up @@ -261,16 +260,17 @@ def is_on(self):
def extra_state_attributes(self):
"""Return device state attributes."""
# pylint: disable=protected-access
timestamp = self._car._vehicle_data.get("charge_state", {}).get(
car = self._car
timestamp = car._vehicle_data.get("charge_state", {}).get(
"scheduled_departure_time"
)
return {
"Departure time": self._car.scheduled_departure_time_minutes,
"Preconditioning enabled": self._car.is_preconditioning_enabled,
"Preconditioning weekdays only": self._car.is_preconditioning_weekday_only,
"Off peak charging enabled": self._car.is_off_peak_charging_enabled,
"Off peak charging weekdays only": self._car.is_off_peak_charging_weekday_only,
"End off peak time": self._car.off_peak_hours_end_time,
"Departure time": car.scheduled_departure_time_minutes,
"Preconditioning enabled": car.is_preconditioning_enabled,
"Preconditioning weekdays only": car.is_preconditioning_weekday_only,
"Off peak charging enabled": car.is_off_peak_charging_enabled,
"Off peak charging weekdays only": car.is_off_peak_charging_weekday_only,
"End off peak time": car.off_peak_hours_end_time,
"Departure timestamp": timestamp,
}

Expand Down
20 changes: 9 additions & 11 deletions custom_components/tesla_custom/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie

for vin, car in cars.items():
coordinator = coordinators[vin]
entities.append(TeslaCarHorn(hass, car, coordinator))
entities.append(TeslaCarFlashLights(hass, car, coordinator))
entities.append(TeslaCarWakeUp(hass, car, coordinator))
entities.append(TeslaCarForceDataUpdate(hass, car, coordinator))
entities.append(TeslaCarTriggerHomelink(hass, car, coordinator))
entities.append(TeslaCarRemoteStart(hass, car, coordinator))
entities.append(TeslaCarEmissionsTest(hass, car, coordinator))
entities.append(TeslaCarHorn(car, coordinator))
entities.append(TeslaCarFlashLights(car, coordinator))
entities.append(TeslaCarWakeUp(car, coordinator))
entities.append(TeslaCarForceDataUpdate(car, coordinator))
entities.append(TeslaCarTriggerHomelink(car, coordinator))
entities.append(TeslaCarRemoteStart(car, coordinator))
entities.append(TeslaCarEmissionsTest(car, coordinator))

async_add_entities(entities, update_before_add=True)

Expand Down Expand Up @@ -97,12 +97,11 @@ class TeslaCarTriggerHomelink(TeslaCarEntity, ButtonEntity):

def __init__(
self,
hass: HomeAssistant,
car: TeslaCar,
coordinator: TeslaDataUpdateCoordinator,
) -> None:
"""Initialise Homelink button."""
super().__init__(hass, car, coordinator)
super().__init__(car, coordinator)
# Entity is only enabled upon first install if garages have been paired to homelink
self._enabled_by_default = self._car.homelink_device_count

Expand Down Expand Up @@ -136,12 +135,11 @@ class TeslaCarEmissionsTest(TeslaCarEntity, ButtonEntity):

def __init__(
self,
hass: HomeAssistant,
car: TeslaCar,
coordinator: TeslaDataUpdateCoordinator,
) -> None:
"""Initialize emissions test button."""
super().__init__(hass, car, coordinator)
super().__init__(car, coordinator)
self._enabled_by_default = self._car.pedestrian_speaker

async def async_press(self) -> None:
Expand Down
13 changes: 3 additions & 10 deletions custom_components/tesla_custom/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,7 @@ async def async_setup_entry(
coordinators = entry_data["coordinators"]
cars = entry_data["cars"]

entities = [
TeslaCarClimate(
hass,
car,
coordinators[vin],
)
for vin, car in cars.items()
]
entities = [TeslaCarClimate(car, coordinators[vin]) for vin, car in cars.items()]
async_add_entities(entities, update_before_add=True)


Expand Down Expand Up @@ -128,7 +121,7 @@ async def async_set_hvac_mode(self, hvac_mode):
elif hvac_mode == HVAC_MODE_HEAT_COOL:
await self._car.set_hvac_mode("on")
# set_hvac_mode changes multiple states so refresh all entities
await self._coordinator.async_refresh()
await self.coordinator.async_refresh()

@property
def preset_mode(self):
Expand Down Expand Up @@ -173,4 +166,4 @@ async def async_set_preset_mode(self, preset_mode: str) -> None:
else:
await self._car.set_climate_keeper_mode(KEEPER_MAP[preset_mode])
# max_defrost changes multiple states so refresh all entities
await self._coordinator.async_refresh()
await self.coordinator.async_refresh()
8 changes: 4 additions & 4 deletions custom_components/tesla_custom/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie

for vin, car in cars.items():
coordinator = coordinators[vin]
entities.append(TeslaCarChargerDoor(hass, car, coordinator))
entities.append(TeslaCarFrunk(hass, car, coordinator))
entities.append(TeslaCarTrunk(hass, car, coordinator))
entities.append(TeslaCarWindows(hass, car, coordinator))
entities.append(TeslaCarChargerDoor(car, coordinator))
entities.append(TeslaCarFrunk(car, coordinator))
entities.append(TeslaCarTrunk(car, coordinator))
entities.append(TeslaCarWindows(car, coordinator))

async_add_entities(entities, update_before_add=True)

Expand Down
4 changes: 2 additions & 2 deletions custom_components/tesla_custom/device_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie

for vin, car in cars.items():
coordinator = coordinators[vin]
entities.append(TeslaCarLocation(hass, car, coordinator))
entities.append(TeslaCarDestinationLocation(hass, car, coordinator))
entities.append(TeslaCarLocation(car, coordinator))
entities.append(TeslaCarDestinationLocation(car, coordinator))

async_add_entities(entities, update_before_add=True)

Expand Down
4 changes: 2 additions & 2 deletions custom_components/tesla_custom/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie

for vin, car in cars.items():
coordinator = coordinators[vin]
entities.append(TeslaCarDoors(hass, car, coordinator))
entities.append(TeslaCarChargePortLatch(hass, car, coordinator))
entities.append(TeslaCarDoors(car, coordinator))
entities.append(TeslaCarChargePortLatch(car, coordinator))

async_add_entities(entities, update_before_add=True)

Expand Down
6 changes: 3 additions & 3 deletions custom_components/tesla_custom/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie

for vin, car in cars.items():
coordinator = coordinators[vin]
entities.append(TeslaCarChargeLimit(hass, car, coordinator))
entities.append(TeslaCarChargingAmps(hass, car, coordinator))
entities.append(TeslaCarChargeLimit(car, coordinator))
entities.append(TeslaCarChargingAmps(car, coordinator))

for energy_site_id, energysite in energysites.items():
coordinator = coordinators[energy_site_id]
if energysite.resource_type == RESOURCE_TYPE_BATTERY:
entities.append(TeslaEnergyBackupReserve(hass, energysite, coordinator))
entities.append(TeslaEnergyBackupReserve(energysite, coordinator))

async_add_entities(entities, update_before_add=True)

Expand Down
18 changes: 8 additions & 10 deletions custom_components/tesla_custom/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie

for vin, car in cars.items():
coordinator = coordinators[vin]
entities.append(TeslaCarCabinOverheatProtection(hass, car, coordinator))
entities.append(TeslaCarCabinOverheatProtection(car, coordinator))
if car.get_heated_steering_wheel_level() is not None:
# Only add steering wheel select if we have a variable heated steering wheel
entities.append(TeslaCarHeatedSteeringWheel(hass, car, coordinator))
entities.append(TeslaCarHeatedSteeringWheel(car, coordinator))
for seat_name in SEAT_ID_MAP:
if "rear" in seat_name and not car.rear_seat_heaters:
continue
Expand All @@ -98,15 +98,15 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie
car.third_row_seats == "None" or car.third_row_seats is None
):
continue
entities.append(TeslaCarHeatedSeat(hass, car, coordinator, seat_name))
entities.append(TeslaCarHeatedSeat(car, coordinator, seat_name))

for energy_site_id, energysite in energysites.items():
coordinator = coordinators[energy_site_id]
if energysite.resource_type == RESOURCE_TYPE_BATTERY:
entities.append(TeslaEnergyOperationMode(hass, energysite, coordinator))
entities.append(TeslaEnergyOperationMode(energysite, coordinator))
if energysite.resource_type == RESOURCE_TYPE_BATTERY and energysite.has_solar:
entities.append(TeslaEnergyExportRule(hass, energysite, coordinator))
entities.append(TeslaEnergyGridCharging(hass, energysite, coordinator))
entities.append(TeslaEnergyExportRule(energysite, coordinator))
entities.append(TeslaEnergyGridCharging(energysite, coordinator))

async_add_entities(entities, update_before_add=True)

Expand All @@ -118,13 +118,12 @@ class TeslaCarHeatedSeat(TeslaCarEntity, SelectEntity):

def __init__(
self,
hass: HomeAssistant,
car: TeslaCar,
coordinator: TeslaDataUpdateCoordinator,
seat_name: str,
):
"""Initialize heated seat entity."""
super().__init__(hass, car, coordinator)
super().__init__(car, coordinator)
self._seat_name = seat_name
self.type = f"heated seat {seat_name}"
if SEAT_ID_MAP[self._seat_name] < 2:
Expand Down Expand Up @@ -192,12 +191,11 @@ class TeslaCarHeatedSteeringWheel(TeslaCarEntity, SelectEntity):

def __init__(
self,
hass: HomeAssistant,
car: TeslaCar,
coordinator: TeslaDataUpdateCoordinator,
):
"""Initialize heated seat entity."""
super().__init__(hass, car, coordinator)
super().__init__(car, coordinator)
self._enabled_by_default = self._car.steering_wheel_heater

async def async_select_option(self, option: str, **kwargs):
Expand Down
Loading

0 comments on commit 246bca1

Please sign in to comment.