1
mirror of https://github.com/home-assistant/core synced 2024-08-31 05:57:13 +02:00

Fix kodi media_player unavailable at start (#41714)

This commit is contained in:
mvn23 2020-11-17 18:27:58 +01:00 committed by GitHub
parent 6a5546afc1
commit 212fb572e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 29 deletions

View File

@ -15,7 +15,6 @@ from homeassistant.const import (
EVENT_HOMEASSISTANT_STOP,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import (
@ -23,7 +22,6 @@ from .const import (
DATA_CONNECTION,
DATA_KODI,
DATA_REMOVE_LISTENER,
DATA_VERSION,
DOMAIN,
)
@ -48,13 +46,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
entry.data[CONF_SSL],
session=async_get_clientsession(hass),
)
kodi = Kodi(conn)
try:
await conn.connect()
kodi = Kodi(conn)
await kodi.ping()
raw_version = (await kodi.get_application_properties(["version"]))["version"]
except CannotConnectError as error:
raise ConfigEntryNotReady from error
except CannotConnectError:
pass
except InvalidAuthError as error:
_LOGGER.error(
"Login to %s failed: [%s]",
@ -68,12 +66,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
remove_stop_listener = hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _close)
version = f"{raw_version['major']}.{raw_version['minor']}"
hass.data[DOMAIN][entry.entry_id] = {
DATA_CONNECTION: conn,
DATA_KODI: kodi,
DATA_REMOVE_LISTENER: remove_stop_listener,
DATA_VERSION: version,
}
for component in PLATFORMS:

View File

@ -6,7 +6,6 @@ CONF_WS_PORT = "ws_port"
DATA_CONNECTION = "connection"
DATA_KODI = "kodi"
DATA_REMOVE_LISTENER = "remove_listener"
DATA_VERSION = "version"
DEFAULT_PORT = 8080
DEFAULT_SSL = False

View File

@ -48,13 +48,18 @@ from homeassistant.const import (
CONF_SSL,
CONF_TIMEOUT,
CONF_USERNAME,
EVENT_HOMEASSISTANT_STARTED,
STATE_IDLE,
STATE_OFF,
STATE_PAUSED,
STATE_PLAYING,
)
from homeassistant.core import callback
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.core import CoreState, callback
from homeassistant.helpers import (
config_validation as cv,
device_registry,
entity_platform,
)
from homeassistant.helpers.event import async_track_time_interval
import homeassistant.util.dt as dt_util
@ -63,7 +68,6 @@ from .const import (
CONF_WS_PORT,
DATA_CONNECTION,
DATA_KODI,
DATA_VERSION,
DEFAULT_PORT,
DEFAULT_SSL,
DEFAULT_TIMEOUT,
@ -91,7 +95,7 @@ DEPRECATED_TURN_OFF_ACTIONS = {
"shutdown": "System.Shutdown",
}
WEBSOCKET_WATCHDOG_INTERVAL = timedelta(minutes=3)
WEBSOCKET_WATCHDOG_INTERVAL = timedelta(seconds=10)
# https://github.com/xbmc/xbmc/blob/master/xbmc/media/MediaType.h
MEDIA_TYPES = {
@ -229,14 +233,13 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
data = hass.data[DOMAIN][config_entry.entry_id]
connection = data[DATA_CONNECTION]
version = data[DATA_VERSION]
kodi = data[DATA_KODI]
name = config_entry.data[CONF_NAME]
uid = config_entry.unique_id
if uid is None:
uid = config_entry.entry_id
entity = KodiEntity(connection, kodi, name, uid, version)
entity = KodiEntity(connection, kodi, name, uid)
async_add_entities([entity])
@ -264,13 +267,12 @@ def cmd(func):
class KodiEntity(MediaPlayerEntity):
"""Representation of a XBMC/Kodi device."""
def __init__(self, connection, kodi, name, uid, version):
def __init__(self, connection, kodi, name, uid):
"""Initialize the Kodi entity."""
self._connection = connection
self._kodi = kodi
self._name = name
self._unique_id = uid
self._version = version
self._players = None
self._properties = {}
self._item = {}
@ -347,7 +349,6 @@ class KodiEntity(MediaPlayerEntity):
"identifiers": {(DOMAIN, self.unique_id)},
"name": self.name,
"manufacturer": "Kodi",
"sw_version": self._version,
}
@property
@ -370,27 +371,43 @@ class KodiEntity(MediaPlayerEntity):
return
if self._connection.connected:
self._on_ws_connected()
await self._on_ws_connected()
self.async_on_remove(
async_track_time_interval(
self.hass,
self._async_connect_websocket_if_disconnected,
WEBSOCKET_WATCHDOG_INTERVAL,
async def start_watchdog(event=None):
"""Start websocket watchdog."""
await self._async_connect_websocket_if_disconnected()
self.async_on_remove(
async_track_time_interval(
self.hass,
self._async_connect_websocket_if_disconnected,
WEBSOCKET_WATCHDOG_INTERVAL,
)
)
)
@callback
def _on_ws_connected(self):
# If Home Assistant is already in a running state, start the watchdog
# immediately, else trigger it after Home Assistant has finished starting.
if self.hass.state == CoreState.running:
await start_watchdog()
else:
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED, start_watchdog)
async def _on_ws_connected(self):
"""Call after ws is connected."""
self._register_ws_callbacks()
version = (await self._kodi.get_application_properties(["version"]))["version"]
sw_version = f"{version['major']}.{version['minor']}"
dev_reg = await device_registry.async_get_registry(self.hass)
device = dev_reg.async_get_device({(DOMAIN, self.unique_id)}, [])
dev_reg.async_update_device(device.id, sw_version=sw_version)
self.async_schedule_update_ha_state(True)
async def _async_ws_connect(self):
"""Connect to Kodi via websocket protocol."""
try:
await self._connection.connect()
self._on_ws_connected()
await self._on_ws_connected()
except (jsonrpc_base.jsonrpc.TransportError, CannotConnectError):
_LOGGER.debug("Unable to connect to Kodi via websocket", exc_info=True)
await self._clear_connection(False)
@ -426,6 +443,7 @@ class KodiEntity(MediaPlayerEntity):
self._connection.server.System.OnRestart = self.async_on_quit
self._connection.server.System.OnSleep = self.async_on_quit
@cmd
async def async_update(self):
"""Retrieve latest state."""
if not self._connection.connected: