""" Support for DoorBird device. For more details about this component, please refer to the documentation at https://home-assistant.io/components/doorbird/ """ import logging import asyncio import voluptuous as vol from homeassistant.components.http import HomeAssistantView from homeassistant.const import CONF_HOST, CONF_USERNAME, \ CONF_PASSWORD, CONF_NAME, CONF_DEVICES, CONF_MONITORED_CONDITIONS import homeassistant.helpers.config_validation as cv from homeassistant.util import slugify REQUIREMENTS = ['DoorBirdPy==0.1.3'] _LOGGER = logging.getLogger(__name__) DOMAIN = 'doorbird' API_URL = '/api/{}'.format(DOMAIN) CONF_DOORBELL_EVENTS = 'doorbell_events' CONF_CUSTOM_URL = 'hass_url_override' DOORBELL_EVENT = 'doorbell' MOTION_EVENT = 'motionsensor' # Sensor types: Name, device_class, event SENSOR_TYPES = { 'doorbell': ['Button', 'occupancy', DOORBELL_EVENT], 'motion': ['Motion', 'motion', MOTION_EVENT], } DEVICE_SCHEMA = vol.Schema({ vol.Required(CONF_HOST): cv.string, vol.Required(CONF_USERNAME): cv.string, vol.Required(CONF_PASSWORD): cv.string, vol.Optional(CONF_CUSTOM_URL): cv.string, vol.Optional(CONF_NAME): cv.string, vol.Optional(CONF_MONITORED_CONDITIONS, default=[]): vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]), }) CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ vol.Required(CONF_DEVICES): vol.All(cv.ensure_list, [DEVICE_SCHEMA]) }), }, extra=vol.ALLOW_EXTRA) def setup(hass, config): """Set up the DoorBird component.""" from doorbirdpy import DoorBird # Provide an endpoint for the doorstations to call to trigger events hass.http.register_view(DoorbirdRequestView()) doorstations = [] for index, doorstation_config in enumerate(config[DOMAIN][CONF_DEVICES]): device_ip = doorstation_config.get(CONF_HOST) username = doorstation_config.get(CONF_USERNAME) password = doorstation_config.get(CONF_PASSWORD) custom_url = doorstation_config.get(CONF_CUSTOM_URL) events = doorstation_config.get(CONF_MONITORED_CONDITIONS) name = (doorstation_config.get(CONF_NAME) or 'DoorBird {}'.format(index + 1)) device = DoorBird(device_ip, username, password) status = device.ready() if status[0]: _LOGGER.info("Connected to DoorBird at %s as %s", device_ip, username) doorstation = ConfiguredDoorbird(device, name, events, custom_url) doorstations.append(doorstation) elif status[1] == 401: _LOGGER.error("Authorization rejected by DoorBird at %s", device_ip) return False else: _LOGGER.error("Could not connect to DoorBird at %s: Error %s", device_ip, str(status[1])) return False # SETUP EVENT SUBSCRIBERS if events is not None: # This will make HA the only service that receives events. doorstation.device.reset_notifications() # Subscribe to doorbell or motion events subscribe_events(hass, doorstation) hass.data[DOMAIN] = doorstations return True def subscribe_events(hass, doorstation): """Initialize the subscriber.""" for sensor_type in doorstation.monitored_events: name = '{} {}'.format(doorstation.name, SENSOR_TYPES[sensor_type][0]) event_type = SENSOR_TYPES[sensor_type][2] # Get the URL of this server hass_url = hass.config.api.base_url # Override url if another is specified onth configuration if doorstation.custom_url is not None: hass_url = doorstation.custom_url slug = slugify(name) url = '{}{}/{}'.format(hass_url, API_URL, slug) _LOGGER.info("DoorBird will connect to this instance via %s", url) _LOGGER.info("You may use the following event name for automations" ": %s_%s", DOMAIN, slug) doorstation.device.subscribe_notification(event_type, url) class ConfiguredDoorbird(): """Attach additional information to pass along with configured device.""" def __init__(self, device, name, events=None, custom_url=None): """Initialize configured device.""" self._name = name self._device = device self._custom_url = custom_url self._monitored_events = events @property def name(self): """Custom device name.""" return self._name @property def device(self): """The configured device.""" return self._device @property def custom_url(self): """Custom url for device.""" return self._custom_url @property def monitored_events(self): """Get monitored events.""" if self._monitored_events is None: return [] return self._monitored_events class DoorbirdRequestView(HomeAssistantView): """Provide a page for the device to call.""" requires_auth = False url = API_URL name = API_URL[1:].replace('/', ':') extra_urls = [API_URL + '/{sensor}'] # pylint: disable=no-self-use @asyncio.coroutine def get(self, request, sensor): """Respond to requests from the device.""" hass = request.app['hass'] hass.bus.async_fire('{}_{}'.format(DOMAIN, sensor)) return 'OK'