Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: reduce entity creation code #671

Merged
merged 1 commit into from
Jul 25, 2023
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
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]):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CoordinatorEntity takes a type var for the coordinator

"""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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.hass is set by the entity platform when the entity is added to 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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CoordinatorEntity sets self.coordinator

self._car = car
self._unit_system = (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT this is dead code

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
Loading