Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
### Fix
* Refactoring
* Changed switch to follow a more homeassistant pattern and allow for easier addition of future switches
  • Loading branch information
ryanbdclark committed Oct 10, 2024
1 parent f63e0a6 commit 9157846
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 94 deletions.
21 changes: 6 additions & 15 deletions custom_components/owlet/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,11 @@ async def async_setup_entry(

sensors = []
for coordinator in coordinators:
for sensor in SENSORS:
if sensor.key in coordinator.sock.properties:
sensors.append(OwletBinarySensor(coordinator, sensor))
sensors = [
OwletBinarySensor(coordinator, sensor)
for sensor in SENSORS
if sensor.key in coordinator.sock.properties
]

if OwletAwakeSensor.entity_description.key in coordinator.sock.properties:
sensors.append(OwletAwakeSensor(coordinator))
Expand Down Expand Up @@ -140,13 +142,6 @@ def available(self) -> bool:
@property
def is_on(self) -> bool:
"""Return true if the binary sensor is on."""
if self.entity_description.key == "sleep_state":
if self.sock.properties["charging"]:
return None
if state in [8, 15]:
state = False
else:
state = True

return self.sock.properties[self.entity_description.key]

Expand All @@ -171,8 +166,4 @@ def __init__(
@property
def is_on(self) -> bool:
"""Return true if the binary sensor is on."""
return (
False
if self.sock.properties[self.entity_description.key] in [8, 15]
else True
)
return self.sock.properties[self.entity_description.key] not in [8, 15]
21 changes: 12 additions & 9 deletions custom_components/owlet/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Config flow for Owlet Smart Sock integration."""

from __future__ import annotations

from collections.abc import Mapping
Expand All @@ -15,19 +16,17 @@
import voluptuous as vol

from homeassistant import config_entries, exceptions
from homeassistant.config_entries import ConfigEntry
from homeassistant.config_entries import ConfigEntry, ConfigFlowResult
from homeassistant.const import (
CONF_API_TOKEN,
CONF_PASSWORD,
CONF_REGION,
CONF_SCAN_INTERVAL,
CONF_USERNAME,
)
from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers.aiohttp_client import async_get_clientsession

from .const import CONF_OWLET_EXPIRY, CONF_OWLET_REFRESH, DOMAIN, POLLING_INTERVAL
from .const import DOMAIN, POLLING_INTERVAL

_LOGGER = logging.getLogger(__name__)

Expand All @@ -51,7 +50,7 @@ def __init__(self) -> None:

async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
) -> ConfigFlowResult:
"""Handle the initial step."""
errors: dict[str, str] = {}
if user_input is not None:
Expand Down Expand Up @@ -101,7 +100,9 @@ def async_get_options_flow(config_entry: ConfigEntry) -> OptionsFlowHandler:
"""Get the options flow for this handler."""
return OptionsFlowHandler(config_entry)

async def async_step_reauth(self, user_input: Mapping[str, Any]) -> FlowResult:
async def async_step_reauth(
self, user_input: Mapping[str, Any]
) -> ConfigFlowResult:
"""Handle reauth."""
self.reauth_entry = self.hass.config_entries.async_get_entry(
self.context["entry_id"]
Expand All @@ -110,7 +111,7 @@ async def async_step_reauth(self, user_input: Mapping[str, Any]) -> FlowResult:

async def async_step_reauth_confirm(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
) -> ConfigFlowResult:
"""Dialog that informs the user that reauth is required."""
assert self.reauth_entry is not None
errors: dict[str, str] = {}
Expand All @@ -130,7 +131,9 @@ async def async_step_reauth_confirm(
self.reauth_entry, data={**entry_data, **token}
)

await self.hass.config_entries.async_reload(self.reauth_entry.entry_id)
await self.hass.config_entries.async_reload(
self.reauth_entry.entry_id
)

return self.async_abort(reason="reauth_successful")

Expand All @@ -155,7 +158,7 @@ def __init__(self, config_entry: ConfigEntry) -> None:

async def async_step_init(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
) -> ConfigFlowResult:
"""Handle options flow."""
if user_input is not None:
return self.async_create_entry(title="", data=user_input)
Expand Down
4 changes: 2 additions & 2 deletions custom_components/owlet/entity.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""Base class for Owlet entities."""

from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.helpers.device_registry import DeviceInfo

from .coordinator import OwletCoordinator
from .const import DOMAIN, MANUFACTURER
from .coordinator import OwletCoordinator


class OwletBaseEntity(CoordinatorEntity[OwletCoordinator], Entity):
Expand Down
8 changes: 5 additions & 3 deletions custom_components/owlet/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,11 @@ async def async_setup_entry(
sensors = []

for coordinator in coordinators:
for sensor in SENSORS:
if sensor.key in coordinator.sock.properties:
sensors.append(OwletSensor(coordinator, sensor))
sensors = [
OwletSensor(coordinator, sensor)
for sensor in SENSORS
if sensor.key in coordinator.sock.properties
]

if OwletSleepSensor.entity_description.key in coordinator.sock.properties:
sensors.append(OwletSleepSensor(coordinator))
Expand Down
58 changes: 47 additions & 11 deletions custom_components/owlet/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

from __future__ import annotations

from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from datetime import timedelta
from typing import Any

from homeassistant.config_entries import ConfigEntry
from pyowletapi.sock import Sock

from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

Expand All @@ -19,6 +22,26 @@
PARALLEL_UPDATES = 0


@dataclass(frozen=True, kw_only=True)
class OwletSwitchEntityDescription(SwitchEntityDescription):
"""Describes Owlet switch entity."""

turn_on_fn: Callable[[Sock], Callable[[bool], Coroutine[Any, Any, None]]]
turn_off_fn: Callable[[Sock], Callable[[bool], Coroutine[Any, Any, None]]]
available_during_charging: bool


SWITCHES: tuple[OwletSwitchEntityDescription, ...] = (
OwletSwitchEntityDescription(
key="base_station_on",
translation_key="base_on",
turn_on_fn=lambda sock: (lambda state: sock.control_base_station(state)),
turn_off_fn=lambda sock: (lambda state: sock.control_base_station(state)),
available_during_charging=False,
),
)


async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
Expand All @@ -29,30 +52,43 @@ async def async_setup_entry(

switches = []
for coordinator in coordinators:
switches.append(OwletBaseSwitch(coordinator))
switches = [OwletBaseSwitch(coordinator, switch) for switch in SWITCHES]
async_add_entities(switches)


class OwletBaseSwitch(OwletBaseEntity, SwitchEntity):
"""Defines a Owlet switch."""

_attr_has_entity_name = True
_attr_translation_key = "base_on"
entity_description: OwletSwitchEntityDescription

def __init__(self, coordinator: OwletCoordinator) -> None:
"""Initialize ecobee ventilator platform."""
def __init__(
self,
coordinator: OwletCoordinator,
description: OwletSwitchEntityDescription,
) -> None:
"""Initialize owlet switch platform."""
super().__init__(coordinator)
self._attr_unique_id = f"{self.sock.serial}-base_station_on"
self.entity_description = description
self._attr_unique_id = f"{self.sock.serial}-{description.key}"
self._attr_is_on = False

@property
def is_on(self):
return self.sock.properties["base_station_on"]
def available(self) -> bool:
"""Return if entity is available."""
return super().available and (
not self.sock.properties["charging"]
or self.entity_description.available_during_charging
)

@property
def is_on(self) -> bool:
"""Return if switch is on or off."""
return self.sock.properties[self.entity_description.key]

async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on the switch."""
await self.sock.control_base_station(True)
await self.entity_description.turn_on_fn(self.sock)(True)

async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off the switch."""
await self.sock.control_base_station(False)
await self.entity_description.turn_off_fn(self.sock)(False)
Loading

0 comments on commit 9157846

Please sign in to comment.