mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 02:37:08 +00:00
Improve type hints in image-processing (#78351)
This commit is contained in:
parent
6256d07255
commit
458ddb6f4b
@ -1,11 +1,14 @@
|
|||||||
"""Provides functionality to interact with image processing services."""
|
"""Provides functionality to interact with image processing services."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
from typing import Final, TypedDict, final
|
from typing import Any, Final, TypedDict, final
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components.camera import Image
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ENTITY_ID,
|
ATTR_ENTITY_ID,
|
||||||
ATTR_NAME,
|
ATTR_NAME,
|
||||||
@ -22,8 +25,6 @@ from homeassistant.helpers.entity_component import EntityComponent
|
|||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.util.async_ import run_callback_threadsafe
|
from homeassistant.util.async_ import run_callback_threadsafe
|
||||||
|
|
||||||
# mypy: allow-untyped-defs, no-check-untyped-defs
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
DOMAIN = "image_processing"
|
DOMAIN = "image_processing"
|
||||||
@ -44,7 +45,7 @@ ATTR_CONFIDENCE: Final = "confidence"
|
|||||||
ATTR_FACES = "faces"
|
ATTR_FACES = "faces"
|
||||||
ATTR_GENDER = "gender"
|
ATTR_GENDER = "gender"
|
||||||
ATTR_GLASSES = "glasses"
|
ATTR_GLASSES = "glasses"
|
||||||
ATTR_MOTION = "motion"
|
ATTR_MOTION: Final = "motion"
|
||||||
ATTR_TOTAL_FACES = "total_faces"
|
ATTR_TOTAL_FACES = "total_faces"
|
||||||
|
|
||||||
CONF_CONFIDENCE = "confidence"
|
CONF_CONFIDENCE = "confidence"
|
||||||
@ -113,24 +114,24 @@ class ImageProcessingEntity(Entity):
|
|||||||
timeout = DEFAULT_TIMEOUT
|
timeout = DEFAULT_TIMEOUT
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def camera_entity(self):
|
def camera_entity(self) -> str | None:
|
||||||
"""Return camera entity id from process pictures."""
|
"""Return camera entity id from process pictures."""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def confidence(self):
|
def confidence(self) -> float | None:
|
||||||
"""Return minimum confidence for do some things."""
|
"""Return minimum confidence for do some things."""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def process_image(self, image):
|
def process_image(self, image: Image) -> None:
|
||||||
"""Process image."""
|
"""Process image."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
async def async_process_image(self, image):
|
async def async_process_image(self, image: Image) -> None:
|
||||||
"""Process image."""
|
"""Process image."""
|
||||||
return await self.hass.async_add_executor_job(self.process_image, image)
|
return await self.hass.async_add_executor_job(self.process_image, image)
|
||||||
|
|
||||||
async def async_update(self):
|
async def async_update(self) -> None:
|
||||||
"""Update image and process it.
|
"""Update image and process it.
|
||||||
|
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
@ -160,9 +161,9 @@ class ImageProcessingFaceEntity(ImageProcessingEntity):
|
|||||||
self.total_faces = 0
|
self.total_faces = 0
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self) -> str | int | None:
|
||||||
"""Return the state of the entity."""
|
"""Return the state of the entity."""
|
||||||
confidence = 0
|
confidence: float = 0
|
||||||
state = None
|
state = None
|
||||||
|
|
||||||
# No confidence support
|
# No confidence support
|
||||||
@ -178,19 +179,19 @@ class ImageProcessingFaceEntity(ImageProcessingEntity):
|
|||||||
confidence = f_co
|
confidence = f_co
|
||||||
for attr in (ATTR_NAME, ATTR_MOTION):
|
for attr in (ATTR_NAME, ATTR_MOTION):
|
||||||
if attr in face:
|
if attr in face:
|
||||||
state = face[attr]
|
state = face[attr] # type: ignore[literal-required]
|
||||||
break
|
break
|
||||||
|
|
||||||
return state
|
return state
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_class(self):
|
def device_class(self) -> str:
|
||||||
"""Return the class of this device, from component DEVICE_CLASSES."""
|
"""Return the class of this device, from component DEVICE_CLASSES."""
|
||||||
return "face"
|
return "face"
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def state_attributes(self):
|
def state_attributes(self) -> dict[str, Any]:
|
||||||
"""Return device specific state attributes."""
|
"""Return device specific state attributes."""
|
||||||
return {ATTR_FACES: self.faces, ATTR_TOTAL_FACES: self.total_faces}
|
return {ATTR_FACES: self.faces, ATTR_TOTAL_FACES: self.total_faces}
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ class ImageProcessingAlprEntity(ImageProcessingEntity):
|
|||||||
plates = {
|
plates = {
|
||||||
plate: confidence
|
plate: confidence
|
||||||
for plate, confidence in plates.items()
|
for plate, confidence in plates.items()
|
||||||
if confidence >= self.confidence
|
if self.confidence is None or confidence >= self.confidence
|
||||||
}
|
}
|
||||||
new_plates = set(plates) - set(self.plates)
|
new_plates = set(plates) - set(self.plates)
|
||||||
|
|
||||||
|
@ -1348,6 +1348,45 @@ _INHERITANCE_MATCH: dict[str, list[ClassTypeHintMatch]] = {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
"image_processing": [
|
||||||
|
ClassTypeHintMatch(
|
||||||
|
base_class="Entity",
|
||||||
|
matches=_ENTITY_MATCH,
|
||||||
|
),
|
||||||
|
ClassTypeHintMatch(
|
||||||
|
base_class="ImageProcessingEntity",
|
||||||
|
matches=[
|
||||||
|
TypeHintMatch(
|
||||||
|
function_name="camera_entity",
|
||||||
|
return_type=["str", None],
|
||||||
|
),
|
||||||
|
TypeHintMatch(
|
||||||
|
function_name="confidence",
|
||||||
|
return_type=["float", None],
|
||||||
|
),
|
||||||
|
TypeHintMatch(
|
||||||
|
function_name="process_image",
|
||||||
|
arg_types={1: "Image"},
|
||||||
|
return_type=None,
|
||||||
|
has_async_counterpart=True,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
ClassTypeHintMatch(
|
||||||
|
base_class="ImageProcessingFaceEntity",
|
||||||
|
matches=[
|
||||||
|
TypeHintMatch(
|
||||||
|
function_name="process_faces",
|
||||||
|
arg_types={
|
||||||
|
1: "list[FaceInformation]",
|
||||||
|
2: "int",
|
||||||
|
},
|
||||||
|
return_type=None,
|
||||||
|
has_async_counterpart=True,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
"light": [
|
"light": [
|
||||||
ClassTypeHintMatch(
|
ClassTypeHintMatch(
|
||||||
base_class="Entity",
|
base_class="Entity",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user