commit
43ff95ad3b
709 changed files with 10140 additions and 5554 deletions
22
.coveragerc
22
.coveragerc
|
@ -77,6 +77,9 @@ omit =
|
|||
homeassistant/components/octoprint.py
|
||||
homeassistant/components/*/octoprint.py
|
||||
|
||||
homeassistant/components/opencv.py
|
||||
homeassistant/components/*/opencv.py
|
||||
|
||||
homeassistant/components/qwikswitch.py
|
||||
homeassistant/components/*/qwikswitch.py
|
||||
|
||||
|
@ -154,6 +157,13 @@ omit =
|
|||
homeassistant/components/tado.py
|
||||
homeassistant/components/*/tado.py
|
||||
|
||||
homeassistant/components/zha/__init__.py
|
||||
homeassistant/components/zha/const.py
|
||||
homeassistant/components/*/zha.py
|
||||
|
||||
homeassistant/components/eight_sleep.py
|
||||
homeassistant/components/*/eight_sleep.py
|
||||
|
||||
homeassistant/components/alarm_control_panel/alarmdotcom.py
|
||||
homeassistant/components/alarm_control_panel/concord232.py
|
||||
homeassistant/components/alarm_control_panel/nx584.py
|
||||
|
@ -165,6 +175,7 @@ omit =
|
|||
homeassistant/components/binary_sensor/flic.py
|
||||
homeassistant/components/binary_sensor/hikvision.py
|
||||
homeassistant/components/binary_sensor/iss.py
|
||||
homeassistant/components/binary_sensor/pilight.py
|
||||
homeassistant/components/binary_sensor/ping.py
|
||||
homeassistant/components/binary_sensor/rest.py
|
||||
homeassistant/components/browser.py
|
||||
|
@ -182,15 +193,18 @@ omit =
|
|||
homeassistant/components/climate/oem.py
|
||||
homeassistant/components/climate/proliphix.py
|
||||
homeassistant/components/climate/radiotherm.py
|
||||
homeassistant/components/climate/sensibo.py
|
||||
homeassistant/components/cover/garadget.py
|
||||
homeassistant/components/cover/homematic.py
|
||||
homeassistant/components/cover/myq.py
|
||||
homeassistant/components/cover/opengarage.py
|
||||
homeassistant/components/cover/rpi_gpio.py
|
||||
homeassistant/components/cover/scsgate.py
|
||||
homeassistant/components/cover/wink.py
|
||||
homeassistant/components/device_tracker/actiontec.py
|
||||
homeassistant/components/device_tracker/aruba.py
|
||||
homeassistant/components/device_tracker/asuswrt.py
|
||||
homeassistant/components/device_tracker/automatic.py
|
||||
homeassistant/components/device_tracker/bbox.py
|
||||
homeassistant/components/device_tracker/bluetooth_le_tracker.py
|
||||
homeassistant/components/device_tracker/bluetooth_tracker.py
|
||||
|
@ -201,6 +215,7 @@ omit =
|
|||
homeassistant/components/device_tracker/icloud.py
|
||||
homeassistant/components/device_tracker/linksys_ap.py
|
||||
homeassistant/components/device_tracker/luci.py
|
||||
homeassistant/components/device_tracker/mikrotik.py
|
||||
homeassistant/components/device_tracker/netgear.py
|
||||
homeassistant/components/device_tracker/nmap_tracker.py
|
||||
homeassistant/components/device_tracker/ping.py
|
||||
|
@ -222,10 +237,13 @@ omit =
|
|||
homeassistant/components/foursquare.py
|
||||
homeassistant/components/hdmi_cec.py
|
||||
homeassistant/components/ifttt.py
|
||||
homeassistant/components/image_processing/dlib_face_detect.py
|
||||
homeassistant/components/image_processing/dlib_face_identify.py
|
||||
homeassistant/components/joaoapps_join.py
|
||||
homeassistant/components/keyboard.py
|
||||
homeassistant/components/keyboard_remote.py
|
||||
homeassistant/components/light/avion.py
|
||||
homeassistant/components/light/blinkt.py
|
||||
homeassistant/components/light/blinksticklight.py
|
||||
homeassistant/components/light/decora.py
|
||||
homeassistant/components/light/flux_led.py
|
||||
|
@ -238,6 +256,7 @@ omit =
|
|||
homeassistant/components/light/osramlightify.py
|
||||
homeassistant/components/light/rpi_gpio_pwm.py
|
||||
homeassistant/components/light/piglow.py
|
||||
homeassistant/components/light/sensehat.py
|
||||
homeassistant/components/light/tikteck.py
|
||||
homeassistant/components/light/tradfri.py
|
||||
homeassistant/components/light/x10.py
|
||||
|
@ -335,6 +354,7 @@ omit =
|
|||
homeassistant/components/sensor/broadlink.py
|
||||
homeassistant/components/sensor/dublin_bus_transport.py
|
||||
homeassistant/components/sensor/coinmarketcap.py
|
||||
homeassistant/components/sensor/cert_expiry.py
|
||||
homeassistant/components/sensor/comed_hourly_pricing.py
|
||||
homeassistant/components/sensor/cpuspeed.py
|
||||
homeassistant/components/sensor/crimereports.py
|
||||
|
@ -350,6 +370,7 @@ omit =
|
|||
homeassistant/components/sensor/eddystone_temperature.py
|
||||
homeassistant/components/sensor/eliqonline.py
|
||||
homeassistant/components/sensor/emoncms.py
|
||||
homeassistant/components/sensor/envirophat.py
|
||||
homeassistant/components/sensor/fastdotcom.py
|
||||
homeassistant/components/sensor/fedex.py
|
||||
homeassistant/components/sensor/fido.py
|
||||
|
@ -391,6 +412,7 @@ omit =
|
|||
homeassistant/components/sensor/pi_hole.py
|
||||
homeassistant/components/sensor/plex.py
|
||||
homeassistant/components/sensor/pocketcasts.py
|
||||
homeassistant/components/sensor/pushbullet.py
|
||||
homeassistant/components/sensor/pvoutput.py
|
||||
homeassistant/components/sensor/qnap.py
|
||||
homeassistant/components/sensor/sabnzbd.py
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
"""Starts home assistant."""
|
||||
"""Start Home Assistant."""
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
|
@ -277,7 +277,7 @@ def cmdline() -> List[str]:
|
|||
|
||||
def setup_and_run_hass(config_dir: str,
|
||||
args: argparse.Namespace) -> Optional[int]:
|
||||
"""Setup HASS and run."""
|
||||
"""Set up HASS and run."""
|
||||
from homeassistant import bootstrap
|
||||
|
||||
# Run a simple daemon runner process on Windows to handle restarts
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
"""Provides methods to bootstrap a home assistant instance."""
|
||||
"""Provide methods to bootstrap a Home Assistant instance."""
|
||||
import asyncio
|
||||
import logging
|
||||
import logging.handlers
|
||||
|
@ -206,7 +206,7 @@ def async_from_config_file(config_path: str,
|
|||
@core.callback
|
||||
def async_enable_logging(hass: core.HomeAssistant, verbose: bool=False,
|
||||
log_rotate_days=None) -> None:
|
||||
"""Setup the logging.
|
||||
"""Set up the logging.
|
||||
|
||||
This method must be run in the event loop.
|
||||
"""
|
||||
|
@ -214,12 +214,12 @@ def async_enable_logging(hass: core.HomeAssistant, verbose: bool=False,
|
|||
fmt = ("%(asctime)s %(levelname)s (%(threadName)s) "
|
||||
"[%(name)s] %(message)s")
|
||||
colorfmt = "%(log_color)s{}%(reset)s".format(fmt)
|
||||
datefmt = '%y-%m-%d %H:%M:%S'
|
||||
datefmt = '%Y-%m-%d %H:%M:%S'
|
||||
|
||||
# suppress overly verbose logs from libraries that aren't helpful
|
||||
logging.getLogger("requests").setLevel(logging.WARNING)
|
||||
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
||||
logging.getLogger("aiohttp.access").setLevel(logging.WARNING)
|
||||
# Suppress overly verbose logs from libraries that aren't helpful
|
||||
logging.getLogger('requests').setLevel(logging.WARNING)
|
||||
logging.getLogger('urllib3').setLevel(logging.WARNING)
|
||||
logging.getLogger('aiohttp.access').setLevel(logging.WARNING)
|
||||
|
||||
try:
|
||||
from colorlog import ColoredFormatter
|
||||
|
@ -274,7 +274,7 @@ def async_enable_logging(hass: core.HomeAssistant, verbose: bool=False,
|
|||
|
||||
else:
|
||||
_LOGGER.error(
|
||||
'Unable to setup error log %s (access denied)', err_log_path)
|
||||
"Unable to setup error log %s (access denied)", err_log_path)
|
||||
|
||||
|
||||
def mount_local_lib_path(config_dir: str) -> str:
|
||||
|
|
|
@ -102,10 +102,10 @@ def reload_core_config(hass):
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup(hass, config):
|
||||
"""Setup general services related to Home Assistant."""
|
||||
"""Set up general services related to Home Assistant."""
|
||||
@asyncio.coroutine
|
||||
def async_handle_turn_service(service):
|
||||
"""Method to handle calls to homeassistant.turn_on/off."""
|
||||
"""Handle calls to homeassistant.turn_on/off."""
|
||||
entity_ids = extract_entity_ids(hass, service)
|
||||
|
||||
# Generic turn on/off method requires entity id
|
||||
|
|
|
@ -25,7 +25,7 @@ DEPENDENCIES = ['alarmdecoder']
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Perform the setup for AlarmDecoder alarm panels."""
|
||||
"""Set up for AlarmDecoder alarm panels."""
|
||||
_LOGGER.debug("AlarmDecoderAlarmPanel: setup")
|
||||
|
||||
device = AlarmDecoderAlarmPanel("Alarm Panel", hass)
|
||||
|
@ -44,7 +44,7 @@ class AlarmDecoderAlarmPanel(alarm.AlarmControlPanel):
|
|||
self._name = name
|
||||
self._state = STATE_UNKNOWN
|
||||
|
||||
_LOGGER.debug("AlarmDecoderAlarm: Setting up panel")
|
||||
_LOGGER.debug("Setting up panel")
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_added_to_hass(self):
|
||||
|
@ -78,12 +78,12 @@ class AlarmDecoderAlarmPanel(alarm.AlarmControlPanel):
|
|||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""No polling needed."""
|
||||
"""Return the polling state."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def code_format(self):
|
||||
"""Regex for code format or None if no code is required."""
|
||||
"""Return the regex for code format or None if no code is required."""
|
||||
return '^\\d{4,6}$'
|
||||
|
||||
@property
|
||||
|
@ -94,26 +94,23 @@ class AlarmDecoderAlarmPanel(alarm.AlarmControlPanel):
|
|||
@asyncio.coroutine
|
||||
def async_alarm_disarm(self, code=None):
|
||||
"""Send disarm command."""
|
||||
_LOGGER.debug("AlarmDecoderAlarm::alarm_disarm: %s", code)
|
||||
_LOGGER.debug("alarm_disarm: %s", code)
|
||||
if code:
|
||||
_LOGGER.debug("AlarmDecoderAlarm::alarm_disarm: sending %s1",
|
||||
str(code))
|
||||
_LOGGER.debug("alarm_disarm: sending %s1", str(code))
|
||||
self.hass.data[DATA_AD].send("{!s}1".format(code))
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_alarm_arm_away(self, code=None):
|
||||
"""Send arm away command."""
|
||||
_LOGGER.debug("AlarmDecoderAlarm::alarm_arm_away: %s", code)
|
||||
_LOGGER.debug("alarm_arm_away: %s", code)
|
||||
if code:
|
||||
_LOGGER.debug("AlarmDecoderAlarm::alarm_arm_away: sending %s2",
|
||||
str(code))
|
||||
_LOGGER.debug("alarm_arm_away: sending %s2", str(code))
|
||||
self.hass.data[DATA_AD].send("{!s}2".format(code))
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_alarm_arm_home(self, code=None):
|
||||
"""Send arm home command."""
|
||||
_LOGGER.debug("AlarmDecoderAlarm::alarm_arm_home: %s", code)
|
||||
_LOGGER.debug("alarm_arm_home: %s", code)
|
||||
if code:
|
||||
_LOGGER.debug("AlarmDecoderAlarm::alarm_arm_home: sending %s3",
|
||||
str(code))
|
||||
_LOGGER.debug("alarm_arm_home: sending %s3", str(code))
|
||||
self.hass.data[DATA_AD].send("{!s}3".format(code))
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
"""
|
||||
|
||||
Interfaces with Alarm.com alarm control panels.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
|
@ -33,7 +32,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup a Alarm.com control panel."""
|
||||
"""Set up a Alarm.com control panel."""
|
||||
name = config.get(CONF_NAME)
|
||||
code = config.get(CONF_CODE)
|
||||
username = config.get(CONF_USERNAME)
|
||||
|
|
|
@ -51,7 +51,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
|
||||
|
||||
class Concord232Alarm(alarm.AlarmControlPanel):
|
||||
"""Represents the Concord232-based alarm panel."""
|
||||
"""Representation of the Concord232-based alarm panel."""
|
||||
|
||||
def __init__(self, hass, url, name):
|
||||
"""Initialize the Concord232 alarm panel."""
|
||||
|
@ -79,7 +79,7 @@ class Concord232Alarm(alarm.AlarmControlPanel):
|
|||
|
||||
@property
|
||||
def code_format(self):
|
||||
"""The characters if code is defined."""
|
||||
"""Return the characters if code is defined."""
|
||||
return '[0-9]{4}([0-9]{2})?'
|
||||
|
||||
@property
|
||||
|
|
|
@ -8,7 +8,7 @@ import homeassistant.components.alarm_control_panel.manual as manual
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Demo alarm control panel platform."""
|
||||
"""Set up the Demo alarm control panel platform."""
|
||||
add_devices([
|
||||
manual.ManualAlarm(hass, 'Alarm', '1234', 5, 10, False),
|
||||
])
|
||||
|
|
|
@ -104,7 +104,7 @@ class EnvisalinkAlarm(EnvisalinkDevice, alarm.AlarmControlPanel):
|
|||
|
||||
@callback
|
||||
def _update_callback(self, partition):
|
||||
"""Update HA state, if needed."""
|
||||
"""Update Home Assistant state, if needed."""
|
||||
if partition is None or int(partition) == self._partition_number:
|
||||
self.hass.async_add_job(self.async_update_ha_state())
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the manual alarm platform."""
|
||||
"""Set up the manual alarm platform."""
|
||||
add_devices([ManualAlarm(
|
||||
hass,
|
||||
config[CONF_NAME],
|
||||
|
@ -52,7 +52,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
|
||||
class ManualAlarm(alarm.AlarmControlPanel):
|
||||
"""
|
||||
Represents an alarm status.
|
||||
Representation of an alarm status.
|
||||
|
||||
When armed, will be pending for 'pending_time', after that armed.
|
||||
When triggered, will be pending for 'trigger_time'. After that will be
|
||||
|
@ -62,7 +62,7 @@ class ManualAlarm(alarm.AlarmControlPanel):
|
|||
|
||||
def __init__(self, hass, name, code, pending_time,
|
||||
trigger_time, disarm_after_trigger):
|
||||
"""Initalize the manual alarm panel."""
|
||||
"""Init the manual alarm panel."""
|
||||
self._state = STATE_ALARM_DISARMED
|
||||
self._hass = hass
|
||||
self._name = name
|
||||
|
@ -75,7 +75,7 @@ class ManualAlarm(alarm.AlarmControlPanel):
|
|||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""No polling needed."""
|
||||
"""Return the plling state."""
|
||||
return False
|
||||
|
||||
@property
|
||||
|
@ -166,5 +166,5 @@ class ManualAlarm(alarm.AlarmControlPanel):
|
|||
"""Validate given code."""
|
||||
check = self._code is None or code == self._code
|
||||
if not check:
|
||||
_LOGGER.warning('Invalid code given for %s', state)
|
||||
_LOGGER.warning("Invalid code given for %s", state)
|
||||
return check
|
||||
|
|
|
@ -45,7 +45,7 @@ PLATFORM_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend({
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup the MQTT platform."""
|
||||
"""Set up the MQTT Alarm Control Panel platform."""
|
||||
async_add_devices([MqttAlarm(
|
||||
config.get(CONF_NAME),
|
||||
config.get(CONF_STATE_TOPIC),
|
||||
|
@ -62,7 +62,7 @@ class MqttAlarm(alarm.AlarmControlPanel):
|
|||
|
||||
def __init__(self, name, state_topic, command_topic, qos, payload_disarm,
|
||||
payload_arm_home, payload_arm_away, code):
|
||||
"""Initalize the MQTT alarm panel."""
|
||||
"""Init the MQTT Alarm Control Panel."""
|
||||
self._state = STATE_UNKNOWN
|
||||
self._name = name
|
||||
self._state_topic = state_topic
|
||||
|
@ -80,11 +80,11 @@ class MqttAlarm(alarm.AlarmControlPanel):
|
|||
"""
|
||||
@callback
|
||||
def message_received(topic, payload, qos):
|
||||
"""A new MQTT message has been received."""
|
||||
"""Run when new MQTT message has been received."""
|
||||
if payload not in (STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME,
|
||||
STATE_ALARM_ARMED_AWAY, STATE_ALARM_PENDING,
|
||||
STATE_ALARM_TRIGGERED):
|
||||
_LOGGER.warning('Received unexpected payload: %s', payload)
|
||||
_LOGGER.warning("Received unexpected payload: %s", payload)
|
||||
return
|
||||
self._state = payload
|
||||
self.hass.async_add_job(self.async_update_ha_state())
|
||||
|
|
|
@ -32,7 +32,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup nx584 platform."""
|
||||
"""Set up the nx584 platform."""
|
||||
name = config.get(CONF_NAME)
|
||||
host = config.get(CONF_HOST)
|
||||
port = config.get(CONF_PORT)
|
||||
|
@ -42,15 +42,15 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
try:
|
||||
add_devices([NX584Alarm(hass, url, name)])
|
||||
except requests.exceptions.ConnectionError as ex:
|
||||
_LOGGER.error('Unable to connect to NX584: %s', str(ex))
|
||||
_LOGGER.error("Unable to connect to NX584: %s", str(ex))
|
||||
return False
|
||||
|
||||
|
||||
class NX584Alarm(alarm.AlarmControlPanel):
|
||||
"""Represents the NX584-based alarm panel."""
|
||||
"""Representation of a NX584-based alarm panel."""
|
||||
|
||||
def __init__(self, hass, url, name):
|
||||
"""Initalize the nx584 alarm panel."""
|
||||
"""Init the nx584 alarm panel."""
|
||||
from nx584 import client
|
||||
self._hass = hass
|
||||
self._name = name
|
||||
|
@ -69,7 +69,7 @@ class NX584Alarm(alarm.AlarmControlPanel):
|
|||
|
||||
@property
|
||||
def code_format(self):
|
||||
"""The characters if code is defined."""
|
||||
"""Return che characters if code is defined."""
|
||||
return '[0-9]{4}([0-9]{2})?'
|
||||
|
||||
@property
|
||||
|
@ -83,20 +83,19 @@ class NX584Alarm(alarm.AlarmControlPanel):
|
|||
part = self._alarm.list_partitions()[0]
|
||||
zones = self._alarm.list_zones()
|
||||
except requests.exceptions.ConnectionError as ex:
|
||||
_LOGGER.error('Unable to connect to %(host)s: %(reason)s',
|
||||
_LOGGER.error("Unable to connect to %(host)s: %(reason)s",
|
||||
dict(host=self._url, reason=ex))
|
||||
self._state = STATE_UNKNOWN
|
||||
zones = []
|
||||
except IndexError:
|
||||
_LOGGER.error('nx584 reports no partitions')
|
||||
_LOGGER.error("nx584 reports no partitions")
|
||||
self._state = STATE_UNKNOWN
|
||||
zones = []
|
||||
|
||||
bypassed = False
|
||||
for zone in zones:
|
||||
if zone['bypassed']:
|
||||
_LOGGER.debug('Zone %(zone)s is bypassed, '
|
||||
'assuming HOME',
|
||||
_LOGGER.debug("Zone %(zone)s is bypassed, assuming HOME",
|
||||
dict(zone=zone['number']))
|
||||
bypassed = True
|
||||
break
|
||||
|
|
|
@ -123,25 +123,25 @@ class SimpliSafeAlarm(alarm.AlarmControlPanel):
|
|||
if not self._validate_code(code, 'disarming'):
|
||||
return
|
||||
self.simplisafe.set_state('off')
|
||||
_LOGGER.info('SimpliSafe alarm disarming')
|
||||
_LOGGER.info("SimpliSafe alarm disarming")
|
||||
|
||||
def alarm_arm_home(self, code=None):
|
||||
"""Send arm home command."""
|
||||
if not self._validate_code(code, 'arming home'):
|
||||
return
|
||||
self.simplisafe.set_state('home')
|
||||
_LOGGER.info('SimpliSafe alarm arming home')
|
||||
_LOGGER.info("SimpliSafe alarm arming home")
|
||||
|
||||
def alarm_arm_away(self, code=None):
|
||||
"""Send arm away command."""
|
||||
if not self._validate_code(code, 'arming away'):
|
||||
return
|
||||
self.simplisafe.set_state('away')
|
||||
_LOGGER.info('SimpliSafe alarm arming away')
|
||||
_LOGGER.info("SimpliSafe alarm arming away")
|
||||
|
||||
def _validate_code(self, code, state):
|
||||
"""Validate given code."""
|
||||
check = self._code is None or code == self._code
|
||||
if not check:
|
||||
_LOGGER.warning('Wrong code entered for %s', state)
|
||||
_LOGGER.warning("Wrong code entered for %s", state)
|
||||
return check
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
"""Interfaces with TotalConnect alarm control panels."""
|
||||
"""
|
||||
Interfaces with TotalConnect alarm control panels.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/alarm_control_panel.totalconnect/
|
||||
"""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
import homeassistant.components.alarm_control_panel as alarm
|
||||
from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA
|
||||
from homeassistant.const import (
|
||||
CONF_PASSWORD, CONF_USERNAME, STATE_ALARM_ARMED_AWAY,
|
||||
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_UNKNOWN,
|
||||
CONF_NAME)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
REQUIREMENTS = ['total_connect_client==0.7']
|
||||
|
||||
|
@ -25,7 +30,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup a TotalConnect control panel."""
|
||||
"""Set up a TotalConnect control panel."""
|
||||
name = config.get(CONF_NAME)
|
||||
username = config.get(CONF_USERNAME)
|
||||
password = config.get(CONF_PASSWORD)
|
||||
|
@ -41,13 +46,13 @@ class TotalConnect(alarm.AlarmControlPanel):
|
|||
"""Initialize the TotalConnect status."""
|
||||
from total_connect_client import TotalConnectClient
|
||||
|
||||
_LOGGER.debug('Setting up TotalConnect...')
|
||||
_LOGGER.debug("Setting up TotalConnect...")
|
||||
self._name = name
|
||||
self._username = username
|
||||
self._password = password
|
||||
self._state = STATE_UNKNOWN
|
||||
self._client = TotalConnectClient.TotalConnectClient(username,
|
||||
password)
|
||||
self._client = TotalConnectClient.TotalConnectClient(
|
||||
username, password)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
|
|
@ -17,7 +17,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Verisure platform."""
|
||||
"""Set up the Verisure platform."""
|
||||
alarms = []
|
||||
if int(hub.config.get(CONF_ALARM, 1)):
|
||||
hub.update_alarms()
|
||||
|
@ -29,10 +29,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
|
||||
|
||||
class VerisureAlarm(alarm.AlarmControlPanel):
|
||||
"""Represent a Verisure alarm status."""
|
||||
"""Representation of a Verisure alarm status."""
|
||||
|
||||
def __init__(self, device_id):
|
||||
"""Initalize the Verisure alarm panel."""
|
||||
"""Initialize the Verisure alarm panel."""
|
||||
self._id = device_id
|
||||
self._state = STATE_UNKNOWN
|
||||
self._digits = hub.config.get(CONF_CODE_DIGITS)
|
||||
|
@ -55,12 +55,12 @@ class VerisureAlarm(alarm.AlarmControlPanel):
|
|||
|
||||
@property
|
||||
def code_format(self):
|
||||
"""The code format as regex."""
|
||||
"""Return the code format as regex."""
|
||||
return '^\\d{%s}$' % self._digits
|
||||
|
||||
@property
|
||||
def changed_by(self):
|
||||
"""Last change triggered by."""
|
||||
"""Return the last change triggered by."""
|
||||
return self._changed_by
|
||||
|
||||
def update(self):
|
||||
|
@ -75,24 +75,23 @@ class VerisureAlarm(alarm.AlarmControlPanel):
|
|||
self._state = STATE_ALARM_ARMED_AWAY
|
||||
elif hub.alarm_status[self._id].status != 'pending':
|
||||
_LOGGER.error(
|
||||
'Unknown alarm state %s',
|
||||
hub.alarm_status[self._id].status)
|
||||
"Unknown alarm state %s", hub.alarm_status[self._id].status)
|
||||
self._changed_by = hub.alarm_status[self._id].name
|
||||
|
||||
def alarm_disarm(self, code=None):
|
||||
"""Send disarm command."""
|
||||
hub.my_pages.alarm.set(code, 'DISARMED')
|
||||
_LOGGER.info('verisure alarm disarming')
|
||||
_LOGGER.info("Verisure alarm disarming")
|
||||
hub.my_pages.alarm.wait_while_pending()
|
||||
|
||||
def alarm_arm_home(self, code=None):
|
||||
"""Send arm home command."""
|
||||
hub.my_pages.alarm.set(code, 'ARMED_HOME')
|
||||
_LOGGER.info('verisure alarm arming home')
|
||||
_LOGGER.info("Verisure alarm arming home")
|
||||
hub.my_pages.alarm.wait_while_pending()
|
||||
|
||||
def alarm_arm_away(self, code=None):
|
||||
"""Send arm away command."""
|
||||
hub.my_pages.alarm.set(code, 'ARMED_AWAY')
|
||||
_LOGGER.info('verisure alarm arming away')
|
||||
_LOGGER.info("Verisure alarm arming away")
|
||||
hub.my_pages.alarm.wait_while_pending()
|
||||
|
|
|
@ -16,11 +16,12 @@ from homeassistant.components.wink import WinkDevice, DOMAIN
|
|||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['wink']
|
||||
|
||||
STATE_ALARM_PRIVACY = 'Private'
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Wink platform."""
|
||||
"""Set up the Wink platform."""
|
||||
import pywink
|
||||
|
||||
for camera in pywink.get_cameras():
|
||||
|
|
|
@ -8,11 +8,10 @@ import asyncio
|
|||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
|
||||
|
||||
from homeassistant.helpers.discovery import async_load_platform
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
|
||||
|
@ -24,19 +23,16 @@ DOMAIN = 'alarmdecoder'
|
|||
|
||||
DATA_AD = 'alarmdecoder'
|
||||
|
||||
|
||||
CONF_DEVICE = 'device'
|
||||
CONF_DEVICE_TYPE = 'type'
|
||||
CONF_DEVICE_HOST = 'host'
|
||||
CONF_DEVICE_PORT = 'port'
|
||||
CONF_DEVICE_PATH = 'path'
|
||||
CONF_DEVICE_BAUD = 'baudrate'
|
||||
|
||||
CONF_ZONES = 'zones'
|
||||
CONF_DEVICE_HOST = 'host'
|
||||
CONF_DEVICE_PATH = 'path'
|
||||
CONF_DEVICE_PORT = 'port'
|
||||
CONF_DEVICE_TYPE = 'type'
|
||||
CONF_PANEL_DISPLAY = 'panel_display'
|
||||
CONF_ZONE_NAME = 'name'
|
||||
CONF_ZONE_TYPE = 'type'
|
||||
|
||||
CONF_PANEL_DISPLAY = 'panel_display'
|
||||
CONF_ZONES = 'zones'
|
||||
|
||||
DEFAULT_DEVICE_TYPE = 'socket'
|
||||
DEFAULT_DEVICE_HOST = 'localhost'
|
||||
|
@ -87,7 +83,7 @@ CONFIG_SCHEMA = vol.Schema({
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup(hass, config):
|
||||
"""Common setup for AlarmDecoder devices."""
|
||||
"""Set up for the AlarmDecoder devices."""
|
||||
from alarmdecoder import AlarmDecoder
|
||||
from alarmdecoder.devices import (SocketDevice, SerialDevice, USBDevice)
|
||||
|
||||
|
@ -106,28 +102,28 @@ def async_setup(hass, config):
|
|||
sync_connect = asyncio.Future(loop=hass.loop)
|
||||
|
||||
def handle_open(device):
|
||||
"""Callback for a successful connection."""
|
||||
_LOGGER.info("Established a connection with the alarmdecoder.")
|
||||
"""Handle the successful connection."""
|
||||
_LOGGER.info("Established a connection with the alarmdecoder")
|
||||
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, stop_alarmdecoder)
|
||||
sync_connect.set_result(True)
|
||||
|
||||
@callback
|
||||
def stop_alarmdecoder(event):
|
||||
"""Callback to handle shutdown alarmdecoder."""
|
||||
_LOGGER.debug("Shutting down alarmdecoder.")
|
||||
"""Handle the shutdown of AlarmDecoder."""
|
||||
_LOGGER.debug("Shutting down alarmdecoder")
|
||||
controller.close()
|
||||
|
||||
@callback
|
||||
def handle_message(sender, message):
|
||||
"""Callback to handle message from alarmdecoder."""
|
||||
"""Handle message from AlarmDecoder."""
|
||||
async_dispatcher_send(hass, SIGNAL_PANEL_MESSAGE, message)
|
||||
|
||||
def zone_fault_callback(sender, zone):
|
||||
"""Callback to handle zone fault from alarmdecoder."""
|
||||
"""Handle zone fault from AlarmDecoder."""
|
||||
async_dispatcher_send(hass, SIGNAL_ZONE_FAULT, zone)
|
||||
|
||||
def zone_restore_callback(sender, zone):
|
||||
"""Callback to handle zone restore from alarmdecoder."""
|
||||
"""Handle zone restore from AlarmDecoder."""
|
||||
async_dispatcher_send(hass, SIGNAL_ZONE_RESTORE, zone)
|
||||
|
||||
controller = False
|
||||
|
@ -157,15 +153,16 @@ def async_setup(hass, config):
|
|||
if not result:
|
||||
return False
|
||||
|
||||
hass.async_add_job(async_load_platform(hass, 'alarm_control_panel', DOMAIN,
|
||||
conf, config))
|
||||
hass.async_add_job(
|
||||
async_load_platform(hass, 'alarm_control_panel', DOMAIN, conf,
|
||||
config))
|
||||
|
||||
if zones:
|
||||
hass.async_add_job(async_load_platform(
|
||||
hass, 'binary_sensor', DOMAIN, {CONF_ZONES: zones}, config))
|
||||
|
||||
if display:
|
||||
hass.async_add_job(async_load_platform(hass, 'sensor', DOMAIN,
|
||||
conf, config))
|
||||
hass.async_add_job(async_load_platform(
|
||||
hass, 'sensor', DOMAIN, conf, config))
|
||||
|
||||
return True
|
||||
|
|
|
@ -141,7 +141,7 @@ def reload(hass):
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup(hass, config):
|
||||
"""Setup the automation."""
|
||||
"""Set up the automation."""
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass,
|
||||
group_name=GROUP_NAME_ALL_AUTOMATIONS)
|
||||
|
||||
|
@ -400,7 +400,7 @@ def _async_get_action(hass, config, name):
|
|||
|
||||
@asyncio.coroutine
|
||||
def action(entity_id, variables):
|
||||
"""Action to be executed."""
|
||||
"""Execute an action."""
|
||||
_LOGGER.info('Executing %s', name)
|
||||
logbook.async_log_entry(
|
||||
hass, name, 'has been triggered', DOMAIN, entity_id)
|
||||
|
@ -430,7 +430,7 @@ def _async_process_if(hass, config, p_config):
|
|||
|
||||
@asyncio.coroutine
|
||||
def _async_process_trigger(hass, config, trigger_configs, name, action):
|
||||
"""Setup the triggers.
|
||||
"""Set up the triggers.
|
||||
|
||||
This method is a coroutine.
|
||||
"""
|
||||
|
|
|
@ -13,8 +13,8 @@ from homeassistant.core import callback, CoreState
|
|||
from homeassistant.const import CONF_PLATFORM, EVENT_HOMEASSISTANT_START
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
|
||||
CONF_EVENT_TYPE = "event_type"
|
||||
CONF_EVENT_DATA = "event_data"
|
||||
CONF_EVENT_TYPE = 'event_type'
|
||||
CONF_EVENT_DATA = 'event_data'
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ def async_trigger(hass, config, action):
|
|||
if event == EVENT_SHUTDOWN:
|
||||
@callback
|
||||
def hass_shutdown(event):
|
||||
"""Called when Home Assistant is shutting down."""
|
||||
"""Execute when Home Assistant is shutting down."""
|
||||
hass.async_run_job(action, {
|
||||
'trigger': {
|
||||
'platform': 'homeassistant',
|
||||
|
|
|
@ -14,11 +14,11 @@ from homeassistant.helpers.event import (
|
|||
async_track_state_change, async_track_point_in_utc_time)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
CONF_ENTITY_ID = "entity_id"
|
||||
CONF_FROM = "from"
|
||||
CONF_TO = "to"
|
||||
CONF_STATE = "state"
|
||||
CONF_FOR = "for"
|
||||
CONF_ENTITY_ID = 'entity_id'
|
||||
CONF_FROM = 'from'
|
||||
CONF_TO = 'to'
|
||||
CONF_STATE = 'state'
|
||||
CONF_FOR = 'for'
|
||||
|
||||
TRIGGER_SCHEMA = vol.All(
|
||||
vol.Schema({
|
||||
|
|
|
@ -14,9 +14,9 @@ from homeassistant.const import CONF_AFTER, CONF_PLATFORM
|
|||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.event import async_track_time_change
|
||||
|
||||
CONF_HOURS = "hours"
|
||||
CONF_MINUTES = "minutes"
|
||||
CONF_SECONDS = "seconds"
|
||||
CONF_HOURS = 'hours'
|
||||
CONF_MINUTES = 'minutes'
|
||||
CONF_SECONDS = 'seconds'
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ from homeassistant.helpers.event import async_track_state_change
|
|||
from homeassistant.helpers import (
|
||||
condition, config_validation as cv, location)
|
||||
|
||||
EVENT_ENTER = "enter"
|
||||
EVENT_LEAVE = "leave"
|
||||
EVENT_ENTER = 'enter'
|
||||
EVENT_LEAVE = 'leave'
|
||||
DEFAULT_EVENT = EVENT_ENTER
|
||||
|
||||
TRIGGER_SCHEMA = vol.Schema({
|
||||
|
|
|
@ -37,14 +37,14 @@ def setup(hass, config):
|
|||
# noqa: F821
|
||||
|
||||
def setup_output(pin):
|
||||
"""Setup a GPIO as output."""
|
||||
"""Set up a GPIO as output."""
|
||||
# pylint: disable=import-error,undefined-variable
|
||||
import Adafruit_BBIO.GPIO as GPIO
|
||||
GPIO.setup(pin, GPIO.OUT)
|
||||
|
||||
|
||||
def setup_input(pin, pull_mode):
|
||||
"""Setup a GPIO as input."""
|
||||
"""Set up a GPIO as input."""
|
||||
# pylint: disable=import-error,undefined-variable
|
||||
import Adafruit_BBIO.GPIO as GPIO
|
||||
GPIO.setup(pin, GPIO.IN, # noqa: F821
|
||||
|
|
|
@ -57,7 +57,7 @@ class BinarySensorDevice(Entity):
|
|||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return True if the binary sensor is on."""
|
||||
"""Return true if the binary sensor is on."""
|
||||
return None
|
||||
|
||||
@property
|
||||
|
|
|
@ -11,7 +11,6 @@ from homeassistant.core import callback
|
|||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||
|
||||
from homeassistant.const import (STATE_ON, STATE_OFF, STATE_OPEN, STATE_CLOSED)
|
||||
from homeassistant.components.alarmdecoder import (ZONE_SCHEMA,
|
||||
CONF_ZONES,
|
||||
CONF_ZONE_NAME,
|
||||
|
@ -27,7 +26,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup AlarmDecoder binary sensor devices."""
|
||||
"""Set up the AlarmDecoder binary sensor devices."""
|
||||
configured_zones = discovery_info[CONF_ZONES]
|
||||
|
||||
devices = []
|
||||
|
@ -36,10 +35,8 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
device_config_data = ZONE_SCHEMA(configured_zones[zone_num])
|
||||
zone_type = device_config_data[CONF_ZONE_TYPE]
|
||||
zone_name = device_config_data[CONF_ZONE_NAME]
|
||||
device = AlarmDecoderBinarySensor(hass,
|
||||
zone_num,
|
||||
zone_name,
|
||||
zone_type)
|
||||
device = AlarmDecoderBinarySensor(
|
||||
hass, zone_num, zone_name, zone_type)
|
||||
devices.append(device)
|
||||
|
||||
async_add_devices(devices)
|
||||
|
@ -58,7 +55,7 @@ class AlarmDecoderBinarySensor(BinarySensorDevice):
|
|||
self._name = zone_name
|
||||
self._type = zone_type
|
||||
|
||||
_LOGGER.debug('AlarmDecoderBinarySensor: Setup up zone: ' + zone_name)
|
||||
_LOGGER.debug("Setup up zone: %s", self._name)
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_added_to_hass(self):
|
||||
|
@ -69,14 +66,6 @@ class AlarmDecoderBinarySensor(BinarySensorDevice):
|
|||
async_dispatcher_connect(
|
||||
self.hass, SIGNAL_ZONE_RESTORE, self._restore_callback)
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the binary sensor."""
|
||||
if self._type == 'opening':
|
||||
return STATE_OPEN if self.is_on else STATE_CLOSED
|
||||
|
||||
return STATE_ON if self.is_on else STATE_OFF
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the entity."""
|
||||
|
|
|
@ -15,7 +15,7 @@ DEPENDENCIES = ['android_ip_webcam']
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup IP Webcam binary sensors."""
|
||||
"""Set up the IP Webcam binary sensors."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
|
@ -28,7 +28,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
|
||||
|
||||
class IPWebcamBinarySensor(AndroidIPCamEntity, BinarySensorDevice):
|
||||
"""Represents an IP Webcam binary sensor."""
|
||||
"""Representation of an IP Webcam binary sensor."""
|
||||
|
||||
def __init__(self, name, host, ipcam, sensor):
|
||||
"""Initialize the binary sensor."""
|
||||
|
@ -47,7 +47,7 @@ class IPWebcamBinarySensor(AndroidIPCamEntity, BinarySensorDevice):
|
|||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""True if the binary sensor is on."""
|
||||
"""Return true if the binary sensor is on."""
|
||||
return self._state
|
||||
|
||||
@asyncio.coroutine
|
||||
|
|
|
@ -21,7 +21,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Setup an Online Status binary sensor."""
|
||||
"""Set up an Online Status binary sensor."""
|
||||
add_entities((OnlineStatus(config, apcupsd.DATA),))
|
||||
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Beaglebone Black GPIO devices."""
|
||||
"""Set up the Beaglebone Black GPIO devices."""
|
||||
pins = config.get(CONF_PINS)
|
||||
|
||||
binary_sensors = []
|
||||
|
@ -53,7 +53,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
|
||||
|
||||
class BBBGPIOBinarySensor(BinarySensorDevice):
|
||||
"""Represent a binary sensor that uses Beaglebone Black GPIO."""
|
||||
"""Representation of a binary sensor that uses Beaglebone Black GPIO."""
|
||||
|
||||
def __init__(self, pin, params):
|
||||
"""Initialize the Beaglebone Black binary sensor."""
|
||||
|
|
|
@ -24,7 +24,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
|
||||
|
||||
class BlinkCameraMotionSensor(BinarySensorDevice):
|
||||
"""A representation of a Blink binary sensor."""
|
||||
"""Representation of a Blink binary sensor."""
|
||||
|
||||
def __init__(self, name, data):
|
||||
"""Initialize the sensor."""
|
||||
|
|
|
@ -18,7 +18,6 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
DEPENDENCIES = ['bloomsky']
|
||||
|
||||
# These are the available sensors mapped to binary_sensor class
|
||||
SENSOR_TYPES = {
|
||||
'Rain': 'moisture',
|
||||
'Night': None,
|
||||
|
@ -31,7 +30,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the available BloomSky weather binary sensors."""
|
||||
"""Set up the available BloomSky weather binary sensors."""
|
||||
bloomsky = get_component('bloomsky')
|
||||
# Default needed in case of discovery
|
||||
sensors = config.get(CONF_MONITORED_CONDITIONS, SENSOR_TYPES)
|
||||
|
@ -42,7 +41,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
|
||||
|
||||
class BloomSkySensor(BinarySensorDevice):
|
||||
"""Represent a single binary sensor in a BloomSky device."""
|
||||
"""Representation of a single binary sensor in a BloomSky device."""
|
||||
|
||||
def __init__(self, bs, device, sensor_name):
|
||||
"""Initialize a BloomSky binary sensor."""
|
||||
|
@ -55,7 +54,7 @@ class BloomSkySensor(BinarySensorDevice):
|
|||
|
||||
@property
|
||||
def name(self):
|
||||
"""The name of the BloomSky device and this sensor."""
|
||||
"""Return the name of the BloomSky device and this sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
|
|
|
@ -39,7 +39,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Command line Binary Sensor."""
|
||||
"""Set up the Command line Binary Sensor."""
|
||||
name = config.get(CONF_NAME)
|
||||
command = config.get(CONF_COMMAND)
|
||||
payload_off = config.get(CONF_PAYLOAD_OFF)
|
||||
|
@ -56,7 +56,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
|
||||
|
||||
class CommandBinarySensor(BinarySensorDevice):
|
||||
"""Represent a command line binary sensor."""
|
||||
"""Representation of a command line binary sensor."""
|
||||
|
||||
def __init__(self, hass, data, name, device_class, payload_on,
|
||||
payload_off, value_template):
|
||||
|
|
|
@ -67,8 +67,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
if zone['number'] not in exclude:
|
||||
sensors.append(
|
||||
Concord232ZoneSensor(
|
||||
hass, client, zone, zone_types.get(zone['number'],
|
||||
get_opening_type(zone)))
|
||||
hass, client, zone, zone_types.get(
|
||||
zone['number'], get_opening_type(zone))
|
||||
)
|
||||
)
|
||||
|
||||
add_devices(sensors)
|
||||
|
@ -77,7 +78,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
|
||||
|
||||
def get_opening_type(zone):
|
||||
"""Helper function to try to guess sensor type from name."""
|
||||
"""Return the result of the type guessing from name."""
|
||||
if 'MOTION' in zone['name']:
|
||||
return 'motion'
|
||||
if 'KEY' in zone['name']:
|
||||
|
@ -123,7 +124,7 @@ class Concord232ZoneSensor(BinarySensorDevice):
|
|||
return bool(self._zone['state'] == 'Normal')
|
||||
|
||||
def update(self):
|
||||
""""Get updated stats from API."""
|
||||
"""Get updated stats from API."""
|
||||
last_update = datetime.datetime.now() - self._client.last_zone_update
|
||||
_LOGGER.debug("Zone: %s ", self._zone)
|
||||
if last_update > datetime.timedelta(seconds=1):
|
||||
|
|
|
@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import BinarySensorDevice
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Demo binary sensor platform."""
|
||||
"""Set up the Demo binary sensor platform."""
|
||||
add_devices([
|
||||
DemoBinarySensor('Basement Floor Wet', False, 'moisture'),
|
||||
DemoBinarySensor('Movement Backyard', True, 'motion'),
|
||||
|
@ -16,7 +16,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
|
||||
|
||||
class DemoBinarySensor(BinarySensorDevice):
|
||||
"""A Demo binary sensor."""
|
||||
"""representation of a Demo binary sensor."""
|
||||
|
||||
def __init__(self, name, state, device_class):
|
||||
"""Initialize the demo sensor."""
|
||||
|
|
|
@ -13,7 +13,7 @@ ECOBEE_CONFIG_FILE = 'ecobee.conf'
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Ecobee sensors."""
|
||||
"""Set up the Ecobee sensors."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
data = ecobee.NETWORK
|
||||
|
|
69
homeassistant/components/binary_sensor/eight_sleep.py
Normal file
69
homeassistant/components/binary_sensor/eight_sleep.py
Normal file
|
@ -0,0 +1,69 @@
|
|||
"""
|
||||
Support for Eight Sleep binary sensors.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/binary_sensor.eight_sleep/
|
||||
"""
|
||||
import logging
|
||||
import asyncio
|
||||
|
||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||
from homeassistant.components.eight_sleep import (
|
||||
DATA_EIGHT, EightSleepHeatEntity, CONF_BINARY_SENSORS, NAME_MAP)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['eight_sleep']
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Set up the eight sleep binary sensor."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
name = 'Eight'
|
||||
sensors = discovery_info[CONF_BINARY_SENSORS]
|
||||
eight = hass.data[DATA_EIGHT]
|
||||
|
||||
all_sensors = []
|
||||
|
||||
for sensor in sensors:
|
||||
all_sensors.append(EightHeatSensor(name, eight, sensor))
|
||||
|
||||
async_add_devices(all_sensors, True)
|
||||
|
||||
|
||||
class EightHeatSensor(EightSleepHeatEntity, BinarySensorDevice):
|
||||
"""Representation of a Eight Sleep heat-based sensor."""
|
||||
|
||||
def __init__(self, name, eight, sensor):
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(eight)
|
||||
|
||||
self._sensor = sensor
|
||||
self._mapped_name = NAME_MAP.get(self._sensor, self._sensor)
|
||||
self._name = '{} {}'.format(name, self._mapped_name)
|
||||
self._state = None
|
||||
|
||||
self._side = self._sensor.split('_')[0]
|
||||
self._userid = self._eight.fetch_userid(self._side)
|
||||
self._usrobj = self._eight.users[self._userid]
|
||||
|
||||
_LOGGER.debug("Presence Sensor: %s, Side: %s, User: %s",
|
||||
self._sensor, self._side, self._userid)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor, if any."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if the binary sensor is on."""
|
||||
return self._state
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_update(self):
|
||||
"""Retrieve latest state."""
|
||||
self._state = self._usrobj.bed_presence
|
|
@ -30,7 +30,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Binary Sensor platform fo EnOcean."""
|
||||
"""Set up the Binary Sensor platform for EnOcean."""
|
||||
dev_id = config.get(CONF_ID)
|
||||
devname = config.get(CONF_NAME)
|
||||
device_class = get_deprecated(config, CONF_DEVICE_CLASS, CONF_SENSOR_CLASS)
|
||||
|
@ -44,7 +44,7 @@ class EnOceanBinarySensor(enocean.EnOceanDevice, BinarySensorDevice):
|
|||
def __init__(self, dev_id, devname, device_class):
|
||||
"""Initialize the EnOcean binary sensor."""
|
||||
enocean.EnOceanDevice.__init__(self)
|
||||
self.stype = "listener"
|
||||
self.stype = 'listener'
|
||||
self.dev_id = dev_id
|
||||
self.which = -1
|
||||
self.onoff = -1
|
||||
|
@ -53,7 +53,7 @@ class EnOceanBinarySensor(enocean.EnOceanDevice, BinarySensorDevice):
|
|||
|
||||
@property
|
||||
def name(self):
|
||||
"""The default name for the binary sensor."""
|
||||
"""Return the default name for the binary sensor."""
|
||||
return self.devname
|
||||
|
||||
@property
|
||||
|
@ -80,7 +80,7 @@ class EnOceanBinarySensor(enocean.EnOceanDevice, BinarySensorDevice):
|
|||
elif value2 == 0x10:
|
||||
self.which = 1
|
||||
self.onoff = 1
|
||||
self.hass.bus.fire('button_pressed', {"id": self.dev_id,
|
||||
self.hass.bus.fire('button_pressed', {'id': self.dev_id,
|
||||
'pushed': value,
|
||||
'which': self.which,
|
||||
'onoff': self.onoff})
|
||||
|
|
|
@ -15,13 +15,14 @@ from homeassistant.components.envisalink import (
|
|||
SIGNAL_ZONE_UPDATE)
|
||||
from homeassistant.const import ATTR_LAST_TRIP_TIME
|
||||
|
||||
DEPENDENCIES = ['envisalink']
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['envisalink']
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup Envisalink binary sensor devices."""
|
||||
"""Set up the Envisalink binary sensor devices."""
|
||||
configured_zones = discovery_info['zones']
|
||||
|
||||
devices = []
|
||||
|
|
|
@ -48,23 +48,21 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Create the binary sensor."""
|
||||
"""Set up the FFmpeg binary moition sensor."""
|
||||
manager = hass.data[DATA_FFMPEG]
|
||||
|
||||
# check source
|
||||
if not manager.async_run_test(config.get(CONF_INPUT)):
|
||||
return
|
||||
|
||||
# generate sensor object
|
||||
entity = FFmpegMotion(hass, manager, config)
|
||||
async_add_devices([entity])
|
||||
|
||||
|
||||
class FFmpegBinarySensor(FFmpegBase, BinarySensorDevice):
|
||||
"""A binary sensor which use ffmpeg for noise detection."""
|
||||
"""A binary sensor which use FFmpeg for noise detection."""
|
||||
|
||||
def __init__(self, config):
|
||||
"""Constructor for binary sensor noise detection."""
|
||||
"""Init for the binary sensor noise detection."""
|
||||
super().__init__(config.get(CONF_INITIAL_STATE))
|
||||
|
||||
self._state = False
|
||||
|
@ -79,7 +77,7 @@ class FFmpegBinarySensor(FFmpegBase, BinarySensorDevice):
|
|||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""True if the binary sensor is on."""
|
||||
"""Return true if the binary sensor is on."""
|
||||
return self._state
|
||||
|
||||
@property
|
||||
|
@ -89,10 +87,10 @@ class FFmpegBinarySensor(FFmpegBase, BinarySensorDevice):
|
|||
|
||||
|
||||
class FFmpegMotion(FFmpegBinarySensor):
|
||||
"""A binary sensor which use ffmpeg for noise detection."""
|
||||
"""A binary sensor which use FFmpeg for noise detection."""
|
||||
|
||||
def __init__(self, hass, manager, config):
|
||||
"""Initialize ffmpeg motion binary sensor."""
|
||||
"""Initialize FFmpeg motion binary sensor."""
|
||||
from haffmpeg import SensorMotion
|
||||
|
||||
super().__init__(config)
|
||||
|
@ -125,4 +123,4 @@ class FFmpegMotion(FFmpegBinarySensor):
|
|||
@property
|
||||
def device_class(self):
|
||||
"""Return the class of this sensor, from DEVICE_CLASSES."""
|
||||
return "motion"
|
||||
return 'motion'
|
||||
|
|
|
@ -45,23 +45,21 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Create the binary sensor."""
|
||||
"""Set up the FFmpeg noise binary sensor."""
|
||||
manager = hass.data[DATA_FFMPEG]
|
||||
|
||||
# check source
|
||||
if not manager.async_run_test(config.get(CONF_INPUT)):
|
||||
return
|
||||
|
||||
# generate sensor object
|
||||
entity = FFmpegNoise(hass, manager, config)
|
||||
async_add_devices([entity])
|
||||
|
||||
|
||||
class FFmpegNoise(FFmpegBinarySensor):
|
||||
"""A binary sensor which use ffmpeg for noise detection."""
|
||||
"""A binary sensor which use FFmpeg for noise detection."""
|
||||
|
||||
def __init__(self, hass, manager, config):
|
||||
"""Initialize ffmpeg noise binary sensor."""
|
||||
"""Initialize FFmpeg noise binary sensor."""
|
||||
from haffmpeg import SensorNoise
|
||||
|
||||
super().__init__(config)
|
||||
|
@ -77,14 +75,12 @@ class FFmpegNoise(FFmpegBinarySensor):
|
|||
if entity_ids is not None and self.entity_id not in entity_ids:
|
||||
return
|
||||
|
||||
# init config
|
||||
self.ffmpeg.set_options(
|
||||
time_duration=self._config.get(CONF_DURATION),
|
||||
time_reset=self._config.get(CONF_RESET),
|
||||
peak=self._config.get(CONF_PEAK),
|
||||
)
|
||||
|
||||
# run
|
||||
yield from self.ffmpeg.open_sensor(
|
||||
input_source=self._config.get(CONF_INPUT),
|
||||
output_dest=self._config.get(CONF_OUTPUT),
|
||||
|
@ -94,4 +90,4 @@ class FFmpegNoise(FFmpegBinarySensor):
|
|||
@property
|
||||
def device_class(self):
|
||||
"""Return the class of this sensor, from DEVICE_CLASSES."""
|
||||
return "sound"
|
||||
return 'sound'
|
||||
|
|
|
@ -110,7 +110,7 @@ def start_scanning(config, add_entities, client):
|
|||
|
||||
|
||||
def setup_button(hass, config, add_entities, client, address):
|
||||
"""Setup single button device."""
|
||||
"""Set up a single button device."""
|
||||
timeout = config.get(CONF_TIMEOUT)
|
||||
ignored_click_types = config.get(CONF_IGNORED_CLICK_TYPES)
|
||||
button = FlicButton(hass, client, address, timeout, ignored_click_types)
|
||||
|
|
|
@ -67,7 +67,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Setup Hikvision binary sensor devices."""
|
||||
"""Set up the Hikvision binary sensor devices."""
|
||||
name = config.get(CONF_NAME)
|
||||
host = config.get(CONF_HOST)
|
||||
port = config.get(CONF_PORT)
|
||||
|
@ -77,16 +77,16 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||
customize = config.get(CONF_CUSTOMIZE)
|
||||
|
||||
if config.get(CONF_SSL):
|
||||
protocol = "https"
|
||||
protocol = 'https'
|
||||
else:
|
||||
protocol = "http"
|
||||
protocol = 'http'
|
||||
|
||||
url = '{}://{}'.format(protocol, host)
|
||||
|
||||
data = HikvisionData(hass, url, port, name, username, password)
|
||||
|
||||
if data.sensors is None:
|
||||
_LOGGER.error('Hikvision event stream has no data, unable to setup.')
|
||||
_LOGGER.error("Hikvision event stream has no data, unable to setup")
|
||||
return False
|
||||
|
||||
entities = []
|
||||
|
@ -104,7 +104,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||
ignore = custom.get(CONF_IGNORED)
|
||||
delay = custom.get(CONF_DELAY)
|
||||
|
||||
_LOGGER.debug('Entity: %s - %s, Options - Ignore: %s, Delay: %s',
|
||||
_LOGGER.debug("Entity: %s - %s, Options - Ignore: %s, Delay: %s",
|
||||
data.name, sensor_name, ignore, delay)
|
||||
if not ignore:
|
||||
entities.append(HikvisionBinarySensor(
|
||||
|
@ -126,8 +126,8 @@ class HikvisionData(object):
|
|||
self._password = password
|
||||
|
||||
# Establish camera
|
||||
self.camdata = HikCamera(self._url, self._port,
|
||||
self._username, self._password)
|
||||
self.camdata = HikCamera(
|
||||
self._url, self._port, self._username, self._password)
|
||||
|
||||
if self._name is None:
|
||||
self._name = self.camdata.get_name
|
||||
|
@ -251,7 +251,7 @@ class HikvisionBinarySensor(BinarySensorDevice):
|
|||
# Set timer to wait until updating the state
|
||||
def _delay_update(now):
|
||||
"""Timer callback for sensor update."""
|
||||
_LOGGER.debug('%s Called delayed (%ssec) update.',
|
||||
_LOGGER.debug("%s Called delayed (%ssec) update",
|
||||
self._name, self._delay)
|
||||
self.schedule_update_ha_state()
|
||||
self._timer = None
|
||||
|
|
|
@ -14,22 +14,22 @@ _LOGGER = logging.getLogger(__name__)
|
|||
DEPENDENCIES = ['homematic']
|
||||
|
||||
SENSOR_TYPES_CLASS = {
|
||||
"Remote": None,
|
||||
"ShutterContact": "opening",
|
||||
"MaxShutterContact": "opening",
|
||||
"IPShutterContact": "opening",
|
||||
"Smoke": "smoke",
|
||||
"SmokeV2": "smoke",
|
||||
"Motion": "motion",
|
||||
"MotionV2": "motion",
|
||||
"RemoteMotion": None,
|
||||
"WeatherSensor": None,
|
||||
"TiltSensor": None,
|
||||
'Remote': None,
|
||||
'ShutterContact': 'opening',
|
||||
'MaxShutterContact': 'opening',
|
||||
'IPShutterContact': 'opening',
|
||||
'Smoke': 'smoke',
|
||||
'SmokeV2': 'smoke',
|
||||
'Motion': 'motion',
|
||||
'MotionV2': 'motion',
|
||||
'RemoteMotion': None,
|
||||
'WeatherSensor': None,
|
||||
'TiltSensor': None,
|
||||
}
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Homematic binary sensor platform."""
|
||||
"""Set up the Homematic binary sensor platform."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
|
@ -56,8 +56,8 @@ class HMBinarySensor(HMDevice, BinarySensorDevice):
|
|||
def device_class(self):
|
||||
"""Return the class of this sensor, from DEVICE_CLASSES."""
|
||||
# If state is MOTION (RemoteMotion works only)
|
||||
if self._state == "MOTION":
|
||||
return "motion"
|
||||
if self._state == 'MOTION':
|
||||
return 'motion'
|
||||
return SENSOR_TYPES_CLASS.get(self._hmdevice.__class__.__name__, None)
|
||||
|
||||
def _init_data_struct(self):
|
||||
|
|
|
@ -67,7 +67,7 @@ class InsteonPLMBinarySensorDevice(BinarySensorDevice):
|
|||
def is_on(self):
|
||||
"""Return the boolean response if the node is on."""
|
||||
sensorstate = self._plm.get_device_attr(self._address, 'sensorstate')
|
||||
_LOGGER.info('sensor state for %s is %s', self._address, sensorstate)
|
||||
_LOGGER.info("Sensor state for %s is %s", self._address, sensorstate)
|
||||
return bool(sensorstate)
|
||||
|
||||
@property
|
||||
|
@ -83,5 +83,5 @@ class InsteonPLMBinarySensorDevice(BinarySensorDevice):
|
|||
@callback
|
||||
def async_binarysensor_update(self, message):
|
||||
"""Receive notification from transport that new data exists."""
|
||||
_LOGGER.info('Received update calback from PLM for %s', self._address)
|
||||
_LOGGER.info("Received update calback from PLM for %s", self._address)
|
||||
self._hass.async_add_job(self.async_update_ha_state())
|
||||
|
|
|
@ -12,7 +12,6 @@ import homeassistant.components.isy994 as isy
|
|||
from homeassistant.const import STATE_ON, STATE_OFF
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
VALUE_TO_STATE = {
|
||||
|
@ -27,9 +26,9 @@ STATES = [STATE_OFF, STATE_ON, 'true', 'false']
|
|||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config: ConfigType,
|
||||
add_devices: Callable[[list], None], discovery_info=None):
|
||||
"""Setup the ISY994 binary sensor platform."""
|
||||
"""Set up the ISY994 binary sensor platform."""
|
||||
if isy.ISY is None or not isy.ISY.connected:
|
||||
_LOGGER.error('A connection has not been made to the ISY controller.')
|
||||
_LOGGER.error("A connection has not been made to the ISY controller")
|
||||
return False
|
||||
|
||||
devices = []
|
||||
|
|
|
@ -11,7 +11,7 @@ DEPENDENCIES = ['knx']
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the KNX binary sensor platform."""
|
||||
"""Set up the KNX binary sensor platform."""
|
||||
add_devices([KNXSwitch(hass, KNXConfig(config))])
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ Support for MAX! Window Shutter via MAX! Cube.
|
|||
For more details about this platform, please refer to the documentation
|
||||
https://home-assistant.io/components/maxcube/
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||
|
@ -15,27 +14,24 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Iterate through all MAX! Devices and add window shutters to HASS."""
|
||||
"""Iterate through all MAX! Devices and add window shutters."""
|
||||
cube = hass.data[MAXCUBE_HANDLE].cube
|
||||
|
||||
# List of devices
|
||||
devices = []
|
||||
|
||||
for device in cube.devices:
|
||||
# Create device name by concatenating room name + device name
|
||||
name = "%s %s" % (cube.room_by_id(device.room_id).name, device.name)
|
||||
name = "{} {}".format(
|
||||
cube.room_by_id(device.room_id).name, device.name)
|
||||
|
||||
# Only add Window Shutters
|
||||
if cube.is_windowshutter(device):
|
||||
# add device to HASS
|
||||
devices.append(MaxCubeShutter(hass, name, device.rf_address))
|
||||
|
||||
if len(devices) > 0:
|
||||
if devices:
|
||||
add_devices(devices)
|
||||
|
||||
|
||||
class MaxCubeShutter(BinarySensorDevice):
|
||||
"""MAX! Cube BinarySensor device."""
|
||||
"""Representation of a MAX! Cube Binary Sensor device."""
|
||||
|
||||
def __init__(self, hass, name, rf_address):
|
||||
"""Initialize MAX! Cube BinarySensorDevice."""
|
||||
|
@ -47,7 +43,7 @@ class MaxCubeShutter(BinarySensorDevice):
|
|||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""Polling is required."""
|
||||
"""Return the polling state."""
|
||||
return True
|
||||
|
||||
@property
|
||||
|
@ -68,9 +64,5 @@ class MaxCubeShutter(BinarySensorDevice):
|
|||
def update(self):
|
||||
"""Get latest data from MAX! Cube."""
|
||||
self._cubehandle.update()
|
||||
|
||||
# Get the device we want to update
|
||||
device = self._cubehandle.cube.device_by_rf(self._rf_address)
|
||||
|
||||
# Update our internal state
|
||||
self._state = device.is_open
|
||||
|
|
|
@ -16,9 +16,9 @@ from homeassistant.components.sensor import PLATFORM_SCHEMA
|
|||
_LOGGER = logging.getLogger(__name__)
|
||||
DEPENDENCIES = ['modbus']
|
||||
|
||||
CONF_COIL = "coil"
|
||||
CONF_COILS = "coils"
|
||||
CONF_SLAVE = "slave"
|
||||
CONF_COIL = 'coil'
|
||||
CONF_COILS = 'coils'
|
||||
CONF_SLAVE = 'slave'
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_COILS): [{
|
||||
|
@ -30,7 +30,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup Modbus binary sensors."""
|
||||
"""Set up the Modbus binary sensors."""
|
||||
sensors = []
|
||||
for coil in config.get(CONF_COILS):
|
||||
sensors.append(ModbusCoilSensor(
|
||||
|
|
|
@ -79,7 +79,7 @@ class MqttBinarySensor(BinarySensorDevice):
|
|||
"""
|
||||
@callback
|
||||
def message_received(topic, payload, qos):
|
||||
"""A new MQTT message has been received."""
|
||||
"""Handle a new received MQTT message."""
|
||||
if self._template is not None:
|
||||
payload = self._template.async_render_with_possible_json_value(
|
||||
payload)
|
||||
|
@ -95,7 +95,7 @@ class MqttBinarySensor(BinarySensorDevice):
|
|||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""No polling needed."""
|
||||
"""Return the polling state."""
|
||||
return False
|
||||
|
||||
@property
|
||||
|
|
|
@ -16,7 +16,7 @@ DEPENDENCIES = []
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the mysensors platform for sensors."""
|
||||
"""Set up the MySensors platform for sensors."""
|
||||
# Only act if loaded via mysensors by discovery event.
|
||||
# Otherwise gateway is not setup.
|
||||
if discovery_info is None:
|
||||
|
|
|
@ -16,15 +16,18 @@ DEPENDENCIES = ['nest']
|
|||
|
||||
BINARY_TYPES = ['online']
|
||||
|
||||
CLIMATE_BINARY_TYPES = ['fan',
|
||||
'is_using_emergency_heat',
|
||||
'is_locked',
|
||||
'has_leaf']
|
||||
CLIMATE_BINARY_TYPES = [
|
||||
'fan',
|
||||
'is_using_emergency_heat',
|
||||
'is_locked',
|
||||
'has_leaf',
|
||||
]
|
||||
|
||||
CAMERA_BINARY_TYPES = [
|
||||
'motion_detected',
|
||||
'sound_detected',
|
||||
'person_detected']
|
||||
'person_detected',
|
||||
]
|
||||
|
||||
_BINARY_TYPES_DEPRECATED = [
|
||||
'hvac_ac_state',
|
||||
|
@ -34,7 +37,8 @@ _BINARY_TYPES_DEPRECATED = [
|
|||
'hvac_heat_x3_state',
|
||||
'hvac_alt_heat_state',
|
||||
'hvac_alt_heat_x2_state',
|
||||
'hvac_emer_heat_state']
|
||||
'hvac_emer_heat_state',
|
||||
]
|
||||
|
||||
_VALID_BINARY_SENSOR_TYPES = BINARY_TYPES + CLIMATE_BINARY_TYPES \
|
||||
+ CAMERA_BINARY_TYPES
|
||||
|
@ -43,7 +47,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup Nest binary sensors."""
|
||||
"""Set up the Nest binary sensors."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
|
@ -93,7 +97,7 @@ class NestBinarySensor(NestSensor, BinarySensorDevice):
|
|||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""True if the binary sensor is on."""
|
||||
"""Return true if the binary sensor is on."""
|
||||
return self._state
|
||||
|
||||
def update(self):
|
||||
|
|
|
@ -7,6 +7,7 @@ For more details about this platform, please refer to the documentation at
|
|||
https://home-assistant.io/components/binary_sensor.netatmo/.
|
||||
"""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
|
@ -16,10 +17,9 @@ from homeassistant.loader import get_component
|
|||
from homeassistant.const import CONF_TIMEOUT, CONF_OFFSET
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
|
||||
DEPENDENCIES = ["netatmo"]
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['netatmo']
|
||||
|
||||
# These are the available sensors mapped to binary_sensor class
|
||||
WELCOME_SENSOR_TYPES = {
|
||||
|
@ -34,8 +34,8 @@ PRESENCE_SENSOR_TYPES = {
|
|||
"Outdoor vehicle": "motion"
|
||||
}
|
||||
TAG_SENSOR_TYPES = {
|
||||
"Tag Vibration": 'vibration',
|
||||
"Tag Open": 'opening'
|
||||
"Tag Vibration": "vibration",
|
||||
"Tag Open": "opening"
|
||||
}
|
||||
|
||||
CONF_HOME = 'home'
|
||||
|
@ -61,7 +61,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup access to Netatmo binary sensor."""
|
||||
"""Set up the access to Netatmo binary sensor."""
|
||||
netatmo = get_component('netatmo')
|
||||
home = config.get(CONF_HOME, None)
|
||||
timeout = config.get(CONF_TIMEOUT, 15)
|
||||
|
@ -85,35 +85,31 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
|
||||
for camera_name in data.get_camera_names():
|
||||
camera_type = data.get_camera_type(camera=camera_name, home=home)
|
||||
if camera_type == "NACamera":
|
||||
if camera_type == 'NACamera':
|
||||
if CONF_CAMERAS in config:
|
||||
if config[CONF_CAMERAS] != [] and \
|
||||
camera_name not in config[CONF_CAMERAS]:
|
||||
continue
|
||||
for variable in welcome_sensors:
|
||||
add_devices([NetatmoBinarySensor(data, camera_name,
|
||||
module_name, home, timeout,
|
||||
offset, camera_type,
|
||||
variable)])
|
||||
if camera_type == "NOC":
|
||||
add_devices([NetatmoBinarySensor(
|
||||
data, camera_name, module_name, home, timeout,
|
||||
offset, camera_type, variable)])
|
||||
if camera_type == 'NOC':
|
||||
if CONF_CAMERAS in config:
|
||||
if config[CONF_CAMERAS] != [] and \
|
||||
camera_name not in config[CONF_CAMERAS]:
|
||||
continue
|
||||
for variable in presence_sensors:
|
||||
add_devices([NetatmoBinarySensor(data, camera_name,
|
||||
module_name, home, timeout,
|
||||
offset, camera_type,
|
||||
variable)])
|
||||
add_devices([NetatmoBinarySensor(
|
||||
data, camera_name, module_name, home, timeout, offset,
|
||||
camera_type, variable)])
|
||||
|
||||
for module_name in data.get_module_names(camera_name):
|
||||
for variable in tag_sensors:
|
||||
camera_type = None
|
||||
add_devices([NetatmoBinarySensor(data, camera_name,
|
||||
module_name, home,
|
||||
timeout, offset,
|
||||
camera_type,
|
||||
variable)])
|
||||
add_devices([NetatmoBinarySensor(
|
||||
data, camera_name, module_name, home, timeout, offset,
|
||||
camera_type, variable)])
|
||||
|
||||
|
||||
class NetatmoBinarySensor(BinarySensorDevice):
|
||||
|
@ -121,7 +117,7 @@ class NetatmoBinarySensor(BinarySensorDevice):
|
|||
|
||||
def __init__(self, data, camera_name, module_name, home,
|
||||
timeout, offset, camera_type, sensor):
|
||||
"""Setup for access to the Netatmo camera events."""
|
||||
"""Set up for access to the Netatmo camera events."""
|
||||
self._data = data
|
||||
self._camera_name = camera_name
|
||||
self._module_name = module_name
|
||||
|
@ -129,23 +125,23 @@ class NetatmoBinarySensor(BinarySensorDevice):
|
|||
self._timeout = timeout
|
||||
self._offset = offset
|
||||
if home:
|
||||
self._name = home + ' / ' + camera_name
|
||||
self._name = '{} / {}'.format(home, camera_name)
|
||||
else:
|
||||
self._name = camera_name
|
||||
if module_name:
|
||||
self._name += ' / ' + module_name
|
||||
self._sensor_name = sensor
|
||||
self._name += ' ' + sensor
|
||||
camera_id = data.camera_data.cameraByName(camera=camera_name,
|
||||
home=home)['id']
|
||||
self._unique_id = "Netatmo_binary_sensor {0} - {1}".format(self._name,
|
||||
camera_id)
|
||||
camera_id = data.camera_data.cameraByName(
|
||||
camera=camera_name, home=home)['id']
|
||||
self._unique_id = "Netatmo_binary_sensor {0} - {1}".format(
|
||||
self._name, camera_id)
|
||||
self._cameratype = camera_type
|
||||
self.update()
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""The name of the Netatmo device and this sensor."""
|
||||
"""Return the name of the Netatmo device and this sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
|
@ -156,9 +152,9 @@ class NetatmoBinarySensor(BinarySensorDevice):
|
|||
@property
|
||||
def device_class(self):
|
||||
"""Return the class of this sensor, from DEVICE_CLASSES."""
|
||||
if self._cameratype == "NACamera":
|
||||
if self._cameratype == 'NACamera':
|
||||
return WELCOME_SENSOR_TYPES.get(self._sensor_name)
|
||||
elif self._cameratype == "NOC":
|
||||
elif self._cameratype == 'NOC':
|
||||
return PRESENCE_SENSOR_TYPES.get(self._sensor_name)
|
||||
else:
|
||||
return TAG_SENSOR_TYPES.get(self._sensor_name)
|
||||
|
@ -173,51 +169,44 @@ class NetatmoBinarySensor(BinarySensorDevice):
|
|||
self._data.update()
|
||||
self._data.update_event()
|
||||
|
||||
if self._cameratype == "NACamera":
|
||||
if self._cameratype == 'NACamera':
|
||||
if self._sensor_name == "Someone known":
|
||||
self._state =\
|
||||
self._data.camera_data.someoneKnownSeen(self._home,
|
||||
self._camera_name,
|
||||
self._timeout*60)
|
||||
self._data.camera_data.someoneKnownSeen(
|
||||
self._home, self._camera_name, self._timeout*60)
|
||||
elif self._sensor_name == "Someone unknown":
|
||||
self._state =\
|
||||
self._data.camera_data.someoneUnknownSeen(
|
||||
self._home, self._camera_name, self._timeout*60)
|
||||
elif self._sensor_name == "Motion":
|
||||
self._state =\
|
||||
self._data.camera_data.motionDetected(self._home,
|
||||
self._camera_name,
|
||||
self._timeout*60)
|
||||
elif self._cameratype == "NOC":
|
||||
self._data.camera_data.motionDetected(
|
||||
self._home, self._camera_name, self._timeout*60)
|
||||
elif self._cameratype == 'NOC':
|
||||
if self._sensor_name == "Outdoor motion":
|
||||
self._state =\
|
||||
self._data.camera_data.outdoormotionDetected(
|
||||
self._home, self._camera_name, self._offset)
|
||||
elif self._sensor_name == "Outdoor human":
|
||||
self._state =\
|
||||
self._data.camera_data.humanDetected(self._home,
|
||||
self._camera_name,
|
||||
self._offset)
|
||||
self._data.camera_data.humanDetected(
|
||||
self._home, self._camera_name, self._offset)
|
||||
elif self._sensor_name == "Outdoor animal":
|
||||
self._state =\
|
||||
self._data.camera_data.animalDetected(self._home,
|
||||
self._camera_name,
|
||||
self._offset)
|
||||
self._data.camera_data.animalDetected(
|
||||
self._home, self._camera_name, self._offset)
|
||||
elif self._sensor_name == "Outdoor vehicle":
|
||||
self._state =\
|
||||
self._data.camera_data.carDetected(self._home,
|
||||
self._camera_name,
|
||||
self._offset)
|
||||
self._data.camera_data.carDetected(
|
||||
self._home, self._camera_name, self._offset)
|
||||
if self._sensor_name == "Tag Vibration":
|
||||
self._state =\
|
||||
self._data.camera_data.moduleMotionDetected(self._home,
|
||||
self._module_name,
|
||||
self._camera_name,
|
||||
self._timeout*60)
|
||||
self._data.camera_data.moduleMotionDetected(
|
||||
self._home, self._module_name, self._camera_name,
|
||||
self._timeout*60)
|
||||
elif self._sensor_name == "Tag Open":
|
||||
self._state =\
|
||||
self._data.camera_data.moduleOpened(self._home,
|
||||
self._module_name,
|
||||
self._camera_name)
|
||||
self._data.camera_data.moduleOpened(
|
||||
self._home, self._module_name, self._camera_name)
|
||||
else:
|
||||
return None
|
||||
|
|
|
@ -41,7 +41,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the NX584 binary sensor platform."""
|
||||
"""Set up the NX584 binary sensor platform."""
|
||||
from nx584 import client as nx584_client
|
||||
|
||||
host = config.get(CONF_HOST)
|
||||
|
@ -53,7 +53,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
client = nx584_client.Client('http://{}:{}'.format(host, port))
|
||||
zones = client.list_zones()
|
||||
except requests.exceptions.ConnectionError as ex:
|
||||
_LOGGER.error('Unable to connect to NX584: %s', str(ex))
|
||||
_LOGGER.error("Unable to connect to NX584: %s", str(ex))
|
||||
return False
|
||||
|
||||
version = [int(v) for v in client.get_version().split('.')]
|
||||
|
|
|
@ -9,14 +9,12 @@ import logging
|
|||
import requests
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import (
|
||||
CONF_NAME, STATE_ON, STATE_OFF, CONF_MONITORED_CONDITIONS)
|
||||
from homeassistant.const import CONF_NAME, CONF_MONITORED_CONDITIONS
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDevice, PLATFORM_SCHEMA)
|
||||
from homeassistant.loader import get_component
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['octoprint']
|
||||
|
@ -38,22 +36,18 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the available OctoPrint binary sensors."""
|
||||
"""Set up the available OctoPrint binary sensors."""
|
||||
octoprint = get_component('octoprint')
|
||||
name = config.get(CONF_NAME)
|
||||
monitored_conditions = config.get(CONF_MONITORED_CONDITIONS,
|
||||
SENSOR_TYPES.keys())
|
||||
monitored_conditions = config.get(
|
||||
CONF_MONITORED_CONDITIONS, SENSOR_TYPES.keys())
|
||||
|
||||
devices = []
|
||||
for octo_type in monitored_conditions:
|
||||
new_sensor = OctoPrintBinarySensor(octoprint.OCTOPRINT,
|
||||
octo_type,
|
||||
SENSOR_TYPES[octo_type][2],
|
||||
name,
|
||||
SENSOR_TYPES[octo_type][3],
|
||||
SENSOR_TYPES[octo_type][0],
|
||||
SENSOR_TYPES[octo_type][1],
|
||||
'flags')
|
||||
new_sensor = OctoPrintBinarySensor(
|
||||
octoprint.OCTOPRINT, octo_type, SENSOR_TYPES[octo_type][2],
|
||||
name, SENSOR_TYPES[octo_type][3], SENSOR_TYPES[octo_type][0],
|
||||
SENSOR_TYPES[octo_type][1], 'flags')
|
||||
devices.append(new_sensor)
|
||||
add_devices(devices)
|
||||
|
||||
|
@ -85,18 +79,10 @@ class OctoPrintBinarySensor(BinarySensorDevice):
|
|||
"""Return the name of the sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self.is_on
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if binary sensor is on."""
|
||||
if self._state:
|
||||
return STATE_ON
|
||||
else:
|
||||
return STATE_OFF
|
||||
return bool(self._state)
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
|
@ -106,10 +92,9 @@ class OctoPrintBinarySensor(BinarySensorDevice):
|
|||
def update(self):
|
||||
"""Update state of sensor."""
|
||||
try:
|
||||
self._state = self.api.update(self.sensor_type,
|
||||
self.api_endpoint,
|
||||
self.api_group,
|
||||
self.api_tool)
|
||||
self._state = self.api.update(
|
||||
self.sensor_type, self.api_endpoint, self.api_group,
|
||||
self.api_tool)
|
||||
except requests.exceptions.ConnectionError:
|
||||
# Error calling the api, already logged in api.update()
|
||||
return
|
||||
|
|
186
homeassistant/components/binary_sensor/pilight.py
Normal file
186
homeassistant/components/binary_sensor/pilight.py
Normal file
|
@ -0,0 +1,186 @@
|
|||
"""
|
||||
Support for Pilight binary sensors.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/binary_sensor.pilight/
|
||||
"""
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
from homeassistant.components import pilight
|
||||
from homeassistant.components.binary_sensor import (
|
||||
PLATFORM_SCHEMA,
|
||||
BinarySensorDevice,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
CONF_DISARM_AFTER_TRIGGER,
|
||||
CONF_NAME,
|
||||
CONF_PAYLOAD,
|
||||
CONF_PAYLOAD_OFF,
|
||||
CONF_PAYLOAD_ON
|
||||
)
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.event import track_point_in_time
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_VARIABLE = 'variable'
|
||||
|
||||
DEFAULT_NAME = 'Pilight Binary Sensor'
|
||||
DEPENDENCIES = ['pilight']
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_VARIABLE): cv.string,
|
||||
vol.Required(CONF_PAYLOAD): vol.Schema(dict),
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_PAYLOAD_ON, default='on'): cv.string,
|
||||
vol.Optional(CONF_PAYLOAD_OFF, default='off'): cv.string,
|
||||
vol.Optional(CONF_DISARM_AFTER_TRIGGER, default=False): cv.boolean
|
||||
})
|
||||
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Set up Pilight Binary Sensor."""
|
||||
disarm = config.get(CONF_DISARM_AFTER_TRIGGER)
|
||||
if disarm:
|
||||
add_devices([PilightTriggerSensor(
|
||||
hass=hass,
|
||||
name=config.get(CONF_NAME),
|
||||
variable=config.get(CONF_VARIABLE),
|
||||
payload=config.get(CONF_PAYLOAD),
|
||||
on_value=config.get(CONF_PAYLOAD_ON),
|
||||
off_value=config.get(CONF_PAYLOAD_OFF),
|
||||
)])
|
||||
else:
|
||||
add_devices([PilightBinarySensor(
|
||||
hass=hass,
|
||||
name=config.get(CONF_NAME),
|
||||
variable=config.get(CONF_VARIABLE),
|
||||
payload=config.get(CONF_PAYLOAD),
|
||||
on_value=config.get(CONF_PAYLOAD_ON),
|
||||
off_value=config.get(CONF_PAYLOAD_OFF),
|
||||
)])
|
||||
|
||||
|
||||
class PilightBinarySensor(BinarySensorDevice):
|
||||
"""Representation of a binary sensor that can be updated using Pilight."""
|
||||
|
||||
def __init__(self, hass, name, variable, payload, on_value, off_value):
|
||||
"""Initialize the sensor."""
|
||||
self._state = False
|
||||
self._hass = hass
|
||||
self._name = name
|
||||
self._variable = variable
|
||||
self._payload = payload
|
||||
self._on_value = on_value
|
||||
self._off_value = off_value
|
||||
|
||||
hass.bus.listen(pilight.EVENT, self._handle_code)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return True if the binary sensor is on."""
|
||||
return self._state
|
||||
|
||||
def _handle_code(self, call):
|
||||
"""Handle received code by the pilight-daemon.
|
||||
|
||||
If the code matches the defined playload
|
||||
of this sensor the sensor state is changed accordingly.
|
||||
"""
|
||||
# Check if received code matches defined playoad
|
||||
# True if payload is contained in received code dict
|
||||
payload_ok = True
|
||||
for key in self._payload:
|
||||
if key not in call.data:
|
||||
payload_ok = False
|
||||
continue
|
||||
if self._payload[key] != call.data[key]:
|
||||
payload_ok = False
|
||||
# Read out variable if payload ok
|
||||
if payload_ok:
|
||||
if self._variable not in call.data:
|
||||
return
|
||||
value = call.data[self._variable]
|
||||
self._state = (value == self._on_value)
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
|
||||
class PilightTriggerSensor(BinarySensorDevice):
|
||||
"""Representation of a binary sensor that can be updated using Pilight."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass,
|
||||
name,
|
||||
variable,
|
||||
payload,
|
||||
on_value,
|
||||
off_value,
|
||||
rst_dly_sec=30):
|
||||
"""Initialize the sensor."""
|
||||
self._state = False
|
||||
self._hass = hass
|
||||
self._name = name
|
||||
self._variable = variable
|
||||
self._payload = payload
|
||||
self._on_value = on_value
|
||||
self._off_value = off_value
|
||||
self._reset_delay_sec = rst_dly_sec
|
||||
self._delay_after = None
|
||||
self._hass = hass
|
||||
|
||||
hass.bus.listen(pilight.EVENT, self._handle_code)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return True if the binary sensor is on."""
|
||||
return self._state
|
||||
|
||||
def _reset_state(self, call):
|
||||
self._state = False
|
||||
self._delay_after = None
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
def _handle_code(self, call):
|
||||
"""Handle received code by the pilight-daemon.
|
||||
|
||||
If the code matches the defined playload
|
||||
of this sensor the sensor state is changed accordingly.
|
||||
"""
|
||||
# Check if received code matches defined playoad
|
||||
# True if payload is contained in received code dict
|
||||
payload_ok = True
|
||||
for key in self._payload:
|
||||
if key not in call.data:
|
||||
payload_ok = False
|
||||
continue
|
||||
if self._payload[key] != call.data[key]:
|
||||
payload_ok = False
|
||||
# Read out variable if payload ok
|
||||
if payload_ok:
|
||||
if self._variable not in call.data:
|
||||
return
|
||||
value = call.data[self._variable]
|
||||
self._state = (value == self._on_value)
|
||||
if self._delay_after is None:
|
||||
self._delay_after = dt_util.utcnow() + datetime.timedelta(
|
||||
seconds=self._reset_delay_sec)
|
||||
track_point_in_time(
|
||||
self._hass, self._reset_state,
|
||||
self._delay_after)
|
||||
self.schedule_update_ha_state()
|
|
@ -35,6 +35,9 @@ SCAN_INTERVAL = timedelta(minutes=5)
|
|||
PING_MATCHER = re.compile(
|
||||
r'(?P<min>\d+.\d+)\/(?P<avg>\d+.\d+)\/(?P<max>\d+.\d+)\/(?P<mdev>\d+.\d+)')
|
||||
|
||||
WIN32_PING_MATCHER = re.compile(
|
||||
r'(?P<min>\d+)ms.+(?P<max>\d+)ms.+(?P<avg>\d+)ms')
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_HOST): cv.string,
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
|
@ -102,7 +105,7 @@ class PingData(object):
|
|||
|
||||
if sys.platform == 'win32':
|
||||
self._ping_cmd = [
|
||||
'ping', '-n', str(self._count), '-w 1000', self._ip_address]
|
||||
'ping', '-n', str(self._count), '-w', '1000', self._ip_address]
|
||||
else:
|
||||
self._ping_cmd = [
|
||||
'ping', '-n', '-q', '-c', str(self._count), '-W1',
|
||||
|
@ -114,13 +117,23 @@ class PingData(object):
|
|||
self._ping_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
try:
|
||||
out = pinger.communicate()
|
||||
match = PING_MATCHER.search(str(out).split('\n')[-1])
|
||||
rtt_min, rtt_avg, rtt_max, rtt_mdev = match.groups()
|
||||
return {
|
||||
'min': rtt_min,
|
||||
'avg': rtt_avg,
|
||||
'max': rtt_max,
|
||||
'mdev': rtt_mdev}
|
||||
_LOGGER.debug("Output is %s", str(out))
|
||||
if sys.platform == 'win32':
|
||||
match = WIN32_PING_MATCHER.search(str(out).split('\n')[-1])
|
||||
rtt_min, rtt_avg, rtt_max = match.groups()
|
||||
return {
|
||||
'min': rtt_min,
|
||||
'avg': rtt_avg,
|
||||
'max': rtt_max,
|
||||
'mdev': ''}
|
||||
else:
|
||||
match = PING_MATCHER.search(str(out).split('\n')[-1])
|
||||
rtt_min, rtt_avg, rtt_max, rtt_mdev = match.groups()
|
||||
return {
|
||||
'min': rtt_min,
|
||||
'avg': rtt_avg,
|
||||
'max': rtt_max,
|
||||
'mdev': rtt_mdev}
|
||||
except (subprocess.CalledProcessError, AttributeError):
|
||||
return False
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the REST binary sensor."""
|
||||
"""Set up the REST binary sensor."""
|
||||
name = config.get(CONF_NAME)
|
||||
resource = config.get(CONF_RESOURCE)
|
||||
method = config.get(CONF_METHOD)
|
||||
|
@ -114,8 +114,8 @@ class RestBinarySensor(BinarySensorDevice):
|
|||
try:
|
||||
return bool(int(response))
|
||||
except ValueError:
|
||||
return {"true": True, "on": True, "open": True,
|
||||
"yes": True}.get(response.lower(), False)
|
||||
return {'true': True, 'on': True, 'open': True,
|
||||
'yes': True}.get(response.lower(), False)
|
||||
|
||||
def update(self):
|
||||
"""Get the latest data from REST API and updates the state."""
|
||||
|
|
|
@ -41,10 +41,10 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Raspberry PI GPIO devices."""
|
||||
pull_mode = config.get('pull_mode', DEFAULT_PULL_MODE)
|
||||
bouncetime = config.get('bouncetime', DEFAULT_BOUNCETIME)
|
||||
invert_logic = config.get('invert_logic', DEFAULT_INVERT_LOGIC)
|
||||
"""Set up the Raspberry PI GPIO devices."""
|
||||
pull_mode = config.get(CONF_PULL_MODE)
|
||||
bouncetime = config.get(CONF_BOUNCETIME)
|
||||
invert_logic = config.get(CONF_INVERT_LOGIC)
|
||||
|
||||
binary_sensors = []
|
||||
ports = config.get('ports')
|
||||
|
|
|
@ -11,7 +11,7 @@ DEPENDENCIES = ['sleepiq']
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the SleepIQ sensors."""
|
||||
"""Set up the SleepIQ sensors."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
|
|
|
@ -27,5 +27,5 @@ class TcpBinarySensor(BinarySensorDevice, TcpSensor):
|
|||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""True if the binary sensor is on."""
|
||||
"""Return true if the binary sensor is on."""
|
||||
return self._state == self._config[CONF_VALUE_ON]
|
||||
|
|
|
@ -41,7 +41,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup template binary sensors."""
|
||||
"""Set up template binary sensors."""
|
||||
sensors = []
|
||||
|
||||
for device, device_config in config[CONF_SENSORS].items():
|
||||
|
@ -57,15 +57,11 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
|
||||
sensors.append(
|
||||
BinarySensorTemplate(
|
||||
hass,
|
||||
device,
|
||||
friendly_name,
|
||||
device_class,
|
||||
value_template,
|
||||
hass, device, friendly_name, device_class, value_template,
|
||||
entity_ids)
|
||||
)
|
||||
if not sensors:
|
||||
_LOGGER.error('No sensors added')
|
||||
_LOGGER.error("No sensors added")
|
||||
return False
|
||||
|
||||
async_add_devices(sensors, True)
|
||||
|
@ -79,8 +75,8 @@ class BinarySensorTemplate(BinarySensorDevice):
|
|||
value_template, entity_ids):
|
||||
"""Initialize the Template binary sensor."""
|
||||
self.hass = hass
|
||||
self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device,
|
||||
hass=hass)
|
||||
self.entity_id = async_generate_entity_id(
|
||||
ENTITY_ID_FORMAT, device, hass=hass)
|
||||
self._name = friendly_name
|
||||
self._device_class = device_class
|
||||
self._template = value_template
|
||||
|
@ -96,7 +92,7 @@ class BinarySensorTemplate(BinarySensorDevice):
|
|||
|
||||
@callback
|
||||
def template_bsensor_state_listener(entity, old_state, new_state):
|
||||
"""Called when the target device changes state."""
|
||||
"""Handle the target device state changes."""
|
||||
self.hass.async_add_job(self.async_update_ha_state(True))
|
||||
|
||||
@callback
|
||||
|
@ -139,8 +135,8 @@ class BinarySensorTemplate(BinarySensorDevice):
|
|||
if ex.args and ex.args[0].startswith(
|
||||
"UndefinedError: 'None' has no attribute"):
|
||||
# Common during HA startup - so just a warning
|
||||
_LOGGER.warning('Could not render template %s,'
|
||||
' the state is unknown.', self._name)
|
||||
_LOGGER.warning("Could not render template %s, "
|
||||
"the state is unknown", self._name)
|
||||
return
|
||||
_LOGGER.error('Could not render template %s: %s', self._name, ex)
|
||||
_LOGGER.error("Could not render template %s: %s", self._name, ex)
|
||||
self._state = False
|
||||
|
|
|
@ -77,7 +77,7 @@ class ThresholdSensor(BinarySensorDevice):
|
|||
# pylint: disable=invalid-name
|
||||
def async_threshold_sensor_state_listener(
|
||||
entity, old_state, new_state):
|
||||
"""Called when the sensor changes state."""
|
||||
"""Handle sensor state changes."""
|
||||
if new_state.state == STATE_UNKNOWN:
|
||||
return
|
||||
|
||||
|
|
|
@ -6,22 +6,18 @@ https://home-assistant.io/components/sensor.trend/
|
|||
"""
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.core import callback
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDevice,
|
||||
ENTITY_ID_FORMAT,
|
||||
PLATFORM_SCHEMA,
|
||||
BinarySensorDevice, ENTITY_ID_FORMAT, PLATFORM_SCHEMA,
|
||||
DEVICE_CLASSES_SCHEMA)
|
||||
from homeassistant.const import (
|
||||
ATTR_FRIENDLY_NAME,
|
||||
ATTR_ENTITY_ID,
|
||||
CONF_SENSOR_CLASS,
|
||||
CONF_DEVICE_CLASS,
|
||||
STATE_UNKNOWN,)
|
||||
ATTR_FRIENDLY_NAME, ATTR_ENTITY_ID, CONF_SENSOR_CLASS,
|
||||
CONF_DEVICE_CLASS, STATE_UNKNOWN,)
|
||||
from homeassistant.helpers.deprecation import get_deprecated
|
||||
from homeassistant.helpers.entity import generate_entity_id
|
||||
from homeassistant.helpers.event import track_state_change
|
||||
|
@ -47,7 +43,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the trend sensors."""
|
||||
"""Set up the trend sensors."""
|
||||
sensors = []
|
||||
|
||||
for device, device_config in config[CONF_SENSORS].items():
|
||||
|
@ -60,13 +56,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
|
||||
sensors.append(
|
||||
SensorTrend(
|
||||
hass,
|
||||
device,
|
||||
friendly_name,
|
||||
entity_id,
|
||||
attribute,
|
||||
device_class,
|
||||
invert)
|
||||
hass, device, friendly_name, entity_id, attribute,
|
||||
device_class, invert)
|
||||
)
|
||||
if not sensors:
|
||||
_LOGGER.error("No sensors added")
|
||||
|
@ -82,8 +73,8 @@ class SensorTrend(BinarySensorDevice):
|
|||
target_entity, attribute, device_class, invert):
|
||||
"""Initialize the sensor."""
|
||||
self._hass = hass
|
||||
self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device_id,
|
||||
hass=hass)
|
||||
self.entity_id = generate_entity_id(
|
||||
ENTITY_ID_FORMAT, device_id, hass=hass)
|
||||
self._name = friendly_name
|
||||
self._target_entity = target_entity
|
||||
self._attribute = attribute
|
||||
|
@ -95,7 +86,7 @@ class SensorTrend(BinarySensorDevice):
|
|||
|
||||
@callback
|
||||
def trend_sensor_state_listener(entity, old_state, new_state):
|
||||
"""Called when the target device changes state."""
|
||||
"""Handle the target device state changes."""
|
||||
self.from_state = old_state
|
||||
self.to_state = new_state
|
||||
hass.async_add_job(self.async_update_ha_state(True))
|
||||
|
|
|
@ -3,7 +3,6 @@ Support for VOC.
|
|||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/binary_sensor.volvooncall/
|
||||
|
||||
"""
|
||||
import logging
|
||||
|
||||
|
@ -14,7 +13,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup Volvo sensors."""
|
||||
"""Set up the Volvo sensors."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
add_devices([VolvoSensor(hass, *discovery_info)])
|
||||
|
@ -28,7 +27,7 @@ class VolvoSensor(VolvoEntity, BinarySensorDevice):
|
|||
"""Return True if the binary sensor is on."""
|
||||
val = getattr(self.vehicle, self._attribute)
|
||||
if self._attribute == 'bulb_failures':
|
||||
return len(val) > 0
|
||||
return bool(val)
|
||||
elif self._attribute in ['doors', 'windows']:
|
||||
return any([val[key] for key in val if 'Open' in key])
|
||||
else:
|
||||
|
|
|
@ -29,7 +29,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
|||
|
||||
|
||||
class WemoBinarySensor(BinarySensorDevice):
|
||||
"""Represents a WeMo binary sensor."""
|
||||
"""Representation a WeMo binary sensor."""
|
||||
|
||||
def __init__(self, device):
|
||||
"""Initialize the WeMo sensor."""
|
||||
|
@ -41,10 +41,8 @@ class WemoBinarySensor(BinarySensorDevice):
|
|||
wemo.SUBSCRIPTION_REGISTRY.on(self.wemo, None, self._update_callback)
|
||||
|
||||
def _update_callback(self, _device, _type, _params):
|
||||
"""Called by the Wemo device callback to update state."""
|
||||
_LOGGER.info(
|
||||
'Subscription update for %s',
|
||||
_device)
|
||||
"""Handle state changes."""
|
||||
_LOGGER.info("Subscription update for %s", _device)
|
||||
updated = self.wemo.subscription_update(_type, _params)
|
||||
self._update(force_update=(not updated))
|
||||
|
||||
|
@ -60,7 +58,7 @@ class WemoBinarySensor(BinarySensorDevice):
|
|||
@property
|
||||
def unique_id(self):
|
||||
"""Return the id of this WeMo device."""
|
||||
return "{}.{}".format(self.__class__, self.wemo.serialnumber)
|
||||
return '{}.{}'.format(self.__class__, self.wemo.serialnumber)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
@ -69,7 +67,7 @@ class WemoBinarySensor(BinarySensorDevice):
|
|||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""True if sensor is on."""
|
||||
"""Return true if sensor is on."""
|
||||
return self._state
|
||||
|
||||
def update(self):
|
||||
|
@ -80,5 +78,5 @@ class WemoBinarySensor(BinarySensorDevice):
|
|||
try:
|
||||
self._state = self.wemo.get_state(force_update)
|
||||
except AttributeError as err:
|
||||
_LOGGER.warning('Could not update status for %s (%s)',
|
||||
self.name, err)
|
||||
_LOGGER.warning(
|
||||
"Could not update status for %s (%s)", self.name, err)
|
||||
|
|
|
@ -16,23 +16,23 @@ DEPENDENCIES = ['wink']
|
|||
|
||||
# These are the available sensors mapped to binary_sensor class
|
||||
SENSOR_TYPES = {
|
||||
"opened": "opening",
|
||||
"brightness": "light",
|
||||
"vibration": "vibration",
|
||||
"loudness": "sound",
|
||||
"noise": "sound",
|
||||
"capturing_audio": "sound",
|
||||
"liquid_detected": "moisture",
|
||||
"motion": "motion",
|
||||
"presence": "occupancy",
|
||||
"co_detected": "gas",
|
||||
"smoke_detected": "smoke",
|
||||
"capturing_video": None
|
||||
'opened': 'opening',
|
||||
'brightness': 'light',
|
||||
'vibration': 'vibration',
|
||||
'loudness': 'sound',
|
||||
'noise': 'sound',
|
||||
'capturing_audio': 'sound',
|
||||
'liquid_detected': 'moisture',
|
||||
'motion': 'motion',
|
||||
'presence': 'occupancy',
|
||||
'co_detected': 'gas',
|
||||
'smoke_detected': 'smoke',
|
||||
'capturing_video': None
|
||||
}
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Wink binary sensor platform."""
|
||||
"""Set up the Wink binary sensor platform."""
|
||||
import pywink
|
||||
|
||||
for sensor in pywink.get_sensors():
|
||||
|
@ -83,7 +83,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
if camera_sensor.capability() in SENSOR_TYPES:
|
||||
add_devices([WinkBinarySensorDevice(camera_sensor, hass)])
|
||||
except AttributeError:
|
||||
_LOGGER.info("Device isn't a sensor, skipping.")
|
||||
_LOGGER.info("Device isn't a sensor, skipping")
|
||||
|
||||
|
||||
class WinkBinarySensorDevice(WinkDevice, BinarySensorDevice, Entity):
|
||||
|
|
|
@ -11,10 +11,9 @@ import datetime
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||
from homeassistant.const import (
|
||||
STATE_ON, STATE_OFF, STATE_UNKNOWN, CONF_NAME, WEEKDAYS)
|
||||
from homeassistant.const import CONF_NAME, WEEKDAYS
|
||||
import homeassistant.util.dt as dt_util
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -66,15 +65,20 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
obj_holidays = getattr(holidays, country)(years=year)
|
||||
|
||||
if province:
|
||||
if province not in obj_holidays.PROVINCES and \
|
||||
province not in obj_holidays.STATES:
|
||||
# 'state' and 'prov' are not interchangeable, so need to make
|
||||
# sure we use the right one
|
||||
if (hasattr(obj_holidays, "PROVINCES") and
|
||||
province in obj_holidays.PROVINCES):
|
||||
obj_holidays = getattr(holidays, country)(prov=province,
|
||||
years=year)
|
||||
elif (hasattr(obj_holidays, "STATES") and
|
||||
province in obj_holidays.STATES):
|
||||
obj_holidays = getattr(holidays, country)(state=province,
|
||||
years=year)
|
||||
else:
|
||||
_LOGGER.error("There is no province/state %s in country %s",
|
||||
province, country)
|
||||
return False
|
||||
else:
|
||||
year = datetime.datetime.now().year
|
||||
obj_holidays = getattr(holidays, country)(prov=province,
|
||||
years=year)
|
||||
|
||||
_LOGGER.debug("Found the following holidays for your configuration:")
|
||||
for date, name in sorted(obj_holidays.items()):
|
||||
|
@ -92,7 +96,7 @@ def day_to_string(day):
|
|||
return None
|
||||
|
||||
|
||||
class IsWorkdaySensor(Entity):
|
||||
class IsWorkdaySensor(BinarySensorDevice):
|
||||
"""Implementation of a Workday sensor."""
|
||||
|
||||
def __init__(self, obj_holidays, workdays, excludes, name):
|
||||
|
@ -101,7 +105,7 @@ class IsWorkdaySensor(Entity):
|
|||
self._obj_holidays = obj_holidays
|
||||
self._workdays = workdays
|
||||
self._excludes = excludes
|
||||
self._state = STATE_UNKNOWN
|
||||
self._state = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
@ -109,7 +113,7 @@ class IsWorkdaySensor(Entity):
|
|||
return self._name
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def is_on(self):
|
||||
"""Return the state of the device."""
|
||||
return self._state
|
||||
|
||||
|
@ -135,14 +139,14 @@ class IsWorkdaySensor(Entity):
|
|||
def async_update(self):
|
||||
"""Get date and look whether it is a holiday."""
|
||||
# Default is no workday
|
||||
self._state = STATE_OFF
|
||||
self._state = False
|
||||
|
||||
# Get iso day of the week (1 = Monday, 7 = Sunday)
|
||||
day = datetime.datetime.today().isoweekday() - 1
|
||||
day_of_week = day_to_string(day)
|
||||
|
||||
if self.is_include(day_of_week, dt_util.now()):
|
||||
self._state = STATE_ON
|
||||
self._state = True
|
||||
|
||||
if self.is_exclude(day_of_week, dt_util.now()):
|
||||
self._state = STATE_OFF
|
||||
self._state = False
|
||||
|
|
89
homeassistant/components/binary_sensor/zha.py
Normal file
89
homeassistant/components/binary_sensor/zha.py
Normal file
|
@ -0,0 +1,89 @@
|
|||
"""
|
||||
Binary sensors on Zigbee Home Automation networks.
|
||||
|
||||
For more details on this platform, please refer to the documentation
|
||||
at https://home-assistant.io/components/binary_sensor.zha/
|
||||
"""
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
from homeassistant.components.binary_sensor import DOMAIN, BinarySensorDevice
|
||||
from homeassistant.components import zha
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['zha']
|
||||
|
||||
# ZigBee Cluster Library Zone Type to Home Assistant device class
|
||||
CLASS_MAPPING = {
|
||||
0x000d: 'motion',
|
||||
0x0015: 'opening',
|
||||
0x0028: 'smoke',
|
||||
0x002a: 'moisture',
|
||||
0x002b: 'gas',
|
||||
0x002d: 'vibration',
|
||||
}
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Set up the Zigbee Home Automation binary sensors."""
|
||||
discovery_info = zha.get_discovery_info(hass, discovery_info)
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
from bellows.zigbee.zcl.clusters.security import IasZone
|
||||
|
||||
clusters = discovery_info['clusters']
|
||||
|
||||
device_class = None
|
||||
cluster = [c for c in clusters if isinstance(c, IasZone)][0]
|
||||
if discovery_info['new_join']:
|
||||
yield from cluster.bind()
|
||||
ieee = cluster.endpoint.device.application.ieee
|
||||
yield from cluster.write_attributes({'cie_addr': ieee})
|
||||
|
||||
try:
|
||||
zone_type = yield from cluster['zone_type']
|
||||
device_class = CLASS_MAPPING.get(zone_type, None)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
# If we fail to read from the device, use a non-specific class
|
||||
pass
|
||||
|
||||
sensor = BinarySensor(device_class, **discovery_info)
|
||||
async_add_devices([sensor])
|
||||
|
||||
|
||||
class BinarySensor(zha.Entity, BinarySensorDevice):
|
||||
"""THe ZHA Binary Sensor."""
|
||||
|
||||
_domain = DOMAIN
|
||||
|
||||
def __init__(self, device_class, **kwargs):
|
||||
"""Initialize the ZHA binary sensor."""
|
||||
super().__init__(**kwargs)
|
||||
self._device_class = device_class
|
||||
from bellows.zigbee.zcl.clusters.security import IasZone
|
||||
self._ias_zone_cluster = self._clusters[IasZone.cluster_id]
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return True if entity is on."""
|
||||
if self._state == 'unknown':
|
||||
return False
|
||||
return bool(self._state)
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Return the class of this device, from component DEVICE_CLASSES."""
|
||||
return self._device_class
|
||||
|
||||
def cluster_command(self, aps_frame, tsn, command_id, args):
|
||||
"""Handle commands received to this cluster."""
|
||||
if command_id == 0:
|
||||
self._state = args[0] & 3
|
||||
_LOGGER.debug("Updated alarm state: %s", self._state)
|
||||
self.schedule_update_ha_state()
|
||||
elif command_id == 1:
|
||||
_LOGGER.debug("Enroll requested")
|
||||
self.hass.add_job(self._ias_zone_cluster.enroll_response(0, 0))
|
|
@ -23,7 +23,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the ZigBee binary sensor platform."""
|
||||
"""Set up the ZigBee binary sensor platform."""
|
||||
add_devices(
|
||||
[ZigBeeBinarySensor(hass, ZigBeeDigitalInConfig(config))], True)
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ DEPENDENCIES = []
|
|||
|
||||
|
||||
def get_device(values, **kwargs):
|
||||
"""Create zwave entity device."""
|
||||
"""Create Z-Wave entity device."""
|
||||
device_mapping = workaround.get_device_mapping(values.primary)
|
||||
if device_mapping == workaround.WORKAROUND_NO_OFF_EVENT:
|
||||
# Default the multiplier to 4
|
||||
|
@ -45,12 +45,12 @@ class ZWaveBinarySensor(BinarySensorDevice, zwave.ZWaveDeviceEntity):
|
|||
self._state = self.values.primary.data
|
||||
|
||||
def update_properties(self):
|
||||
"""Callback on data changes for node values."""
|
||||
"""Handle data changes for node values."""
|
||||
self._state = self.values.primary.data
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return True if the binary sensor is on."""
|
||||
"""Return true if the binary sensor is on."""
|
||||
return self._state
|
||||
|
||||
@property
|
||||
|
@ -69,7 +69,7 @@ class ZWaveTriggerSensor(ZWaveBinarySensor):
|
|||
self.invalidate_after = None
|
||||
|
||||
def update_properties(self):
|
||||
"""Called when a value for this entity's node has changed."""
|
||||
"""Handle value changes for this entity's node."""
|
||||
self._state = self.values.primary.data
|
||||
# only allow this value to be true for re_arm secs
|
||||
if not self.hass:
|
||||
|
@ -83,7 +83,7 @@ class ZWaveTriggerSensor(ZWaveBinarySensor):
|
|||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return True if movement has happened within the rearm time."""
|
||||
"""Return true if movement has happened within the rearm time."""
|
||||
return self._state and \
|
||||
(self.invalidate_after is None or
|
||||
self.invalidate_after > dt_util.utcnow())
|
||||
|
|
|
@ -35,7 +35,7 @@ CONFIG_SCHEMA = vol.Schema({
|
|||
|
||||
# pylint: disable=unused-argument
|
||||
def setup(hass, config):
|
||||
"""Setup BloomSky component."""
|
||||
"""Set up the BloomSky component."""
|
||||
api_key = config[DOMAIN][CONF_API_KEY]
|
||||
|
||||
global BLOOMSKY
|
||||
|
@ -67,9 +67,8 @@ class BloomSky(object):
|
|||
def refresh_devices(self):
|
||||
"""Use the API to retrieve a list of devices."""
|
||||
_LOGGER.debug("Fetching BloomSky update")
|
||||
response = requests.get(self.API_URL,
|
||||
headers={"Authorization": self._api_key},
|
||||
timeout=10)
|
||||
response = requests.get(
|
||||
self.API_URL, headers={"Authorization": self._api_key}, timeout=10)
|
||||
if response.status_code == 401:
|
||||
raise RuntimeError("Invalid API_KEY")
|
||||
elif response.status_code != 200:
|
||||
|
|
|
@ -7,12 +7,10 @@ https://home-assistant.io/components/calendar/
|
|||
import asyncio
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
import re
|
||||
|
||||
from homeassistant.components.google import (CONF_OFFSET,
|
||||
CONF_DEVICE_ID,
|
||||
CONF_NAME)
|
||||
from homeassistant.components.google import (
|
||||
CONF_OFFSET, CONF_DEVICE_ID, CONF_NAME)
|
||||
from homeassistant.const import STATE_OFF, STATE_ON
|
||||
from homeassistant.helpers.config_validation import time_period_str
|
||||
from homeassistant.helpers.entity import Entity, generate_entity_id
|
||||
|
@ -22,16 +20,18 @@ from homeassistant.util import dt
|
|||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SCAN_INTERVAL = timedelta(seconds=60)
|
||||
DOMAIN = 'calendar'
|
||||
|
||||
ENTITY_ID_FORMAT = DOMAIN + '.{}'
|
||||
|
||||
SCAN_INTERVAL = timedelta(seconds=60)
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_setup(hass, config):
|
||||
"""Track states and offer events for calendars."""
|
||||
component = EntityComponent(
|
||||
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL, DOMAIN)
|
||||
_LOGGER, DOMAIN, hass, SCAN_INTERVAL, DOMAIN)
|
||||
|
||||
yield from component.async_setup(config)
|
||||
return True
|
||||
|
@ -55,9 +55,8 @@ class CalendarEventDevice(Entity):
|
|||
self._name = data.get(CONF_NAME)
|
||||
self.dev_id = data.get(CONF_DEVICE_ID)
|
||||
self._offset = data.get(CONF_OFFSET, DEFAULT_CONF_OFFSET)
|
||||
self.entity_id = generate_entity_id(ENTITY_ID_FORMAT,
|
||||
self.dev_id,
|
||||
hass=hass)
|
||||
self.entity_id = generate_entity_id(
|
||||
ENTITY_ID_FORMAT, self.dev_id, hass=hass)
|
||||
|
||||
self._cal_data = {
|
||||
'all_day': False,
|
||||
|
@ -87,7 +86,7 @@ class CalendarEventDevice(Entity):
|
|||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""State Attributes for HA."""
|
||||
"""Return the device state attributes."""
|
||||
start = self._cal_data.get('start', None)
|
||||
end = self._cal_data.get('end', None)
|
||||
start = start.strftime(DATE_STR_FORMAT) if start is not None else None
|
||||
|
|
|
@ -10,7 +10,7 @@ from homeassistant.components.google import CONF_DEVICE_ID, CONF_NAME
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Demo binary sensor platform."""
|
||||
"""Set up the Demo Calendar platform."""
|
||||
calendar_data_future = DemoGoogleCalendarDataFuture()
|
||||
calendar_data_current = DemoGoogleCalendarDataCurrent()
|
||||
add_devices([
|
||||
|
@ -27,7 +27,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
|
||||
|
||||
class DemoGoogleCalendarData(object):
|
||||
"""Setup base class for data."""
|
||||
"""Representation of a Demo Calendar element."""
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
def update(self):
|
||||
|
@ -36,7 +36,7 @@ class DemoGoogleCalendarData(object):
|
|||
|
||||
|
||||
class DemoGoogleCalendarDataFuture(DemoGoogleCalendarData):
|
||||
"""Setup future data event."""
|
||||
"""Representation of a Demo Calendar for a future event."""
|
||||
|
||||
def __init__(self):
|
||||
"""Set the event to a future event."""
|
||||
|
@ -55,7 +55,7 @@ class DemoGoogleCalendarDataFuture(DemoGoogleCalendarData):
|
|||
|
||||
|
||||
class DemoGoogleCalendarDataCurrent(DemoGoogleCalendarData):
|
||||
"""Create a current event we're in the middle of."""
|
||||
"""Representation of a Demo Calendar for a current event."""
|
||||
|
||||
def __init__(self):
|
||||
"""Set the event data."""
|
||||
|
@ -74,9 +74,9 @@ class DemoGoogleCalendarDataCurrent(DemoGoogleCalendarData):
|
|||
|
||||
|
||||
class DemoGoogleCalendar(CalendarEventDevice):
|
||||
"""A Demo binary sensor."""
|
||||
"""Representation of a Demo Calendar element."""
|
||||
|
||||
def __init__(self, hass, calendar_data, data):
|
||||
"""The same as a google calendar but without the api calls."""
|
||||
"""Initialize Google Calendar but without the API calls."""
|
||||
self.data = calendar_data
|
||||
super().__init__(hass, data)
|
||||
|
|
|
@ -9,25 +9,24 @@ import logging
|
|||
from datetime import timedelta
|
||||
|
||||
from homeassistant.components.calendar import CalendarEventDevice
|
||||
from homeassistant.components.google import (CONF_CAL_ID, CONF_ENTITIES,
|
||||
CONF_TRACK, TOKEN_FILE,
|
||||
GoogleCalendarService)
|
||||
from homeassistant.components.google import (
|
||||
CONF_CAL_ID, CONF_ENTITIES, CONF_TRACK, TOKEN_FILE,
|
||||
GoogleCalendarService)
|
||||
from homeassistant.util import Throttle, dt
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_GOOGLE_SEARCH_PARAMS = {
|
||||
'orderBy': 'startTime',
|
||||
'maxResults': 1,
|
||||
'singleEvents': True,
|
||||
}
|
||||
|
||||
# Return cached results if last scan was less then this time ago
|
||||
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=15)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, disc_info=None):
|
||||
"""Setup the calendar platform for event devices."""
|
||||
"""Set up the calendar platform for event devices."""
|
||||
if disc_info is None:
|
||||
return
|
||||
|
||||
|
@ -55,7 +54,7 @@ class GoogleCalendarData(object):
|
|||
"""Class to utilize calendar service object to get next event."""
|
||||
|
||||
def __init__(self, calendar_service, calendar_id, search=None):
|
||||
"""Setup how we are going to search the google calendar."""
|
||||
"""Set up how we are going to search the google calendar."""
|
||||
self.calendar_service = calendar_service
|
||||
self.calendar_id = calendar_id
|
||||
self.search = search
|
||||
|
|
|
@ -76,7 +76,7 @@ def async_get_image(hass, entity_id, timeout=10):
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup(hass, config):
|
||||
"""Setup the camera component."""
|
||||
"""Set up the camera component."""
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL)
|
||||
|
||||
hass.http.register_view(CameraImageView(component.entities))
|
||||
|
@ -121,12 +121,12 @@ class Camera(Entity):
|
|||
|
||||
@property
|
||||
def brand(self):
|
||||
"""Camera brand."""
|
||||
"""Return the camera brand."""
|
||||
return None
|
||||
|
||||
@property
|
||||
def model(self):
|
||||
"""Camera model."""
|
||||
"""Return the camera model."""
|
||||
return None
|
||||
|
||||
def camera_image(self):
|
||||
|
@ -191,7 +191,7 @@ class Camera(Entity):
|
|||
|
||||
@property
|
||||
def state(self):
|
||||
"""Camera state."""
|
||||
"""Return the camera state."""
|
||||
if self.is_recording:
|
||||
return STATE_RECORDING
|
||||
elif self.is_streaming:
|
||||
|
@ -201,7 +201,7 @@ class Camera(Entity):
|
|||
|
||||
@property
|
||||
def state_attributes(self):
|
||||
"""Camera state attributes."""
|
||||
"""Return the camera state attributes."""
|
||||
attr = {
|
||||
'access_token': self.access_tokens[-1],
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ class CameraView(HomeAssistantView):
|
|||
|
||||
@asyncio.coroutine
|
||||
def get(self, request, entity_id):
|
||||
"""Start a get request."""
|
||||
"""Start a GET request."""
|
||||
camera = self.entities.get(entity_id)
|
||||
|
||||
if camera is None:
|
||||
|
@ -251,15 +251,15 @@ class CameraView(HomeAssistantView):
|
|||
|
||||
@asyncio.coroutine
|
||||
def handle(self, request, camera):
|
||||
"""Hanlde the camera request."""
|
||||
"""Handle the camera request."""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class CameraImageView(CameraView):
|
||||
"""Camera view to serve an image."""
|
||||
|
||||
url = "/api/camera_proxy/{entity_id}"
|
||||
name = "api:camera:image"
|
||||
url = '/api/camera_proxy/{entity_id}'
|
||||
name = 'api:camera:image'
|
||||
|
||||
@asyncio.coroutine
|
||||
def handle(self, request, camera):
|
||||
|
@ -277,8 +277,8 @@ class CameraImageView(CameraView):
|
|||
class CameraMjpegStream(CameraView):
|
||||
"""Camera View to serve an MJPEG stream."""
|
||||
|
||||
url = "/api/camera_proxy_stream/{entity_id}"
|
||||
name = "api:camera:stream"
|
||||
url = '/api/camera_proxy_stream/{entity_id}'
|
||||
name = 'api:camera:stream'
|
||||
|
||||
@asyncio.coroutine
|
||||
def handle(self, request, camera):
|
||||
|
|
|
@ -21,7 +21,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup a Blink Camera."""
|
||||
"""Set up a Blink Camera."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
|
@ -49,19 +49,19 @@ class BlinkCamera(Camera):
|
|||
|
||||
@property
|
||||
def name(self):
|
||||
"""A camera name."""
|
||||
"""Return the camera name."""
|
||||
return self._name
|
||||
|
||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
def request_image(self):
|
||||
"""An image request from Blink servers."""
|
||||
"""Request a new image from Blink servers."""
|
||||
_LOGGER.info("Requesting new image from blink servers")
|
||||
image_url = self.check_for_motion()
|
||||
header = self.data.cameras[self._name].header
|
||||
self.response = requests.get(image_url, headers=header, stream=True)
|
||||
|
||||
def check_for_motion(self):
|
||||
"""A method to check if motion has been detected since last update."""
|
||||
"""Check if motion has been detected since last update."""
|
||||
self.data.refresh()
|
||||
notifs = self.data.cameras[self._name].notifications
|
||||
if notifs > self.notifications:
|
||||
|
|
|
@ -16,7 +16,7 @@ DEPENDENCIES = ['bloomsky']
|
|||
|
||||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup access to BloomSky cameras."""
|
||||
"""Set up access to BloomSky cameras."""
|
||||
bloomsky = get_component('bloomsky')
|
||||
for device in bloomsky.BLOOMSKY.devices.values():
|
||||
add_devices([BloomSkyCamera(bloomsky.BLOOMSKY, device)])
|
||||
|
@ -26,14 +26,14 @@ class BloomSkyCamera(Camera):
|
|||
"""Representation of the images published from the BloomSky's camera."""
|
||||
|
||||
def __init__(self, bs, device):
|
||||
"""Setup for access to the BloomSky camera images."""
|
||||
"""Initialize access to the BloomSky camera images."""
|
||||
super(BloomSkyCamera, self).__init__()
|
||||
self._name = device['DeviceName']
|
||||
self._id = device['DeviceID']
|
||||
self._bloomsky = bs
|
||||
self._url = ""
|
||||
self._last_url = ""
|
||||
# _last_image will store images as they are downloaded so that the
|
||||
# last_image will store images as they are downloaded so that the
|
||||
# frequent updates in home-assistant don't keep poking the server
|
||||
# to download the same image over and over.
|
||||
self._last_image = ""
|
||||
|
|
|
@ -11,7 +11,7 @@ from homeassistant.components.camera import Camera
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Demo camera platform."""
|
||||
"""Set up the Demo camera platform."""
|
||||
add_devices([
|
||||
DemoCamera('Demo camera')
|
||||
])
|
||||
|
@ -29,8 +29,8 @@ class DemoCamera(Camera):
|
|||
"""Return a faked still image response."""
|
||||
now = dt_util.utcnow()
|
||||
|
||||
image_path = os.path.join(os.path.dirname(__file__),
|
||||
'demo_{}.jpg'.format(now.second % 4))
|
||||
image_path = os.path.join(
|
||||
os.path.dirname(__file__), 'demo_{}.jpg'.format(now.second % 4))
|
||||
with open(image_path, 'rb') as file:
|
||||
return file.read()
|
||||
|
||||
|
|
|
@ -16,10 +16,10 @@ from homeassistant.components.ffmpeg import (
|
|||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.aiohttp_client import (
|
||||
async_aiohttp_proxy_stream)
|
||||
DEPENDENCIES = ['ffmpeg']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['ffmpeg']
|
||||
DEFAULT_NAME = 'FFmpeg'
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
|
@ -31,7 +31,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup a FFmpeg Camera."""
|
||||
"""Set up a FFmpeg camera."""
|
||||
if not hass.data[DATA_FFMPEG].async_run_test(config.get(CONF_INPUT)):
|
||||
return
|
||||
async_add_devices([FFmpegCamera(hass, config)])
|
||||
|
|
|
@ -32,7 +32,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup a Foscam IP Camera."""
|
||||
"""Set up a Foscam IP Camera."""
|
||||
add_devices([FoscamCamera(config)])
|
||||
|
||||
|
||||
|
@ -60,7 +60,7 @@ class FoscamCamera(Camera):
|
|||
)
|
||||
self._name = device_info.get(CONF_NAME)
|
||||
|
||||
_LOGGER.info('Using the following URL for %s: %s',
|
||||
_LOGGER.info("Using the following URL for %s: %s",
|
||||
self._name, uri_template.format('***', '***'))
|
||||
|
||||
def camera_image(self):
|
||||
|
|
|
@ -43,7 +43,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
@asyncio.coroutine
|
||||
# pylint: disable=unused-argument
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup a generic IP Camera."""
|
||||
"""Set up a generic IP Camera."""
|
||||
async_add_devices([GenericCamera(hass, config)])
|
||||
|
||||
|
||||
|
@ -85,8 +85,8 @@ class GenericCamera(Camera):
|
|||
try:
|
||||
url = self._still_image_url.async_render()
|
||||
except TemplateError as err:
|
||||
_LOGGER.error('Error parsing template %s: %s',
|
||||
self._still_image_url, err)
|
||||
_LOGGER.error(
|
||||
"Error parsing template %s: %s", self._still_image_url, err)
|
||||
return self._last_image
|
||||
|
||||
if url == self._last_url and self._limit_refetch:
|
||||
|
@ -100,7 +100,7 @@ class GenericCamera(Camera):
|
|||
response = requests.get(url, timeout=10, auth=self._auth)
|
||||
return response.content
|
||||
except requests.exceptions.RequestException as error:
|
||||
_LOGGER.error('Error getting camera image: %s', error)
|
||||
_LOGGER.error("Error getting camera image: %s", error)
|
||||
return self._last_image
|
||||
|
||||
self._last_image = yield from self.hass.loop.run_in_executor(
|
||||
|
@ -114,10 +114,10 @@ class GenericCamera(Camera):
|
|||
url, auth=self._auth)
|
||||
self._last_image = yield from response.read()
|
||||
except asyncio.TimeoutError:
|
||||
_LOGGER.error('Timeout getting camera image')
|
||||
_LOGGER.error("Timeout getting camera image")
|
||||
return self._last_image
|
||||
except aiohttp.ClientError as err:
|
||||
_LOGGER.error('Error getting new camera image: %s', err)
|
||||
_LOGGER.error("Error getting new camera image: %s", err)
|
||||
return self._last_image
|
||||
|
||||
self._last_url = url
|
||||
|
|
|
@ -26,7 +26,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Camera."""
|
||||
"""Set up the Camera that works with local files."""
|
||||
file_path = config[CONF_FILE_PATH]
|
||||
|
||||
# check filepath given is readable
|
||||
|
@ -38,7 +38,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
|
||||
|
||||
class LocalFile(Camera):
|
||||
"""Local camera."""
|
||||
"""Representation of a local file camera."""
|
||||
|
||||
def __init__(self, name, file_path):
|
||||
"""Initialize Local File Camera component."""
|
||||
|
|
|
@ -44,7 +44,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
@asyncio.coroutine
|
||||
# pylint: disable=unused-argument
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup a MJPEG IP Camera."""
|
||||
"""Set up a MJPEG IP Camera."""
|
||||
if discovery_info:
|
||||
config = PLATFORM_SCHEMA(discovery_info)
|
||||
async_add_devices([MjpegCamera(hass, config)])
|
||||
|
@ -102,10 +102,10 @@ class MjpegCamera(Camera):
|
|||
return image
|
||||
|
||||
except asyncio.TimeoutError:
|
||||
_LOGGER.error('Timeout getting camera image')
|
||||
_LOGGER.error("Timeout getting camera image")
|
||||
|
||||
except aiohttp.ClientError as err:
|
||||
_LOGGER.error('Error getting new camera image: %s', err)
|
||||
_LOGGER.error("Error getting new camera image: %s", err)
|
||||
|
||||
def camera_image(self):
|
||||
"""Return a still image response from the camera."""
|
||||
|
|
|
@ -32,17 +32,17 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup the Camera."""
|
||||
"""Set up the MQTT Camera."""
|
||||
topic = config[CONF_TOPIC]
|
||||
|
||||
async_add_devices([MqttCamera(config[CONF_NAME], topic)])
|
||||
|
||||
|
||||
class MqttCamera(Camera):
|
||||
"""MQTT camera."""
|
||||
"""representation of a MQTT camera."""
|
||||
|
||||
def __init__(self, name, topic):
|
||||
"""Initialize Local File Camera component."""
|
||||
"""Initialize the MQTT Camera."""
|
||||
super().__init__()
|
||||
|
||||
self._name = name
|
||||
|
@ -61,13 +61,13 @@ class MqttCamera(Camera):
|
|||
return self._name
|
||||
|
||||
def async_added_to_hass(self):
|
||||
"""Subscribe mqtt events.
|
||||
"""Subscribe MQTT events.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
@callback
|
||||
def message_received(topic, payload, qos):
|
||||
"""A new MQTT message has been received."""
|
||||
"""Handle new MQTT messages."""
|
||||
self._last_image = payload
|
||||
|
||||
return mqtt.async_subscribe(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
Camera that loads a picture from a local file.
|
||||
Camera that loads a picture from Neato.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/camera.neato/
|
||||
|
@ -18,12 +18,12 @@ DEPENDENCIES = ['neato']
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Camera."""
|
||||
"""Set up the Neato Camera."""
|
||||
dev = []
|
||||
for robot in hass.data[NEATO_ROBOTS]:
|
||||
if 'maps' in robot.traits:
|
||||
dev.append(NeatoCleaningMap(hass, robot))
|
||||
_LOGGER.debug('Adding robots for cleaning maps %s', dev)
|
||||
_LOGGER.debug("Adding robots for cleaning maps %s", dev)
|
||||
add_devices(dev, True)
|
||||
|
||||
|
||||
|
@ -34,7 +34,7 @@ class NeatoCleaningMap(Camera):
|
|||
"""Initialize Neato cleaning map."""
|
||||
super().__init__()
|
||||
self.robot = robot
|
||||
self._robot_name = self.robot.name + ' Cleaning Map'
|
||||
self._robot_name = '{} {}'.format(self.robot.name, 'Cleaning Map')
|
||||
self._robot_serial = self.robot.serial
|
||||
self.neato = hass.data[NEATO_LOGIN]
|
||||
self._image_url = None
|
||||
|
@ -53,7 +53,7 @@ class NeatoCleaningMap(Camera):
|
|||
map_data = self.hass.data[NEATO_MAP_DATA]
|
||||
image_url = map_data[self._robot_serial]['maps'][0]['url']
|
||||
if image_url == self._image_url:
|
||||
_LOGGER.debug('The map image_url is the same as old')
|
||||
_LOGGER.debug("The map image_url is the same as old")
|
||||
return
|
||||
image = self.neato.download_map(image_url)
|
||||
self._image = image.read()
|
||||
|
|
|
@ -32,7 +32,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup access to Netatmo cameras."""
|
||||
"""Set up access to Netatmo cameras."""
|
||||
netatmo = get_component('netatmo')
|
||||
home = config.get(CONF_HOME)
|
||||
verify_ssl = config.get(CONF_VERIFY_SSL, True)
|
||||
|
@ -55,7 +55,7 @@ class NetatmoCamera(Camera):
|
|||
"""Representation of the images published from a Netatmo camera."""
|
||||
|
||||
def __init__(self, data, camera_name, home, camera_type, verify_ssl):
|
||||
"""Setup for access to the Netatmo camera images."""
|
||||
"""Set up for access to the Netatmo camera images."""
|
||||
super(NetatmoCamera, self).__init__()
|
||||
self._data = data
|
||||
self._camera_name = camera_name
|
||||
|
@ -64,10 +64,10 @@ class NetatmoCamera(Camera):
|
|||
self._name = home + ' / ' + camera_name
|
||||
else:
|
||||
self._name = camera_name
|
||||
camera_id = data.camera_data.cameraByName(camera=camera_name,
|
||||
home=home)['id']
|
||||
self._unique_id = "Welcome_camera {0} - {1}".format(self._name,
|
||||
camera_id)
|
||||
camera_id = data.camera_data.cameraByName(
|
||||
camera=camera_name, home=home)['id']
|
||||
self._unique_id = "Welcome_camera {0} - {1}".format(
|
||||
self._name, camera_id)
|
||||
self._vpnurl, self._localurl = self._data.camera_data.cameraUrls(
|
||||
camera=camera_name
|
||||
)
|
||||
|
@ -83,13 +83,13 @@ class NetatmoCamera(Camera):
|
|||
response = requests.get('{0}/live/snapshot_720.jpg'.format(
|
||||
self._vpnurl), timeout=10, verify=self._verify_ssl)
|
||||
else:
|
||||
_LOGGER.error('Welcome VPN url is None')
|
||||
_LOGGER.error("Welcome VPN URL is None")
|
||||
self._data.update()
|
||||
(self._vpnurl, self._localurl) = \
|
||||
self._data.camera_data.cameraUrls(camera=self._camera_name)
|
||||
return None
|
||||
except requests.exceptions.RequestException as error:
|
||||
_LOGGER.error('Welcome url changed: %s', error)
|
||||
_LOGGER.error("Welcome URL changed: %s", error)
|
||||
self._data.update()
|
||||
(self._vpnurl, self._localurl) = \
|
||||
self._data.camera_data.cameraUrls(camera=self._camera_name)
|
||||
|
@ -103,12 +103,12 @@ class NetatmoCamera(Camera):
|
|||
|
||||
@property
|
||||
def brand(self):
|
||||
"""Camera brand."""
|
||||
"""Return the camera brand."""
|
||||
return "Netatmo"
|
||||
|
||||
@property
|
||||
def model(self):
|
||||
"""Camera model."""
|
||||
"""Return the camera model."""
|
||||
if self._cameratype == "NOC":
|
||||
return "Presence"
|
||||
elif self._cameratype == "NACamera":
|
||||
|
|
|
@ -62,7 +62,7 @@ def kill_raspistill(*args):
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Raspberry Camera."""
|
||||
"""Set up the Raspberry Camera."""
|
||||
if shutil.which("raspistill") is None:
|
||||
_LOGGER.error("'raspistill' was not found")
|
||||
return False
|
||||
|
|
|
@ -59,7 +59,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup a Synology IP Camera."""
|
||||
"""Set up a Synology IP Camera."""
|
||||
verify_ssl = config.get(CONF_VERIFY_SSL)
|
||||
timeout = config.get(CONF_TIMEOUT)
|
||||
websession_init = async_get_clientsession(hass, verify_ssl)
|
||||
|
@ -140,16 +140,8 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
snapshot_path = camera['snapshot_path']
|
||||
|
||||
device = SynologyCamera(
|
||||
hass,
|
||||
websession,
|
||||
config,
|
||||
camera_id,
|
||||
camera['name'],
|
||||
snapshot_path,
|
||||
streaming_path,
|
||||
camera_path,
|
||||
auth_path,
|
||||
timeout
|
||||
hass, websession, config, camera_id, camera['name'],
|
||||
snapshot_path, streaming_path, camera_path, auth_path, timeout
|
||||
)
|
||||
devices.append(device)
|
||||
|
||||
|
|
|
@ -41,13 +41,13 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
try:
|
||||
cameras = nvrconn.index()
|
||||
except nvr.NotAuthorized:
|
||||
_LOGGER.error('Authorization failure while connecting to NVR')
|
||||
_LOGGER.error("Authorization failure while connecting to NVR")
|
||||
return False
|
||||
except nvr.NvrError:
|
||||
_LOGGER.error('NVR refuses to talk to me')
|
||||
_LOGGER.error("NVR refuses to talk to me")
|
||||
return False
|
||||
except requests.exceptions.ConnectionError as ex:
|
||||
_LOGGER.error('Unable to connect to NVR: %s', str(ex))
|
||||
_LOGGER.error("Unable to connect to NVR: %s", str(ex))
|
||||
return False
|
||||
|
||||
identifier = nvrconn.server_version >= (3, 2, 0) and 'id' or 'uuid'
|
||||
|
@ -113,7 +113,7 @@ class UnifiVideoCamera(Camera):
|
|||
store = uvc_store.get_info_store()
|
||||
password = store.get_camera_password(self._uuid)
|
||||
if password is None:
|
||||
_LOGGER.debug('Logging into camera %(name)s with default password',
|
||||
_LOGGER.debug("Logging into camera %(name)s with default password",
|
||||
dict(name=self._name))
|
||||
password = 'ubnt'
|
||||
|
||||
|
@ -125,11 +125,10 @@ class UnifiVideoCamera(Camera):
|
|||
camera = None
|
||||
for addr in addrs:
|
||||
try:
|
||||
camera = client_cls(addr,
|
||||
caminfo['username'],
|
||||
password)
|
||||
camera = client_cls(
|
||||
addr, caminfo['username'], password)
|
||||
camera.login()
|
||||
_LOGGER.debug('Logged into UVC camera %(name)s via %(addr)s',
|
||||
_LOGGER.debug("Logged into UVC camera %(name)s via %(addr)s",
|
||||
dict(name=self._name, addr=addr))
|
||||
self._connect_addr = addr
|
||||
break
|
||||
|
@ -140,7 +139,7 @@ class UnifiVideoCamera(Camera):
|
|||
except uvc_camera.CameraAuthError:
|
||||
pass
|
||||
if not self._connect_addr:
|
||||
_LOGGER.error('Unable to login to camera')
|
||||
_LOGGER.error("Unable to login to camera")
|
||||
return None
|
||||
|
||||
self._camera = camera
|
||||
|
@ -157,14 +156,14 @@ class UnifiVideoCamera(Camera):
|
|||
try:
|
||||
return self._camera.get_snapshot()
|
||||
except uvc_camera.CameraConnectError:
|
||||
_LOGGER.error('Unable to contact camera')
|
||||
_LOGGER.error("Unable to contact camera")
|
||||
except uvc_camera.CameraAuthError:
|
||||
if retry:
|
||||
self._login()
|
||||
return _get_image(retry=False)
|
||||
else:
|
||||
_LOGGER.error('Unable to log into camera, unable '
|
||||
'to get snapshot')
|
||||
_LOGGER.error(
|
||||
"Unable to log into camera, unable to get snapshot")
|
||||
raise
|
||||
|
||||
return _get_image()
|
||||
|
|
|
@ -17,7 +17,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Camera."""
|
||||
"""Set up the Verisure Camera."""
|
||||
if not int(hub.config.get(CONF_SMARTCAM, 1)):
|
||||
return False
|
||||
directory_path = hass.config.config_dir
|
||||
|
@ -33,7 +33,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
|
||||
|
||||
class VerisureSmartcam(Camera):
|
||||
"""Local camera."""
|
||||
"""Representation of a Verisure camera."""
|
||||
|
||||
def __init__(self, hass, device_id, directory_path):
|
||||
"""Initialize Verisure File Camera component."""
|
||||
|
@ -50,9 +50,9 @@ class VerisureSmartcam(Camera):
|
|||
"""Return image response."""
|
||||
self.check_imagelist()
|
||||
if not self._image:
|
||||
_LOGGER.debug('No image to display')
|
||||
_LOGGER.debug("No image to display")
|
||||
return
|
||||
_LOGGER.debug('Trying to open %s', self._image)
|
||||
_LOGGER.debug("Trying to open %s", self._image)
|
||||
with open(self._image, 'rb') as file:
|
||||
return file.read()
|
||||
|
||||
|
@ -64,35 +64,30 @@ class VerisureSmartcam(Camera):
|
|||
return
|
||||
images = hub.smartcam_dict[self._device_id]
|
||||
new_image_id = images[0]
|
||||
_LOGGER.debug('self._device_id=%s, self._images=%s, '
|
||||
'self._new_image_id=%s', self._device_id,
|
||||
_LOGGER.debug("self._device_id=%s, self._images=%s, "
|
||||
"self._new_image_id=%s", self._device_id,
|
||||
images, new_image_id)
|
||||
if (new_image_id == '-1' or
|
||||
self._image_id == new_image_id):
|
||||
_LOGGER.debug('The image is the same, or loading image_id')
|
||||
_LOGGER.debug("The image is the same, or loading image_id")
|
||||
return
|
||||
_LOGGER.debug('Download new image %s', new_image_id)
|
||||
hub.my_pages.smartcam.download_image(self._device_id,
|
||||
new_image_id,
|
||||
self._directory_path)
|
||||
_LOGGER.debug('Old image_id=%s', self._image_id)
|
||||
_LOGGER.debug("Download new image %s", new_image_id)
|
||||
hub.my_pages.smartcam.download_image(
|
||||
self._device_id, new_image_id, self._directory_path)
|
||||
_LOGGER.debug("Old image_id=%s", self._image_id)
|
||||
self.delete_image(self)
|
||||
|
||||
self._image_id = new_image_id
|
||||
self._image = os.path.join(self._directory_path,
|
||||
'{}{}'.format(
|
||||
self._image_id,
|
||||
'.jpg'))
|
||||
self._image = os.path.join(
|
||||
self._directory_path, '{}{}'.format(self._image_id, '.jpg'))
|
||||
|
||||
def delete_image(self, event):
|
||||
"""Delete an old image."""
|
||||
remove_image = os.path.join(self._directory_path,
|
||||
'{}{}'.format(
|
||||
self._image_id,
|
||||
'.jpg'))
|
||||
remove_image = os.path.join(
|
||||
self._directory_path, '{}{}'.format(self._image_id, '.jpg'))
|
||||
try:
|
||||
os.remove(remove_image)
|
||||
_LOGGER.debug('Deleting old image %s', remove_image)
|
||||
_LOGGER.debug("Deleting old image %s", remove_image)
|
||||
except OSError as error:
|
||||
if error.errno != errno.ENOENT:
|
||||
raise
|
||||
|
|
|
@ -51,21 +51,21 @@ def _get_image_url(hass, monitor, mode):
|
|||
@asyncio.coroutine
|
||||
# pylint: disable=unused-argument
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup ZoneMinder cameras."""
|
||||
"""Set up the ZoneMinder cameras."""
|
||||
cameras = []
|
||||
monitors = zoneminder.get_state('api/monitors.json')
|
||||
if not monitors:
|
||||
_LOGGER.warning('Could not fetch monitors from ZoneMinder')
|
||||
_LOGGER.warning("Could not fetch monitors from ZoneMinder")
|
||||
return
|
||||
|
||||
for i in monitors['monitors']:
|
||||
monitor = i['Monitor']
|
||||
|
||||
if monitor['Function'] == 'None':
|
||||
_LOGGER.info('Skipping camera %s', monitor['Id'])
|
||||
_LOGGER.info("Skipping camera %s", monitor['Id'])
|
||||
continue
|
||||
|
||||
_LOGGER.info('Initializing camera %s', monitor['Id'])
|
||||
_LOGGER.info("Initializing camera %s", monitor['Id'])
|
||||
|
||||
device_info = {
|
||||
CONF_NAME: monitor['Name'],
|
||||
|
@ -75,7 +75,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
cameras.append(ZoneMinderCamera(hass, device_info, monitor))
|
||||
|
||||
if not cameras:
|
||||
_LOGGER.warning('No active cameras found')
|
||||
_LOGGER.warning("No active cameras found")
|
||||
return
|
||||
|
||||
async_add_devices(cameras)
|
||||
|
@ -97,18 +97,18 @@ class ZoneMinderCamera(MjpegCamera):
|
|||
|
||||
def update(self):
|
||||
"""Update our recording state from the ZM API."""
|
||||
_LOGGER.debug('Updating camera state for monitor %i', self._monitor_id)
|
||||
_LOGGER.debug("Updating camera state for monitor %i", self._monitor_id)
|
||||
status_response = zoneminder.get_state(
|
||||
'api/monitors/alarm/id:%i/command:status.json' % self._monitor_id
|
||||
)
|
||||
|
||||
if not status_response:
|
||||
_LOGGER.warning('Could not get status for monitor %i',
|
||||
_LOGGER.warning("Could not get status for monitor %i",
|
||||
self._monitor_id)
|
||||
return
|
||||
|
||||
if status_response['success'] is False:
|
||||
_LOGGER.warning('Alarm status API call failed for monitor %i',
|
||||
if not status_response.get("success", False):
|
||||
_LOGGER.warning("Alarm status API call failed for monitor %i",
|
||||
self._monitor_id)
|
||||
return
|
||||
|
||||
|
|
|
@ -23,45 +23,46 @@ from homeassistant.const import (
|
|||
ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_ON, STATE_OFF, STATE_UNKNOWN,
|
||||
TEMP_CELSIUS)
|
||||
|
||||
DOMAIN = "climate"
|
||||
DOMAIN = 'climate'
|
||||
|
||||
ENTITY_ID_FORMAT = DOMAIN + ".{}"
|
||||
ENTITY_ID_FORMAT = DOMAIN + '.{}'
|
||||
SCAN_INTERVAL = timedelta(seconds=60)
|
||||
|
||||
SERVICE_SET_AWAY_MODE = "set_away_mode"
|
||||
SERVICE_SET_AUX_HEAT = "set_aux_heat"
|
||||
SERVICE_SET_TEMPERATURE = "set_temperature"
|
||||
SERVICE_SET_FAN_MODE = "set_fan_mode"
|
||||
SERVICE_SET_HOLD_MODE = "set_hold_mode"
|
||||
SERVICE_SET_OPERATION_MODE = "set_operation_mode"
|
||||
SERVICE_SET_SWING_MODE = "set_swing_mode"
|
||||
SERVICE_SET_HUMIDITY = "set_humidity"
|
||||
SERVICE_SET_AWAY_MODE = 'set_away_mode'
|
||||
SERVICE_SET_AUX_HEAT = 'set_aux_heat'
|
||||
SERVICE_SET_TEMPERATURE = 'set_temperature'
|
||||
SERVICE_SET_FAN_MODE = 'set_fan_mode'
|
||||
SERVICE_SET_HOLD_MODE = 'set_hold_mode'
|
||||
SERVICE_SET_OPERATION_MODE = 'set_operation_mode'
|
||||
SERVICE_SET_SWING_MODE = 'set_swing_mode'
|
||||
SERVICE_SET_HUMIDITY = 'set_humidity'
|
||||
|
||||
STATE_HEAT = "heat"
|
||||
STATE_COOL = "cool"
|
||||
STATE_IDLE = "idle"
|
||||
STATE_AUTO = "auto"
|
||||
STATE_DRY = "dry"
|
||||
STATE_FAN_ONLY = "fan_only"
|
||||
STATE_HEAT = 'heat'
|
||||
STATE_COOL = 'cool'
|
||||
STATE_IDLE = 'idle'
|
||||
STATE_AUTO = 'auto'
|
||||
STATE_DRY = 'dry'
|
||||
STATE_FAN_ONLY = 'fan_only'
|
||||
|
||||
ATTR_CURRENT_TEMPERATURE = "current_temperature"
|
||||
ATTR_MAX_TEMP = "max_temp"
|
||||
ATTR_MIN_TEMP = "min_temp"
|
||||
ATTR_TARGET_TEMP_HIGH = "target_temp_high"
|
||||
ATTR_TARGET_TEMP_LOW = "target_temp_low"
|
||||
ATTR_AWAY_MODE = "away_mode"
|
||||
ATTR_AUX_HEAT = "aux_heat"
|
||||
ATTR_FAN_MODE = "fan_mode"
|
||||
ATTR_FAN_LIST = "fan_list"
|
||||
ATTR_CURRENT_HUMIDITY = "current_humidity"
|
||||
ATTR_HUMIDITY = "humidity"
|
||||
ATTR_MAX_HUMIDITY = "max_humidity"
|
||||
ATTR_MIN_HUMIDITY = "min_humidity"
|
||||
ATTR_HOLD_MODE = "hold_mode"
|
||||
ATTR_OPERATION_MODE = "operation_mode"
|
||||
ATTR_OPERATION_LIST = "operation_list"
|
||||
ATTR_SWING_MODE = "swing_mode"
|
||||
ATTR_SWING_LIST = "swing_list"
|
||||
ATTR_CURRENT_TEMPERATURE = 'current_temperature'
|
||||
ATTR_MAX_TEMP = 'max_temp'
|
||||
ATTR_MIN_TEMP = 'min_temp'
|
||||
ATTR_TARGET_TEMP_HIGH = 'target_temp_high'
|
||||
ATTR_TARGET_TEMP_LOW = 'target_temp_low'
|
||||
ATTR_TARGET_TEMP_STEP = 'target_temp_step'
|
||||
ATTR_AWAY_MODE = 'away_mode'
|
||||
ATTR_AUX_HEAT = 'aux_heat'
|
||||
ATTR_FAN_MODE = 'fan_mode'
|
||||
ATTR_FAN_LIST = 'fan_list'
|
||||
ATTR_CURRENT_HUMIDITY = 'current_humidity'
|
||||
ATTR_HUMIDITY = 'humidity'
|
||||
ATTR_MAX_HUMIDITY = 'max_humidity'
|
||||
ATTR_MIN_HUMIDITY = 'min_humidity'
|
||||
ATTR_HOLD_MODE = 'hold_mode'
|
||||
ATTR_OPERATION_MODE = 'operation_mode'
|
||||
ATTR_OPERATION_LIST = 'operation_list'
|
||||
ATTR_SWING_MODE = 'swing_mode'
|
||||
ATTR_SWING_LIST = 'swing_list'
|
||||
|
||||
# The degree of precision for each platform
|
||||
PRECISION_WHOLE = 1
|
||||
|
@ -208,7 +209,7 @@ def set_swing_mode(hass, swing_mode, entity_id=None):
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup(hass, config):
|
||||
"""Setup climate devices."""
|
||||
"""Set up climate devices."""
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL)
|
||||
yield from component.async_setup(config)
|
||||
|
||||
|
@ -273,7 +274,7 @@ def async_setup(hass, config):
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_aux_heat_set_service(service):
|
||||
"""Set auxillary heater on target climate devices."""
|
||||
"""Set auxiliary heater on target climate devices."""
|
||||
target_climate = component.async_extract_from_service(service)
|
||||
|
||||
aux_heat = service.data.get(ATTR_AUX_HEAT)
|
||||
|
@ -419,6 +420,10 @@ class ClimateDevice(Entity):
|
|||
ATTR_TEMPERATURE:
|
||||
self._convert_for_display(self.target_temperature),
|
||||
}
|
||||
|
||||
if self.target_temperature_step is not None:
|
||||
data[ATTR_TARGET_TEMP_STEP] = self.target_temperature_step
|
||||
|
||||
target_temp_high = self.target_temperature_high
|
||||
if target_temp_high is not None:
|
||||
data[ATTR_TARGET_TEMP_HIGH] = self._convert_for_display(
|
||||
|
@ -467,12 +472,12 @@ class ClimateDevice(Entity):
|
|||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""The unit of measurement to display."""
|
||||
"""Return the unit of measurement to display."""
|
||||
return self.hass.config.units.temperature_unit
|
||||
|
||||
@property
|
||||
def temperature_unit(self):
|
||||
"""The unit of measurement used by the platform."""
|
||||
"""Return the unit of measurement used by the platform."""
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
|
@ -492,7 +497,7 @@ class ClimateDevice(Entity):
|
|||
|
||||
@property
|
||||
def operation_list(self):
|
||||
"""List of available operation modes."""
|
||||
"""Return the list of available operation modes."""
|
||||
return None
|
||||
|
||||
@property
|
||||
|
@ -505,6 +510,11 @@ class ClimateDevice(Entity):
|
|||
"""Return the temperature we try to reach."""
|
||||
return None
|
||||
|
||||
@property
|
||||
def target_temperature_step(self):
|
||||
"""Return the supported step of target temperature."""
|
||||
return None
|
||||
|
||||
@property
|
||||
def target_temperature_high(self):
|
||||
"""Return the highbound target temperature we try to reach."""
|
||||
|
@ -537,7 +547,7 @@ class ClimateDevice(Entity):
|
|||
|
||||
@property
|
||||
def fan_list(self):
|
||||
"""List of available fan modes."""
|
||||
"""Return the list of available fan modes."""
|
||||
return None
|
||||
|
||||
@property
|
||||
|
@ -547,7 +557,7 @@ class ClimateDevice(Entity):
|
|||
|
||||
@property
|
||||
def swing_list(self):
|
||||
"""List of available swing modes."""
|
||||
"""Return the list of available swing modes."""
|
||||
return None
|
||||
|
||||
def set_temperature(self, **kwargs):
|
||||
|
@ -695,8 +705,8 @@ class ClimateDevice(Entity):
|
|||
if temp is None or not isinstance(temp, Number):
|
||||
return temp
|
||||
if self.temperature_unit != self.unit_of_measurement:
|
||||
temp = convert_temperature(temp, self.temperature_unit,
|
||||
self.unit_of_measurement)
|
||||
temp = convert_temperature(
|
||||
temp, self.temperature_unit, self.unit_of_measurement)
|
||||
# Round in the units appropriate
|
||||
if self.precision == PRECISION_HALVES:
|
||||
return round(temp * 2) / 2.0
|
||||
|
|
|
@ -10,14 +10,14 @@ from homeassistant.const import TEMP_CELSIUS, TEMP_FAHRENHEIT, ATTR_TEMPERATURE
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Demo climate devices."""
|
||||
"""Set up the Demo climate devices."""
|
||||
add_devices([
|
||||
DemoClimate("HeatPump", 68, TEMP_FAHRENHEIT, None, None, 77,
|
||||
"Auto Low", None, None, "Auto", "heat", None, None, None),
|
||||
DemoClimate("Hvac", 21, TEMP_CELSIUS, True, None, 22, "On High",
|
||||
67, 54, "Off", "cool", False, None, None),
|
||||
DemoClimate("Ecobee", None, TEMP_CELSIUS, None, None, 23, "Auto Low",
|
||||
None, None, "Auto", "auto", None, 24, 21)
|
||||
DemoClimate('HeatPump', 68, TEMP_FAHRENHEIT, None, None, 77,
|
||||
'Auto Low', None, None, 'Auto', 'heat', None, None, None),
|
||||
DemoClimate('Hvac', 21, TEMP_CELSIUS, True, None, 22, 'On High',
|
||||
67, 54, 'Off', 'cool', False, None, None),
|
||||
DemoClimate('Ecobee', None, TEMP_CELSIUS, None, None, 23, 'Auto Low',
|
||||
None, None, 'Auto', 'auto', None, 24, 21)
|
||||
])
|
||||
|
||||
|
||||
|
@ -41,15 +41,15 @@ class DemoClimate(ClimateDevice):
|
|||
self._current_operation = current_operation
|
||||
self._aux = aux
|
||||
self._current_swing_mode = current_swing_mode
|
||||
self._fan_list = ["On Low", "On High", "Auto Low", "Auto High", "Off"]
|
||||
self._operation_list = ["heat", "cool", "auto", "off"]
|
||||
self._swing_list = ["Auto", "1", "2", "3", "Off"]
|
||||
self._fan_list = ['On Low', 'On High', 'Auto Low', 'Auto High', 'Off']
|
||||
self._operation_list = ['heat', 'cool', 'auto', 'off']
|
||||
self._swing_list = ['Auto', '1', '2', '3', 'Off']
|
||||
self._target_temperature_high = target_temp_high
|
||||
self._target_temperature_low = target_temp_low
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""Polling not needed for a demo climate device."""
|
||||
"""Return the polling state."""
|
||||
return False
|
||||
|
||||
@property
|
||||
|
@ -99,7 +99,7 @@ class DemoClimate(ClimateDevice):
|
|||
|
||||
@property
|
||||
def operation_list(self):
|
||||
"""List of available operation modes."""
|
||||
"""Return the list of available operation modes."""
|
||||
return self._operation_list
|
||||
|
||||
@property
|
||||
|
@ -124,7 +124,7 @@ class DemoClimate(ClimateDevice):
|
|||
|
||||
@property
|
||||
def fan_list(self):
|
||||
"""List of available fan modes."""
|
||||
"""Return the list of available fan modes."""
|
||||
return self._fan_list
|
||||
|
||||
def set_temperature(self, **kwargs):
|
||||
|
|
|
@ -45,7 +45,7 @@ RESUME_PROGRAM_SCHEMA = vol.Schema({
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Ecobee Thermostat Platform."""
|
||||
"""Set up the Ecobee Thermostat Platform."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
data = ecobee.NETWORK
|
||||
|
@ -197,19 +197,19 @@ class Thermostat(ClimateDevice):
|
|||
if event['holdClimateRef'] == 'away':
|
||||
if int(event['endDate'][0:4]) - \
|
||||
int(event['startDate'][0:4]) <= 1:
|
||||
# a temporary hold from away climate is a hold
|
||||
# A temporary hold from away climate is a hold
|
||||
return 'away'
|
||||
else:
|
||||
# a premanent hold from away climate is away_mode
|
||||
# A permanent hold from away climate is away_mode
|
||||
return None
|
||||
elif event['holdClimateRef'] != "":
|
||||
# any other hold based on climate
|
||||
# Any other hold based on climate
|
||||
return event['holdClimateRef']
|
||||
else:
|
||||
# any hold not based on a climate is a temp hold
|
||||
# Any hold not based on a climate is a temp hold
|
||||
return TEMPERATURE_HOLD
|
||||
elif event['type'].startswith('auto'):
|
||||
# all auto modes are treated as holds
|
||||
# All auto modes are treated as holds
|
||||
return event['type'][4:].lower()
|
||||
elif event['type'] == 'vacation':
|
||||
self.vacation = event['name']
|
||||
|
@ -278,6 +278,11 @@ class Thermostat(ClimateDevice):
|
|||
"""Return true if away mode is on."""
|
||||
return self.current_hold_mode == 'away'
|
||||
|
||||
@property
|
||||
def is_aux_heat_on(self):
|
||||
"""Return true if aux heater."""
|
||||
return 'auxHeat' in self.thermostat['equipmentStatus']
|
||||
|
||||
def turn_away_mode_on(self):
|
||||
"""Turn away on."""
|
||||
self.set_hold_mode('away')
|
||||
|
@ -295,17 +300,16 @@ class Thermostat(ClimateDevice):
|
|||
return
|
||||
elif hold_mode == 'None' or hold_mode is None:
|
||||
if hold == VACATION_HOLD:
|
||||
self.data.ecobee.delete_vacation(self.thermostat_index,
|
||||
self.vacation)
|
||||
self.data.ecobee.delete_vacation(
|
||||
self.thermostat_index, self.vacation)
|
||||
else:
|
||||
self.data.ecobee.resume_program(self.thermostat_index)
|
||||
else:
|
||||
if hold_mode == TEMPERATURE_HOLD:
|
||||
self.set_temp_hold(int(self.current_temperature))
|
||||
else:
|
||||
self.data.ecobee.set_climate_hold(self.thermostat_index,
|
||||
hold_mode,
|
||||
self.hold_preference())
|
||||
self.data.ecobee.set_climate_hold(
|
||||
self.thermostat_index, hold_mode, self.hold_preference())
|
||||
self.update_without_throttle = True
|
||||
|
||||
def set_auto_temp_hold(self, heat_temp, cool_temp):
|
||||
|
@ -351,7 +355,7 @@ class Thermostat(ClimateDevice):
|
|||
self.set_temp_hold(int(temp))
|
||||
else:
|
||||
_LOGGER.error(
|
||||
'Missing valid arguments for set_temperature in %s', kwargs)
|
||||
"Missing valid arguments for set_temperature in %s", kwargs)
|
||||
|
||||
def set_operation_mode(self, operation_mode):
|
||||
"""Set HVAC mode (auto, auxHeatOnly, cool, heat, off)."""
|
||||
|
@ -360,14 +364,14 @@ class Thermostat(ClimateDevice):
|
|||
|
||||
def set_fan_min_on_time(self, fan_min_on_time):
|
||||
"""Set the minimum fan on time."""
|
||||
self.data.ecobee.set_fan_min_on_time(self.thermostat_index,
|
||||
fan_min_on_time)
|
||||
self.data.ecobee.set_fan_min_on_time(
|
||||
self.thermostat_index, fan_min_on_time)
|
||||
self.update_without_throttle = True
|
||||
|
||||
def resume_program(self, resume_all):
|
||||
"""Resume the thermostat schedule program."""
|
||||
self.data.ecobee.resume_program(self.thermostat_index,
|
||||
str(resume_all).lower())
|
||||
self.data.ecobee.resume_program(
|
||||
self.thermostat_index, str(resume_all).lower())
|
||||
self.update_without_throttle = True
|
||||
|
||||
def hold_preference(self):
|
||||
|
|
|
@ -21,15 +21,15 @@ REQUIREMENTS = ['python-eq3bt==0.1.5']
|
|||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
STATE_BOOST = "boost"
|
||||
STATE_AWAY = "away"
|
||||
STATE_MANUAL = "manual"
|
||||
STATE_BOOST = 'boost'
|
||||
STATE_AWAY = 'away'
|
||||
STATE_MANUAL = 'manual'
|
||||
|
||||
ATTR_STATE_WINDOW_OPEN = "window_open"
|
||||
ATTR_STATE_VALVE = "valve"
|
||||
ATTR_STATE_LOCKED = "is_locked"
|
||||
ATTR_STATE_LOW_BAT = "low_battery"
|
||||
ATTR_STATE_AWAY_END = "away_end"
|
||||
ATTR_STATE_WINDOW_OPEN = 'window_open'
|
||||
ATTR_STATE_VALVE = 'valve'
|
||||
ATTR_STATE_LOCKED = 'is_locked'
|
||||
ATTR_STATE_LOW_BAT = 'low_battery'
|
||||
ATTR_STATE_AWAY_END = 'away_end'
|
||||
|
||||
DEVICE_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_MAC): cv.string,
|
||||
|
@ -42,7 +42,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the eQ-3 BLE thermostats."""
|
||||
"""Set up the eQ-3 BLE thermostats."""
|
||||
devices = []
|
||||
|
||||
for name, device_cfg in config[CONF_DEVICES].items():
|
||||
|
@ -112,14 +112,14 @@ class EQ3BTSmartThermostat(ClimateDevice):
|
|||
|
||||
@property
|
||||
def current_operation(self):
|
||||
"""Current mode."""
|
||||
"""Return the current operation mode."""
|
||||
if self._thermostat.mode < 0:
|
||||
return None
|
||||
return self.modes[self._thermostat.mode]
|
||||
|
||||
@property
|
||||
def operation_list(self):
|
||||
"""List of available operation modes."""
|
||||
"""Return the list of available operation modes."""
|
||||
return [x for x in self.modes.values()]
|
||||
|
||||
def set_operation_mode(self, operation_mode):
|
||||
|
|
|
@ -14,7 +14,8 @@ from homeassistant.components import switch
|
|||
from homeassistant.components.climate import (
|
||||
STATE_HEAT, STATE_COOL, STATE_IDLE, ClimateDevice, PLATFORM_SCHEMA)
|
||||
from homeassistant.const import (
|
||||
ATTR_UNIT_OF_MEASUREMENT, STATE_ON, STATE_OFF, ATTR_TEMPERATURE)
|
||||
ATTR_UNIT_OF_MEASUREMENT, STATE_ON, STATE_OFF, ATTR_TEMPERATURE,
|
||||
CONF_NAME)
|
||||
from homeassistant.helpers import condition
|
||||
from homeassistant.helpers.event import (
|
||||
async_track_state_change, async_track_time_interval)
|
||||
|
@ -27,7 +28,6 @@ DEPENDENCIES = ['switch', 'sensor']
|
|||
DEFAULT_TOLERANCE = 0.3
|
||||
DEFAULT_NAME = 'Generic Thermostat'
|
||||
|
||||
CONF_NAME = 'name'
|
||||
CONF_HEATER = 'heater'
|
||||
CONF_SENSOR = 'target_sensor'
|
||||
CONF_MIN_TEMP = 'min_temp'
|
||||
|
@ -56,7 +56,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Setup the generic thermostat."""
|
||||
"""Set up the generic thermostat platform."""
|
||||
name = config.get(CONF_NAME)
|
||||
heater_entity_id = config.get(CONF_HEATER)
|
||||
sensor_entity_id = config.get(CONF_SENSOR)
|
||||
|
@ -74,7 +74,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
|
||||
|
||||
class GenericThermostat(ClimateDevice):
|
||||
"""Representation of a GenericThermostat device."""
|
||||
"""Representation of a Generic Thermostat device."""
|
||||
|
||||
def __init__(self, hass, name, heater_entity_id, sensor_entity_id,
|
||||
min_temp, max_temp, target_temp, ac_mode, min_cycle_duration,
|
||||
|
@ -110,7 +110,7 @@ class GenericThermostat(ClimateDevice):
|
|||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""No polling needed."""
|
||||
"""Return the polling state."""
|
||||
return False
|
||||
|
||||
@property
|
||||
|
@ -175,7 +175,7 @@ class GenericThermostat(ClimateDevice):
|
|||
|
||||
@asyncio.coroutine
|
||||
def _async_sensor_changed(self, entity_id, old_state, new_state):
|
||||
"""Called when temperature changes."""
|
||||
"""Handle temperature changes."""
|
||||
if new_state is None:
|
||||
return
|
||||
|
||||
|
@ -185,14 +185,14 @@ class GenericThermostat(ClimateDevice):
|
|||
|
||||
@callback
|
||||
def _async_switch_changed(self, entity_id, old_state, new_state):
|
||||
"""Called when heater switch changes state."""
|
||||
"""Handle heater switch state changes."""
|
||||
if new_state is None:
|
||||
return
|
||||
self.hass.async_add_job(self.async_update_ha_state())
|
||||
|
||||
@callback
|
||||
def _async_keep_alive(self, time):
|
||||
"""Called at constant intervals for keep-alive purposes."""
|
||||
"""Call at constant intervals for keep-alive purposes."""
|
||||
if self.current_operation in [STATE_COOL, STATE_HEAT]:
|
||||
switch.async_turn_on(self.hass, self.heater_entity_id)
|
||||
else:
|
||||
|
|
|
@ -35,7 +35,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
# pylint: disable=unused-variable
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the heatmiser thermostat."""
|
||||
"""Set up the heatmiser thermostat."""
|
||||
from heatmiserV3 import heatmiser, connection
|
||||
|
||||
ipaddress = config.get(CONF_IPADDRESS)
|
||||
|
|
|
@ -14,17 +14,17 @@ DEPENDENCIES = ['homematic']
|
|||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
STATE_MANUAL = "manual"
|
||||
STATE_BOOST = "boost"
|
||||
STATE_COMFORT = "comfort"
|
||||
STATE_LOWERING = "lowering"
|
||||
STATE_MANUAL = 'manual'
|
||||
STATE_BOOST = 'boost'
|
||||
STATE_COMFORT = 'comfort'
|
||||
STATE_LOWERING = 'lowering'
|
||||
|
||||
HM_STATE_MAP = {
|
||||
"AUTO_MODE": STATE_AUTO,
|
||||
"MANU_MODE": STATE_MANUAL,
|
||||
"BOOST_MODE": STATE_BOOST,
|
||||
"COMFORT_MODE": STATE_COMFORT,
|
||||
"LOWERING_MODE": STATE_LOWERING
|
||||
'AUTO_MODE': STATE_AUTO,
|
||||
'MANU_MODE': STATE_MANUAL,
|
||||
'BOOST_MODE': STATE_BOOST,
|
||||
'COMFORT_MODE': STATE_COMFORT,
|
||||
'LOWERING_MODE': STATE_LOWERING
|
||||
}
|
||||
|
||||
HM_TEMP_MAP = [
|
||||
|
@ -41,7 +41,7 @@ HM_CONTROL_MODE = 'CONTROL_MODE'
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Homematic thermostat platform."""
|
||||
"""Set up the Homematic thermostat platform."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
|
@ -76,10 +76,9 @@ class HMThermostat(HMDevice, ClimateDevice):
|
|||
|
||||
@property
|
||||
def operation_list(self):
|
||||
"""List of available operation modes."""
|
||||
"""Return the list of available operation modes."""
|
||||
op_list = []
|
||||
|
||||
# generate list
|
||||
for mode in self._hmdevice.ACTIONNODE:
|
||||
if mode in HM_STATE_MAP:
|
||||
op_list.append(HM_STATE_MAP.get(mode))
|
||||
|
@ -132,11 +131,9 @@ class HMThermostat(HMDevice, ClimateDevice):
|
|||
|
||||
def _init_data_struct(self):
|
||||
"""Generate a data dict (self._data) from the Homematic metadata."""
|
||||
# Add state to data dict
|
||||
self._state = next(iter(self._hmdevice.WRITENODE.keys()))
|
||||
self._data[self._state] = STATE_UNKNOWN
|
||||
|
||||
# support state
|
||||
if HM_CONTROL_MODE in self._hmdevice.ATTRIBUTENODE:
|
||||
self._data[HM_CONTROL_MODE] = STATE_UNKNOWN
|
||||
|
||||
|
|
|
@ -8,13 +8,12 @@ import logging
|
|||
import socket
|
||||
import datetime
|
||||
|
||||
import voluptuous as vol
|
||||
import requests
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.climate import (ClimateDevice, PLATFORM_SCHEMA,
|
||||
ATTR_FAN_MODE, ATTR_FAN_LIST,
|
||||
ATTR_OPERATION_MODE,
|
||||
ATTR_OPERATION_LIST)
|
||||
from homeassistant.components.climate import (
|
||||
ClimateDevice, PLATFORM_SCHEMA, ATTR_FAN_MODE, ATTR_FAN_LIST,
|
||||
ATTR_OPERATION_MODE, ATTR_OPERATION_LIST)
|
||||
from homeassistant.const import (
|
||||
CONF_PASSWORD, CONF_USERNAME, TEMP_CELSIUS, TEMP_FAHRENHEIT,
|
||||
ATTR_TEMPERATURE)
|
||||
|
@ -54,7 +53,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Honeywell thermostat."""
|
||||
"""Set up the Honeywell thermostat."""
|
||||
username = config.get(CONF_USERNAME)
|
||||
password = config.get(CONF_PASSWORD)
|
||||
region = config.get(CONF_REGION)
|
||||
|
@ -66,7 +65,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
|
||||
|
||||
def _setup_round(username, password, config, add_devices):
|
||||
"""Setup rounding function."""
|
||||
"""Set up the rounding function."""
|
||||
from evohomeclient import EvohomeClient
|
||||
|
||||
away_temp = config.get(CONF_AWAY_TEMPERATURE)
|
||||
|
@ -87,16 +86,16 @@ def _setup_round(username, password, config, add_devices):
|
|||
|
||||
# config will be used later
|
||||
def _setup_us(username, password, config, add_devices):
|
||||
"""Setup user."""
|
||||
"""Set up the user."""
|
||||
import somecomfort
|
||||
|
||||
try:
|
||||
client = somecomfort.SomeComfort(username, password)
|
||||
except somecomfort.AuthError:
|
||||
_LOGGER.error('Failed to login to honeywell account %s', username)
|
||||
_LOGGER.error("Failed to login to honeywell account %s", username)
|
||||
return False
|
||||
except somecomfort.SomeComfortError as ex:
|
||||
_LOGGER.error('Failed to initialize honeywell client: %s', str(ex))
|
||||
_LOGGER.error("Failed to initialize honeywell client: %s", str(ex))
|
||||
return False
|
||||
|
||||
dev_id = config.get('thermostat')
|
||||
|
@ -199,7 +198,7 @@ class RoundThermostat(ClimateDevice):
|
|||
|
||||
except StopIteration:
|
||||
_LOGGER.error("Did not receive any temperature data from the "
|
||||
"evohomeclient API.")
|
||||
"evohomeclient API")
|
||||
return
|
||||
|
||||
self._current_temperature = data['temp']
|
||||
|
@ -289,7 +288,7 @@ class HoneywellUSThermostat(ClimateDevice):
|
|||
"setpoint_{}".format(mode),
|
||||
temperature)
|
||||
except somecomfort.SomeComfortError:
|
||||
_LOGGER.error('Temperature %.1f out of range', temperature)
|
||||
_LOGGER.error("Temperature %.1f out of range", temperature)
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
|
@ -369,8 +368,8 @@ class HoneywellUSThermostat(ClimateDevice):
|
|||
raise exp
|
||||
if not self._retry():
|
||||
raise exp
|
||||
_LOGGER.error("SomeComfort update failed, Retrying "
|
||||
"- Error: %s", exp)
|
||||
_LOGGER.error(
|
||||
"SomeComfort update failed, Retrying - Error: %s", exp)
|
||||
|
||||
def _retry(self):
|
||||
"""Recreate a new somecomfort client.
|
||||
|
@ -380,14 +379,14 @@ class HoneywellUSThermostat(ClimateDevice):
|
|||
"""
|
||||
import somecomfort
|
||||
try:
|
||||
self._client = somecomfort.SomeComfort(self._username,
|
||||
self._password)
|
||||
self._client = somecomfort.SomeComfort(
|
||||
self._username, self._password)
|
||||
except somecomfort.AuthError:
|
||||
_LOGGER.error('Failed to login to honeywell account %s',
|
||||
_LOGGER.error("Failed to login to honeywell account %s",
|
||||
self._username)
|
||||
return False
|
||||
except somecomfort.SomeComfortError as ex:
|
||||
_LOGGER.error('Failed to initialize honeywell client: %s',
|
||||
_LOGGER.error("Failed to initialize honeywell client: %s",
|
||||
str(ex))
|
||||
return False
|
||||
|
||||
|
@ -397,7 +396,7 @@ class HoneywellUSThermostat(ClimateDevice):
|
|||
if device.name == self._device.name]
|
||||
|
||||
if len(devices) != 1:
|
||||
_LOGGER.error('Failed to find device %s', self._device.name)
|
||||
_LOGGER.error("Failed to find device %s", self._device.name)
|
||||
return False
|
||||
|
||||
self._device = devices[0]
|
||||
|
|
|
@ -61,7 +61,7 @@ class KNXThermostat(KNXMultiAddressDevice, ClimateDevice):
|
|||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""Polling is needed for the KNX thermostat."""
|
||||
"""Return the polling state, is needed for the KNX thermostat."""
|
||||
return True
|
||||
|
||||
@property
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue