mirror of
https://github.com/home-assistant/core.git
synced 2025-07-07 21:37:07 +00:00
Add type hints to ps4 media player (#89236)
This commit is contained in:
parent
5ee383456f
commit
ee6f969c2a
@ -2,6 +2,7 @@
|
||||
import asyncio
|
||||
from contextlib import suppress
|
||||
import logging
|
||||
from typing import Any, cast
|
||||
|
||||
from pyps4_2ndscreen.errors import NotReady, PSDataIncomplete
|
||||
from pyps4_2ndscreen.media_art import TYPE_APP as PS_TYPE_APP
|
||||
@ -27,6 +28,7 @@ from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.helpers.entity import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.util.json import JsonObjectType
|
||||
|
||||
from . import format_unique_id, load_games, save_games
|
||||
from .const import (
|
||||
@ -52,12 +54,12 @@ async def async_setup_entry(
|
||||
) -> None:
|
||||
"""Set up PS4 from a config entry."""
|
||||
config = config_entry
|
||||
creds = config.data[CONF_TOKEN]
|
||||
creds: str = config.data[CONF_TOKEN]
|
||||
device_list = []
|
||||
for device in config.data["devices"]:
|
||||
host = device[CONF_HOST]
|
||||
region = device[CONF_REGION]
|
||||
name = device[CONF_NAME]
|
||||
host: str = device[CONF_HOST]
|
||||
region: str = device[CONF_REGION]
|
||||
name: str = device[CONF_NAME]
|
||||
ps4 = pyps4.Ps4Async(host, creds, device_name=DEFAULT_ALIAS)
|
||||
device_list.append(PS4Device(config, name, host, region, ps4, creds))
|
||||
async_add_entities(device_list, update_before_add=True)
|
||||
@ -75,7 +77,15 @@ class PS4Device(MediaPlayerEntity):
|
||||
| MediaPlayerEntityFeature.SELECT_SOURCE
|
||||
)
|
||||
|
||||
def __init__(self, config, name, host, region, ps4, creds):
|
||||
def __init__(
|
||||
self,
|
||||
config: ConfigEntry,
|
||||
name: str,
|
||||
host: str,
|
||||
region: str,
|
||||
ps4: pyps4.Ps4Async,
|
||||
creds: str,
|
||||
) -> None:
|
||||
"""Initialize the ps4 device."""
|
||||
self._entry_id = config.entry_id
|
||||
self._ps4 = ps4
|
||||
@ -83,30 +93,30 @@ class PS4Device(MediaPlayerEntity):
|
||||
self._attr_name = name
|
||||
self._region = region
|
||||
self._creds = creds
|
||||
self._media_image = None
|
||||
self._games = {}
|
||||
self._media_image: str | None = None
|
||||
self._games: JsonObjectType = {}
|
||||
self._retry = 0
|
||||
self._disconnected = False
|
||||
|
||||
@callback
|
||||
def status_callback(self):
|
||||
def status_callback(self) -> None:
|
||||
"""Handle status callback. Parse status."""
|
||||
self._parse_status()
|
||||
self.async_write_ha_state()
|
||||
|
||||
@callback
|
||||
def subscribe_to_protocol(self):
|
||||
def subscribe_to_protocol(self) -> None:
|
||||
"""Notify protocol to callback with update changes."""
|
||||
self.hass.data[PS4_DATA].protocol.add_callback(self._ps4, self.status_callback)
|
||||
|
||||
@callback
|
||||
def unsubscribe_to_protocol(self):
|
||||
def unsubscribe_to_protocol(self) -> None:
|
||||
"""Notify protocol to remove callback."""
|
||||
self.hass.data[PS4_DATA].protocol.remove_callback(
|
||||
self._ps4, self.status_callback
|
||||
)
|
||||
|
||||
def check_region(self):
|
||||
def check_region(self) -> None:
|
||||
"""Display logger msg if region is deprecated."""
|
||||
# Non-Breaking although data returned may be inaccurate.
|
||||
if self._region in deprecated_regions:
|
||||
@ -151,10 +161,11 @@ class PS4Device(MediaPlayerEntity):
|
||||
|
||||
self._parse_status()
|
||||
|
||||
def _parse_status(self):
|
||||
def _parse_status(self) -> None:
|
||||
"""Parse status."""
|
||||
if (status := self._ps4.status) is not None:
|
||||
self._games = load_games(self.hass, self.unique_id)
|
||||
status: dict[str, Any] | None = self._ps4.status
|
||||
if status is not None:
|
||||
self._games = load_games(self.hass, cast(str, self.unique_id))
|
||||
if self._games:
|
||||
self.get_source_list()
|
||||
|
||||
@ -193,28 +204,30 @@ class PS4Device(MediaPlayerEntity):
|
||||
def _use_saved(self) -> bool:
|
||||
"""Return True, Set media attrs if data is locked."""
|
||||
if self.media_content_id in self._games:
|
||||
store = self._games[self.media_content_id]
|
||||
store = cast(JsonObjectType, self._games[self.media_content_id])
|
||||
|
||||
# If locked get attributes from file.
|
||||
if store.get(ATTR_LOCKED):
|
||||
self._attr_media_title = store.get(ATTR_MEDIA_TITLE)
|
||||
self._attr_media_title = cast(str | None, store.get(ATTR_MEDIA_TITLE))
|
||||
self._attr_source = self._attr_media_title
|
||||
self._media_image = store.get(ATTR_MEDIA_IMAGE_URL)
|
||||
self._attr_media_content_type = store.get(ATTR_MEDIA_CONTENT_TYPE)
|
||||
self._media_image = cast(str | None, store.get(ATTR_MEDIA_IMAGE_URL))
|
||||
self._attr_media_content_type = cast(
|
||||
str | None, store.get(ATTR_MEDIA_CONTENT_TYPE)
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
def idle(self):
|
||||
def idle(self) -> None:
|
||||
"""Set states for state idle."""
|
||||
self.reset_title()
|
||||
self._attr_state = MediaPlayerState.IDLE
|
||||
|
||||
def state_standby(self):
|
||||
def state_standby(self) -> None:
|
||||
"""Set states for state standby."""
|
||||
self.reset_title()
|
||||
self._attr_state = MediaPlayerState.STANDBY
|
||||
|
||||
def state_unknown(self):
|
||||
def state_unknown(self) -> None:
|
||||
"""Set states for state unknown."""
|
||||
self.reset_title()
|
||||
self._attr_state = None
|
||||
@ -223,14 +236,14 @@ class PS4Device(MediaPlayerEntity):
|
||||
self._disconnected = True
|
||||
self._retry = 0
|
||||
|
||||
def reset_title(self):
|
||||
def reset_title(self) -> None:
|
||||
"""Update if there is no title."""
|
||||
self._attr_media_title = None
|
||||
self._attr_media_content_id = None
|
||||
self._attr_media_content_type = None
|
||||
self._attr_source = None
|
||||
|
||||
async def async_get_title_data(self, title_id, name):
|
||||
async def async_get_title_data(self, title_id: str, name: str) -> None:
|
||||
"""Get PS Store Data."""
|
||||
|
||||
app_name = None
|
||||
@ -272,10 +285,10 @@ class PS4Device(MediaPlayerEntity):
|
||||
await self.hass.async_add_executor_job(self.update_list)
|
||||
self.async_write_ha_state()
|
||||
|
||||
def update_list(self):
|
||||
def update_list(self) -> None:
|
||||
"""Update Game List, Correct data if different."""
|
||||
if self.media_content_id in self._games:
|
||||
store = self._games[self.media_content_id]
|
||||
store = cast(JsonObjectType, self._games[self.media_content_id])
|
||||
|
||||
if (
|
||||
store.get(ATTR_MEDIA_TITLE) != self.media_title
|
||||
@ -290,7 +303,7 @@ class PS4Device(MediaPlayerEntity):
|
||||
self._media_image,
|
||||
self._attr_media_content_type,
|
||||
)
|
||||
self._games = load_games(self.hass, self.unique_id)
|
||||
self._games = load_games(self.hass, cast(str, self.unique_id))
|
||||
|
||||
self.get_source_list()
|
||||
|
||||
@ -298,14 +311,22 @@ class PS4Device(MediaPlayerEntity):
|
||||
"""Parse data entry and update source list."""
|
||||
games = []
|
||||
for data in self._games.values():
|
||||
games.append(data[ATTR_MEDIA_TITLE])
|
||||
data = cast(JsonObjectType, data)
|
||||
games.append(cast(str, data[ATTR_MEDIA_TITLE]))
|
||||
self._attr_source_list = sorted(games)
|
||||
|
||||
def add_games(self, title_id, app_name, image, g_type, is_locked=False):
|
||||
def add_games(
|
||||
self,
|
||||
title_id: str | None,
|
||||
app_name: str | None,
|
||||
image: str | None,
|
||||
g_type: str | None,
|
||||
is_locked: bool = False,
|
||||
) -> None:
|
||||
"""Add games to list."""
|
||||
games = self._games
|
||||
if title_id is not None and title_id not in games:
|
||||
game = {
|
||||
game: JsonObjectType = {
|
||||
title_id: {
|
||||
ATTR_MEDIA_TITLE: app_name,
|
||||
ATTR_MEDIA_IMAGE_URL: image,
|
||||
@ -314,9 +335,9 @@ class PS4Device(MediaPlayerEntity):
|
||||
}
|
||||
}
|
||||
games.update(game)
|
||||
save_games(self.hass, games, self.unique_id)
|
||||
save_games(self.hass, games, cast(str, self.unique_id))
|
||||
|
||||
async def async_get_device_info(self, status):
|
||||
async def async_get_device_info(self, status: dict[str, Any] | None) -> None:
|
||||
"""Set device info for registry."""
|
||||
# If cannot get status on startup, assume info from registry.
|
||||
if status is None:
|
||||
@ -362,7 +383,7 @@ class PS4Device(MediaPlayerEntity):
|
||||
self.hass.data[PS4_DATA].devices.remove(self)
|
||||
|
||||
@property
|
||||
def entity_picture(self):
|
||||
def entity_picture(self) -> str | None:
|
||||
"""Return picture."""
|
||||
if (
|
||||
self.state == MediaPlayerState.PLAYING
|
||||
@ -376,7 +397,7 @@ class PS4Device(MediaPlayerEntity):
|
||||
return None
|
||||
|
||||
@property
|
||||
def media_image_url(self):
|
||||
def media_image_url(self) -> str | None:
|
||||
"""Image url of current playing media."""
|
||||
if self.media_content_id is None:
|
||||
return None
|
||||
@ -405,7 +426,8 @@ class PS4Device(MediaPlayerEntity):
|
||||
async def async_select_source(self, source: str) -> None:
|
||||
"""Select input source."""
|
||||
for title_id, data in self._games.items():
|
||||
game = data[ATTR_MEDIA_TITLE]
|
||||
data = cast(JsonObjectType, data)
|
||||
game = cast(str, data[ATTR_MEDIA_TITLE])
|
||||
if (
|
||||
source.lower().encode(encoding="utf-8")
|
||||
== game.lower().encode(encoding="utf-8")
|
||||
@ -421,10 +443,10 @@ class PS4Device(MediaPlayerEntity):
|
||||
_LOGGER.warning("Could not start title. '%s' is not in source list", source)
|
||||
return
|
||||
|
||||
async def async_send_command(self, command):
|
||||
async def async_send_command(self, command: str) -> None:
|
||||
"""Send Button Command."""
|
||||
await self.async_send_remote_control(command)
|
||||
|
||||
async def async_send_remote_control(self, command):
|
||||
async def async_send_remote_control(self, command: str) -> None:
|
||||
"""Send RC command."""
|
||||
await self._ps4.remote_control(command)
|
||||
|
Loading…
x
Reference in New Issue
Block a user