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

Update to Home Assistant 2024.11 [Fixes #49] #52

Merged
merged 2 commits into from
Jan 5, 2025
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
47 changes: 25 additions & 22 deletions custom_components/teslafi/alarm_control_panel.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
"""TeslaFi Alarm Control Panel."""

from dataclasses import dataclass

from homeassistant.components.alarm_control_panel import (
AlarmControlPanelEntity,
AlarmControlPanelEntityDescription,
AlarmControlPanelEntityFeature,
AlarmControlPanelState,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
STATE_ALARM_ARMING,
STATE_ALARM_ARMED_AWAY,
STATE_ALARM_DISARMING,
STATE_ALARM_DISARMED,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .base import (
TeslaFiBaseEntityDescription,
TeslaFiEntity,
)
from .const import DELAY_WAKEUP, DELAY_LOCKS, DOMAIN, LOGGER
from .base import TeslaFiBaseEntityDescription, TeslaFiEntity
from .const import DELAY_LOCKS, DELAY_WAKEUP, DOMAIN, LOGGER
from .coordinator import TeslaFiCoordinator
from .util import _convert_to_bool

Expand All @@ -28,13 +23,15 @@ class TeslaFiSentryEntityDescription(
AlarmControlPanelEntityDescription,
TeslaFiBaseEntityDescription,
):
"""Alarm panel to control Sentry Mode"""
"""Alarm panel to control Sentry Mode."""


class TeslaFiSentryEntity(
TeslaFiEntity[TeslaFiSentryEntityDescription],
AlarmControlPanelEntity,
):
"""TeslaFi Sentry Mode Alarm Control Panel."""

_attr_code_arm_required: bool = False
_attr_supported_features: AlarmControlPanelEntityFeature = (
AlarmControlPanelEntityFeature.ARM_AWAY
Expand All @@ -46,17 +43,20 @@ def __init__(
coordinator: TeslaFiCoordinator,
entity_description: TeslaFiSentryEntityDescription,
) -> None:
"""Initialize the TeslaFi alarm control panel entity."""
super().__init__(coordinator, entity_description)
self._attr_changed_by = None
self._target_state = None

@property
def icon(self) -> str | None:
if self.state == STATE_ALARM_ARMED_AWAY:
"""Return the icon for the entity."""
if self.state == AlarmControlPanelState.ARMED_AWAY:
return "mdi:shield-car"
return super().icon

async def async_alarm_disarm(self, code: str | None = None) -> None:
"""Send the disarm command to the Tesla vehicle."""
LOGGER.debug("Disarming")
response = await self.coordinator.execute_command(
"set_sentry_mode", sentryMode=False
Expand All @@ -67,8 +67,8 @@ async def async_alarm_disarm(self, code: str | None = None) -> None:
# > https://developer.tesla.com/docs/fleet-api#2023-10-09-rest-api-vehicle-commands-endpoint-deprecation-warning:

if response:
self._target_state = STATE_ALARM_DISARMED
self._attr_state = STATE_ALARM_DISARMING
self._target_state = AlarmControlPanelState.DISARMED
self._attr_alarm_state = AlarmControlPanelState.DISARMING
self._attr_changed_by = "hass"
self.async_write_ha_state()

Expand All @@ -79,6 +79,7 @@ async def async_alarm_disarm(self, code: str | None = None) -> None:
self.coordinator.schedule_refresh_in(DELAY_LOCKS)

async def async_alarm_arm_away(self, code: str | None = None) -> None:
"""Send the arm command to the Tesla vehicle."""
LOGGER.debug("Arming")
response = await self.coordinator.execute_command(
"set_sentry_mode", sentryMode=True
Expand All @@ -89,8 +90,8 @@ async def async_alarm_arm_away(self, code: str | None = None) -> None:
# > https://developer.tesla.com/docs/fleet-api#2023-10-09-rest-api-vehicle-commands-endpoint-deprecation-warning:

if response:
self._target_state = STATE_ALARM_ARMED_AWAY
self._attr_state = STATE_ALARM_ARMING
self._target_state = AlarmControlPanelState.ARMED_AWAY
self._attr_alarm_state = AlarmControlPanelState.ARMING
self._attr_changed_by = "hass"
self.async_write_ha_state()

Expand All @@ -109,7 +110,7 @@ def _handle_coordinator_update(self) -> None:
if waiting:
if new_state == target:
# It succeeded
self._attr_state = new_state
self._attr_alarm_state = new_state
self._attr_changed_by = "hass"
self._target_state = None
LOGGER.info("Target state succeeded: %s", target)
Expand All @@ -119,10 +120,10 @@ def _handle_coordinator_update(self) -> None:
return self.coordinator.schedule_refresh_in(DELAY_WAKEUP)
elif old_state is None or new_state is None:
self._attr_changed_by = None
self._attr_state = new_state
self._attr_alarm_state = new_state
elif old_state != new_state:
self._attr_changed_by = "remote"
self._attr_state = new_state
self._attr_alarm_state = new_state

return super()._handle_coordinator_update()

Expand All @@ -133,7 +134,9 @@ def _handle_coordinator_update(self) -> None:
name="Sentry Mode",
entity_registry_enabled_default=False,
convert=lambda v: (
STATE_ALARM_ARMED_AWAY if _convert_to_bool(v) else STATE_ALARM_DISARMED
AlarmControlPanelState.ARMED_AWAY
if _convert_to_bool(v)
else AlarmControlPanelState.DISARMED
),
),
]
Expand All @@ -144,7 +147,7 @@ async def async_setup_entry(
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up from config entry"""
"""Set up from config entry."""
coordinator: TeslaFiCoordinator
coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"]
entities: list[TeslaFiSentryEntity] = []
Expand Down
30 changes: 12 additions & 18 deletions custom_components/teslafi/lock.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
"""TeslaFi Locks"""
"""TeslaFi Locks."""

from typing import Any
from homeassistant.components.lock import LockEntity

from homeassistant.components.lock import LockEntity, LockState
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_LOCKING, STATE_UNLOCKING
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import (
DELAY_LOCKS,
DELAY_WAKEUP,
DOMAIN,
LOGGER,
)
from .coordinator import TeslaFiCoordinator
from .base import TeslaFiEntity, TeslaFiLockEntityDescription

from .const import DELAY_LOCKS, DELAY_WAKEUP, DOMAIN, LOGGER
from .coordinator import TeslaFiCoordinator

LOCKS = [
TeslaFiLockEntityDescription(
Expand All @@ -31,7 +25,7 @@ async def async_setup_entry(
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up from config entry"""
"""Set up from config entry."""
coordinator: TeslaFiCoordinator
coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"]
entities: list[TeslaFiLock] = []
Expand All @@ -40,20 +34,20 @@ async def async_setup_entry(


class TeslaFiLock(TeslaFiEntity[TeslaFiLockEntityDescription], LockEntity):
"""TeslaFi Door Locks"""
"""TeslaFi Door Locks."""

_pending_action: str | None = None

async def async_lock(self, **kwargs: Any) -> None:
"""Ask TeslaFi to lock the vehicle"""
"""Ask TeslaFi to lock the vehicle."""
self._attr_is_unlocking = False

response = await self.coordinator.execute_command("door_lock")
assert response

if response:
LOGGER.debug("Lock response %s", response)
self._pending_action = STATE_LOCKING
self._pending_action = LockState.LOCKING
self._attr_is_locking = True
self.async_write_ha_state()
if self.coordinator.data.is_sleeping:
Expand All @@ -63,15 +57,15 @@ async def async_lock(self, **kwargs: Any) -> None:
self.coordinator.schedule_refresh_in(DELAY_LOCKS)

async def async_unlock(self, **kwargs: Any) -> None:
"""Ask TeslaFi to unlock the vehicle"""
"""Ask TeslaFi to unlock the vehicle."""
self._attr_is_locking = False

response = await self.coordinator.execute_command("door_unlock")
assert response

if response:
LOGGER.debug("Unlock response %s", response)
self._pending_action = STATE_UNLOCKING
self._pending_action = LockState.UNLOCKING
self._attr_is_unlocking = True
self.async_write_ha_state()
if self.coordinator.data.is_sleeping:
Expand All @@ -84,7 +78,7 @@ def _handle_coordinator_update(self) -> None:
prev = self.state
newest = self._get_value()
waiting = self._pending_action is not None
target = prev == STATE_LOCKING if waiting else None
target = prev == LockState.LOCKING if waiting else None
LOGGER.debug(
"lock %s: prev=%s, new=%s, pending=%s, target=%s",
self.entity_id,
Expand Down
2 changes: 1 addition & 1 deletion hacs.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"name": "TeslaFi",
"render_readme": true,
"country": "US",
"homeassistant": "2024.4.0"
"homeassistant": "2024.11.0"
}
Loading