2021-04-25 17:20:21 +00:00
|
|
|
"""Entity representing a Sonos player."""
|
|
|
|
from __future__ import annotations
|
|
|
|
|
2021-05-28 10:07:58 +00:00
|
|
|
import datetime
|
2021-04-25 17:20:21 +00:00
|
|
|
import logging
|
|
|
|
|
|
|
|
from pysonos.core import SoCo
|
|
|
|
|
|
|
|
import homeassistant.helpers.device_registry as dr
|
2021-04-27 14:52:05 +00:00
|
|
|
from homeassistant.helpers.dispatcher import (
|
|
|
|
async_dispatcher_connect,
|
|
|
|
async_dispatcher_send,
|
|
|
|
)
|
2021-05-01 22:37:19 +00:00
|
|
|
from homeassistant.helpers.entity import DeviceInfo, Entity
|
2021-04-25 17:20:21 +00:00
|
|
|
|
2021-04-27 14:52:05 +00:00
|
|
|
from .const import (
|
|
|
|
DOMAIN,
|
|
|
|
SONOS_ENTITY_CREATED,
|
2021-05-16 09:11:35 +00:00
|
|
|
SONOS_HOUSEHOLD_UPDATED,
|
2021-05-28 10:07:58 +00:00
|
|
|
SONOS_POLL_UPDATE,
|
2021-04-27 14:52:05 +00:00
|
|
|
SONOS_STATE_UPDATED,
|
|
|
|
)
|
2021-04-25 17:20:21 +00:00
|
|
|
from .speaker import SonosSpeaker
|
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class SonosEntity(Entity):
|
|
|
|
"""Representation of a Sonos entity."""
|
|
|
|
|
2021-04-30 05:01:09 +00:00
|
|
|
def __init__(self, speaker: SonosSpeaker) -> None:
|
2021-04-25 17:20:21 +00:00
|
|
|
"""Initialize a SonosEntity."""
|
|
|
|
self.speaker = speaker
|
|
|
|
|
|
|
|
async def async_added_to_hass(self) -> None:
|
|
|
|
"""Handle common setup when added to hass."""
|
|
|
|
await self.speaker.async_seen()
|
|
|
|
|
|
|
|
self.async_on_remove(
|
|
|
|
async_dispatcher_connect(
|
|
|
|
self.hass,
|
2021-05-28 10:07:58 +00:00
|
|
|
f"{SONOS_POLL_UPDATE}-{self.soco.uid}",
|
|
|
|
self.async_poll,
|
2021-04-25 17:20:21 +00:00
|
|
|
)
|
|
|
|
)
|
|
|
|
self.async_on_remove(
|
|
|
|
async_dispatcher_connect(
|
|
|
|
self.hass,
|
|
|
|
f"{SONOS_STATE_UPDATED}-{self.soco.uid}",
|
2021-04-26 21:59:04 +00:00
|
|
|
self.async_write_ha_state,
|
2021-04-25 17:20:21 +00:00
|
|
|
)
|
|
|
|
)
|
2021-05-16 09:11:35 +00:00
|
|
|
self.async_on_remove(
|
|
|
|
async_dispatcher_connect(
|
|
|
|
self.hass,
|
|
|
|
f"{SONOS_HOUSEHOLD_UPDATED}-{self.soco.household_id}",
|
|
|
|
self.async_write_ha_state,
|
|
|
|
)
|
|
|
|
)
|
2021-05-11 17:36:40 +00:00
|
|
|
async_dispatcher_send(
|
|
|
|
self.hass, f"{SONOS_ENTITY_CREATED}-{self.soco.uid}", self.platform.domain
|
|
|
|
)
|
2021-04-25 17:20:21 +00:00
|
|
|
|
2021-05-28 10:07:58 +00:00
|
|
|
async def async_poll(self, now: datetime.datetime) -> None:
|
|
|
|
"""Poll the entity if subscriptions fail."""
|
|
|
|
if self.speaker.is_first_poll:
|
|
|
|
_LOGGER.warning(
|
|
|
|
"%s cannot reach [%s], falling back to polling, functionality may be limited",
|
|
|
|
self.speaker.zone_name,
|
|
|
|
self.speaker.subscription_address,
|
|
|
|
)
|
|
|
|
self.speaker.is_first_poll = False
|
|
|
|
await self.async_update() # pylint: disable=no-member
|
|
|
|
|
2021-04-25 17:20:21 +00:00
|
|
|
@property
|
|
|
|
def soco(self) -> SoCo:
|
|
|
|
"""Return the speaker SoCo instance."""
|
|
|
|
return self.speaker.soco
|
|
|
|
|
|
|
|
@property
|
2021-05-01 22:37:19 +00:00
|
|
|
def device_info(self) -> DeviceInfo:
|
2021-04-25 17:20:21 +00:00
|
|
|
"""Return information about the device."""
|
|
|
|
return {
|
|
|
|
"identifiers": {(DOMAIN, self.soco.uid)},
|
|
|
|
"name": self.speaker.zone_name,
|
|
|
|
"model": self.speaker.model_name.replace("Sonos ", ""),
|
|
|
|
"sw_version": self.speaker.version,
|
|
|
|
"connections": {(dr.CONNECTION_NETWORK_MAC, self.speaker.mac_address)},
|
|
|
|
"manufacturer": "Sonos",
|
|
|
|
"suggested_area": self.speaker.zone_name,
|
|
|
|
}
|
|
|
|
|
|
|
|
@property
|
|
|
|
def available(self) -> bool:
|
|
|
|
"""Return whether this device is available."""
|
|
|
|
return self.speaker.available
|
|
|
|
|
|
|
|
@property
|
|
|
|
def should_poll(self) -> bool:
|
|
|
|
"""Return that we should not be polled (we handle that internally)."""
|
|
|
|
return False
|