Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions homeassistant/components/camera/doorbird.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@

DEPENDENCIES = ['doorbird']

_CAMERA_LAST_VISITOR = "DoorBird Last Ring"
_CAMERA_LAST_MOTION = "DoorBird Last Motion"
_CAMERA_LIVE = "DoorBird Live"
_CAMERA_LAST_VISITOR = "{} Last Ring"
_CAMERA_LAST_MOTION = "{} Last Motion"
_CAMERA_LIVE = "{} Live"
_LAST_VISITOR_INTERVAL = datetime.timedelta(minutes=1)
_LAST_MOTION_INTERVAL = datetime.timedelta(minutes=1)
_LIVE_INTERVAL = datetime.timedelta(seconds=1)
Expand All @@ -30,16 +30,17 @@
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up the DoorBird camera platform."""
device = hass.data.get(DOORBIRD_DOMAIN)
async_add_devices([
DoorBirdCamera(device.live_image_url, _CAMERA_LIVE, _LIVE_INTERVAL),
DoorBirdCamera(
device.history_image_url(1, 'doorbell'), _CAMERA_LAST_VISITOR,
_LAST_VISITOR_INTERVAL),
DoorBirdCamera(
device.history_image_url(1, 'motionsensor'), _CAMERA_LAST_MOTION,
_LAST_MOTION_INTERVAL),
])
for doorstation in hass.data.get(DOORBIRD_DOMAIN):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use dict.get.

device = doorstation.device
async_add_devices([
DoorBirdCamera(device.live_image_url, _CAMERA_LIVE.format(doorstation.name), _LIVE_INTERVAL),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (105 > 79 characters)

DoorBirdCamera(
device.history_image_url(1, 'doorbell'), _CAMERA_LAST_VISITOR.format(doorstation.name),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (103 > 79 characters)

_LAST_VISITOR_INTERVAL),
DoorBirdCamera(
device.history_image_url(1, 'motionsensor'), _CAMERA_LAST_MOTION.format(doorstation.name),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (106 > 79 characters)

_LAST_MOTION_INTERVAL),
])


class DoorBirdCamera(Camera):
Expand Down
115 changes: 71 additions & 44 deletions homeassistant/components/doorbird.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

import voluptuous as vol

from homeassistant.const import CONF_HOST, CONF_USERNAME, CONF_PASSWORD
from homeassistant.const import CONF_HOST, CONF_USERNAME, CONF_PASSWORD, \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'homeassistant.const.CONF_DEVICES' imported but unused

CONF_DEVICES, CONF_NAME
from homeassistant.components.http import HomeAssistantView
import homeassistant.helpers.config_validation as cv

Expand All @@ -24,14 +25,20 @@
CONF_DOORBELL_EVENTS = 'doorbell_events'
CONF_CUSTOM_URL = 'hass_url_override'

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_DOORBELL_EVENTS): cv.boolean,
vol.Optional(CONF_CUSTOM_URL): cv.string,
vol.Optional(CONF_NAME): cv.string
})

CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_HOST): cv.string,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to suggest this schema:

doorbird:
  gateways:
    - host: <host_ip>
      username: <username>
      password: <password>
      doorbell_events: 1
      name: Side Entry
    - host: <host_ip>
      username: <username>
      password: <password>
      doorbell_events: 1
      name: Front Door

In this case the schema can be extended in future with parameters applied to all gateways without another beaking change of the configuration.

cp. #13517

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This schema is better (extensible)
Although these are not really gateways I think. So gateways should be devices probably.

vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_DOORBELL_EVENTS): cv.boolean,
vol.Optional(CONF_CUSTOM_URL): cv.string,
})
DOMAIN: vol.All(
cv.ensure_list,
[DEVICE_SCHEMA]
),
}, extra=vol.ALLOW_EXTRA)

SENSOR_DOORBELL = 'doorbell'
Expand All @@ -41,57 +48,77 @@ def setup(hass, config):
"""Set up the DoorBird component."""
from doorbirdpy import DoorBird

device_ip = config[DOMAIN].get(CONF_HOST)
username = config[DOMAIN].get(CONF_USERNAME)
password = config[DOMAIN].get(CONF_PASSWORD)

device = DoorBird(device_ip, username, password)
status = device.ready()

if status[0]:
_LOGGER.info("Connected to DoorBird at %s as %s", device_ip, username)
hass.data[DOMAIN] = device
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

if config[DOMAIN].get(CONF_DOORBELL_EVENTS):
# Provide an endpoint for the device to call to trigger events
hass.http.register_view(DoorbirdRequestView())

# Get the URL of this server
hass_url = hass.config.api.base_url

# Override it if another is specified in the component configuration
if config[DOMAIN].get(CONF_CUSTOM_URL):
hass_url = config[DOMAIN].get(CONF_CUSTOM_URL)
doorstations = []

for index, doorstation_config in enumerate(config[DOMAIN]):
device_ip = doorstation_config.get(CONF_HOST)
username = doorstation_config.get(CONF_USERNAME)
password = doorstation_config.get(CONF_PASSWORD)
name = doorstation_config.get(CONF_NAME) or 'DoorBird {}'.format(index + 1)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (83 > 79 characters)


device = DoorBird(device_ip, username, password)
status = device.ready()

if status[0]:
_LOGGER.info("Connected to DoorBird at %s as %s", device_ip, username)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (82 > 79 characters)

doorstations.append(ConfiguredDoorbird(device, name))
elif status[1] == 401:
_LOGGER.error("Authorization rejected by DoorBird at %s", device_ip)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (80 > 79 characters)

return False
else:
_LOGGER.error("Could not connect to DoorBird at %s: Error %s",
device_ip, str(status[1]))
return False

if doorstation_config.get(CONF_DOORBELL_EVENTS):
# Provide an endpoint for the device to call to trigger events
hass.http.register_view(DoorbirdRequestView())

# Get the URL of this server
hass_url = hass.config.api.base_url

# Override it if another is specified in the component configuration

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (80 > 79 characters)

if doorstation_config.get(CONF_CUSTOM_URL):
hass_url = doorstation_config.get(CONF_CUSTOM_URL)

# This will make HA the only service that gets doorbell events
url = '{}{}/{}/{}'.format(hass_url, API_URL, index + 1, SENSOR_DOORBELL)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (84 > 79 characters)


_LOGGER.info("DoorBird will connect to this instance via %s",
hass_url)
url)

# This will make HA the only service that gets doorbell events
url = '{}{}/{}'.format(hass_url, API_URL, SENSOR_DOORBELL)
device.reset_notifications()
device.subscribe_notification(SENSOR_DOORBELL, url)
device.reset_notifications()
device.subscribe_notification(SENSOR_DOORBELL, url)

hass.data[DOMAIN] = doorstations

return True

class ConfiguredDoorbird():

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expected 2 blank lines, found 1

def __init__(self, device, name):
self._name = name
self._device = device

@property
def name(self):
return self._name

@property
def device(self):
return self._device

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}']
extra_urls = [API_URL + '/{index}/{sensor}']

# pylint: disable=no-self-use
@asyncio.coroutine
def get(self, request, sensor):
def get(self, request, index, sensor):
"""Respond to requests from the device."""
hass = request.app['hass']
hass.bus.async_fire('{}_{}'.format(DOMAIN, sensor))
hass.bus.async_fire('{}_{}_{}'.format(DOMAIN, index, sensor))
return 'OK'
29 changes: 17 additions & 12 deletions homeassistant/components/switch/doorbird.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,23 @@

SWITCHES = {
"open_door": {
"name": "Open Door",
"name": "{} Open Door",
"icon": {
True: "lock-open",
False: "lock"
},
"time": datetime.timedelta(seconds=3)
},
"open_door_2": {
"name": "Open Door 2",
"name": "{} Open Door 2",
"icon": {
True: "lock-open",
False: "lock"
},
"time": datetime.timedelta(seconds=3)
},
"light_on": {
"name": "Light On",
"name": "{} Light On",
"icon": {
True: "lightbulb-on",
False: "lightbulb"
Expand All @@ -48,31 +48,36 @@

def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the DoorBird switch platform."""
device = hass.data.get(DOORBIRD_DOMAIN)
for doorstation in hass.data.get(DOORBIRD_DOMAIN):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use dict.get.


switches = []
for switch in SWITCHES:
_LOGGER.debug("Adding DoorBird switch %s", SWITCHES[switch]["name"])
switches.append(DoorBirdSwitch(device, switch))
device = doorstation.device

add_devices(switches)
_LOGGER.info("Added DoorBird switches")
switches = []

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this out of the loop. It's accessed outside the loop.

for switch in SWITCHES:

_LOGGER.debug("Adding DoorBird switch %s",
SWITCHES[switch]["name"].format(doorstation.name))
switches.append(DoorBirdSwitch(device, switch, doorstation.name))

add_devices(switches)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make a single call to add_devices, not one for every station.

_LOGGER.info("Added DoorBird switches")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this. There's already a debug log above and the core will log platforms being setup.



class DoorBirdSwitch(SwitchDevice):
"""A relay in a DoorBird device."""

def __init__(self, device, switch):
def __init__(self, device, switch, name):
"""Initialize a relay in a DoorBird device."""
self._device = device
self._switch = switch
self._name = name
self._state = False
self._assume_off = datetime.datetime.min

@property
def name(self):
"""Return the name of the switch."""
return SWITCHES[self._switch]["name"]
return SWITCHES[self._switch]["name"].format(self._name)

@property
def icon(self):
Expand Down