Add resolution to Amcrest camera unique id (#56207)
Co-authored-by: Joakim Sørensen <hi@ludeeus.dev>
This commit is contained in:
parent
dd52ec78c7
commit
f18e4bab60
4 changed files with 42 additions and 8 deletions
|
@ -380,3 +380,4 @@ class AmcrestDevice:
|
|||
stream_source: str
|
||||
resolution: int
|
||||
control_light: bool
|
||||
channel: int = 0
|
||||
|
|
|
@ -170,7 +170,7 @@ class AmcrestBinarySensor(BinarySensorEntity):
|
|||
"""Initialize entity."""
|
||||
self._signal_name = name
|
||||
self._api = device.api
|
||||
self._channel = 0 # Used in unique id, reserved for future use
|
||||
self._channel = device.channel
|
||||
self.entity_description: AmcrestSensorEntityDescription = entity_description
|
||||
|
||||
self._attr_name = f"{name} {entity_description.name}"
|
||||
|
@ -195,14 +195,13 @@ class AmcrestBinarySensor(BinarySensorEntity):
|
|||
return
|
||||
_LOGGER.debug(_UPDATE_MSG, self.name)
|
||||
|
||||
self._update_unique_id()
|
||||
|
||||
if self._api.available:
|
||||
# Send a command to the camera to test if we can still communicate with it.
|
||||
# Override of Http.command() in __init__.py will set self._api.available
|
||||
# accordingly.
|
||||
with suppress(AmcrestError):
|
||||
self._api.current_time # pylint: disable=pointless-statement
|
||||
self._update_unique_id()
|
||||
self._attr_is_on = self._api.available
|
||||
|
||||
def _update_others(self) -> None:
|
||||
|
@ -210,7 +209,11 @@ class AmcrestBinarySensor(BinarySensorEntity):
|
|||
return
|
||||
_LOGGER.debug(_UPDATE_MSG, self.name)
|
||||
|
||||
try:
|
||||
self._update_unique_id()
|
||||
except AmcrestError as error:
|
||||
log_update_error(_LOGGER, "update", self.name, "binary sensor", error)
|
||||
return
|
||||
|
||||
event_code = self.entity_description.event_code
|
||||
if event_code is None:
|
||||
|
@ -221,6 +224,7 @@ class AmcrestBinarySensor(BinarySensorEntity):
|
|||
self._attr_is_on = len(self._api.event_channels_happened(event_code)) > 0
|
||||
except AmcrestError as error:
|
||||
log_update_error(_LOGGER, "update", self.name, "binary sensor", error)
|
||||
return
|
||||
|
||||
def _update_unique_id(self) -> None:
|
||||
"""Set the unique id."""
|
||||
|
|
|
@ -14,9 +14,11 @@ from haffmpeg.camera import CameraMjpeg
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.camera import SUPPORT_ON_OFF, SUPPORT_STREAM, Camera
|
||||
from homeassistant.components.camera.const import DOMAIN as CAMERA_DOMAIN
|
||||
from homeassistant.components.ffmpeg import DATA_FFMPEG, FFmpegManager
|
||||
from homeassistant.const import ATTR_ENTITY_ID, CONF_NAME, STATE_OFF, STATE_ON
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry
|
||||
from homeassistant.helpers.aiohttp_client import (
|
||||
async_aiohttp_proxy_stream,
|
||||
async_aiohttp_proxy_web,
|
||||
|
@ -33,6 +35,7 @@ from .const import (
|
|||
COMM_TIMEOUT,
|
||||
DATA_AMCREST,
|
||||
DEVICES,
|
||||
DOMAIN,
|
||||
SERVICE_UPDATE,
|
||||
SNAPSHOT_TIMEOUT,
|
||||
)
|
||||
|
@ -133,7 +136,21 @@ async def async_setup_platform(
|
|||
|
||||
name = discovery_info[CONF_NAME]
|
||||
device = hass.data[DATA_AMCREST][DEVICES][name]
|
||||
async_add_entities([AmcrestCam(name, device, hass.data[DATA_FFMPEG])], True)
|
||||
entity = AmcrestCam(name, device, hass.data[DATA_FFMPEG])
|
||||
|
||||
# 2021.9.0 introduced unique id's for the camera entity, but these were not
|
||||
# unique for different resolution streams. If any cameras were configured
|
||||
# with this version, update the old entity with the new unique id.
|
||||
serial_number = await hass.async_add_executor_job(lambda: device.api.serial_number) # type: ignore[no-any-return]
|
||||
serial_number = serial_number.strip()
|
||||
registry = entity_registry.async_get(hass)
|
||||
entity_id = registry.async_get_entity_id(CAMERA_DOMAIN, DOMAIN, serial_number)
|
||||
if entity_id is not None:
|
||||
_LOGGER.debug("Updating unique id for camera %s", entity_id)
|
||||
new_unique_id = f"{serial_number}-{device.resolution}-{device.channel}"
|
||||
registry.async_update_entity(entity_id, new_unique_id=new_unique_id)
|
||||
|
||||
async_add_entities([entity], True)
|
||||
|
||||
|
||||
class CannotSnapshot(Exception):
|
||||
|
@ -156,6 +173,7 @@ class AmcrestCam(Camera):
|
|||
self._ffmpeg_arguments = device.ffmpeg_arguments
|
||||
self._stream_source = device.stream_source
|
||||
self._resolution = device.resolution
|
||||
self._channel = device.channel
|
||||
self._token = self._auth = device.authentication
|
||||
self._control_light = device.control_light
|
||||
self._is_recording: bool = False
|
||||
|
@ -388,7 +406,11 @@ class AmcrestCam(Camera):
|
|||
else:
|
||||
self._model = "unknown"
|
||||
if self._attr_unique_id is None:
|
||||
self._attr_unique_id = self._api.serial_number.strip()
|
||||
serial_number = self._api.serial_number.strip()
|
||||
if serial_number:
|
||||
self._attr_unique_id = (
|
||||
f"{serial_number}-{self._resolution}-{self._channel}"
|
||||
)
|
||||
_LOGGER.debug("Assigned unique_id=%s", self._attr_unique_id)
|
||||
self.is_streaming = self._get_video()
|
||||
self._is_recording = self._get_recording()
|
||||
|
|
|
@ -78,7 +78,7 @@ class AmcrestSensor(SensorEntity):
|
|||
self.entity_description = description
|
||||
self._signal_name = name
|
||||
self._api = device.api
|
||||
self._channel = 0 # Used in unique id, reserved for future use
|
||||
self._channel = device.channel
|
||||
self._unsub_dispatcher: Callable[[], None] | None = None
|
||||
|
||||
self._attr_name = f"{name} {description.name}"
|
||||
|
@ -102,6 +102,13 @@ class AmcrestSensor(SensorEntity):
|
|||
self._attr_unique_id = f"{serial_number}-{sensor_type}-{self._channel}"
|
||||
|
||||
try:
|
||||
if self._attr_unique_id is None:
|
||||
serial_number = self._api.serial_number
|
||||
if serial_number:
|
||||
self._attr_unique_id = (
|
||||
f"{serial_number}-{sensor_type}-{self._channel}"
|
||||
)
|
||||
|
||||
if sensor_type == SENSOR_PTZ_PRESET:
|
||||
self._attr_native_value = self._api.ptz_presets_count
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue