Add Plex scan_clients button, enable autoscan (#67055)

Co-authored-by: Robert Svensson <Kane610@users.noreply.github.com>
pull/67101/head
jjlawren 2022-02-22 18:34:48 -06:00 committed by GitHub
parent d5a2381f07
commit 1658d530e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 129 additions and 2 deletions

View File

@ -25,10 +25,12 @@ from homeassistant.helpers.dispatcher import (
async_dispatcher_connect,
async_dispatcher_send,
)
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.network import is_internal_request
from homeassistant.helpers.typing import ConfigType
from .const import (
CLIENT_SCAN_INTERVAL,
CONF_SERVER,
CONF_SERVER_IDENTIFIER,
DISPATCHERS,
@ -247,6 +249,19 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
await hass.async_add_executor_job(get_plex_account, plex_server)
@callback
def scheduled_client_scan(_):
_LOGGER.debug("Scheduled scan for new clients on %s", plex_server.friendly_name)
async_dispatcher_send(hass, PLEX_UPDATE_PLATFORMS_SIGNAL.format(server_id))
entry.async_on_unload(
async_track_time_interval(
hass,
scheduled_client_scan,
CLIENT_SCAN_INTERVAL,
)
)
return True

View File

@ -0,0 +1,53 @@
"""Representation of Plex buttons."""
from __future__ import annotations
from homeassistant.components.button import ButtonEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.entity import DeviceInfo, EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import (
CONF_SERVER,
CONF_SERVER_IDENTIFIER,
DOMAIN,
PLEX_UPDATE_PLATFORMS_SIGNAL,
)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up Plex button from config entry."""
server_id: str = config_entry.data[CONF_SERVER_IDENTIFIER]
server_name: str = config_entry.data[CONF_SERVER]
async_add_entities([PlexScanClientsButton(server_id, server_name)])
class PlexScanClientsButton(ButtonEntity):
"""Representation of a scan_clients button entity."""
_attr_entity_category = EntityCategory.CONFIG
def __init__(self, server_id: str, server_name: str) -> None:
"""Initialize a scan_clients Plex button entity."""
self.server_id = server_id
self._attr_name = f"Scan Clients ({server_name})"
self._attr_unique_id = f"plex-scan_clients-{self.server_id}"
async def async_press(self) -> None:
"""Press the button."""
async_dispatcher_send(
self.hass, PLEX_UPDATE_PLATFORMS_SIGNAL.format(self.server_id)
)
@property
def device_info(self) -> DeviceInfo:
"""Return a device description for device registry."""
return DeviceInfo(
identifiers={(DOMAIN, self.server_id)},
manufacturer="Plex",
)

View File

@ -1,4 +1,6 @@
"""Constants for the Plex component."""
from datetime import timedelta
from homeassistant.const import Platform, __version__
DOMAIN = "plex"
@ -12,11 +14,12 @@ DEFAULT_VERIFY_SSL = True
PLEXTV_THROTTLE = 60
CLIENT_SCAN_INTERVAL = timedelta(minutes=10)
DEBOUNCE_TIMEOUT = 1
DISPATCHERS = "dispatchers"
GDM_DEBOUNCER = "gdm_debouncer"
GDM_SCANNER = "gdm_scanner"
PLATFORMS = frozenset([Platform.MEDIA_PLAYER, Platform.SENSOR])
PLATFORMS = frozenset([Platform.BUTTON, Platform.MEDIA_PLAYER, Platform.SENSOR])
PLATFORMS_COMPLETED = "platforms_completed"
PLAYER_SOURCE = "player_source"
SERVERS = "servers"

View File

@ -31,7 +31,10 @@ async def async_setup_services(hass):
await hass.async_add_executor_job(refresh_library, hass, service_call)
async def async_scan_clients_service(_: ServiceCall) -> None:
_LOGGER.debug("Scanning for new Plex clients")
_LOGGER.warning(
"This service is deprecated in favor of the scan_clients button entity. "
"Service calls will still work for now but the service will be removed in a future release"
)
for server_id in hass.data[DOMAIN][SERVERS]:
async_dispatcher_send(hass, PLEX_UPDATE_PLATFORMS_SIGNAL.format(server_id))

View File

@ -0,0 +1,36 @@
"""Tests for Plex buttons."""
from datetime import timedelta
from unittest.mock import patch
from homeassistant.components.button.const import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS
from homeassistant.components.plex.const import DEBOUNCE_TIMEOUT
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.util import dt
from tests.common import async_fire_time_changed
async def test_scan_clients_button_schedule(hass, setup_plex_server):
"""Test scan_clients button scheduled update."""
with patch(
"homeassistant.components.plex.server.PlexServer._async_update_platforms"
) as mock_scan_clients:
await setup_plex_server()
mock_scan_clients.reset_mock()
async_fire_time_changed(
hass,
dt.utcnow() + timedelta(seconds=DEBOUNCE_TIMEOUT),
)
assert await hass.services.async_call(
BUTTON_DOMAIN,
SERVICE_PRESS,
{
ATTR_ENTITY_ID: "button.scan_clients_plex_server_1",
},
True,
)
await hass.async_block_till_done()
assert mock_scan_clients.called

View File

@ -276,3 +276,20 @@ async def test_bad_token_with_tokenless_server(
# Ensure updates that rely on account return nothing
trigger_plex_update(mock_websocket)
await hass.async_block_till_done()
async def test_scan_clients_schedule(hass, setup_plex_server):
"""Test scan_clients scheduled update."""
with patch(
"homeassistant.components.plex.server.PlexServer._async_update_platforms"
) as mock_scan_clients:
await setup_plex_server()
mock_scan_clients.reset_mock()
async_fire_time_changed(
hass,
dt_util.utcnow() + const.CLIENT_SCAN_INTERVAL,
)
await hass.async_block_till_done()
assert mock_scan_clients.called