mirror of
https://github.com/home-assistant/core.git
synced 2025-08-05 11:38:21 +00:00
Code refactoring
This commit is contained in:
parent
baeb70af8a
commit
7b2641d136
@ -1,7 +1,12 @@
|
||||
"""Constants for the Swing2Sleep Smarla integration."""
|
||||
|
||||
from homeassistant.const import Platform
|
||||
|
||||
DOMAIN = "smarla"
|
||||
|
||||
HOST = "https://devices.swing2sleep.de"
|
||||
|
||||
PLATFORMS = ["switch"]
|
||||
PLATFORMS = [Platform.SWITCH]
|
||||
|
||||
DEVICE_MODEL_NAME = "Smarla"
|
||||
MANUFACTURER_NAME = "Swing2Sleep"
|
||||
|
@ -5,12 +5,14 @@ from pysmarlaapi import Federwiege
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
from .const import DOMAIN
|
||||
from .const import DEVICE_MODEL_NAME, DOMAIN, MANUFACTURER_NAME
|
||||
|
||||
|
||||
class SmarlaBaseEntity(Entity):
|
||||
"""Common Base Entity class for defining Smarla device."""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
federwiege: Federwiege,
|
||||
@ -18,12 +20,10 @@ class SmarlaBaseEntity(Entity):
|
||||
"""Initialise the entity."""
|
||||
super().__init__()
|
||||
|
||||
self._attr_has_entity_name = True
|
||||
|
||||
self._attr_device_info = DeviceInfo(
|
||||
identifiers={(DOMAIN, federwiege.serial_number)},
|
||||
name="Smarla",
|
||||
model="Smarla",
|
||||
manufacturer="Swing2Sleep",
|
||||
name=DEVICE_MODEL_NAME,
|
||||
model=DEVICE_MODEL_NAME,
|
||||
manufacturer=MANUFACTURER_NAME,
|
||||
serial_number=federwiege.serial_number,
|
||||
)
|
||||
|
@ -3,7 +3,6 @@
|
||||
"name": "Swing2Sleep Smarla",
|
||||
"codeowners": ["@explicatis", "@rlint-explicatis"],
|
||||
"config_flow": true,
|
||||
"dependencies": [],
|
||||
"documentation": "https://www.home-assistant.io/integrations/smarla",
|
||||
"integration_type": "device",
|
||||
"iot_class": "cloud_push",
|
||||
|
@ -10,7 +10,7 @@
|
||||
"access_token": "[%key:common::config_flow::data::access_token%]"
|
||||
},
|
||||
"data_description": {
|
||||
"access_token": "The access token generated from the App."
|
||||
"access_token": "The access token generated by the Swing2Sleep app."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -4,6 +4,7 @@ from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from pysmarlaapi import Federwiege
|
||||
from pysmarlaapi.federwiege.classes import Property
|
||||
|
||||
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
|
||||
from homeassistant.core import HomeAssistant
|
||||
@ -15,13 +16,13 @@ from .entity import SmarlaBaseEntity
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class SmarlaSwitchEntityDescription(SwitchEntityDescription):
|
||||
"""Class describing Swing2Sleep Smarla switch entities."""
|
||||
"""Class describing Swing2Sleep Smarla switch entity."""
|
||||
|
||||
service: str
|
||||
property: str
|
||||
|
||||
|
||||
NUMBER_TYPES: list[SmarlaSwitchEntityDescription] = [
|
||||
SWITCHES: list[SmarlaSwitchEntityDescription] = [
|
||||
SmarlaSwitchEntityDescription(
|
||||
key="cradle",
|
||||
name=None,
|
||||
@ -43,20 +44,17 @@ async def async_setup_entry(
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Smarla switches from config entry."""
|
||||
federwiege = config_entry.runtime_data
|
||||
|
||||
entities: list[SwitchEntity] = []
|
||||
|
||||
for desc in NUMBER_TYPES:
|
||||
entity = SmarlaSwitch(federwiege, desc)
|
||||
entities.append(entity)
|
||||
|
||||
async_add_entities(entities)
|
||||
federwiege: Federwiege = config_entry.runtime_data
|
||||
async_add_entities(SmarlaSwitch(federwiege, desc) for desc in SWITCHES)
|
||||
|
||||
|
||||
class SmarlaSwitch(SmarlaBaseEntity, SwitchEntity):
|
||||
"""Representation of Smarla switch."""
|
||||
|
||||
entity_description: SmarlaSwitchEntityDescription
|
||||
_property: Property
|
||||
_attr_should_poll = False
|
||||
|
||||
async def on_change(self, value: Any):
|
||||
"""Notify ha when state changes."""
|
||||
self.async_write_ha_state()
|
||||
@ -68,30 +66,29 @@ class SmarlaSwitch(SmarlaBaseEntity, SwitchEntity):
|
||||
) -> None:
|
||||
"""Initialize a Smarla switch."""
|
||||
super().__init__(federwiege)
|
||||
self.property = federwiege.get_service(description.service).get_property(
|
||||
self._property = federwiege.get_service(description.service).get_property(
|
||||
description.property
|
||||
)
|
||||
self.entity_description = description
|
||||
self._attr_should_poll = False
|
||||
self._attr_unique_id = f"{federwiege.serial_number}-{description.key}"
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Run when this Entity has been added to HA."""
|
||||
await self.property.add_listener(self.on_change)
|
||||
await self._property.add_listener(self.on_change)
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Entity being removed from hass."""
|
||||
await self.property.remove_listener(self.on_change)
|
||||
await self._property.remove_listener(self.on_change)
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return the entity value to represent the entity state."""
|
||||
return self.property.get()
|
||||
return self._property.get()
|
||||
|
||||
def turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch on."""
|
||||
self.property.set(True)
|
||||
self._property.set(True)
|
||||
|
||||
def turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch off."""
|
||||
self.property.set(False)
|
||||
self._property.set(False)
|
||||
|
@ -1,7 +1,9 @@
|
||||
"""Test config flow for Swing2Sleep Smarla integration."""
|
||||
|
||||
import json
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.smarla.config_flow import Connection
|
||||
from homeassistant.components.smarla.const import DOMAIN
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN
|
||||
@ -10,9 +12,12 @@ from homeassistant.data_entry_flow import FlowResultType
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
MOCK_ACCESS_TOKEN = "eyJyZWZyZXNoVG9rZW4iOiJ0ZXN0IiwidG9rZW4iOiJ0ZXN0IiwiZGF0ZUNyZWF0ZWQiOiIyMDI1LTAxLTAxVDIzOjU5OjU5Ljk5OTk5OVoiLCJhcHBJZGVudGlmaWVyIjoiSEEtaG9tZWFzc2lzdGFudHRlc3QiLCJzZXJpYWxOdW1iZXIiOiJBQkNELUFCQ0QiLCJhcHBWZXJzaW9uIjoidW5rbm93biIsImFwcEN1bHR1cmUiOiJkZSJ9"
|
||||
MOCK_ACCESS_TOKEN_JSON = '{"refreshToken": "test", "token": "test", "dateCreated": "2025-01-01T23:59:59.999999Z", "appIdentifier": "HA-homeassistanttest", "serialNumber": "ABCD-ABCD", "appVersion": "unknown", "appCulture": "de"}'
|
||||
MOCK_SERIAL = "ABCD-ABCD"
|
||||
MOCK_ACCESS_TOKEN = "eyJyZWZyZXNoVG9rZW4iOiJ0ZXN0IiwiYXBwSWRlbnRpZmllciI6IkhBLXRlc3QiLCJzZXJpYWxOdW1iZXIiOiJBQkNEIn0="
|
||||
MOCK_ACCESS_TOKEN_JSON = {
|
||||
"refreshToken": "test",
|
||||
"appIdentifier": "HA-test",
|
||||
"serialNumber": "ABCD",
|
||||
}
|
||||
|
||||
|
||||
async def test_show_form(hass: HomeAssistant) -> None:
|
||||
@ -30,13 +35,13 @@ async def test_create_entry(hass: HomeAssistant) -> None:
|
||||
with patch.object(Connection, "get_token", new=AsyncMock(return_value=True)):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": "user"},
|
||||
context={"source": config_entries.SOURCE_USER},
|
||||
data={CONF_ACCESS_TOKEN: MOCK_ACCESS_TOKEN},
|
||||
)
|
||||
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert result["title"] == MOCK_SERIAL
|
||||
assert result["data"] == {CONF_ACCESS_TOKEN: MOCK_ACCESS_TOKEN_JSON}
|
||||
assert result["title"] == MOCK_ACCESS_TOKEN_JSON["serialNumber"]
|
||||
assert result["data"] == {CONF_ACCESS_TOKEN: json.dumps(MOCK_ACCESS_TOKEN_JSON)}
|
||||
|
||||
|
||||
async def test_invalid_auth(hass: HomeAssistant) -> None:
|
||||
@ -44,7 +49,7 @@ async def test_invalid_auth(hass: HomeAssistant) -> None:
|
||||
with patch.object(Connection, "get_token", new=AsyncMock(return_value=None)):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": "user"},
|
||||
context={"source": config_entries.SOURCE_USER},
|
||||
data={CONF_ACCESS_TOKEN: MOCK_ACCESS_TOKEN},
|
||||
)
|
||||
|
||||
@ -56,7 +61,7 @@ async def test_invalid_token(hass: HomeAssistant) -> None:
|
||||
"""Test we handle invalid/malformed tokens."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": "user"},
|
||||
context={"source": config_entries.SOURCE_USER},
|
||||
data={CONF_ACCESS_TOKEN: "invalid_token"},
|
||||
)
|
||||
|
||||
@ -68,8 +73,8 @@ async def test_device_exists_abort(hass: HomeAssistant) -> None:
|
||||
"""Test we abort config flow if Smarla device already configured."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id=MOCK_SERIAL,
|
||||
source="user",
|
||||
unique_id=MOCK_ACCESS_TOKEN_JSON["serialNumber"],
|
||||
source=config_entries.SOURCE_USER,
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
@ -77,7 +82,7 @@ async def test_device_exists_abort(hass: HomeAssistant) -> None:
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": "user"},
|
||||
context={"source": config_entries.SOURCE_USER},
|
||||
data={CONF_ACCESS_TOKEN: MOCK_ACCESS_TOKEN},
|
||||
)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user