mirror of
https://github.com/home-assistant/core.git
synced 2026-10-06 14:29:21 -04:00
Fix JVC Projector diagnostic entities showing unavailable (#183526)
This commit is contained in:
@@ -156,7 +156,9 @@ class JvcProjectorDataUpdateCoordinator(DataUpdateCoordinator[dict[str, str]]):
|
||||
# Command has dependencies so defer until below
|
||||
deferred_commands.append(command)
|
||||
else:
|
||||
await self._update_command_state(command, new_state)
|
||||
await self._update_command_state(
|
||||
command, new_state, ignore_timeout=True
|
||||
)
|
||||
|
||||
# Deferred commands should have had dependencies met above
|
||||
for command in deferred_commands:
|
||||
@@ -167,7 +169,9 @@ class JvcProjectorDataUpdateCoordinator(DataUpdateCoordinator[dict[str, str]]):
|
||||
elif depend_command in self.state:
|
||||
value = self.state[depend_command]
|
||||
if value and value in depend_values:
|
||||
await self._update_command_state(command, new_state)
|
||||
await self._update_command_state(
|
||||
command, new_state, ignore_timeout=True
|
||||
)
|
||||
|
||||
elif self.state.get(cmd.Signal) != cmd.Signal.NONE:
|
||||
new_state[cmd.Signal] = cmd.Signal.NONE
|
||||
@@ -183,11 +187,20 @@ class JvcProjectorDataUpdateCoordinator(DataUpdateCoordinator[dict[str, str]]):
|
||||
return new_state
|
||||
|
||||
async def _update_command_state(
|
||||
self, command: type[Command], new_state: dict[type[Command], str]
|
||||
self,
|
||||
command: type[Command],
|
||||
new_state: dict[type[Command], str],
|
||||
*,
|
||||
ignore_timeout: bool = False,
|
||||
) -> str | None:
|
||||
"""Update state with the current value of a command."""
|
||||
try:
|
||||
value = await self.device.get(command)
|
||||
except JvcProjectorTimeoutError:
|
||||
if not ignore_timeout:
|
||||
raise
|
||||
_LOGGER.debug("Command %s timed out; retaining cached value", command.name)
|
||||
return self.state.get(command)
|
||||
except JvcProjectorCommandError as err:
|
||||
_LOGGER.warning("Command %s failed: %s", command.name, err)
|
||||
cached = self.state.get(command)
|
||||
|
||||
@@ -4,7 +4,8 @@ from datetime import timedelta
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
from jvcprojector import command as cmd
|
||||
from jvcprojector import JvcProjectorTimeoutError, command as cmd
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.jvc_projector.coordinator import INTERVAL_FAST
|
||||
from homeassistant.components.select import (
|
||||
@@ -12,7 +13,12 @@ from homeassistant.components.select import (
|
||||
DOMAIN as SELECT_DOMAIN,
|
||||
SERVICE_SELECT_OPTION,
|
||||
)
|
||||
from homeassistant.const import ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME, ATTR_OPTION
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
ATTR_FRIENDLY_NAME,
|
||||
ATTR_OPTION,
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
@@ -21,6 +27,7 @@ from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
INPUT_ENTITY_ID = "select.jvc_projector_input"
|
||||
HDR_PROCESSING_ENTITY_ID = "select.jvc_projector_hdr_processing"
|
||||
HDR_SENSOR_ENTITY_ID = "sensor.jvc_projector_hdr"
|
||||
MOTION_ENHANCE_ENTITY_ID = "select.jvc_projector_motion_enhance"
|
||||
|
||||
|
||||
async def test_input_select(
|
||||
@@ -47,6 +54,30 @@ async def test_input_select(
|
||||
mock_device.set.assert_called_once_with(cmd.Input, cmd.Input.HDMI2)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"mock_device",
|
||||
[{"fixture_override": {cmd.MotionEnhance: JvcProjectorTimeoutError}}],
|
||||
indirect=True,
|
||||
)
|
||||
async def test_motion_enhance_timeout_is_unknown(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
mock_device: MagicMock,
|
||||
mock_integration: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test a motion enhance timeout does not make the select unavailable."""
|
||||
entity_registry.async_update_entity(MOTION_ENHANCE_ENTITY_ID, disabled_by=None)
|
||||
|
||||
await hass.config_entries.async_reload(mock_integration.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
await mock_integration.runtime_data.async_refresh()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(MOTION_ENHANCE_ENTITY_ID)
|
||||
assert state is not None
|
||||
assert state.state == STATE_UNKNOWN
|
||||
|
||||
|
||||
async def test_enable_hdr_processing_select(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from jvcprojector import Command, command as cmd
|
||||
from jvcprojector import Command, JvcProjectorTimeoutError, command as cmd
|
||||
import pytest
|
||||
|
||||
from homeassistant.const import STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
@@ -46,6 +47,45 @@ async def test_diagnostic_sensor_state(
|
||||
assert state.state == expected_state
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"mock_device",
|
||||
[
|
||||
{
|
||||
"fixture_override": {
|
||||
cmd.Source: JvcProjectorTimeoutError,
|
||||
cmd.Colorimetry: JvcProjectorTimeoutError,
|
||||
cmd.LinkRate: JvcProjectorTimeoutError,
|
||||
}
|
||||
}
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
async def test_diagnostic_sensor_timeout_is_unknown(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
mock_device: MagicMock,
|
||||
mock_integration: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test optional diagnostic sensor timeouts do not make entities unavailable."""
|
||||
entity_ids = (
|
||||
"sensor.jvc_projector_resolution",
|
||||
"sensor.jvc_projector_colorimetry",
|
||||
"sensor.jvc_projector_link_rate",
|
||||
)
|
||||
for entity_id in entity_ids:
|
||||
entity_registry.async_update_entity(entity_id, disabled_by=None)
|
||||
|
||||
await hass.config_entries.async_reload(mock_integration.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
await mock_integration.runtime_data.async_refresh()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
for entity_id in entity_ids:
|
||||
state = hass.states.get(entity_id)
|
||||
assert state is not None
|
||||
assert state.state == STATE_UNKNOWN
|
||||
|
||||
|
||||
async def test_entity_state(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
|
||||
Reference in New Issue
Block a user