Skip to content

Commit

Permalink
Merge pull request #372 from alandtse/dev
Browse files Browse the repository at this point in the history
2022-11-26
  • Loading branch information
alandtse authored Nov 27, 2022
2 parents a3bc302 + 4d1270b commit 26bfdbe
Show file tree
Hide file tree
Showing 8 changed files with 445 additions and 1,156 deletions.
2 changes: 1 addition & 1 deletion custom_components/tesla_custom/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"documentation": "https://github.com/alandtse/tesla/wiki",
"issue_tracker": "https://github.com/alandtse/tesla/issues",
"requirements": [
"teslajsonpy==3.2.1"
"teslajsonpy==3.2.2"
],
"codeowners": [
"@alandtse"
Expand Down
32 changes: 32 additions & 0 deletions custom_components/tesla_custom/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,19 @@
POWER_KILO_WATT,
SPEED_MILES_PER_HOUR,
TEMP_CELSIUS,
TIME_HOURS,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.icon import icon_for_battery_level
from homeassistant.util.unit_conversion import DistanceConverter
from homeassistant.util import dt

from . import TeslaDataUpdateCoordinator
from .base import TeslaCarEntity, TeslaEnergyEntity
from .const import DISTANCE_UNITS_KM_HR, DOMAIN

from datetime import datetime, timedelta

SOLAR_SITE_SENSORS = ["solar power", "grid power", "load power"]
BATTERY_SITE_SENSORS = SOLAR_SITE_SENSORS + ["battery power"]

Expand All @@ -47,6 +51,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie
entities.append(TeslaCarRange(hass, car, coordinator))
entities.append(TeslaCarTemp(hass, car, coordinator))
entities.append(TeslaCarTemp(hass, car, coordinator, inside=True))
entities.append(TeslaCarTimeChargeComplete(hass, car, coordinator))

for energysite in energysites.values():
if (
Expand Down Expand Up @@ -458,3 +463,30 @@ def native_value(self) -> int:
def icon(self):
"""Return icon for the backup reserve."""
return icon_for_battery_level(battery_level=self.native_value)


class TeslaCarTimeChargeComplete(TeslaCarEntity, SensorEntity):
"""Representation of the Tesla car time charge complete."""

def __init__(
self,
hass: HomeAssistant,
car: TeslaCar,
coordinator: TeslaDataUpdateCoordinator,
) -> None:
"""Initialize time charge complete entity."""
super().__init__(hass, car, coordinator)
self.type = "time charge complete"
self._attr_device_class = SensorDeviceClass.TIMESTAMP
self._attr_state_class = SensorStateClass.MEASUREMENT
self._attr_icon = "mdi:timer-plus"

@property
def native_value(self) -> datetime:
"""Return time charge complete."""
if self._car.time_to_full_charge is None:
charge_hours = 0
else:
charge_hours = float(self._car.time_to_full_charge)

return dt.now() + timedelta(hours=charge_hours)
48 changes: 38 additions & 10 deletions custom_components/tesla_custom/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie
async_add_entities(entities, True)


INSTALLABLE_STATUSES = ["available", "scheduled"]

PRETTY_STATUS_STRINGS = {
"downloading_wifi_wait": "Waiting on Wi-Fi",
"downloading": "Downloading",
"available": "Available to install",
"scheduled": "Scheduled for install",
"installing": "Installing",
}


class TeslaCarUpdate(TeslaCarEntity, UpdateEntity):
"""Representation of a Tesla car update."""

Expand All @@ -43,34 +54,50 @@ def __init__(
@property
def supported_features(self):
"""Return the list of supported features."""
return UpdateEntityFeature.INSTALL | UpdateEntityFeature.PROGRESS
# Don't enable Install button until the update has downloaded
if (
self._car.software_update
and self._car.software_update.get("status") in INSTALLABLE_STATUSES
):
return UpdateEntityFeature.INSTALL | UpdateEntityFeature.PROGRESS
else:
return UpdateEntityFeature.PROGRESS

@property
def release_url(self) -> str:
"""Return release URL.
Uses notateslaapp.com as Tesla doesn't have offical web based release Notes.
"""
version_str = self.latest_version
if version_str is None:
version_str = ""

if self._car.software_update:
# latest_version may include a status tag, so get the original version
version_str: str = self._car.software_update.get("version", "").strip()
if not version_str:
version_str = self.installed_version

if version_str is None:
if not version_str:
return None

return f"https://www.notateslaapp.com/software-updates/version/{version_str}/release-notes"

@property
def latest_version(self) -> str:
"""Get the latest version."""
version_str = None
version_str = ""
status_str = ""

if self._car.software_update:
version_str: str = self._car.software_update.get("version")
version_str: str = self._car.software_update.get("version", "").strip()
status_str: str = self._car.software_update.get("status", "").strip()
# If we don't have a software_update version, then we're running the latest version.
if version_str is None or version_str.strip() == "":
version_str = self.installed_version
if not version_str:
return self.installed_version

# Append the status so users can tell if it's downloading or scheduled, etc
if status_str:
version_str += f" ({PRETTY_STATUS_STRINGS.get(status_str, status_str)})"
return version_str

@property
Expand All @@ -90,9 +117,10 @@ def in_progress(self):

if self._car.software_update:
update_status = self._car.software_update.get("status")
# If the update is scheduled, then its Simply In Progress
# If the update is scheduled, don't consider in-progress so the
# user can still install immediately if desired
if update_status == "scheduled":
return True
return False
# If its actually installing, we can use the install_perc
if update_status == "installing":
progress = self._car.software_update.get("install_perc")
Expand Down
Loading

0 comments on commit 26bfdbe

Please sign in to comment.