From 07a433a5164600c31581e12acc5a0dcd3d6b02d5 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Wed, 27 Jul 2022 12:52:13 +0200 Subject: [PATCH] Deprecate the OpenALPR Local integration (#75810) * Deprecate the OpenALPR Local integration * Remove tests --- .../openalpr_local/image_processing.py | 16 ++ .../components/openalpr_local/manifest.json | 1 + .../components/openalpr_local/strings.json | 8 + .../openalpr_local/translations/en.json | 8 + tests/components/openalpr_local/__init__.py | 1 - .../openalpr_local/test_image_processing.py | 142 ------------------ 6 files changed, 33 insertions(+), 143 deletions(-) create mode 100644 homeassistant/components/openalpr_local/strings.json create mode 100644 homeassistant/components/openalpr_local/translations/en.json delete mode 100644 tests/components/openalpr_local/__init__.py delete mode 100644 tests/components/openalpr_local/test_image_processing.py diff --git a/homeassistant/components/openalpr_local/image_processing.py b/homeassistant/components/openalpr_local/image_processing.py index e24af7c7d1f..06688b3b297 100644 --- a/homeassistant/components/openalpr_local/image_processing.py +++ b/homeassistant/components/openalpr_local/image_processing.py @@ -3,6 +3,7 @@ from __future__ import annotations import asyncio import io +import logging import re import voluptuous as vol @@ -13,6 +14,7 @@ from homeassistant.components.image_processing import ( PLATFORM_SCHEMA, ImageProcessingEntity, ) +from homeassistant.components.repairs import IssueSeverity, create_issue from homeassistant.const import ( ATTR_ENTITY_ID, CONF_ENTITY_ID, @@ -26,6 +28,8 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.util.async_ import run_callback_threadsafe +_LOGGER = logging.getLogger(__name__) + RE_ALPR_PLATE = re.compile(r"^plate\d*:") RE_ALPR_RESULT = re.compile(r"- (\w*)\s*confidence: (\d*.\d*)") @@ -69,6 +73,18 @@ async def async_setup_platform( discovery_info: DiscoveryInfoType | None = None, ) -> None: """Set up the OpenALPR local platform.""" + create_issue( + hass, + "openalpr_local", + "pending_removal", + breaks_in_ha_version="2022.10.0", + is_fixable=False, + severity=IssueSeverity.WARNING, + translation_key="pending_removal", + ) + _LOGGER.warning( + "The OpenALPR Local is deprecated and will be removed in Home Assistant 2022.10" + ) command = [config[CONF_ALPR_BIN], "-c", config[CONF_REGION], "-"] confidence = config[CONF_CONFIDENCE] diff --git a/homeassistant/components/openalpr_local/manifest.json b/homeassistant/components/openalpr_local/manifest.json index 8837d79369d..5243aa2b282 100644 --- a/homeassistant/components/openalpr_local/manifest.json +++ b/homeassistant/components/openalpr_local/manifest.json @@ -3,5 +3,6 @@ "name": "OpenALPR Local", "documentation": "https://www.home-assistant.io/integrations/openalpr_local", "codeowners": [], + "dependencies": ["repairs"], "iot_class": "local_push" } diff --git a/homeassistant/components/openalpr_local/strings.json b/homeassistant/components/openalpr_local/strings.json new file mode 100644 index 00000000000..b0dc80c6d06 --- /dev/null +++ b/homeassistant/components/openalpr_local/strings.json @@ -0,0 +1,8 @@ +{ + "issues": { + "pending_removal": { + "title": "The OpenALPR Local integration is being removed", + "description": "The OpenALPR Local integration is pending removal from Home Assistant and will no longer be available as of Home Assistant 2022.10.\n\nRemove the YAML configuration from your configuration.yaml file and restart Home Assistant to fix this issue." + } + } +} diff --git a/homeassistant/components/openalpr_local/translations/en.json b/homeassistant/components/openalpr_local/translations/en.json new file mode 100644 index 00000000000..9bc9035515b --- /dev/null +++ b/homeassistant/components/openalpr_local/translations/en.json @@ -0,0 +1,8 @@ +{ + "issues": { + "pending_removal": { + "description": "The OpenALPR Local integration is pending removal from Home Assistant and will no longer be available as of Home Assistant 2022.10.\n\nRemove the YAML configuration from your configuration.yaml file and restart Home Assistant to fix this issue.", + "title": "The OpenALPR Local integration is being removed" + } + } +} \ No newline at end of file diff --git a/tests/components/openalpr_local/__init__.py b/tests/components/openalpr_local/__init__.py deleted file mode 100644 index 36b7703491f..00000000000 --- a/tests/components/openalpr_local/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Tests for the openalpr_local component.""" diff --git a/tests/components/openalpr_local/test_image_processing.py b/tests/components/openalpr_local/test_image_processing.py deleted file mode 100644 index fefc42fe2ab..00000000000 --- a/tests/components/openalpr_local/test_image_processing.py +++ /dev/null @@ -1,142 +0,0 @@ -"""The tests for the openalpr local platform.""" -from unittest.mock import MagicMock, PropertyMock, patch - -import pytest - -import homeassistant.components.image_processing as ip -from homeassistant.const import ATTR_ENTITY_PICTURE -from homeassistant.setup import async_setup_component - -from tests.common import assert_setup_component, async_capture_events, load_fixture -from tests.components.image_processing import common - - -@pytest.fixture -async def setup_openalpr_local(hass): - """Set up openalpr local.""" - config = { - ip.DOMAIN: { - "platform": "openalpr_local", - "source": {"entity_id": "camera.demo_camera", "name": "test local"}, - "region": "eu", - }, - "camera": {"platform": "demo"}, - } - - with patch( - "homeassistant.components.openalpr_local.image_processing." - "OpenAlprLocalEntity.should_poll", - new_callable=PropertyMock(return_value=False), - ): - await async_setup_component(hass, ip.DOMAIN, config) - await hass.async_block_till_done() - - -@pytest.fixture -def url(hass, setup_openalpr_local): - """Return the camera URL.""" - state = hass.states.get("camera.demo_camera") - return f"{hass.config.internal_url}{state.attributes.get(ATTR_ENTITY_PICTURE)}" - - -@pytest.fixture -async def alpr_events(hass): - """Listen for events.""" - return async_capture_events(hass, "image_processing.found_plate") - - -@pytest.fixture -def popen_mock(): - """Get a Popen mock back.""" - async_popen = MagicMock() - - async def communicate(input=None): - """Communicate mock.""" - fixture = bytes(load_fixture("alpr_stdout.txt"), "utf-8") - return (fixture, None) - - async_popen.communicate = communicate - - with patch("asyncio.create_subprocess_exec", return_value=async_popen) as mock: - yield mock - - -async def test_setup_platform(hass): - """Set up platform with one entity.""" - config = { - ip.DOMAIN: { - "platform": "openalpr_local", - "source": {"entity_id": "camera.demo_camera"}, - "region": "eu", - }, - "camera": {"platform": "demo"}, - } - - with assert_setup_component(1, ip.DOMAIN): - await async_setup_component(hass, ip.DOMAIN, config) - await hass.async_block_till_done() - - assert hass.states.get("image_processing.openalpr_demo_camera") - - -async def test_setup_platform_name(hass): - """Set up platform with one entity and set name.""" - config = { - ip.DOMAIN: { - "platform": "openalpr_local", - "source": {"entity_id": "camera.demo_camera", "name": "test local"}, - "region": "eu", - }, - "camera": {"platform": "demo"}, - } - - with assert_setup_component(1, ip.DOMAIN): - await async_setup_component(hass, ip.DOMAIN, config) - await hass.async_block_till_done() - - assert hass.states.get("image_processing.test_local") - - -async def test_setup_platform_without_region(hass): - """Set up platform with one entity without region.""" - config = { - ip.DOMAIN: { - "platform": "openalpr_local", - "source": {"entity_id": "camera.demo_camera"}, - }, - "camera": {"platform": "demo"}, - } - - with assert_setup_component(0, ip.DOMAIN): - await async_setup_component(hass, ip.DOMAIN, config) - await hass.async_block_till_done() - - -async def test_openalpr_process_image( - setup_openalpr_local, - url, - hass, - alpr_events, - popen_mock, - aioclient_mock, -): - """Set up and scan a picture and test plates from event.""" - aioclient_mock.get(url, content=b"image") - - common.async_scan(hass, entity_id="image_processing.test_local") - await hass.async_block_till_done() - - state = hass.states.get("image_processing.test_local") - - assert popen_mock.called - assert len(alpr_events) == 5 - assert state.attributes.get("vehicles") == 1 - assert state.state == "PE3R2X" - - event_data = [ - event.data for event in alpr_events if event.data.get("plate") == "PE3R2X" - ] - assert len(event_data) == 1 - assert event_data[0]["plate"] == "PE3R2X" - assert event_data[0]["confidence"] == float(98.9371) - assert event_data[0]["entity_id"] == "image_processing.test_local"