Update rokuecp to 0.13.1 (#65814)
parent
2da4d280b2
commit
15e5f516d2
|
@ -152,6 +152,7 @@ homeassistant.components.remote.*
|
||||||
homeassistant.components.renault.*
|
homeassistant.components.renault.*
|
||||||
homeassistant.components.ridwell.*
|
homeassistant.components.ridwell.*
|
||||||
homeassistant.components.rituals_perfume_genie.*
|
homeassistant.components.rituals_perfume_genie.*
|
||||||
|
homeassistant.components.roku.*
|
||||||
homeassistant.components.rpi_power.*
|
homeassistant.components.rpi_power.*
|
||||||
homeassistant.components.rtsp_to_webrtc.*
|
homeassistant.components.rtsp_to_webrtc.*
|
||||||
homeassistant.components.samsungtv.*
|
homeassistant.components.samsungtv.*
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""Support for Roku."""
|
"""Support for Roku."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from rokuecp import RokuConnectionError, RokuError
|
from rokuecp import RokuConnectionError, RokuError
|
||||||
|
@ -46,10 +47,10 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
return unload_ok
|
return unload_ok
|
||||||
|
|
||||||
|
|
||||||
def roku_exception_handler(func):
|
def roku_exception_handler(func: Callable) -> Callable:
|
||||||
"""Decorate Roku calls to handle Roku exceptions."""
|
"""Decorate Roku calls to handle Roku exceptions."""
|
||||||
|
|
||||||
async def handler(self, *args, **kwargs):
|
async def handler(self, *args, **kwargs) -> None: # type: ignore
|
||||||
try:
|
try:
|
||||||
await func(self, *args, **kwargs)
|
await func(self, *args, **kwargs)
|
||||||
except RokuConnectionError as error:
|
except RokuConnectionError as error:
|
||||||
|
|
|
@ -69,12 +69,12 @@ def get_thumbnail_url_full(
|
||||||
|
|
||||||
|
|
||||||
async def async_browse_media(
|
async def async_browse_media(
|
||||||
hass,
|
hass: HomeAssistant,
|
||||||
coordinator: RokuDataUpdateCoordinator,
|
coordinator: RokuDataUpdateCoordinator,
|
||||||
get_browse_image_url: GetBrowseImageUrlType,
|
get_browse_image_url: GetBrowseImageUrlType,
|
||||||
media_content_id: str | None,
|
media_content_id: str | None,
|
||||||
media_content_type: str | None,
|
media_content_type: str | None,
|
||||||
):
|
) -> BrowseMedia:
|
||||||
"""Browse media."""
|
"""Browse media."""
|
||||||
if media_content_id is None:
|
if media_content_id is None:
|
||||||
return await root_payload(
|
return await root_payload(
|
||||||
|
@ -113,7 +113,7 @@ async def root_payload(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
coordinator: RokuDataUpdateCoordinator,
|
coordinator: RokuDataUpdateCoordinator,
|
||||||
get_browse_image_url: GetBrowseImageUrlType,
|
get_browse_image_url: GetBrowseImageUrlType,
|
||||||
):
|
) -> BrowseMedia:
|
||||||
"""Return root payload for Roku."""
|
"""Return root payload for Roku."""
|
||||||
device = coordinator.data
|
device = coordinator.data
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ def item_payload(
|
||||||
item: dict,
|
item: dict,
|
||||||
coordinator: RokuDataUpdateCoordinator,
|
coordinator: RokuDataUpdateCoordinator,
|
||||||
get_browse_image_url: GetBrowseImageUrlType,
|
get_browse_image_url: GetBrowseImageUrlType,
|
||||||
):
|
) -> BrowseMedia:
|
||||||
"""
|
"""
|
||||||
Create response payload for a single media item.
|
Create response payload for a single media item.
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Any
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
from rokuecp import Roku, RokuError
|
from rokuecp import Roku, RokuError
|
||||||
|
@ -24,7 +25,7 @@ ERROR_UNKNOWN = "unknown"
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
async def validate_input(hass: HomeAssistant, data: dict) -> dict:
|
async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str, Any]:
|
||||||
"""Validate the user input allows us to connect.
|
"""Validate the user input allows us to connect.
|
||||||
|
|
||||||
Data has the keys from DATA_SCHEMA with values provided by the user.
|
Data has the keys from DATA_SCHEMA with values provided by the user.
|
||||||
|
@ -44,12 +45,14 @@ class RokuConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||||
|
|
||||||
VERSION = 1
|
VERSION = 1
|
||||||
|
|
||||||
def __init__(self):
|
discovery_info: dict[str, Any]
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
"""Set up the instance."""
|
"""Set up the instance."""
|
||||||
self.discovery_info = {}
|
self.discovery_info = {}
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _show_form(self, errors: dict | None = None) -> FlowResult:
|
def _show_form(self, errors: dict[str, Any] | None = None) -> FlowResult:
|
||||||
"""Show the form to the user."""
|
"""Show the form to the user."""
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
step_id="user",
|
step_id="user",
|
||||||
|
@ -57,7 +60,9 @@ class RokuConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||||
errors=errors or {},
|
errors=errors or {},
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_step_user(self, user_input: dict | None = None) -> FlowResult:
|
async def async_step_user(
|
||||||
|
self, user_input: dict[str, Any] | None = None
|
||||||
|
) -> FlowResult:
|
||||||
"""Handle a flow initialized by the user."""
|
"""Handle a flow initialized by the user."""
|
||||||
if not user_input:
|
if not user_input:
|
||||||
return self._show_form()
|
return self._show_form()
|
||||||
|
|
|
@ -17,7 +17,7 @@ class RokuEntity(CoordinatorEntity):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
device_id: str,
|
device_id: str | None,
|
||||||
coordinator: RokuDataUpdateCoordinator,
|
coordinator: RokuDataUpdateCoordinator,
|
||||||
description: EntityDescription | None = None,
|
description: EntityDescription | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -28,10 +28,11 @@ class RokuEntity(CoordinatorEntity):
|
||||||
if description is not None:
|
if description is not None:
|
||||||
self.entity_description = description
|
self.entity_description = description
|
||||||
self._attr_name = f"{coordinator.data.info.name} {description.name}"
|
self._attr_name = f"{coordinator.data.info.name} {description.name}"
|
||||||
self._attr_unique_id = f"{device_id}_{description.key}"
|
if device_id is not None:
|
||||||
|
self._attr_unique_id = f"{device_id}_{description.key}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_info(self) -> DeviceInfo:
|
def device_info(self) -> DeviceInfo | None:
|
||||||
"""Return device information about this Roku device."""
|
"""Return device information about this Roku device."""
|
||||||
if self._device_id is None:
|
if self._device_id is None:
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"domain": "roku",
|
"domain": "roku",
|
||||||
"name": "Roku",
|
"name": "Roku",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/roku",
|
"documentation": "https://www.home-assistant.io/integrations/roku",
|
||||||
"requirements": ["rokuecp==0.12.0"],
|
"requirements": ["rokuecp==0.13.1"],
|
||||||
"homekit": {
|
"homekit": {
|
||||||
"models": ["3810X", "4660X", "7820X", "C105X", "C135X"]
|
"models": ["3810X", "4660X", "7820X", "C105X", "C135X"]
|
||||||
},
|
},
|
||||||
|
|
|
@ -117,7 +117,9 @@ async def async_setup_entry(
|
||||||
class RokuMediaPlayer(RokuEntity, MediaPlayerEntity):
|
class RokuMediaPlayer(RokuEntity, MediaPlayerEntity):
|
||||||
"""Representation of a Roku media player on the network."""
|
"""Representation of a Roku media player on the network."""
|
||||||
|
|
||||||
def __init__(self, unique_id: str, coordinator: RokuDataUpdateCoordinator) -> None:
|
def __init__(
|
||||||
|
self, unique_id: str | None, coordinator: RokuDataUpdateCoordinator
|
||||||
|
) -> None:
|
||||||
"""Initialize the Roku device."""
|
"""Initialize the Roku device."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
coordinator=coordinator,
|
coordinator=coordinator,
|
||||||
|
@ -231,7 +233,7 @@ class RokuMediaPlayer(RokuEntity, MediaPlayerEntity):
|
||||||
@property
|
@property
|
||||||
def media_duration(self) -> int | None:
|
def media_duration(self) -> int | None:
|
||||||
"""Duration of current playing media in seconds."""
|
"""Duration of current playing media in seconds."""
|
||||||
if self._media_playback_trackable():
|
if self.coordinator.data.media is not None and self._media_playback_trackable():
|
||||||
return self.coordinator.data.media.duration
|
return self.coordinator.data.media.duration
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
@ -239,7 +241,7 @@ class RokuMediaPlayer(RokuEntity, MediaPlayerEntity):
|
||||||
@property
|
@property
|
||||||
def media_position(self) -> int | None:
|
def media_position(self) -> int | None:
|
||||||
"""Position of current playing media in seconds."""
|
"""Position of current playing media in seconds."""
|
||||||
if self._media_playback_trackable():
|
if self.coordinator.data.media is not None and self._media_playback_trackable():
|
||||||
return self.coordinator.data.media.position
|
return self.coordinator.data.media.position
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
@ -247,7 +249,7 @@ class RokuMediaPlayer(RokuEntity, MediaPlayerEntity):
|
||||||
@property
|
@property
|
||||||
def media_position_updated_at(self) -> dt.datetime | None:
|
def media_position_updated_at(self) -> dt.datetime | None:
|
||||||
"""When was the position of the current playing media valid."""
|
"""When was the position of the current playing media valid."""
|
||||||
if self._media_playback_trackable():
|
if self.coordinator.data.media is not None and self._media_playback_trackable():
|
||||||
return self.coordinator.data.media.at
|
return self.coordinator.data.media.at
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
@ -263,10 +265,12 @@ class RokuMediaPlayer(RokuEntity, MediaPlayerEntity):
|
||||||
@property
|
@property
|
||||||
def source_list(self) -> list:
|
def source_list(self) -> list:
|
||||||
"""List of available input sources."""
|
"""List of available input sources."""
|
||||||
return ["Home"] + sorted(app.name for app in self.coordinator.data.apps)
|
return ["Home"] + sorted(
|
||||||
|
app.name for app in self.coordinator.data.apps if app.name is not None
|
||||||
|
)
|
||||||
|
|
||||||
@roku_exception_handler
|
@roku_exception_handler
|
||||||
async def search(self, keyword):
|
async def search(self, keyword: str) -> None:
|
||||||
"""Emulate opening the search screen and entering the search keyword."""
|
"""Emulate opening the search screen and entering the search keyword."""
|
||||||
await self.coordinator.roku.search(keyword)
|
await self.coordinator.roku.search(keyword)
|
||||||
|
|
||||||
|
@ -343,7 +347,7 @@ class RokuMediaPlayer(RokuEntity, MediaPlayerEntity):
|
||||||
await self.coordinator.async_request_refresh()
|
await self.coordinator.async_request_refresh()
|
||||||
|
|
||||||
@roku_exception_handler
|
@roku_exception_handler
|
||||||
async def async_mute_volume(self, mute) -> None:
|
async def async_mute_volume(self, mute: bool) -> None:
|
||||||
"""Mute the volume."""
|
"""Mute the volume."""
|
||||||
await self.coordinator.roku.remote("volume_mute")
|
await self.coordinator.roku.remote("volume_mute")
|
||||||
await self.coordinator.async_request_refresh()
|
await self.coordinator.async_request_refresh()
|
||||||
|
@ -359,7 +363,9 @@ class RokuMediaPlayer(RokuEntity, MediaPlayerEntity):
|
||||||
await self.coordinator.roku.remote("volume_down")
|
await self.coordinator.roku.remote("volume_down")
|
||||||
|
|
||||||
@roku_exception_handler
|
@roku_exception_handler
|
||||||
async def async_play_media(self, media_type: str, media_id: str, **kwargs) -> None:
|
async def async_play_media(
|
||||||
|
self, media_type: str, media_id: str, **kwargs: Any
|
||||||
|
) -> None:
|
||||||
"""Play media from a URL or file, launch an application, or tune to a channel."""
|
"""Play media from a URL or file, launch an application, or tune to a channel."""
|
||||||
extra: dict[str, Any] = kwargs.get(ATTR_MEDIA_EXTRA) or {}
|
extra: dict[str, Any] = kwargs.get(ATTR_MEDIA_EXTRA) or {}
|
||||||
|
|
||||||
|
@ -433,7 +439,6 @@ class RokuMediaPlayer(RokuEntity, MediaPlayerEntity):
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
|
||||||
if appl is not None:
|
if appl is not None and appl.app_id is not None:
|
||||||
await self.coordinator.roku.launch(appl.app_id)
|
await self.coordinator.roku.launch(appl.app_id)
|
||||||
|
await self.coordinator.async_request_refresh()
|
||||||
await self.coordinator.async_request_refresh()
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
"""Support for the Roku remote."""
|
"""Support for the Roku remote."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.components.remote import ATTR_NUM_REPEATS, RemoteEntity
|
from homeassistant.components.remote import ATTR_NUM_REPEATS, RemoteEntity
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
@ -42,19 +44,19 @@ class RokuRemote(RokuEntity, RemoteEntity):
|
||||||
return not self.coordinator.data.state.standby
|
return not self.coordinator.data.state.standby
|
||||||
|
|
||||||
@roku_exception_handler
|
@roku_exception_handler
|
||||||
async def async_turn_on(self, **kwargs) -> None:
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||||
"""Turn the device on."""
|
"""Turn the device on."""
|
||||||
await self.coordinator.roku.remote("poweron")
|
await self.coordinator.roku.remote("poweron")
|
||||||
await self.coordinator.async_request_refresh()
|
await self.coordinator.async_request_refresh()
|
||||||
|
|
||||||
@roku_exception_handler
|
@roku_exception_handler
|
||||||
async def async_turn_off(self, **kwargs) -> None:
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||||
"""Turn the device off."""
|
"""Turn the device off."""
|
||||||
await self.coordinator.roku.remote("poweroff")
|
await self.coordinator.roku.remote("poweroff")
|
||||||
await self.coordinator.async_request_refresh()
|
await self.coordinator.async_request_refresh()
|
||||||
|
|
||||||
@roku_exception_handler
|
@roku_exception_handler
|
||||||
async def async_send_command(self, command: list, **kwargs) -> None:
|
async def async_send_command(self, command: list, **kwargs: Any) -> None:
|
||||||
"""Send a command to one device."""
|
"""Send a command to one device."""
|
||||||
num_repeats = kwargs[ATTR_NUM_REPEATS]
|
num_repeats = kwargs[ATTR_NUM_REPEATS]
|
||||||
|
|
||||||
|
|
11
mypy.ini
11
mypy.ini
|
@ -1489,6 +1489,17 @@ no_implicit_optional = true
|
||||||
warn_return_any = true
|
warn_return_any = true
|
||||||
warn_unreachable = true
|
warn_unreachable = true
|
||||||
|
|
||||||
|
[mypy-homeassistant.components.roku.*]
|
||||||
|
check_untyped_defs = true
|
||||||
|
disallow_incomplete_defs = true
|
||||||
|
disallow_subclassing_any = true
|
||||||
|
disallow_untyped_calls = true
|
||||||
|
disallow_untyped_decorators = true
|
||||||
|
disallow_untyped_defs = true
|
||||||
|
no_implicit_optional = true
|
||||||
|
warn_return_any = true
|
||||||
|
warn_unreachable = true
|
||||||
|
|
||||||
[mypy-homeassistant.components.rpi_power.*]
|
[mypy-homeassistant.components.rpi_power.*]
|
||||||
check_untyped_defs = true
|
check_untyped_defs = true
|
||||||
disallow_incomplete_defs = true
|
disallow_incomplete_defs = true
|
||||||
|
|
|
@ -2111,7 +2111,7 @@ rjpl==0.3.6
|
||||||
rocketchat-API==0.6.1
|
rocketchat-API==0.6.1
|
||||||
|
|
||||||
# homeassistant.components.roku
|
# homeassistant.components.roku
|
||||||
rokuecp==0.12.0
|
rokuecp==0.13.1
|
||||||
|
|
||||||
# homeassistant.components.roomba
|
# homeassistant.components.roomba
|
||||||
roombapy==1.6.5
|
roombapy==1.6.5
|
||||||
|
|
|
@ -1300,7 +1300,7 @@ rflink==0.0.62
|
||||||
ring_doorbell==0.7.2
|
ring_doorbell==0.7.2
|
||||||
|
|
||||||
# homeassistant.components.roku
|
# homeassistant.components.roku
|
||||||
rokuecp==0.12.0
|
rokuecp==0.13.1
|
||||||
|
|
||||||
# homeassistant.components.roomba
|
# homeassistant.components.roomba
|
||||||
roombapy==1.6.5
|
roombapy==1.6.5
|
||||||
|
|
Loading…
Reference in New Issue