mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 14:17:45 +00:00
Improve type hints in doods (#145426)
This commit is contained in:
parent
1db5c514e6
commit
8758a086c1
@ -6,6 +6,7 @@ import io
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from PIL import Image, ImageDraw, UnidentifiedImageError
|
from PIL import Image, ImageDraw, UnidentifiedImageError
|
||||||
from pydoods import PyDOODS
|
from pydoods import PyDOODS
|
||||||
@ -88,10 +89,11 @@ def setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the Doods client."""
|
"""Set up the Doods client."""
|
||||||
url = config[CONF_URL]
|
url: str = config[CONF_URL]
|
||||||
auth_key = config[CONF_AUTH_KEY]
|
auth_key: str = config[CONF_AUTH_KEY]
|
||||||
detector_name = config[CONF_DETECTOR]
|
detector_name: str = config[CONF_DETECTOR]
|
||||||
timeout = config[CONF_TIMEOUT]
|
source: list[dict[str, str]] = config[CONF_SOURCE]
|
||||||
|
timeout: int = config[CONF_TIMEOUT]
|
||||||
|
|
||||||
doods = PyDOODS(url, auth_key, timeout)
|
doods = PyDOODS(url, auth_key, timeout)
|
||||||
response = doods.get_detectors()
|
response = doods.get_detectors()
|
||||||
@ -113,31 +115,35 @@ def setup_platform(
|
|||||||
|
|
||||||
add_entities(
|
add_entities(
|
||||||
Doods(
|
Doods(
|
||||||
hass,
|
|
||||||
camera[CONF_ENTITY_ID],
|
camera[CONF_ENTITY_ID],
|
||||||
camera.get(CONF_NAME),
|
camera.get(CONF_NAME),
|
||||||
doods,
|
doods,
|
||||||
detector,
|
detector,
|
||||||
config,
|
config,
|
||||||
)
|
)
|
||||||
for camera in config[CONF_SOURCE]
|
for camera in source
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Doods(ImageProcessingEntity):
|
class Doods(ImageProcessingEntity):
|
||||||
"""Doods image processing service client."""
|
"""Doods image processing service client."""
|
||||||
|
|
||||||
def __init__(self, hass, camera_entity, name, doods, detector, config):
|
def __init__(
|
||||||
|
self,
|
||||||
|
camera_entity: str,
|
||||||
|
name: str | None,
|
||||||
|
doods: PyDOODS,
|
||||||
|
detector: dict[str, Any],
|
||||||
|
config: dict[str, Any],
|
||||||
|
) -> None:
|
||||||
"""Initialize the DOODS entity."""
|
"""Initialize the DOODS entity."""
|
||||||
self.hass = hass
|
self._attr_camera_entity = camera_entity
|
||||||
self._camera_entity = camera_entity
|
|
||||||
if name:
|
if name:
|
||||||
self._name = name
|
self._attr_name = name
|
||||||
else:
|
else:
|
||||||
name = split_entity_id(camera_entity)[1]
|
self._attr_name = f"Doods {split_entity_id(camera_entity)[1]}"
|
||||||
self._name = f"Doods {name}"
|
|
||||||
self._doods = doods
|
self._doods = doods
|
||||||
self._file_out = config[CONF_FILE_OUT]
|
self._file_out: list[template.Template] = config[CONF_FILE_OUT]
|
||||||
self._detector_name = detector["name"]
|
self._detector_name = detector["name"]
|
||||||
|
|
||||||
# detector config and aspect ratio
|
# detector config and aspect ratio
|
||||||
@ -150,16 +156,16 @@ class Doods(ImageProcessingEntity):
|
|||||||
self._aspect = self._width / self._height
|
self._aspect = self._width / self._height
|
||||||
|
|
||||||
# the base confidence
|
# the base confidence
|
||||||
dconfig = {}
|
dconfig: dict[str, float] = {}
|
||||||
confidence = config[CONF_CONFIDENCE]
|
confidence: float = config[CONF_CONFIDENCE]
|
||||||
|
|
||||||
# handle labels and specific detection areas
|
# handle labels and specific detection areas
|
||||||
labels = config[CONF_LABELS]
|
labels: list[str | dict[str, Any]] = config[CONF_LABELS]
|
||||||
self._label_areas = {}
|
self._label_areas = {}
|
||||||
self._label_covers = {}
|
self._label_covers = {}
|
||||||
for label in labels:
|
for label in labels:
|
||||||
if isinstance(label, dict):
|
if isinstance(label, dict):
|
||||||
label_name = label[CONF_NAME]
|
label_name: str = label[CONF_NAME]
|
||||||
if label_name not in detector["labels"] and label_name != "*":
|
if label_name not in detector["labels"] and label_name != "*":
|
||||||
_LOGGER.warning("Detector does not support label %s", label_name)
|
_LOGGER.warning("Detector does not support label %s", label_name)
|
||||||
continue
|
continue
|
||||||
@ -207,28 +213,18 @@ class Doods(ImageProcessingEntity):
|
|||||||
self._covers = area_config[CONF_COVERS]
|
self._covers = area_config[CONF_COVERS]
|
||||||
|
|
||||||
self._dconfig = dconfig
|
self._dconfig = dconfig
|
||||||
self._matches = {}
|
self._matches: dict[str, list[dict[str, Any]]] = {}
|
||||||
self._total_matches = 0
|
self._total_matches = 0
|
||||||
self._last_image = None
|
self._last_image = None
|
||||||
self._process_time = 0
|
self._process_time = 0.0
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def camera_entity(self):
|
def state(self) -> int:
|
||||||
"""Return camera entity id from process pictures."""
|
|
||||||
return self._camera_entity
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
"""Return the name of the image processor."""
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def state(self):
|
|
||||||
"""Return the state of the entity."""
|
"""Return the state of the entity."""
|
||||||
return self._total_matches
|
return self._total_matches
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extra_state_attributes(self):
|
def extra_state_attributes(self) -> dict[str, Any]:
|
||||||
"""Return device specific state attributes."""
|
"""Return device specific state attributes."""
|
||||||
return {
|
return {
|
||||||
ATTR_MATCHES: self._matches,
|
ATTR_MATCHES: self._matches,
|
||||||
@ -281,7 +277,7 @@ class Doods(ImageProcessingEntity):
|
|||||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||||
img.save(path)
|
img.save(path)
|
||||||
|
|
||||||
def process_image(self, image):
|
def process_image(self, image: bytes) -> None:
|
||||||
"""Process the image."""
|
"""Process the image."""
|
||||||
try:
|
try:
|
||||||
img = Image.open(io.BytesIO(bytearray(image))).convert("RGB")
|
img = Image.open(io.BytesIO(bytearray(image))).convert("RGB")
|
||||||
@ -312,7 +308,7 @@ class Doods(ImageProcessingEntity):
|
|||||||
time.monotonic() - start,
|
time.monotonic() - start,
|
||||||
)
|
)
|
||||||
|
|
||||||
matches = {}
|
matches: dict[str, list[dict[str, Any]]] = {}
|
||||||
total_matches = 0
|
total_matches = 0
|
||||||
|
|
||||||
if not response or "error" in response:
|
if not response or "error" in response:
|
||||||
@ -382,9 +378,7 @@ class Doods(ImageProcessingEntity):
|
|||||||
paths = []
|
paths = []
|
||||||
for path_template in self._file_out:
|
for path_template in self._file_out:
|
||||||
if isinstance(path_template, template.Template):
|
if isinstance(path_template, template.Template):
|
||||||
paths.append(
|
paths.append(path_template.render(camera_entity=self.camera_entity))
|
||||||
path_template.render(camera_entity=self._camera_entity)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
paths.append(path_template)
|
paths.append(path_template)
|
||||||
self._save_image(image, matches, paths)
|
self._save_image(image, matches, paths)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user