From 3050a5c896bf8361b82459de22d7696f8aed98bd Mon Sep 17 00:00:00 2001 From: Paul Tarjan Date: Fri, 19 Dec 2025 23:08:48 -1000 Subject: [PATCH] Support NVR Hikvision devices (#159253) --- homeassistant/components/hikvision/__init__.py | 10 ++++++++++ tests/components/hikvision/conftest.py | 11 +++++++++++ tests/components/hikvision/test_init.py | 13 +++++++++++++ 3 files changed, 34 insertions(+) diff --git a/homeassistant/components/hikvision/__init__.py b/homeassistant/components/hikvision/__init__.py index d1f539470e2..1fdd09c2edb 100644 --- a/homeassistant/components/hikvision/__init__.py +++ b/homeassistant/components/hikvision/__init__.py @@ -70,6 +70,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: HikvisionConfigEntry) -> device_type=device_type, ) + # For NVRs or devices with no detected events, try to fetch events from ISAPI + if device_type == "NVR" or not camera.current_event_states: + + def fetch_and_inject_nvr_events() -> None: + """Fetch and inject NVR events in a single executor job.""" + if nvr_events := camera.get_event_triggers(None): + camera.inject_events(nvr_events) + + await hass.async_add_executor_job(fetch_and_inject_nvr_events) + # Start the event stream await hass.async_add_executor_job(camera.start_stream) diff --git a/tests/components/hikvision/conftest.py b/tests/components/hikvision/conftest.py index 758906629ea..faa612e3180 100644 --- a/tests/components/hikvision/conftest.py +++ b/tests/components/hikvision/conftest.py @@ -82,9 +82,20 @@ def mock_hikcamera() -> Generator[MagicMock]: None, "2024-01-01T00:00:00Z", ) + camera.get_event_triggers.return_value = {} yield hikcamera_mock +@pytest.fixture +def mock_hik_nvr(mock_hikcamera: MagicMock) -> MagicMock: + """Return a mocked HikCamera configured as an NVR.""" + camera = mock_hikcamera.return_value + camera.get_type = "NVR" + camera.current_event_states = {} + camera.get_event_triggers.return_value = {"Motion": [1, 2]} + return mock_hikcamera + + @pytest.fixture async def init_integration( hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_hikcamera: MagicMock diff --git a/tests/components/hikvision/test_init.py b/tests/components/hikvision/test_init.py index 389fbf71183..b1a0e50dab2 100644 --- a/tests/components/hikvision/test_init.py +++ b/tests/components/hikvision/test_init.py @@ -89,3 +89,16 @@ async def test_setup_entry_no_device_id( await hass.async_block_till_done() assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY + + +async def test_setup_entry_nvr_fetches_events( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_hik_nvr: MagicMock, +) -> None: + """Test setup fetches NVR events for NVR devices.""" + await setup_integration(hass, mock_config_entry) + + assert mock_config_entry.state is ConfigEntryState.LOADED + mock_hik_nvr.return_value.get_event_triggers.assert_called_once() + mock_hik_nvr.return_value.inject_events.assert_called_once()