mirror of
https://github.com/home-assistant/core.git
synced 2025-08-07 14:45:09 +02:00
Add unique_id to MPD (#120495)
This commit is contained in:
committed by
GitHub
parent
bff9d12cc0
commit
5a0841155e
@@ -31,6 +31,7 @@ from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_PORT
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
@@ -129,7 +130,7 @@ async def async_setup_entry(
|
||||
entry.data[CONF_HOST],
|
||||
entry.data[CONF_PORT],
|
||||
entry.data.get(CONF_PASSWORD),
|
||||
entry.title,
|
||||
entry.entry_id,
|
||||
)
|
||||
],
|
||||
True,
|
||||
@@ -140,23 +141,26 @@ class MpdDevice(MediaPlayerEntity):
|
||||
"""Representation of a MPD server."""
|
||||
|
||||
_attr_media_content_type = MediaType.MUSIC
|
||||
_attr_has_entity_name = True
|
||||
_attr_name = None
|
||||
|
||||
def __init__(self, server, port, password, name):
|
||||
def __init__(
|
||||
self, server: str, port: int, password: str | None, unique_id: str
|
||||
) -> None:
|
||||
"""Initialize the MPD device."""
|
||||
self.server = server
|
||||
self.port = port
|
||||
self._name = name
|
||||
self._attr_unique_id = unique_id
|
||||
self._attr_device_info = DeviceInfo(
|
||||
identifiers={(DOMAIN, unique_id)},
|
||||
entry_type=DeviceEntryType.SERVICE,
|
||||
)
|
||||
self.password = password
|
||||
|
||||
self._status = {}
|
||||
self._status: dict[str, Any] = {}
|
||||
self._currentsong = None
|
||||
self._playlists = None
|
||||
self._currentplaylist = None
|
||||
self._is_available = None
|
||||
self._muted = False
|
||||
self._current_playlist: str | None = None
|
||||
self._muted_volume = None
|
||||
self._media_position_updated_at = None
|
||||
self._media_position = None
|
||||
self._media_image_hash = None
|
||||
# Track if the song changed so image doesn't have to be loaded every update.
|
||||
self._media_image_file = None
|
||||
@@ -188,7 +192,7 @@ class MpdDevice(MediaPlayerEntity):
|
||||
raise TimeoutError("Connection attempt timed out") from error
|
||||
if self.password is not None:
|
||||
await self._client.password(self.password)
|
||||
self._is_available = True
|
||||
self._attr_available = True
|
||||
yield
|
||||
except (
|
||||
TimeoutError,
|
||||
@@ -199,12 +203,12 @@ class MpdDevice(MediaPlayerEntity):
|
||||
# Log a warning during startup or when previously connected; for
|
||||
# subsequent errors a debug message is sufficient.
|
||||
log_level = logging.DEBUG
|
||||
if self._is_available is not False:
|
||||
if self._attr_available is not False:
|
||||
log_level = logging.WARNING
|
||||
LOGGER.log(
|
||||
log_level, "Error connecting to '%s': %s", self.server, error
|
||||
)
|
||||
self._is_available = False
|
||||
self._attr_available = False
|
||||
self._status = {}
|
||||
# Also yield on failure. Handling mpd.ConnectionErrors caused by
|
||||
# attempting to control a disconnected client is the
|
||||
@@ -228,24 +232,14 @@ class MpdDevice(MediaPlayerEntity):
|
||||
if isinstance(position, str) and ":" in position:
|
||||
position = position.split(":")[0]
|
||||
|
||||
if position is not None and self._media_position != position:
|
||||
self._media_position_updated_at = dt_util.utcnow()
|
||||
self._media_position = int(float(position))
|
||||
if position is not None and self._attr_media_position != position:
|
||||
self._attr_media_position_updated_at = dt_util.utcnow()
|
||||
self._attr_media_position = int(float(position))
|
||||
|
||||
await self._update_playlists()
|
||||
except (mpd.ConnectionError, ValueError) as error:
|
||||
LOGGER.debug("Error updating status: %s", error)
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return true if MPD is available and connected."""
|
||||
return self._is_available is True
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the device."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def state(self) -> MediaPlayerState:
|
||||
"""Return the media state."""
|
||||
@@ -260,11 +254,6 @@ class MpdDevice(MediaPlayerEntity):
|
||||
|
||||
return MediaPlayerState.OFF
|
||||
|
||||
@property
|
||||
def is_volume_muted(self):
|
||||
"""Boolean if volume is currently muted."""
|
||||
return self._muted
|
||||
|
||||
@property
|
||||
def media_content_id(self):
|
||||
"""Return the content ID of current playing media."""
|
||||
@@ -282,20 +271,6 @@ class MpdDevice(MediaPlayerEntity):
|
||||
|
||||
return None
|
||||
|
||||
@property
|
||||
def media_position(self):
|
||||
"""Position of current playing media in seconds.
|
||||
|
||||
This is returned as part of the mpd status rather than in the details
|
||||
of the current song.
|
||||
"""
|
||||
return self._media_position
|
||||
|
||||
@property
|
||||
def media_position_updated_at(self):
|
||||
"""Last valid time of media position."""
|
||||
return self._media_position_updated_at
|
||||
|
||||
@property
|
||||
def media_title(self):
|
||||
"""Return the title of current playing media."""
|
||||
@@ -436,7 +411,7 @@ class MpdDevice(MediaPlayerEntity):
|
||||
| MediaPlayerEntityFeature.VOLUME_STEP
|
||||
| MediaPlayerEntityFeature.VOLUME_MUTE
|
||||
)
|
||||
if self._playlists is not None:
|
||||
if self._attr_source_list is not None:
|
||||
supported |= MediaPlayerEntityFeature.SELECT_SOURCE
|
||||
|
||||
return supported
|
||||
@@ -444,7 +419,7 @@ class MpdDevice(MediaPlayerEntity):
|
||||
@property
|
||||
def source(self):
|
||||
"""Name of the current input source."""
|
||||
return self._currentplaylist
|
||||
return self._current_playlist
|
||||
|
||||
@property
|
||||
def source_list(self):
|
||||
@@ -459,12 +434,12 @@ class MpdDevice(MediaPlayerEntity):
|
||||
async def _update_playlists(self, **kwargs: Any) -> None:
|
||||
"""Update available MPD playlists."""
|
||||
try:
|
||||
self._playlists = []
|
||||
self._attr_source_list = []
|
||||
with suppress(mpd.ConnectionError):
|
||||
for playlist_data in await self._client.listplaylists():
|
||||
self._playlists.append(playlist_data["playlist"])
|
||||
self._attr_source_list.append(playlist_data["playlist"])
|
||||
except mpd.CommandError as error:
|
||||
self._playlists = None
|
||||
self._attr_source_list = None
|
||||
LOGGER.warning("Playlists could not be updated: %s:", error)
|
||||
|
||||
async def async_set_volume_level(self, volume: float) -> None:
|
||||
@@ -527,7 +502,7 @@ class MpdDevice(MediaPlayerEntity):
|
||||
await self.async_set_volume_level(0)
|
||||
elif self._muted_volume is not None:
|
||||
await self.async_set_volume_level(self._muted_volume)
|
||||
self._muted = mute
|
||||
self._attr_is_volume_muted = mute
|
||||
|
||||
async def async_play_media(
|
||||
self, media_type: MediaType | str, media_id: str, **kwargs: Any
|
||||
@@ -543,17 +518,17 @@ class MpdDevice(MediaPlayerEntity):
|
||||
|
||||
if media_type == MediaType.PLAYLIST:
|
||||
LOGGER.debug("Playing playlist: %s", media_id)
|
||||
if media_id in self._playlists:
|
||||
self._currentplaylist = media_id
|
||||
if self._attr_source_list and media_id in self._attr_source_list:
|
||||
self._current_playlist = media_id
|
||||
else:
|
||||
self._currentplaylist = None
|
||||
self._current_playlist = None
|
||||
LOGGER.warning("Unknown playlist name %s", media_id)
|
||||
await self._client.clear()
|
||||
await self._client.load(media_id)
|
||||
await self._client.play()
|
||||
else:
|
||||
await self._client.clear()
|
||||
self._currentplaylist = None
|
||||
self._current_playlist = None
|
||||
await self._client.add(media_id)
|
||||
await self._client.play()
|
||||
|
||||
|
Reference in New Issue
Block a user