mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 17:27:52 +00:00
Merge pull request #6488 from pvizeli/pydroid-ipcam
Android IP Cam support
This commit is contained in:
commit
8f2009a187
@ -14,9 +14,12 @@ omit =
|
||||
homeassistant/components/arduino.py
|
||||
homeassistant/components/*/arduino.py
|
||||
|
||||
homeassistant/components/android_ip_webcam.py
|
||||
homeassistant/components/*/android_ip_webcam.py
|
||||
|
||||
homeassistant/components/bbb_gpio.py
|
||||
homeassistant/components/*/bbb_gpio.py
|
||||
|
||||
|
||||
homeassistant/components/blink.py
|
||||
homeassistant/components/*/blink.py
|
||||
|
||||
|
300
homeassistant/components/android_ip_webcam.py
Normal file
300
homeassistant/components/android_ip_webcam.py
Normal file
@ -0,0 +1,300 @@
|
||||
"""
|
||||
Support for IP Webcam, an Android app that acts as a full-featured webcam.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/android_ip_webcam/
|
||||
"""
|
||||
import asyncio
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.const import (
|
||||
CONF_NAME, CONF_HOST, CONF_PORT, CONF_USERNAME, CONF_PASSWORD,
|
||||
CONF_SENSORS, CONF_SWITCHES, CONF_TIMEOUT, CONF_SCAN_INTERVAL,
|
||||
CONF_PLATFORM)
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers import discovery
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.dispatcher import (
|
||||
async_dispatcher_send, async_dispatcher_connect)
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.event import async_track_point_in_utc_time
|
||||
from homeassistant.util.dt import utcnow
|
||||
from homeassistant.components.camera.mjpeg import (
|
||||
CONF_MJPEG_URL, CONF_STILL_IMAGE_URL)
|
||||
|
||||
DOMAIN = 'android_ip_webcam'
|
||||
REQUIREMENTS = ["pydroid-ipcam==0.3"]
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
SCAN_INTERVAL = timedelta(seconds=10)
|
||||
|
||||
DATA_IP_WEBCAM = 'android_ip_webcam'
|
||||
|
||||
ATTR_HOST = 'host'
|
||||
ATTR_VID_CONNS = 'Video Connections'
|
||||
ATTR_AUD_CONNS = 'Audio Connections'
|
||||
|
||||
KEY_MAP = {
|
||||
'audio_connections': 'Audio Connections',
|
||||
'adet_limit': 'Audio Trigger Limit',
|
||||
'antibanding': 'Anti-banding',
|
||||
'audio_only': 'Audio Only',
|
||||
'battery_level': 'Battery Level',
|
||||
'battery_temp': 'Battery Temperature',
|
||||
'battery_voltage': 'Battery Voltage',
|
||||
'coloreffect': 'Color Effect',
|
||||
'exposure': 'Exposure Level',
|
||||
'exposure_lock': 'Exposure Lock',
|
||||
'ffc': 'Front-facing Camera',
|
||||
'flashmode': 'Flash Mode',
|
||||
'focus': 'Focus',
|
||||
'focus_homing': 'Focus Homing',
|
||||
'focus_region': 'Focus Region',
|
||||
'focusmode': 'Focus Mode',
|
||||
'gps_active': 'GPS Active',
|
||||
'idle': 'Idle',
|
||||
'ip_address': 'IPv4 Address',
|
||||
'ipv6_address': 'IPv6 Address',
|
||||
'ivideon_streaming': 'Ivideon Streaming',
|
||||
'light': 'Light Level',
|
||||
'mirror_flip': 'Mirror Flip',
|
||||
'motion': 'Motion',
|
||||
'motion_active': 'Motion Active',
|
||||
'motion_detect': 'Motion Detection',
|
||||
'motion_event': 'Motion Event',
|
||||
'motion_limit': 'Motion Limit',
|
||||
'night_vision': 'Night Vision',
|
||||
'night_vision_average': 'Night Vision Average',
|
||||
'night_vision_gain': 'Night Vision Gain',
|
||||
'orientation': 'Orientation',
|
||||
'overlay': 'Overlay',
|
||||
'photo_size': 'Photo Size',
|
||||
'pressure': 'Pressure',
|
||||
'proximity': 'Proximity',
|
||||
'quality': 'Quality',
|
||||
'scenemode': 'Scene Mode',
|
||||
'sound': 'Sound',
|
||||
'sound_event': 'Sound Event',
|
||||
'sound_timeout': 'Sound Timeout',
|
||||
'torch': 'Torch',
|
||||
'video_connections': 'Video Connections',
|
||||
'video_chunk_len': 'Video Chunk Length',
|
||||
'video_recording': 'Video Recording',
|
||||
'video_size': 'Video Size',
|
||||
'whitebalance': 'White Balance',
|
||||
'whitebalance_lock': 'White Balance Lock',
|
||||
'zoom': 'Zoom'
|
||||
}
|
||||
|
||||
ICON_MAP = {
|
||||
'audio_connections': 'mdi:speaker',
|
||||
'battery_level': 'mdi:battery',
|
||||
'battery_temp': 'mdi:thermometer',
|
||||
'battery_voltage': 'mdi:battery-charging-100',
|
||||
'exposure_lock': 'mdi:camera',
|
||||
'ffc': 'mdi:camera-front-variant',
|
||||
'focus': 'mdi:image-filter-center-focus',
|
||||
'gps_active': 'mdi:crosshairs-gps',
|
||||
'light': 'mdi:flashlight',
|
||||
'motion': 'mdi:run',
|
||||
'night_vision': 'mdi:weather-night',
|
||||
'overlay': 'mdi:monitor',
|
||||
'pressure': 'mdi:gauge',
|
||||
'proximity': 'mdi:map-marker-radius',
|
||||
'quality': 'mdi:quality-high',
|
||||
'sound': 'mdi:speaker',
|
||||
'sound_event': 'mdi:speaker',
|
||||
'sound_timeout': 'mdi:speaker',
|
||||
'torch': 'mdi:white-balance-sunny',
|
||||
'video_chunk_len': 'mdi:video',
|
||||
'video_connections': 'mdi:eye',
|
||||
'video_recording': 'mdi:record-rec',
|
||||
'whitebalance_lock': 'mdi:white-balance-auto'
|
||||
}
|
||||
|
||||
SWITCHES = ['exposure_lock', 'ffc', 'focus', 'gps_active', 'night_vision',
|
||||
'overlay', 'torch', 'whitebalance_lock', 'video_recording']
|
||||
|
||||
SENSORS = ['audio_connections', 'battery_level', 'battery_temp',
|
||||
'battery_voltage', 'light', 'motion', 'pressure', 'proximity',
|
||||
'sound', 'video_connections']
|
||||
|
||||
SIGNAL_UPDATE_DATA = 'android_ip_webcam_update'
|
||||
|
||||
CONF_AUTO_DISCOVERY = 'auto_discovery'
|
||||
CONF_MOTION_SENSOR = 'motion_sensor'
|
||||
|
||||
DEFAULT_AUTO_DISCOVERY = True
|
||||
DEFAULT_MOTION_SENSOR = False
|
||||
DEFAULT_NAME = 'IP Webcam'
|
||||
DEFAULT_PORT = 8080
|
||||
DEFAULT_TIMEOUT = 10
|
||||
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
DOMAIN: vol.All(cv.ensure_list, [vol.Schema({
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Required(CONF_HOST): cv.string,
|
||||
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
||||
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
|
||||
vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL):
|
||||
cv.time_period,
|
||||
vol.Inclusive(CONF_USERNAME, 'authentication'): cv.string,
|
||||
vol.Inclusive(CONF_PASSWORD, 'authentication'): cv.string,
|
||||
vol.Optional(CONF_AUTO_DISCOVERY, default=DEFAULT_AUTO_DISCOVERY):
|
||||
cv.boolean,
|
||||
vol.Optional(CONF_SWITCHES, default=[]):
|
||||
vol.All(cv.ensure_list, [vol.In(SWITCHES)]),
|
||||
vol.Optional(CONF_SENSORS, default=[]):
|
||||
vol.All(cv.ensure_list, [vol.In(SENSORS)]),
|
||||
vol.Optional(CONF_MOTION_SENSOR, default=DEFAULT_MOTION_SENSOR):
|
||||
cv.boolean,
|
||||
})])
|
||||
}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_setup(hass, config):
|
||||
"""Setup the IP Webcam component."""
|
||||
from pydroid_ipcam import PyDroidIPCam
|
||||
|
||||
webcams = hass.data[DATA_IP_WEBCAM] = {}
|
||||
websession = async_get_clientsession(hass)
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_setup_ipcamera(cam_config):
|
||||
"""Setup a ip camera."""
|
||||
host = cam_config[CONF_HOST]
|
||||
username = cam_config.get(CONF_USERNAME)
|
||||
password = cam_config.get(CONF_PASSWORD)
|
||||
name = cam_config[CONF_NAME]
|
||||
interval = cam_config[CONF_SCAN_INTERVAL]
|
||||
switches = cam_config[CONF_SWITCHES]
|
||||
sensors = cam_config[CONF_SENSORS]
|
||||
motion = cam_config[CONF_MOTION_SENSOR]
|
||||
|
||||
# init ip webcam
|
||||
cam = PyDroidIPCam(
|
||||
hass.loop, websession, host, cam_config[CONF_PORT],
|
||||
username=username, password=password,
|
||||
timeout=cam_config[CONF_TIMEOUT]
|
||||
)
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_update_data(now):
|
||||
"""Update data from ipcam in SCAN_INTERVAL."""
|
||||
yield from cam.update()
|
||||
async_dispatcher_send(hass, SIGNAL_UPDATE_DATA, host)
|
||||
|
||||
async_track_point_in_utc_time(
|
||||
hass, async_update_data, utcnow() + interval)
|
||||
|
||||
yield from async_update_data(None)
|
||||
|
||||
# use autodiscovery to detect sensors/configs
|
||||
if cam_config[CONF_AUTO_DISCOVERY]:
|
||||
if not cam.available:
|
||||
_LOGGER.error(
|
||||
"Android webcam %s not found for discovery!", host)
|
||||
return
|
||||
|
||||
sensors = cam.enabled_sensors
|
||||
switches = cam.enabled_settings
|
||||
if 'motion_active' in sensors:
|
||||
sensors.pop('motion_active')
|
||||
motion = True
|
||||
|
||||
# load platforms
|
||||
webcams[host] = cam
|
||||
|
||||
mjpeg_camera = {
|
||||
CONF_PLATFORM: 'mjpeg',
|
||||
CONF_MJPEG_URL: cam.mjpeg_url,
|
||||
CONF_STILL_IMAGE_URL: cam.image_url,
|
||||
CONF_NAME: name,
|
||||
}
|
||||
if username and password:
|
||||
mjpeg_camera.update({
|
||||
CONF_USERNAME: username,
|
||||
CONF_PASSWORD: password
|
||||
})
|
||||
|
||||
hass.async_add_job(discovery.async_load_platform(
|
||||
hass, 'camera', 'mjpeg', mjpeg_camera, config))
|
||||
|
||||
hass.async_add_job(discovery.async_load_platform(
|
||||
hass, 'sensor', DOMAIN, {
|
||||
CONF_NAME: name,
|
||||
CONF_HOST: host,
|
||||
CONF_SENSORS: sensors,
|
||||
}, config))
|
||||
|
||||
hass.async_add_job(discovery.async_load_platform(
|
||||
hass, 'switch', DOMAIN, {
|
||||
CONF_NAME: name,
|
||||
CONF_HOST: host,
|
||||
CONF_SWITCHES: switches,
|
||||
}, config))
|
||||
|
||||
if motion:
|
||||
hass.async_add_job(discovery.async_load_platform(
|
||||
hass, 'binary_sensor', DOMAIN, {
|
||||
CONF_HOST: host,
|
||||
CONF_NAME: name,
|
||||
}, config))
|
||||
|
||||
tasks = [async_setup_ipcamera(conf) for conf in config[DOMAIN]]
|
||||
if tasks:
|
||||
yield from asyncio.wait(tasks, loop=hass.loop)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class AndroidIPCamEntity(Entity):
|
||||
"""The Android device running IP Webcam."""
|
||||
|
||||
def __init__(self, host, ipcam):
|
||||
"""Initialize the data oject."""
|
||||
self._host = host
|
||||
self._ipcam = ipcam
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_added_to_hass(self):
|
||||
"""Register update dispatcher."""
|
||||
@callback
|
||||
def async_ipcam_update(host):
|
||||
"""Update callback."""
|
||||
if self._host != host:
|
||||
return
|
||||
self.hass.async_add_job(self.async_update_ha_state(True))
|
||||
|
||||
async_dispatcher_connect(
|
||||
self.hass, SIGNAL_UPDATE_DATA, async_ipcam_update)
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""Return True if entity has to be polled for state."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
"""Return True if entity is available."""
|
||||
return self._ipcam.available
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return the state attributes."""
|
||||
state_attr = {ATTR_HOST: self._host}
|
||||
if self._ipcam.status_data is None:
|
||||
return state_attr
|
||||
|
||||
state_attr[ATTR_VID_CONNS] = \
|
||||
self._ipcam.status_data.get('video_connections')
|
||||
state_attr[ATTR_AUD_CONNS] = \
|
||||
self._ipcam.status_data.get('audio_connections')
|
||||
|
||||
return state_attr
|
62
homeassistant/components/binary_sensor/android_ip_webcam.py
Normal file
62
homeassistant/components/binary_sensor/android_ip_webcam.py
Normal file
@ -0,0 +1,62 @@
|
||||
"""
|
||||
Support for IP Webcam binary sensors.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/binary_sensor.android_ip_webcam/
|
||||
"""
|
||||
import asyncio
|
||||
|
||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||
from homeassistant.components.android_ip_webcam import (
|
||||
KEY_MAP, DATA_IP_WEBCAM, AndroidIPCamEntity, CONF_HOST, CONF_NAME)
|
||||
|
||||
DEPENDENCIES = ['android_ip_webcam']
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup IP Webcam binary sensors."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
host = discovery_info[CONF_HOST]
|
||||
name = discovery_info[CONF_NAME]
|
||||
ipcam = hass.data[DATA_IP_WEBCAM][host]
|
||||
|
||||
async_add_devices(
|
||||
[IPWebcamBinarySensor(name, host, ipcam, 'motion_active')], True)
|
||||
|
||||
|
||||
class IPWebcamBinarySensor(AndroidIPCamEntity, BinarySensorDevice):
|
||||
"""Represents an IP Webcam binary sensor."""
|
||||
|
||||
def __init__(self, name, host, ipcam, sensor):
|
||||
"""Initialize the binary sensor."""
|
||||
super().__init__(host, ipcam)
|
||||
|
||||
self._sensor = sensor
|
||||
self._mapped_name = KEY_MAP.get(self._sensor, self._sensor)
|
||||
self._name = '{} {}'.format(name, self._mapped_name)
|
||||
self._state = None
|
||||
self._unit = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the binary sensor, if any."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""True if the binary sensor is on."""
|
||||
return self._state
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_update(self):
|
||||
"""Retrieve latest state."""
|
||||
state, _ = self._ipcam.export_sensor(self._sensor)
|
||||
self._state = state == 1.0
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Return the class of this device, from component DEVICE_CLASSES."""
|
||||
return 'motion'
|
@ -45,6 +45,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
# pylint: disable=unused-argument
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup a MJPEG IP Camera."""
|
||||
if discovery_info:
|
||||
config = PLATFORM_SCHEMA(discovery_info)
|
||||
async_add_devices([MjpegCamera(hass, config)])
|
||||
|
||||
|
||||
|
86
homeassistant/components/sensor/android_ip_webcam.py
Normal file
86
homeassistant/components/sensor/android_ip_webcam.py
Normal file
@ -0,0 +1,86 @@
|
||||
"""
|
||||
Support for IP Webcam sensors.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/sensor.android_ip_webcam/
|
||||
"""
|
||||
import asyncio
|
||||
|
||||
from homeassistant.components.android_ip_webcam import (
|
||||
KEY_MAP, ICON_MAP, DATA_IP_WEBCAM, AndroidIPCamEntity, CONF_HOST,
|
||||
CONF_NAME, CONF_SENSORS)
|
||||
|
||||
DEPENDENCIES = ['android_ip_webcam']
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup the IP Webcam Sensor."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
host = discovery_info[CONF_HOST]
|
||||
name = discovery_info[CONF_NAME]
|
||||
sensors = discovery_info[CONF_SENSORS]
|
||||
ipcam = hass.data[DATA_IP_WEBCAM][host]
|
||||
|
||||
all_sensors = []
|
||||
|
||||
for sensor in sensors:
|
||||
all_sensors.append(IPWebcamSensor(name, host, ipcam, sensor))
|
||||
|
||||
async_add_devices(all_sensors, True)
|
||||
|
||||
|
||||
class IPWebcamSensor(AndroidIPCamEntity):
|
||||
"""Representation of a IP Webcam sensor."""
|
||||
|
||||
def __init__(self, name, host, ipcam, sensor):
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(host, ipcam)
|
||||
|
||||
self._sensor = sensor
|
||||
self._mapped_name = KEY_MAP.get(self._sensor, self._sensor)
|
||||
self._name = '{} {}'.format(name, self._mapped_name)
|
||||
self._state = None
|
||||
self._unit = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor, if any."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the unit the value is expressed in."""
|
||||
return self._unit
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_update(self):
|
||||
"""Retrieve latest state."""
|
||||
if self._sensor in ('audio_connections', 'video_connections'):
|
||||
self._state = self._ipcam.status_data.get(self._sensor)
|
||||
self._unit = 'Connections'
|
||||
else:
|
||||
self._state, self._unit = self._ipcam.export_sensor(self._sensor)
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the icon for the sensor."""
|
||||
if self._sensor == 'battery_level' and self._state is not None:
|
||||
rounded_level = round(int(self._state), -1)
|
||||
returning_icon = 'mdi:battery'
|
||||
if rounded_level < 10:
|
||||
returning_icon = 'mdi:battery-outline'
|
||||
elif self._state == 100:
|
||||
returning_icon = 'mdi:battery'
|
||||
else:
|
||||
returning_icon = 'mdi:battery-{}'.format(str(rounded_level))
|
||||
|
||||
return returning_icon
|
||||
return ICON_MAP.get(self._sensor, 'mdi:eye')
|
94
homeassistant/components/switch/android_ip_webcam.py
Normal file
94
homeassistant/components/switch/android_ip_webcam.py
Normal file
@ -0,0 +1,94 @@
|
||||
"""
|
||||
Support for IP Webcam settings.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/switch.android_ip_webcam/
|
||||
"""
|
||||
import asyncio
|
||||
|
||||
from homeassistant.components.switch import SwitchDevice
|
||||
from homeassistant.components.android_ip_webcam import (
|
||||
KEY_MAP, ICON_MAP, DATA_IP_WEBCAM, AndroidIPCamEntity, CONF_HOST,
|
||||
CONF_NAME, CONF_SWITCHES)
|
||||
|
||||
DEPENDENCIES = ['android_ip_webcam']
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Set up the IP Webcam switch platform."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
host = discovery_info[CONF_HOST]
|
||||
name = discovery_info[CONF_NAME]
|
||||
switches = discovery_info[CONF_SWITCHES]
|
||||
ipcam = hass.data[DATA_IP_WEBCAM][host]
|
||||
|
||||
all_switches = []
|
||||
|
||||
for setting in switches:
|
||||
all_switches.append(IPWebcamSettingsSwitch(name, host, ipcam, setting))
|
||||
|
||||
async_add_devices(all_switches, True)
|
||||
|
||||
|
||||
class IPWebcamSettingsSwitch(AndroidIPCamEntity, SwitchDevice):
|
||||
"""An abstract class for an IP Webcam setting."""
|
||||
|
||||
def __init__(self, name, host, ipcam, setting):
|
||||
"""Initialize the settings switch."""
|
||||
super().__init__(host, ipcam)
|
||||
|
||||
self._setting = setting
|
||||
self._mapped_name = KEY_MAP.get(self._setting, self._setting)
|
||||
self._name = '{} {}'.format(name, self._mapped_name)
|
||||
self._state = False
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the the name of the node."""
|
||||
return self._name
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_update(self):
|
||||
"""Get the updated status of the switch."""
|
||||
self._state = bool(self._ipcam.current_settings.get(self._setting))
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return the boolean response if the node is on."""
|
||||
return self._state
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_turn_on(self, **kwargs):
|
||||
"""Turn device on."""
|
||||
if self._setting is 'torch':
|
||||
yield from self._ipcam.torch(activate=True)
|
||||
elif self._setting is 'focus':
|
||||
yield from self._ipcam.focus(activate=True)
|
||||
elif self._setting is 'video_recording':
|
||||
yield from self._ipcam.record(record=True)
|
||||
else:
|
||||
yield from self._ipcam.change_setting(self._setting, True)
|
||||
self._state = True
|
||||
self.hass.async_add_job(self.async_update_ha_state())
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_turn_off(self, **kwargs):
|
||||
"""Turn device off."""
|
||||
if self._setting is 'torch':
|
||||
yield from self._ipcam.torch(activate=False)
|
||||
elif self._setting is 'focus':
|
||||
yield from self._ipcam.focus(activate=False)
|
||||
elif self._setting is 'video_recording':
|
||||
yield from self._ipcam.record(record=False)
|
||||
else:
|
||||
yield from self._ipcam.change_setting(self._setting, False)
|
||||
self._state = False
|
||||
self.hass.async_add_job(self.async_update_ha_state())
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the icon for the switch."""
|
||||
return ICON_MAP.get(self._setting, 'mdi:flash')
|
@ -481,6 +481,9 @@ pycmus==0.1.0
|
||||
# homeassistant.components.zwave
|
||||
pydispatcher==2.0.5
|
||||
|
||||
# homeassistant.components.android_ip_webcam
|
||||
pydroid-ipcam==0.3
|
||||
|
||||
# homeassistant.components.sensor.ebox
|
||||
pyebox==0.1.0
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user