Amcrest: Add on/off support & attributes. Bump amcrest to 1.3.0 (#22418)
* Amcrest: Add on/off support & attributes to camera entity. Bump amcrest package to 1.3.0. Add support for turn_on & turn_off services. Add implementation of is_recording method, as well as brand, model, hardware_version, machine_name, serial_number, software_build and software_version attributes. Bump amcrest package to 1.3.0 required for above changes and also handles errors in storage commands which resolves #19982. * Update per review Rebase to upstream/dev. Remove video_enabled property and setter and replace with _enable_video_stream method. Remove static attributes from camera and sensors.
This commit is contained in:
parent
e78709c5f5
commit
82296aeb71
4 changed files with 85 additions and 19 deletions
|
@ -12,7 +12,7 @@ from homeassistant.helpers import discovery
|
|||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
|
||||
REQUIREMENTS = ['amcrest==1.2.7']
|
||||
REQUIREMENTS = ['amcrest==1.3.0']
|
||||
DEPENDENCIES = ['ffmpeg']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
|
|
@ -3,7 +3,7 @@ import asyncio
|
|||
import logging
|
||||
|
||||
from homeassistant.components.camera import (
|
||||
Camera, SUPPORT_STREAM)
|
||||
Camera, SUPPORT_ON_OFF, SUPPORT_STREAM)
|
||||
from homeassistant.components.ffmpeg import DATA_FFMPEG
|
||||
from homeassistant.const import CONF_NAME
|
||||
from homeassistant.helpers.aiohttp_client import (
|
||||
|
@ -39,18 +39,23 @@ class AmcrestCam(Camera):
|
|||
super(AmcrestCam, self).__init__()
|
||||
self._name = amcrest.name
|
||||
self._camera = amcrest.device
|
||||
self._base_url = self._camera.get_base_url()
|
||||
self._ffmpeg = hass.data[DATA_FFMPEG]
|
||||
self._ffmpeg_arguments = amcrest.ffmpeg_arguments
|
||||
self._stream_source = amcrest.stream_source
|
||||
self._resolution = amcrest.resolution
|
||||
self._token = self._auth = amcrest.authentication
|
||||
self._is_recording = False
|
||||
self._model = None
|
||||
self._snapshot_lock = asyncio.Lock()
|
||||
|
||||
async def async_camera_image(self):
|
||||
"""Return a still image response from the camera."""
|
||||
from amcrest import AmcrestError
|
||||
|
||||
if not self.is_on:
|
||||
_LOGGER.error(
|
||||
'Attempt to take snaphot when %s camera is off', self.name)
|
||||
return None
|
||||
async with self._snapshot_lock:
|
||||
try:
|
||||
# Send the request to snap a picture and return raw jpg data
|
||||
|
@ -59,7 +64,8 @@ class AmcrestCam(Camera):
|
|||
return response.data
|
||||
except AmcrestError as error:
|
||||
_LOGGER.error(
|
||||
'Could not get camera image due to error %s', error)
|
||||
'Could not get image from %s camera due to error: %s',
|
||||
self.name, error)
|
||||
return None
|
||||
|
||||
async def handle_async_mjpeg_stream(self, request):
|
||||
|
@ -94,6 +100,8 @@ class AmcrestCam(Camera):
|
|||
finally:
|
||||
await stream.close()
|
||||
|
||||
# Entity property overrides
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of this camera."""
|
||||
|
@ -102,9 +110,80 @@ class AmcrestCam(Camera):
|
|||
@property
|
||||
def supported_features(self):
|
||||
"""Return supported features."""
|
||||
return SUPPORT_STREAM
|
||||
return SUPPORT_ON_OFF | SUPPORT_STREAM
|
||||
|
||||
# Camera property overrides
|
||||
|
||||
@property
|
||||
def is_recording(self):
|
||||
"""Return true if the device is recording."""
|
||||
return self._is_recording
|
||||
|
||||
@property
|
||||
def brand(self):
|
||||
"""Return the camera brand."""
|
||||
return 'Amcrest'
|
||||
|
||||
@property
|
||||
def model(self):
|
||||
"""Return the camera model."""
|
||||
return self._model
|
||||
|
||||
@property
|
||||
def stream_source(self):
|
||||
"""Return the source of the stream."""
|
||||
return self._camera.rtsp_url(typeno=self._resolution)
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if on."""
|
||||
return self.is_streaming
|
||||
|
||||
# Other Entity method overrides
|
||||
|
||||
def update(self):
|
||||
"""Update entity status."""
|
||||
from amcrest import AmcrestError
|
||||
|
||||
_LOGGER.debug('Pulling data from %s camera', self.name)
|
||||
if self._model is None:
|
||||
try:
|
||||
self._model = self._camera.device_type.split('=')[-1].strip()
|
||||
except AmcrestError as error:
|
||||
_LOGGER.error(
|
||||
'Could not get %s camera model due to error: %s',
|
||||
self.name, error)
|
||||
self._model = ''
|
||||
try:
|
||||
self.is_streaming = self._camera.video_enabled
|
||||
self._is_recording = self._camera.record_mode == 'Manual'
|
||||
except AmcrestError as error:
|
||||
_LOGGER.error(
|
||||
'Could not get %s camera attributes due to error: %s',
|
||||
self.name, error)
|
||||
|
||||
# Other Camera method overrides
|
||||
|
||||
def turn_off(self):
|
||||
"""Turn off camera."""
|
||||
self._enable_video_stream(False)
|
||||
|
||||
def turn_on(self):
|
||||
"""Turn on camera."""
|
||||
self._enable_video_stream(True)
|
||||
|
||||
# Utility methods
|
||||
|
||||
def _enable_video_stream(self, enable):
|
||||
"""Enable or disable camera video stream."""
|
||||
from amcrest import AmcrestError
|
||||
|
||||
try:
|
||||
self._camera.video_enabled = enable
|
||||
except AmcrestError as error:
|
||||
_LOGGER.error(
|
||||
'Could not %s %s camera video stream due to error: %s',
|
||||
'enable' if enable else 'disable', self.name, error)
|
||||
else:
|
||||
self.is_streaming = enable
|
||||
self.schedule_update_ha_state()
|
||||
|
|
|
@ -75,19 +75,6 @@ class AmcrestSensor(Entity):
|
|||
"""Get the latest data and updates the state."""
|
||||
_LOGGER.debug("Pulling data from %s sensor.", self._name)
|
||||
|
||||
try:
|
||||
version, build_date = self._camera.software_information
|
||||
self._attrs['Build Date'] = build_date.split('=')[-1]
|
||||
self._attrs['Version'] = version.split('=')[-1]
|
||||
except ValueError:
|
||||
self._attrs['Build Date'] = 'Not Available'
|
||||
self._attrs['Version'] = 'Not Available'
|
||||
|
||||
try:
|
||||
self._attrs['Serial Number'] = self._camera.serial_number
|
||||
except ValueError:
|
||||
self._attrs['Serial Number'] = 'Not Available'
|
||||
|
||||
if self._sensor_type == 'motion_detector':
|
||||
self._state = self._camera.is_motion_detected
|
||||
self._attrs['Record Mode'] = self._camera.record_mode
|
||||
|
|
|
@ -155,7 +155,7 @@ alarmdecoder==1.13.2
|
|||
alpha_vantage==2.1.0
|
||||
|
||||
# homeassistant.components.amcrest
|
||||
amcrest==1.2.7
|
||||
amcrest==1.3.0
|
||||
|
||||
# homeassistant.components.androidtv.media_player
|
||||
androidtv==0.0.14
|
||||
|
|
Loading…
Add table
Reference in a new issue