8000 0.57.3 by balloob · Pull Request #10534 · home-assistant/core · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

0.57.3 #10534

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 11, 2017
Merged

0.57.3 #10534

Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion homeassistant/components/binary_sensor/ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

# Sensor types: Name, category, device_class
SENSOR_TYPES = {
'ding': ['Ding', ['doorbell', 'stickup_cams'], 'occupancy'],
'ding': ['Ding', ['doorbell'], 'occupancy'],
'motion': ['Motion', ['doorbell', 'stickup_cams'], 'motion'],
}

Expand Down
30 changes: 16 additions & 14 deletions homeassistant/components/camera/ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import asyncio
import logging

from datetime import datetime, timedelta
from datetime import timedelta

import voluptuous as vol

Expand All @@ -23,6 +23,8 @@

DEPENDENCIES = ['ring', 'ffmpeg']

FORCE_REFRESH_INTERVAL = timedelta(minutes=45)

_LOGGER = logging.getLogger(__name__)

SCAN_INTERVAL = timedelta(seconds=90)
Expand Down Expand Up @@ -63,8 +65,8 @@ def __init__(self, hass, camera, device_info):
self._ffmpeg_arguments = device_info.get(CONF_FFMPEG_ARGUMENTS)
self._last_video_id = self._camera.last_recording_id
self._video_url = self._camera.recording_url(self._last_video_id)
self._expires_at = None
self._utcnow = None
self._utcnow = dt_util.utcnow()
self._expires_at = FORCE_REFRESH_INTERVAL + self._utcnow

@property
def name(self):
Expand Down Expand Up @@ -123,19 +125,19 @@ def should_poll(self):

def update(self):
"""Update camera entity and refresh attributes."""
# extract the video expiration from URL
x_amz_expires = int(self._video_url.split('&')[0].split('=')[-1])
x_amz_date = self._video_url.split('&')[1].split('=')[-1]
_LOGGER.debug("Checking if Ring DoorBell needs to refresh video_url")

self._camera.update()
self._utcnow = dt_util.utcnow()
self._expires_at = \
timedelta(seconds=x_amz_expires) + \
dt_util.as_utc(datetime.strptime(x_amz_date, "%Y%m%dT%H%M%SZ"))

if self._last_video_id != self._camera.last_recording_id:
_LOGGER.debug("Updated Ring DoorBell last_video_id")
self._last_video_id = self._camera.last_recording_id
last_recording_id = self._camera.last_recording_id

if self._utcnow >= self._expires_at:
_LOGGER.debug("Updated Ring DoorBell video_url")
if self._last_video_id != last_recording_id or \
self._utcnow >= self._expires_at:

_LOGGER.info("Ring DoorBell properties refreshed")

# update attributes if new video or if URL has expired
self._last_video_id = self._camera.last_recording_id
self._video_url = self._camera.recording_url(self._last_video_id)
self._expires_at = FORCE_REFRESH_INTERVAL + self._utcnow
20 changes: 9 additions & 11 deletions homeassistant/components/light/tellstick.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.tellstick/
"""
import voluptuous as vol

from homeassistant.components.light import (
ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, Light)
from homeassistant.components.tellstick import (
DEFAULT_SIGNAL_REPETITIONS, ATTR_DISCOVER_DEVICES, ATTR_DISCOVER_CONFIG,
DOMAIN, TellstickDevice)
DATA_TELLSTICK, TellstickDevice)

PLATFORM_SCHEMA = vol.Schema({vol.Required("platform"): DOMAIN})

SUPPORT_TELLSTICK = SUPPORT_BRIGHTNESS

Expand All @@ -27,17 +25,18 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
signal_repetitions = discovery_info.get(
ATTR_DISCOVER_CONFIG, DEFAULT_SIGNAL_REPETITIONS)

add_devices(TellstickLight(tellcore_id, hass.data['tellcore_registry'],
signal_repetitions)
for tellcore_id in discovery_info[ATTR_DISCOVER_DEVICES])
add_devices([TellstickLight(hass.data[DATA_TELLSTICK][tellcore_id],
signal_repetitions)
for tellcore_id in discovery_info[ATTR_DISCOVER_DEVICES]],
True)


class TellstickLight(TellstickDevice, Light):
"""Representation of a Tellstick light."""

def __init__(self, tellcore_id, tellcore_registry, signal_repetitions):
def __init__(self, tellcore_device, signal_repetitions):
"""Initialize the Tellstick light."""
super().__init__(tellcore_id, tellcore_registry, signal_repetitions)
super().__init__(tellcore_device, signal_repetitions)

self._brightness = 255

Expand All @@ -57,9 +56,8 @@ def _parse_ha_data(self, kwargs):

def _parse_tellcore_data(self, tellcore_data):
"""Turn the value received from tellcore into something useful."""
if tellcore_data is not None:
brightness = int(tellcore_data)
return brightness
if tellcore_data:
return int(tellcore_data) # brightness
return None

def _update_model(self, new_state, data):
E30A Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/sensor/ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
'Last Activity', ['doorbell', 'stickup_cams'], None, 'history', None],

'last_ding': [
'Last Ding', ['doorbell', 'stickup_cams'], None, 'history', 'ding'],
'Last Ding', ['doorbell'], None, 'history', 'ding'],

'last_motion': [
'Last Motion', ['doorbell', 'stickup_cams'], None,
Expand Down
22 changes: 9 additions & 13 deletions homeassistant/components/switch/tellstick.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,11 @@
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/switch.tellstick/
"""
import voluptuous as vol

from homeassistant.components.tellstick import (DEFAULT_SIGNAL_REPETITIONS,
ATTR_DISCOVER_DEVICES,
ATTR_DISCOVER_CONFIG,
DOMAIN, TellstickDevice)
from homeassistant.components.tellstick import (
DEFAULT_SIGNAL_REPETITIONS, ATTR_DISCOVER_DEVICES,
ATTR_DISCOVER_CONFIG, DATA_TELLSTICK, TellstickDevice)
from homeassistant.helpers.entity import ToggleEntity

PLATFORM_SCHEMA = vol.Schema({vol.Required("platform"): DOMAIN})


# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
Expand All @@ -26,21 +21,22 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
signal_repetitions = discovery_info.get(ATTR_DISCOVER_CONFIG,
DEFAULT_SIGNAL_REPETITIONS)

add_devices(TellstickSwitch(tellcore_id, hass.data['tellcore_registry'],
signal_repetitions)
for tellcore_id in discovery_info[ATTR_DISCOVER_DEVICES])
add_devices([TellstickSwitch(hass.data[DATA_TELLSTICK][tellcore_id],
signal_repetitions)
for tellcore_id in discovery_info[ATTR_DISCOVER_DEVICES]],
True)


class TellstickSwitch(TellstickDevice, ToggleEntity):
"""Representation of a Tellstick switch."""

def _parse_ha_data(self, kwargs):
"""Turn the value from HA into something useful."""
return None
pass

def _parse_tellcore_data(self, tellcore_data):
"""Turn the value received from tellcore into something useful."""
return None
pass

def _update_model(self, new_state, data):
"""Update the device entity state to match the arguments."""
Expand Down
118 changes: 46 additions & 72 deletions homeassistant/components/tellstick.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/tellstick/
"""
import asyncio
import logging
import threading

import voluptuous as vol

from homeassistant.helpers import discovery
from homeassistant.core import callback
from homeassistant.const import (
EVENT_HOMEASSISTANT_STOP, CONF_HOST, CONF_PORT)
from homeassistant.helpers.entity import Entity
Expand All @@ -26,6 +28,9 @@
DEFAULT_SIGNAL_REPETITIONS = 1
DOMAIN = 'tellstick'

DATA_TELLSTICK = 'tellstick_device'
SIGNAL_TELLCORE_CALLBACK = 'tellstick_callback'

# Use a global tellstick domain lock to avoid getting Tellcore errors when
# calling concurrently.
TELLSTICK_LOCK = threading.RLock()
Expand Down Expand Up @@ -62,7 +67,7 @@ def _discover(hass, config, component_name, found_tellcore_devices):
def setup(hass, config):
"""Set up the Tellstick component."""
from tellcore.constants import TELLSTICK_DIM
from tellcore.telldus import QueuedCallbackDispatcher
from tellcore.telldus import AsyncioCallbackDispatcher
from tellcore.telldus import TelldusCore
from tellcorenet import TellCoreClient

Expand All @@ -83,85 +88,48 @@ def stop_tellcore_net(event):

try:
tellcore_lib = TelldusCore(
callback_dispatcher=QueuedCallbackDispatcher())
callback_dispatcher=AsyncioCallbackDispatcher(hass.loop))
except OSError:
_LOGGER.exception("Could not initialize Tellstick")
return False

# Get all devices, switches and lights alike
all_tellcore_devices = tellcore_lib.devices()
tellcore_devices = tellcore_lib.devices()

# Register devices
tellcore_registry = TellstickRegistry(hass, tellcore_lib)
tellcore_registry.register_tellcore_devices(all_tellcore_devices)
hass.data['tellcore_registry'] = tellcore_registry
hass.data[DATA_TELLSTICK] = {device.id: device for
device in tellcore_devices}

# Discover the switches
_discover(hass, config, 'switch',
[tellcore_ 10000 device.id for tellcore_device in all_tellcore_devices
if not tellcore_device.methods(TELLSTICK_DIM)])
[device.id for device in tellcore_devices
if not device.methods(TELLSTICK_DIM)])

# Discover the lights
_discover(hass, config, 'light',
[tellcore_device.id for tellcore_device in all_tellcore_devices
if tellcore_device.methods(TELLSTICK_DIM)])

return True


class TellstickRegistry(object):
"""Handle everything around Tellstick callbacks.

Keeps a map device ids to the tellcore device object, and
another to the HA device objects (entities).

Also responsible for registering / cleanup of callbacks, and for
dispatching the callbacks to the corresponding HA device object.

All device specific logic should be elsewhere (Entities).
"""

def __init__(self, hass, tellcore_lib):
"""Initialize the Tellstick mappings and callbacks."""
# used when map callback device id to ha entities.
self._id_to_ha_device_map = {}
self._id_to_tellcore_device_map = {}
self._setup_tellcore_callback(hass, tellcore_lib)
[device.id for device in tellcore_devices
if device.methods(TELLSTICK_DIM)])

def _tellcore_event_callback(self, tellcore_id, tellcore_command,
tellcore_data, cid):
@callback
def async_handle_callback(tellcore_id, tellcore_command,
tellcore_data, cid):
"""Handle the actual callback from Tellcore."""
ha_device = self._id_to_ha_device_map.get(tellcore_id, None)
if ha_device is not None:
# Pass it on to the HA device object
ha_device.update_from_callback(tellcore_command, tellcore_data)
hass.helpers.dispatcher.async_dispatcher_send(
SIGNAL_TELLCORE_CALLBACK, tellcore_id,
tellcore_command, tellcore_data)

def _setup_tellcore_callback(self, hass, tellcore_lib):
"""Register the callback handler."""
callback_id = tellcore_lib.register_device_event(
self._tellcore_event_callback)
# Register callback
callback_id = tellcore_lib.register_device_event(
async_handle_callback)

def clean_up_callback(event):
"""Unregister the callback bindings."""
if callback_id is not None:
tellcore_lib.unregister_callback(callback_id)
_LOGGER.debug("Tellstick callback unregistered")
def clean_up_callback(event):
"""Unregister the callback bindings."""
if callback_id is not None:
tellcore_lib.unregister_callback(callback_id)

hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, clean_up_callback)
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, clean_up_callback)

def register_ha_device(self, tellcore_id, ha_device):
"""Register a new HA device to receive callback updates."""
self._id_to_ha_device_map[tellcore_id] = ha_device

def register_tellcore_devices(self, tellcore_devices):
"""Register a list of devices."""
self._id_to_tellcore_device_map.update(
{tellcore_device.id: tellcore_device for tellcore_device
in tellcore_devices})

def get_tellcore_device(self, tellcore_id):
"""Return a device by tellcore_id."""
return self._id_to_tellcore_device_map.get(tellcore_id, None)
return True


class TellstickDevice(Entity):
Expand All @@ -170,7 +138,7 @@ class TellstickDevice(Entity):
Contains the common logic for all Tellstick devices.
"""

def __init__(self, tellcore_id, tellcore_registry, signal_repetitions):
def __init__(self, tellcore_device, signal_repetitions):
"""Init the Tellstick device."""
self._signal_repetitions = signal_repetitions
self._state = None
Expand All @@ -179,13 +147,16 @@ def __init__(self, tellcore_id, tellcore_registry, signal_repetitions):
self._repeats_left = 0

# Look up our corresponding tellcore device
self._tellcore_device = tellcore_registry.get_tellcore_device(
tellcore_id)
self._name = self._tellcore_device.name
# Query tellcore for the current state
self._update_from_tellcore()
# Add ourselves to the mapping for callbacks
tellcore_registry.register_ha_device(tellcore_id, self)
self._tellcore_device = tellcore_device
self._name = tellcore_device.name

@asyncio.coroutine
def async_added_to_hass(self):
"""Register callbacks."""
self.hass.helpers.dispatcher.async_dispatcher_connect(
SIGNAL_TELLCORE_CALLBACK,
self.update_from_callback
)

@property
def should_poll(self):
Expand Down Expand Up @@ -275,15 +246,19 @@ def _update_model_from_command(self, tellcore_command, tellcore_data):
self._update_model(tellcore_command != TELLSTICK_TURNOFF,
self._parse_tellcore_data(tellcore_data))

def update_from_callback(self, tellcore_command, tellcore_data):
def update_from_callback(self, tellcore_id, tellcore_command,
tellcore_data):
"""Handle updates from the tellcore callback."""
if tellcore_id != self._tellcore_device.id:
return

self._update_model_from_command(tellcore_command, tellcore_data)
self.schedule_update_ha_state()

# This is a benign race on _repeats_left -- it's checked with the lock
# in _send_repeated_command.
if self._repeats_left > 0:
self.hass.async_add_job(self._send_repeated_command)
self._send_repeated_command()

def _update_from_tellcore(self):
"""Read the current state of the device from the tellcore library."""
Expand All @@ -303,4 +278,3 @@ def _update_from_tellcore(self):
def update(self):
"""Poll the current state of the device."""
self._update_from_tellcore()
self.schedule_update_ha_state()
2 changes: 1 addition & 1 deletion homeassistant/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""Constants used by Home Assistant components."""
MAJOR_VERSION = 0
MINOR_VERSION = 57
PATCH_VERSION = '2'
PATCH_VERSION = '3'
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
REQUIRED_PYTHON_VER = (3, 4, 2)
Expand Down
1 change: 1 addition & 0 deletions homeassistant/package_constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ jinja2>=2.9.6
voluptuous==0.10.5
typing>=3,<4
aiohttp==2.2.5
yarl==0.13
async_timeout==2.0.0
chardet==3.0.4
astral==1.4
Expand Down
Loading
0