mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 13:47:35 +00:00
Distinct sources per zone in Onkyo (#130547)
This commit is contained in:
parent
b5f6734197
commit
af1222e97b
@ -3,6 +3,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from functools import cache
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, Literal
|
from typing import Any, Literal
|
||||||
|
|
||||||
@ -19,6 +20,7 @@ from homeassistant.config_entries import SOURCE_IMPORT
|
|||||||
from homeassistant.const import CONF_HOST, CONF_NAME
|
from homeassistant.const import CONF_HOST, CONF_NAME
|
||||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant, callback
|
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant, callback
|
||||||
from homeassistant.data_entry_flow import FlowResultType
|
from homeassistant.data_entry_flow import FlowResultType
|
||||||
|
from homeassistant.exceptions import ServiceValidationError
|
||||||
from homeassistant.helpers import config_validation as cv, entity_registry as er
|
from homeassistant.helpers import config_validation as cv, entity_registry as er
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
||||||
@ -128,10 +130,17 @@ VIDEO_INFORMATION_MAPPING = [
|
|||||||
]
|
]
|
||||||
ISSUE_URL_PLACEHOLDER = "/config/integrations/dashboard/add?domain=onkyo"
|
ISSUE_URL_PLACEHOLDER = "/config/integrations/dashboard/add?domain=onkyo"
|
||||||
|
|
||||||
type InputLibValue = str | tuple[str, ...]
|
type LibValue = str | tuple[str, ...]
|
||||||
|
|
||||||
|
|
||||||
def _input_lib_cmds(zone: str) -> dict[InputSource, InputLibValue]:
|
def _get_single_lib_value(value: LibValue) -> str:
|
||||||
|
if isinstance(value, str):
|
||||||
|
return value
|
||||||
|
return value[0]
|
||||||
|
|
||||||
|
|
||||||
|
@cache
|
||||||
|
def _input_source_lib_mappings(zone: str) -> dict[InputSource, LibValue]:
|
||||||
match zone:
|
match zone:
|
||||||
case "main":
|
case "main":
|
||||||
cmds = PYEISCP_COMMANDS["main"]["SLI"]
|
cmds = PYEISCP_COMMANDS["main"]["SLI"]
|
||||||
@ -142,7 +151,7 @@ def _input_lib_cmds(zone: str) -> dict[InputSource, InputLibValue]:
|
|||||||
case "zone4":
|
case "zone4":
|
||||||
cmds = PYEISCP_COMMANDS["zone4"]["SL4"]
|
cmds = PYEISCP_COMMANDS["zone4"]["SL4"]
|
||||||
|
|
||||||
result: dict[InputSource, InputLibValue] = {}
|
result: dict[InputSource, LibValue] = {}
|
||||||
for k, v in cmds["values"].items():
|
for k, v in cmds["values"].items():
|
||||||
try:
|
try:
|
||||||
source = InputSource(k)
|
source = InputSource(k)
|
||||||
@ -153,6 +162,11 @@ def _input_lib_cmds(zone: str) -> dict[InputSource, InputLibValue]:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
@cache
|
||||||
|
def _rev_input_source_lib_mappings(zone: str) -> dict[LibValue, InputSource]:
|
||||||
|
return {value: key for key, value in _input_source_lib_mappings(zone).items()}
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
@ -164,7 +178,7 @@ async def async_setup_platform(
|
|||||||
|
|
||||||
source_mapping: dict[str, InputSource] = {}
|
source_mapping: dict[str, InputSource] = {}
|
||||||
for zone in ZONES:
|
for zone in ZONES:
|
||||||
for source, source_lib in _input_lib_cmds(zone).items():
|
for source, source_lib in _input_source_lib_mappings(zone).items():
|
||||||
if isinstance(source_lib, str):
|
if isinstance(source_lib, str):
|
||||||
source_mapping.setdefault(source_lib, source)
|
source_mapping.setdefault(source_lib, source)
|
||||||
else:
|
else:
|
||||||
@ -353,14 +367,18 @@ class OnkyoMediaPlayer(MediaPlayerEntity):
|
|||||||
self._volume_resolution = volume_resolution
|
self._volume_resolution = volume_resolution
|
||||||
self._max_volume = max_volume
|
self._max_volume = max_volume
|
||||||
|
|
||||||
self._name_mapping = sources
|
self._source_lib_mapping = _input_source_lib_mappings(zone)
|
||||||
self._reverse_name_mapping = {value: key for key, value in sources.items()}
|
self._rev_source_lib_mapping = _rev_input_source_lib_mappings(zone)
|
||||||
self._lib_mapping = _input_lib_cmds(zone)
|
self._source_mapping = {
|
||||||
self._reverse_lib_mapping = {
|
key: value
|
||||||
value: key for key, value in self._lib_mapping.items()
|
for key, value in sources.items()
|
||||||
|
if key in self._source_lib_mapping
|
||||||
|
}
|
||||||
|
self._rev_source_mapping = {
|
||||||
|
value: key for key, value in self._source_mapping.items()
|
||||||
}
|
}
|
||||||
|
|
||||||
self._attr_source_list = list(sources.values())
|
self._attr_source_list = list(self._rev_source_mapping)
|
||||||
self._attr_extra_state_attributes = {}
|
self._attr_extra_state_attributes = {}
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
@ -429,12 +447,18 @@ class OnkyoMediaPlayer(MediaPlayerEntity):
|
|||||||
|
|
||||||
async def async_select_source(self, source: str) -> None:
|
async def async_select_source(self, source: str) -> None:
|
||||||
"""Select input source."""
|
"""Select input source."""
|
||||||
if self.source_list and source in self.source_list:
|
if not self.source_list or source not in self.source_list:
|
||||||
source_lib = self._lib_mapping[self._reverse_name_mapping[source]]
|
raise ServiceValidationError(
|
||||||
if isinstance(source_lib, str):
|
translation_domain=DOMAIN,
|
||||||
source_lib_single = source_lib
|
translation_key="invalid_source",
|
||||||
else:
|
translation_placeholders={
|
||||||
source_lib_single = source_lib[0]
|
"invalid_source": source,
|
||||||
|
"entity_id": self.entity_id,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
source_lib = self._source_lib_mapping[self._rev_source_mapping[source]]
|
||||||
|
source_lib_single = _get_single_lib_value(source_lib)
|
||||||
self._update_receiver(
|
self._update_receiver(
|
||||||
"input-selector" if self._zone == "main" else "selector", source_lib_single
|
"input-selector" if self._zone == "main" else "selector", source_lib_single
|
||||||
)
|
)
|
||||||
@ -448,7 +472,7 @@ class OnkyoMediaPlayer(MediaPlayerEntity):
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Play radio station by preset number."""
|
"""Play radio station by preset number."""
|
||||||
if self.source is not None:
|
if self.source is not None:
|
||||||
source = self._reverse_name_mapping[self.source]
|
source = self._rev_source_mapping[self.source]
|
||||||
if media_type.lower() == "radio" and source in DEFAULT_PLAYABLE_SOURCES:
|
if media_type.lower() == "radio" and source in DEFAULT_PLAYABLE_SOURCES:
|
||||||
self._update_receiver("preset", media_id)
|
self._update_receiver("preset", media_id)
|
||||||
|
|
||||||
@ -520,15 +544,17 @@ class OnkyoMediaPlayer(MediaPlayerEntity):
|
|||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _parse_source(self, source_lib: InputLibValue) -> None:
|
def _parse_source(self, source_lib: LibValue) -> None:
|
||||||
source = self._reverse_lib_mapping[source_lib]
|
source = self._rev_source_lib_mapping[source_lib]
|
||||||
if source in self._name_mapping:
|
if source in self._source_mapping:
|
||||||
self._attr_source = self._name_mapping[source]
|
self._attr_source = self._source_mapping[source]
|
||||||
return
|
return
|
||||||
|
|
||||||
source_meaning = source.value_meaning
|
source_meaning = source.value_meaning
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
'Input source "%s" not in source list: %s', source_meaning, self.entity_id
|
'Input source "%s" is invalid for entity: %s',
|
||||||
|
source_meaning,
|
||||||
|
self.entity_id,
|
||||||
)
|
)
|
||||||
self._attr_source = source_meaning
|
self._attr_source = source_meaning
|
||||||
|
|
||||||
|
@ -69,5 +69,10 @@
|
|||||||
"title": "The Onkyo YAML configuration import failed",
|
"title": "The Onkyo YAML configuration import failed",
|
||||||
"description": "Configuring Onkyo using YAML is being removed but there was a connection error when importing your YAML configuration for host {host}.\n\nEnsure the connection to the receiver works and restart Home Assistant to try again or remove the Onkyo YAML configuration from your configuration.yaml file and continue to [set up the integration]({url}) manually."
|
"description": "Configuring Onkyo using YAML is being removed but there was a connection error when importing your YAML configuration for host {host}.\n\nEnsure the connection to the receiver works and restart Home Assistant to try again or remove the Onkyo YAML configuration from your configuration.yaml file and continue to [set up the integration]({url}) manually."
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"exceptions": {
|
||||||
|
"invalid_source": {
|
||||||
|
"message": "Cannot select input source \"{invalid_source}\" for entity: {entity_id}."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user