Skip to content

Commit

Permalink
Refactor Snapcast client and group classes to use a common base clase (
Browse files Browse the repository at this point in the history
…#124499)

Co-authored-by: Joost Lekkerkerker <[email protected]>
  • Loading branch information
mill1000 and joostlek authored Dec 4, 2024
1 parent b6b340a commit b3ff8f5
Show file tree
Hide file tree
Showing 5 changed files with 327 additions and 343 deletions.
19 changes: 5 additions & 14 deletions homeassistant/components/snapcast/__init__.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,28 @@
"""Snapcast Integration."""

import logging

import snapcast.control

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PORT
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady

from .const import DOMAIN, PLATFORMS
from .server import HomeAssistantSnapcast

_LOGGER = logging.getLogger(__name__)
from .coordinator import SnapcastUpdateCoordinator


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Snapcast from a config entry."""
host = entry.data[CONF_HOST]
port = entry.data[CONF_PORT]
coordinator = SnapcastUpdateCoordinator(hass, host, port)

try:
server = await snapcast.control.create_server(
hass.loop, host, port, reconnect=True
)
await coordinator.async_config_entry_first_refresh()
except OSError as ex:
raise ConfigEntryNotReady(
f"Could not connect to Snapcast server at {host}:{port}"
) from ex

hass.data.setdefault(DOMAIN, {})[entry.entry_id] = HomeAssistantSnapcast(
hass, server, f"{host}:{port}", entry.entry_id
)

hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

return True
Expand Down
72 changes: 72 additions & 0 deletions homeassistant/components/snapcast/coordinator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""Data update coordinator for Snapcast server."""

from __future__ import annotations

import logging

from snapcast.control.server import Snapserver

from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed

_LOGGER = logging.getLogger(__name__)


class SnapcastUpdateCoordinator(DataUpdateCoordinator[None]):
"""Data update coordinator for pushed data from Snapcast server."""

def __init__(self, hass: HomeAssistant, host: str, port: int) -> None:
"""Initialize coordinator."""
super().__init__(
hass,
logger=_LOGGER,
name=f"{host}:{port}",
update_interval=None, # Disable update interval as server pushes
)

self._server = Snapserver(hass.loop, host, port, True)
self.last_update_success = False

self._server.set_on_update_callback(self._on_update)
self._server.set_new_client_callback(self._on_update)
self._server.set_on_connect_callback(self._on_connect)
self._server.set_on_disconnect_callback(self._on_disconnect)

def _on_update(self) -> None:
"""Snapserver on_update callback."""
# Assume availability if an update is received.
self.last_update_success = True
self.async_update_listeners()

def _on_connect(self) -> None:
"""Snapserver on_connect callback."""
self.last_update_success = True
self.async_update_listeners()

def _on_disconnect(self, ex):
"""Snapsever on_disconnect callback."""
self.async_set_update_error(ex)

async def _async_setup(self) -> None:
"""Perform async setup for the coordinator."""
# Start the server
try:
await self._server.start()
except OSError as ex:
raise UpdateFailed from ex

async def _async_update_data(self) -> None:
"""Empty update method since data is pushed."""

async def disconnect(self) -> None:
"""Disconnect from the server."""
self._server.set_on_update_callback(None)
self._server.set_on_connect_callback(None)
self._server.set_on_disconnect_callback(None)
self._server.set_new_client_callback(None)
self._server.stop()

@property
def server(self) -> Snapserver:
"""Get the Snapserver object."""
return self._server
11 changes: 11 additions & 0 deletions homeassistant/components/snapcast/entity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""Coordinator entity for Snapcast server."""

from __future__ import annotations

from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .coordinator import SnapcastUpdateCoordinator


class SnapcastCoordinatorEntity(CoordinatorEntity[SnapcastUpdateCoordinator]):
"""Coordinator entity for Snapcast."""
Loading

0 comments on commit b3ff8f5

Please sign in to comment.