Skip to content

Commit

Permalink
Rewrite Yandex devices include code
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexxIT committed Apr 3, 2024
1 parent e1159ee commit 785639b
Show file tree
Hide file tree
Showing 14 changed files with 137 additions and 205 deletions.
41 changes: 17 additions & 24 deletions custom_components/yandex_station/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,24 @@
from .core.yandex_glagol import YandexIOListener
from .core.yandex_quasar import YandexQuasar
from .core.yandex_session import YandexSession
from .hass import hass_utils

_LOGGER = logging.getLogger(__name__)

MAIN_DOMAINS = ["media_player", "select"]
SUB_DOMAINS = [
PLATFORMS = [
"climate",
"light",
"humidifier",
"media_player",
"number",
"remote",
"select",
"switch",
"vacuum",
"sensor",
"water_heater",
]
PLATFORMS2 = ["media_player", "select"] # only for speakers

CONF_TTS_NAME = "tts_service_name"
CONF_DEBUG = "debug"
Expand Down Expand Up @@ -156,27 +159,29 @@ async def update_cookie_and_token(**kwargs):
speakers[did] = device

await _setup_intents(hass, quasar)
await _setup_include(hass, entry)
await _setup_devices(hass, quasar)

if not entry.update_listeners:
entry.add_update_listener(async_update_options)

quasar.start()

for domain in MAIN_DOMAINS:
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, domain)
)
platforms = PLATFORMS if hass_utils.incluce_devices(hass, entry) else PLATFORMS2
await hass.config_entries.async_forward_entry_setups(entry, platforms)

return True


async def async_update_options(hass: HomeAssistant, config_entry: ConfigEntry):
await hass.config_entries.async_reload(config_entry.entry_id)


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
quasar: YandexQuasar = hass.data[DOMAIN][entry.unique_id]
quasar.stop()

domains = MAIN_DOMAINS
if CONF_INCLUDE in hass.data[DOMAIN][DATA_CONFIG]:
domains += SUB_DOMAINS

return await hass.config_entries.async_unload_platforms(entry, domains)
platforms = PLATFORMS if hass_utils.incluce_devices(hass, entry) else PLATFORMS2
return await hass.config_entries.async_unload_platforms(entry, platforms)


async def _init_local_discovery(hass: HomeAssistant):
Expand Down Expand Up @@ -331,18 +336,6 @@ async def _setup_devices(hass: HomeAssistant, quasar: YandexQuasar):
device.update(upd)


async def _setup_include(hass: HomeAssistant, entry: ConfigEntry):
"""Setup additional devices from Yandex account."""
config = hass.data[DOMAIN][DATA_CONFIG]
if CONF_INCLUDE not in config:
return

for domain in SUB_DOMAINS:
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, domain)
)


async def async_remove_config_entry_device(
hass: HomeAssistant, entry: ConfigEntry, device: dr.DeviceEntry
) -> bool:
Expand Down
16 changes: 6 additions & 10 deletions custom_components/yandex_station/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
ClimateEntityFeature,
HVACMode,
)
from homeassistant.const import CONF_INCLUDE, UnitOfTemperature
from homeassistant.const import UnitOfTemperature

from .core import utils
from .core.const import DATA_CONFIG, DOMAIN
from .core.entity import YandexEntity
from .core.yandex_quasar import YandexQuasar
from .hass import hass_utils

_LOGGER = logging.getLogger(__name__)

Expand All @@ -22,14 +21,11 @@


async def async_setup_entry(hass, entry, async_add_entities):
include = hass.data[DOMAIN][DATA_CONFIG][CONF_INCLUDE]
quasar = hass.data[DOMAIN][entry.unique_id]
entities = [
async_add_entities(
YandexClimate(quasar, device, config)
for device in quasar.devices
if (config := utils.device_include(device, include, INCLUDE_TYPES))
]
async_add_entities(entities, True)
for quasar, device, config in hass_utils.incluce_devices(hass, entry)
if device["type"] in INCLUDE_TYPES
)


def check_hvac_modes(item: dict) -> bool:
Expand Down
29 changes: 0 additions & 29 deletions custom_components/yandex_station/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,35 +419,6 @@ def decode_media_source(media_id: str) -> dict:
return dict(url.query)


INCLUDE_KEYS = ("id", "name", "type", "room_name", "skill_id")


def device_include(
device: dict, include: list[dict], types: list[str] = None
) -> dict | None:
if types and device["type"] not in types:
return None

for item in include:
if isinstance(item, str):
if item == device["name"]:
return {"name": item}
elif isinstance(item, dict):
# one and more INCLUDE_KEYS should match
if sum(item[k] == device.get(k) for k in INCLUDE_KEYS if k in item):
return item

return None


def instance_include(instance: dict, include: list[str], types: list[str]) -> bool:
if instance["type"] not in types:
return False
if include is None:
return True
return instance["parameters"].get("instance", "on") in include


def track_template(hass: HomeAssistant, template: str, update: Callable) -> Callable:
template = Template(template, hass)
update(template.async_render())
Expand Down
31 changes: 31 additions & 0 deletions custom_components/yandex_station/hass/hass_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_INCLUDE
from homeassistant.core import HomeAssistant

from ..core.const import DOMAIN, DATA_CONFIG
from ..core.yandex_quasar import YandexQuasar

INCLUDE_KEYS = ("id", "name", "type", "room_name", "skill_id")


def incluce_devices(
hass: HomeAssistant, config_entry: ConfigEntry
) -> list[tuple[YandexQuasar, dict, dict]]:
quasar: YandexQuasar = hass.data[DOMAIN][config_entry.unique_id]
config: dict = hass.data[DOMAIN][DATA_CONFIG]
includes = config.get(CONF_INCLUDE, []) + config_entry.options.get(CONF_INCLUDE, [])

devices = []

for conf in includes:
for device in quasar.devices:
if isinstance(conf, str):
if conf == device["name"] or conf == device["id"]:
devices.append((quasar, device, {}))
break
elif isinstance(conf, dict):
if any(conf[k] == device.get(k) for k in INCLUDE_KEYS if k in conf):
devices.append((quasar, device, conf))
break

return devices
17 changes: 5 additions & 12 deletions custom_components/yandex_station/humidifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,22 @@
HumidifierEntity,
HumidifierEntityFeature,
)
from homeassistant.const import CONF_INCLUDE
from homeassistant.helpers.event import async_track_template_result, TrackTemplate
from homeassistant.helpers.template import Template

from .core import utils
from .core.const import DATA_CONFIG, DOMAIN
from .core.entity import YandexEntity
from .core.yandex_quasar import YandexQuasar
from .hass import hass_utils

_LOGGER = logging.getLogger(__name__)

INCLUDE_TYPES = ["devices.types.humidifier"]


async def async_setup_entry(hass, entry, async_add_entities):
include = hass.data[DOMAIN][DATA_CONFIG][CONF_INCLUDE]
quasar = hass.data[DOMAIN][entry.unique_id]
entities = [
async_add_entities(
YandexHumidifier(quasar, device, config)
for device in quasar.devices
if (config := utils.device_include(device, include, INCLUDE_TYPES))
]
async_add_entities(entities)
for quasar, device, config in hass_utils.incluce_devices(hass, entry)
if device["type"] in INCLUDE_TYPES
)


# noinspection PyAbstractClass
Expand Down
17 changes: 6 additions & 11 deletions custom_components/yandex_station/light.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
from homeassistant.components.light import ColorMode, LightEntity, LightEntityFeature
from homeassistant.const import CONF_INCLUDE

from .core import utils
from .core.const import DATA_CONFIG, DOMAIN
from .core.entity import YandexEntity
from .hass import hass_utils

INCLUDE_TYPES = ["devices.types.light"]


async def async_setup_entry(hass, entry, async_add_entities):
include = hass.data[DOMAIN][DATA_CONFIG][CONF_INCLUDE]
quasar = hass.data[DOMAIN][entry.unique_id]
entities = [
YandexLight(quasar, device)
for device in quasar.devices
if utils.device_include(device, include, INCLUDE_TYPES)
]
async_add_entities(entities, True)
async_add_entities(
YandexLight(quasar, device, config)
for quasar, device, config in hass_utils.incluce_devices(hass, entry)
if device["type"] in INCLUDE_TYPES
)


def conv(value: int, src_min: int, src_max: int, dst_min: int, dst_max: int) -> int:
Expand Down
17 changes: 6 additions & 11 deletions custom_components/yandex_station/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
MediaPlayerState,
MediaType,
)
from homeassistant.const import CONF_INCLUDE

from .core import utils
from .core.const import CONF_INTENTS, DATA_CONFIG, DOMAIN
from .core.const import CONF_INTENTS, DOMAIN
from .core.entity import YandexEntity
from .core.yandex_quasar import YandexQuasar
from .core.yandex_station import YandexStation, YandexModule
from .hass import hass_utils

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -42,16 +42,11 @@ async def async_setup_entry(hass, entry, async_add_entities):
async_add_entities(entities, True)

# add Quasar TVs
if CONF_INCLUDE not in hass.data[DOMAIN][DATA_CONFIG]:
return

include = hass.data[DOMAIN][DATA_CONFIG][CONF_INCLUDE]
entities = [
async_add_entities(
YandexMediaPlayer(quasar, device, config)
for device in quasar.devices
if (config := utils.device_include(device, include, INCLUDE_TYPES))
]
async_add_entities(entities, True)
for quasar, device, config in hass_utils.incluce_devices(hass, entry)
if device["type"] in INCLUDE_TYPES
)


# noinspection PyUnusedLocal
Expand Down
27 changes: 10 additions & 17 deletions custom_components/yandex_station/number.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import logging

from homeassistant.components.number import NumberEntity
from homeassistant.const import CONF_INCLUDE, UnitOfTemperature
from homeassistant.const import UnitOfTemperature

from .core import utils
from .core.const import DATA_CONFIG, DOMAIN
from .core.entity import YandexCustomEntity
from .hass import hass_utils

_LOGGER = logging.getLogger(__name__)

Expand All @@ -15,24 +15,17 @@


async def async_setup_entry(hass, entry, async_add_entities):
include = hass.data[DOMAIN][DATA_CONFIG][CONF_INCLUDE]
quasar = hass.data[DOMAIN][entry.unique_id]

entities = []

for device in quasar.devices:
# compare device name/id/room/etc
if not (config := utils.device_include(device, include)):
continue

if not (instances := config.get("capabilities")):
continue

for config in device["capabilities"]:
if utils.instance_include(config, instances, INCLUDE_CAPABILITIES):
entities.append(YandexCustomNumber(quasar, device, config))
for quasar, device, config in hass_utils.incluce_devices(hass, entry):
if instances := config.get("capabilities"):
for instance in device["capabilities"]:
if instance["type"] not in INCLUDE_CAPABILITIES:
continue
if instance["parameters"].get("instance", "on") in instances:
entities.append(YandexCustomNumber(quasar, device, instance))

async_add_entities(entities, True)
async_add_entities(entities)


# noinspection PyAbstractClass
Expand Down
15 changes: 5 additions & 10 deletions custom_components/yandex_station/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,21 @@
ATTR_NUM_REPEATS,
RemoteEntity,
)
from homeassistant.const import CONF_INCLUDE

from .core import utils
from .core.const import DATA_CONFIG, DOMAIN
from .core.yandex_quasar import YandexQuasar
from .hass import hass_utils

_LOGGER = logging.getLogger(__name__)

INCLUDE_TYPES = ["devices.types.other"]


async def async_setup_entry(hass, entry, async_add_entities):
include = hass.data[DOMAIN][DATA_CONFIG][CONF_INCLUDE]
quasar = hass.data[DOMAIN][entry.unique_id]
entities = [
async_add_entities(
YandexOther(quasar, device)
for device in quasar.devices
if utils.device_include(device, include, INCLUDE_TYPES)
]
async_add_entities(entities, True)
for quasar, device, _ in hass_utils.incluce_devices(hass, entry)
if device["type"] in INCLUDE_TYPES
)


# noinspection PyAbstractClass
Expand Down
Loading

0 comments on commit 785639b

Please sign in to comment.