Fix JVC Projector diagnostic entities showing unavailable (#183526)

This commit is contained in:
kernelpanic85
2026-09-30 11:28:59 +02:00
committed by GitHub
parent 120e94cf0e
commit 0d20c2f5e5
3 changed files with 90 additions and 6 deletions
@@ -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)
+33 -2
View File
@@ -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,
+41 -1
View File
@@ -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,