Fixes for PEP257 (#11810)

* Fixes for PEP257

* More updates
This commit is contained in:
Fabian Affolter 2018-01-21 07:35:38 +01:00 committed by Paulus Schoutsen
parent 0100f87ff2
commit 47e31dc9ee
143 changed files with 1584 additions and 1761 deletions

View file

@ -1,9 +1,8 @@
""" """
ADS Component. Support for Automation Device Specification (ADS).
For more details about this component, please refer to the documentation. For more details about this component, please refer to the documentation.
https://home-assistant.io/components/ads/ https://home-assistant.io/components/ads/
""" """
import threading import threading
import struct import struct
@ -29,7 +28,6 @@ ADSTYPE_BOOL = 'bool'
DOMAIN = 'ads' DOMAIN = 'ads'
# config variable names
CONF_ADS_VAR = 'adsvar' CONF_ADS_VAR = 'adsvar'
CONF_ADS_VAR_BRIGHTNESS = 'adsvar_brightness' CONF_ADS_VAR_BRIGHTNESS = 'adsvar_brightness'
CONF_ADS_TYPE = 'adstype' CONF_ADS_TYPE = 'adstype'
@ -47,10 +45,10 @@ CONFIG_SCHEMA = vol.Schema({
}, extra=vol.ALLOW_EXTRA) }, extra=vol.ALLOW_EXTRA)
SCHEMA_SERVICE_WRITE_DATA_BY_NAME = vol.Schema({ SCHEMA_SERVICE_WRITE_DATA_BY_NAME = vol.Schema({
vol.Required(CONF_ADS_TYPE):
vol.In([ADSTYPE_INT, ADSTYPE_UINT, ADSTYPE_BYTE]),
vol.Required(CONF_ADS_VALUE): cv.match_all,
vol.Required(CONF_ADS_VAR): cv.string, vol.Required(CONF_ADS_VAR): cv.string,
vol.Required(CONF_ADS_TYPE): vol.In([ADSTYPE_INT, ADSTYPE_UINT,
ADSTYPE_BYTE]),
vol.Required(CONF_ADS_VALUE): cv.match_all
}) })
@ -59,15 +57,12 @@ def setup(hass, config):
import pyads import pyads
conf = config[DOMAIN] conf = config[DOMAIN]
# get ads connection parameters from config
net_id = conf.get(CONF_DEVICE) net_id = conf.get(CONF_DEVICE)
ip_address = conf.get(CONF_IP_ADDRESS) ip_address = conf.get(CONF_IP_ADDRESS)
port = conf.get(CONF_PORT) port = conf.get(CONF_PORT)
# create a new ads connection
client = pyads.Connection(net_id, port, ip_address) client = pyads.Connection(net_id, port, ip_address)
# add some constants to AdsHub
AdsHub.ADS_TYPEMAP = { AdsHub.ADS_TYPEMAP = {
ADSTYPE_BOOL: pyads.PLCTYPE_BOOL, ADSTYPE_BOOL: pyads.PLCTYPE_BOOL,
ADSTYPE_BYTE: pyads.PLCTYPE_BYTE, ADSTYPE_BYTE: pyads.PLCTYPE_BYTE,
@ -81,16 +76,13 @@ def setup(hass, config):
AdsHub.PLCTYPE_UINT = pyads.PLCTYPE_UINT AdsHub.PLCTYPE_UINT = pyads.PLCTYPE_UINT
AdsHub.ADSError = pyads.ADSError AdsHub.ADSError = pyads.ADSError
# connect to ads client and try to connect
try: try:
ads = AdsHub(client) ads = AdsHub(client)
except pyads.pyads.ADSError: except pyads.pyads.ADSError:
_LOGGER.error( _LOGGER.error(
'Could not connect to ADS host (netid=%s, port=%s)', net_id, port "Could not connect to ADS host (netid=%s, port=%s)", net_id, port)
)
return False return False
# add ads hub to hass data collection, listen to shutdown
hass.data[DATA_ADS] = ads hass.data[DATA_ADS] = ads
hass.bus.listen(EVENT_HOMEASSISTANT_STOP, ads.shutdown) hass.bus.listen(EVENT_HOMEASSISTANT_STOP, ads.shutdown)
@ -107,43 +99,41 @@ def setup(hass, config):
hass.services.register( hass.services.register(
DOMAIN, SERVICE_WRITE_DATA_BY_NAME, handle_write_data_by_name, DOMAIN, SERVICE_WRITE_DATA_BY_NAME, handle_write_data_by_name,
schema=SCHEMA_SERVICE_WRITE_DATA_BY_NAME schema=SCHEMA_SERVICE_WRITE_DATA_BY_NAME)
)
return True return True
# tuple to hold data needed for notification # Tuple to hold data needed for notification
NotificationItem = namedtuple( NotificationItem = namedtuple(
'NotificationItem', 'hnotify huser name plc_datatype callback' 'NotificationItem', 'hnotify huser name plc_datatype callback'
) )
class AdsHub: class AdsHub(object):
"""Representation of a PyADS connection.""" """Representation of an ADS connection."""
def __init__(self, ads_client): def __init__(self, ads_client):
"""Initialize the ADS Hub.""" """Initialize the ADS hub."""
self._client = ads_client self._client = ads_client
self._client.open() self._client.open()
# all ADS devices are registered here # All ADS devices are registered here
self._devices = [] self._devices = []
self._notification_items = {} self._notification_items = {}
self._lock = threading.Lock() self._lock = threading.Lock()
def shutdown(self, *args, **kwargs): def shutdown(self, *args, **kwargs):
"""Shutdown ADS connection.""" """Shutdown ADS connection."""
_LOGGER.debug('Shutting down ADS') _LOGGER.debug("Shutting down ADS")
for notification_item in self._notification_items.values(): for notification_item in self._notification_items.values():
self._client.del_device_notification( self._client.del_device_notification(
notification_item.hnotify, notification_item.hnotify,
notification_item.huser notification_item.huser
) )
_LOGGER.debug( _LOGGER.debug(
'Deleting device notification %d, %d', "Deleting device notification %d, %d",
notification_item.hnotify, notification_item.huser notification_item.hnotify, notification_item.huser)
)
self._client.close() self._client.close()
def register_device(self, device): def register_device(self, device):
@ -167,33 +157,30 @@ class AdsHub:
with self._lock: with self._lock:
hnotify, huser = self._client.add_device_notification( hnotify, huser = self._client.add_device_notification(
name, attr, self._device_notification_callback name, attr, self._device_notification_callback)
)
hnotify = int(hnotify) hnotify = int(hnotify)
_LOGGER.debug( _LOGGER.debug(
'Added Device Notification %d for variable %s', hnotify, name "Added device notification %d for variable %s", hnotify, name)
)
self._notification_items[hnotify] = NotificationItem( self._notification_items[hnotify] = NotificationItem(
hnotify, huser, name, plc_datatype, callback hnotify, huser, name, plc_datatype, callback)
)
def _device_notification_callback(self, addr, notification, huser): def _device_notification_callback(self, addr, notification, huser):
"""Handle device notifications.""" """Handle device notifications."""
contents = notification.contents contents = notification.contents
hnotify = int(contents.hNotification) hnotify = int(contents.hNotification)
_LOGGER.debug('Received Notification %d', hnotify) _LOGGER.debug("Received notification %d", hnotify)
data = contents.data data = contents.data
try: try:
notification_item = self._notification_items[hnotify] notification_item = self._notification_items[hnotify]
except KeyError: except KeyError:
_LOGGER.debug('Unknown Device Notification handle: %d', hnotify) _LOGGER.debug("Unknown device notification handle: %d", hnotify)
return return
# parse data to desired datatype # Parse data to desired datatype
if notification_item.plc_datatype == self.PLCTYPE_BOOL: if notification_item.plc_datatype == self.PLCTYPE_BOOL:
value = bool(struct.unpack('<?', bytearray(data)[:1])[0]) value = bool(struct.unpack('<?', bytearray(data)[:1])[0])
elif notification_item.plc_datatype == self.PLCTYPE_INT: elif notification_item.plc_datatype == self.PLCTYPE_INT:
@ -204,7 +191,6 @@ class AdsHub:
value = struct.unpack('<H', bytearray(data)[:2])[0] value = struct.unpack('<H', bytearray(data)[:2])[0]
else: else:
value = bytearray(data) value = bytearray(data)
_LOGGER.warning('No callback available for this datatype.') _LOGGER.warning("No callback available for this datatype")
# execute callback
notification_item.callback(notification_item.name, value) notification_item.callback(notification_item.name, value)

View file

@ -6,12 +6,12 @@ https://home-assistant.io/components/alarm_control_panel.abode/
""" """
import logging import logging
from homeassistant.components.abode import ( from homeassistant.components.abode import CONF_ATTRIBUTION, AbodeDevice
AbodeDevice, DOMAIN as ABODE_DOMAIN, CONF_ATTRIBUTION) from homeassistant.components.abode import DOMAIN as ABODE_DOMAIN
from homeassistant.components.alarm_control_panel import (AlarmControlPanel) from homeassistant.components.alarm_control_panel import AlarmControlPanel
from homeassistant.const import (ATTR_ATTRIBUTION, STATE_ALARM_ARMED_AWAY, from homeassistant.const import (
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED) ATTR_ATTRIBUTION, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_DISARMED)
DEPENDENCIES = ['abode'] DEPENDENCIES = ['abode']
@ -21,7 +21,7 @@ ICON = 'mdi:security'
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up a sensor for an Abode device.""" """Set up an alarm control panel for an Abode device."""
data = hass.data[ABODE_DOMAIN] data = hass.data[ABODE_DOMAIN]
alarm_devices = [AbodeAlarm(data, data.abode.get_alarm(), data.name)] alarm_devices = [AbodeAlarm(data, data.abode.get_alarm(), data.name)]
@ -41,7 +41,7 @@ class AbodeAlarm(AbodeDevice, AlarmControlPanel):
@property @property
def icon(self): def icon(self):
"""Return icon.""" """Return the icon."""
return ICON return ICON
@property @property
@ -81,5 +81,5 @@ class AbodeAlarm(AbodeDevice, AlarmControlPanel):
ATTR_ATTRIBUTION: CONF_ATTRIBUTION, ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
'device_id': self._device.device_id, 'device_id': self._device.device_id,
'battery_backup': self._device.battery, 'battery_backup': self._device.battery,
'cellular_backup': self._device.is_cellular 'cellular_backup': self._device.is_cellular,
} }

View file

@ -10,12 +10,11 @@ import logging
import voluptuous as vol import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm import homeassistant.components.alarm_control_panel as alarm
import homeassistant.helpers.config_validation as cv from homeassistant.components.alarmdecoder import DATA_AD, SIGNAL_PANEL_MESSAGE
from homeassistant.components.alarmdecoder import (
DATA_AD, SIGNAL_PANEL_MESSAGE)
from homeassistant.const import ( from homeassistant.const import (
ATTR_CODE, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, ATTR_CODE, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED) STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED)
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -67,6 +66,7 @@ class AlarmDecoderAlarmPanel(alarm.AlarmControlPanel):
SIGNAL_PANEL_MESSAGE, self._message_callback) SIGNAL_PANEL_MESSAGE, self._message_callback)
def _message_callback(self, message): def _message_callback(self, message):
"""Handle received messages."""
if message.alarm_sounding or message.fire_alarm: if message.alarm_sounding or message.fire_alarm:
self._state = STATE_ALARM_TRIGGERED self._state = STATE_ALARM_TRIGGERED
elif message.armed_away: elif message.armed_away:
@ -120,7 +120,7 @@ class AlarmDecoderAlarmPanel(alarm.AlarmControlPanel):
'entry_delay_off': self._entry_delay_off, 'entry_delay_off': self._entry_delay_off,
'programming_mode': self._programming_mode, 'programming_mode': self._programming_mode,
'ready': self._ready, 'ready': self._ready,
'zone_bypassed': self._zone_bypassed 'zone_bypassed': self._zone_bypassed,
} }
def alarm_disarm(self, code=None): def alarm_disarm(self, code=None):

View file

@ -4,17 +4,18 @@ Interfaces with Alarm.com alarm control panels.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.alarmdotcom/ https://home-assistant.io/components/alarm_control_panel.alarmdotcom/
""" """
import logging
import asyncio import asyncio
import logging
import voluptuous as vol import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA
from homeassistant.const import ( from homeassistant.const import (
CONF_PASSWORD, CONF_USERNAME, STATE_ALARM_ARMED_AWAY, CONF_CODE, CONF_NAME, CONF_PASSWORD, CONF_USERNAME, STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_UNKNOWN, CONF_CODE, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_UNKNOWN)
CONF_NAME)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pyalarmdotcom==0.3.0'] REQUIREMENTS = ['pyalarmdotcom==0.3.0']
@ -44,7 +45,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
class AlarmDotCom(alarm.AlarmControlPanel): class AlarmDotCom(alarm.AlarmControlPanel):
"""Represent an Alarm.com status.""" """Representation of an Alarm.com status."""
def __init__(self, hass, name, code, username, password): def __init__(self, hass, name, code, username, password):
"""Initialize the Alarm.com status.""" """Initialize the Alarm.com status."""
@ -57,10 +58,8 @@ class AlarmDotCom(alarm.AlarmControlPanel):
self._password = password self._password = password
self._websession = async_get_clientsession(self._hass) self._websession = async_get_clientsession(self._hass)
self._state = STATE_UNKNOWN self._state = STATE_UNKNOWN
self._alarm = Alarmdotcom(username, self._alarm = Alarmdotcom(
password, username, password, self._websession, hass.loop)
self._websession,
hass.loop)
@asyncio.coroutine @asyncio.coroutine
def async_login(self): def async_login(self):
@ -80,7 +79,7 @@ class AlarmDotCom(alarm.AlarmControlPanel):
@property @property
def code_format(self): def code_format(self):
"""One or more characters if code is defined.""" """Return one or more characters if code is defined."""
return None if self._code is None else '.+' return None if self._code is None else '.+'
@property @property
@ -116,5 +115,5 @@ class AlarmDotCom(alarm.AlarmControlPanel):
"""Validate given code.""" """Validate given code."""
check = self._code is None or code == self._code check = self._code is None or code == self._code
if not check: if not check:
_LOGGER.warning('Wrong code entered.') _LOGGER.warning("Wrong code entered")
return check return check

View file

@ -29,9 +29,9 @@ DEFAULT_PORT = 5007
SCAN_INTERVAL = timedelta(seconds=1) SCAN_INTERVAL = timedelta(seconds=1)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string, vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
}) })
@ -47,7 +47,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices([Concord232Alarm(hass, url, name)]) add_devices([Concord232Alarm(hass, url, name)])
except requests.exceptions.ConnectionError as ex: except requests.exceptions.ConnectionError as ex:
_LOGGER.error("Unable to connect to Concord232: %s", str(ex)) _LOGGER.error("Unable to connect to Concord232: %s", str(ex))
return False return
class Concord232Alarm(alarm.AlarmControlPanel): class Concord232Alarm(alarm.AlarmControlPanel):
@ -107,7 +107,7 @@ class Concord232Alarm(alarm.AlarmControlPanel):
newstate = STATE_ALARM_ARMED_AWAY newstate = STATE_ALARM_ARMED_AWAY
if not newstate == self._state: if not newstate == self._state:
_LOGGER.info("State Change from %s to %s", self._state, newstate) _LOGGER.info("State change from %s to %s", self._state, newstate)
self._state = newstate self._state = newstate
return self._state return self._state

View file

@ -10,13 +10,13 @@ import requests
import voluptuous as vol import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm import homeassistant.components.alarm_control_panel as alarm
import homeassistant.exceptions as exc
import homeassistant.helpers.config_validation as cv
from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA
from homeassistant.const import ( from homeassistant.const import (
CONF_PORT, CONF_HOST, CONF_PASSWORD, CONF_USERNAME, STATE_UNKNOWN, CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_PORT, CONF_USERNAME,
CONF_NAME, STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME, EVENT_HOMEASSISTANT_STOP, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_AWAY, STATE_ALARM_TRIGGERED, EVENT_HOMEASSISTANT_STOP) STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED, STATE_UNKNOWN)
import homeassistant.exceptions as exc
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pythonegardia==1.0.26'] REQUIREMENTS = ['pythonegardia==1.0.26']
@ -35,6 +35,7 @@ DEFAULT_REPORT_SERVER_PORT = 52010
DEFAULT_VERSION = 'GATE-01' DEFAULT_VERSION = 'GATE-01'
DOMAIN = 'egardia' DOMAIN = 'egardia'
D_EGARDIASRV = 'egardiaserver' D_EGARDIASRV = 'egardiaserver'
NOTIFICATION_ID = 'egardia_notification' NOTIFICATION_ID = 'egardia_notification'
NOTIFICATION_TITLE = 'Egardia' NOTIFICATION_TITLE = 'Egardia'
@ -97,8 +98,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
server = egardiaserver.EgardiaServer('', rs_port) server = egardiaserver.EgardiaServer('', rs_port)
bound = server.bind() bound = server.bind()
if not bound: if not bound:
raise IOError("Binding error occurred while " + raise IOError(
"starting EgardiaServer") "Binding error occurred while starting EgardiaServer")
hass.data[D_EGARDIASRV] = server hass.data[D_EGARDIASRV] = server
server.start() server.start()
except IOError: except IOError:
@ -106,22 +107,19 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
hass.data[D_EGARDIASRV].register_callback(eg_dev.handle_status_event) hass.data[D_EGARDIASRV].register_callback(eg_dev.handle_status_event)
def handle_stop_event(event): def handle_stop_event(event):
"""Callback function for HA stop event.""" """Call function for Home Assistant stop event."""
hass.data[D_EGARDIASRV].stop() hass.data[D_EGARDIASRV].stop()
# listen to home assistant stop event
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, handle_stop_event) hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, handle_stop_event)
# add egardia alarm device
add_devices([eg_dev], True) add_devices([eg_dev], True)
class EgardiaAlarm(alarm.AlarmControlPanel): class EgardiaAlarm(alarm.AlarmControlPanel):
"""Representation of a Egardia alarm.""" """Representation of a Egardia alarm."""
def __init__(self, name, egardiasystem, def __init__(self, name, egardiasystem, rs_enabled=False, rs_codes=None):
rs_enabled=False, rs_codes=None): """Initialize the Egardia alarm."""
"""Initialize object."""
self._name = name self._name = name
self._egardiasystem = egardiasystem self._egardiasystem = egardiasystem
self._status = None self._status = None
@ -149,7 +147,7 @@ class EgardiaAlarm(alarm.AlarmControlPanel):
return False return False
def handle_status_event(self, event): def handle_status_event(self, event):
"""Handle egardia_system_status_event.""" """Handle the Egardia system status event."""
statuscode = event.get('status') statuscode = event.get('status')
if statuscode is not None: if statuscode is not None:
status = self.lookupstatusfromcode(statuscode) status = self.lookupstatusfromcode(statuscode)

View file

@ -8,12 +8,12 @@ import logging
import voluptuous as vol import voluptuous as vol
import homeassistant.helpers.config_validation as cv
import homeassistant.components.alarm_control_panel as alarm import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA
from homeassistant.const import ( from homeassistant.const import (
CONF_PASSWORD, CONF_USERNAME, CONF_HOST, STATE_ALARM_ARMED_AWAY, CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_USERNAME, STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, CONF_NAME) STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pyialarm==0.2'] REQUIREMENTS = ['pyialarm==0.2']
@ -33,9 +33,9 @@ def no_application_protocol(value):
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): vol.All(cv.string, no_application_protocol),
vol.Required(CONF_PASSWORD): cv.string, vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_USERNAME): cv.string, vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_HOST): vol.All(cv.string, no_application_protocol),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
}) })
@ -53,7 +53,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class IAlarmPanel(alarm.AlarmControlPanel): class IAlarmPanel(alarm.AlarmControlPanel):
"""Represent an iAlarm status.""" """Representation of an iAlarm status."""
def __init__(self, name, username, password, url): def __init__(self, name, username, password, url):
"""Initialize the iAlarm status.""" """Initialize the iAlarm status."""

View file

@ -11,15 +11,17 @@ import logging
import voluptuous as vol import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm import homeassistant.components.alarm_control_panel as alarm
import homeassistant.util.dt as dt_util
from homeassistant.const import ( from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_NIGHT, CONF_CODE, CONF_DELAY_TIME, CONF_DISARM_AFTER_TRIGGER, CONF_NAME,
STATE_ALARM_ARMED_CUSTOM_BYPASS, STATE_ALARM_DISARMED, STATE_ALARM_PENDING, CONF_PENDING_TIME, CONF_PLATFORM, CONF_TRIGGER_TIME,
STATE_ALARM_TRIGGERED, CONF_PLATFORM, CONF_NAME, CONF_CODE, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_CUSTOM_BYPASS,
CONF_DELAY_TIME, CONF_PENDING_TIME, CONF_TRIGGER_TIME, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_NIGHT, STATE_ALARM_DISARMED,
CONF_DISARM_AFTER_TRIGGER) STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.event import track_point_in_time from homeassistant.helpers.event import track_point_in_time
import homeassistant.util.dt as dt_util
_LOGGER = logging.getLogger(__name__)
CONF_CODE_TEMPLATE = 'code_template' CONF_CODE_TEMPLATE = 'code_template'
@ -44,6 +46,7 @@ ATTR_POST_PENDING_STATE = 'post_pending_state'
def _state_validator(config): def _state_validator(config):
"""Validate the state."""
config = copy.deepcopy(config) config = copy.deepcopy(config)
for state in SUPPORTED_PRETRIGGER_STATES: for state in SUPPORTED_PRETRIGGER_STATES:
if CONF_DELAY_TIME not in config[state]: if CONF_DELAY_TIME not in config[state]:
@ -58,6 +61,7 @@ def _state_validator(config):
def _state_schema(state): def _state_schema(state):
"""Validate the state."""
schema = {} schema = {}
if state in SUPPORTED_PRETRIGGER_STATES: if state in SUPPORTED_PRETRIGGER_STATES:
schema[vol.Optional(CONF_DELAY_TIME)] = vol.All( schema[vol.Optional(CONF_DELAY_TIME)] = vol.All(
@ -97,8 +101,6 @@ PLATFORM_SCHEMA = vol.Schema(vol.All({
_state_schema(STATE_ALARM_TRIGGERED), _state_schema(STATE_ALARM_TRIGGERED),
}, _state_validator)) }, _state_validator))
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the manual alarm platform.""" """Set up the manual alarm platform."""
@ -151,7 +153,7 @@ class ManualAlarm(alarm.AlarmControlPanel):
@property @property
def should_poll(self): def should_poll(self):
"""Return the plling state.""" """Return the polling state."""
return False return False
@property @property
@ -182,23 +184,26 @@ class ManualAlarm(alarm.AlarmControlPanel):
@property @property
def _active_state(self): def _active_state(self):
"""Get the current state."""
if self.state == STATE_ALARM_PENDING: if self.state == STATE_ALARM_PENDING:
return self._previous_state return self._previous_state
else: else:
return self._state return self._state
def _pending_time(self, state): def _pending_time(self, state):
"""Get the pending time."""
pending_time = self._pending_time_by_state[state] pending_time = self._pending_time_by_state[state]
if state == STATE_ALARM_TRIGGERED: if state == STATE_ALARM_TRIGGERED:
pending_time += self._delay_time_by_state[self._previous_state] pending_time += self._delay_time_by_state[self._previous_state]
return pending_time return pending_time
def _within_pending_time(self, state): def _within_pending_time(self, state):
"""Get if the action is in the pending time window."""
return self._state_ts + self._pending_time(state) > dt_util.utcnow() return self._state_ts + self._pending_time(state) > dt_util.utcnow()
@property @property
def code_format(self): def code_format(self):
"""One or more characters.""" """Return one or more characters."""
return None if self._code is None else '.+' return None if self._code is None else '.+'
def alarm_disarm(self, code=None): def alarm_disarm(self, code=None):
@ -250,6 +255,7 @@ class ManualAlarm(alarm.AlarmControlPanel):
self._update_state(STATE_ALARM_TRIGGERED) self._update_state(STATE_ALARM_TRIGGERED)
def _update_state(self, state): def _update_state(self, state):
"""Update the state."""
if self._state == state: if self._state == state:
return return

View file

@ -26,6 +26,8 @@ from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.event import track_point_in_time from homeassistant.helpers.event import track_point_in_time
_LOGGER = logging.getLogger(__name__)
CONF_CODE_TEMPLATE = 'code_template' CONF_CODE_TEMPLATE = 'code_template'
CONF_PAYLOAD_DISARM = 'payload_disarm' CONF_PAYLOAD_DISARM = 'payload_disarm'
@ -58,6 +60,7 @@ ATTR_POST_PENDING_STATE = 'post_pending_state'
def _state_validator(config): def _state_validator(config):
"""Validate the state."""
config = copy.deepcopy(config) config = copy.deepcopy(config)
for state in SUPPORTED_PRETRIGGER_STATES: for state in SUPPORTED_PRETRIGGER_STATES:
if CONF_DELAY_TIME not in config[state]: if CONF_DELAY_TIME not in config[state]:
@ -72,6 +75,7 @@ def _state_validator(config):
def _state_schema(state): def _state_schema(state):
"""Validate the state."""
schema = {} schema = {}
if state in SUPPORTED_PRETRIGGER_STATES: if state in SUPPORTED_PRETRIGGER_STATES:
schema[vol.Optional(CONF_DELAY_TIME)] = vol.All( schema[vol.Optional(CONF_DELAY_TIME)] = vol.All(
@ -117,8 +121,6 @@ PLATFORM_SCHEMA = vol.Schema(vol.All(mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_PAYLOAD_DISARM, default=DEFAULT_DISARM): cv.string, vol.Optional(CONF_PAYLOAD_DISARM, default=DEFAULT_DISARM): cv.string,
}), _state_validator)) }), _state_validator))
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the manual MQTT alarm platform.""" """Set up the manual MQTT alarm platform."""
@ -150,11 +152,10 @@ class ManualMQTTAlarm(alarm.AlarmControlPanel):
A trigger_time of zero disables the alarm_trigger service. A trigger_time of zero disables the alarm_trigger service.
""" """
def __init__(self, hass, name, code, code_template, def __init__(self, hass, name, code, code_template, disarm_after_trigger,
disarm_after_trigger, state_topic, command_topic, qos, payload_disarm,
state_topic, command_topic, qos, payload_arm_home, payload_arm_away, payload_arm_night,
payload_disarm, payload_arm_home, payload_arm_away, config):
payload_arm_night, config):
"""Init the manual MQTT alarm panel.""" """Init the manual MQTT alarm panel."""
self._state = STATE_ALARM_DISARMED self._state = STATE_ALARM_DISARMED
self._hass = hass self._hass = hass
@ -219,23 +220,26 @@ class ManualMQTTAlarm(alarm.AlarmControlPanel):
@property @property
def _active_state(self): def _active_state(self):
"""Get the current state."""
if self.state == STATE_ALARM_PENDING: if self.state == STATE_ALARM_PENDING:
return self._previous_state return self._previous_state
else: else:
return self._state return self._state
def _pending_time(self, state): def _pending_time(self, state):
"""Get the pending time."""
pending_time = self._pending_time_by_state[state] pending_time = self._pending_time_by_state[state]
if state == STATE_ALARM_TRIGGERED: if state == STATE_ALARM_TRIGGERED:
pending_time += self._delay_time_by_state[self._previous_state] pending_time += self._delay_time_by_state[self._previous_state]
return pending_time return pending_time
def _within_pending_time(self, state): def _within_pending_time(self, state):
"""Get if the action is in the pending time window."""
return self._state_ts + self._pending_time(state) > dt_util.utcnow() return self._state_ts + self._pending_time(state) > dt_util.utcnow()
@property @property
def code_format(self): def code_format(self):
"""One or more characters.""" """Return one or more characters."""
return None if self._code is None else '.+' return None if self._code is None else '.+'
def alarm_disarm(self, code=None): def alarm_disarm(self, code=None):
@ -280,6 +284,7 @@ class ManualMQTTAlarm(alarm.AlarmControlPanel):
self._update_state(STATE_ALARM_TRIGGERED) self._update_state(STATE_ALARM_TRIGGERED)
def _update_state(self, state): def _update_state(self, state):
"""Update the state."""
if self._state == state: if self._state == state:
return return
@ -329,7 +334,7 @@ class ManualMQTTAlarm(alarm.AlarmControlPanel):
return state_attr return state_attr
def async_added_to_hass(self): def async_added_to_hass(self):
"""Subscribe mqtt events. """Subscribe to MQTT events.
This method must be run in the event loop and returns a coroutine. This method must be run in the event loop and returns a coroutine.
""" """
@ -358,5 +363,5 @@ class ManualMQTTAlarm(alarm.AlarmControlPanel):
@asyncio.coroutine @asyncio.coroutine
def _async_state_changed_listener(self, entity_id, old_state, new_state): def _async_state_changed_listener(self, entity_id, old_state, new_state):
"""Publish state change to MQTT.""" """Publish state change to MQTT."""
mqtt.async_publish(self.hass, self._state_topic, new_state.state, mqtt.async_publish(
self._qos, True) self.hass, self._state_topic, new_state.state, self._qos, True)

View file

@ -12,8 +12,8 @@ import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA
from homeassistant.const import ( from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, CONF_HOST, CONF_NAME, CONF_PORT, STATE_ALARM_ARMED_AWAY,
STATE_UNKNOWN, CONF_NAME, CONF_HOST, CONF_PORT) STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_UNKNOWN)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pynx584==0.4'] REQUIREMENTS = ['pynx584==0.4']
@ -25,14 +25,14 @@ DEFAULT_NAME = 'NX584'
DEFAULT_PORT = 5007 DEFAULT_PORT = 5007
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string, vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
}) })
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the nx584 platform.""" """Set up the NX584 platform."""
name = config.get(CONF_NAME) name = config.get(CONF_NAME)
host = config.get(CONF_HOST) host = config.get(CONF_HOST)
port = config.get(CONF_PORT) port = config.get(CONF_PORT)
@ -88,7 +88,7 @@ class NX584Alarm(alarm.AlarmControlPanel):
self._state = STATE_UNKNOWN self._state = STATE_UNKNOWN
zones = [] zones = []
except IndexError: except IndexError:
_LOGGER.error("nx584 reports no partitions") _LOGGER.error("NX584 reports no partitions")
self._state = STATE_UNKNOWN self._state = STATE_UNKNOWN
zones = [] zones = []

View file

@ -8,9 +8,8 @@ import asyncio
import logging import logging
import homeassistant.components.alarm_control_panel as alarm import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.satel_integra import (CONF_ARM_HOME_MODE, from homeassistant.components.satel_integra import (
DATA_SATEL, CONF_ARM_HOME_MODE, DATA_SATEL, SIGNAL_PANEL_MESSAGE)
SIGNAL_PANEL_MESSAGE)
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
@ -21,12 +20,12 @@ DEPENDENCIES = ['satel_integra']
@asyncio.coroutine @asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None): def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up for AlarmDecoder alarm panels.""" """Set up for Satel Integra alarm panels."""
if not discovery_info: if not discovery_info:
return return
device = SatelIntegraAlarmPanel("Alarm Panel", device = SatelIntegraAlarmPanel(
discovery_info.get(CONF_ARM_HOME_MODE)) "Alarm Panel", discovery_info.get(CONF_ARM_HOME_MODE))
async_add_devices([device]) async_add_devices([device])
@ -47,7 +46,7 @@ class SatelIntegraAlarmPanel(alarm.AlarmControlPanel):
@callback @callback
def _message_callback(self, message): def _message_callback(self, message):
"""Handle received messages."""
if message != self._state: if message != self._state:
self._state = message self._state = message
self.async_schedule_update_ha_state() self.async_schedule_update_ha_state()
@ -90,5 +89,5 @@ class SatelIntegraAlarmPanel(alarm.AlarmControlPanel):
def async_alarm_arm_home(self, code=None): def async_alarm_arm_home(self, code=None):
"""Send arm home command.""" """Send arm home command."""
if code: if code:
yield from self.hass.data[DATA_SATEL].arm(code, yield from self.hass.data[DATA_SATEL].arm(
self._arm_home_mode) code, self._arm_home_mode)

View file

@ -11,9 +11,9 @@ import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA
from homeassistant.const import ( from homeassistant.const import (
CONF_PASSWORD, CONF_USERNAME, STATE_UNKNOWN, CONF_CODE, CONF_NAME, CONF_CODE, CONF_NAME, CONF_PASSWORD, CONF_USERNAME,
STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_AWAY, EVENT_HOMEASSISTANT_STOP, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
EVENT_HOMEASSISTANT_STOP) STATE_ALARM_DISARMED, STATE_UNKNOWN)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['simplisafe-python==1.0.5'] REQUIREMENTS = ['simplisafe-python==1.0.5']
@ -22,6 +22,7 @@ _LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = 'SimpliSafe' DEFAULT_NAME = 'SimpliSafe'
DOMAIN = 'simplisafe' DOMAIN = 'simplisafe'
NOTIFICATION_ID = 'simplisafe_notification' NOTIFICATION_ID = 'simplisafe_notification'
NOTIFICATION_TITLE = 'SimpliSafe Setup' NOTIFICATION_TITLE = 'SimpliSafe Setup'
@ -65,7 +66,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class SimpliSafeAlarm(alarm.AlarmControlPanel): class SimpliSafeAlarm(alarm.AlarmControlPanel):
"""Representation a SimpliSafe alarm.""" """Representation of a SimpliSafe alarm."""
def __init__(self, simplisafe, name, code): def __init__(self, simplisafe, name, code):
"""Initialize the SimpliSafe alarm.""" """Initialize the SimpliSafe alarm."""
@ -82,7 +83,7 @@ class SimpliSafeAlarm(alarm.AlarmControlPanel):
@property @property
def code_format(self): def code_format(self):
"""One or more characters if code is defined.""" """Return one or more characters if code is defined."""
return None if self._code is None else '.+' return None if self._code is None else '.+'
@property @property
@ -103,12 +104,12 @@ class SimpliSafeAlarm(alarm.AlarmControlPanel):
def device_state_attributes(self): def device_state_attributes(self):
"""Return the state attributes.""" """Return the state attributes."""
return { return {
'temperature': self.simplisafe.temperature(), 'alarm': self.simplisafe.alarm(),
'co': self.simplisafe.carbon_monoxide(), 'co': self.simplisafe.carbon_monoxide(),
'fire': self.simplisafe.fire(), 'fire': self.simplisafe.fire(),
'alarm': self.simplisafe.alarm(), 'flood': self.simplisafe.flood(),
'last_event': self.simplisafe.last_event(), 'last_event': self.simplisafe.last_event(),
'flood': self.simplisafe.flood() 'temperature': self.simplisafe.temperature(),
} }
def update(self): def update(self):

View file

@ -9,26 +9,27 @@ import logging
import homeassistant.components.alarm_control_panel as alarm import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.spc import ( from homeassistant.components.spc import (
SpcWebGateway, ATTR_DISCOVER_AREAS, DATA_API, DATA_REGISTRY) ATTR_DISCOVER_AREAS, DATA_API, DATA_REGISTRY, SpcWebGateway)
from homeassistant.const import ( from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_UNKNOWN) STATE_UNKNOWN)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
SPC_AREA_MODE_TO_STATE = {'0': STATE_ALARM_DISARMED, SPC_AREA_MODE_TO_STATE = {
'1': STATE_ALARM_ARMED_HOME, '0': STATE_ALARM_DISARMED,
'3': STATE_ALARM_ARMED_AWAY} '1': STATE_ALARM_ARMED_HOME,
'3': STATE_ALARM_ARMED_AWAY,
}
def _get_alarm_state(spc_mode): def _get_alarm_state(spc_mode):
"""Get the alarm state."""
return SPC_AREA_MODE_TO_STATE.get(spc_mode, STATE_UNKNOWN) return SPC_AREA_MODE_TO_STATE.get(spc_mode, STATE_UNKNOWN)
@asyncio.coroutine @asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
discovery_info=None):
"""Set up the SPC alarm control panel platform.""" """Set up the SPC alarm control panel platform."""
if (discovery_info is None or if (discovery_info is None or
discovery_info[ATTR_DISCOVER_AREAS] is None): discovery_info[ATTR_DISCOVER_AREAS] is None):
@ -42,7 +43,7 @@ def async_setup_platform(hass, config, async_add_devices,
class SpcAlarm(alarm.AlarmControlPanel): class SpcAlarm(alarm.AlarmControlPanel):
"""Represents the SPC alarm panel.""" """Representation of the SPC alarm panel."""
def __init__(self, api, area): def __init__(self, api, area):
"""Initialize the SPC alarm panel.""" """Initialize the SPC alarm panel."""
@ -57,7 +58,7 @@ class SpcAlarm(alarm.AlarmControlPanel):
@asyncio.coroutine @asyncio.coroutine
def async_added_to_hass(self): def async_added_to_hass(self):
"""Calbback for init handlers.""" """Call for adding new entities."""
self.hass.data[DATA_REGISTRY].register_alarm_device( self.hass.data[DATA_REGISTRY].register_alarm_device(
self._area_id, self) self._area_id, self)

View file

@ -8,8 +8,8 @@ import logging
from time import sleep from time import sleep
import homeassistant.components.alarm_control_panel as alarm import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.verisure import CONF_ALARM, CONF_CODE_DIGITS
from homeassistant.components.verisure import HUB as hub from homeassistant.components.verisure import HUB as hub
from homeassistant.components.verisure import (CONF_ALARM, CONF_CODE_DIGITS)
from homeassistant.const import ( from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_UNKNOWN) STATE_UNKNOWN)
@ -43,7 +43,7 @@ class VerisureAlarm(alarm.AlarmControlPanel):
"""Representation of a Verisure alarm status.""" """Representation of a Verisure alarm status."""
def __init__(self): def __init__(self):
"""Initalize the Verisure alarm panel.""" """Initialize the Verisure alarm panel."""
self._state = STATE_UNKNOWN self._state = STATE_UNKNOWN
self._digits = hub.config.get(CONF_CODE_DIGITS) self._digits = hub.config.get(CONF_CODE_DIGITS)
self._changed_by = None self._changed_by = None

View file

@ -8,11 +8,10 @@ import asyncio
import logging import logging
import homeassistant.components.alarm_control_panel as alarm import homeassistant.components.alarm_control_panel as alarm
from homeassistant.const import (STATE_UNKNOWN, from homeassistant.components.wink import DOMAIN, WinkDevice
STATE_ALARM_DISARMED, from homeassistant.const import (
STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_ALARM_ARMED_AWAY) STATE_UNKNOWN)
from homeassistant.components.wink import WinkDevice, DOMAIN
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -41,7 +40,7 @@ class WinkCameraDevice(WinkDevice, alarm.AlarmControlPanel):
@asyncio.coroutine @asyncio.coroutine
def async_added_to_hass(self): def async_added_to_hass(self):
"""Callback when entity is added to hass.""" """Call when entity is added to hass."""
self.hass.data[DOMAIN]['entities']['alarm_control_panel'].append(self) self.hass.data[DOMAIN]['entities']['alarm_control_panel'].append(self)
@property @property

View file

@ -11,17 +11,15 @@ import voluptuous as vol
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from .const import (
DOMAIN, CONF_UID, CONF_TITLE, CONF_AUDIO, CONF_TEXT, CONF_DISPLAY_URL)
from . import flash_briefings, intent from . import flash_briefings, intent
from .const import (
CONF_AUDIO, CONF_DISPLAY_URL, CONF_TEXT, CONF_TITLE, CONF_UID, DOMAIN)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['http']
CONF_FLASH_BRIEFINGS = 'flash_briefings' CONF_FLASH_BRIEFINGS = 'flash_briefings'
DEPENDENCIES = ['http']
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = vol.Schema({
DOMAIN: { DOMAIN: {

View file

@ -5,19 +5,18 @@ For more details about this component, please refer to the documentation at
https://home-assistant.io/components/alexa/ https://home-assistant.io/components/alexa/
""" """
import copy import copy
import logging
from datetime import datetime from datetime import datetime
import logging
import uuid import uuid
from homeassistant.components import http
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers import template from homeassistant.helpers import template
from homeassistant.components import http
from .const import ( from .const import (
CONF_UID, CONF_TITLE, CONF_AUDIO, CONF_TEXT, CONF_DISPLAY_URL, ATTR_UID, ATTR_MAIN_TEXT, ATTR_REDIRECTION_URL, ATTR_STREAM_URL, ATTR_TITLE_TEXT,
ATTR_UPDATE_DATE, ATTR_TITLE_TEXT, ATTR_STREAM_URL, ATTR_MAIN_TEXT, ATTR_UID, ATTR_UPDATE_DATE, CONF_AUDIO, CONF_DISPLAY_URL, CONF_TEXT,
ATTR_REDIRECTION_URL, DATE_FORMAT) CONF_TITLE, CONF_UID, DATE_FORMAT)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -46,11 +45,11 @@ class AlexaFlashBriefingView(http.HomeAssistantView):
@callback @callback
def get(self, request, briefing_id): def get(self, request, briefing_id):
"""Handle Alexa Flash Briefing request.""" """Handle Alexa Flash Briefing request."""
_LOGGER.debug('Received Alexa flash briefing request for: %s', _LOGGER.debug("Received Alexa flash briefing request for: %s",
briefing_id) briefing_id)
if self.flash_briefings.get(briefing_id) is None: if self.flash_briefings.get(briefing_id) is None:
err = 'No configured Alexa flash briefing was found for: %s' err = "No configured Alexa flash briefing was found for: %s"
_LOGGER.error(err, briefing_id) _LOGGER.error(err, briefing_id)
return b'', 404 return b'', 404

View file

@ -3,30 +3,31 @@ Support for Alexa skill service end point.
For more details about this component, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/alexa/ https://home-assistant.io/components/alexa/
""" """
import asyncio import asyncio
import enum import enum
import logging import logging
from homeassistant.exceptions import HomeAssistantError
from homeassistant.core import callback
from homeassistant.helpers import intent
from homeassistant.components import http from homeassistant.components import http
from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import intent
from homeassistant.util.decorator import Registry from homeassistant.util.decorator import Registry
from .const import DOMAIN, SYN_RESOLUTION_MATCH from .const import DOMAIN, SYN_RESOLUTION_MATCH
INTENTS_API_ENDPOINT = '/api/alexa'
HANDLERS = Registry()
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
HANDLERS = Registry()
INTENTS_API_ENDPOINT = '/api/alexa'
class SpeechType(enum.Enum): class SpeechType(enum.Enum):
"""The Alexa speech types.""" """The Alexa speech types."""
plaintext = "PlainText" plaintext = 'PlainText'
ssml = "SSML" ssml = 'SSML'
SPEECH_MAPPINGS = { SPEECH_MAPPINGS = {
@ -38,8 +39,8 @@ SPEECH_MAPPINGS = {
class CardType(enum.Enum): class CardType(enum.Enum):
"""The Alexa card types.""" """The Alexa card types."""
simple = "Simple" simple = 'Simple'
link_account = "LinkAccount" link_account = 'LinkAccount'
@callback @callback
@ -64,7 +65,7 @@ class AlexaIntentsView(http.HomeAssistantView):
hass = request.app['hass'] hass = request.app['hass']
message = yield from request.json() message = yield from request.json()
_LOGGER.debug('Received Alexa request: %s', message) _LOGGER.debug("Received Alexa request: %s", message)
try: try:
response = yield from async_handle_message(hass, message) response = yield from async_handle_message(hass, message)
@ -81,7 +82,7 @@ class AlexaIntentsView(http.HomeAssistantView):
"This intent is not yet configured within Home Assistant.")) "This intent is not yet configured within Home Assistant."))
except intent.InvalidSlotInfo as err: except intent.InvalidSlotInfo as err:
_LOGGER.error('Received invalid slot data from Alexa: %s', err) _LOGGER.error("Received invalid slot data from Alexa: %s", err)
return self.json(intent_error_response( return self.json(intent_error_response(
hass, message, hass, message,
"Invalid slot information received for this intent.")) "Invalid slot information received for this intent."))
@ -109,6 +110,7 @@ def async_handle_message(hass, message):
- intent.UnknownIntent - intent.UnknownIntent
- intent.InvalidSlotInfo - intent.InvalidSlotInfo
- intent.IntentError - intent.IntentError
""" """
req = message.get('request') req = message.get('request')
req_type = req['type'] req_type = req['type']
@ -138,6 +140,7 @@ def async_handle_intent(hass, message):
- intent.UnknownIntent - intent.UnknownIntent
- intent.InvalidSlotInfo - intent.InvalidSlotInfo
- intent.IntentError - intent.IntentError
""" """
req = message.get('request') req = message.get('request')
alexa_intent_info = req.get('intent') alexa_intent_info = req.get('intent')

View file

@ -4,20 +4,19 @@ import logging
import math import math
from uuid import uuid4 from uuid import uuid4
import homeassistant.core as ha from homeassistant.components import (
alert, automation, cover, fan, group, input_boolean, light, lock,
media_player, scene, script, switch)
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, SERVICE_LOCK, ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, CONF_NAME, SERVICE_LOCK,
SERVICE_MEDIA_NEXT_TRACK, SERVICE_MEDIA_PAUSE, SERVICE_MEDIA_PLAY, SERVICE_MEDIA_NEXT_TRACK, SERVICE_MEDIA_PAUSE, SERVICE_MEDIA_PLAY,
SERVICE_MEDIA_PREVIOUS_TRACK, SERVICE_MEDIA_STOP, SERVICE_MEDIA_PREVIOUS_TRACK, SERVICE_MEDIA_STOP,
SERVICE_SET_COVER_POSITION, SERVICE_TURN_OFF, SERVICE_TURN_ON, SERVICE_SET_COVER_POSITION, SERVICE_TURN_OFF, SERVICE_TURN_ON,
SERVICE_UNLOCK, SERVICE_VOLUME_SET) SERVICE_UNLOCK, SERVICE_VOLUME_SET)
from homeassistant.components import ( import homeassistant.core as ha
alert, automation, cover, fan, group, input_boolean, light, lock,
media_player, scene, script, switch)
import homeassistant.util.color as color_util import homeassistant.util.color as color_util
from homeassistant.util.decorator import Registry from homeassistant.util.decorator import Registry
HANDLERS = Registry()
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
API_DIRECTIVE = 'directive' API_DIRECTIVE = 'directive'
@ -28,8 +27,8 @@ API_PAYLOAD = 'payload'
CONF_DESCRIPTION = 'description' CONF_DESCRIPTION = 'description'
CONF_DISPLAY_CATEGORIES = 'display_categories' CONF_DISPLAY_CATEGORIES = 'display_categories'
CONF_NAME = 'name'
HANDLERS = Registry()
MAPPING_COMPONENT = { MAPPING_COMPONENT = {
alert.DOMAIN: ['OTHER', ('Alexa.PowerController',), None], alert.DOMAIN: ['OTHER', ('Alexa.PowerController',), None],
@ -174,8 +173,8 @@ def async_api_discovery(hass, config, request):
scene_fmt = '{} (Scene connected via Home Assistant)' scene_fmt = '{} (Scene connected via Home Assistant)'
description = scene_fmt.format(description) description = scene_fmt.format(description)
display_categories = entity_conf.get(CONF_DISPLAY_CATEGORIES, display_categories = entity_conf.get(
class_data[0]) CONF_DISPLAY_CATEGORIES, class_data[0])
endpoint = { endpoint = {
'displayCategories': [display_categories], 'displayCategories': [display_categories],
@ -216,7 +215,7 @@ def async_api_discovery(hass, config, request):
def extract_entity(funct): def extract_entity(funct):
"""Decorator for extract entity object from request.""" """Decorate for extract entity object from request."""
@asyncio.coroutine @asyncio.coroutine
def async_api_entity_wrapper(hass, config, request): def async_api_entity_wrapper(hass, config, request):
"""Process a turn on request.""" """Process a turn on request."""

View file

@ -7,13 +7,14 @@ https://home-assistant.io/components/apple_tv/
import asyncio import asyncio
import logging import logging
from typing import Sequence, TypeVar, Union
import voluptuous as vol import voluptuous as vol
from typing import Union, TypeVar, Sequence
from homeassistant.const import (CONF_HOST, CONF_NAME, ATTR_ENTITY_ID)
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers import discovery
from homeassistant.components.discovery import SERVICE_APPLE_TV from homeassistant.components.discovery import SERVICE_APPLE_TV
from homeassistant.const import ATTR_ENTITY_ID, CONF_HOST, CONF_NAME
from homeassistant.helpers import discovery
from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pyatv==0.3.9'] REQUIREMENTS = ['pyatv==0.3.9']
@ -59,9 +60,9 @@ CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.All(ensure_list, [vol.Schema({ DOMAIN: vol.All(ensure_list, [vol.Schema({
vol.Required(CONF_HOST): cv.string, vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_LOGIN_ID): cv.string, vol.Required(CONF_LOGIN_ID): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_CREDENTIALS, default=None): cv.string, vol.Optional(CONF_CREDENTIALS, default=None): cv.string,
vol.Optional(CONF_START_OFF, default=False): cv.boolean vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_START_OFF, default=False): cv.boolean,
})]) })])
}, extra=vol.ALLOW_EXTRA) }, extra=vol.ALLOW_EXTRA)
@ -140,7 +141,7 @@ def async_setup(hass, config):
@asyncio.coroutine @asyncio.coroutine
def async_service_handler(service): def async_service_handler(service):
"""Handler for service calls.""" """Handle service calls."""
entity_ids = service.data.get(ATTR_ENTITY_ID) entity_ids = service.data.get(ATTR_ENTITY_ID)
if service.service == SERVICE_SCAN: if service.service == SERVICE_SCAN:
@ -167,7 +168,7 @@ def async_setup(hass, config):
@asyncio.coroutine @asyncio.coroutine
def atv_discovered(service, info): def atv_discovered(service, info):
"""Setup an Apple TV that was auto discovered.""" """Set up an Apple TV that was auto discovered."""
yield from _setup_atv(hass, { yield from _setup_atv(hass, {
CONF_NAME: info['name'], CONF_NAME: info['name'],
CONF_HOST: info['host'], CONF_HOST: info['host'],
@ -194,7 +195,7 @@ def async_setup(hass, config):
@asyncio.coroutine @asyncio.coroutine
def _setup_atv(hass, atv_config): def _setup_atv(hass, atv_config):
"""Setup an Apple TV.""" """Set up an Apple TV."""
import pyatv import pyatv
name = atv_config.get(CONF_NAME) name = atv_config.get(CONF_NAME)
host = atv_config.get(CONF_HOST) host = atv_config.get(CONF_HOST)
@ -245,7 +246,7 @@ class AppleTVPowerManager:
@property @property
def turned_on(self): def turned_on(self):
"""If device is on or off.""" """Return true if device is on or off."""
return self._is_on return self._is_on
def set_power_on(self, value): def set_power_on(self, value):

View file

@ -4,24 +4,21 @@ Support for Axis devices.
For more details about this component, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/axis/ https://home-assistant.io/components/axis/
""" """
import logging import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.components.discovery import SERVICE_AXIS from homeassistant.components.discovery import SERVICE_AXIS
from homeassistant.const import (ATTR_LOCATION, ATTR_TRIPPED, from homeassistant.const import (
CONF_EVENT, CONF_HOST, CONF_INCLUDE, ATTR_LOCATION, ATTR_TRIPPED, CONF_EVENT, CONF_HOST, CONF_INCLUDE,
CONF_NAME, CONF_PASSWORD, CONF_PORT, CONF_NAME, CONF_PASSWORD, CONF_PORT, CONF_TRIGGER_TIME, CONF_USERNAME,
CONF_TRIGGER_TIME, CONF_USERNAME, EVENT_HOMEASSISTANT_STOP)
EVENT_HOMEASSISTANT_STOP)
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import discovery from homeassistant.helpers import discovery
from homeassistant.helpers.dispatcher import dispatcher_send from homeassistant.helpers.dispatcher import dispatcher_send
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.util.json import load_json, save_json from homeassistant.util.json import load_json, save_json
REQUIREMENTS = ['axis==14'] REQUIREMENTS = ['axis==14']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -81,10 +78,10 @@ def request_configuration(hass, config, name, host, serialnumber):
configurator = hass.components.configurator configurator = hass.components.configurator
def configuration_callback(callback_data): def configuration_callback(callback_data):
"""Called when config is submitted.""" """Call when configuration is submitted."""
if CONF_INCLUDE not in callback_data: if CONF_INCLUDE not in callback_data:
configurator.notify_errors(request_id, configurator.notify_errors(
"Functionality mandatory.") request_id, "Functionality mandatory.")
return False return False
callback_data[CONF_INCLUDE] = callback_data[CONF_INCLUDE].split() callback_data[CONF_INCLUDE] = callback_data[CONF_INCLUDE].split()
@ -96,8 +93,8 @@ def request_configuration(hass, config, name, host, serialnumber):
try: try:
device_config = DEVICE_SCHEMA(callback_data) device_config = DEVICE_SCHEMA(callback_data)
except vol.Invalid: except vol.Invalid:
configurator.notify_errors(request_id, configurator.notify_errors(
"Bad input, please check spelling.") request_id, "Bad input, please check spelling.")
return False return False
if setup_device(hass, config, device_config): if setup_device(hass, config, device_config):
@ -108,8 +105,8 @@ def request_configuration(hass, config, name, host, serialnumber):
save_json(hass.config.path(CONFIG_FILE), config_file) save_json(hass.config.path(CONFIG_FILE), config_file)
configurator.request_done(request_id) configurator.request_done(request_id)
else: else:
configurator.notify_errors(request_id, configurator.notify_errors(
"Failed to register, please try again.") request_id, "Failed to register, please try again.")
return False return False
title = '{} ({})'.format(name, host) title = '{} ({})'.format(name, host)
@ -147,7 +144,7 @@ def request_configuration(hass, config, name, host, serialnumber):
def setup(hass, config): def setup(hass, config):
"""Common setup for Axis devices.""" """Set up for Axis devices."""
def _shutdown(call): # pylint: disable=unused-argument def _shutdown(call): # pylint: disable=unused-argument
"""Stop the event stream on shutdown.""" """Stop the event stream on shutdown."""
for serialnumber, device in AXIS_DEVICES.items(): for serialnumber, device in AXIS_DEVICES.items():
@ -157,7 +154,7 @@ def setup(hass, config):
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, _shutdown) hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, _shutdown)
def axis_device_discovered(service, discovery_info): def axis_device_discovered(service, discovery_info):
"""Called when axis devices has been found.""" """Call when axis devices has been found."""
host = discovery_info[CONF_HOST] host = discovery_info[CONF_HOST]
name = discovery_info['hostname'] name = discovery_info['hostname']
serialnumber = discovery_info['properties']['macaddress'] serialnumber = discovery_info['properties']['macaddress']
@ -173,8 +170,8 @@ def setup(hass, config):
_LOGGER.error("Bad data from %s. %s", CONFIG_FILE, err) _LOGGER.error("Bad data from %s. %s", CONFIG_FILE, err)
return False return False
if not setup_device(hass, config, device_config): if not setup_device(hass, config, device_config):
_LOGGER.error("Couldn\'t set up %s", _LOGGER.error(
device_config[CONF_NAME]) "Couldn't set up %s", device_config[CONF_NAME])
else: else:
# New device, create configuration request for UI # New device, create configuration request for UI
request_configuration(hass, config, name, host, serialnumber) request_configuration(hass, config, name, host, serialnumber)
@ -193,7 +190,7 @@ def setup(hass, config):
if CONF_NAME not in device_config: if CONF_NAME not in device_config:
device_config[CONF_NAME] = device device_config[CONF_NAME] = device
if not setup_device(hass, config, device_config): if not setup_device(hass, config, device_config):
_LOGGER.error("Couldn\'t set up %s", device_config[CONF_NAME]) _LOGGER.error("Couldn't set up %s", device_config[CONF_NAME])
def vapix_service(call): def vapix_service(call):
"""Service to send a message.""" """Service to send a message."""
@ -205,23 +202,21 @@ def setup(hass, config):
call.data[SERVICE_PARAM]) call.data[SERVICE_PARAM])
hass.bus.fire(SERVICE_VAPIX_CALL_RESPONSE, response) hass.bus.fire(SERVICE_VAPIX_CALL_RESPONSE, response)
return True return True
_LOGGER.info("Couldn\'t find device %s", call.data[CONF_NAME]) _LOGGER.info("Couldn't find device %s", call.data[CONF_NAME])
return False return False
# Register service with Home Assistant. # Register service with Home Assistant.
hass.services.register(DOMAIN, hass.services.register(
SERVICE_VAPIX_CALL, DOMAIN, SERVICE_VAPIX_CALL, vapix_service, schema=SERVICE_SCHEMA)
vapix_service,
schema=SERVICE_SCHEMA)
return True return True
def setup_device(hass, config, device_config): def setup_device(hass, config, device_config):
"""Set up device.""" """Set up an Axis device."""
from axis import AxisDevice from axis import AxisDevice
def signal_callback(action, event): def signal_callback(action, event):
"""Callback to configure events when initialized on event stream.""" """Call to configure events when initialized on event stream."""
if action == 'add': if action == 'add':
event_config = { event_config = {
CONF_EVENT: event, CONF_EVENT: event,
@ -230,11 +225,8 @@ def setup_device(hass, config, device_config):
CONF_TRIGGER_TIME: device_config[CONF_TRIGGER_TIME] CONF_TRIGGER_TIME: device_config[CONF_TRIGGER_TIME]
} }
component = event.event_platform component = event.event_platform
discovery.load_platform(hass, discovery.load_platform(
component, hass, component, DOMAIN, event_config, config)
DOMAIN,
event_config,
config)
event_types = list(filter(lambda x: x in device_config[CONF_INCLUDE], event_types = list(filter(lambda x: x in device_config[CONF_INCLUDE],
EVENT_TYPES)) EVENT_TYPES))
@ -245,7 +237,7 @@ def setup_device(hass, config, device_config):
if device.serial_number is None: if device.serial_number is None:
# If there is no serial number a connection could not be made # If there is no serial number a connection could not be made
_LOGGER.error("Couldn\'t connect to %s", device_config[CONF_HOST]) _LOGGER.error("Couldn't connect to %s", device_config[CONF_HOST])
return False return False
for component in device_config[CONF_INCLUDE]: for component in device_config[CONF_INCLUDE]:
@ -257,11 +249,8 @@ def setup_device(hass, config, device_config):
CONF_USERNAME: device_config[CONF_USERNAME], CONF_USERNAME: device_config[CONF_USERNAME],
CONF_PASSWORD: device_config[CONF_PASSWORD] CONF_PASSWORD: device_config[CONF_PASSWORD]
} }
discovery.load_platform(hass, discovery.load_platform(
component, hass, component, DOMAIN, camera_config, config)
DOMAIN,
camera_config,
config)
AXIS_DEVICES[device.serial_number] = device AXIS_DEVICES[device.serial_number] = device
if event_types: if event_types:
@ -275,9 +264,9 @@ class AxisDeviceEvent(Entity):
def __init__(self, event_config): def __init__(self, event_config):
"""Initialize the event.""" """Initialize the event."""
self.axis_event = event_config[CONF_EVENT] self.axis_event = event_config[CONF_EVENT]
self._name = '{}_{}_{}'.format(event_config[CONF_NAME], self._name = '{}_{}_{}'.format(
self.axis_event.event_type, event_config[CONF_NAME], self.axis_event.event_type,
self.axis_event.id) self.axis_event.id)
self.location = event_config[ATTR_LOCATION] self.location = event_config[ATTR_LOCATION]
self.axis_event.callback = self._update_callback self.axis_event.callback = self._update_callback
@ -298,7 +287,7 @@ class AxisDeviceEvent(Entity):
@property @property
def should_poll(self): def should_poll(self):
"""No polling needed.""" """Return the polling state. No polling needed."""
return False return False
@property @property

View file

@ -3,23 +3,22 @@ Support for ADS binary sensors.
For more details about this platform, please refer to the documentation. For more details about this platform, please refer to the documentation.
https://home-assistant.io/components/binary_sensor.ads/ https://home-assistant.io/components/binary_sensor.ads/
""" """
import asyncio import asyncio
import logging import logging
import voluptuous as vol
from homeassistant.components.binary_sensor import BinarySensorDevice, \
PLATFORM_SCHEMA, DEVICE_CLASSES_SCHEMA
from homeassistant.components.ads import DATA_ADS, CONF_ADS_VAR
from homeassistant.const import CONF_NAME, CONF_DEVICE_CLASS
import homeassistant.helpers.config_validation as cv
import voluptuous as vol
from homeassistant.components.ads import CONF_ADS_VAR, DATA_ADS
from homeassistant.components.binary_sensor import (
DEVICE_CLASSES_SCHEMA, PLATFORM_SCHEMA, BinarySensorDevice)
from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['ads']
DEFAULT_NAME = 'ADS binary sensor' DEFAULT_NAME = 'ADS binary sensor'
DEPENDENCIES = ['ads']
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_ADS_VAR): cv.string, vol.Required(CONF_ADS_VAR): cv.string,
@ -44,7 +43,7 @@ class AdsBinarySensor(BinarySensorDevice):
"""Representation of ADS binary sensors.""" """Representation of ADS binary sensors."""
def __init__(self, ads_hub, name, ads_var, device_class): def __init__(self, ads_hub, name, ads_var, device_class):
"""Initialize AdsBinarySensor entity.""" """Initialize ADS binary sensor."""
self._name = name self._name = name
self._state = False self._state = False
self._device_class = device_class or 'moving' self._device_class = device_class or 'moving'
@ -56,15 +55,13 @@ class AdsBinarySensor(BinarySensorDevice):
"""Register device notification.""" """Register device notification."""
def update(name, value): def update(name, value):
"""Handle device notifications.""" """Handle device notifications."""
_LOGGER.debug('Variable %s changed its value to %d', _LOGGER.debug('Variable %s changed its value to %d', name, value)
name, value)
self._state = value self._state = value
self.schedule_update_ha_state() self.schedule_update_ha_state()
self.hass.async_add_job( self.hass.async_add_job(
self._ads_hub.add_device_notification, self._ads_hub.add_device_notification,
self.ads_var, self._ads_hub.PLCTYPE_BOOL, update self.ads_var, self._ads_hub.PLCTYPE_BOOL, update)
)
@property @property
def name(self): def name(self):

View file

@ -4,13 +4,12 @@ Support for Axis binary sensors.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.axis/ https://home-assistant.io/components/binary_sensor.axis/
""" """
import logging
from datetime import timedelta from datetime import timedelta
import logging
from homeassistant.components.binary_sensor import (BinarySensorDevice) from homeassistant.components.axis import AxisDeviceEvent
from homeassistant.components.axis import (AxisDeviceEvent) from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.const import (CONF_TRIGGER_TIME) from homeassistant.const import CONF_TRIGGER_TIME
from homeassistant.helpers.event import track_point_in_utc_time from homeassistant.helpers.event import track_point_in_utc_time
from homeassistant.util.dt import utcnow from homeassistant.util.dt import utcnow
@ -20,7 +19,7 @@ _LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup Axis device event.""" """Set up the Axis binary devices."""
add_devices([AxisBinarySensor(hass, discovery_info)], True) add_devices([AxisBinarySensor(hass, discovery_info)], True)
@ -28,7 +27,7 @@ class AxisBinarySensor(AxisDeviceEvent, BinarySensorDevice):
"""Representation of a binary Axis event.""" """Representation of a binary Axis event."""
def __init__(self, hass, event_config): def __init__(self, hass, event_config):
"""Initialize the binary sensor.""" """Initialize the Axis binary sensor."""
self.hass = hass self.hass = hass
self._state = False self._state = False
self._delay = event_config[CONF_TRIGGER_TIME] self._delay = event_config[CONF_TRIGGER_TIME]
@ -56,7 +55,7 @@ class AxisBinarySensor(AxisDeviceEvent, BinarySensorDevice):
# Set timer to wait until updating the state # Set timer to wait until updating the state
def _delay_update(now): def _delay_update(now):
"""Timer callback for sensor update.""" """Timer callback for sensor update."""
_LOGGER.debug("%s Called delayed (%s sec) update.", _LOGGER.debug("%s called delayed (%s sec) update",
self._name, self._delay) self._name, self._delay)
self.schedule_update_ha_state() self.schedule_update_ha_state()
self._timer = None self._timer = None

View file

@ -53,7 +53,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
sensors = [] sensors = []
try: try:
_LOGGER.debug("Initializing Client") _LOGGER.debug("Initializing client")
client = concord232_client.Client('http://{}:{}'.format(host, port)) client = concord232_client.Client('http://{}:{}'.format(host, port))
client.zones = client.list_zones() client.zones = client.list_zones()
client.last_zone_update = datetime.datetime.now() client.last_zone_update = datetime.datetime.now()

View file

@ -5,12 +5,13 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.knx/ https://home-assistant.io/components/binary_sensor.knx/
""" """
import asyncio import asyncio
import voluptuous as vol import voluptuous as vol
from homeassistant.components.knx import DATA_KNX, ATTR_DISCOVER_DEVICES, \ from homeassistant.components.binary_sensor import (
KNXAutomation PLATFORM_SCHEMA, BinarySensorDevice)
from homeassistant.components.binary_sensor import PLATFORM_SCHEMA, \ from homeassistant.components.knx import (
BinarySensorDevice ATTR_DISCOVER_DEVICES, DATA_KNX, KNXAutomation)
from homeassistant.const import CONF_NAME from homeassistant.const import CONF_NAME
from homeassistant.core import callback from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
@ -53,20 +54,16 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
@asyncio.coroutine @asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
discovery_info=None):
"""Set up binary sensor(s) for KNX platform.""" """Set up binary sensor(s) for KNX platform."""
if DATA_KNX not in hass.data \ if DATA_KNX not in hass.data or not hass.data[DATA_KNX].initialized:
or not hass.data[DATA_KNX].initialized: return
return False
if discovery_info is not None: if discovery_info is not None:
async_add_devices_discovery(hass, discovery_info, async_add_devices) async_add_devices_discovery(hass, discovery_info, async_add_devices)
else: else:
async_add_devices_config(hass, config, async_add_devices) async_add_devices_config(hass, config, async_add_devices)
return True
@callback @callback
def async_add_devices_discovery(hass, discovery_info, async_add_devices): def async_add_devices_discovery(hass, discovery_info, async_add_devices):
@ -80,7 +77,7 @@ def async_add_devices_discovery(hass, discovery_info, async_add_devices):
@callback @callback
def async_add_devices_config(hass, config, async_add_devices): def async_add_devices_config(hass, config, async_add_devices):
"""Set up binary senor for KNX platform configured within plattform.""" """Set up binary senor for KNX platform configured within platform."""
name = config.get(CONF_NAME) name = config.get(CONF_NAME)
import xknx import xknx
binary_sensor = xknx.devices.BinarySensor( binary_sensor = xknx.devices.BinarySensor(
@ -108,7 +105,7 @@ class KNXBinarySensor(BinarySensorDevice):
"""Representation of a KNX binary sensor.""" """Representation of a KNX binary sensor."""
def __init__(self, hass, device): def __init__(self, hass, device):
"""Initialization of KNXBinarySensor.""" """Initialize of KNX binary sensor."""
self.device = device self.device = device
self.hass = hass self.hass = hass
self.async_register_callbacks() self.async_register_callbacks()
@ -119,7 +116,7 @@ class KNXBinarySensor(BinarySensorDevice):
"""Register callbacks to update hass after device was changed.""" """Register callbacks to update hass after device was changed."""
@asyncio.coroutine @asyncio.coroutine
def after_update_callback(device): def after_update_callback(device):
"""Callback after device was updated.""" """Call after device was updated."""
# pylint: disable=unused-argument # pylint: disable=unused-argument
yield from self.async_update_ha_state() yield from self.async_update_ha_state()
self.device.register_device_updated_cb(after_update_callback) self.device.register_device_updated_cb(after_update_callback)

View file

@ -5,21 +5,20 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.mysensors/ https://home-assistant.io/components/binary_sensor.mysensors/
""" """
from homeassistant.components import mysensors from homeassistant.components import mysensors
from homeassistant.components.binary_sensor import (DEVICE_CLASSES, DOMAIN, from homeassistant.components.binary_sensor import (
BinarySensorDevice) DEVICE_CLASSES, DOMAIN, BinarySensorDevice)
from homeassistant.const import STATE_ON from homeassistant.const import STATE_ON
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the mysensors platform for binary sensors.""" """Set up the MySensors platform for binary sensors."""
mysensors.setup_mysensors_platform( mysensors.setup_mysensors_platform(
hass, DOMAIN, discovery_info, MySensorsBinarySensor, hass, DOMAIN, discovery_info, MySensorsBinarySensor,
add_devices=add_devices) add_devices=add_devices)
class MySensorsBinarySensor( class MySensorsBinarySensor(mysensors.MySensorsEntity, BinarySensorDevice):
mysensors.MySensorsEntity, BinarySensorDevice): """Representation of a MySensors Binary Sensor child node."""
"""Represent the value of a MySensors Binary Sensor child node."""
@property @property
def is_on(self): def is_on(self):

View file

@ -7,7 +7,7 @@ https://home-assistant.io/components/binary_sensor.mystrom/
import asyncio import asyncio
import logging import logging
from homeassistant.components.binary_sensor import (BinarySensorDevice, DOMAIN) from homeassistant.components.binary_sensor import DOMAIN, BinarySensorDevice
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.const import HTTP_UNPROCESSABLE_ENTITY from homeassistant.const import HTTP_UNPROCESSABLE_ENTITY
@ -37,7 +37,7 @@ class MyStromView(HomeAssistantView):
@asyncio.coroutine @asyncio.coroutine
def get(self, request): def get(self, request):
"""The GET request received from a myStrom button.""" """Handle the GET request received from a myStrom button."""
res = yield from self._handle(request.app['hass'], request.query) res = yield from self._handle(request.app['hass'], request.query)
return res return res

View file

@ -5,18 +5,17 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.raspihats/ https://home-assistant.io/components/binary_sensor.raspihats/
""" """
import logging import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.const import (
CONF_NAME, CONF_DEVICE_CLASS, DEVICE_DEFAULT_NAME
)
import homeassistant.helpers.config_validation as cv
from homeassistant.components.binary_sensor import ( from homeassistant.components.binary_sensor import (
PLATFORM_SCHEMA, BinarySensorDevice PLATFORM_SCHEMA, BinarySensorDevice)
)
from homeassistant.components.raspihats import ( from homeassistant.components.raspihats import (
CONF_I2C_HATS, CONF_BOARD, CONF_ADDRESS, CONF_CHANNELS, CONF_INDEX, CONF_ADDRESS, CONF_BOARD, CONF_CHANNELS, CONF_I2C_HATS, CONF_INDEX,
CONF_INVERT_LOGIC, I2C_HAT_NAMES, I2C_HATS_MANAGER, I2CHatsException CONF_INVERT_LOGIC, I2C_HAT_NAMES, I2C_HATS_MANAGER, I2CHatsException)
) from homeassistant.const import (
CONF_DEVICE_CLASS, CONF_NAME, DEVICE_DEFAULT_NAME)
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -45,7 +44,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
# pylint: disable=unused-argument # pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the raspihats binary_sensor devices.""" """Set up the raspihats binary_sensor devices."""
I2CHatBinarySensor.I2C_HATS_MANAGER = hass.data[I2C_HATS_MANAGER] I2CHatBinarySensor.I2C_HATS_MANAGER = hass.data[I2C_HATS_MANAGER]
binary_sensors = [] binary_sensors = []
i2c_hat_configs = config.get(CONF_I2C_HATS) i2c_hat_configs = config.get(CONF_I2C_HATS)
@ -65,39 +64,32 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
) )
) )
except I2CHatsException as ex: except I2CHatsException as ex:
_LOGGER.error( _LOGGER.error("Failed to register %s I2CHat@%s %s",
"Failed to register " + board + "I2CHat@" + hex(address) + " " board, hex(address), str(ex))
+ str(ex)
)
add_devices(binary_sensors) add_devices(binary_sensors)
class I2CHatBinarySensor(BinarySensorDevice): class I2CHatBinarySensor(BinarySensorDevice):
"""Represents a binary sensor that uses a I2C-HAT digital input.""" """Representation of a binary sensor that uses a I2C-HAT digital input."""
I2C_HATS_MANAGER = None I2C_HATS_MANAGER = None
def __init__(self, address, channel, name, invert_logic, device_class): def __init__(self, address, channel, name, invert_logic, device_class):
"""Initialize sensor.""" """Initialize the raspihats sensor."""
self._address = address self._address = address
self._channel = channel self._channel = channel
self._name = name or DEVICE_DEFAULT_NAME self._name = name or DEVICE_DEFAULT_NAME
self._invert_logic = invert_logic self._invert_logic = invert_logic
self._device_class = device_class self._device_class = device_class
self._state = self.I2C_HATS_MANAGER.read_di( self._state = self.I2C_HATS_MANAGER.read_di(
self._address, self._address, self._channel)
self._channel
)
def online_callback(): def online_callback():
"""Callback fired when board is online.""" """Call fired when board is online."""
self.schedule_update_ha_state() self.schedule_update_ha_state()
self.I2C_HATS_MANAGER.register_online_callback( self.I2C_HATS_MANAGER.register_online_callback(
self._address, self._address, self._channel, online_callback)
self._channel,
online_callback
)
def edge_callback(state): def edge_callback(state):
"""Read digital input state.""" """Read digital input state."""
@ -105,10 +97,7 @@ class I2CHatBinarySensor(BinarySensorDevice):
self.schedule_update_ha_state() self.schedule_update_ha_state()
self.I2C_HATS_MANAGER.register_di_callback( self.I2C_HATS_MANAGER.register_di_callback(
self._address, self._address, self._channel, edge_callback)
self._channel,
edge_callback
)
@property @property
def device_class(self): def device_class(self):
@ -122,7 +111,7 @@ class I2CHatBinarySensor(BinarySensorDevice):
@property @property
def should_poll(self): def should_poll(self):
"""Polling not needed for this sensor.""" """No polling needed for this sensor."""
return False return False
@property @property

View file

@ -1,33 +1,30 @@
""" """
Support for RFXtrx binary sensors. Support for RFXtrx binary sensors.
Lighting4 devices (sensors based on PT2262 encoder) are supported and For more details about this platform, please refer to the documentation at
tested. Other types may need some work. https://home-assistant.io/components/binary_sensor.rfxtrx/
""" """
import logging import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.const import (
CONF_DEVICE_CLASS, CONF_COMMAND_ON, CONF_COMMAND_OFF, CONF_NAME)
from homeassistant.components import rfxtrx from homeassistant.components import rfxtrx
from homeassistant.helpers import event as evt
from homeassistant.helpers import config_validation as cv
from homeassistant.components.binary_sensor import ( from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA) PLATFORM_SCHEMA, BinarySensorDevice)
from homeassistant.components.rfxtrx import ( from homeassistant.components.rfxtrx import (
ATTR_NAME, CONF_AUTOMATIC_ADD, CONF_FIRE_EVENT, ATTR_NAME, CONF_AUTOMATIC_ADD, CONF_DATA_BITS, CONF_DEVICES,
CONF_OFF_DELAY, CONF_DATA_BITS, CONF_DEVICES) CONF_FIRE_EVENT, CONF_OFF_DELAY)
from homeassistant.util import slugify from homeassistant.const import (
CONF_COMMAND_OFF, CONF_COMMAND_ON, CONF_DEVICE_CLASS, CONF_NAME)
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import event as evt
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
from homeassistant.util import slugify
DEPENDENCIES = ["rfxtrx"]
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['rfxtrx']
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_DEVICES, default={}): { vol.Optional(CONF_DEVICES, default={}): {
cv.string: vol.Schema({ cv.string: vol.Schema({
@ -45,8 +42,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
}, extra=vol.ALLOW_EXTRA) }, extra=vol.ALLOW_EXTRA)
def setup_platform(hass, config, add_devices_callback, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Binary Sensor platform to rfxtrx.""" """Set up the Binary Sensor platform to RFXtrx."""
import RFXtrx as rfxtrxmod import RFXtrx as rfxtrxmod
sensors = [] sensors = []
@ -58,29 +55,26 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
continue continue
if entity[CONF_DATA_BITS] is not None: if entity[CONF_DATA_BITS] is not None:
_LOGGER.debug("Masked device id: %s", _LOGGER.debug(
rfxtrx.get_pt2262_deviceid(device_id, "Masked device id: %s", rfxtrx.get_pt2262_deviceid(
entity[CONF_DATA_BITS])) device_id, entity[CONF_DATA_BITS]))
_LOGGER.debug("Add %s rfxtrx.binary_sensor (class %s)", _LOGGER.debug("Add %s rfxtrx.binary_sensor (class %s)",
entity[ATTR_NAME], entity[CONF_DEVICE_CLASS]) entity[ATTR_NAME], entity[CONF_DEVICE_CLASS])
device = RfxtrxBinarySensor(event, entity[ATTR_NAME], device = RfxtrxBinarySensor(
entity[CONF_DEVICE_CLASS], event, entity[ATTR_NAME], entity[CONF_DEVICE_CLASS],
entity[CONF_FIRE_EVENT], entity[CONF_FIRE_EVENT], entity[CONF_OFF_DELAY],
entity[CONF_OFF_DELAY], entity[CONF_DATA_BITS], entity[CONF_COMMAND_ON],
entity[CONF_DATA_BITS], entity[CONF_COMMAND_OFF])
entity[CONF_COMMAND_ON],
entity[CONF_COMMAND_OFF])
device.hass = hass device.hass = hass
sensors.append(device) sensors.append(device)
rfxtrx.RFX_DEVICES[device_id] = device rfxtrx.RFX_DEVICES[device_id] = device
add_devices_callback(sensors) add_devices(sensors)
# pylint: disable=too-many-branches
def binary_sensor_update(event): def binary_sensor_update(event):
"""Callback for control updates from the RFXtrx gateway.""" """Call for control updates from the RFXtrx gateway."""
if not isinstance(event, rfxtrxmod.ControlEvent): if not isinstance(event, rfxtrxmod.ControlEvent):
return return
@ -100,29 +94,26 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
poss_dev = rfxtrx.find_possible_pt2262_device(device_id) poss_dev = rfxtrx.find_possible_pt2262_device(device_id)
if poss_dev is not None: if poss_dev is not None:
poss_id = slugify(poss_dev.event.device.id_string.lower()) poss_id = slugify(poss_dev.event.device.id_string.lower())
_LOGGER.debug("Found possible matching deviceid %s.", _LOGGER.debug(
poss_id) "Found possible matching device ID: %s", poss_id)
pkt_id = "".join("{0:02x}".format(x) for x in event.data) pkt_id = "".join("{0:02x}".format(x) for x in event.data)
sensor = RfxtrxBinarySensor(event, pkt_id) sensor = RfxtrxBinarySensor(event, pkt_id)
sensor.hass = hass sensor.hass = hass
rfxtrx.RFX_DEVICES[device_id] = sensor rfxtrx.RFX_DEVICES[device_id] = sensor
add_devices_callback([sensor]) add_devices([sensor])
_LOGGER.info("Added binary sensor %s " _LOGGER.info(
"(Device_id: %s Class: %s Sub: %s)", "Added binary sensor %s (Device ID: %s Class: %s Sub: %s)",
pkt_id, pkt_id, slugify(event.device.id_string.lower()),
slugify(event.device.id_string.lower()), event.device.__class__.__name__, event.device.subtype)
event.device.__class__.__name__,
event.device.subtype)
elif not isinstance(sensor, RfxtrxBinarySensor): elif not isinstance(sensor, RfxtrxBinarySensor):
return return
else: else:
_LOGGER.debug("Binary sensor update " _LOGGER.debug(
"(Device_id: %s Class: %s Sub: %s)", "Binary sensor update (Device ID: %s Class: %s Sub: %s)",
slugify(event.device.id_string.lower()), slugify(event.device.id_string.lower()),
event.device.__class__.__name__, event.device.__class__.__name__, event.device.subtype)
event.device.subtype)
if sensor.is_lighting4: if sensor.is_lighting4:
if sensor.data_bits is not None: if sensor.data_bits is not None:
@ -142,22 +133,20 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
sensor.update_state(False) sensor.update_state(False)
sensor.delay_listener = evt.track_point_in_time( sensor.delay_listener = evt.track_point_in_time(
hass, off_delay_listener, dt_util.utcnow() + sensor.off_delay hass, off_delay_listener, dt_util.utcnow() + sensor.off_delay)
)
# Subscribe to main rfxtrx events # Subscribe to main RFXtrx events
if binary_sensor_update not in rfxtrx.RECEIVED_EVT_SUBSCRIBERS: if binary_sensor_update not in rfxtrx.RECEIVED_EVT_SUBSCRIBERS:
rfxtrx.RECEIVED_EVT_SUBSCRIBERS.append(binary_sensor_update) rfxtrx.RECEIVED_EVT_SUBSCRIBERS.append(binary_sensor_update)
# pylint: disable=too-many-instance-attributes,too-many-arguments
class RfxtrxBinarySensor(BinarySensorDevice): class RfxtrxBinarySensor(BinarySensorDevice):
"""An Rfxtrx binary sensor.""" """A representation of a RFXtrx binary sensor."""
def __init__(self, event, name, device_class=None, def __init__(self, event, name, device_class=None,
should_fire=False, off_delay=None, data_bits=None, should_fire=False, off_delay=None, data_bits=None,
cmd_on=None, cmd_off=None): cmd_on=None, cmd_off=None):
"""Initialize the sensor.""" """Initialize the RFXtrx sensor."""
self.event = event self.event = event
self._name = name self._name = name
self._should_fire_event = should_fire self._should_fire_event = should_fire
@ -172,8 +161,7 @@ class RfxtrxBinarySensor(BinarySensorDevice):
if data_bits is not None: if data_bits is not None:
self._masked_id = rfxtrx.get_pt2262_deviceid( self._masked_id = rfxtrx.get_pt2262_deviceid(
event.device.id_string.lower(), event.device.id_string.lower(), data_bits)
data_bits)
else: else:
self._masked_id = None self._masked_id = None

View file

@ -8,18 +8,17 @@ import logging
import voluptuous as vol import voluptuous as vol
import homeassistant.components.rpi_pfio as rpi_pfio
from homeassistant.components.binary_sensor import ( from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA) PLATFORM_SCHEMA, BinarySensorDevice)
from homeassistant.const import DEVICE_DEFAULT_NAME import homeassistant.components.rpi_pfio as rpi_pfio
from homeassistant.const import CONF_NAME, DEVICE_DEFAULT_NAME
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
ATTR_NAME = 'name' CONF_INVERT_LOGIC = 'invert_logic'
ATTR_INVERT_LOGIC = 'invert_logic'
ATTR_SETTLE_TIME = 'settle_time'
CONF_PORTS = 'ports' CONF_PORTS = 'ports'
CONF_SETTLE_TIME = 'settle_time'
DEFAULT_INVERT_LOGIC = False DEFAULT_INVERT_LOGIC = False
DEFAULT_SETTLE_TIME = 20 DEFAULT_SETTLE_TIME = 20
@ -27,27 +26,27 @@ DEFAULT_SETTLE_TIME = 20
DEPENDENCIES = ['rpi_pfio'] DEPENDENCIES = ['rpi_pfio']
PORT_SCHEMA = vol.Schema({ PORT_SCHEMA = vol.Schema({
vol.Optional(ATTR_NAME, default=None): cv.string, vol.Optional(CONF_NAME, default=None): cv.string,
vol.Optional(ATTR_SETTLE_TIME, default=DEFAULT_SETTLE_TIME): vol.Optional(CONF_SETTLE_TIME, default=DEFAULT_SETTLE_TIME):
cv.positive_int, cv.positive_int,
vol.Optional(ATTR_INVERT_LOGIC, default=DEFAULT_INVERT_LOGIC): cv.boolean vol.Optional(CONF_INVERT_LOGIC, default=DEFAULT_INVERT_LOGIC): cv.boolean,
}) })
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_PORTS, default={}): vol.Schema({ vol.Optional(CONF_PORTS, default={}): vol.Schema({
cv.positive_int: PORT_SCHEMA cv.positive_int: PORT_SCHEMA,
}) })
}) })
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the PiFace Digital Input devices.""" """Set up the PiFace Digital Input devices."""
binary_sensors = [] binary_sensors = []
ports = config.get('ports') ports = config.get(CONF_PORTS)
for port, port_entity in ports.items(): for port, port_entity in ports.items():
name = port_entity[ATTR_NAME] name = port_entity[CONF_NAME]
settle_time = port_entity[ATTR_SETTLE_TIME] / 1000 settle_time = port_entity[CONF_SETTLE_TIME] / 1000
invert_logic = port_entity[ATTR_INVERT_LOGIC] invert_logic = port_entity[CONF_INVERT_LOGIC]
binary_sensors.append(RPiPFIOBinarySensor( binary_sensors.append(RPiPFIOBinarySensor(
hass, port, name, settle_time, invert_logic)) hass, port, name, settle_time, invert_logic))

View file

@ -4,46 +4,49 @@ Support for Vanderbilt (formerly Siemens) SPC alarm systems.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.spc/ https://home-assistant.io/components/binary_sensor.spc/
""" """
import logging
import asyncio import asyncio
import logging
from homeassistant.components.spc import (
ATTR_DISCOVER_DEVICES, DATA_REGISTRY)
from homeassistant.components.binary_sensor import BinarySensorDevice from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.const import (STATE_UNAVAILABLE, STATE_ON, STATE_OFF) from homeassistant.components.spc import ATTR_DISCOVER_DEVICES, DATA_REGISTRY
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
SPC_TYPE_TO_DEVICE_CLASS = {'0': 'motion', SPC_TYPE_TO_DEVICE_CLASS = {
'1': 'opening', '0': 'motion',
'3': 'smoke'} '1': 'opening',
'3': 'smoke',
}
SPC_INPUT_TO_SENSOR_STATE = {
SPC_INPUT_TO_SENSOR_STATE = {'0': STATE_OFF, '0': STATE_OFF,
'1': STATE_ON} '1': STATE_ON,
}
def _get_device_class(spc_type): def _get_device_class(spc_type):
"""Get the device class."""
return SPC_TYPE_TO_DEVICE_CLASS.get(spc_type, None) return SPC_TYPE_TO_DEVICE_CLASS.get(spc_type, None)
def _get_sensor_state(spc_input): def _get_sensor_state(spc_input):
"""Get the sensor state."""
return SPC_INPUT_TO_SENSOR_STATE.get(spc_input, STATE_UNAVAILABLE) return SPC_INPUT_TO_SENSOR_STATE.get(spc_input, STATE_UNAVAILABLE)
def _create_sensor(hass, zone): def _create_sensor(hass, zone):
return SpcBinarySensor(zone_id=zone['id'], """Create a SPC sensor."""
name=zone['zone_name'], return SpcBinarySensor(
state=_get_sensor_state(zone['input']), zone_id=zone['id'], name=zone['zone_name'],
device_class=_get_device_class(zone['type']), state=_get_sensor_state(zone['input']),
spc_registry=hass.data[DATA_REGISTRY]) device_class=_get_device_class(zone['type']),
spc_registry=hass.data[DATA_REGISTRY])
@asyncio.coroutine @asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
discovery_info=None): """Set up the SPC binary sensor."""
"""Initialize the platform."""
if (discovery_info is None or if (discovery_info is None or
discovery_info[ATTR_DISCOVER_DEVICES] is None): discovery_info[ATTR_DISCOVER_DEVICES] is None):
return return
@ -55,7 +58,7 @@ def async_setup_platform(hass, config, async_add_devices,
class SpcBinarySensor(BinarySensorDevice): class SpcBinarySensor(BinarySensorDevice):
"""Represents a sensor based on an SPC zone.""" """Representation of a sensor based on a SPC zone."""
def __init__(self, zone_id, name, state, device_class, spc_registry): def __init__(self, zone_id, name, state, device_class, spc_registry):
"""Initialize the sensor device.""" """Initialize the sensor device."""
@ -74,7 +77,7 @@ class SpcBinarySensor(BinarySensorDevice):
@property @property
def name(self): def name(self):
"""The name of the device.""" """Return the name of the device."""
return self._name return self._name
@property @property
@ -85,7 +88,7 @@ class SpcBinarySensor(BinarySensorDevice):
@property @property
def hidden(self) -> bool: def hidden(self) -> bool:
"""Whether the device is hidden by default.""" """Whether the device is hidden by default."""
# these type of sensors are probably mainly used for automations # These type of sensors are probably mainly used for automations
return True return True
@property @property
@ -95,5 +98,5 @@ class SpcBinarySensor(BinarySensorDevice):
@property @property
def device_class(self): def device_class(self):
"""The device class.""" """Return the device class."""
return self._device_class return self._device_class

View file

@ -4,15 +4,15 @@ Support for Taps Affs.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.tapsaff/ https://home-assistant.io/components/binary_sensor.tapsaff/
""" """
import logging
from datetime import timedelta from datetime import timedelta
import logging
import voluptuous as vol import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.binary_sensor import ( from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA) PLATFORM_SCHEMA, BinarySensorDevice)
from homeassistant.const import (CONF_NAME) from homeassistant.const import CONF_NAME
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['tapsaff==0.1.3'] REQUIREMENTS = ['tapsaff==0.1.3']
@ -67,7 +67,7 @@ class TapsAffData(object):
"""Class for handling the data retrieval for pins.""" """Class for handling the data retrieval for pins."""
def __init__(self, location): def __init__(self, location):
"""Initialize the sensor.""" """Initialize the data object."""
from tapsaff import TapsAff from tapsaff import TapsAff
self._is_taps_aff = None self._is_taps_aff = None

View file

@ -28,7 +28,7 @@ class TeslaBinarySensor(TeslaDevice, BinarySensorDevice):
"""Implement an Tesla binary sensor for parking and charger.""" """Implement an Tesla binary sensor for parking and charger."""
def __init__(self, tesla_device, controller, sensor_type): def __init__(self, tesla_device, controller, sensor_type):
"""Initialisation of binary sensor.""" """Initialise of a Tesla binary sensor."""
super().__init__(tesla_device, controller) super().__init__(tesla_device, controller)
self._state = False self._state = False
self.entity_id = ENTITY_ID_FORMAT.format(self.tesla_id) self.entity_id = ENTITY_ID_FORMAT.format(self.tesla_id)

View file

@ -6,15 +6,15 @@ https://home-assistant.io/components/binary_sensor.verisure/
""" """
import logging import logging
from homeassistant.components.verisure import HUB as hub
from homeassistant.components.binary_sensor import BinarySensorDevice from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.components.verisure import CONF_DOOR_WINDOW from homeassistant.components.verisure import CONF_DOOR_WINDOW
from homeassistant.components.verisure import HUB as hub
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup Verisure binary sensors.""" """Set up the Verisure binary sensors."""
sensors = [] sensors = []
hub.update_overview() hub.update_overview()
@ -27,10 +27,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class VerisureDoorWindowSensor(BinarySensorDevice): class VerisureDoorWindowSensor(BinarySensorDevice):
"""Verisure door window sensor.""" """Representation of a Verisure door window sensor."""
def __init__(self, device_label): def __init__(self, device_label):
"""Initialize the modbus coil sensor.""" """Initialize the Verisure door window sensor."""
self._device_label = device_label self._device_label = device_label
@property @property

View file

@ -31,7 +31,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Vultr subscription (server) sensor.""" """Set up the Vultr subscription (server) binary sensor."""
vultr = hass.data[DATA_VULTR] vultr = hass.data[DATA_VULTR]
subscription = config.get(CONF_SUBSCRIPTION) subscription = config.get(CONF_SUBSCRIPTION)
@ -39,7 +39,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
if subscription not in vultr.data: if subscription not in vultr.data:
_LOGGER.error("Subscription %s not found", subscription) _LOGGER.error("Subscription %s not found", subscription)
return False return
add_devices([VultrBinarySensor(vultr, subscription, name)], True) add_devices([VultrBinarySensor(vultr, subscription, name)], True)
@ -48,7 +48,7 @@ class VultrBinarySensor(BinarySensorDevice):
"""Representation of a Vultr subscription sensor.""" """Representation of a Vultr subscription sensor."""
def __init__(self, vultr, subscription, name): def __init__(self, vultr, subscription, name):
"""Initialize a new Vultr sensor.""" """Initialize a new Vultr binary sensor."""
self._vultr = vultr self._vultr = vultr
self._name = name self._name = name

View file

@ -8,7 +8,7 @@ import asyncio
import logging import logging
from homeassistant.components.binary_sensor import BinarySensorDevice from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.components.wink import WinkDevice, DOMAIN from homeassistant.components.wink import DOMAIN, WinkDevice
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -16,18 +16,18 @@ DEPENDENCIES = ['wink']
# These are the available sensors mapped to binary_sensor class # These are the available sensors mapped to binary_sensor class
SENSOR_TYPES = { SENSOR_TYPES = {
'opened': 'opening',
'brightness': 'light', 'brightness': 'light',
'vibration': 'vibration',
'loudness': 'sound',
'noise': 'sound',
'capturing_audio': 'sound', 'capturing_audio': 'sound',
'liquid_detected': 'moisture', 'capturing_video': None,
'motion': 'motion',
'presence': 'occupancy',
'co_detected': 'gas', 'co_detected': 'gas',
'liquid_detected': 'moisture',
'loudness': 'sound',
'motion': 'motion',
'noise': 'sound',
'opened': 'opening',
'presence': 'occupancy',
'smoke_detected': 'smoke', 'smoke_detected': 'smoke',
'capturing_video': None 'vibration': 'vibration',
} }
@ -103,7 +103,7 @@ class WinkBinarySensorDevice(WinkDevice, BinarySensorDevice):
@asyncio.coroutine @asyncio.coroutine
def async_added_to_hass(self): def async_added_to_hass(self):
"""Callback when entity is added to hass.""" """Call when entity is added to hass."""
self.hass.data[DOMAIN]['entities']['binary_sensor'].append(self) self.hass.data[DOMAIN]['entities']['binary_sensor'].append(self)
@property @property
@ -118,7 +118,7 @@ class WinkBinarySensorDevice(WinkDevice, BinarySensorDevice):
@property @property
def device_state_attributes(self): def device_state_attributes(self):
"""Return the state attributes.""" """Return the device state attributes."""
return super().device_state_attributes return super().device_state_attributes
@ -127,7 +127,7 @@ class WinkSmokeDetector(WinkBinarySensorDevice):
@property @property
def device_state_attributes(self): def device_state_attributes(self):
"""Return the state attributes.""" """Return the device state attributes."""
_attributes = super().device_state_attributes _attributes = super().device_state_attributes
_attributes['test_activated'] = self.wink.test_activated() _attributes['test_activated'] = self.wink.test_activated()
return _attributes return _attributes
@ -138,7 +138,7 @@ class WinkHub(WinkBinarySensorDevice):
@property @property
def device_state_attributes(self): def device_state_attributes(self):
"""Return the state attributes.""" """Return the device state attributes."""
_attributes = super().device_state_attributes _attributes = super().device_state_attributes
_attributes['update_needed'] = self.wink.update_needed() _attributes['update_needed'] = self.wink.update_needed()
_attributes['firmware_version'] = self.wink.firmware_version() _attributes['firmware_version'] = self.wink.firmware_version()
@ -170,7 +170,7 @@ class WinkButton(WinkBinarySensorDevice):
@property @property
def device_state_attributes(self): def device_state_attributes(self):
"""Return the state attributes.""" """Return the device state attributes."""
_attributes = super().device_state_attributes _attributes = super().device_state_attributes
_attributes['pressed'] = self.wink.pressed() _attributes['pressed'] = self.wink.pressed()
_attributes['long_pressed'] = self.wink.long_pressed() _attributes['long_pressed'] = self.wink.long_pressed()

View file

@ -4,18 +4,18 @@ Support for WebDav Calendar.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/calendar.caldav/ https://home-assistant.io/components/calendar.caldav/
""" """
from datetime import datetime, timedelta
import logging import logging
import re import re
from datetime import datetime, timedelta
import voluptuous as vol import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.calendar import ( from homeassistant.components.calendar import (
CalendarEventDevice, PLATFORM_SCHEMA) PLATFORM_SCHEMA, CalendarEventDevice)
from homeassistant.const import ( from homeassistant.const import (
CONF_NAME, CONF_PASSWORD, CONF_URL, CONF_USERNAME) CONF_NAME, CONF_PASSWORD, CONF_URL, CONF_USERNAME)
from homeassistant.util import dt, Throttle import homeassistant.helpers.config_validation as cv
from homeassistant.util import Throttle, dt
REQUIREMENTS = ['caldav==0.5.0'] REQUIREMENTS = ['caldav==0.5.0']
@ -39,9 +39,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_CUSTOM_CALENDARS, default=[]): vol.Optional(CONF_CUSTOM_CALENDARS, default=[]):
vol.All(cv.ensure_list, vol.Schema([ vol.All(cv.ensure_list, vol.Schema([
vol.Schema({ vol.Schema({
vol.Required(CONF_NAME): cv.string,
vol.Required(CONF_CALENDAR): cv.string, vol.Required(CONF_CALENDAR): cv.string,
vol.Required(CONF_SEARCH): cv.string vol.Required(CONF_NAME): cv.string,
vol.Required(CONF_SEARCH): cv.string,
}) })
])) ]))
}) })
@ -53,12 +53,12 @@ def setup_platform(hass, config, add_devices, disc_info=None):
"""Set up the WebDav Calendar platform.""" """Set up the WebDav Calendar platform."""
import caldav import caldav
client = caldav.DAVClient(config.get(CONF_URL), url = config.get(CONF_URL)
None, username = config.get(CONF_USERNAME)
config.get(CONF_USERNAME), password = config.get(CONF_PASSWORD)
config.get(CONF_PASSWORD))
client = caldav.DAVClient(url, None, username, password)
# Retrieve all the remote calendars
calendars = client.principal().calendars() calendars = client.principal().calendars()
calendar_devices = [] calendar_devices = []
@ -70,8 +70,7 @@ def setup_platform(hass, config, add_devices, disc_info=None):
_LOGGER.debug("Ignoring calendar '%s'", calendar.name) _LOGGER.debug("Ignoring calendar '%s'", calendar.name)
continue continue
# Create additional calendars based on custom filtering # Create additional calendars based on custom filtering rules
# rules
for cust_calendar in config.get(CONF_CUSTOM_CALENDARS): for cust_calendar in config.get(CONF_CUSTOM_CALENDARS):
# Check that the base calendar matches # Check that the base calendar matches
if cust_calendar.get(CONF_CALENDAR) != calendar.name: if cust_calendar.get(CONF_CALENDAR) != calendar.name:
@ -85,12 +84,9 @@ def setup_platform(hass, config, add_devices, disc_info=None):
} }
calendar_devices.append( calendar_devices.append(
WebDavCalendarEventDevice(hass, WebDavCalendarEventDevice(
device_data, hass, device_data, calendar, True,
calendar, cust_calendar.get(CONF_SEARCH)))
True,
cust_calendar.get(CONF_SEARCH))
)
# Create a default calendar if there was no custom one # Create a default calendar if there was no custom one
if not config.get(CONF_CUSTOM_CALENDARS): if not config.get(CONF_CUSTOM_CALENDARS):
@ -102,18 +98,13 @@ def setup_platform(hass, config, add_devices, disc_info=None):
WebDavCalendarEventDevice(hass, device_data, calendar) WebDavCalendarEventDevice(hass, device_data, calendar)
) )
# Finally add all the calendars we've created
add_devices(calendar_devices) add_devices(calendar_devices)
class WebDavCalendarEventDevice(CalendarEventDevice): class WebDavCalendarEventDevice(CalendarEventDevice):
"""A device for getting the next Task from a WebDav Calendar.""" """A device for getting the next Task from a WebDav Calendar."""
def __init__(self, def __init__(self, hass, device_data, calendar, all_day=False,
hass,
device_data,
calendar,
all_day=False,
search=None): search=None):
"""Create the WebDav Calendar Event Device.""" """Create the WebDav Calendar Event Device."""
self.data = WebDavCalendarData(calendar, all_day, search) self.data = WebDavCalendarData(calendar, all_day, search)
@ -167,9 +158,7 @@ class WebDavCalendarData(object):
if vevent is None: if vevent is None:
_LOGGER.debug( _LOGGER.debug(
"No matching event found in the %d results for %s", "No matching event found in the %d results for %s",
len(results), len(results), self.calendar.name)
self.calendar.name,
)
self.event = None self.event = None
return True return True

View file

@ -4,29 +4,28 @@ Support for Todoist task management (https://todoist.com).
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/calendar.todoist/ https://home-assistant.io/components/calendar.todoist/
""" """
from datetime import datetime, timedelta
from datetime import datetime
from datetime import timedelta
import logging import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.components.calendar import ( from homeassistant.components.calendar import (
CalendarEventDevice, DOMAIN, PLATFORM_SCHEMA) DOMAIN, PLATFORM_SCHEMA, CalendarEventDevice)
from homeassistant.components.google import ( from homeassistant.components.google import CONF_DEVICE_ID
CONF_DEVICE_ID) from homeassistant.const import CONF_ID, CONF_NAME, CONF_TOKEN
from homeassistant.const import (
CONF_ID, CONF_NAME, CONF_TOKEN)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.template import DATE_STR_FORMAT from homeassistant.helpers.template import DATE_STR_FORMAT
from homeassistant.util import dt from homeassistant.util import Throttle, dt
from homeassistant.util import Throttle
REQUIREMENTS = ['todoist-python==7.0.17'] REQUIREMENTS = ['todoist-python==7.0.17']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONF_EXTRA_PROJECTS = 'custom_projects'
CONF_PROJECT_DUE_DATE = 'due_date_days'
CONF_PROJECT_LABEL_WHITELIST = 'labels'
CONF_PROJECT_WHITELIST = 'include_projects'
# Calendar Platform: Does this calendar event last all day? # Calendar Platform: Does this calendar event last all day?
ALL_DAY = 'all_day' ALL_DAY = 'all_day'
# Attribute: All tasks in this project # Attribute: All tasks in this project
@ -78,20 +77,15 @@ SUMMARY = 'summary'
TASKS = 'items' TASKS = 'items'
SERVICE_NEW_TASK = 'todoist_new_task' SERVICE_NEW_TASK = 'todoist_new_task'
NEW_TASK_SERVICE_SCHEMA = vol.Schema({ NEW_TASK_SERVICE_SCHEMA = vol.Schema({
vol.Required(CONTENT): cv.string, vol.Required(CONTENT): cv.string,
vol.Optional(PROJECT_NAME, default='inbox'): vol.All(cv.string, vol.Lower), vol.Optional(PROJECT_NAME, default='inbox'): vol.All(cv.string, vol.Lower),
vol.Optional(LABELS): cv.ensure_list_csv, vol.Optional(LABELS): cv.ensure_list_csv,
vol.Optional(PRIORITY): vol.All(vol.Coerce(int), vol.Optional(PRIORITY): vol.All(vol.Coerce(int), vol.Range(min=1, max=4)),
vol.Range(min=1, max=4)), vol.Optional(DUE_DATE): cv.string,
vol.Optional(DUE_DATE): cv.string
}) })
CONF_EXTRA_PROJECTS = 'custom_projects'
CONF_PROJECT_DUE_DATE = 'due_date_days'
CONF_PROJECT_WHITELIST = 'include_projects'
CONF_PROJECT_LABEL_WHITELIST = 'labels'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_TOKEN): cv.string, vol.Required(CONF_TOKEN): cv.string,
vol.Optional(CONF_EXTRA_PROJECTS, default=[]): vol.Optional(CONF_EXTRA_PROJECTS, default=[]):
@ -111,8 +105,7 @@ MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=15)
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Todoist platform.""" """Set up the Todoist platform."""
# Check token:
token = config.get(CONF_TOKEN) token = config.get(CONF_TOKEN)
# Look up IDs based on (lowercase) names. # Look up IDs based on (lowercase) names.
@ -176,7 +169,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices(project_devices) add_devices(project_devices)
def handle_new_task(call): def handle_new_task(call):
"""Called when a user creates a new Todoist Task from HASS.""" """Call when a user creates a new Todoist Task from HASS."""
project_name = call.data[PROJECT_NAME] project_name = call.data[PROJECT_NAME]
project_id = project_id_lookup[project_name] project_id = project_id_lookup[project_name]
@ -528,8 +521,7 @@ class TodoistProjectData(object):
# Let's set our "due date" to tomorrow # Let's set our "due date" to tomorrow
self.event[END] = { self.event[END] = {
DATETIME: ( DATETIME: (
datetime.utcnow() + datetime.utcnow() + timedelta(days=1)
timedelta(days=1)
).strftime(DATE_STR_FORMAT) ).strftime(DATE_STR_FORMAT)
} }
_LOGGER.debug("Updated %s", self._name) _LOGGER.debug("Updated %s", self._name)

View file

@ -6,11 +6,11 @@ https://home-assistant.io/components/camera.axis/
""" """
import logging import logging
from homeassistant.const import (
CONF_HOST, CONF_NAME, CONF_USERNAME, CONF_PASSWORD, CONF_PORT,
CONF_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION)
from homeassistant.components.camera.mjpeg import ( from homeassistant.components.camera.mjpeg import (
CONF_MJPEG_URL, CONF_STILL_IMAGE_URL, MjpegCamera) CONF_MJPEG_URL, CONF_STILL_IMAGE_URL, MjpegCamera)
from homeassistant.const import (
CONF_AUTHENTICATION, CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_PORT,
CONF_USERNAME, HTTP_DIGEST_AUTHENTICATION)
from homeassistant.helpers.dispatcher import dispatcher_connect from homeassistant.helpers.dispatcher import dispatcher_connect
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -20,6 +20,7 @@ DEPENDENCIES = [DOMAIN]
def _get_image_url(host, port, mode): def _get_image_url(host, port, mode):
"""Set the URL to get the image."""
if mode == 'mjpeg': if mode == 'mjpeg':
return 'http://{}:{}/axis-cgi/mjpg/video.cgi'.format(host, port) return 'http://{}:{}/axis-cgi/mjpg/video.cgi'.format(host, port)
elif mode == 'single': elif mode == 'single':
@ -27,34 +28,32 @@ def _get_image_url(host, port, mode):
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup Axis camera.""" """Set up the Axis camera."""
camera_config = { camera_config = {
CONF_NAME: discovery_info[CONF_NAME], CONF_NAME: discovery_info[CONF_NAME],
CONF_USERNAME: discovery_info[CONF_USERNAME], CONF_USERNAME: discovery_info[CONF_USERNAME],
CONF_PASSWORD: discovery_info[CONF_PASSWORD], CONF_PASSWORD: discovery_info[CONF_PASSWORD],
CONF_MJPEG_URL: _get_image_url(discovery_info[CONF_HOST], CONF_MJPEG_URL: _get_image_url(
str(discovery_info[CONF_PORT]), discovery_info[CONF_HOST], str(discovery_info[CONF_PORT]),
'mjpeg'), 'mjpeg'),
CONF_STILL_IMAGE_URL: _get_image_url(discovery_info[CONF_HOST], CONF_STILL_IMAGE_URL: _get_image_url(
str(discovery_info[CONF_PORT]), discovery_info[CONF_HOST], str(discovery_info[CONF_PORT]),
'single'), 'single'),
CONF_AUTHENTICATION: HTTP_DIGEST_AUTHENTICATION, CONF_AUTHENTICATION: HTTP_DIGEST_AUTHENTICATION,
} }
add_devices([AxisCamera(hass, add_devices([AxisCamera(
camera_config, hass, camera_config, str(discovery_info[CONF_PORT]))])
str(discovery_info[CONF_PORT]))])
class AxisCamera(MjpegCamera): class AxisCamera(MjpegCamera):
"""AxisCamera class.""" """Representation of a Axis camera."""
def __init__(self, hass, config, port): def __init__(self, hass, config, port):
"""Initialize Axis Communications camera component.""" """Initialize Axis Communications camera component."""
super().__init__(hass, config) super().__init__(hass, config)
self.port = port self.port = port
dispatcher_connect(hass, dispatcher_connect(
DOMAIN + '_' + config[CONF_NAME] + '_new_ip', hass, DOMAIN + '_' + config[CONF_NAME] + '_new_ip', self._new_ip)
self._new_ip)
def _new_ip(self, host): def _new_ip(self, host):
"""Set new IP for video stream.""" """Set new IP for video stream."""

View file

@ -4,21 +4,21 @@ Support for Blink system camera.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/camera.blink/ https://home-assistant.io/components/camera.blink/
""" """
from datetime import timedelta
import logging import logging
from datetime import timedelta
import requests import requests
from homeassistant.components.blink import DOMAIN from homeassistant.components.blink import DOMAIN
from homeassistant.components.camera import Camera from homeassistant.components.camera import Camera
from homeassistant.util import Throttle from homeassistant.util import Throttle
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['blink'] DEPENDENCIES = ['blink']
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=90) MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=90)
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up a Blink Camera.""" """Set up a Blink Camera."""
@ -45,7 +45,7 @@ class BlinkCamera(Camera):
self.notifications = self.data.cameras[self._name].notifications self.notifications = self.data.cameras[self._name].notifications
self.response = None self.response = None
_LOGGER.info("Initialized blink camera %s", self._name) _LOGGER.debug("Initialized blink camera %s", self._name)
@property @property
def name(self): def name(self):
@ -55,7 +55,7 @@ class BlinkCamera(Camera):
@Throttle(MIN_TIME_BETWEEN_UPDATES) @Throttle(MIN_TIME_BETWEEN_UPDATES)
def request_image(self): def request_image(self):
"""Request a new image from Blink servers.""" """Request a new image from Blink servers."""
_LOGGER.info("Requesting new image from blink servers") _LOGGER.debug("Requesting new image from blink servers")
image_url = self.check_for_motion() image_url = self.check_for_motion()
header = self.data.cameras[self._name].header header = self.data.cameras[self._name].header
self.response = requests.get(image_url, headers=header, stream=True) self.response = requests.get(image_url, headers=header, stream=True)
@ -68,7 +68,7 @@ class BlinkCamera(Camera):
# We detected motion at some point # We detected motion at some point
self.data.last_motion() self.data.last_motion()
self.notifications = notifs self.notifications = notifs
# returning motion image currently not working # Returning motion image currently not working
# return self.data.cameras[self._name].motion['image'] # return self.data.cameras[self._name].motion['image']
elif notifs < self.notifications: elif notifs < self.notifications:
self.notifications = notifs self.notifications = notifs

View file

@ -9,25 +9,18 @@ import re
import voluptuous as vol import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.climate import ( from homeassistant.components.climate import (
ATTR_OPERATION_MODE, ATTR_FAN_MODE, ATTR_SWING_MODE, ATTR_CURRENT_TEMPERATURE, ATTR_FAN_MODE, ATTR_OPERATION_MODE,
ATTR_CURRENT_TEMPERATURE, ClimateDevice, PLATFORM_SCHEMA, ATTR_SWING_MODE, PLATFORM_SCHEMA, STATE_AUTO, STATE_COOL, STATE_DRY,
SUPPORT_TARGET_TEMPERATURE, SUPPORT_FAN_MODE, SUPPORT_OPERATION_MODE, STATE_FAN_ONLY, STATE_HEAT, STATE_OFF, SUPPORT_FAN_MODE,
SUPPORT_SWING_MODE, STATE_OFF, STATE_AUTO, STATE_HEAT, STATE_COOL, SUPPORT_OPERATION_MODE, SUPPORT_SWING_MODE, SUPPORT_TARGET_TEMPERATURE,
STATE_DRY, STATE_FAN_ONLY ClimateDevice)
)
from homeassistant.components.daikin import ( from homeassistant.components.daikin import (
daikin_api_setup, ATTR_INSIDE_TEMPERATURE, ATTR_OUTSIDE_TEMPERATURE, ATTR_TARGET_TEMPERATURE,
ATTR_TARGET_TEMPERATURE, daikin_api_setup)
ATTR_INSIDE_TEMPERATURE,
ATTR_OUTSIDE_TEMPERATURE
)
from homeassistant.const import ( from homeassistant.const import (
CONF_HOST, CONF_NAME, ATTR_TEMPERATURE, CONF_HOST, CONF_NAME, TEMP_CELSIUS)
TEMP_CELSIUS, import homeassistant.helpers.config_validation as cv
ATTR_TEMPERATURE
)
REQUIREMENTS = ['pydaikin==0.4'] REQUIREMENTS = ['pydaikin==0.4']
@ -60,15 +53,15 @@ HA_ATTR_TO_DAIKIN = {
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Daikin HVAC platform.""" """Set up the Daikin HVAC platform."""
if discovery_info is not None: if discovery_info is not None:
host = discovery_info.get('ip') host = discovery_info.get('ip')
name = None name = None
_LOGGER.info("Discovered a Daikin AC on %s", host) _LOGGER.debug("Discovered a Daikin AC on %s", host)
else: else:
host = config.get(CONF_HOST) host = config.get(CONF_HOST)
name = config.get(CONF_NAME) name = config.get(CONF_NAME)
_LOGGER.info("Added Daikin AC on %s", host) _LOGGER.debug("Added Daikin AC on %s", host)
api = daikin_api_setup(hass, host, name) api = daikin_api_setup(hass, host, name)
add_devices([DaikinClimate(api)], True) add_devices([DaikinClimate(api)], True)
@ -130,7 +123,7 @@ class DaikinClimate(ClimateDevice):
).title() ).title()
if value is None: if value is None:
_LOGGER.warning("Invalid value requested for key %s", key) _LOGGER.error("Invalid value requested for key %s", key)
else: else:
if value == "-" or value == "--": if value == "-" or value == "--":
value = None value = None

View file

@ -10,17 +10,12 @@ import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.components.climate import ( from homeassistant.components.climate import (
DOMAIN, DOMAIN, PLATFORM_SCHEMA, STATE_ECO, STATE_ELECTRIC, STATE_GAS,
PLATFORM_SCHEMA, STATE_HEAT_PUMP, STATE_HIGH_DEMAND, STATE_OFF, STATE_PERFORMANCE,
STATE_ECO, STATE_GAS, STATE_ELECTRIC, SUPPORT_OPERATION_MODE, SUPPORT_TARGET_TEMPERATURE, ClimateDevice)
STATE_HEAT_PUMP, STATE_HIGH_DEMAND, from homeassistant.const import (
STATE_OFF, SUPPORT_TARGET_TEMPERATURE, ATTR_ENTITY_ID, ATTR_TEMPERATURE, CONF_PASSWORD, CONF_USERNAME,
SUPPORT_OPERATION_MODE, TEMP_FAHRENHEIT)
STATE_PERFORMANCE,
ClimateDevice)
from homeassistant.const import (ATTR_ENTITY_ID,
CONF_PASSWORD, CONF_USERNAME, TEMP_FAHRENHEIT,
ATTR_TEMPERATURE)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pyeconet==0.0.4'] REQUIREMENTS = ['pyeconet==0.0.4']
@ -89,7 +84,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
hass.data[ECONET_DATA]['water_heaters'].extend(hass_water_heaters) hass.data[ECONET_DATA]['water_heaters'].extend(hass_water_heaters)
def service_handle(service): def service_handle(service):
"""Handler for services.""" """Handle the service calls."""
entity_ids = service.data.get('entity_id') entity_ids = service.data.get('entity_id')
all_heaters = hass.data[ECONET_DATA]['water_heaters'] all_heaters = hass.data[ECONET_DATA]['water_heaters']
_heaters = [ _heaters = [
@ -107,12 +102,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
_water_heater.schedule_update_ha_state(True) _water_heater.schedule_update_ha_state(True)
hass.services.register(DOMAIN, SERVICE_ADD_VACATION, hass.services.register(DOMAIN, SERVICE_ADD_VACATION, service_handle,
service_handle,
schema=ADD_VACATION_SCHEMA) schema=ADD_VACATION_SCHEMA)
hass.services.register(DOMAIN, SERVICE_DELETE_VACATION, hass.services.register(DOMAIN, SERVICE_DELETE_VACATION, service_handle,
service_handle,
schema=DELETE_VACATION_SCHEMA) schema=DELETE_VACATION_SCHEMA)
@ -140,7 +133,7 @@ class EcoNetWaterHeater(ClimateDevice):
@property @property
def device_state_attributes(self): def device_state_attributes(self):
"""Return the optional state attributes.""" """Return the optional device state attributes."""
data = {} data = {}
vacations = self.water_heater.get_vacations() vacations = self.water_heater.get_vacations()
if vacations: if vacations:
@ -159,8 +152,7 @@ class EcoNetWaterHeater(ClimateDevice):
""" """
Return current operation as one of the following. Return current operation as one of the following.
["eco", "heat_pump", ["eco", "heat_pump", "high_demand", "electric_only"]
"high_demand", "electric_only"]
""" """
current_op = ECONET_STATE_TO_HA.get(self.water_heater.mode) current_op = ECONET_STATE_TO_HA.get(self.water_heater.mode)
return current_op return current_op
@ -191,7 +183,7 @@ class EcoNetWaterHeater(ClimateDevice):
if target_temp is not None: if target_temp is not None:
self.water_heater.set_target_set_point(target_temp) self.water_heater.set_target_set_point(target_temp)
else: else:
_LOGGER.error("A target temperature must be provided.") _LOGGER.error("A target temperature must be provided")
def set_operation_mode(self, operation_mode): def set_operation_mode(self, operation_mode):
"""Set operation mode.""" """Set operation mode."""
@ -199,7 +191,7 @@ class EcoNetWaterHeater(ClimateDevice):
if op_mode_to_set is not None: if op_mode_to_set is not None:
self.water_heater.set_mode(op_mode_to_set) self.water_heater.set_mode(op_mode_to_set)
else: else:
_LOGGER.error("An operation mode must be provided.") _LOGGER.error("An operation mode must be provided")
def add_vacation(self, start, end): def add_vacation(self, start, end):
"""Add a vacation to this water heater.""" """Add a vacation to this water heater."""

View file

@ -5,13 +5,14 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/climate.knx/ https://home-assistant.io/components/climate.knx/
""" """
import asyncio import asyncio
import voluptuous as vol import voluptuous as vol
from homeassistant.components.knx import DATA_KNX, ATTR_DISCOVER_DEVICES
from homeassistant.components.climate import ( from homeassistant.components.climate import (
PLATFORM_SCHEMA, ClimateDevice, SUPPORT_TARGET_TEMPERATURE, PLATFORM_SCHEMA, SUPPORT_OPERATION_MODE, SUPPORT_TARGET_TEMPERATURE,
SUPPORT_OPERATION_MODE) ClimateDevice)
from homeassistant.const import CONF_NAME, TEMP_CELSIUS, ATTR_TEMPERATURE from homeassistant.components.knx import ATTR_DISCOVER_DEVICES, DATA_KNX
from homeassistant.const import ATTR_TEMPERATURE, CONF_NAME, TEMP_CELSIUS
from homeassistant.core import callback from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
@ -61,24 +62,20 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
@asyncio.coroutine @asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
discovery_info=None):
"""Set up climate(s) for KNX platform.""" """Set up climate(s) for KNX platform."""
if DATA_KNX not in hass.data \ if DATA_KNX not in hass.data or not hass.data[DATA_KNX].initialized:
or not hass.data[DATA_KNX].initialized: return
return False
if discovery_info is not None: if discovery_info is not None:
async_add_devices_discovery(hass, discovery_info, async_add_devices) async_add_devices_discovery(hass, discovery_info, async_add_devices)
else: else:
async_add_devices_config(hass, config, async_add_devices) async_add_devices_config(hass, config, async_add_devices)
return True
@callback @callback
def async_add_devices_discovery(hass, discovery_info, async_add_devices): def async_add_devices_discovery(hass, discovery_info, async_add_devices):
"""Set up climates for KNX platform configured within plattform.""" """Set up climates for KNX platform configured within platform."""
entities = [] entities = []
for device_name in discovery_info[ATTR_DISCOVER_DEVICES]: for device_name in discovery_info[ATTR_DISCOVER_DEVICES]:
device = hass.data[DATA_KNX].xknx.devices[device_name] device = hass.data[DATA_KNX].xknx.devices[device_name]
@ -88,28 +85,22 @@ def async_add_devices_discovery(hass, discovery_info, async_add_devices):
@callback @callback
def async_add_devices_config(hass, config, async_add_devices): def async_add_devices_config(hass, config, async_add_devices):
"""Set up climate for KNX platform configured within plattform.""" """Set up climate for KNX platform configured within platform."""
import xknx import xknx
climate = xknx.devices.Climate( climate = xknx.devices.Climate(
hass.data[DATA_KNX].xknx, hass.data[DATA_KNX].xknx,
name=config.get(CONF_NAME), name=config.get(CONF_NAME),
group_address_temperature=config.get( group_address_temperature=config.get(CONF_TEMPERATURE_ADDRESS),
CONF_TEMPERATURE_ADDRESS),
group_address_target_temperature=config.get( group_address_target_temperature=config.get(
CONF_TARGET_TEMPERATURE_ADDRESS), CONF_TARGET_TEMPERATURE_ADDRESS),
group_address_setpoint_shift=config.get( group_address_setpoint_shift=config.get(CONF_SETPOINT_SHIFT_ADDRESS),
CONF_SETPOINT_SHIFT_ADDRESS),
group_address_setpoint_shift_state=config.get( group_address_setpoint_shift_state=config.get(
CONF_SETPOINT_SHIFT_STATE_ADDRESS), CONF_SETPOINT_SHIFT_STATE_ADDRESS),
setpoint_shift_step=config.get( setpoint_shift_step=config.get(CONF_SETPOINT_SHIFT_STEP),
CONF_SETPOINT_SHIFT_STEP), setpoint_shift_max=config.get(CONF_SETPOINT_SHIFT_MAX),
setpoint_shift_max=config.get( setpoint_shift_min=config.get(CONF_SETPOINT_SHIFT_MIN),
CONF_SETPOINT_SHIFT_MAX), group_address_operation_mode=config.get(CONF_OPERATION_MODE_ADDRESS),
setpoint_shift_min=config.get(
CONF_SETPOINT_SHIFT_MIN),
group_address_operation_mode=config.get(
CONF_OPERATION_MODE_ADDRESS),
group_address_operation_mode_state=config.get( group_address_operation_mode_state=config.get(
CONF_OPERATION_MODE_STATE_ADDRESS), CONF_OPERATION_MODE_STATE_ADDRESS),
group_address_controller_status=config.get( group_address_controller_status=config.get(
@ -127,10 +118,10 @@ def async_add_devices_config(hass, config, async_add_devices):
class KNXClimate(ClimateDevice): class KNXClimate(ClimateDevice):
"""Representation of a KNX climate.""" """Representation of a KNX climate device."""
def __init__(self, hass, device): def __init__(self, hass, device):
"""Initialization of KNXClimate.""" """Initialize of a KNX climate device."""
self.device = device self.device = device
self.hass = hass self.hass = hass
self.async_register_callbacks() self.async_register_callbacks()
@ -149,7 +140,7 @@ class KNXClimate(ClimateDevice):
"""Register callbacks to update hass after device was changed.""" """Register callbacks to update hass after device was changed."""
@asyncio.coroutine @asyncio.coroutine
def after_update_callback(device): def after_update_callback(device):
"""Callback after device was updated.""" """Call after device was updated."""
# pylint: disable=unused-argument # pylint: disable=unused-argument
yield from self.async_update_ha_state() yield from self.async_update_ha_state()
self.device.register_device_updated_cb(after_update_callback) self.device.register_device_updated_cb(after_update_callback)

View file

@ -7,9 +7,10 @@ https://home-assistant.io/components/climate.mysensors/
from homeassistant.components import mysensors from homeassistant.components import mysensors
from homeassistant.components.climate import ( from homeassistant.components.climate import (
ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW, DOMAIN, STATE_AUTO, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW, DOMAIN, STATE_AUTO,
STATE_COOL, STATE_HEAT, STATE_OFF, ClimateDevice, STATE_COOL, STATE_HEAT, STATE_OFF, SUPPORT_FAN_MODE,
SUPPORT_TARGET_TEMPERATURE, SUPPORT_TARGET_TEMPERATURE_HIGH, SUPPORT_OPERATION_MODE, SUPPORT_TARGET_TEMPERATURE,
SUPPORT_TARGET_TEMPERATURE_LOW, SUPPORT_FAN_MODE, SUPPORT_OPERATION_MODE) SUPPORT_TARGET_TEMPERATURE_HIGH, SUPPORT_TARGET_TEMPERATURE_LOW,
ClimateDevice)
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS, TEMP_FAHRENHEIT from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS, TEMP_FAHRENHEIT
DICT_HA_TO_MYS = { DICT_HA_TO_MYS = {
@ -31,7 +32,7 @@ SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_TARGET_TEMPERATURE_HIGH |
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the mysensors climate.""" """Set up the MySensors climate."""
mysensors.setup_mysensors_platform( mysensors.setup_mysensors_platform(
hass, DOMAIN, discovery_info, MySensorsHVAC, add_devices=add_devices) hass, DOMAIN, discovery_info, MySensorsHVAC, add_devices=add_devices)
@ -52,8 +53,7 @@ class MySensorsHVAC(mysensors.MySensorsEntity, ClimateDevice):
@property @property
def temperature_unit(self): def temperature_unit(self):
"""Return the unit of measurement.""" """Return the unit of measurement."""
return (TEMP_CELSIUS return TEMP_CELSIUS if self.gateway.metric else TEMP_FAHRENHEIT
if self.gateway.metric else TEMP_FAHRENHEIT)
@property @property
def current_temperature(self): def current_temperature(self):
@ -139,7 +139,8 @@ class MySensorsHVAC(mysensors.MySensorsEntity, ClimateDevice):
self.gateway.set_child_value( self.gateway.set_child_value(
self.node_id, self.child_id, value_type, value) self.node_id, self.child_id, value_type, value)
if self.gateway.optimistic: if self.gateway.optimistic:
# optimistically assume that device has changed state # O
# ptimistically assume that device has changed state
self._values[value_type] = value self._values[value_type] = value
self.schedule_update_ha_state() self.schedule_update_ha_state()
@ -149,7 +150,7 @@ class MySensorsHVAC(mysensors.MySensorsEntity, ClimateDevice):
self.gateway.set_child_value( self.gateway.set_child_value(
self.node_id, self.child_id, set_req.V_HVAC_SPEED, fan) self.node_id, self.child_id, set_req.V_HVAC_SPEED, fan)
if self.gateway.optimistic: if self.gateway.optimistic:
# optimistically assume that device has changed state # Optimistically assume that device has changed state
self._values[set_req.V_HVAC_SPEED] = fan self._values[set_req.V_HVAC_SPEED] = fan
self.schedule_update_ha_state() self.schedule_update_ha_state()
@ -159,7 +160,7 @@ class MySensorsHVAC(mysensors.MySensorsEntity, ClimateDevice):
self.node_id, self.child_id, self.value_type, self.node_id, self.child_id, self.value_type,
DICT_HA_TO_MYS[operation_mode]) DICT_HA_TO_MYS[operation_mode])
if self.gateway.optimistic: if self.gateway.optimistic:
# optimistically assume that device has changed state # Optimistically assume that device has changed state
self._values[self.value_type] = operation_mode self._values[self.value_type] = operation_mode
self.schedule_update_ha_state() self.schedule_update_ha_state()

View file

@ -6,13 +6,13 @@ https://home-assistant.io/components/climate.tesla/
""" """
import logging import logging
from homeassistant.const import STATE_ON, STATE_OFF
from homeassistant.components.climate import ( from homeassistant.components.climate import (
ClimateDevice, ENTITY_ID_FORMAT, SUPPORT_TARGET_TEMPERATURE, ENTITY_ID_FORMAT, SUPPORT_OPERATION_MODE, SUPPORT_TARGET_TEMPERATURE,
SUPPORT_OPERATION_MODE) ClimateDevice)
from homeassistant.components.tesla import DOMAIN as TESLA_DOMAIN, TeslaDevice from homeassistant.components.tesla import DOMAIN as TESLA_DOMAIN
from homeassistant.components.tesla import TeslaDevice
from homeassistant.const import ( from homeassistant.const import (
TEMP_FAHRENHEIT, TEMP_CELSIUS, ATTR_TEMPERATURE) ATTR_TEMPERATURE, STATE_OFF, STATE_ON, TEMP_CELSIUS, TEMP_FAHRENHEIT)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -60,7 +60,7 @@ class TeslaThermostat(TeslaDevice, ClimateDevice):
return OPERATION_LIST return OPERATION_LIST
def update(self): def update(self):
"""Called by the Tesla device callback to update state.""" """Call by the Tesla device callback to update state."""
_LOGGER.debug("Updating: %s", self._name) _LOGGER.debug("Updating: %s", self._name)
self.tesla_device.update() self.tesla_device.update()
self._target_temperature = self.tesla_device.get_goal_temp() self._target_temperature = self.tesla_device.get_goal_temp()

View file

@ -7,25 +7,25 @@ Eneco.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/climate.toon/ https://home-assistant.io/components/climate.toon/
""" """
import homeassistant.components.toon as toon_main
from homeassistant.components.climate import ( from homeassistant.components.climate import (
ClimateDevice, ATTR_TEMPERATURE, STATE_PERFORMANCE, STATE_HEAT, STATE_ECO, ATTR_TEMPERATURE, STATE_COOL, STATE_ECO, STATE_HEAT, STATE_PERFORMANCE,
STATE_COOL, SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE) SUPPORT_OPERATION_MODE, SUPPORT_TARGET_TEMPERATURE, ClimateDevice)
import homeassistant.components.toon as toon_main
from homeassistant.const import TEMP_CELSIUS from homeassistant.const import TEMP_CELSIUS
SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Toon thermostat.""" """Set up the Toon climate device."""
add_devices([ThermostatDevice(hass)], True) add_devices([ThermostatDevice(hass)], True)
class ThermostatDevice(ClimateDevice): class ThermostatDevice(ClimateDevice):
"""Interface class for the toon module and HA.""" """Representation of a Toon climate device."""
def __init__(self, hass): def __init__(self, hass):
"""Initialize the device.""" """Initialize the Toon climate device."""
self._name = 'Toon van Eneco' self._name = 'Toon van Eneco'
self.hass = hass self.hass = hass
self.thermos = hass.data[toon_main.TOON_HANDLE] self.thermos = hass.data[toon_main.TOON_HANDLE]
@ -47,12 +47,12 @@ class ThermostatDevice(ClimateDevice):
@property @property
def name(self): def name(self):
"""Name of this Thermostat.""" """Return the name of this thermostat."""
return self._name return self._name
@property @property
def temperature_unit(self): def temperature_unit(self):
"""The unit of measurement used by the platform.""" """Return the unit of measurement used by the platform."""
return TEMP_CELSIUS return TEMP_CELSIUS
@property @property
@ -63,7 +63,7 @@ class ThermostatDevice(ClimateDevice):
@property @property
def operation_list(self): def operation_list(self):
"""List of available operation modes.""" """Return a list of available operation modes."""
return self._operation_list return self._operation_list
@property @property
@ -82,7 +82,7 @@ class ThermostatDevice(ClimateDevice):
self.thermos.set_temp(temp) self.thermos.set_temp(temp)
def set_operation_mode(self, operation_mode): def set_operation_mode(self, operation_mode):
"""Set new operation mode as toonlib requires it.""" """Set new operation mode."""
toonlib_values = { toonlib_values = {
STATE_PERFORMANCE: 'Comfort', STATE_PERFORMANCE: 'Comfort',
STATE_HEAT: 'Home', STATE_HEAT: 'Home',

View file

@ -8,16 +8,16 @@ import asyncio
import logging import logging
from homeassistant.components.climate import ( from homeassistant.components.climate import (
STATE_ECO, STATE_GAS, STATE_AUTO, STATE_COOL, STATE_HEAT, STATE_ELECTRIC, ATTR_CURRENT_HUMIDITY, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW,
STATE_FAN_ONLY, STATE_HEAT_PUMP, ATTR_TEMPERATURE, STATE_HIGH_DEMAND, ATTR_TEMPERATURE, STATE_AUTO, STATE_COOL, STATE_ECO, STATE_ELECTRIC,
STATE_PERFORMANCE, ATTR_TARGET_TEMP_LOW, ATTR_CURRENT_HUMIDITY, STATE_FAN_ONLY, STATE_GAS, STATE_HEAT, STATE_HEAT_PUMP, STATE_HIGH_DEMAND,
ATTR_TARGET_TEMP_HIGH, ClimateDevice, SUPPORT_TARGET_TEMPERATURE, STATE_PERFORMANCE, SUPPORT_AUX_HEAT, SUPPORT_AWAY_MODE, SUPPORT_FAN_MODE,
SUPPORT_OPERATION_MODE, SUPPORT_TARGET_TEMPERATURE,
SUPPORT_TARGET_TEMPERATURE_HIGH, SUPPORT_TARGET_TEMPERATURE_LOW, SUPPORT_TARGET_TEMPERATURE_HIGH, SUPPORT_TARGET_TEMPERATURE_LOW,
SUPPORT_OPERATION_MODE, SUPPORT_AWAY_MODE, SUPPORT_FAN_MODE, ClimateDevice)
SUPPORT_AUX_HEAT)
from homeassistant.components.wink import DOMAIN, WinkDevice from homeassistant.components.wink import DOMAIN, WinkDevice
from homeassistant.const import ( from homeassistant.const import (
STATE_ON, STATE_OFF, TEMP_CELSIUS, STATE_UNKNOWN, PRECISION_TENTHS) PRECISION_TENTHS, STATE_OFF, STATE_ON, STATE_UNKNOWN, TEMP_CELSIUS)
from homeassistant.helpers.temperature import display_temp as show_temp from homeassistant.helpers.temperature import display_temp as show_temp
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -93,7 +93,7 @@ class WinkThermostat(WinkDevice, ClimateDevice):
@asyncio.coroutine @asyncio.coroutine
def async_added_to_hass(self): def async_added_to_hass(self):
"""Callback when entity is added to hass.""" """Call when entity is added to hass."""
self.hass.data[DOMAIN]['entities']['climate'].append(self) self.hass.data[DOMAIN]['entities']['climate'].append(self)
@property @property
@ -104,7 +104,7 @@ class WinkThermostat(WinkDevice, ClimateDevice):
@property @property
def device_state_attributes(self): def device_state_attributes(self):
"""Return the optional state attributes.""" """Return the optional device state attributes."""
data = {} data = {}
target_temp_high = self.target_temperature_high target_temp_high = self.target_temperature_high
target_temp_low = self.target_temperature_low target_temp_low = self.target_temperature_low
@ -385,7 +385,7 @@ class WinkAC(WinkDevice, ClimateDevice):
@property @property
def device_state_attributes(self): def device_state_attributes(self):
"""Return the optional state attributes.""" """Return the optional device state attributes."""
data = {} data = {}
target_temp_high = self.target_temperature_high target_temp_high = self.target_temperature_high
target_temp_low = self.target_temperature_low target_temp_low = self.target_temperature_low
@ -508,7 +508,7 @@ class WinkWaterHeater(WinkDevice, ClimateDevice):
@property @property
def device_state_attributes(self): def device_state_attributes(self):
"""Return the optional state attributes.""" """Return the optional device state attributes."""
data = {} data = {}
data[ATTR_VACATION_MODE] = self.wink.vacation_mode_enabled() data[ATTR_VACATION_MODE] = self.wink.vacation_mode_enabled()
data[ATTR_RHEEM_TYPE] = self.wink.rheem_type() data[ATTR_RHEEM_TYPE] = self.wink.rheem_type()

View file

@ -1,4 +1,9 @@
"""Component to integrate the Home Assistant cloud.""" """
Component to integrate the Home Assistant cloud.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/cloud/
"""
import asyncio import asyncio
from datetime import datetime from datetime import datetime
import json import json
@ -26,18 +31,18 @@ REQUIREMENTS = ['warrant==0.6.1']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONF_ALEXA = 'alexa' CONF_ALEXA = 'alexa'
CONF_GOOGLE_ACTIONS = 'google_actions' CONF_ALIASES = 'aliases'
CONF_FILTER = 'filter'
CONF_COGNITO_CLIENT_ID = 'cognito_client_id' CONF_COGNITO_CLIENT_ID = 'cognito_client_id'
CONF_ENTITY_CONFIG = 'entity_config'
CONF_FILTER = 'filter'
CONF_GOOGLE_ACTIONS = 'google_actions'
CONF_RELAYER = 'relayer' CONF_RELAYER = 'relayer'
CONF_USER_POOL_ID = 'user_pool_id' CONF_USER_POOL_ID = 'user_pool_id'
CONF_ALIASES = 'aliases'
MODE_DEV = 'development'
DEFAULT_MODE = 'production' DEFAULT_MODE = 'production'
DEPENDENCIES = ['http'] DEPENDENCIES = ['http']
CONF_ENTITY_CONFIG = 'entity_config' MODE_DEV = 'development'
ALEXA_ENTITY_SCHEMA = vol.Schema({ ALEXA_ENTITY_SCHEMA = vol.Schema({
vol.Optional(alexa_sh.CONF_DESCRIPTION): cv.string, vol.Optional(alexa_sh.CONF_DESCRIPTION): cv.string,
@ -149,7 +154,7 @@ class Cloud:
@property @property
def subscription_expired(self): def subscription_expired(self):
"""Return a boolen if the subscription has expired.""" """Return a boolean if the subscription has expired."""
return dt_util.utcnow() > self.expiration_date return dt_util.utcnow() > self.expiration_date
@property @property
@ -195,8 +200,8 @@ class Cloud:
if not jwt_success: if not jwt_success:
return False return False
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, self.hass.bus.async_listen_once(
self._start_cloud) EVENT_HOMEASSISTANT_START, self._start_cloud)
return True return True
@ -248,7 +253,7 @@ class Cloud:
for token in 'id_token', 'access_token': for token in 'id_token', 'access_token':
self._decode_claims(info[token]) self._decode_claims(info[token])
except ValueError as err: # Raised when token is invalid except ValueError as err: # Raised when token is invalid
_LOGGER.warning('Found invalid token %s: %s', token, err) _LOGGER.warning("Found invalid token %s: %s", token, err)
return return
self.id_token = info['id_token'] self.id_token = info['id_token']
@ -282,15 +287,15 @@ class Cloud:
header = jwt.get_unverified_header(token) header = jwt.get_unverified_header(token)
except jose_exceptions.JWTError as err: except jose_exceptions.JWTError as err:
raise ValueError(str(err)) from None raise ValueError(str(err)) from None
kid = header.get("kid") kid = header.get('kid')
if kid is None: if kid is None:
raise ValueError('No kid in header') raise ValueError("No kid in header")
# Locate the key for this kid # Locate the key for this kid
key = None key = None
for key_dict in self.jwt_keyset["keys"]: for key_dict in self.jwt_keyset['keys']:
if key_dict["kid"] == kid: if key_dict['kid'] == kid:
key = key_dict key = key_dict
break break
if not key: if not key:

View file

@ -1,7 +1,6 @@
"""Package to communicate with the authentication API.""" """Package to communicate with the authentication API."""
import logging import logging
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -22,7 +21,7 @@ class UserNotConfirmed(CloudError):
class ExpiredCode(CloudError): class ExpiredCode(CloudError):
"""Raised when an expired code is encoutered.""" """Raised when an expired code is encountered."""
class InvalidCode(CloudError): class InvalidCode(CloudError):
@ -38,7 +37,7 @@ class PasswordChangeRequired(CloudError):
class UnknownError(CloudError): class UnknownError(CloudError):
"""Raised when an unknown error occurrs.""" """Raised when an unknown error occurs."""
AWS_EXCEPTIONS = { AWS_EXCEPTIONS = {
@ -98,7 +97,7 @@ def resend_email_confirm(cloud, email):
def forgot_password(cloud, email): def forgot_password(cloud, email):
"""Initiate forgotten password flow.""" """Initialize forgotten password flow."""
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
cognito = _cognito(cloud, username=email) cognito = _cognito(cloud, username=email)

View file

@ -3,8 +3,8 @@ import asyncio
from functools import wraps from functools import wraps
import logging import logging
import voluptuous as vol
import async_timeout import async_timeout
import voluptuous as vol
from homeassistant.components.http import ( from homeassistant.components.http import (
HomeAssistantView, RequestDataValidator) HomeAssistantView, RequestDataValidator)
@ -17,7 +17,7 @@ _LOGGER = logging.getLogger(__name__)
@asyncio.coroutine @asyncio.coroutine
def async_setup(hass): def async_setup(hass):
"""Initialize the HTTP api.""" """Initialize the HTTP API."""
hass.http.register_view(CloudLoginView) hass.http.register_view(CloudLoginView)
hass.http.register_view(CloudLogoutView) hass.http.register_view(CloudLogoutView)
hass.http.register_view(CloudAccountView) hass.http.register_view(CloudAccountView)
@ -40,7 +40,7 @@ _CLOUD_ERRORS = {
def _handle_cloud_errors(handler): def _handle_cloud_errors(handler):
"""Helper method to handle auth errors.""" """Handle auth errors."""
@asyncio.coroutine @asyncio.coroutine
@wraps(handler) @wraps(handler)
def error_handler(view, request, *args, **kwargs): def error_handler(view, request, *args, **kwargs):

View file

@ -12,7 +12,6 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession
from . import auth_api from . import auth_api
from .const import MESSAGE_EXPIRATION from .const import MESSAGE_EXPIRATION
HANDLERS = Registry() HANDLERS = Registry()
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -85,7 +84,7 @@ class CloudIoT:
}) })
self.tries = 0 self.tries = 0
_LOGGER.info('Connected') _LOGGER.info("Connected")
self.state = STATE_CONNECTED self.state = STATE_CONNECTED
while not client.closed: while not client.closed:
@ -107,7 +106,7 @@ class CloudIoT:
disconnect_warn = 'Received invalid JSON.' disconnect_warn = 'Received invalid JSON.'
break break
_LOGGER.debug('Received message: %s', msg) _LOGGER.debug("Received message: %s", msg)
response = { response = {
'msgid': msg['msgid'], 'msgid': msg['msgid'],
@ -126,14 +125,14 @@ class CloudIoT:
response['error'] = 'unknown-handler' response['error'] = 'unknown-handler'
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
_LOGGER.exception('Error handling message') _LOGGER.exception("Error handling message")
response['error'] = 'exception' response['error'] = 'exception'
_LOGGER.debug('Publishing message: %s', response) _LOGGER.debug("Publishing message: %s", response)
yield from client.send_json(response) yield from client.send_json(response)
except auth_api.CloudError: except auth_api.CloudError:
_LOGGER.warning('Unable to connect: Unable to refresh token.') _LOGGER.warning("Unable to connect: Unable to refresh token.")
except client_exceptions.WSServerHandshakeError as err: except client_exceptions.WSServerHandshakeError as err:
if err.code == 401: if err.code == 401:
@ -141,18 +140,18 @@ class CloudIoT:
self.close_requested = True self.close_requested = True
# Should we notify user? # Should we notify user?
else: else:
_LOGGER.warning('Unable to connect: %s', err) _LOGGER.warning("Unable to connect: %s", err)
except client_exceptions.ClientError as err: except client_exceptions.ClientError as err:
_LOGGER.warning('Unable to connect: %s', err) _LOGGER.warning("Unable to connect: %s", err)
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
if not self.close_requested: if not self.close_requested:
_LOGGER.exception('Unexpected error') _LOGGER.exception("Unexpected error")
finally: finally:
if disconnect_warn is not None: if disconnect_warn is not None:
_LOGGER.warning('Connection closed: %s', disconnect_warn) _LOGGER.warning("Connection closed: %s", disconnect_warn)
if remove_hass_stop_listener is not None: if remove_hass_stop_listener is not None:
remove_hass_stop_listener() remove_hass_stop_listener()
@ -169,7 +168,7 @@ class CloudIoT:
self.tries += 1 self.tries += 1
try: try:
# Sleep 0, 5, 10, 15 up to 30 seconds between retries # Sleep 0, 5, 10, 15 ... up to 30 seconds between retries
self.retry_task = hass.async_add_job(asyncio.sleep( self.retry_task = hass.async_add_job(asyncio.sleep(
min(30, (self.tries - 1) * 5), loop=hass.loop)) min(30, (self.tries - 1) * 5), loop=hass.loop))
yield from self.retry_task yield from self.retry_task
@ -205,8 +204,8 @@ def async_handle_message(hass, cloud, handler_name, payload):
@asyncio.coroutine @asyncio.coroutine
def async_handle_alexa(hass, cloud, payload): def async_handle_alexa(hass, cloud, payload):
"""Handle an incoming IoT message for Alexa.""" """Handle an incoming IoT message for Alexa."""
result = yield from alexa.async_handle_message(hass, cloud.alexa_config, result = yield from alexa.async_handle_message(
payload) hass, cloud.alexa_config, payload)
return result return result
@ -214,8 +213,8 @@ def async_handle_alexa(hass, cloud, payload):
@asyncio.coroutine @asyncio.coroutine
def async_handle_google_actions(hass, cloud, payload): def async_handle_google_actions(hass, cloud, payload):
"""Handle an incoming IoT message for Google Actions.""" """Handle an incoming IoT message for Google Actions."""
result = yield from ga.async_handle_message(hass, cloud.gactions_config, result = yield from ga.async_handle_message(
payload) hass, cloud.gactions_config, payload)
return result return result
@ -227,9 +226,9 @@ def async_handle_cloud(hass, cloud, payload):
if action == 'logout': if action == 'logout':
yield from cloud.logout() yield from cloud.logout()
_LOGGER.error('You have been logged out from Home Assistant cloud: %s', _LOGGER.error("You have been logged out from Home Assistant cloud: %s",
payload['reason']) payload['reason'])
else: else:
_LOGGER.warning('Received unknown cloud action: %s', action) _LOGGER.warning("Received unknown cloud action: %s", action)
return None return None

View file

@ -8,11 +8,11 @@ import logging
import voluptuous as vol import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.const import ( from homeassistant.const import (
CONF_HOST, CONF_NAME, CONF_TOKEN, CONF_PIN, EVENT_HOMEASSISTANT_STOP) CONF_HOST, CONF_NAME, CONF_PIN, CONF_TOKEN, EVENT_HOMEASSISTANT_STOP)
from homeassistant.helpers import (discovery) from homeassistant.helpers import discovery
from homeassistant.helpers.dispatcher import (dispatcher_send) import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.dispatcher import dispatcher_send
REQUIREMENTS = ['pycomfoconnect==0.3'] REQUIREMENTS = ['pycomfoconnect==0.3']
@ -115,7 +115,7 @@ class ComfoConnectBridge(object):
self.comfoconnect.disconnect() self.comfoconnect.disconnect()
def sensor_callback(self, var, value): def sensor_callback(self, var, value):
"""Callback function for sensor updates.""" """Call function for sensor updates."""
_LOGGER.debug("Got value from bridge: %d = %d", var, value) _LOGGER.debug("Got value from bridge: %d = %d", var, value)
from pycomfoconnect import ( from pycomfoconnect import (

View file

@ -5,17 +5,18 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/cover.knx/ https://home-assistant.io/components/cover.knx/
""" """
import asyncio import asyncio
import voluptuous as vol import voluptuous as vol
from homeassistant.components.knx import DATA_KNX, ATTR_DISCOVER_DEVICES
from homeassistant.helpers.event import async_track_utc_time_change
from homeassistant.components.cover import ( from homeassistant.components.cover import (
CoverDevice, PLATFORM_SCHEMA, SUPPORT_OPEN, SUPPORT_CLOSE, ATTR_POSITION, ATTR_TILT_POSITION, PLATFORM_SCHEMA, SUPPORT_CLOSE,
SUPPORT_SET_POSITION, SUPPORT_STOP, SUPPORT_SET_TILT_POSITION, SUPPORT_OPEN, SUPPORT_SET_POSITION, SUPPORT_SET_TILT_POSITION,
ATTR_POSITION, ATTR_TILT_POSITION) SUPPORT_STOP, CoverDevice)
from homeassistant.core import callback from homeassistant.components.knx import ATTR_DISCOVER_DEVICES, DATA_KNX
from homeassistant.const import CONF_NAME from homeassistant.const import CONF_NAME
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.event import async_track_utc_time_change
CONF_MOVE_LONG_ADDRESS = 'move_long_address' CONF_MOVE_LONG_ADDRESS = 'move_long_address'
CONF_MOVE_SHORT_ADDRESS = 'move_short_address' CONF_MOVE_SHORT_ADDRESS = 'move_short_address'
@ -50,20 +51,16 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
@asyncio.coroutine @asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
discovery_info=None):
"""Set up cover(s) for KNX platform.""" """Set up cover(s) for KNX platform."""
if DATA_KNX not in hass.data \ if DATA_KNX not in hass.data or not hass.data[DATA_KNX].initialized:
or not hass.data[DATA_KNX].initialized: return
return False
if discovery_info is not None: if discovery_info is not None:
async_add_devices_discovery(hass, discovery_info, async_add_devices) async_add_devices_discovery(hass, discovery_info, async_add_devices)
else: else:
async_add_devices_config(hass, config, async_add_devices) async_add_devices_config(hass, config, async_add_devices)
return True
@callback @callback
def async_add_devices_discovery(hass, discovery_info, async_add_devices): def async_add_devices_discovery(hass, discovery_info, async_add_devices):
@ -114,7 +111,7 @@ class KNXCover(CoverDevice):
"""Register callbacks to update hass after device was changed.""" """Register callbacks to update hass after device was changed."""
@asyncio.coroutine @asyncio.coroutine
def after_update_callback(device): def after_update_callback(device):
"""Callback after device was updated.""" """Call after device was updated."""
# pylint: disable=unused-argument # pylint: disable=unused-argument
yield from self.async_update_ha_state() yield from self.async_update_ha_state()
self.device.register_device_updated_cb(after_update_callback) self.device.register_device_updated_cb(after_update_callback)
@ -209,7 +206,7 @@ class KNXCover(CoverDevice):
@callback @callback
def auto_updater_hook(self, now): def auto_updater_hook(self, now):
"""Callback for autoupdater.""" """Call for the autoupdater."""
# pylint: disable=unused-argument # pylint: disable=unused-argument
self.async_schedule_update_ha_state() self.async_schedule_update_ha_state()
if self.device.position_reached(): if self.device.position_reached():

View file

@ -5,12 +5,12 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/cover.mysensors/ https://home-assistant.io/components/cover.mysensors/
""" """
from homeassistant.components import mysensors from homeassistant.components import mysensors
from homeassistant.components.cover import CoverDevice, ATTR_POSITION, DOMAIN from homeassistant.components.cover import ATTR_POSITION, DOMAIN, CoverDevice
from homeassistant.const import STATE_ON, STATE_OFF from homeassistant.const import STATE_OFF, STATE_ON
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the mysensors platform for covers.""" """Set up the MySensors platform for covers."""
mysensors.setup_mysensors_platform( mysensors.setup_mysensors_platform(
hass, DOMAIN, discovery_info, MySensorsCover, add_devices=add_devices) hass, DOMAIN, discovery_info, MySensorsCover, add_devices=add_devices)

View file

@ -29,12 +29,12 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
}) })
def setup_platform(hass, config, add_devices_callback, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the RFXtrx cover.""" """Set up the RFXtrx cover."""
import RFXtrx as rfxtrxmod import RFXtrx as rfxtrxmod
covers = rfxtrx.get_devices_from_config(config, RfxtrxCover) covers = rfxtrx.get_devices_from_config(config, RfxtrxCover)
add_devices_callback(covers) add_devices(covers)
def cover_update(event): def cover_update(event):
"""Handle cover updates from the RFXtrx gateway.""" """Handle cover updates from the RFXtrx gateway."""
@ -45,7 +45,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
new_device = rfxtrx.get_new_device(event, config, RfxtrxCover) new_device = rfxtrx.get_new_device(event, config, RfxtrxCover)
if new_device: if new_device:
add_devices_callback([new_device]) add_devices([new_device])
rfxtrx.apply_received_command(event) rfxtrx.apply_received_command(event)
@ -59,7 +59,7 @@ class RfxtrxCover(rfxtrx.RfxtrxDevice, CoverDevice):
@property @property
def should_poll(self): def should_poll(self):
"""No polling available in RFXtrx cover.""" """Return the polling state. No polling available in RFXtrx cover."""
return False return False
@property @property

View file

@ -7,7 +7,7 @@ https://home-assistant.io/components/cover.wink/
import asyncio import asyncio
from homeassistant.components.cover import CoverDevice from homeassistant.components.cover import CoverDevice
from homeassistant.components.wink import WinkDevice, DOMAIN from homeassistant.components.wink import DOMAIN, WinkDevice
DEPENDENCIES = ['wink'] DEPENDENCIES = ['wink']
@ -31,7 +31,7 @@ class WinkCoverDevice(WinkDevice, CoverDevice):
@asyncio.coroutine @asyncio.coroutine
def async_added_to_hass(self): def async_added_to_hass(self):
"""Callback when entity is added to hass.""" """Call when entity is added to hass."""
self.hass.data[DOMAIN]['entities']['cover'].append(self) self.hass.data[DOMAIN]['entities']['cover'].append(self)
def close_cover(self, **kwargs): def close_cover(self, **kwargs):

View file

@ -5,11 +5,12 @@ For more details about this component, please refer to the documentation at
https://home-assistant.io/components/datadog/ https://home-assistant.io/components/datadog/
""" """
import logging import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.const import (CONF_HOST, CONF_PORT, CONF_PREFIX, from homeassistant.const import (
EVENT_LOGBOOK_ENTRY, EVENT_STATE_CHANGED, CONF_HOST, CONF_PORT, CONF_PREFIX, EVENT_LOGBOOK_ENTRY,
STATE_UNKNOWN) EVENT_STATE_CHANGED, STATE_UNKNOWN)
from homeassistant.helpers import state as state_helper from homeassistant.helpers import state as state_helper
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
@ -36,7 +37,7 @@ CONFIG_SCHEMA = vol.Schema({
def setup(hass, config): def setup(hass, config):
"""Setup the Datadog component.""" """Set up the Datadog component."""
from datadog import initialize, statsd from datadog import initialize, statsd
conf = config[DOMAIN] conf = config[DOMAIN]
@ -81,36 +82,19 @@ def setup(hass, config):
if isinstance(value, (float, int)): if isinstance(value, (float, int)):
attribute = "{}.{}".format(metric, key.replace(' ', '_')) attribute = "{}.{}".format(metric, key.replace(' ', '_'))
statsd.gauge( statsd.gauge(
attribute, attribute, value, sample_rate=sample_rate, tags=tags)
value,
sample_rate=sample_rate,
tags=tags
)
_LOGGER.debug( _LOGGER.debug(
'Sent metric %s: %s (tags: %s)', "Sent metric %s: %s (tags: %s)", attribute, value, tags)
attribute,
value,
tags
)
try: try:
value = state_helper.state_as_number(state) value = state_helper.state_as_number(state)
except ValueError: except ValueError:
_LOGGER.debug( _LOGGER.debug(
'Error sending %s: %s (tags: %s)', "Error sending %s: %s (tags: %s)", metric, state.state, tags)
metric,
state.state,
tags
)
return return
statsd.gauge( statsd.gauge(metric, value, sample_rate=sample_rate, tags=tags)
metric,
value,
sample_rate=sample_rate,
tags=tags
)
_LOGGER.debug('Sent metric %s: %s (tags: %s)', metric, value, tags) _LOGGER.debug('Sent metric %s: %s (tags: %s)', metric, value, tags)

View file

@ -60,7 +60,7 @@ def async_setup(hass, config):
@asyncio.coroutine @asyncio.coroutine
def async_deconz_discovered(service, discovery_info): def async_deconz_discovered(service, discovery_info):
"""Called when deCONZ gateway has been found.""" """Call when deCONZ gateway has been found."""
deconz_config = {} deconz_config = {}
deconz_config[CONF_HOST] = discovery_info.get(CONF_HOST) deconz_config[CONF_HOST] = discovery_info.get(CONF_HOST)
deconz_config[CONF_PORT] = discovery_info.get(CONF_PORT) deconz_config[CONF_PORT] = discovery_info.get(CONF_PORT)
@ -90,13 +90,13 @@ def async_setup_deconz(hass, config, deconz_config):
Load config, group, light and sensor data for server information. Load config, group, light and sensor data for server information.
Start websocket for push notification of state changes from deCONZ. Start websocket for push notification of state changes from deCONZ.
""" """
_LOGGER.debug('deCONZ config %s', deconz_config) _LOGGER.debug("deCONZ config %s", deconz_config)
from pydeconz import DeconzSession from pydeconz import DeconzSession
websession = async_get_clientsession(hass) websession = async_get_clientsession(hass)
deconz = DeconzSession(hass.loop, websession, **deconz_config) deconz = DeconzSession(hass.loop, websession, **deconz_config)
result = yield from deconz.async_load_parameters() result = yield from deconz.async_load_parameters()
if result is False: if result is False:
_LOGGER.error("Failed to communicate with deCONZ.") _LOGGER.error("Failed to communicate with deCONZ")
return False return False
hass.data[DOMAIN] = deconz hass.data[DOMAIN] = deconz
@ -126,8 +126,7 @@ def async_setup_deconz(hass, config, deconz_config):
data = call.data.get(SERVICE_DATA) data = call.data.get(SERVICE_DATA)
yield from deconz.async_put_state(field, data) yield from deconz.async_put_state(field, data)
hass.services.async_register( hass.services.async_register(
DOMAIN, 'configure', async_configure, DOMAIN, 'configure', async_configure, schema=SERVICE_SCHEMA)
schema=SERVICE_SCHEMA)
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, deconz.close) hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, deconz.close)
return True return True

View file

@ -14,8 +14,8 @@ from aiohttp import web
import voluptuous as vol import voluptuous as vol
from homeassistant.components.device_tracker import ( from homeassistant.components.device_tracker import (
PLATFORM_SCHEMA, ATTR_ATTRIBUTES, ATTR_DEV_ID, ATTR_HOST_NAME, ATTR_MAC, ATTR_ATTRIBUTES, ATTR_DEV_ID, ATTR_GPS, ATTR_GPS_ACCURACY, ATTR_HOST_NAME,
ATTR_GPS, ATTR_GPS_ACCURACY) ATTR_MAC, PLATFORM_SCHEMA)
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.core import callback from homeassistant.core import callback
@ -24,35 +24,33 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.event import async_track_time_interval from homeassistant.helpers.event import async_track_time_interval
REQUIREMENTS = ['aioautomatic==0.6.4'] REQUIREMENTS = ['aioautomatic==0.6.4']
DEPENDENCIES = ['http']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONF_CLIENT_ID = 'client_id'
CONF_SECRET = 'secret'
CONF_DEVICES = 'devices'
CONF_CURRENT_LOCATION = 'current_location'
DEFAULT_TIMEOUT = 5
DEFAULT_SCOPE = ['location', 'trip', 'vehicle:events', 'vehicle:profile']
FULL_SCOPE = DEFAULT_SCOPE + ['current_location']
ATTR_FUEL_LEVEL = 'fuel_level' ATTR_FUEL_LEVEL = 'fuel_level'
EVENT_AUTOMATIC_UPDATE = 'automatic_update'
AUTOMATIC_CONFIG_FILE = '.automatic/session-{}.json' AUTOMATIC_CONFIG_FILE = '.automatic/session-{}.json'
CONF_CLIENT_ID = 'client_id'
CONF_CURRENT_LOCATION = 'current_location'
CONF_DEVICES = 'devices'
CONF_SECRET = 'secret'
DATA_CONFIGURING = 'automatic_configurator_clients' DATA_CONFIGURING = 'automatic_configurator_clients'
DATA_REFRESH_TOKEN = 'refresh_token' DATA_REFRESH_TOKEN = 'refresh_token'
DEFAULT_SCOPE = ['location', 'trip', 'vehicle:events', 'vehicle:profile']
DEFAULT_TIMEOUT = 5
DEPENDENCIES = ['http']
EVENT_AUTOMATIC_UPDATE = 'automatic_update'
FULL_SCOPE = DEFAULT_SCOPE + ['current_location']
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_CLIENT_ID): cv.string, vol.Required(CONF_CLIENT_ID): cv.string,
vol.Required(CONF_SECRET): cv.string, vol.Required(CONF_SECRET): cv.string,
vol.Optional(CONF_CURRENT_LOCATION, default=False): cv.boolean, vol.Optional(CONF_CURRENT_LOCATION, default=False): cv.boolean,
vol.Optional(CONF_DEVICES, default=None): vol.All( vol.Optional(CONF_DEVICES, default=None):
cv.ensure_list, [cv.string]) vol.All(cv.ensure_list, [cv.string]),
}) })
@ -142,7 +140,7 @@ def async_setup_scanner(hass, config, async_see, discovery_info=None):
@asyncio.coroutine @asyncio.coroutine
def initialize_callback(code, state): def initialize_callback(code, state):
"""Callback after OAuth2 response is returned.""" """Call after OAuth2 response is returned."""
try: try:
session = yield from client.create_session_from_oauth_code( session = yield from client.create_session_from_oauth_code(
code, state) code, state)
@ -181,12 +179,12 @@ class AutomaticAuthCallbackView(HomeAssistantView):
return response return response
else: else:
_LOGGER.error( _LOGGER.error(
"Error authorizing Automatic. Invalid response returned.") "Error authorizing Automatic. Invalid response returned")
return response return response
if DATA_CONFIGURING not in hass.data or \ if DATA_CONFIGURING not in hass.data or \
params['state'] not in hass.data[DATA_CONFIGURING]: params['state'] not in hass.data[DATA_CONFIGURING]:
_LOGGER.error("Automatic configuration request not found.") _LOGGER.error("Automatic configuration request not found")
return response return response
code = params['code'] code = params['code']
@ -220,16 +218,15 @@ class AutomaticData(object):
@asyncio.coroutine @asyncio.coroutine
def handle_event(self, name, event): def handle_event(self, name, event):
"""Coroutine to update state for a realtime event.""" """Coroutine to update state for a real time event."""
import aioautomatic import aioautomatic
# Fire a hass event
self.hass.bus.async_fire(EVENT_AUTOMATIC_UPDATE, event.data) self.hass.bus.async_fire(EVENT_AUTOMATIC_UPDATE, event.data)
if event.vehicle.id not in self.vehicle_info: if event.vehicle.id not in self.vehicle_info:
# If vehicle hasn't been seen yet, request the detailed # If vehicle hasn't been seen yet, request the detailed
# info for this vehicle. # info for this vehicle.
_LOGGER.info("New vehicle found.") _LOGGER.info("New vehicle found")
try: try:
vehicle = yield from event.get_vehicle() vehicle = yield from event.get_vehicle()
except aioautomatic.exceptions.AutomaticError as err: except aioautomatic.exceptions.AutomaticError as err:
@ -240,7 +237,7 @@ class AutomaticData(object):
if event.created_at < self.vehicle_seen[event.vehicle.id]: if event.created_at < self.vehicle_seen[event.vehicle.id]:
# Skip events received out of order # Skip events received out of order
_LOGGER.debug("Skipping out of order event. Event Created %s. " _LOGGER.debug("Skipping out of order event. Event Created %s. "
"Last seen event: %s.", event.created_at, "Last seen event: %s", event.created_at,
self.vehicle_seen[event.vehicle.id]) self.vehicle_seen[event.vehicle.id])
return return
self.vehicle_seen[event.vehicle.id] = event.created_at self.vehicle_seen[event.vehicle.id] = event.created_at
@ -270,13 +267,13 @@ class AutomaticData(object):
self.ws_close_requested = False self.ws_close_requested = False
if self.ws_reconnect_handle is not None: if self.ws_reconnect_handle is not None:
_LOGGER.debug("Retrying websocket connection.") _LOGGER.debug("Retrying websocket connection")
try: try:
ws_loop_future = yield from self.client.ws_connect() ws_loop_future = yield from self.client.ws_connect()
except aioautomatic.exceptions.UnauthorizedClientError: except aioautomatic.exceptions.UnauthorizedClientError:
_LOGGER.error("Client unauthorized for websocket connection. " _LOGGER.error("Client unauthorized for websocket connection. "
"Ensure Websocket is selected in the Automatic " "Ensure Websocket is selected in the Automatic "
"developer application event delivery preferences.") "developer application event delivery preferences")
return return
except aioautomatic.exceptions.AutomaticError as err: except aioautomatic.exceptions.AutomaticError as err:
if self.ws_reconnect_handle is None: if self.ws_reconnect_handle is None:
@ -290,14 +287,14 @@ class AutomaticData(object):
self.ws_reconnect_handle() self.ws_reconnect_handle()
self.ws_reconnect_handle = None self.ws_reconnect_handle = None
_LOGGER.info("Websocket connected.") _LOGGER.info("Websocket connected")
try: try:
yield from ws_loop_future yield from ws_loop_future
except aioautomatic.exceptions.AutomaticError as err: except aioautomatic.exceptions.AutomaticError as err:
_LOGGER.error(str(err)) _LOGGER.error(str(err))
_LOGGER.info("Websocket closed.") _LOGGER.info("Websocket closed")
# If websocket was close was not requested, attempt to reconnect # If websocket was close was not requested, attempt to reconnect
if not self.ws_close_requested: if not self.ws_close_requested:

View file

@ -11,11 +11,11 @@ import re
import requests import requests
import voluptuous as vol import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.device_tracker import ( from homeassistant.components.device_tracker import (
DOMAIN, PLATFORM_SCHEMA, DeviceScanner) DOMAIN, PLATFORM_SCHEMA, DeviceScanner)
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -30,8 +30,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string, vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_PASSWORD): cv.string, vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_USERNAME): cv.string, vol.Required(CONF_USERNAME): cv.string,
vol.Optional(CONF_DHCP_SOFTWARE, vol.Optional(CONF_DHCP_SOFTWARE, default=DEFAULT_DHCP_SOFTWARE):
default=DEFAULT_DHCP_SOFTWARE): vol.In(DHCP_SOFTWARES) vol.In(DHCP_SOFTWARES),
}) })
@ -49,14 +49,14 @@ def get_scanner(hass, config):
def _refresh_on_acccess_denied(func): def _refresh_on_acccess_denied(func):
"""If remove rebooted, it lost our session so rebuld one and try again.""" """If remove rebooted, it lost our session so rebuld one and try again."""
def decorator(self, *args, **kwargs): def decorator(self, *args, **kwargs):
"""Wrapper function to refresh session_id on PermissionError.""" """Wrap the function to refresh session_id on PermissionError."""
try: try:
return func(self, *args, **kwargs) return func(self, *args, **kwargs)
except PermissionError: except PermissionError:
_LOGGER.warning("Invalid session detected." + _LOGGER.warning("Invalid session detected." +
" Tryign to refresh session_id and re-run the rpc") " Trying to refresh session_id and re-run RPC")
self.session_id = _get_session_id(self.url, self.username, self.session_id = _get_session_id(
self.password) self.url, self.username, self.password)
return func(self, *args, **kwargs) return func(self, *args, **kwargs)
@ -80,8 +80,8 @@ class UbusDeviceScanner(DeviceScanner):
self.last_results = {} self.last_results = {}
self.url = 'http://{}/ubus'.format(host) self.url = 'http://{}/ubus'.format(host)
self.session_id = _get_session_id(self.url, self.username, self.session_id = _get_session_id(
self.password) self.url, self.username, self.password)
self.hostapd = [] self.hostapd = []
self.mac2name = None self.mac2name = None
self.success_init = self.session_id is not None self.success_init = self.session_id is not None

View file

@ -84,7 +84,7 @@ class UPCDeviceScanner(DeviceScanner):
@asyncio.coroutine @asyncio.coroutine
def async_get_device_name(self, device): def async_get_device_name(self, device):
"""The firmware doesn't save the name of the wireless device.""" """Get the device name (the name of the wireless device not used)."""
return None return None
@asyncio.coroutine @asyncio.coroutine

View file

@ -3,38 +3,42 @@
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/fan.dyson/ https://home-assistant.io/components/fan.dyson/
""" """
import logging
import asyncio import asyncio
import voluptuous as vol import logging
import homeassistant.helpers.config_validation as cv
from homeassistant.components.fan import (FanEntity, SUPPORT_OSCILLATE,
SUPPORT_SET_SPEED,
DOMAIN)
from homeassistant.helpers.entity import ToggleEntity
from homeassistant.components.dyson import DYSON_DEVICES
DEPENDENCIES = ['dyson'] import voluptuous as vol
from homeassistant.components.dyson import DYSON_DEVICES
from homeassistant.components.fan import (
DOMAIN, SUPPORT_OSCILLATE, SUPPORT_SET_SPEED, FanEntity)
from homeassistant.const import CONF_ENTITY_ID
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import ToggleEntity
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONF_NIGHT_MODE = 'night_mode'
DEPENDENCIES = ['dyson']
DYSON_FAN_DEVICES = 'dyson_fan_devices'
DYSON_FAN_DEVICES = "dyson_fan_devices"
SERVICE_SET_NIGHT_MODE = 'dyson_set_night_mode' SERVICE_SET_NIGHT_MODE = 'dyson_set_night_mode'
DYSON_SET_NIGHT_MODE_SCHEMA = vol.Schema({ DYSON_SET_NIGHT_MODE_SCHEMA = vol.Schema({
vol.Required('entity_id'): cv.entity_id, vol.Required(CONF_ENTITY_ID): cv.entity_id,
vol.Required('night_mode'): cv.boolean vol.Required(CONF_NIGHT_MODE): cv.boolean,
}) })
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Dyson fan components.""" """Set up the Dyson fan components."""
_LOGGER.info("Creating new Dyson fans") from libpurecoollink.dyson_pure_cool_link import DysonPureCoolLink
_LOGGER.debug("Creating new Dyson fans")
if DYSON_FAN_DEVICES not in hass.data: if DYSON_FAN_DEVICES not in hass.data:
hass.data[DYSON_FAN_DEVICES] = [] hass.data[DYSON_FAN_DEVICES] = []
# Get Dyson Devices from parent component # Get Dyson Devices from parent component
from libpurecoollink.dyson_pure_cool_link import DysonPureCoolLink
for device in [d for d in hass.data[DYSON_DEVICES] if for device in [d for d in hass.data[DYSON_DEVICES] if
isinstance(d, DysonPureCoolLink)]: isinstance(d, DysonPureCoolLink)]:
dyson_entity = DysonPureCoolLinkDevice(hass, device) dyson_entity = DysonPureCoolLinkDevice(hass, device)
@ -43,9 +47,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices(hass.data[DYSON_FAN_DEVICES]) add_devices(hass.data[DYSON_FAN_DEVICES])
def service_handle(service): def service_handle(service):
"""Handle dyson services.""" """Handle the Dyson services."""
entity_id = service.data.get('entity_id') entity_id = service.data.get(CONF_ENTITY_ID)
night_mode = service.data.get('night_mode') night_mode = service.data.get(CONF_NIGHT_MODE)
fan_device = next([fan for fan in hass.data[DYSON_FAN_DEVICES] if fan_device = next([fan for fan in hass.data[DYSON_FAN_DEVICES] if
fan.entity_id == entity_id].__iter__(), None) fan.entity_id == entity_id].__iter__(), None)
if fan_device is None: if fan_device is None:
@ -57,9 +61,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
fan_device.night_mode(night_mode) fan_device.night_mode(night_mode)
# Register dyson service(s) # Register dyson service(s)
hass.services.register(DOMAIN, SERVICE_SET_NIGHT_MODE, hass.services.register(
service_handle, DOMAIN, SERVICE_SET_NIGHT_MODE, service_handle,
schema=DYSON_SET_NIGHT_MODE_SCHEMA) schema=DYSON_SET_NIGHT_MODE_SCHEMA)
class DysonPureCoolLinkDevice(FanEntity): class DysonPureCoolLinkDevice(FanEntity):
@ -67,21 +71,22 @@ class DysonPureCoolLinkDevice(FanEntity):
def __init__(self, hass, device): def __init__(self, hass, device):
"""Initialize the fan.""" """Initialize the fan."""
_LOGGER.info("Creating device %s", device.name) _LOGGER.debug("Creating device %s", device.name)
self.hass = hass self.hass = hass
self._device = device self._device = device
@asyncio.coroutine @asyncio.coroutine
def async_added_to_hass(self): def async_added_to_hass(self):
"""Callback when entity is added to hass.""" """Call when entity is added to hass."""
self.hass.async_add_job( self.hass.async_add_job(
self._device.add_message_listener, self.on_message) self._device.add_message_listener, self.on_message)
def on_message(self, message): def on_message(self, message):
"""Called when new messages received from the fan.""" """Call when new messages received from the fan."""
from libpurecoollink.dyson_pure_state import DysonPureCoolState from libpurecoollink.dyson_pure_state import DysonPureCoolState
if isinstance(message, DysonPureCoolState): if isinstance(message, DysonPureCoolState):
_LOGGER.debug("Message received for fan device %s : %s", self.name, _LOGGER.debug("Message received for fan device %s: %s", self.name,
message) message)
self.schedule_update_ha_state() self.schedule_update_ha_state()
@ -97,41 +102,46 @@ class DysonPureCoolLinkDevice(FanEntity):
def set_speed(self: ToggleEntity, speed: str) -> None: def set_speed(self: ToggleEntity, speed: str) -> None:
"""Set the speed of the fan. Never called ??.""" """Set the speed of the fan. Never called ??."""
_LOGGER.debug("Set fan speed to: " + speed)
from libpurecoollink.const import FanSpeed, FanMode from libpurecoollink.const import FanSpeed, FanMode
_LOGGER.debug("Set fan speed to: %s", speed)
if speed == FanSpeed.FAN_SPEED_AUTO.value: if speed == FanSpeed.FAN_SPEED_AUTO.value:
self._device.set_configuration(fan_mode=FanMode.AUTO) self._device.set_configuration(fan_mode=FanMode.AUTO)
else: else:
fan_speed = FanSpeed('{0:04d}'.format(int(speed))) fan_speed = FanSpeed('{0:04d}'.format(int(speed)))
self._device.set_configuration(fan_mode=FanMode.FAN, self._device.set_configuration(
fan_speed=fan_speed) fan_mode=FanMode.FAN, fan_speed=fan_speed)
def turn_on(self: ToggleEntity, speed: str=None, **kwargs) -> None: def turn_on(self: ToggleEntity, speed: str=None, **kwargs) -> None:
"""Turn on the fan.""" """Turn on the fan."""
_LOGGER.debug("Turn on fan %s with speed %s", self.name, speed)
from libpurecoollink.const import FanSpeed, FanMode from libpurecoollink.const import FanSpeed, FanMode
_LOGGER.debug("Turn on fan %s with speed %s", self.name, speed)
if speed: if speed:
if speed == FanSpeed.FAN_SPEED_AUTO.value: if speed == FanSpeed.FAN_SPEED_AUTO.value:
self._device.set_configuration(fan_mode=FanMode.AUTO) self._device.set_configuration(fan_mode=FanMode.AUTO)
else: else:
fan_speed = FanSpeed('{0:04d}'.format(int(speed))) fan_speed = FanSpeed('{0:04d}'.format(int(speed)))
self._device.set_configuration(fan_mode=FanMode.FAN, self._device.set_configuration(
fan_speed=fan_speed) fan_mode=FanMode.FAN, fan_speed=fan_speed)
else: else:
# Speed not set, just turn on # Speed not set, just turn on
self._device.set_configuration(fan_mode=FanMode.FAN) self._device.set_configuration(fan_mode=FanMode.FAN)
def turn_off(self: ToggleEntity, **kwargs) -> None: def turn_off(self: ToggleEntity, **kwargs) -> None:
"""Turn off the fan.""" """Turn off the fan."""
_LOGGER.debug("Turn off fan %s", self.name)
from libpurecoollink.const import FanMode from libpurecoollink.const import FanMode
_LOGGER.debug("Turn off fan %s", self.name)
self._device.set_configuration(fan_mode=FanMode.OFF) self._device.set_configuration(fan_mode=FanMode.OFF)
def oscillate(self: ToggleEntity, oscillating: bool) -> None: def oscillate(self: ToggleEntity, oscillating: bool) -> None:
"""Turn on/off oscillating.""" """Turn on/off oscillating."""
from libpurecoollink.const import Oscillation
_LOGGER.debug("Turn oscillation %s for device %s", oscillating, _LOGGER.debug("Turn oscillation %s for device %s", oscillating,
self.name) self.name)
from libpurecoollink.const import Oscillation
if oscillating: if oscillating:
self._device.set_configuration( self._device.set_configuration(
@ -155,8 +165,9 @@ class DysonPureCoolLinkDevice(FanEntity):
@property @property
def speed(self) -> str: def speed(self) -> str:
"""Return the current speed.""" """Return the current speed."""
from libpurecoollink.const import FanSpeed
if self._device.state: if self._device.state:
from libpurecoollink.const import FanSpeed
if self._device.state.speed == FanSpeed.FAN_SPEED_AUTO.value: if self._device.state.speed == FanSpeed.FAN_SPEED_AUTO.value:
return self._device.state.speed return self._device.state.speed
return int(self._device.state.speed) return int(self._device.state.speed)
@ -174,8 +185,9 @@ class DysonPureCoolLinkDevice(FanEntity):
def night_mode(self: ToggleEntity, night_mode: bool) -> None: def night_mode(self: ToggleEntity, night_mode: bool) -> None:
"""Turn fan in night mode.""" """Turn fan in night mode."""
_LOGGER.debug("Set %s night mode %s", self.name, night_mode)
from libpurecoollink.const import NightMode from libpurecoollink.const import NightMode
_LOGGER.debug("Set %s night mode %s", self.name, night_mode)
if night_mode: if night_mode:
self._device.set_configuration(night_mode=NightMode.NIGHT_MODE_ON) self._device.set_configuration(night_mode=NightMode.NIGHT_MODE_ON)
else: else:
@ -188,8 +200,9 @@ class DysonPureCoolLinkDevice(FanEntity):
def auto_mode(self: ToggleEntity, auto_mode: bool) -> None: def auto_mode(self: ToggleEntity, auto_mode: bool) -> None:
"""Turn fan in auto mode.""" """Turn fan in auto mode."""
_LOGGER.debug("Set %s auto mode %s", self.name, auto_mode)
from libpurecoollink.const import FanMode from libpurecoollink.const import FanMode
_LOGGER.debug("Set %s auto mode %s", self.name, auto_mode)
if auto_mode: if auto_mode:
self._device.set_configuration(fan_mode=FanMode.AUTO) self._device.set_configuration(fan_mode=FanMode.AUTO)
else: else:
@ -199,17 +212,20 @@ class DysonPureCoolLinkDevice(FanEntity):
def speed_list(self: ToggleEntity) -> list: def speed_list(self: ToggleEntity) -> list:
"""Get the list of available speeds.""" """Get the list of available speeds."""
from libpurecoollink.const import FanSpeed from libpurecoollink.const import FanSpeed
supported_speeds = [FanSpeed.FAN_SPEED_AUTO.value,
int(FanSpeed.FAN_SPEED_1.value), supported_speeds = [
int(FanSpeed.FAN_SPEED_2.value), FanSpeed.FAN_SPEED_AUTO.value,
int(FanSpeed.FAN_SPEED_3.value), int(FanSpeed.FAN_SPEED_1.value),
int(FanSpeed.FAN_SPEED_4.value), int(FanSpeed.FAN_SPEED_2.value),
int(FanSpeed.FAN_SPEED_5.value), int(FanSpeed.FAN_SPEED_3.value),
int(FanSpeed.FAN_SPEED_6.value), int(FanSpeed.FAN_SPEED_4.value),
int(FanSpeed.FAN_SPEED_7.value), int(FanSpeed.FAN_SPEED_5.value),
int(FanSpeed.FAN_SPEED_8.value), int(FanSpeed.FAN_SPEED_6.value),
int(FanSpeed.FAN_SPEED_9.value), int(FanSpeed.FAN_SPEED_7.value),
int(FanSpeed.FAN_SPEED_10.value)] int(FanSpeed.FAN_SPEED_8.value),
int(FanSpeed.FAN_SPEED_9.value),
int(FanSpeed.FAN_SPEED_10.value),
]
return supported_speeds return supported_speeds

View file

@ -7,20 +7,18 @@ https://home-assistant.io/components/fan.wink/
import asyncio import asyncio
import logging import logging
from homeassistant.components.fan import (FanEntity, SPEED_HIGH, from homeassistant.components.fan import (
SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH, SPEED_LOW, SPEED_MEDIUM, STATE_UNKNOWN, SUPPORT_DIRECTION,
STATE_UNKNOWN, SUPPORT_SET_SPEED, SUPPORT_SET_SPEED, FanEntity)
SUPPORT_DIRECTION) from homeassistant.components.wink import DOMAIN, WinkDevice
from homeassistant.helpers.entity import ToggleEntity from homeassistant.helpers.entity import ToggleEntity
from homeassistant.components.wink import WinkDevice, DOMAIN
DEPENDENCIES = ['wink']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
SPEED_LOWEST = 'lowest' DEPENDENCIES = ['wink']
SPEED_AUTO = 'auto'
SPEED_AUTO = 'auto'
SPEED_LOWEST = 'lowest'
SUPPORTED_FEATURES = SUPPORT_DIRECTION + SUPPORT_SET_SPEED SUPPORTED_FEATURES = SUPPORT_DIRECTION + SUPPORT_SET_SPEED
@ -38,7 +36,7 @@ class WinkFanDevice(WinkDevice, FanEntity):
@asyncio.coroutine @asyncio.coroutine
def async_added_to_hass(self): def async_added_to_hass(self):
"""Callback when entity is added to hass.""" """Call when entity is added to hass."""
self.hass.data[DOMAIN]['entities']['fan'].append(self) self.hass.data[DOMAIN]['entities']['fan'].append(self)
def set_direction(self: ToggleEntity, direction: str) -> None: def set_direction(self: ToggleEntity, direction: str) -> None:

View file

@ -260,10 +260,10 @@ def async_register_panel(hass, component_name, path, md5=None,
component_name: name of the web component component_name: name of the web component
path: path to the HTML of the web component path: path to the HTML of the web component
(required unless url is provided) (required unless url is provided)
md5: the md5 hash of the web component (for versioning in url, optional) md5: the md5 hash of the web component (for versioning in URL, optional)
sidebar_title: title to show in the sidebar (optional) sidebar_title: title to show in the sidebar (optional)
sidebar_icon: icon to show next to title in sidebar (optional) sidebar_icon: icon to show next to title in sidebar (optional)
url_path: name to use in the url (defaults to component_name) url_path: name to use in the URL (defaults to component_name)
config: config to be passed into the web component config: config to be passed into the web component
""" """
panel = ExternalPanel(component_name, path, md5, sidebar_title, panel = ExternalPanel(component_name, path, md5, sidebar_title,

View file

@ -12,21 +12,22 @@ import re
import aiohttp import aiohttp
from aiohttp import web from aiohttp import web
from aiohttp.web_exceptions import HTTPBadGateway
from aiohttp.hdrs import CONTENT_TYPE from aiohttp.hdrs import CONTENT_TYPE
from aiohttp.web_exceptions import HTTPBadGateway
import async_timeout import async_timeout
import voluptuous as vol import voluptuous as vol
from homeassistant.core import callback, DOMAIN as HASS_DOMAIN
from homeassistant.const import (
CONTENT_TYPE_TEXT_PLAIN, SERVER_PORT, CONF_TIME_ZONE,
SERVICE_HOMEASSISTANT_STOP, SERVICE_HOMEASSISTANT_RESTART)
from homeassistant.components import SERVICE_CHECK_CONFIG from homeassistant.components import SERVICE_CHECK_CONFIG
from homeassistant.components.http import ( from homeassistant.components.http import (
HomeAssistantView, KEY_AUTHENTICATED, CONF_API_PASSWORD, CONF_SERVER_PORT, CONF_API_PASSWORD, CONF_SERVER_HOST, CONF_SERVER_PORT,
CONF_SERVER_HOST, CONF_SSL_CERTIFICATE) CONF_SSL_CERTIFICATE, KEY_AUTHENTICATED, HomeAssistantView)
from homeassistant.loader import bind_hass from homeassistant.const import (
CONF_TIME_ZONE, CONTENT_TYPE_TEXT_PLAIN, SERVER_PORT,
SERVICE_HOMEASSISTANT_RESTART, SERVICE_HOMEASSISTANT_STOP)
from homeassistant.core import DOMAIN as HASS_DOMAIN
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.loader import bind_hass
from homeassistant.util.dt import utcnow from homeassistant.util.dt import utcnow
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -126,7 +127,7 @@ MAP_SERVICE_API = {
@callback @callback
@bind_hass @bind_hass
def get_homeassistant_version(hass): def get_homeassistant_version(hass):
"""Return latest available HomeAssistant version. """Return latest available Home Assistant version.
Async friendly. Async friendly.
""" """
@ -136,7 +137,7 @@ def get_homeassistant_version(hass):
@callback @callback
@bind_hass @bind_hass
def is_hassio(hass): def is_hassio(hass):
"""Return True if hass.io is loaded. """Return true if hass.io is loaded.
Async friendly. Async friendly.
""" """
@ -146,7 +147,7 @@ def is_hassio(hass):
@bind_hass @bind_hass
@asyncio.coroutine @asyncio.coroutine
def async_check_config(hass): def async_check_config(hass):
"""Check config over Hass.io API.""" """Check configuration over Hass.io API."""
result = yield from hass.data[DOMAIN].send_command( result = yield from hass.data[DOMAIN].send_command(
'/homeassistant/check', timeout=300) '/homeassistant/check', timeout=300)
@ -159,18 +160,18 @@ def async_check_config(hass):
@asyncio.coroutine @asyncio.coroutine
def async_setup(hass, config): def async_setup(hass, config):
"""Set up the HASSio component.""" """Set up the Hass.io component."""
try: try:
host = os.environ['HASSIO'] host = os.environ['HASSIO']
except KeyError: except KeyError:
_LOGGER.error("No HassIO supervisor detect!") _LOGGER.error("No Hass.io supervisor detect")
return False return False
websession = hass.helpers.aiohttp_client.async_get_clientsession() websession = hass.helpers.aiohttp_client.async_get_clientsession()
hass.data[DOMAIN] = hassio = HassIO(hass.loop, websession, host) hass.data[DOMAIN] = hassio = HassIO(hass.loop, websession, host)
if not (yield from hassio.is_connected()): if not (yield from hassio.is_connected()):
_LOGGER.error("Not connected with HassIO!") _LOGGER.error("Not connected with Hass.io")
return False return False
hass.http.register_view(HassIOView(hassio)) hass.http.register_view(HassIOView(hassio))
@ -187,7 +188,7 @@ def async_setup(hass, config):
@asyncio.coroutine @asyncio.coroutine
def async_service_handler(service): def async_service_handler(service):
"""Handle service calls for HassIO.""" """Handle service calls for Hass.io."""
api_command = MAP_SERVICE_API[service.service][0] api_command = MAP_SERVICE_API[service.service][0]
data = service.data.copy() data = service.data.copy()
addon = data.pop(ATTR_ADDON, None) addon = data.pop(ATTR_ADDON, None)
@ -215,7 +216,7 @@ def async_setup(hass, config):
@asyncio.coroutine @asyncio.coroutine
def update_homeassistant_version(now): def update_homeassistant_version(now):
"""Update last available HomeAssistant version.""" """Update last available Home Assistant version."""
data = yield from hassio.get_homeassistant_info() data = yield from hassio.get_homeassistant_info()
if data: if data:
hass.data[DATA_HOMEASSISTANT_VERSION] = \ hass.data[DATA_HOMEASSISTANT_VERSION] = \
@ -255,10 +256,10 @@ def async_setup(hass, config):
def _api_bool(funct): def _api_bool(funct):
"""API wrapper to return Boolean.""" """Return a boolean."""
@asyncio.coroutine @asyncio.coroutine
def _wrapper(*argv, **kwargs): def _wrapper(*argv, **kwargs):
"""Wrapper function.""" """Wrap function."""
data = yield from funct(*argv, **kwargs) data = yield from funct(*argv, **kwargs)
return data and data['result'] == "ok" return data and data['result'] == "ok"
@ -266,24 +267,24 @@ def _api_bool(funct):
class HassIO(object): class HassIO(object):
"""Small API wrapper for HassIO.""" """Small API wrapper for Hass.io."""
def __init__(self, loop, websession, ip): def __init__(self, loop, websession, ip):
"""Initialze HassIO api.""" """Initialize Hass.io API."""
self.loop = loop self.loop = loop
self.websession = websession self.websession = websession
self._ip = ip self._ip = ip
@_api_bool @_api_bool
def is_connected(self): def is_connected(self):
"""Return True if it connected to HassIO supervisor. """Return true if it connected to Hass.io supervisor.
This method return a coroutine. This method return a coroutine.
""" """
return self.send_command("/supervisor/ping", method="get") return self.send_command("/supervisor/ping", method="get")
def get_homeassistant_info(self): def get_homeassistant_info(self):
"""Return data for HomeAssistant. """Return data for Home Assistant.
This method return a coroutine. This method return a coroutine.
""" """
@ -291,7 +292,7 @@ class HassIO(object):
@_api_bool @_api_bool
def update_hass_api(self, http_config): def update_hass_api(self, http_config):
"""Update Home-Assistant API data on HassIO. """Update Home Assistant API data on Hass.io.
This method return a coroutine. This method return a coroutine.
""" """
@ -305,13 +306,13 @@ class HassIO(object):
if CONF_SERVER_HOST in http_config: if CONF_SERVER_HOST in http_config:
options['watchdog'] = False options['watchdog'] = False
_LOGGER.warning("Don't use 'server_host' options with Hass.io!") _LOGGER.warning("Don't use 'server_host' options with Hass.io")
return self.send_command("/homeassistant/options", payload=options) return self.send_command("/homeassistant/options", payload=options)
@_api_bool @_api_bool
def update_hass_timezone(self, core_config): def update_hass_timezone(self, core_config):
"""Update Home-Assistant timezone data on HassIO. """Update Home-Assistant timezone data on Hass.io.
This method return a coroutine. This method return a coroutine.
""" """
@ -321,7 +322,7 @@ class HassIO(object):
@asyncio.coroutine @asyncio.coroutine
def send_command(self, command, method="post", payload=None, timeout=10): def send_command(self, command, method="post", payload=None, timeout=10):
"""Send API command to HassIO. """Send API command to Hass.io.
This method is a coroutine. This method is a coroutine.
""" """
@ -351,7 +352,7 @@ class HassIO(object):
@asyncio.coroutine @asyncio.coroutine
def command_proxy(self, path, request): def command_proxy(self, path, request):
"""Return a client request with proxy origin for HassIO supervisor. """Return a client request with proxy origin for Hass.io supervisor.
This method is a coroutine. This method is a coroutine.
""" """
@ -376,28 +377,28 @@ class HassIO(object):
return client return client
except aiohttp.ClientError as err: except aiohttp.ClientError as err:
_LOGGER.error("Client error on api %s request %s.", path, err) _LOGGER.error("Client error on api %s request %s", path, err)
except asyncio.TimeoutError: except asyncio.TimeoutError:
_LOGGER.error("Client timeout error on api request %s.", path) _LOGGER.error("Client timeout error on API request %s", path)
raise HTTPBadGateway() raise HTTPBadGateway()
class HassIOView(HomeAssistantView): class HassIOView(HomeAssistantView):
"""HassIO view to handle base part.""" """Hass.io view to handle base part."""
name = "api:hassio" name = "api:hassio"
url = "/api/hassio/{path:.+}" url = "/api/hassio/{path:.+}"
requires_auth = False requires_auth = False
def __init__(self, hassio): def __init__(self, hassio):
"""Initialize a hassio base view.""" """Initialize a Hass.io base view."""
self.hassio = hassio self.hassio = hassio
@asyncio.coroutine @asyncio.coroutine
def _handle(self, request, path): def _handle(self, request, path):
"""Route data to hassio.""" """Route data to Hass.io."""
if _need_auth(path) and not request[KEY_AUTHENTICATED]: if _need_auth(path) and not request[KEY_AUTHENTICATED]:
return web.Response(status=401) return web.Response(status=401)
@ -434,7 +435,7 @@ def _create_response_log(client, data):
def _get_timeout(path): def _get_timeout(path):
"""Return timeout for a url path.""" """Return timeout for a URL path."""
for re_path in NO_TIMEOUT: for re_path in NO_TIMEOUT:
if re_path.match(path): if re_path.match(path):
return 0 return 0
@ -442,7 +443,7 @@ def _get_timeout(path):
def _need_auth(path): def _need_auth(path):
"""Return if a path need a auth.""" """Return if a path need authentication."""
for re_path in NO_AUTH: for re_path in NO_AUTH:
if re_path.match(path): if re_path.match(path):
return False return False

View file

@ -5,7 +5,7 @@ For more details about this component, please refer to the documentation at
https://home-assistant.io/components/influxdb/ https://home-assistant.io/components/influxdb/
""" """
from datetime import timedelta from datetime import timedelta
from functools import wraps, partial from functools import partial, wraps
import logging import logging
import re import re
@ -13,13 +13,13 @@ import requests.exceptions
import voluptuous as vol import voluptuous as vol
from homeassistant.const import ( from homeassistant.const import (
EVENT_STATE_CHANGED, STATE_UNAVAILABLE, STATE_UNKNOWN, CONF_HOST, CONF_DOMAINS, CONF_ENTITIES, CONF_EXCLUDE, CONF_HOST, CONF_INCLUDE,
CONF_PORT, CONF_SSL, CONF_VERIFY_SSL, CONF_USERNAME, CONF_PASSWORD, CONF_PASSWORD, CONF_PORT, CONF_SSL, CONF_USERNAME, CONF_VERIFY_SSL,
CONF_EXCLUDE, CONF_INCLUDE, CONF_DOMAINS, CONF_ENTITIES) EVENT_STATE_CHANGED, STATE_UNAVAILABLE, STATE_UNKNOWN)
from homeassistant.helpers import state as state_helper from homeassistant.helpers import state as state_helper
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_values import EntityValues from homeassistant.helpers.entity_values import EntityValues
from homeassistant.util import utcnow from homeassistant.util import utcnow
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['influxdb==4.1.1'] REQUIREMENTS = ['influxdb==4.1.1']
@ -227,6 +227,7 @@ def setup(hass, config):
@RetryOnError(hass, retry_limit=max_tries, retry_delay=20, @RetryOnError(hass, retry_limit=max_tries, retry_delay=20,
queue_limit=queue_limit) queue_limit=queue_limit)
def _write_data(json_body): def _write_data(json_body):
"""Write the data."""
try: try:
influx.write_points(json_body) influx.write_points(json_body)
except exceptions.InfluxDBClientError: except exceptions.InfluxDBClientError:
@ -268,7 +269,7 @@ class RetryOnError(object):
@wraps(method) @wraps(method)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
"""Wrapped method.""" """Wrap method."""
# pylint: disable=protected-access # pylint: disable=protected-access
if not hasattr(wrapper, "_retry_queue"): if not hasattr(wrapper, "_retry_queue"):
wrapper._retry_queue = [] wrapper._retry_queue = []

View file

@ -11,7 +11,7 @@ import requests
import voluptuous as vol import voluptuous as vol
from homeassistant.const import ( from homeassistant.const import (
CONF_PASSWORD, CONF_USERNAME, CONF_HOST, CONF_PORT, CONF_TIMEOUT) CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_TIMEOUT, CONF_USERNAME)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.discovery import load_platform from homeassistant.helpers.discovery import load_platform
@ -37,14 +37,15 @@ CONFIG_SCHEMA = vol.Schema({
vol.Required(CONF_PASSWORD): cv.string, vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_USERNAME): cv.string, vol.Required(CONF_USERNAME): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
}) })
}, extra=vol.ALLOW_EXTRA) }, extra=vol.ALLOW_EXTRA)
def setup(hass, config): def setup(hass, config):
"""Setup insteon hub.""" """Set up the local Insteon hub."""
from insteonlocal.Hub import Hub from insteonlocal.Hub import Hub
conf = config[DOMAIN] conf = config[DOMAIN]
username = conf.get(CONF_USERNAME) username = conf.get(CONF_USERNAME)
password = conf.get(CONF_PASSWORD) password = conf.get(CONF_PASSWORD)
@ -62,20 +63,16 @@ def setup(hass, config):
# Check for successful connection # Check for successful connection
insteonhub.get_buffer_status() insteonhub.get_buffer_status()
except requests.exceptions.ConnectTimeout: except requests.exceptions.ConnectTimeout:
_LOGGER.error( _LOGGER.error("Could not connect", exc_info=True)
"Could not connect. Check config",
exc_info=True)
return False return False
except requests.exceptions.ConnectionError: except requests.exceptions.ConnectionError:
_LOGGER.error( _LOGGER.error("Could not connect", exc_info=True)
"Could not connect. Check config",
exc_info=True)
return False return False
except requests.exceptions.RequestException: except requests.exceptions.RequestException:
if insteonhub.http_code == 401: if insteonhub.http_code == 401:
_LOGGER.error("Bad user/pass for insteon_local hub") _LOGGER.error("Bad username or password for Insteon_local hub")
else: else:
_LOGGER.error("Error on insteon_local hub check", exc_info=True) _LOGGER.error("Error on Insteon_local hub check", exc_info=True)
return False return False
linked = insteonhub.get_linked() linked = insteonhub.get_linked()

View file

@ -1,26 +1,23 @@
"""KIRA interface to receive UDP packets from an IR-IP bridge.""" """
# pylint: disable=import-error KIRA interface to receive UDP packets from an IR-IP bridge.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/kira/
"""
import logging import logging
import os import os
import yaml
import voluptuous as vol import voluptuous as vol
from voluptuous.error import Error as VoluptuousError from voluptuous.error import Error as VoluptuousError
import yaml
from homeassistant.const import (
CONF_DEVICE, CONF_HOST, CONF_NAME, CONF_PORT, CONF_SENSORS, CONF_TYPE,
EVENT_HOMEASSISTANT_STOP, STATE_UNKNOWN)
from homeassistant.helpers import discovery from homeassistant.helpers import discovery
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.const import ( REQUIREMENTS = ['pykira==0.1.1']
CONF_DEVICE,
CONF_HOST,
CONF_NAME,
CONF_PORT,
CONF_SENSORS,
CONF_TYPE,
EVENT_HOMEASSISTANT_STOP,
STATE_UNKNOWN)
REQUIREMENTS = ["pykira==0.1.1"]
DOMAIN = 'kira' DOMAIN = 'kira'
@ -67,7 +64,7 @@ CONFIG_SCHEMA = vol.Schema({
def load_codes(path): def load_codes(path):
"""Load Kira codes from specified file.""" """Load KIRA codes from specified file."""
codes = [] codes = []
if os.path.exists(path): if os.path.exists(path):
with open(path) as code_file: with open(path) as code_file:
@ -77,7 +74,7 @@ def load_codes(path):
codes.append(CODE_SCHEMA(code)) codes.append(CODE_SCHEMA(code))
except VoluptuousError as exception: except VoluptuousError as exception:
# keep going # keep going
_LOGGER.warning('Kira Code Invalid Data: %s', exception) _LOGGER.warning("KIRA code invalid data: %s", exception)
else: else:
with open(path, 'w') as code_file: with open(path, 'w') as code_file:
code_file.write('') code_file.write('')
@ -85,7 +82,7 @@ def load_codes(path):
def setup(hass, config): def setup(hass, config):
"""Setup KIRA capability.""" """Set up the KIRA component."""
import pykira import pykira
sensors = config.get(DOMAIN, {}).get(CONF_SENSORS, []) sensors = config.get(DOMAIN, {}).get(CONF_SENSORS, [])
@ -99,10 +96,10 @@ def setup(hass, config):
hass.data[DOMAIN] = { hass.data[DOMAIN] = {
CONF_SENSOR: {}, CONF_SENSOR: {},
CONF_REMOTE: {}, CONF_REMOTE: {},
} }
def load_module(platform, idx, module_conf): def load_module(platform, idx, module_conf):
"""Set up Kira module and load platform.""" """Set up the KIRA module and load platform."""
# note: module_name is not the HA device name. it's just a unique name # note: module_name is not the HA device name. it's just a unique name
# to ensure the component and platform can share information # to ensure the component and platform can share information
module_name = ("%s_%d" % (DOMAIN, idx)) if idx else DOMAIN module_name = ("%s_%d" % (DOMAIN, idx)) if idx else DOMAIN
@ -133,6 +130,7 @@ def setup(hass, config):
load_module(CONF_REMOTE, idx, module_conf) load_module(CONF_REMOTE, idx, module_conf)
def _stop_kira(_event): def _stop_kira(_event):
"""Stop the KIRA receiver."""
for receiver in hass.data[DOMAIN][CONF_SENSOR].values(): for receiver in hass.data[DOMAIN][CONF_SENSOR].values():
receiver.stop() receiver.stop()
_LOGGER.info("Terminated receivers") _LOGGER.info("Terminated receivers")

View file

@ -1,22 +1,21 @@
""" """
Connects to KNX platform. Connects to KNX platform.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/knx/ https://home-assistant.io/components/knx/
""" """
import logging
import asyncio import asyncio
import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.const import CONF_HOST, CONF_PORT, EVENT_HOMEASSISTANT_STOP
from homeassistant.helpers import discovery from homeassistant.helpers import discovery
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.const import EVENT_HOMEASSISTANT_STOP, \
CONF_HOST, CONF_PORT
from homeassistant.helpers.script import Script from homeassistant.helpers.script import Script
REQUIREMENTS = ['xknx==0.7.18']
DOMAIN = "knx" DOMAIN = "knx"
DATA_KNX = "data_knx" DATA_KNX = "data_knx"
CONF_KNX_CONFIG = "config_file" CONF_KNX_CONFIG = "config_file"
@ -36,12 +35,10 @@ ATTR_DISCOVER_DEVICES = 'devices'
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
REQUIREMENTS = ['xknx==0.7.18']
TUNNELING_SCHEMA = vol.Schema({ TUNNELING_SCHEMA = vol.Schema({
vol.Required(CONF_HOST): cv.string, vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_PORT): cv.port,
vol.Required(CONF_KNX_LOCAL_IP): cv.string, vol.Required(CONF_KNX_LOCAL_IP): cv.string,
vol.Optional(CONF_PORT): cv.port,
}) })
ROUTING_SCHEMA = vol.Schema({ ROUTING_SCHEMA = vol.Schema({
@ -57,9 +54,7 @@ CONFIG_SCHEMA = vol.Schema({
vol.Inclusive(CONF_KNX_FIRE_EVENT, 'fire_ev'): vol.Inclusive(CONF_KNX_FIRE_EVENT, 'fire_ev'):
cv.boolean, cv.boolean,
vol.Inclusive(CONF_KNX_FIRE_EVENT_FILTER, 'fire_ev'): vol.Inclusive(CONF_KNX_FIRE_EVENT_FILTER, 'fire_ev'):
vol.All( vol.All(cv.ensure_list, [cv.string]),
cv.ensure_list,
[cv.string]),
vol.Optional(CONF_KNX_STATE_UPDATER, default=True): cv.boolean, vol.Optional(CONF_KNX_STATE_UPDATER, default=True): cv.boolean,
}) })
}, extra=vol.ALLOW_EXTRA) }, extra=vol.ALLOW_EXTRA)
@ -73,7 +68,7 @@ SERVICE_KNX_SEND_SCHEMA = vol.Schema({
@asyncio.coroutine @asyncio.coroutine
def async_setup(hass, config): def async_setup(hass, config):
"""Set up knx component.""" """Set up the KNX component."""
from xknx.exceptions import XKNXException from xknx.exceptions import XKNXException
try: try:
hass.data[DATA_KNX] = KNXModule(hass, config) hass.data[DATA_KNX] = KNXModule(hass, config)
@ -109,6 +104,7 @@ def async_setup(hass, config):
def _get_devices(hass, discovery_type): def _get_devices(hass, discovery_type):
"""Get the KNX devices."""
return list( return list(
map(lambda device: device.name, map(lambda device: device.name,
filter( filter(
@ -120,7 +116,7 @@ class KNXModule(object):
"""Representation of KNX Object.""" """Representation of KNX Object."""
def __init__(self, hass, config): def __init__(self, hass, config):
"""Initialization of KNXModule.""" """Initialize of KNX module."""
self.hass = hass self.hass = hass
self.config = config self.config = config
self.connected = False self.connected = False
@ -129,11 +125,9 @@ class KNXModule(object):
self.register_callbacks() self.register_callbacks()
def init_xknx(self): def init_xknx(self):
"""Initialization of KNX object.""" """Initialize of KNX object."""
from xknx import XKNX from xknx import XKNX
self.xknx = XKNX( self.xknx = XKNX(config=self.config_file(), loop=self.hass.loop)
config=self.config_file(),
loop=self.hass.loop)
@asyncio.coroutine @asyncio.coroutine
def start(self): def start(self):
@ -189,10 +183,8 @@ class KNXModule(object):
if gateway_port is None: if gateway_port is None:
gateway_port = DEFAULT_MCAST_PORT gateway_port = DEFAULT_MCAST_PORT
return ConnectionConfig( return ConnectionConfig(
connection_type=ConnectionType.TUNNELING, connection_type=ConnectionType.TUNNELING, gateway_ip=gateway_ip,
gateway_ip=gateway_ip, gateway_port=gateway_port, local_ip=local_ip)
gateway_port=gateway_port,
local_ip=local_ip)
def connection_config_auto(self): def connection_config_auto(self):
"""Return the connection_config if auto is configured.""" """Return the connection_config if auto is configured."""
@ -213,7 +205,7 @@ class KNXModule(object):
@asyncio.coroutine @asyncio.coroutine
def telegram_received_cb(self, telegram): def telegram_received_cb(self, telegram):
"""Callback invoked after a KNX telegram was received.""" """Call invoked after a KNX telegram was received."""
self.hass.bus.fire('knx_event', { self.hass.bus.fire('knx_event', {
'address': telegram.group_address.str(), 'address': telegram.group_address.str(),
'data': telegram.payload.value 'data': telegram.payload.value
@ -254,8 +246,6 @@ class KNXAutomation():
import xknx import xknx
self.action = xknx.devices.ActionCallback( self.action = xknx.devices.ActionCallback(
hass.data[DATA_KNX].xknx, hass.data[DATA_KNX].xknx, self.script.async_run,
self.script.async_run, hook=hook, counter=counter)
hook=hook,
counter=counter)
device.actions.append(self.action) device.actions.append(self.action)

View file

@ -5,33 +5,33 @@ For more details about this component, please refer to the documentation at
https://home-assistant.io/components/light/ https://home-assistant.io/components/light/
""" """
import asyncio import asyncio
import csv
from datetime import timedelta from datetime import timedelta
import logging import logging
import os import os
import csv
import voluptuous as vol import voluptuous as vol
from homeassistant.core import callback
from homeassistant.loader import bind_hass
from homeassistant.components import group from homeassistant.components import group
from homeassistant.const import ( from homeassistant.const import (
STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE, ATTR_ENTITY_ID, SERVICE_TOGGLE, SERVICE_TURN_OFF, SERVICE_TURN_ON,
ATTR_ENTITY_ID) STATE_ON)
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
from homeassistant.helpers.entity import ToggleEntity from homeassistant.helpers.entity import ToggleEntity
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa from homeassistant.loader import bind_hass
import homeassistant.helpers.config_validation as cv
import homeassistant.util.color as color_util import homeassistant.util.color as color_util
DOMAIN = "light" DOMAIN = 'light'
DEPENDENCIES = ['group'] DEPENDENCIES = ['group']
SCAN_INTERVAL = timedelta(seconds=30) SCAN_INTERVAL = timedelta(seconds=30)
GROUP_NAME_ALL_LIGHTS = 'all lights' GROUP_NAME_ALL_LIGHTS = 'all lights'
ENTITY_ID_ALL_LIGHTS = group.ENTITY_ID_FORMAT.format('all_lights') ENTITY_ID_ALL_LIGHTS = group.ENTITY_ID_FORMAT.format('all_lights')
ENTITY_ID_FORMAT = DOMAIN + ".{}" ENTITY_ID_FORMAT = DOMAIN + '.{}'
# Bitfield of features supported by the light entity # Bitfield of features supported by the light entity
SUPPORT_BRIGHTNESS = 1 SUPPORT_BRIGHTNESS = 1
@ -220,7 +220,7 @@ def toggle(hass, entity_id=None, transition=None):
def preprocess_turn_on_alternatives(params): def preprocess_turn_on_alternatives(params):
"""Processing extra data for turn light on request.""" """Process extra data for turn light on request."""
profile = Profiles.get(params.pop(ATTR_PROFILE, None)) profile = Profiles.get(params.pop(ATTR_PROFILE, None))
if profile is not None: if profile is not None:
params.setdefault(ATTR_XY_COLOR, profile[:2]) params.setdefault(ATTR_XY_COLOR, profile[:2])
@ -242,7 +242,7 @@ def preprocess_turn_on_alternatives(params):
@asyncio.coroutine @asyncio.coroutine
def async_setup(hass, config): def async_setup(hass, config):
"""Expose light control via statemachine and services.""" """Expose light control via state machine and services."""
component = EntityComponent( component = EntityComponent(
_LOGGER, DOMAIN, hass, SCAN_INTERVAL, GROUP_NAME_ALL_LIGHTS) _LOGGER, DOMAIN, hass, SCAN_INTERVAL, GROUP_NAME_ALL_LIGHTS)
yield from component.async_setup(config) yield from component.async_setup(config)

View file

@ -9,28 +9,31 @@ import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, Light, PLATFORM_SCHEMA, SUPPORT_BRIGHTNESS) ATTR_BRIGHTNESS, PLATFORM_SCHEMA, SUPPORT_BRIGHTNESS, Light)
from homeassistant.const import CONF_HOST from homeassistant.const import CONF_HOST
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
SUPPORTED_FEATURES = (SUPPORT_BRIGHTNESS)
REQUIREMENTS = ['greenwavereality==0.2.9'] REQUIREMENTS = ['greenwavereality==0.2.9']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONF_VERSION = 'version'
SUPPORTED_FEATURES = (SUPPORT_BRIGHTNESS)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string, vol.Required(CONF_HOST): cv.string,
vol.Required("version"): cv.positive_int, vol.Required(CONF_VERSION): cv.positive_int,
}) })
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup Greenwave Reality Platform.""" """Set up the Greenwave Reality Platform."""
import greenwavereality as greenwave import greenwavereality as greenwave
import os import os
host = config.get(CONF_HOST) host = config.get(CONF_HOST)
tokenfile = hass.config.path('.greenwave') tokenfile = hass.config.path('.greenwave')
if config.get("version") == 3: if config.get(CONF_VERSION) == 3:
if os.path.exists(tokenfile): if os.path.exists(tokenfile):
tokenfile = open(tokenfile) tokenfile = open(tokenfile)
token = tokenfile.read() token = tokenfile.read()

View file

@ -14,13 +14,12 @@ import socket
import voluptuous as vol import voluptuous as vol
import homeassistant.components.hue as hue import homeassistant.components.hue as hue
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_EFFECT, ATTR_FLASH, ATTR_RGB_COLOR, ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_EFFECT, ATTR_FLASH, ATTR_RGB_COLOR,
ATTR_TRANSITION, ATTR_XY_COLOR, EFFECT_COLORLOOP, EFFECT_RANDOM, ATTR_TRANSITION, ATTR_XY_COLOR, EFFECT_COLORLOOP, EFFECT_RANDOM,
FLASH_LONG, FLASH_SHORT, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, FLASH_LONG, FLASH_SHORT, PLATFORM_SCHEMA, SUPPORT_BRIGHTNESS,
SUPPORT_EFFECT, SUPPORT_FLASH, SUPPORT_RGB_COLOR, SUPPORT_TRANSITION, SUPPORT_COLOR_TEMP, SUPPORT_EFFECT, SUPPORT_FLASH, SUPPORT_RGB_COLOR,
SUPPORT_XY_COLOR, Light, PLATFORM_SCHEMA) SUPPORT_TRANSITION, SUPPORT_XY_COLOR, Light)
from homeassistant.const import CONF_FILENAME, CONF_HOST, DEVICE_DEFAULT_NAME from homeassistant.const import CONF_FILENAME, CONF_HOST, DEVICE_DEFAULT_NAME
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
import homeassistant.util as util import homeassistant.util as util
@ -114,7 +113,7 @@ def update_lights(hass, bridge, add_devices):
def unthrottled_update_lights(hass, bridge, add_devices): def unthrottled_update_lights(hass, bridge, add_devices):
"""Internal version of update_lights.""" """Update the lights (Internal version of update_lights)."""
import phue import phue
if not bridge.configured: if not bridge.configured:
@ -123,14 +122,14 @@ def unthrottled_update_lights(hass, bridge, add_devices):
try: try:
api = bridge.get_api() api = bridge.get_api()
except phue.PhueRequestTimeout: except phue.PhueRequestTimeout:
_LOGGER.warning('Timeout trying to reach the bridge') _LOGGER.warning("Timeout trying to reach the bridge")
return return
except ConnectionRefusedError: except ConnectionRefusedError:
_LOGGER.error('The bridge refused the connection') _LOGGER.error("The bridge refused the connection")
return return
except socket.error: except socket.error:
# socket.error when we cannot reach Hue # socket.error when we cannot reach Hue
_LOGGER.exception('Cannot reach the bridge') _LOGGER.exception("Cannot reach the bridge")
return return
new_lights = process_lights( new_lights = process_lights(
@ -151,7 +150,7 @@ def process_lights(hass, api, bridge, update_lights_cb):
api_lights = api.get('lights') api_lights = api.get('lights')
if not isinstance(api_lights, dict): if not isinstance(api_lights, dict):
_LOGGER.error('Got unexpected result from Hue API') _LOGGER.error("Got unexpected result from Hue API")
return [] return []
new_lights = [] new_lights = []
@ -186,8 +185,8 @@ def process_groups(hass, api, bridge, update_lights_cb):
for lightgroup_id, info in api_groups.items(): for lightgroup_id, info in api_groups.items():
if 'state' not in info: if 'state' not in info:
_LOGGER.warning('Group info does not contain state. ' _LOGGER.warning(
'Please update your hub.') "Group info does not contain state. Please update your hub")
return [] return []
if lightgroup_id not in bridge.lightgroups: if lightgroup_id not in bridge.lightgroups:

View file

@ -9,13 +9,10 @@ import math
import voluptuous as vol import voluptuous as vol
from homeassistant.const import (CONF_HOST, CONF_NAME, CONF_PORT)
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_RGB_COLOR, ATTR_COLOR_TEMP, ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_RGB_COLOR, PLATFORM_SCHEMA,
SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_RGB_COLOR, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_RGB_COLOR, Light)
Light, PLATFORM_SCHEMA from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT
)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
import homeassistant.util.color as color_util import homeassistant.util.color as color_util

View file

@ -5,11 +5,12 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.knx/ https://home-assistant.io/components/light.knx/
""" """
import asyncio import asyncio
import voluptuous as vol import voluptuous as vol
from homeassistant.components.knx import DATA_KNX, ATTR_DISCOVER_DEVICES from homeassistant.components.knx import ATTR_DISCOVER_DEVICES, DATA_KNX
from homeassistant.components.light import PLATFORM_SCHEMA, Light, \ from homeassistant.components.light import (
SUPPORT_BRIGHTNESS, ATTR_BRIGHTNESS ATTR_BRIGHTNESS, PLATFORM_SCHEMA, SUPPORT_BRIGHTNESS, Light)
from homeassistant.const import CONF_NAME from homeassistant.const import CONF_NAME
from homeassistant.core import callback from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
@ -32,20 +33,17 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
@asyncio.coroutine @asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
discovery_info=None): """Set up lights for KNX platform."""
"""Set up light(s) for KNX platform."""
if DATA_KNX not in hass.data \ if DATA_KNX not in hass.data \
or not hass.data[DATA_KNX].initialized: or not hass.data[DATA_KNX].initialized:
return False return
if discovery_info is not None: if discovery_info is not None:
async_add_devices_discovery(hass, discovery_info, async_add_devices) async_add_devices_discovery(hass, discovery_info, async_add_devices)
else: else:
async_add_devices_config(hass, config, async_add_devices) async_add_devices_config(hass, config, async_add_devices)
return True
@callback @callback
def async_add_devices_discovery(hass, discovery_info, async_add_devices): def async_add_devices_discovery(hass, discovery_info, async_add_devices):
@ -77,7 +75,7 @@ class KNXLight(Light):
"""Representation of a KNX light.""" """Representation of a KNX light."""
def __init__(self, hass, device): def __init__(self, hass, device):
"""Initialization of KNXLight.""" """Initialize of KNX light."""
self.device = device self.device = device
self.hass = hass self.hass = hass
self.async_register_callbacks() self.async_register_callbacks()
@ -87,7 +85,7 @@ class KNXLight(Light):
"""Register callbacks to update hass after device was changed.""" """Register callbacks to update hass after device was changed."""
@asyncio.coroutine @asyncio.coroutine
def after_update_callback(device): def after_update_callback(device):
"""Callback after device was updated.""" """Call after device was updated."""
# pylint: disable=unused-argument # pylint: disable=unused-argument
yield from self.async_update_ha_state() yield from self.async_update_ha_state()
self.device.register_device_updated_cb(after_update_callback) self.device.register_device_updated_cb(after_update_callback)

View file

@ -4,29 +4,28 @@ Support for the LIFX platform that implements lights.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.lifx/ https://home-assistant.io/components/light.lifx/
""" """
import logging
import asyncio import asyncio
import sys
import math
from functools import partial
from datetime import timedelta from datetime import timedelta
from functools import partial
import logging
import math
import sys
import voluptuous as vol import voluptuous as vol
from homeassistant import util
from homeassistant.components.light import ( from homeassistant.components.light import (
Light, DOMAIN, PLATFORM_SCHEMA, LIGHT_TURN_ON_SCHEMA, ATTR_BRIGHTNESS, ATTR_BRIGHTNESS_PCT, ATTR_COLOR_NAME, ATTR_COLOR_TEMP,
ATTR_BRIGHTNESS, ATTR_BRIGHTNESS_PCT, ATTR_COLOR_NAME, ATTR_RGB_COLOR, ATTR_EFFECT, ATTR_KELVIN, ATTR_RGB_COLOR, ATTR_TRANSITION, ATTR_XY_COLOR,
ATTR_XY_COLOR, ATTR_COLOR_TEMP, ATTR_KELVIN, ATTR_TRANSITION, ATTR_EFFECT, DOMAIN, LIGHT_TURN_ON_SCHEMA, PLATFORM_SCHEMA, SUPPORT_BRIGHTNESS,
SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_RGB_COLOR, SUPPORT_COLOR_TEMP, SUPPORT_EFFECT, SUPPORT_RGB_COLOR, SUPPORT_TRANSITION,
SUPPORT_XY_COLOR, SUPPORT_TRANSITION, SUPPORT_EFFECT, SUPPORT_XY_COLOR, VALID_BRIGHTNESS, VALID_BRIGHTNESS_PCT, Light,
VALID_BRIGHTNESS, VALID_BRIGHTNESS_PCT,
preprocess_turn_on_alternatives) preprocess_turn_on_alternatives)
from homeassistant.const import ATTR_ENTITY_ID, EVENT_HOMEASSISTANT_STOP from homeassistant.const import ATTR_ENTITY_ID, EVENT_HOMEASSISTANT_STOP
from homeassistant import util
from homeassistant.core import callback from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.event import async_track_point_in_utc_time from homeassistant.helpers.event import async_track_point_in_utc_time
from homeassistant.helpers.service import extract_entity_ids from homeassistant.helpers.service import extract_entity_ids
import homeassistant.helpers.config_validation as cv
import homeassistant.util.color as color_util import homeassistant.util.color as color_util
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -296,12 +295,12 @@ class LIFXManager(object):
@callback @callback
def register(self, device): def register(self, device):
"""Handler for newly detected bulb.""" """Handle newly detected bulb."""
self.hass.async_add_job(self.async_register(device)) self.hass.async_add_job(self.async_register(device))
@asyncio.coroutine @asyncio.coroutine
def async_register(self, device): def async_register(self, device):
"""Handler for newly detected bulb.""" """Handle newly detected bulb."""
if device.mac_addr in self.entities: if device.mac_addr in self.entities:
entity = self.entities[device.mac_addr] entity = self.entities[device.mac_addr]
entity.registered = True entity.registered = True

View file

@ -16,7 +16,7 @@ SUPPORT_MYSENSORS = (SUPPORT_BRIGHTNESS | SUPPORT_RGB_COLOR |
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the mysensors platform for lights.""" """Set up the MySensors platform for lights."""
device_class_map = { device_class_map = {
'S_DIMMER': MySensorsLightDimmer, 'S_DIMMER': MySensorsLightDimmer,
'S_RGB_LIGHT': MySensorsLightRGB, 'S_RGB_LIGHT': MySensorsLightRGB,

View file

@ -63,7 +63,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
setup_bridge(bridge, add_devices, add_groups) setup_bridge(bridge, add_devices, add_groups)
def setup_bridge(bridge, add_devices_callback, add_groups): def setup_bridge(bridge, add_devices, add_groups):
"""Set up the Lightify bridge.""" """Set up the Lightify bridge."""
lights = {} lights = {}
@ -100,7 +100,7 @@ def setup_bridge(bridge, add_devices_callback, add_groups):
lights[group_name].group = group lights[group_name].group = group
if new_lights: if new_lights:
add_devices_callback(new_lights) add_devices(new_lights)
update_lights() update_lights()
@ -109,7 +109,7 @@ class Luminary(Light):
"""Representation of Luminary Lights and Groups.""" """Representation of Luminary Lights and Groups."""
def __init__(self, luminary, update_lights): def __init__(self, luminary, update_lights):
"""Initize a Luminary light.""" """Initialize a Luminary light."""
self.update_lights = update_lights self.update_lights = update_lights
self._luminary = luminary self._luminary = luminary
self._brightness = None self._brightness = None

View file

@ -10,7 +10,7 @@ import colorsys
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_RGB_COLOR, SUPPORT_BRIGHTNESS, ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_RGB_COLOR, SUPPORT_BRIGHTNESS,
SUPPORT_COLOR_TEMP, SUPPORT_RGB_COLOR, Light) SUPPORT_COLOR_TEMP, SUPPORT_RGB_COLOR, Light)
from homeassistant.components.wink import WinkDevice, DOMAIN from homeassistant.components.wink import DOMAIN, WinkDevice
from homeassistant.util import color as color_util from homeassistant.util import color as color_util
from homeassistant.util.color import \ from homeassistant.util.color import \
color_temperature_mired_to_kelvin as mired_to_kelvin color_temperature_mired_to_kelvin as mired_to_kelvin
@ -39,7 +39,7 @@ class WinkLight(WinkDevice, Light):
@asyncio.coroutine @asyncio.coroutine
def async_added_to_hass(self): def async_added_to_hass(self):
"""Callback when entity is added to hass.""" """Call when entity is added to hass."""
self.hass.data[DOMAIN]['entities']['light'].append(self) self.hass.data[DOMAIN]['entities']['light'].append(self)
@property @property

View file

@ -10,10 +10,10 @@ import logging
import voluptuous as vol import voluptuous as vol
import homeassistant.helpers.config_validation as cv from homeassistant.components.lock import DOMAIN, PLATFORM_SCHEMA, LockDevice
from homeassistant.components.lock import (DOMAIN, LockDevice, PLATFORM_SCHEMA)
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, CONF_HOST, CONF_PORT, CONF_TOKEN) ATTR_ENTITY_ID, CONF_HOST, CONF_PORT, CONF_TOKEN)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.service import extract_entity_ids from homeassistant.helpers.service import extract_entity_ids
REQUIREMENTS = ['pynuki==1.3.1'] REQUIREMENTS = ['pynuki==1.3.1']
@ -25,7 +25,12 @@ DEFAULT_PORT = 8080
ATTR_BATTERY_CRITICAL = 'battery_critical' ATTR_BATTERY_CRITICAL = 'battery_critical'
ATTR_NUKI_ID = 'nuki_id' ATTR_NUKI_ID = 'nuki_id'
ATTR_UNLATCH = 'unlatch' ATTR_UNLATCH = 'unlatch'
MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(seconds=5)
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=30)
NUKI_DATA = 'nuki' NUKI_DATA = 'nuki'
SERVICE_LOCK_N_GO = 'nuki_lock_n_go' SERVICE_LOCK_N_GO = 'nuki_lock_n_go'
SERVICE_UNLATCH = 'nuki_unlatch' SERVICE_UNLATCH = 'nuki_unlatch'
@ -44,9 +49,6 @@ UNLATCH_SERVICE_SCHEMA = vol.Schema({
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids vol.Optional(ATTR_ENTITY_ID): cv.entity_ids
}) })
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=30)
MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(seconds=5)
# pylint: disable=unused-argument # pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
@ -93,7 +95,7 @@ class NukiLock(LockDevice):
@asyncio.coroutine @asyncio.coroutine
def async_added_to_hass(self): def async_added_to_hass(self):
"""Callback when entity is added to hass.""" """Call when entity is added to hass."""
if NUKI_DATA not in self.hass.data: if NUKI_DATA not in self.hass.data:
self.hass.data[NUKI_DATA] = {} self.hass.data[NUKI_DATA] = {}
if DOMAIN not in self.hass.data[NUKI_DATA]: if DOMAIN not in self.hass.data[NUKI_DATA]:

View file

@ -7,7 +7,8 @@ https://home-assistant.io/components/lock.tesla/
import logging import logging
from homeassistant.components.lock import ENTITY_ID_FORMAT, LockDevice from homeassistant.components.lock import ENTITY_ID_FORMAT, LockDevice
from homeassistant.components.tesla import DOMAIN as TESLA_DOMAIN, TeslaDevice from homeassistant.components.tesla import DOMAIN as TESLA_DOMAIN
from homeassistant.components.tesla import TeslaDevice
from homeassistant.const import STATE_LOCKED, STATE_UNLOCKED from homeassistant.const import STATE_LOCKED, STATE_UNLOCKED
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -26,7 +27,7 @@ class TeslaLock(TeslaDevice, LockDevice):
"""Representation of a Tesla door lock.""" """Representation of a Tesla door lock."""
def __init__(self, tesla_device, controller): def __init__(self, tesla_device, controller):
"""Initialisation of the lock.""" """Initialise of the lock."""
self._state = None self._state = None
super().__init__(tesla_device, controller) super().__init__(tesla_device, controller)
self.entity_id = ENTITY_ID_FORMAT.format(self.tesla_id) self.entity_id = ENTITY_ID_FORMAT.format(self.tesla_id)
@ -47,7 +48,7 @@ class TeslaLock(TeslaDevice, LockDevice):
return self._state == STATE_LOCKED return self._state == STATE_LOCKED
def update(self): def update(self):
"""Updating state of the lock.""" """Update state of the lock."""
_LOGGER.debug("Updating state for: %s", self._name) _LOGGER.debug("Updating state for: %s", self._name)
self.tesla_device.update() self.tesla_device.update()
self._state = STATE_LOCKED if self.tesla_device.is_locked() \ self._state = STATE_LOCKED if self.tesla_device.is_locked() \

View file

@ -10,9 +10,9 @@ import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.components.lock import LockDevice from homeassistant.components.lock import LockDevice
from homeassistant.components.wink import WinkDevice, DOMAIN from homeassistant.components.wink import DOMAIN, WinkDevice
from homeassistant.const import ATTR_CODE, ATTR_ENTITY_ID, STATE_UNKNOWN
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNKNOWN, ATTR_CODE
DEPENDENCIES = ['wink'] DEPENDENCIES = ['wink']
@ -30,13 +30,19 @@ ATTR_SENSITIVITY = 'sensitivity'
ATTR_MODE = 'mode' ATTR_MODE = 'mode'
ATTR_NAME = 'name' ATTR_NAME = 'name'
ALARM_SENSITIVITY_MAP = {"low": 0.2, "medium_low": 0.4, ALARM_SENSITIVITY_MAP = {
"medium": 0.6, "medium_high": 0.8, 'low': 0.2,
"high": 1.0} 'medium_low': 0.4,
'medium': 0.6,
'medium_high': 0.8,
'high': 1.0,
}
ALARM_MODES_MAP = {"tamper": "tamper", ALARM_MODES_MAP = {
"activity": "alert", 'activity': 'alert',
"forced_entry": "forced_entry"} 'forced_entry': 'forced_entry',
'tamper': 'tamper',
}
SET_ENABLED_SCHEMA = vol.Schema({ SET_ENABLED_SCHEMA = vol.Schema({
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
@ -70,7 +76,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices([WinkLockDevice(lock, hass)]) add_devices([WinkLockDevice(lock, hass)])
def service_handle(service): def service_handle(service):
"""Handler for services.""" """Handle for services."""
entity_ids = service.data.get('entity_id') entity_ids = service.data.get('entity_id')
all_locks = hass.data[DOMAIN]['entities']['lock'] all_locks = hass.data[DOMAIN]['entities']['lock']
locks_to_set = [] locks_to_set = []
@ -127,7 +133,7 @@ class WinkLockDevice(WinkDevice, LockDevice):
@asyncio.coroutine @asyncio.coroutine
def async_added_to_hass(self): def async_added_to_hass(self):
"""Callback when entity is added to hass.""" """Call when entity is added to hass."""
self.hass.data[DOMAIN]['entities']['lock'].append(self) self.hass.data[DOMAIN]['entities']['lock'].append(self)
@property @property

View file

@ -1,5 +1,5 @@
""" """
Bluesound. Support for Bluesound devices.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.bluesound/ https://home-assistant.io/components/media_player.bluesound/
@ -16,14 +16,14 @@ import async_timeout
import voluptuous as vol import voluptuous as vol
from homeassistant.components.media_player import ( from homeassistant.components.media_player import (
SUPPORT_PLAY, SUPPORT_SEEK, SUPPORT_STOP, SUPPORT_PAUSE, PLATFORM_SCHEMA, MEDIA_TYPE_MUSIC, PLATFORM_SCHEMA, SUPPORT_CLEAR_PLAYLIST,
MEDIA_TYPE_MUSIC, SUPPORT_NEXT_TRACK, SUPPORT_PLAY_MEDIA, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_PLAY, SUPPORT_PLAY_MEDIA,
SUPPORT_VOLUME_SET, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP, SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK, SUPPORT_SELECT_SOURCE, SUPPORT_STOP,
SUPPORT_SELECT_SOURCE, SUPPORT_CLEAR_PLAYLIST, SUPPORT_PREVIOUS_TRACK, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, SUPPORT_VOLUME_STEP,
MediaPlayerDevice) MediaPlayerDevice)
from homeassistant.const import ( from homeassistant.const import (
CONF_HOST, CONF_NAME, CONF_PORT, CONF_HOSTS, STATE_IDLE, STATE_PAUSED, CONF_HOST, CONF_HOSTS, CONF_NAME, CONF_PORT, EVENT_HOMEASSISTANT_START,
STATE_PLAYING, EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_START) EVENT_HOMEASSISTANT_STOP, STATE_IDLE, STATE_PAUSED, STATE_PLAYING)
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
@ -60,6 +60,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
def _add_player(hass, async_add_devices, host, port=None, name=None): def _add_player(hass, async_add_devices, host, port=None, name=None):
"""Add Bluesound players."""
if host in [x.host for x in hass.data[DATA_BLUESOUND]]: if host in [x.host for x in hass.data[DATA_BLUESOUND]]:
return return
@ -108,8 +109,8 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
hass.data[DATA_BLUESOUND] = [] hass.data[DATA_BLUESOUND] = []
if discovery_info: if discovery_info:
_add_player(hass, async_add_devices, discovery_info.get('host'), _add_player(hass, async_add_devices, discovery_info.get(CONF_HOST),
discovery_info.get('port', None)) discovery_info.get(CONF_PORT, None))
return return
hosts = config.get(CONF_HOSTS, None) hosts = config.get(CONF_HOSTS, None)
@ -117,11 +118,11 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
for host in hosts: for host in hosts:
_add_player( _add_player(
hass, async_add_devices, host.get(CONF_HOST), hass, async_add_devices, host.get(CONF_HOST),
host.get(CONF_PORT), host.get(CONF_NAME, None)) host.get(CONF_PORT), host.get(CONF_NAME))
class BluesoundPlayer(MediaPlayerDevice): class BluesoundPlayer(MediaPlayerDevice):
"""Bluesound Player Object.""" """Represenatation of a Bluesound Player."""
def __init__(self, hass, host, port=None, name=None, init_callback=None): def __init__(self, hass, host, port=None, name=None, init_callback=None):
"""Initialize the media player.""" """Initialize the media player."""
@ -150,6 +151,7 @@ class BluesoundPlayer(MediaPlayerDevice):
@staticmethod @staticmethod
def _try_get_index(string, seach_string): def _try_get_index(string, seach_string):
"""Get the index."""
try: try:
return string.index(seach_string) return string.index(seach_string)
except ValueError: except ValueError:
@ -158,6 +160,7 @@ class BluesoundPlayer(MediaPlayerDevice):
@asyncio.coroutine @asyncio.coroutine
def _internal_update_sync_status( def _internal_update_sync_status(
self, on_updated_cb=None, raise_timeout=False): self, on_updated_cb=None, raise_timeout=False):
"""Update the internal status."""
resp = None resp = None
try: try:
resp = yield from self.send_bluesound_command( resp = yield from self.send_bluesound_command(
@ -186,7 +189,7 @@ class BluesoundPlayer(MediaPlayerDevice):
@asyncio.coroutine @asyncio.coroutine
def _start_poll_command(self): def _start_poll_command(self):
""""Loop which polls the status of the player.""" """Loop which polls the status of the player."""
try: try:
while True: while True:
yield from self.async_update_status() yield from self.async_update_status()
@ -214,7 +217,7 @@ class BluesoundPlayer(MediaPlayerDevice):
@asyncio.coroutine @asyncio.coroutine
def async_init(self): def async_init(self):
"""Initiate the player async.""" """Initialize the player async."""
try: try:
if self._retry_remove is not None: if self._retry_remove is not None:
self._retry_remove() self._retry_remove()
@ -284,7 +287,7 @@ class BluesoundPlayer(MediaPlayerDevice):
@asyncio.coroutine @asyncio.coroutine
def async_update_status(self): def async_update_status(self):
"""Using the poll session to always get the status of the player.""" """Use the poll session to always get the status of the player."""
import xmltodict import xmltodict
response = None response = None

View file

@ -8,14 +8,13 @@ import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.const import (ATTR_ENTITY_ID, CONF_NAME, CONF_PORT,
STATE_OFF, STATE_ON)
import homeassistant.helpers.config_validation as cv
from homeassistant.components.media_player import ( from homeassistant.components.media_player import (
DOMAIN, MediaPlayerDevice, MEDIA_PLAYER_SCHEMA, PLATFORM_SCHEMA, DOMAIN, MEDIA_PLAYER_SCHEMA, PLATFORM_SCHEMA, SUPPORT_SELECT_SOURCE,
SUPPORT_VOLUME_MUTE, SUPPORT_SELECT_SOURCE, SUPPORT_TURN_ON, SUPPORT_TURN_OFF, SUPPORT_TURN_ON, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET,
SUPPORT_TURN_OFF, SUPPORT_VOLUME_SET, SUPPORT_VOLUME_STEP) SUPPORT_VOLUME_STEP, MediaPlayerDevice)
from homeassistant.const import (
ATTR_ENTITY_ID, CONF_NAME, CONF_PORT, STATE_OFF, STATE_ON)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pymonoprice==0.3'] REQUIREMENTS = ['pymonoprice==0.3']
@ -42,9 +41,9 @@ SERVICE_SNAPSHOT = 'snapshot'
SERVICE_RESTORE = 'restore' SERVICE_RESTORE = 'restore'
# Valid zone ids: 11-16 or 21-26 or 31-36 # Valid zone ids: 11-16 or 21-26 or 31-36
ZONE_IDS = vol.All(vol.Coerce(int), vol.Any(vol.Range(min=11, max=16), ZONE_IDS = vol.All(vol.Coerce(int), vol.Any(
vol.Range(min=21, max=26), vol.Range(min=11, max=16), vol.Range(min=21, max=26),
vol.Range(min=31, max=36))) vol.Range(min=31, max=36)))
# Valid source ids: 1-6 # Valid source ids: 1-6
SOURCE_IDS = vol.All(vol.Coerce(int), vol.Range(min=1, max=6)) SOURCE_IDS = vol.All(vol.Coerce(int), vol.Range(min=1, max=6))
@ -66,7 +65,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
try: try:
monoprice = get_monoprice(port) monoprice = get_monoprice(port)
except SerialException: except SerialException:
_LOGGER.error('Error connecting to Monoprice controller.') _LOGGER.error("Error connecting to Monoprice controller")
return return
sources = {source_id: extra[CONF_NAME] for source_id, extra sources = {source_id: extra[CONF_NAME] for source_id, extra
@ -75,9 +74,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
hass.data[DATA_MONOPRICE] = [] hass.data[DATA_MONOPRICE] = []
for zone_id, extra in config[CONF_ZONES].items(): for zone_id, extra in config[CONF_ZONES].items():
_LOGGER.info("Adding zone %d - %s", zone_id, extra[CONF_NAME]) _LOGGER.info("Adding zone %d - %s", zone_id, extra[CONF_NAME])
hass.data[DATA_MONOPRICE].append(MonopriceZone(monoprice, sources, hass.data[DATA_MONOPRICE].append(MonopriceZone(
zone_id, monoprice, sources, zone_id, extra[CONF_NAME]))
extra[CONF_NAME]))
add_devices(hass.data[DATA_MONOPRICE], True) add_devices(hass.data[DATA_MONOPRICE], True)
@ -98,19 +96,15 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
device.restore() device.restore()
hass.services.register( hass.services.register(
DOMAIN, SERVICE_SNAPSHOT, service_handle, DOMAIN, SERVICE_SNAPSHOT, service_handle, schema=MEDIA_PLAYER_SCHEMA)
schema=MEDIA_PLAYER_SCHEMA)
hass.services.register( hass.services.register(
DOMAIN, SERVICE_RESTORE, service_handle, DOMAIN, SERVICE_RESTORE, service_handle, schema=MEDIA_PLAYER_SCHEMA)
schema=MEDIA_PLAYER_SCHEMA)
class MonopriceZone(MediaPlayerDevice): class MonopriceZone(MediaPlayerDevice):
"""Representation of a a Monoprice amplifier zone.""" """Representation of a a Monoprice amplifier zone."""
# pylint: disable=too-many-public-methods
def __init__(self, monoprice, sources, zone_id, zone_name): def __init__(self, monoprice, sources, zone_id, zone_name):
"""Initialize new zone.""" """Initialize new zone."""
self._monoprice = monoprice self._monoprice = monoprice
@ -179,7 +173,7 @@ class MonopriceZone(MediaPlayerDevice):
@property @property
def source(self): def source(self):
""""Return the current input source of the device.""" """Return the current input source of the device."""
return self._source return self._source
@property @property
@ -224,12 +218,10 @@ class MonopriceZone(MediaPlayerDevice):
"""Volume up the media player.""" """Volume up the media player."""
if self._volume is None: if self._volume is None:
return return
self._monoprice.set_volume(self._zone_id, self._monoprice.set_volume(self._zone_id, min(self._volume + 1, 38))
min(self._volume + 1, 38))
def volume_down(self): def volume_down(self):
"""Volume down media player.""" """Volume down media player."""
if self._volume is None: if self._volume is None:
return return
self._monoprice.set_volume(self._zone_id, self._monoprice.set_volume(self._zone_id, max(self._volume - 1, 0))
max(self._volume - 1, 0))

View file

@ -4,22 +4,22 @@ Support to interact with a Music Player Daemon.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.mpd/ https://home-assistant.io/components/media_player.mpd/
""" """
from datetime import timedelta
import logging import logging
import os import os
from datetime import timedelta
import voluptuous as vol import voluptuous as vol
from homeassistant.components.media_player import ( from homeassistant.components.media_player import (
MEDIA_TYPE_MUSIC, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, PLATFORM_SCHEMA, MEDIA_TYPE_MUSIC, MEDIA_TYPE_PLAYLIST, PLATFORM_SCHEMA,
SUPPORT_PREVIOUS_TRACK, SUPPORT_STOP, SUPPORT_PLAY, SUPPORT_CLEAR_PLAYLIST, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_PLAY,
SUPPORT_VOLUME_SET, SUPPORT_PLAY_MEDIA, MEDIA_TYPE_PLAYLIST, SUPPORT_PLAY_MEDIA, SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK,
SUPPORT_SELECT_SOURCE, SUPPORT_CLEAR_PLAYLIST, SUPPORT_SHUFFLE_SET, SUPPORT_SELECT_SOURCE, SUPPORT_SHUFFLE_SET, SUPPORT_STOP, SUPPORT_TURN_OFF,
SUPPORT_SEEK, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP, SUPPORT_TURN_ON, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET,
SUPPORT_TURN_OFF, SUPPORT_TURN_ON, MediaPlayerDevice) SUPPORT_VOLUME_STEP, MediaPlayerDevice)
from homeassistant.const import ( from homeassistant.const import (
STATE_OFF, STATE_PAUSED, STATE_PLAYING, CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_PORT, STATE_OFF, STATE_PAUSED,
CONF_PORT, CONF_PASSWORD, CONF_HOST, CONF_NAME) STATE_PLAYING)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.util import Throttle from homeassistant.util import Throttle
@ -116,7 +116,7 @@ class MpdDevice(MediaPlayerDevice):
@property @property
def available(self): def available(self):
"""True if MPD is available and connected.""" """Return true if MPD is available and connected."""
return self._is_connected return self._is_connected
def update(self): def update(self):

View file

@ -5,14 +5,14 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.nadtcp/ https://home-assistant.io/components/media_player.nadtcp/
""" """
import logging import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.components.media_player import ( from homeassistant.components.media_player import (
SUPPORT_VOLUME_SET, PLATFORM_SCHEMA, SUPPORT_SELECT_SOURCE, SUPPORT_TURN_OFF, SUPPORT_TURN_ON,
SUPPORT_VOLUME_MUTE, SUPPORT_TURN_ON, SUPPORT_TURN_OFF, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, SUPPORT_VOLUME_STEP,
SUPPORT_VOLUME_STEP, SUPPORT_SELECT_SOURCE, MediaPlayerDevice, MediaPlayerDevice)
PLATFORM_SCHEMA) from homeassistant.const import CONF_HOST, CONF_NAME, STATE_OFF, STATE_ON
from homeassistant.const import (
CONF_NAME, STATE_OFF, STATE_ON)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['nad_receiver==0.0.9'] REQUIREMENTS = ['nad_receiver==0.0.9']
@ -30,7 +30,6 @@ SUPPORT_NAD = SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE | SUPPORT_TURN_ON | \
CONF_MIN_VOLUME = 'min_volume' CONF_MIN_VOLUME = 'min_volume'
CONF_MAX_VOLUME = 'max_volume' CONF_MAX_VOLUME = 'max_volume'
CONF_VOLUME_STEP = 'volume_step' CONF_VOLUME_STEP = 'volume_step'
CONF_HOST = 'host'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string, vol.Required(CONF_HOST): cv.string,
@ -42,7 +41,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the NAD platform.""" """Set up the NAD platform."""
from nad_receiver import NADReceiverTCP from nad_receiver import NADReceiverTCP
add_devices([NADtcp( add_devices([NADtcp(
NADReceiverTCP(config.get(CONF_HOST)), NADReceiverTCP(config.get(CONF_HOST)),

View file

@ -11,11 +11,11 @@ import socket
import voluptuous as vol import voluptuous as vol
from homeassistant.components.media_player import ( from homeassistant.components.media_player import (
SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, SUPPORT_SELECT_SOURCE, DOMAIN, PLATFORM_SCHEMA, SUPPORT_SELECT_SOURCE, SUPPORT_VOLUME_MUTE,
DOMAIN, PLATFORM_SCHEMA, MediaPlayerDevice) SUPPORT_VOLUME_SET, MediaPlayerDevice)
from homeassistant.const import ( from homeassistant.const import (
STATE_ON, STATE_OFF, STATE_IDLE, STATE_PLAYING, STATE_UNKNOWN, CONF_HOST, ATTR_ENTITY_ID, CONF_HOST, CONF_PORT, STATE_IDLE, STATE_OFF, STATE_ON,
CONF_PORT, ATTR_ENTITY_ID) STATE_PLAYING, STATE_UNKNOWN)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['snapcast==2.0.8'] REQUIREMENTS = ['snapcast==2.0.8']
@ -42,14 +42,14 @@ SERVICE_SCHEMA = vol.Schema({
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string, vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_PORT): cv.port vol.Optional(CONF_PORT): cv.port,
}) })
# pylint: disable=unused-argument # pylint: disable=unused-argument
@asyncio.coroutine @asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None): def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Setup the Snapcast platform.""" """Set up the Snapcast platform."""
import snapcast.control import snapcast.control
from snapcast.control.server import CONTROL_PORT from snapcast.control.server import CONTROL_PORT
host = config.get(CONF_HOST) host = config.get(CONF_HOST)
@ -68,25 +68,23 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
yield from device.async_restore() yield from device.async_restore()
hass.services.async_register( hass.services.async_register(
DOMAIN, SERVICE_SNAPSHOT, _handle_service, DOMAIN, SERVICE_SNAPSHOT, _handle_service, schema=SERVICE_SCHEMA)
schema=SERVICE_SCHEMA)
hass.services.async_register( hass.services.async_register(
DOMAIN, SERVICE_RESTORE, _handle_service, DOMAIN, SERVICE_RESTORE, _handle_service, schema=SERVICE_SCHEMA)
schema=SERVICE_SCHEMA)
try: try:
server = yield from snapcast.control.create_server( server = yield from snapcast.control.create_server(
hass.loop, host, port, reconnect=True) hass.loop, host, port, reconnect=True)
except socket.gaierror: except socket.gaierror:
_LOGGER.error('Could not connect to Snapcast server at %s:%d', _LOGGER.error("Could not connect to Snapcast server at %s:%d",
host, port) host, port)
return False return
groups = [SnapcastGroupDevice(group) for group in server.groups] groups = [SnapcastGroupDevice(group) for group in server.groups]
clients = [SnapcastClientDevice(client) for client in server.clients] clients = [SnapcastClientDevice(client) for client in server.clients]
devices = groups + clients devices = groups + clients
hass.data[DATA_KEY] = devices hass.data[DATA_KEY] = devices
async_add_devices(devices) async_add_devices(devices)
return True
class SnapcastGroupDevice(MediaPlayerDevice): class SnapcastGroupDevice(MediaPlayerDevice):

View file

@ -14,14 +14,14 @@ import urllib
import voluptuous as vol import voluptuous as vol
from homeassistant.components.media_player import ( from homeassistant.components.media_player import (
ATTR_MEDIA_ENQUEUE, DOMAIN, MEDIA_TYPE_MUSIC, SUPPORT_NEXT_TRACK, ATTR_MEDIA_ENQUEUE, DOMAIN, MEDIA_TYPE_MUSIC, PLATFORM_SCHEMA,
SUPPORT_PAUSE, SUPPORT_PLAY_MEDIA, SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK, SUPPORT_CLEAR_PLAYLIST, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_PLAY,
SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, SUPPORT_CLEAR_PLAYLIST, SUPPORT_PLAY_MEDIA, SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK,
SUPPORT_SELECT_SOURCE, MediaPlayerDevice, PLATFORM_SCHEMA, SUPPORT_STOP, SUPPORT_SELECT_SOURCE, SUPPORT_SHUFFLE_SET, SUPPORT_STOP,
SUPPORT_PLAY, SUPPORT_SHUFFLE_SET) SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, MediaPlayerDevice)
from homeassistant.const import ( from homeassistant.const import (
STATE_IDLE, STATE_PAUSED, STATE_PLAYING, STATE_OFF, ATTR_ENTITY_ID, ATTR_ENTITY_ID, ATTR_TIME, CONF_HOSTS, STATE_IDLE, STATE_OFF, STATE_PAUSED,
CONF_HOSTS, ATTR_TIME) STATE_PLAYING)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.util.dt import utcnow from homeassistant.util.dt import utcnow
@ -126,7 +126,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
if discovery_info: if discovery_info:
player = soco.SoCo(discovery_info.get('host')) player = soco.SoCo(discovery_info.get('host'))
# if device already exists by config # If device already exists by config
if player.uid in [x.unique_id for x in hass.data[DATA_SONOS]]: if player.uid in [x.unique_id for x in hass.data[DATA_SONOS]]:
return return
@ -167,7 +167,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices(coordinators, True) add_devices(coordinators, True)
if slaves: if slaves:
add_devices(slaves, True) add_devices(slaves, True)
_LOGGER.info("Added %s Sonos speakers", len(players)) _LOGGER.debug("Added %s Sonos speakers", len(players))
def service_handle(service): def service_handle(service):
"""Handle for services.""" """Handle for services."""
@ -242,10 +242,11 @@ def _parse_timespan(timespan):
reversed(timespan.split(':')))) reversed(timespan.split(':'))))
class _ProcessSonosEventQueue(): class _ProcessSonosEventQueue(object):
"""Queue like object for dispatching sonos events.""" """Queue like object for dispatching sonos events."""
def __init__(self, sonos_device): def __init__(self, sonos_device):
"""Initialize Sonos event queue."""
self._sonos_device = sonos_device self._sonos_device = sonos_device
def put(self, item, block=True, timeout=None): def put(self, item, block=True, timeout=None):
@ -266,7 +267,7 @@ def _get_entity_from_soco(hass, soco):
def soco_error(errorcodes=None): def soco_error(errorcodes=None):
"""Filter out specified UPnP errors from logs and avoid exceptions.""" """Filter out specified UPnP errors from logs and avoid exceptions."""
def decorator(funct): def decorator(funct):
"""Decorator function.""" """Decorate functions."""
@ft.wraps(funct) @ft.wraps(funct)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
"""Wrap for all soco UPnP exception.""" """Wrap for all soco UPnP exception."""

View file

@ -1,36 +1,23 @@
""" """
Vizio SmartCast TV support. Vizio SmartCast TV support.
Usually only 2016+ models come with SmartCast capabilities.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.vizio/ https://home-assistant.io/components/media_player.vizio/
""" """
import logging
from datetime import timedelta from datetime import timedelta
import logging
import voluptuous as vol import voluptuous as vol
import homeassistant.util as util
from homeassistant.components.media_player import ( from homeassistant.components.media_player import (
PLATFORM_SCHEMA, PLATFORM_SCHEMA, SUPPORT_NEXT_TRACK, SUPPORT_PREVIOUS_TRACK,
SUPPORT_TURN_ON, SUPPORT_SELECT_SOURCE, SUPPORT_TURN_OFF, SUPPORT_TURN_ON,
SUPPORT_TURN_OFF, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP, MediaPlayerDevice)
SUPPORT_SELECT_SOURCE,
SUPPORT_PREVIOUS_TRACK,
SUPPORT_NEXT_TRACK,
SUPPORT_VOLUME_MUTE,
SUPPORT_VOLUME_STEP,
MediaPlayerDevice
)
from homeassistant.const import ( from homeassistant.const import (
STATE_UNKNOWN, CONF_ACCESS_TOKEN, CONF_HOST, CONF_NAME, STATE_OFF, STATE_ON,
STATE_OFF, STATE_UNKNOWN)
STATE_ON,
CONF_NAME,
CONF_HOST,
CONF_ACCESS_TOKEN
)
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
import homeassistant.util as util
REQUIREMENTS = ['pyvizio==0.0.2'] REQUIREMENTS = ['pyvizio==0.0.2']
@ -39,13 +26,16 @@ _LOGGER = logging.getLogger(__name__)
CONF_SUPPRESS_WARNING = 'suppress_warning' CONF_SUPPRESS_WARNING = 'suppress_warning'
CONF_VOLUME_STEP = 'volume_step' CONF_VOLUME_STEP = 'volume_step'
ICON = 'mdi:television'
DEFAULT_NAME = 'Vizio SmartCast' DEFAULT_NAME = 'Vizio SmartCast'
DEFAULT_VOLUME_STEP = 1 DEFAULT_VOLUME_STEP = 1
DEVICE_NAME = 'Python Vizio'
DEVICE_ID = 'pyvizio' DEVICE_ID = 'pyvizio'
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10) DEVICE_NAME = 'Python Vizio'
ICON = 'mdi:television'
MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(seconds=1) MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(seconds=1)
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
SUPPORTED_COMMANDS = SUPPORT_TURN_ON | SUPPORT_TURN_OFF \ SUPPORTED_COMMANDS = SUPPORT_TURN_ON | SUPPORT_TURN_OFF \
| SUPPORT_SELECT_SOURCE \ | SUPPORT_SELECT_SOURCE \
| SUPPORT_NEXT_TRACK | SUPPORT_PREVIOUS_TRACK \ | SUPPORT_NEXT_TRACK | SUPPORT_PREVIOUS_TRACK \
@ -70,14 +60,14 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
device = VizioDevice(host, token, name, volume_step) device = VizioDevice(host, token, name, volume_step)
if device.validate_setup() is False: if device.validate_setup() is False:
_LOGGER.error('Failed to setup Vizio TV platform, ' _LOGGER.error("Failed to setup Vizio TV platform, "
'please check if host and API key are correct.') "please check if host and API key are correct")
return False return
if config.get(CONF_SUPPRESS_WARNING): if config.get(CONF_SUPPRESS_WARNING):
from requests.packages import urllib3 from requests.packages import urllib3
_LOGGER.warning('InsecureRequestWarning is disabled ' _LOGGER.warning("InsecureRequestWarning is disabled "
'because of Vizio platform configuration.') "because of Vizio platform configuration")
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
add_devices([device], True) add_devices([device], True)
@ -184,5 +174,5 @@ class VizioDevice(MediaPlayerDevice):
self._device.vol_down(num=self._volume_step) self._device.vol_down(num=self._volume_step)
def validate_setup(self): def validate_setup(self):
"""Validating if host is available and key is correct.""" """Validate if host is available and key is correct."""
return self._device.get_current_volume() is not None return self._device.get_current_volume() is not None

View file

@ -4,30 +4,26 @@ Support for interface with an LG webOS Smart TV.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.webostv/ https://home-assistant.io/components/media_player.webostv/
""" """
import logging
import asyncio import asyncio
from datetime import timedelta from datetime import timedelta
import logging
from urllib.parse import urlparse from urllib.parse import urlparse
import voluptuous as vol import voluptuous as vol
import homeassistant.util as util
from homeassistant.components.media_player import ( from homeassistant.components.media_player import (
SUPPORT_TURN_ON, SUPPORT_TURN_OFF, SUPPORT_PLAY, MEDIA_TYPE_CHANNEL, PLATFORM_SCHEMA, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE,
SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_PREVIOUS_TRACK, SUPPORT_PLAY, SUPPORT_PLAY_MEDIA, SUPPORT_PREVIOUS_TRACK,
SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP, SUPPORT_SELECT_SOURCE, SUPPORT_TURN_OFF, SUPPORT_TURN_ON,
SUPPORT_SELECT_SOURCE, SUPPORT_PLAY_MEDIA, MEDIA_TYPE_CHANNEL, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP, MediaPlayerDevice)
MediaPlayerDevice, PLATFORM_SCHEMA)
from homeassistant.const import ( from homeassistant.const import (
CONF_HOST, CONF_CUSTOMIZE, CONF_TIMEOUT, STATE_OFF, CONF_CUSTOMIZE, CONF_FILENAME, CONF_HOST, CONF_NAME, CONF_TIMEOUT,
STATE_PLAYING, STATE_PAUSED, STATE_OFF, STATE_PAUSED, STATE_PLAYING, STATE_UNKNOWN)
STATE_UNKNOWN, CONF_NAME, CONF_FILENAME)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.script import Script from homeassistant.helpers.script import Script
import homeassistant.util as util
REQUIREMENTS = ['pylgtv==0.1.7', REQUIREMENTS = ['pylgtv==0.1.7', 'websockets==3.2', 'wakeonlan==0.2.2']
'websockets==3.2',
'wakeonlan==0.2.2']
_CONFIGURING = {} # type: Dict[str, str] _CONFIGURING = {} # type: Dict[str, str]
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -48,17 +44,16 @@ MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(seconds=1) MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(seconds=1)
CUSTOMIZE_SCHEMA = vol.Schema({ CUSTOMIZE_SCHEMA = vol.Schema({
vol.Optional(CONF_SOURCES): vol.Optional(CONF_SOURCES): vol.All(cv.ensure_list, [cv.string]),
vol.All(cv.ensure_list, [cv.string]),
}) })
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_HOST): cv.string,
vol.Optional(CONF_CUSTOMIZE, default={}): CUSTOMIZE_SCHEMA, vol.Optional(CONF_CUSTOMIZE, default={}): CUSTOMIZE_SCHEMA,
vol.Optional(CONF_FILENAME, default=WEBOSTV_CONFIG_FILE): cv.string, vol.Optional(CONF_FILENAME, default=WEBOSTV_CONFIG_FILE): cv.string,
vol.Optional(CONF_TIMEOUT, default=8): cv.positive_int, vol.Optional(CONF_HOST): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_ON_ACTION): cv.SCRIPT_SCHEMA, vol.Optional(CONF_ON_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_TIMEOUT, default=8): cv.positive_int,
}) })
@ -142,7 +137,7 @@ def request_configuration(
# pylint: disable=unused-argument # pylint: disable=unused-argument
def lgtv_configuration_callback(data): def lgtv_configuration_callback(data):
"""The actions to do when our configuration callback is called.""" """Handle actions when configuration callback is called."""
setup_tv(host, name, customize, config, timeout, hass, setup_tv(host, name, customize, config, timeout, hass,
add_devices, turn_on_action) add_devices, turn_on_action)

View file

@ -4,16 +4,14 @@ MyChevy Component.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/mychevy/ https://home-assistant.io/components/mychevy/
""" """
from datetime import timedelta from datetime import timedelta
import logging import logging
import time
import threading import threading
import time
import voluptuous as vol import voluptuous as vol
from homeassistant.const import ( from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
CONF_USERNAME, CONF_PASSWORD)
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import discovery from homeassistant.helpers import discovery
from homeassistant.util import Throttle from homeassistant.util import Throttle
@ -38,16 +36,16 @@ ERROR_SLEEP_TIME = timedelta(minutes=30)
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({ DOMAIN: vol.Schema({
vol.Required(CONF_USERNAME): cv.string, vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string vol.Required(CONF_PASSWORD): cv.string,
}), }),
}, extra=vol.ALLOW_EXTRA) }, extra=vol.ALLOW_EXTRA)
class EVSensorConfig(object): class EVSensorConfig(object):
"""EV Sensor Config.""" """The EV sensor configuration."""
def __init__(self, name, attr, unit_of_measurement=None, icon=None): def __init__(self, name, attr, unit_of_measurement=None, icon=None):
"""Create new Sensor Config.""" """Create new sensor configuration."""
self.name = name self.name = name
self.attr = attr self.attr = attr
self.unit_of_measurement = unit_of_measurement self.unit_of_measurement = unit_of_measurement
@ -55,17 +53,17 @@ class EVSensorConfig(object):
class EVBinarySensorConfig(object): class EVBinarySensorConfig(object):
"""EV Binary Sensor Config.""" """The EV binary sensor configuration."""
def __init__(self, name, attr, device_class=None): def __init__(self, name, attr, device_class=None):
"""Create new Binary Sensor Config.""" """Create new binary sensor configuration."""
self.name = name self.name = name
self.attr = attr self.attr = attr
self.device_class = device_class self.device_class = device_class
def setup(hass, base_config): def setup(hass, base_config):
"""Setup mychevy platform.""" """Set up the mychevy component."""
import mychevy.mychevy as mc import mychevy.mychevy as mc
config = base_config.get(DOMAIN) config = base_config.get(DOMAIN)

View file

@ -1,8 +1,8 @@
""" """
Connect to a MySensors gateway via pymysensors API. Connect to a MySensors gateway via pymysensors API.
For more details about this platform, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/sensor.mysensors/ https://home-assistant.io/components/mysensors/
""" """
import asyncio import asyncio
from collections import defaultdict from collections import defaultdict
@ -115,21 +115,20 @@ def is_serial_port(value):
if value in ports: if value in ports:
return value return value
else: else:
raise vol.Invalid( raise vol.Invalid('{} is not a serial port'.format(value))
'{} is not a serial port'.format(value))
else: else:
return cv.isdevice(value) return cv.isdevice(value)
def deprecated(key): def deprecated(key):
"""Mark key as deprecated in config.""" """Mark key as deprecated in configuration."""
def validator(config): def validator(config):
"""Check if key is in config, log warning and remove key.""" """Check if key is in config, log warning and remove key."""
if key not in config: if key not in config:
return config return config
_LOGGER.warning( _LOGGER.warning(
'%s option for %s is deprecated. Please remove %s from your ' '%s option for %s is deprecated. Please remove %s from your '
'configuration file.', key, DOMAIN, key) 'configuration file', key, DOMAIN, key)
config.pop(key) config.pop(key)
return config return config
return validator return validator
@ -150,16 +149,13 @@ CONFIG_SCHEMA = vol.Schema({
vol.Any(MQTT_COMPONENT, is_socket_address, is_serial_port), vol.Any(MQTT_COMPONENT, is_socket_address, is_serial_port),
vol.Optional(CONF_PERSISTENCE_FILE): vol.Optional(CONF_PERSISTENCE_FILE):
vol.All(cv.string, is_persistence_file, has_parent_dir), vol.All(cv.string, is_persistence_file, has_parent_dir),
vol.Optional( vol.Optional(CONF_BAUD_RATE, default=DEFAULT_BAUD_RATE):
CONF_BAUD_RATE, cv.positive_int,
default=DEFAULT_BAUD_RATE): cv.positive_int, vol.Optional(CONF_TCP_PORT, default=DEFAULT_TCP_PORT): cv.port,
vol.Optional( vol.Optional(CONF_TOPIC_IN_PREFIX, default=''):
CONF_TCP_PORT, valid_subscribe_topic,
default=DEFAULT_TCP_PORT): cv.port, vol.Optional(CONF_TOPIC_OUT_PREFIX, default=''):
vol.Optional( valid_publish_topic,
CONF_TOPIC_IN_PREFIX, default=''): valid_subscribe_topic,
vol.Optional(
CONF_TOPIC_OUT_PREFIX, default=''): valid_publish_topic,
vol.Optional(CONF_NODES, default={}): NODE_SCHEMA, vol.Optional(CONF_NODES, default={}): NODE_SCHEMA,
}] }]
), ),
@ -171,7 +167,7 @@ CONFIG_SCHEMA = vol.Schema({
}, extra=vol.ALLOW_EXTRA) }, extra=vol.ALLOW_EXTRA)
# mysensors const schemas # MySensors const schemas
BINARY_SENSOR_SCHEMA = {PLATFORM: 'binary_sensor', TYPE: 'V_TRIPPED'} BINARY_SENSOR_SCHEMA = {PLATFORM: 'binary_sensor', TYPE: 'V_TRIPPED'}
CLIMATE_SCHEMA = {PLATFORM: 'climate', TYPE: 'V_HVAC_FLOW_STATE'} CLIMATE_SCHEMA = {PLATFORM: 'climate', TYPE: 'V_HVAC_FLOW_STATE'}
LIGHT_DIMMER_SCHEMA = { LIGHT_DIMMER_SCHEMA = {
@ -439,7 +435,7 @@ def validate_child(gateway, node_id, child):
def discover_mysensors_platform(hass, platform, new_devices): def discover_mysensors_platform(hass, platform, new_devices):
"""Discover a mysensors platform.""" """Discover a MySensors platform."""
discovery.load_platform( discovery.load_platform(
hass, platform, DOMAIN, {ATTR_DEVICES: new_devices, CONF_NAME: DOMAIN}) hass, platform, DOMAIN, {ATTR_DEVICES: new_devices, CONF_NAME: DOMAIN})
@ -458,7 +454,7 @@ def discover_persistent_devices(hass, gateway):
def get_mysensors_devices(hass, domain): def get_mysensors_devices(hass, domain):
"""Return mysensors devices for a platform.""" """Return MySensors devices for a platform."""
if MYSENSORS_PLATFORM_DEVICES.format(domain) not in hass.data: if MYSENSORS_PLATFORM_DEVICES.format(domain) not in hass.data:
hass.data[MYSENSORS_PLATFORM_DEVICES.format(domain)] = {} hass.data[MYSENSORS_PLATFORM_DEVICES.format(domain)] = {}
return hass.data[MYSENSORS_PLATFORM_DEVICES.format(domain)] return hass.data[MYSENSORS_PLATFORM_DEVICES.format(domain)]
@ -467,15 +463,14 @@ def get_mysensors_devices(hass, domain):
def gw_callback_factory(hass): def gw_callback_factory(hass):
"""Return a new callback for the gateway.""" """Return a new callback for the gateway."""
def mysensors_callback(msg): def mysensors_callback(msg):
"""Default callback for a mysensors gateway.""" """Handle messages from a MySensors gateway."""
start = timer() start = timer()
_LOGGER.debug( _LOGGER.debug(
"Node update: node %s child %s", msg.node_id, msg.child_id) "Node update: node %s child %s", msg.node_id, msg.child_id)
child = msg.gateway.sensors[msg.node_id].children.get(msg.child_id) child = msg.gateway.sensors[msg.node_id].children.get(msg.child_id)
if child is None: if child is None:
_LOGGER.debug( _LOGGER.debug("Not a child update for node %s", msg.node_id)
"Not a child update for node %s", msg.node_id)
return return
signals = [] signals = []
@ -518,7 +513,7 @@ def get_mysensors_name(gateway, node_id, child_id):
def get_mysensors_gateway(hass, gateway_id): def get_mysensors_gateway(hass, gateway_id):
"""Return gateway.""" """Return MySensors gateway."""
if MYSENSORS_GATEWAYS not in hass.data: if MYSENSORS_GATEWAYS not in hass.data:
hass.data[MYSENSORS_GATEWAYS] = {} hass.data[MYSENSORS_GATEWAYS] = {}
gateways = hass.data.get(MYSENSORS_GATEWAYS) gateways = hass.data.get(MYSENSORS_GATEWAYS)
@ -528,8 +523,8 @@ def get_mysensors_gateway(hass, gateway_id):
def setup_mysensors_platform( def setup_mysensors_platform(
hass, domain, discovery_info, device_class, device_args=None, hass, domain, discovery_info, device_class, device_args=None,
add_devices=None): add_devices=None):
"""Set up a mysensors platform.""" """Set up a MySensors platform."""
# Only act if called via mysensors by discovery event. # Only act if called via MySensors by discovery event.
# Otherwise gateway is not setup. # Otherwise gateway is not setup.
if not discovery_info: if not discovery_info:
return return
@ -627,7 +622,7 @@ class MySensorsEntity(MySensorsDevice, Entity):
@property @property
def should_poll(self): def should_poll(self):
"""Mysensor gateway pushes its state to HA.""" """Return the polling state. The gateway pushes its states."""
return False return False
@property @property

View file

@ -129,7 +129,7 @@ class PushBulletNotificationService(BaseNotificationService):
continue continue
def _push_data(self, message, title, data, pusher, email=None): def _push_data(self, message, title, data, pusher, email=None):
"""Helper for creating the message content.""" """Create the message content."""
from pushbullet import PushError from pushbullet import PushError
if data is None: if data is None:
data = {} data = {}

View file

@ -12,11 +12,11 @@ import time
import voluptuous as vol import voluptuous as vol
import homeassistant.util.dt as dt_util
from homeassistant.const import SERVICE_RELOAD from homeassistant.const import SERVICE_RELOAD
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.loader import bind_hass from homeassistant.loader import bind_hass
from homeassistant.util import sanitize_filename from homeassistant.util import sanitize_filename
import homeassistant.util.dt as dt_util
REQUIREMENTS = ['restrictedpython==4.0b2'] REQUIREMENTS = ['restrictedpython==4.0b2']
@ -185,7 +185,7 @@ class StubPrinter:
class TimeWrapper: class TimeWrapper:
"""Wrapper of the time module.""" """Wrap the time module."""
# Class variable, only going to warn once per Home Assistant run # Class variable, only going to warn once per Home Assistant run
warned = False warned = False
@ -205,7 +205,7 @@ class TimeWrapper:
attribute = getattr(time, attr) attribute = getattr(time, attr)
if callable(attribute): if callable(attribute):
def wrapper(*args, **kw): def wrapper(*args, **kw):
"""Wrapper to return callable method if callable.""" """Wrap to return callable method if callable."""
return attribute(*args, **kw) return attribute(*args, **kw)
return wrapper return wrapper
else: else:

View file

@ -5,20 +5,19 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/raincloud/ https://home-assistant.io/components/raincloud/
""" """
import asyncio import asyncio
import logging
from datetime import timedelta from datetime import timedelta
import logging
from requests.exceptions import ConnectTimeout, HTTPError
import voluptuous as vol import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.const import ( from homeassistant.const import (
ATTR_ATTRIBUTION, CONF_USERNAME, CONF_PASSWORD, CONF_SCAN_INTERVAL) ATTR_ATTRIBUTION, CONF_PASSWORD, CONF_SCAN_INTERVAL, CONF_USERNAME)
from homeassistant.helpers.event import track_time_interval import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.dispatcher import ( from homeassistant.helpers.dispatcher import (
async_dispatcher_connect, dispatcher_send) async_dispatcher_connect, dispatcher_send)
from homeassistant.helpers.entity import Entity
from requests.exceptions import HTTPError, ConnectTimeout from homeassistant.helpers.event import track_time_interval
REQUIREMENTS = ['raincloudy==0.0.4'] REQUIREMENTS = ['raincloudy==0.0.4']
@ -115,7 +114,7 @@ def setup(hass, config):
def hub_refresh(event_time): def hub_refresh(event_time):
"""Call Raincloud hub to refresh information.""" """Call Raincloud hub to refresh information."""
_LOGGER.debug("Updating RainCloud Hub component.") _LOGGER.debug("Updating RainCloud Hub component")
hass.data[DATA_RAINCLOUD].data.update() hass.data[DATA_RAINCLOUD].data.update()
dispatcher_send(hass, SIGNAL_UPDATE_RAINCLOUD) dispatcher_send(hass, SIGNAL_UPDATE_RAINCLOUD)
@ -156,7 +155,7 @@ class RainCloudEntity(Entity):
self.hass, SIGNAL_UPDATE_RAINCLOUD, self._update_callback) self.hass, SIGNAL_UPDATE_RAINCLOUD, self._update_callback)
def _update_callback(self): def _update_callback(self):
"""Callback update method.""" """Call update method."""
self.schedule_update_ha_state(True) self.schedule_update_ha_state(True)
@property @property
@ -175,5 +174,5 @@ class RainCloudEntity(Entity):
@property @property
def icon(self): def icon(self):
"""Icon to use in the frontend, if any.""" """Return the icon to use in the frontend, if any."""
return ICON_MAP.get(self._sensor_type) return ICON_MAP.get(self._sensor_type)

View file

@ -9,11 +9,9 @@ import threading
import time import time
from homeassistant.const import ( from homeassistant.const import (
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)
)
REQUIREMENTS = ['raspihats==2.2.3', REQUIREMENTS = ['raspihats==2.2.3', 'smbus-cffi==0.5.1']
'smbus-cffi==0.5.1']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -37,7 +35,7 @@ I2C_HATS_MANAGER = 'I2CH_MNG'
# pylint: disable=unused-argument # pylint: disable=unused-argument
def setup(hass, config): def setup(hass, config):
"""Setup the raspihats component.""" """Set up the raspihats component."""
hass.data[I2C_HATS_MANAGER] = I2CHatsManager() hass.data[I2C_HATS_MANAGER] = I2CHatsManager()
def start_i2c_hats_keep_alive(event): def start_i2c_hats_keep_alive(event):
@ -73,13 +71,13 @@ class I2CHatsDIScanner(object):
_CALLBACKS = "callbacks" _CALLBACKS = "callbacks"
def setup(self, i2c_hat): def setup(self, i2c_hat):
"""Setup I2C-HAT instance for digital inputs scanner.""" """Set up the I2C-HAT instance for digital inputs scanner."""
if hasattr(i2c_hat, self._DIGITAL_INPUTS): if hasattr(i2c_hat, self._DIGITAL_INPUTS):
digital_inputs = getattr(i2c_hat, self._DIGITAL_INPUTS) digital_inputs = getattr(i2c_hat, self._DIGITAL_INPUTS)
old_value = None old_value = None
# add old value attribute # Add old value attribute
setattr(digital_inputs, self._OLD_VALUE, old_value) setattr(digital_inputs, self._OLD_VALUE, old_value)
# add callbacks dict attribute {channel: callback} # Add callbacks dict attribute {channel: callback}
setattr(digital_inputs, self._CALLBACKS, {}) setattr(digital_inputs, self._CALLBACKS, {})
def register_callback(self, i2c_hat, channel, callback): def register_callback(self, i2c_hat, channel, callback):
@ -141,17 +139,15 @@ class I2CHatsManager(threading.Thread):
self._i2c_hats[address] = i2c_hat self._i2c_hats[address] = i2c_hat
status_word = i2c_hat.status # read status_word to reset bits status_word = i2c_hat.status # read status_word to reset bits
_LOGGER.info( _LOGGER.info(
log_message(self, i2c_hat, "registered", status_word) log_message(self, i2c_hat, "registered", status_word))
)
def run(self): def run(self):
"""Keep alive for I2C-HATs.""" """Keep alive for I2C-HATs."""
# pylint: disable=import-error # pylint: disable=import-error
from raspihats.i2c_hats import ResponseException from raspihats.i2c_hats import ResponseException
_LOGGER.info( _LOGGER.info(log_message(self, "starting"))
log_message(self, "starting")
)
while self._run: while self._run:
with self._lock: with self._lock:
for i2c_hat in list(self._i2c_hats.values()): for i2c_hat in list(self._i2c_hats.values()):
@ -176,17 +172,13 @@ class I2CHatsManager(threading.Thread):
) )
setattr(i2c_hat, self._EXCEPTION, ex) setattr(i2c_hat, self._EXCEPTION, ex)
time.sleep(0.05) time.sleep(0.05)
_LOGGER.info( _LOGGER.info(log_message(self, "exiting"))
log_message(self, "exiting")
)
def _read_status(self, i2c_hat): def _read_status(self, i2c_hat):
"""Read I2C-HATs status.""" """Read I2C-HATs status."""
status_word = i2c_hat.status status_word = i2c_hat.status
if status_word.value != 0x00: if status_word.value != 0x00:
_LOGGER.error( _LOGGER.error(log_message(self, i2c_hat, status_word))
log_message(self, i2c_hat, status_word)
)
def start_keep_alive(self): def start_keep_alive(self):
"""Start keep alive mechanism.""" """Start keep alive mechanism."""

View file

@ -1,21 +1,17 @@
"""Component to interact with Remember The Milk. """
Component to interact with Remember The Milk.
For more details about this component, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/remember_the_milk/ https://home-assistant.io/components/remember_the_milk/
Minimum viable product, it currently only support creating new tasks in your
Remember The Milk (https://www.rememberthemilk.com/) account.
This product uses the Remember The Milk API but is not endorsed or certified
by Remember The Milk.
""" """
import json
import logging import logging
import os import os
import json
import voluptuous as vol import voluptuous as vol
from homeassistant.const import (CONF_API_KEY, STATE_OK, CONF_TOKEN, from homeassistant.const import (
CONF_NAME, CONF_ID) CONF_API_KEY, CONF_ID, CONF_NAME, CONF_TOKEN, STATE_OK)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
@ -61,9 +57,9 @@ SERVICE_SCHEMA_COMPLETE_TASK = vol.Schema({
def setup(hass, config): def setup(hass, config):
"""Set up the remember_the_milk component.""" """Set up the Remember the milk component."""
component = EntityComponent(_LOGGER, DOMAIN, hass, component = EntityComponent(
group_name=GROUP_NAME_RTM) _LOGGER, DOMAIN, hass, group_name=GROUP_NAME_RTM)
stored_rtm_config = RememberTheMilkConfiguration(hass) stored_rtm_config = RememberTheMilkConfiguration(hass)
for rtm_config in config[DOMAIN]: for rtm_config in config[DOMAIN]:
@ -107,21 +103,21 @@ def _register_new_account(hass, account_name, api_key, shared_secret,
configurator = hass.components.configurator configurator = hass.components.configurator
api = Rtm(api_key, shared_secret, "write", None) api = Rtm(api_key, shared_secret, "write", None)
url, frob = api.authenticate_desktop() url, frob = api.authenticate_desktop()
_LOGGER.debug('sent authentication request to server') _LOGGER.debug("Sent authentication request to server")
def register_account_callback(_): def register_account_callback(_):
"""Callback for configurator.""" """Call for register the configurator."""
api.retrieve_token(frob) api.retrieve_token(frob)
token = api.token token = api.token
if api.token is None: if api.token is None:
_LOGGER.error('Failed to register, please try again.') _LOGGER.error("Failed to register, please try again")
configurator.notify_errors( configurator.notify_errors(
request_id, request_id,
'Failed to register, please try again.') 'Failed to register, please try again.')
return return
stored_rtm_config.set_token(account_name, token) stored_rtm_config.set_token(account_name, token)
_LOGGER.debug('retrieved new token from server') _LOGGER.debug("Retrieved new token from server")
_create_instance( _create_instance(
hass, account_name, api_key, shared_secret, token, hass, account_name, api_key, shared_secret, token,
@ -155,13 +151,13 @@ class RememberTheMilkConfiguration(object):
self._config = dict() self._config = dict()
return return
try: try:
_LOGGER.debug('loading configuration from file: %s', _LOGGER.debug("Loading configuration from file: %s",
self._config_file_path) self._config_file_path)
with open(self._config_file_path, 'r') as config_file: with open(self._config_file_path, 'r') as config_file:
self._config = json.load(config_file) self._config = json.load(config_file)
except ValueError: except ValueError:
_LOGGER.error('failed to load configuration file, creating a ' _LOGGER.error("Failed to load configuration file, creating a "
'new one: %s', self._config_file_path) "new one: %s", self._config_file_path)
self._config = dict() self._config = dict()
def save_config(self): def save_config(self):
@ -197,9 +193,9 @@ class RememberTheMilkConfiguration(object):
self._config[profile_name][CONF_ID_MAP] = dict() self._config[profile_name][CONF_ID_MAP] = dict()
def get_rtm_id(self, profile_name, hass_id): def get_rtm_id(self, profile_name, hass_id):
"""Get the rtm ids for a home assistant task id. """Get the RTM ids for a Home Assistant task ID.
The id of a rtm tasks consists of the tuple: The id of a RTM tasks consists of the tuple:
list id, timeseries id and the task id. list id, timeseries id and the task id.
""" """
self._initialize_profile(profile_name) self._initialize_profile(profile_name)
@ -210,7 +206,7 @@ class RememberTheMilkConfiguration(object):
def set_rtm_id(self, profile_name, hass_id, list_id, time_series_id, def set_rtm_id(self, profile_name, hass_id, list_id, time_series_id,
rtm_task_id): rtm_task_id):
"""Add/Update the rtm task id for a home assistant task id.""" """Add/Update the RTM task ID for a Home Assistant task IS."""
self._initialize_profile(profile_name) self._initialize_profile(profile_name)
id_tuple = { id_tuple = {
CONF_LIST_ID: list_id, CONF_LIST_ID: list_id,
@ -229,7 +225,7 @@ class RememberTheMilkConfiguration(object):
class RememberTheMilk(Entity): class RememberTheMilk(Entity):
"""MVP implementation of an interface to Remember The Milk.""" """Representation of an interface to Remember The Milk."""
def __init__(self, name, api_key, shared_secret, token, rtm_config): def __init__(self, name, api_key, shared_secret, token, rtm_config):
"""Create new instance of Remember The Milk component.""" """Create new instance of Remember The Milk component."""
@ -243,7 +239,7 @@ class RememberTheMilk(Entity):
self._rtm_api = rtmapi.Rtm(api_key, shared_secret, "delete", token) self._rtm_api = rtmapi.Rtm(api_key, shared_secret, "delete", token)
self._token_valid = None self._token_valid = None
self._check_token() self._check_token()
_LOGGER.debug("instance created for account %s", self._name) _LOGGER.debug("Instance created for account %s", self._name)
def _check_token(self): def _check_token(self):
"""Check if the API token is still valid. """Check if the API token is still valid.
@ -253,8 +249,8 @@ class RememberTheMilk(Entity):
""" """
valid = self._rtm_api.token_valid() valid = self._rtm_api.token_valid()
if not valid: if not valid:
_LOGGER.error('Token for account %s is invalid. You need to ' _LOGGER.error("Token for account %s is invalid. You need to "
'register again!', self.name) "register again!", self.name)
self._rtm_config.delete_token(self._name) self._rtm_config.delete_token(self._name)
self._token_valid = False self._token_valid = False
else: else:
@ -264,7 +260,7 @@ class RememberTheMilk(Entity):
def create_task(self, call): def create_task(self, call):
"""Create a new task on Remember The Milk. """Create a new task on Remember The Milk.
You can use the smart syntax to define the attribues of a new task, You can use the smart syntax to define the attributes of a new task,
e.g. "my task #some_tag ^today" will add tag "some_tag" and set the e.g. "my task #some_tag ^today" will add tag "some_tag" and set the
due date to today. due date to today.
""" """
@ -282,25 +278,20 @@ class RememberTheMilk(Entity):
if hass_id is None or rtm_id is None: if hass_id is None or rtm_id is None:
result = self._rtm_api.rtm.tasks.add( result = self._rtm_api.rtm.tasks.add(
timeline=timeline, name=task_name, parse='1') timeline=timeline, name=task_name, parse='1')
_LOGGER.debug('created new task "%s" in account %s', _LOGGER.debug("Created new task '%s' in account %s",
task_name, self.name) task_name, self.name)
self._rtm_config.set_rtm_id(self._name, self._rtm_config.set_rtm_id(
hass_id, self._name, hass_id, result.list.id,
result.list.id, result.list.taskseries.id, result.list.taskseries.task.id)
result.list.taskseries.id,
result.list.taskseries.task.id)
else: else:
self._rtm_api.rtm.tasks.setName(name=task_name, self._rtm_api.rtm.tasks.setName(
list_id=rtm_id[0], name=task_name, list_id=rtm_id[0], taskseries_id=rtm_id[1],
taskseries_id=rtm_id[1], task_id=rtm_id[2], timeline=timeline)
task_id=rtm_id[2], _LOGGER.debug("Updated task with id '%s' in account "
timeline=timeline) "%s to name %s", hass_id, self.name, task_name)
_LOGGER.debug('updated task with id "%s" in account '
'%s to name %s',
hass_id, self.name, task_name)
except rtmapi.RtmRequestFailedException as rtm_exception: except rtmapi.RtmRequestFailedException as rtm_exception:
_LOGGER.error('Error creating new Remember The Milk task for ' _LOGGER.error("Error creating new Remember The Milk task for "
'account %s: %s', self._name, rtm_exception) "account %s: %s", self._name, rtm_exception)
return False return False
return True return True
@ -311,23 +302,21 @@ class RememberTheMilk(Entity):
hass_id = call.data.get(CONF_ID) hass_id = call.data.get(CONF_ID)
rtm_id = self._rtm_config.get_rtm_id(self._name, hass_id) rtm_id = self._rtm_config.get_rtm_id(self._name, hass_id)
if rtm_id is None: if rtm_id is None:
_LOGGER.error('Could not find task with id %s in account %s. ' _LOGGER.error("Could not find task with ID %s in account %s. "
'So task could not be closed.', "So task could not be closed", hass_id, self._name)
hass_id, self._name)
return False return False
try: try:
result = self._rtm_api.rtm.timelines.create() result = self._rtm_api.rtm.timelines.create()
timeline = result.timeline.value timeline = result.timeline.value
self._rtm_api.rtm.tasks.complete(list_id=rtm_id[0], self._rtm_api.rtm.tasks.complete(
taskseries_id=rtm_id[1], list_id=rtm_id[0], taskseries_id=rtm_id[1], task_id=rtm_id[2],
task_id=rtm_id[2], timeline=timeline)
timeline=timeline)
self._rtm_config.delete_rtm_id(self._name, hass_id) self._rtm_config.delete_rtm_id(self._name, hass_id)
_LOGGER.debug('Completed task with id %s in account %s', _LOGGER.debug("Completed task with id %s in account %s",
hass_id, self._name) hass_id, self._name)
except rtmapi.RtmRequestFailedException as rtm_exception: except rtmapi.RtmRequestFailedException as rtm_exception:
_LOGGER.error('Error creating new Remember The Milk task for ' _LOGGER.error("Error creating new Remember The Milk task for "
'account %s: %s', self._name, rtm_exception) "account %s: %s", self._name, rtm_exception)
return True return True
@property @property
@ -339,5 +328,5 @@ class RememberTheMilk(Entity):
def state(self): def state(self):
"""Return the state of the device.""" """Return the state of the device."""
if not self._token_valid: if not self._token_valid:
return 'API token invalid' return "API token invalid"
return STATE_OK return STATE_OK

View file

@ -4,19 +4,19 @@ Support for Harmony Hub devices.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/remote.harmony/ https://home-assistant.io/components/remote.harmony/
""" """
import logging
import asyncio import asyncio
import logging
import time import time
import voluptuous as vol import voluptuous as vol
import homeassistant.components.remote as remote import homeassistant.components.remote as remote
import homeassistant.helpers.config_validation as cv
from homeassistant.const import (
CONF_NAME, CONF_HOST, CONF_PORT, ATTR_ENTITY_ID, EVENT_HOMEASSISTANT_STOP)
from homeassistant.components.remote import ( from homeassistant.components.remote import (
PLATFORM_SCHEMA, DOMAIN, ATTR_DEVICE, ATTR_ACTIVITY, ATTR_NUM_REPEATS, ATTR_ACTIVITY, ATTR_DELAY_SECS, ATTR_DEVICE, ATTR_NUM_REPEATS,
ATTR_DELAY_SECS, DEFAULT_DELAY_SECS) DEFAULT_DELAY_SECS, DOMAIN, PLATFORM_SCHEMA)
from homeassistant.const import (
ATTR_ENTITY_ID, CONF_HOST, CONF_NAME, CONF_PORT, EVENT_HOMEASSISTANT_STOP)
import homeassistant.helpers.config_validation as cv
from homeassistant.util import slugify from homeassistant.util import slugify
REQUIREMENTS = ['pyharmony==1.0.18'] REQUIREMENTS = ['pyharmony==1.0.18']
@ -30,12 +30,12 @@ CONF_DEVICE_CACHE = 'harmony_device_cache'
SERVICE_SYNC = 'harmony_sync' SERVICE_SYNC = 'harmony_sync'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_NAME): cv.string,
vol.Optional(CONF_HOST): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Required(ATTR_ACTIVITY, default=None): cv.string, vol.Required(ATTR_ACTIVITY, default=None): cv.string,
vol.Required(CONF_NAME): cv.string,
vol.Optional(ATTR_DELAY_SECS, default=DEFAULT_DELAY_SECS): vol.Optional(ATTR_DELAY_SECS, default=DEFAULT_DELAY_SECS):
vol.Coerce(float), vol.Coerce(float),
vol.Optional(CONF_HOST): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
}) })
HARMONY_SYNC_SCHEMA = vol.Schema({ HARMONY_SYNC_SCHEMA = vol.Schema({
@ -182,7 +182,7 @@ class HarmonyRemote(remote.RemoteDevice):
return self._current_activity not in [None, 'PowerOff'] return self._current_activity not in [None, 'PowerOff']
def new_activity(self, activity_id): def new_activity(self, activity_id):
"""Callback for updating the current activity.""" """Call for updating the current activity."""
import pyharmony import pyharmony
activity_name = pyharmony.activity_name(self._config, activity_id) activity_name = pyharmony.activity_name(self._config, activity_id)
_LOGGER.debug("%s activity reported as: %s", self._name, activity_name) _LOGGER.debug("%s activity reported as: %s", self._name, activity_name)

View file

@ -4,15 +4,13 @@ Support for Keene Electronics IR-IP devices.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/remote.kira/ https://home-assistant.io/components/remote.kira/
""" """
import logging
import functools as ft import functools as ft
import logging
import homeassistant.components.remote as remote import homeassistant.components.remote as remote
from homeassistant.const import CONF_DEVICE, CONF_NAME
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.const import (
CONF_DEVICE, CONF_NAME)
DOMAIN = 'kira' DOMAIN = 'kira'
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)

View file

@ -8,10 +8,11 @@ import asyncio
import logging import logging
from homeassistant.components.scene import Scene from homeassistant.components.scene import Scene
from homeassistant.components.wink import WinkDevice, DOMAIN from homeassistant.components.wink import DOMAIN, WinkDevice
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['wink'] DEPENDENCIES = ['wink']
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
@ -34,7 +35,7 @@ class WinkScene(WinkDevice, Scene):
@asyncio.coroutine @asyncio.coroutine
def async_added_to_hass(self): def async_added_to_hass(self):
"""Callback when entity is added to hass.""" """Call when entity is added to hass."""
self.hass.data[DOMAIN]['entities']['scene'].append(self) self.hass.data[DOMAIN]['entities']['scene'].append(self)
@property @property

View file

@ -47,8 +47,8 @@ class AbodeSensor(AbodeDevice):
super().__init__(data, device) super().__init__(data, device)
self._sensor_type = sensor_type self._sensor_type = sensor_type
self._icon = 'mdi:{}'.format(SENSOR_TYPES[self._sensor_type][1]) self._icon = 'mdi:{}'.format(SENSOR_TYPES[self._sensor_type][1])
self._name = '{0} {1}'.format(self._device.name, self._name = '{0} {1}'.format(
SENSOR_TYPES[self._sensor_type][0]) self._device.name, SENSOR_TYPES[self._sensor_type][0])
@property @property
def icon(self): def icon(self):

Some files were not shown because too many files have changed in this diff Show more