* Add amcrest camera services and deprecate switches - Implement enabling and disabling motion detection from camera platform. - Add amcrest specific camera services for controlling audio stream, motion recording, continuous recording and camera color mode, as well as moving camera to PTZ preset and starting and stopping PTZ tour function. - Add camera attributes to indicate the state of the various camera settings controlled by the new services. - Deprecate switches in favor of camera services and attributes. * Rename services and move service handling to __init__.py Rename services from 'camera.amcrest_xxx' to 'amcrest.xxx'. This allows services to be documented in services.yaml. Add services.yaml. Reorganize hass.data[DATA_AMCREST] and do some general cleanup to make various platform modules more consistent. Move service handling code to __init__.py from camera.py. * Update per review comments, part 1 - Rebase - Add permission checking to services - Change cv.ensure_list_csv to cv.ensure_list - Add comment for "pointless-statement" in setup - Change handler_services to handled_services - Remove check if services have alreaday been registered - Pass ffmpeg instead of hass to AmcrestCam __init__ - Remove writing motion_detection attr from device_state_attributes - Change service methods from callbacks to coroutines * Update per review comments, part 2 - Use dispatcher to signal camera entities to run services. - Reorganize a bit, including moving a few things to new modules const.py & helpers.py. * Update per review comments, part 3 Move call data extraction from camera.py to __init__.py.
91 lines
2.8 KiB
Python
91 lines
2.8 KiB
Python
"""Suppoort for Amcrest IP camera sensors."""
|
|
from datetime import timedelta
|
|
import logging
|
|
|
|
from homeassistant.const import CONF_NAME, CONF_SENSORS
|
|
from homeassistant.helpers.entity import Entity
|
|
|
|
from .const import DATA_AMCREST, SENSOR_SCAN_INTERVAL_SECS
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
SCAN_INTERVAL = timedelta(seconds=SENSOR_SCAN_INTERVAL_SECS)
|
|
|
|
# Sensor types are defined like: Name, units, icon
|
|
SENSOR_MOTION_DETECTOR = 'motion_detector'
|
|
SENSORS = {
|
|
SENSOR_MOTION_DETECTOR: ['Motion Detected', None, 'mdi:run'],
|
|
'sdcard': ['SD Used', '%', 'mdi:sd'],
|
|
'ptz_preset': ['PTZ Preset', None, 'mdi:camera-iris'],
|
|
}
|
|
|
|
|
|
async def async_setup_platform(
|
|
hass, config, async_add_entities, discovery_info=None):
|
|
"""Set up a sensor for an Amcrest IP Camera."""
|
|
if discovery_info is None:
|
|
return
|
|
|
|
name = discovery_info[CONF_NAME]
|
|
device = hass.data[DATA_AMCREST]['devices'][name]
|
|
async_add_entities(
|
|
[AmcrestSensor(name, device, sensor_type)
|
|
for sensor_type in discovery_info[CONF_SENSORS]],
|
|
True)
|
|
|
|
|
|
class AmcrestSensor(Entity):
|
|
"""A sensor implementation for Amcrest IP camera."""
|
|
|
|
def __init__(self, name, device, sensor_type):
|
|
"""Initialize a sensor for Amcrest camera."""
|
|
self._name = '{} {}'.format(name, SENSORS[sensor_type][0])
|
|
self._api = device.api
|
|
self._sensor_type = sensor_type
|
|
self._state = None
|
|
self._attrs = {}
|
|
self._unit_of_measurement = SENSORS[sensor_type][1]
|
|
self._icon = SENSORS[sensor_type][2]
|
|
|
|
@property
|
|
def name(self):
|
|
"""Return the name of the sensor."""
|
|
return self._name
|
|
|
|
@property
|
|
def state(self):
|
|
"""Return the state of the sensor."""
|
|
return self._state
|
|
|
|
@property
|
|
def device_state_attributes(self):
|
|
"""Return the state attributes."""
|
|
return self._attrs
|
|
|
|
@property
|
|
def icon(self):
|
|
"""Icon to use in the frontend, if any."""
|
|
return self._icon
|
|
|
|
@property
|
|
def unit_of_measurement(self):
|
|
"""Return the units of measurement."""
|
|
return self._unit_of_measurement
|
|
|
|
def update(self):
|
|
"""Get the latest data and updates the state."""
|
|
_LOGGER.debug("Pulling data from %s sensor.", self._name)
|
|
|
|
if self._sensor_type == 'motion_detector':
|
|
self._state = self._api.is_motion_detected
|
|
self._attrs['Record Mode'] = self._api.record_mode
|
|
|
|
elif self._sensor_type == 'ptz_preset':
|
|
self._state = self._api.ptz_presets_count
|
|
|
|
elif self._sensor_type == 'sdcard':
|
|
sd_used = self._api.storage_used
|
|
sd_total = self._api.storage_total
|
|
self._attrs['Total'] = '{0} {1}'.format(*sd_total)
|
|
self._attrs['Used'] = '{0} {1}'.format(*sd_used)
|
|
self._state = self._api.storage_used_percent
|