merge upstream dev
This commit is contained in:
commit
0495776a22
22 changed files with 601 additions and 221 deletions
|
@ -44,6 +44,9 @@ omit =
|
||||||
homeassistant/components/nest.py
|
homeassistant/components/nest.py
|
||||||
homeassistant/components/*/nest.py
|
homeassistant/components/*/nest.py
|
||||||
|
|
||||||
|
homeassistant/components/rpi_gpio.py
|
||||||
|
homeassistant/components/*/rpi_gpio.py
|
||||||
|
|
||||||
homeassistant/components/binary_sensor/arest.py
|
homeassistant/components/binary_sensor/arest.py
|
||||||
homeassistant/components/binary_sensor/rest.py
|
homeassistant/components/binary_sensor/rest.py
|
||||||
homeassistant/components/browser.py
|
homeassistant/components/browser.py
|
||||||
|
@ -104,7 +107,6 @@ omit =
|
||||||
homeassistant/components/sensor/netatmo.py
|
homeassistant/components/sensor/netatmo.py
|
||||||
homeassistant/components/sensor/openweathermap.py
|
homeassistant/components/sensor/openweathermap.py
|
||||||
homeassistant/components/sensor/rest.py
|
homeassistant/components/sensor/rest.py
|
||||||
homeassistant/components/sensor/rpi_gpio.py
|
|
||||||
homeassistant/components/sensor/sabnzbd.py
|
homeassistant/components/sensor/sabnzbd.py
|
||||||
homeassistant/components/sensor/swiss_public_transport.py
|
homeassistant/components/sensor/swiss_public_transport.py
|
||||||
homeassistant/components/sensor/systemmonitor.py
|
homeassistant/components/sensor/systemmonitor.py
|
||||||
|
@ -120,7 +122,6 @@ omit =
|
||||||
homeassistant/components/switch/mystrom.py
|
homeassistant/components/switch/mystrom.py
|
||||||
homeassistant/components/switch/orvibo.py
|
homeassistant/components/switch/orvibo.py
|
||||||
homeassistant/components/switch/rest.py
|
homeassistant/components/switch/rest.py
|
||||||
homeassistant/components/switch/rpi_gpio.py
|
|
||||||
homeassistant/components/switch/transmission.py
|
homeassistant/components/switch/transmission.py
|
||||||
homeassistant/components/switch/wemo.py
|
homeassistant/components/switch/wemo.py
|
||||||
homeassistant/components/thermostat/heatmiser.py
|
homeassistant/components/thermostat/heatmiser.py
|
||||||
|
|
|
@ -52,6 +52,8 @@ class AlarmDotCom(alarm.AlarmControlPanel):
|
||||||
self._hass = hass
|
self._hass = hass
|
||||||
self._name = name
|
self._name = name
|
||||||
self._code = str(code) if code else None
|
self._code = str(code) if code else None
|
||||||
|
self._username = username
|
||||||
|
self._password = password
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def should_poll(self):
|
def should_poll(self):
|
||||||
|
@ -82,21 +84,30 @@ class AlarmDotCom(alarm.AlarmControlPanel):
|
||||||
""" Send disarm command. """
|
""" Send disarm command. """
|
||||||
if not self._validate_code(code, 'arming home'):
|
if not self._validate_code(code, 'arming home'):
|
||||||
return
|
return
|
||||||
self._alarm.disarm()
|
from pyalarmdotcom.pyalarmdotcom import Alarmdotcom
|
||||||
|
# Open another session to alarm.com to fire off the command
|
||||||
|
_alarm = Alarmdotcom(self._username, self._password, timeout=10)
|
||||||
|
_alarm.disarm()
|
||||||
self.update_ha_state()
|
self.update_ha_state()
|
||||||
|
|
||||||
def alarm_arm_home(self, code=None):
|
def alarm_arm_home(self, code=None):
|
||||||
""" Send arm home command. """
|
""" Send arm home command. """
|
||||||
if not self._validate_code(code, 'arming home'):
|
if not self._validate_code(code, 'arming home'):
|
||||||
return
|
return
|
||||||
self._alarm.arm_stay()
|
from pyalarmdotcom.pyalarmdotcom import Alarmdotcom
|
||||||
|
# Open another session to alarm.com to fire off the command
|
||||||
|
_alarm = Alarmdotcom(self._username, self._password, timeout=10)
|
||||||
|
_alarm.arm_stay()
|
||||||
self.update_ha_state()
|
self.update_ha_state()
|
||||||
|
|
||||||
def alarm_arm_away(self, code=None):
|
def alarm_arm_away(self, code=None):
|
||||||
""" Send arm away command. """
|
""" Send arm away command. """
|
||||||
if not self._validate_code(code, 'arming home'):
|
if not self._validate_code(code, 'arming home'):
|
||||||
return
|
return
|
||||||
self._alarm.arm_away()
|
from pyalarmdotcom.pyalarmdotcom import Alarmdotcom
|
||||||
|
# Open another session to alarm.com to fire off the command
|
||||||
|
_alarm = Alarmdotcom(self._username, self._password, timeout=10)
|
||||||
|
_alarm.arm_away()
|
||||||
self.update_ha_state()
|
self.update_ha_state()
|
||||||
|
|
||||||
def _validate_code(self, code, state):
|
def _validate_code(self, code, state):
|
||||||
|
|
|
@ -57,7 +57,7 @@ class VerisureAlarm(alarm.AlarmControlPanel):
|
||||||
@property
|
@property
|
||||||
def code_format(self):
|
def code_format(self):
|
||||||
""" Four digit code required. """
|
""" Four digit code required. """
|
||||||
return '^\\d{4}$'
|
return '^\\d{%s}$' % verisure.CODE_DIGITS
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
""" Update alarm status """
|
""" Update alarm status """
|
||||||
|
|
|
@ -46,7 +46,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class NestBinarySensor(BinarySensorDevice, NestSensor):
|
class NestBinarySensor(NestSensor, BinarySensorDevice):
|
||||||
""" Represents a Nst Binary sensor. """
|
""" Represents a Nst Binary sensor. """
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
73
homeassistant/components/binary_sensor/rpi_gpio.py
Normal file
73
homeassistant/components/binary_sensor/rpi_gpio.py
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
"""
|
||||||
|
homeassistant.components.binary_sensor.rpi_gpio
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
Allows to configure a binary_sensor using RPi GPIO.
|
||||||
|
|
||||||
|
For more details about this platform, please refer to the documentation at
|
||||||
|
https://home-assistant.io/components/binary_sensor.rpi_gpio/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import homeassistant.components.rpi_gpio as rpi_gpio
|
||||||
|
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||||
|
from homeassistant.const import (DEVICE_DEFAULT_NAME)
|
||||||
|
|
||||||
|
DEFAULT_PULL_MODE = "UP"
|
||||||
|
DEFAULT_BOUNCETIME = 50
|
||||||
|
DEFAULT_INVERT_LOGIC = False
|
||||||
|
|
||||||
|
DEPENDENCIES = ['rpi_gpio']
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
# pylint: disable=unused-argument
|
||||||
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
|
""" Sets up 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)
|
||||||
|
|
||||||
|
binary_sensors = []
|
||||||
|
ports = config.get('ports')
|
||||||
|
for port_num, port_name in ports.items():
|
||||||
|
binary_sensors.append(RPiGPIOBinarySensor(
|
||||||
|
port_name, port_num, pull_mode, bouncetime, invert_logic))
|
||||||
|
add_devices(binary_sensors)
|
||||||
|
|
||||||
|
|
||||||
|
# pylint: disable=too-many-arguments, too-many-instance-attributes
|
||||||
|
class RPiGPIOBinarySensor(BinarySensorDevice):
|
||||||
|
""" Represents a binary sensor that uses Raspberry Pi GPIO. """
|
||||||
|
def __init__(self, name, port, pull_mode, bouncetime, invert_logic):
|
||||||
|
# pylint: disable=no-member
|
||||||
|
|
||||||
|
self._name = name or DEVICE_DEFAULT_NAME
|
||||||
|
self._port = port
|
||||||
|
self._pull_mode = pull_mode
|
||||||
|
self._bouncetime = bouncetime
|
||||||
|
self._invert_logic = invert_logic
|
||||||
|
|
||||||
|
rpi_gpio.setup_input(self._port, self._pull_mode)
|
||||||
|
self._state = rpi_gpio.read_input(self._port)
|
||||||
|
|
||||||
|
def read_gpio(port):
|
||||||
|
""" Reads state from GPIO. """
|
||||||
|
self._state = rpi_gpio.read_input(self._port)
|
||||||
|
self.update_ha_state()
|
||||||
|
rpi_gpio.edge_detect(self._port, read_gpio, self._bouncetime)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def should_poll(self):
|
||||||
|
""" No polling needed. """
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
""" The name of the sensor. """
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self):
|
||||||
|
""" Returns the state of the entity. """
|
||||||
|
return self._state != self._invert_logic
|
|
@ -49,10 +49,9 @@ def _handle_get_api_locative(hass, see, handler, path_match, data):
|
||||||
handler.write_text("Setting location to {}".format(location_name))
|
handler.write_text("Setting location to {}".format(location_name))
|
||||||
|
|
||||||
elif direction == 'exit':
|
elif direction == 'exit':
|
||||||
current_state = hass.states.get(
|
current_state = hass.states.get("{}.{}".format(DOMAIN, device))
|
||||||
"{}.{}".format(DOMAIN, device)).state
|
|
||||||
|
|
||||||
if current_state == location_name:
|
if current_state is None or current_state.state == location_name:
|
||||||
see(dev_id=device, location_name=STATE_NOT_HOME)
|
see(dev_id=device, location_name=STATE_NOT_HOME)
|
||||||
handler.write_text("Setting location to not home")
|
handler.write_text("Setting location to not home")
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -112,10 +112,10 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer):
|
||||||
_LOGGER.info("running http in development mode")
|
_LOGGER.info("running http in development mode")
|
||||||
|
|
||||||
if ssl_certificate is not None:
|
if ssl_certificate is not None:
|
||||||
wrap_kwargs = {'certfile': ssl_certificate}
|
context = ssl.create_default_context(
|
||||||
if ssl_key is not None:
|
purpose=ssl.Purpose.CLIENT_AUTH)
|
||||||
wrap_kwargs['keyfile'] = ssl_key
|
context.load_cert_chain(ssl_certificate, keyfile=ssl_key)
|
||||||
self.socket = ssl.wrap_socket(self.socket, **wrap_kwargs)
|
self.socket = context.wrap_socket(self.socket, server_side=True)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
""" Starts the HTTP server. """
|
""" Starts the HTTP server. """
|
||||||
|
|
124
homeassistant/components/input_boolean.py
Normal file
124
homeassistant/components/input_boolean.py
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
"""
|
||||||
|
Component to keep track of user controlled booleans for within automation.
|
||||||
|
|
||||||
|
For more details about this component, please refer to the documentation
|
||||||
|
at https://home-assistant.io/components/input_boolean/
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from homeassistant.const import (
|
||||||
|
STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, ATTR_ENTITY_ID)
|
||||||
|
from homeassistant.helpers.entity_component import EntityComponent
|
||||||
|
from homeassistant.helpers.entity import ToggleEntity
|
||||||
|
from homeassistant.util import slugify
|
||||||
|
|
||||||
|
DOMAIN = 'input_boolean'
|
||||||
|
|
||||||
|
ENTITY_ID_FORMAT = DOMAIN + '.{}'
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
CONF_NAME = "name"
|
||||||
|
CONF_INITIAL = "initial"
|
||||||
|
CONF_ICON = "icon"
|
||||||
|
|
||||||
|
|
||||||
|
def is_on(hass, entity_id):
|
||||||
|
"""Test if input_boolean is True."""
|
||||||
|
return hass.states.is_state(entity_id, STATE_ON)
|
||||||
|
|
||||||
|
|
||||||
|
def turn_on(hass, entity_id):
|
||||||
|
"""Set input_boolean to True."""
|
||||||
|
hass.services.call(DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id})
|
||||||
|
|
||||||
|
|
||||||
|
def turn_off(hass, entity_id):
|
||||||
|
"""Set input_boolean to False."""
|
||||||
|
hass.services.call(DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: entity_id})
|
||||||
|
|
||||||
|
|
||||||
|
def setup(hass, config):
|
||||||
|
"""Set up input booleans."""
|
||||||
|
if not isinstance(config.get(DOMAIN), dict):
|
||||||
|
_LOGGER.error('Expected %s config to be a dictionary', DOMAIN)
|
||||||
|
return False
|
||||||
|
|
||||||
|
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||||
|
|
||||||
|
entities = []
|
||||||
|
|
||||||
|
for object_id, cfg in config[DOMAIN].items():
|
||||||
|
if object_id != slugify(object_id):
|
||||||
|
_LOGGER.warning("Found invalid key for boolean input: %s. "
|
||||||
|
"Use %s instead", object_id, slugify(object_id))
|
||||||
|
continue
|
||||||
|
if not cfg:
|
||||||
|
cfg = {}
|
||||||
|
|
||||||
|
name = cfg.get(CONF_NAME)
|
||||||
|
state = cfg.get(CONF_INITIAL, False)
|
||||||
|
icon = cfg.get(CONF_ICON)
|
||||||
|
|
||||||
|
entities.append(InputBoolean(object_id, name, state, icon))
|
||||||
|
|
||||||
|
if not entities:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def toggle_service(service):
|
||||||
|
"""Handle a calls to the input boolean services."""
|
||||||
|
target_inputs = component.extract_from_service(service)
|
||||||
|
|
||||||
|
for input_b in target_inputs:
|
||||||
|
if service.service == SERVICE_TURN_ON:
|
||||||
|
input_b.turn_on()
|
||||||
|
else:
|
||||||
|
input_b.turn_off()
|
||||||
|
|
||||||
|
hass.services.register(DOMAIN, SERVICE_TURN_OFF, toggle_service)
|
||||||
|
hass.services.register(DOMAIN, SERVICE_TURN_ON, toggle_service)
|
||||||
|
|
||||||
|
component.add_entities(entities)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class InputBoolean(ToggleEntity):
|
||||||
|
"""Represent a boolean input within Home Assistant."""
|
||||||
|
|
||||||
|
def __init__(self, object_id, name, state, icon):
|
||||||
|
"""Initialize a boolean input."""
|
||||||
|
self.entity_id = ENTITY_ID_FORMAT.format(object_id)
|
||||||
|
self._name = name
|
||||||
|
self._state = state
|
||||||
|
self._icon = icon
|
||||||
|
|
||||||
|
@property
|
||||||
|
def should_poll(self):
|
||||||
|
"""If entitiy should be polled."""
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Name of the boolean input."""
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def icon(self):
|
||||||
|
"""Icon to be used for this entity."""
|
||||||
|
return self._icon
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self):
|
||||||
|
"""True if entity is on."""
|
||||||
|
return self._state
|
||||||
|
|
||||||
|
def turn_on(self, **kwargs):
|
||||||
|
"""Turn the entity on."""
|
||||||
|
self._state = True
|
||||||
|
self.update_ha_state()
|
||||||
|
|
||||||
|
def turn_off(self, **kwargs):
|
||||||
|
"""Turn the entity off."""
|
||||||
|
self._state = False
|
||||||
|
self.update_ha_state()
|
|
@ -15,7 +15,7 @@ from homeassistant.components.light import ATTR_BRIGHTNESS
|
||||||
|
|
||||||
from homeassistant.const import EVENT_HOMEASSISTANT_STOP, STATE_ON
|
from homeassistant.const import EVENT_HOMEASSISTANT_STOP, STATE_ON
|
||||||
|
|
||||||
REQUIREMENTS = ['pyvera==0.2.3']
|
REQUIREMENTS = ['pyvera==0.2.7']
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -86,4 +86,4 @@ class VeraLight(VeraSwitch):
|
||||||
self.vera_device.switch_on()
|
self.vera_device.switch_on()
|
||||||
|
|
||||||
self._state = STATE_ON
|
self._state = STATE_ON
|
||||||
self.update_ha_state()
|
self.update_ha_state(True)
|
||||||
|
|
69
homeassistant/components/rpi_gpio.py
Normal file
69
homeassistant/components/rpi_gpio.py
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
"""
|
||||||
|
homeassistant.components.rpi_gpio
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
Allows to control the GPIO pins of a Raspberry Pi.
|
||||||
|
|
||||||
|
For more details about this platform, please refer to the documentation at
|
||||||
|
https://home-assistant.io/components/rpi_gpio/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
try:
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
except ImportError:
|
||||||
|
GPIO = None
|
||||||
|
from homeassistant.const import (EVENT_HOMEASSISTANT_START,
|
||||||
|
EVENT_HOMEASSISTANT_STOP)
|
||||||
|
REQUIREMENTS = ['RPi.GPIO==0.6.1']
|
||||||
|
DOMAIN = "rpi_gpio"
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
# pylint: disable=no-member
|
||||||
|
def setup(hass, config):
|
||||||
|
""" Sets up the Raspberry PI GPIO component. """
|
||||||
|
if GPIO is None:
|
||||||
|
_LOGGER.error('RPi.GPIO not available. rpi_gpio ports ignored.')
|
||||||
|
return False
|
||||||
|
|
||||||
|
def cleanup_gpio(event):
|
||||||
|
""" Stuff to do before stop home assistant. """
|
||||||
|
GPIO.cleanup()
|
||||||
|
|
||||||
|
def prepare_gpio(event):
|
||||||
|
""" Stuff to do when home assistant starts. """
|
||||||
|
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, cleanup_gpio)
|
||||||
|
|
||||||
|
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, prepare_gpio)
|
||||||
|
GPIO.setmode(GPIO.BCM)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def setup_output(port):
|
||||||
|
""" Setup a GPIO as output. """
|
||||||
|
GPIO.setup(port, GPIO.OUT)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_input(port, pull_mode):
|
||||||
|
""" Setup a GPIO as input. """
|
||||||
|
GPIO.setup(port, GPIO.IN,
|
||||||
|
GPIO.PUD_DOWN if pull_mode == 'DOWN' else GPIO.PUD_UP)
|
||||||
|
|
||||||
|
|
||||||
|
def write_output(port, value):
|
||||||
|
""" Write a value to a GPIO. """
|
||||||
|
GPIO.output(port, value)
|
||||||
|
|
||||||
|
|
||||||
|
def read_input(port):
|
||||||
|
""" Read a value from a GPIO. """
|
||||||
|
return GPIO.input(port)
|
||||||
|
|
||||||
|
|
||||||
|
def edge_detect(port, event_callback, bounce):
|
||||||
|
""" Adds detection for RISING and FALLING events. """
|
||||||
|
GPIO.add_event_detect(
|
||||||
|
port,
|
||||||
|
GPIO.BOTH,
|
||||||
|
callback=event_callback,
|
||||||
|
bouncetime=bounce)
|
|
@ -81,7 +81,7 @@ def setup(hass, config):
|
||||||
object_id)
|
object_id)
|
||||||
continue
|
continue
|
||||||
alias = cfg.get(CONF_ALIAS, object_id)
|
alias = cfg.get(CONF_ALIAS, object_id)
|
||||||
script = Script(hass, object_id, alias, cfg[CONF_SEQUENCE])
|
script = Script(object_id, alias, cfg[CONF_SEQUENCE])
|
||||||
component.add_entities((script,))
|
component.add_entities((script,))
|
||||||
hass.services.register(DOMAIN, object_id, service_handler)
|
hass.services.register(DOMAIN, object_id, service_handler)
|
||||||
|
|
||||||
|
@ -106,8 +106,7 @@ def setup(hass, config):
|
||||||
class Script(ToggleEntity):
|
class Script(ToggleEntity):
|
||||||
""" Represents a script. """
|
""" Represents a script. """
|
||||||
# pylint: disable=too-many-instance-attributes
|
# pylint: disable=too-many-instance-attributes
|
||||||
def __init__(self, hass, object_id, name, sequence):
|
def __init__(self, object_id, name, sequence):
|
||||||
self.hass = hass
|
|
||||||
self.entity_id = ENTITY_ID_FORMAT.format(object_id)
|
self.entity_id = ENTITY_ID_FORMAT.format(object_id)
|
||||||
self._name = name
|
self._name = name
|
||||||
self.sequence = sequence
|
self.sequence = sequence
|
||||||
|
|
|
@ -38,7 +38,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
for device in structure.devices:
|
for device in structure.devices:
|
||||||
for variable in config['monitored_conditions']:
|
for variable in config['monitored_conditions']:
|
||||||
if variable in SENSOR_TYPES:
|
if variable in SENSOR_TYPES:
|
||||||
add_devices([NestSensor(structure, device, variable)])
|
add_devices([NestBasicSensor(structure, device, variable)])
|
||||||
elif variable in SENSOR_TEMP_TYPES:
|
elif variable in SENSOR_TEMP_TYPES:
|
||||||
add_devices([NestTempSensor(structure,
|
add_devices([NestTempSensor(structure,
|
||||||
device,
|
device,
|
||||||
|
@ -76,6 +76,8 @@ class NestSensor(Entity):
|
||||||
name,
|
name,
|
||||||
self.variable)
|
self.variable)
|
||||||
|
|
||||||
|
|
||||||
|
class NestBasicSensor(NestSensor):
|
||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self):
|
||||||
""" Returns the state of the sensor. """
|
""" Returns the state of the sensor. """
|
||||||
|
@ -87,7 +89,7 @@ class NestSensor(Entity):
|
||||||
return SENSOR_UNITS.get(self.variable, None)
|
return SENSOR_UNITS.get(self.variable, None)
|
||||||
|
|
||||||
|
|
||||||
class NestTempSensor(NestSensor):
|
class NestTempSensor(NestBasicSensor):
|
||||||
""" Represents a Nest Temperature sensor. """
|
""" Represents a Nest Temperature sensor. """
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -1,97 +0,0 @@
|
||||||
"""
|
|
||||||
homeassistant.components.sensor.rpi_gpio
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Allows to configure a binary state sensor using RPi GPIO.
|
|
||||||
|
|
||||||
For more details about this platform, please refer to the documentation at
|
|
||||||
https://home-assistant.io/components/sensor.rpi_gpio/
|
|
||||||
"""
|
|
||||||
# pylint: disable=import-error
|
|
||||||
import logging
|
|
||||||
from homeassistant.helpers.entity import Entity
|
|
||||||
|
|
||||||
from homeassistant.const import (DEVICE_DEFAULT_NAME,
|
|
||||||
EVENT_HOMEASSISTANT_START,
|
|
||||||
EVENT_HOMEASSISTANT_STOP)
|
|
||||||
|
|
||||||
DEFAULT_PULL_MODE = "UP"
|
|
||||||
DEFAULT_VALUE_HIGH = "HIGH"
|
|
||||||
DEFAULT_VALUE_LOW = "LOW"
|
|
||||||
DEFAULT_BOUNCETIME = 50
|
|
||||||
|
|
||||||
REQUIREMENTS = ['RPi.GPIO==0.5.11']
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
|
||||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
|
||||||
""" Sets up the Raspberry PI GPIO ports. """
|
|
||||||
import RPi.GPIO as GPIO
|
|
||||||
GPIO.setmode(GPIO.BCM)
|
|
||||||
|
|
||||||
sensors = []
|
|
||||||
pull_mode = config.get('pull_mode', DEFAULT_PULL_MODE)
|
|
||||||
value_high = config.get('value_high', DEFAULT_VALUE_HIGH)
|
|
||||||
value_low = config.get('value_low', DEFAULT_VALUE_LOW)
|
|
||||||
bouncetime = config.get('bouncetime', DEFAULT_BOUNCETIME)
|
|
||||||
ports = config.get('ports')
|
|
||||||
for port_num, port_name in ports.items():
|
|
||||||
sensors.append(RPiGPIOSensor(
|
|
||||||
port_name, port_num, pull_mode,
|
|
||||||
value_high, value_low, bouncetime))
|
|
||||||
add_devices(sensors)
|
|
||||||
|
|
||||||
def cleanup_gpio(event):
|
|
||||||
""" Stuff to do before stop home assistant. """
|
|
||||||
# pylint: disable=no-member
|
|
||||||
GPIO.cleanup()
|
|
||||||
|
|
||||||
def prepare_gpio(event):
|
|
||||||
""" Stuff to do when home assistant starts. """
|
|
||||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, cleanup_gpio)
|
|
||||||
|
|
||||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, prepare_gpio)
|
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=too-many-arguments, too-many-instance-attributes
|
|
||||||
class RPiGPIOSensor(Entity):
|
|
||||||
""" Sets up the Raspberry PI GPIO ports. """
|
|
||||||
def __init__(self, port_name, port_num, pull_mode,
|
|
||||||
value_high, value_low, bouncetime):
|
|
||||||
# pylint: disable=no-member
|
|
||||||
import RPi.GPIO as GPIO
|
|
||||||
self._name = port_name or DEVICE_DEFAULT_NAME
|
|
||||||
self._port = port_num
|
|
||||||
self._pull = GPIO.PUD_DOWN if pull_mode == "DOWN" else GPIO.PUD_UP
|
|
||||||
self._vhigh = value_high
|
|
||||||
self._vlow = value_low
|
|
||||||
self._bouncetime = bouncetime
|
|
||||||
GPIO.setup(self._port, GPIO.IN, pull_up_down=self._pull)
|
|
||||||
self._state = self._vhigh if GPIO.input(self._port) else self._vlow
|
|
||||||
|
|
||||||
def edge_callback(channel):
|
|
||||||
""" port changed state """
|
|
||||||
# pylint: disable=no-member
|
|
||||||
self._state = self._vhigh if GPIO.input(channel) else self._vlow
|
|
||||||
self.update_ha_state()
|
|
||||||
|
|
||||||
GPIO.add_event_detect(
|
|
||||||
self._port,
|
|
||||||
GPIO.BOTH,
|
|
||||||
callback=edge_callback,
|
|
||||||
bouncetime=self._bouncetime)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def should_poll(self):
|
|
||||||
""" No polling needed. """
|
|
||||||
return False
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
""" The name of the sensor. """
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def state(self):
|
|
||||||
""" Returns the state of the entity. """
|
|
||||||
return self._state
|
|
|
@ -15,7 +15,7 @@ from homeassistant.const import (
|
||||||
ATTR_BATTERY_LEVEL, ATTR_TRIPPED, ATTR_ARMED, ATTR_LAST_TRIP_TIME,
|
ATTR_BATTERY_LEVEL, ATTR_TRIPPED, ATTR_ARMED, ATTR_LAST_TRIP_TIME,
|
||||||
TEMP_CELCIUS, TEMP_FAHRENHEIT, EVENT_HOMEASSISTANT_STOP)
|
TEMP_CELCIUS, TEMP_FAHRENHEIT, EVENT_HOMEASSISTANT_STOP)
|
||||||
|
|
||||||
REQUIREMENTS = ['pyvera==0.2.3']
|
REQUIREMENTS = ['pyvera==0.2.7']
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -45,7 +45,10 @@ def get_devices(hass, config):
|
||||||
|
|
||||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_subscription)
|
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_subscription)
|
||||||
|
|
||||||
categories = ['Temperature Sensor', 'Light Sensor', 'Sensor']
|
categories = ['Temperature Sensor',
|
||||||
|
'Light Sensor',
|
||||||
|
'Humidity Sensor',
|
||||||
|
'Sensor']
|
||||||
devices = []
|
devices = []
|
||||||
try:
|
try:
|
||||||
devices = vera_controller.get_devices(categories)
|
devices = vera_controller.get_devices(categories)
|
||||||
|
@ -86,6 +89,7 @@ class VeraSensor(Entity):
|
||||||
self._temperature_units = None
|
self._temperature_units = None
|
||||||
|
|
||||||
self.controller.register(vera_device, self._update_callback)
|
self.controller.register(vera_device, self._update_callback)
|
||||||
|
self.update()
|
||||||
|
|
||||||
def _update_callback(self, _device):
|
def _update_callback(self, _device):
|
||||||
""" Called by the vera device callback to update state. """
|
""" Called by the vera device callback to update state. """
|
||||||
|
@ -106,7 +110,12 @@ class VeraSensor(Entity):
|
||||||
@property
|
@property
|
||||||
def unit_of_measurement(self):
|
def unit_of_measurement(self):
|
||||||
""" Unit of measurement of this entity, if any. """
|
""" Unit of measurement of this entity, if any. """
|
||||||
|
if self.vera_device.category == "Temperature Sensor":
|
||||||
return self._temperature_units
|
return self._temperature_units
|
||||||
|
elif self.vera_device.category == "Light Sensor":
|
||||||
|
return 'lux'
|
||||||
|
elif self.vera_device.category == "Humidity Sensor":
|
||||||
|
return '%'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state_attributes(self):
|
def state_attributes(self):
|
||||||
|
@ -115,19 +124,19 @@ class VeraSensor(Entity):
|
||||||
attr[ATTR_BATTERY_LEVEL] = self.vera_device.battery_level + '%'
|
attr[ATTR_BATTERY_LEVEL] = self.vera_device.battery_level + '%'
|
||||||
|
|
||||||
if self.vera_device.is_armable:
|
if self.vera_device.is_armable:
|
||||||
armed = self.vera_device.get_value('Armed')
|
armed = self.vera_device.is_armed
|
||||||
attr[ATTR_ARMED] = 'True' if armed == '1' else 'False'
|
attr[ATTR_ARMED] = 'True' if armed else 'False'
|
||||||
|
|
||||||
if self.vera_device.is_trippable:
|
if self.vera_device.is_trippable:
|
||||||
last_tripped = self.vera_device.get_value('LastTrip')
|
last_tripped = self.vera_device.last_trip
|
||||||
if last_tripped is not None:
|
if last_tripped is not None:
|
||||||
utc_time = dt_util.utc_from_timestamp(int(last_tripped))
|
utc_time = dt_util.utc_from_timestamp(int(last_tripped))
|
||||||
attr[ATTR_LAST_TRIP_TIME] = dt_util.datetime_to_str(
|
attr[ATTR_LAST_TRIP_TIME] = dt_util.datetime_to_str(
|
||||||
utc_time)
|
utc_time)
|
||||||
else:
|
else:
|
||||||
attr[ATTR_LAST_TRIP_TIME] = None
|
attr[ATTR_LAST_TRIP_TIME] = None
|
||||||
tripped = self.vera_device.get_value('Tripped')
|
tripped = self.vera_device.is_tripped
|
||||||
attr[ATTR_TRIPPED] = 'True' if tripped == '1' else 'False'
|
attr[ATTR_TRIPPED] = 'True' if tripped else 'False'
|
||||||
|
|
||||||
attr['Vera Device Id'] = self.vera_device.vera_device_id
|
attr['Vera Device Id'] = self.vera_device.vera_device_id
|
||||||
return attr
|
return attr
|
||||||
|
@ -139,8 +148,9 @@ class VeraSensor(Entity):
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
if self.vera_device.category == "Temperature Sensor":
|
if self.vera_device.category == "Temperature Sensor":
|
||||||
current_temp = self.vera_device.get_value('CurrentTemperature')
|
current_temp = self.vera_device.temperature
|
||||||
vera_temp_units = self.vera_device.veraController.temperature_units
|
vera_temp_units = (
|
||||||
|
self.vera_device.vera_controller.temperature_units)
|
||||||
|
|
||||||
if vera_temp_units == 'F':
|
if vera_temp_units == 'F':
|
||||||
self._temperature_units = TEMP_FAHRENHEIT
|
self._temperature_units = TEMP_FAHRENHEIT
|
||||||
|
@ -156,9 +166,11 @@ class VeraSensor(Entity):
|
||||||
|
|
||||||
self.current_value = current_temp
|
self.current_value = current_temp
|
||||||
elif self.vera_device.category == "Light Sensor":
|
elif self.vera_device.category == "Light Sensor":
|
||||||
self.current_value = self.vera_device.get_value('CurrentLevel')
|
self.current_value = self.vera_device.light
|
||||||
|
elif self.vera_device.category == "Humidity Sensor":
|
||||||
|
self.current_value = self.vera_device.humidity
|
||||||
elif self.vera_device.category == "Sensor":
|
elif self.vera_device.category == "Sensor":
|
||||||
tripped = self.vera_device.get_value('Tripped')
|
tripped = self.vera_device.is_tripped
|
||||||
self.current_value = 'Tripped' if tripped == '1' else 'Not Tripped'
|
self.current_value = 'Tripped' if tripped else 'Not Tripped'
|
||||||
else:
|
else:
|
||||||
self.current_value = 'Unknown'
|
self.current_value = 'Unknown'
|
||||||
|
|
|
@ -1,69 +1,48 @@
|
||||||
"""
|
"""
|
||||||
homeassistant.components.switch.rpi_gpio
|
homeassistant.components.switch.rpi_gpio
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Allows to control the GPIO pins of a Raspberry Pi.
|
Allows to configure a switch using RPi GPIO.
|
||||||
|
|
||||||
For more details about this platform, please refer to the documentation at
|
For more details about this platform, please refer to the documentation at
|
||||||
https://home-assistant.io/components/switch.rpi_gpio/
|
https://home-assistant.io/components/switch.rpi_gpio/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
try:
|
import homeassistant.components.rpi_gpio as rpi_gpio
|
||||||
import RPi.GPIO as GPIO
|
|
||||||
except ImportError:
|
|
||||||
GPIO = None
|
|
||||||
from homeassistant.helpers.entity import ToggleEntity
|
from homeassistant.helpers.entity import ToggleEntity
|
||||||
from homeassistant.const import (DEVICE_DEFAULT_NAME,
|
from homeassistant.const import (DEVICE_DEFAULT_NAME)
|
||||||
EVENT_HOMEASSISTANT_START,
|
|
||||||
EVENT_HOMEASSISTANT_STOP)
|
|
||||||
|
|
||||||
DEFAULT_INVERT_LOGIC = False
|
DEFAULT_INVERT_LOGIC = False
|
||||||
|
|
||||||
REQUIREMENTS = ['RPi.GPIO==0.5.11']
|
DEPENDENCIES = ['rpi_gpio']
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
""" Sets up the Raspberry PI GPIO ports. """
|
""" Sets up the Raspberry PI GPIO devices. """
|
||||||
if GPIO is None:
|
|
||||||
_LOGGER.error('RPi.GPIO not available. rpi_gpio ports ignored.')
|
invert_logic = config.get('invert_logic', DEFAULT_INVERT_LOGIC)
|
||||||
return
|
|
||||||
# pylint: disable=no-member
|
|
||||||
GPIO.setmode(GPIO.BCM)
|
|
||||||
|
|
||||||
switches = []
|
switches = []
|
||||||
invert_logic = config.get('invert_logic', DEFAULT_INVERT_LOGIC)
|
|
||||||
ports = config.get('ports')
|
ports = config.get('ports')
|
||||||
for port_num, port_name in ports.items():
|
for port, name in ports.items():
|
||||||
switches.append(RPiGPIOSwitch(port_name, port_num, invert_logic))
|
switches.append(RPiGPIOSwitch(name, port, invert_logic))
|
||||||
add_devices(switches)
|
add_devices(switches)
|
||||||
|
|
||||||
def cleanup_gpio(event):
|
|
||||||
""" Stuff to do before stop home assistant. """
|
|
||||||
# pylint: disable=no-member
|
|
||||||
GPIO.cleanup()
|
|
||||||
|
|
||||||
def prepare_gpio(event):
|
|
||||||
""" Stuff to do when home assistant starts. """
|
|
||||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, cleanup_gpio)
|
|
||||||
|
|
||||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, prepare_gpio)
|
|
||||||
|
|
||||||
|
|
||||||
class RPiGPIOSwitch(ToggleEntity):
|
class RPiGPIOSwitch(ToggleEntity):
|
||||||
""" Represents a port that can be toggled using Raspberry Pi GPIO. """
|
""" Represents a switch that can be toggled using Raspberry Pi GPIO. """
|
||||||
|
def __init__(self, name, port, invert_logic):
|
||||||
def __init__(self, name, gpio, invert_logic):
|
|
||||||
self._name = name or DEVICE_DEFAULT_NAME
|
self._name = name or DEVICE_DEFAULT_NAME
|
||||||
self._gpio = gpio
|
self._port = port
|
||||||
self._active_state = not invert_logic
|
self._invert_logic = invert_logic
|
||||||
self._state = not self._active_state
|
self._state = False
|
||||||
# pylint: disable=no-member
|
rpi_gpio.setup_output(self._port)
|
||||||
GPIO.setup(gpio, GPIO.OUT)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
""" The name of the port. """
|
""" The name of the switch. """
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -76,41 +55,14 @@ class RPiGPIOSwitch(ToggleEntity):
|
||||||
""" True if device is on. """
|
""" True if device is on. """
|
||||||
return self._state
|
return self._state
|
||||||
|
|
||||||
def turn_on(self, **kwargs):
|
def turn_on(self):
|
||||||
""" Turn the device on. """
|
""" Turn the device on. """
|
||||||
if self._switch(self._active_state):
|
rpi_gpio.write_output(self._port, 0 if self._invert_logic else 1)
|
||||||
self._state = True
|
self._state = True
|
||||||
self.update_ha_state()
|
self.update_ha_state()
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self):
|
||||||
""" Turn the device off. """
|
""" Turn the device off. """
|
||||||
if self._switch(not self._active_state):
|
rpi_gpio.write_output(self._port, 1 if self._invert_logic else 0)
|
||||||
self._state = False
|
self._state = False
|
||||||
self.update_ha_state()
|
self.update_ha_state()
|
||||||
|
|
||||||
def _switch(self, new_state):
|
|
||||||
""" Change the output value to Raspberry Pi GPIO port. """
|
|
||||||
_LOGGER.info('Setting GPIO %s to %s', self._gpio, new_state)
|
|
||||||
# pylint: disable=bare-except
|
|
||||||
try:
|
|
||||||
# pylint: disable=no-member
|
|
||||||
GPIO.output(self._gpio, 1 if new_state else 0)
|
|
||||||
except:
|
|
||||||
_LOGGER.error('GPIO "%s" output failed', self._gpio)
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
# pylint: disable=no-self-use
|
|
||||||
@property
|
|
||||||
def device_state_attributes(self):
|
|
||||||
""" Returns device specific state attributes. """
|
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def state_attributes(self):
|
|
||||||
""" Returns optional state attributes. """
|
|
||||||
data = {}
|
|
||||||
device_attr = self.device_state_attributes
|
|
||||||
if device_attr is not None:
|
|
||||||
data.update(device_attr)
|
|
||||||
return data
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ from homeassistant.const import (
|
||||||
STATE_ON,
|
STATE_ON,
|
||||||
STATE_OFF)
|
STATE_OFF)
|
||||||
|
|
||||||
REQUIREMENTS = ['pyvera==0.2.3']
|
REQUIREMENTS = ['pyvera==0.2.7']
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -91,14 +91,10 @@ class VeraSwitch(SwitchDevice):
|
||||||
self._state = STATE_OFF
|
self._state = STATE_OFF
|
||||||
|
|
||||||
self.controller.register(vera_device, self._update_callback)
|
self.controller.register(vera_device, self._update_callback)
|
||||||
|
self.update()
|
||||||
|
|
||||||
def _update_callback(self, _device):
|
def _update_callback(self, _device):
|
||||||
""" Called by the vera device callback to update state. """
|
self.update_ha_state(True)
|
||||||
if self.vera_device.is_switched_on():
|
|
||||||
self._state = STATE_ON
|
|
||||||
else:
|
|
||||||
self._state = STATE_OFF
|
|
||||||
self.update_ha_state()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
@ -113,19 +109,19 @@ class VeraSwitch(SwitchDevice):
|
||||||
attr[ATTR_BATTERY_LEVEL] = self.vera_device.battery_level + '%'
|
attr[ATTR_BATTERY_LEVEL] = self.vera_device.battery_level + '%'
|
||||||
|
|
||||||
if self.vera_device.is_armable:
|
if self.vera_device.is_armable:
|
||||||
armed = self.vera_device.get_value('Armed')
|
armed = self.vera_device.is_armed
|
||||||
attr[ATTR_ARMED] = 'True' if armed == '1' else 'False'
|
attr[ATTR_ARMED] = 'True' if armed else 'False'
|
||||||
|
|
||||||
if self.vera_device.is_trippable:
|
if self.vera_device.is_trippable:
|
||||||
last_tripped = self.vera_device.get_value('LastTrip')
|
last_tripped = self.vera_device.last_trip
|
||||||
if last_tripped is not None:
|
if last_tripped is not None:
|
||||||
utc_time = dt_util.utc_from_timestamp(int(last_tripped))
|
utc_time = dt_util.utc_from_timestamp(int(last_tripped))
|
||||||
attr[ATTR_LAST_TRIP_TIME] = dt_util.datetime_to_str(
|
attr[ATTR_LAST_TRIP_TIME] = dt_util.datetime_to_str(
|
||||||
utc_time)
|
utc_time)
|
||||||
else:
|
else:
|
||||||
attr[ATTR_LAST_TRIP_TIME] = None
|
attr[ATTR_LAST_TRIP_TIME] = None
|
||||||
tripped = self.vera_device.get_value('Tripped')
|
tripped = self.vera_device.is_tripped
|
||||||
attr[ATTR_TRIPPED] = 'True' if tripped == '1' else 'False'
|
attr[ATTR_TRIPPED] = 'True' if tripped else 'False'
|
||||||
|
|
||||||
attr['Vera Device Id'] = self.vera_device.vera_device_id
|
attr['Vera Device Id'] = self.vera_device.vera_device_id
|
||||||
|
|
||||||
|
@ -150,3 +146,10 @@ class VeraSwitch(SwitchDevice):
|
||||||
def is_on(self):
|
def is_on(self):
|
||||||
""" True if device is on. """
|
""" True if device is on. """
|
||||||
return self._state == STATE_ON
|
return self._state == STATE_ON
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
""" Called by the vera device callback to update state. """
|
||||||
|
if self.vera_device.is_switched_on():
|
||||||
|
self._state = STATE_ON
|
||||||
|
else:
|
||||||
|
self._state = STATE_OFF
|
||||||
|
|
|
@ -44,6 +44,7 @@ SHOW_THERMOMETERS = True
|
||||||
SHOW_HYGROMETERS = True
|
SHOW_HYGROMETERS = True
|
||||||
SHOW_ALARM = True
|
SHOW_ALARM = True
|
||||||
SHOW_SMARTPLUGS = True
|
SHOW_SMARTPLUGS = True
|
||||||
|
CODE_DIGITS = 4
|
||||||
|
|
||||||
# if wrong password was given don't try again
|
# if wrong password was given don't try again
|
||||||
WRONG_PASSWORD_GIVEN = False
|
WRONG_PASSWORD_GIVEN = False
|
||||||
|
@ -61,11 +62,13 @@ def setup(hass, config):
|
||||||
|
|
||||||
from verisure import MyPages, LoginError, Error
|
from verisure import MyPages, LoginError, Error
|
||||||
|
|
||||||
global SHOW_THERMOMETERS, SHOW_HYGROMETERS, SHOW_ALARM, SHOW_SMARTPLUGS
|
global SHOW_THERMOMETERS, SHOW_HYGROMETERS,\
|
||||||
|
SHOW_ALARM, SHOW_SMARTPLUGS, CODE_DIGITS
|
||||||
SHOW_THERMOMETERS = int(config[DOMAIN].get('thermometers', '1'))
|
SHOW_THERMOMETERS = int(config[DOMAIN].get('thermometers', '1'))
|
||||||
SHOW_HYGROMETERS = int(config[DOMAIN].get('hygrometers', '1'))
|
SHOW_HYGROMETERS = int(config[DOMAIN].get('hygrometers', '1'))
|
||||||
SHOW_ALARM = int(config[DOMAIN].get('alarm', '1'))
|
SHOW_ALARM = int(config[DOMAIN].get('alarm', '1'))
|
||||||
SHOW_SMARTPLUGS = int(config[DOMAIN].get('smartplugs', '1'))
|
SHOW_SMARTPLUGS = int(config[DOMAIN].get('smartplugs', '1'))
|
||||||
|
CODE_DIGITS = int(config[DOMAIN].get('code_digits', '4'))
|
||||||
|
|
||||||
global MY_PAGES
|
global MY_PAGES
|
||||||
MY_PAGES = MyPages(
|
MY_PAGES = MyPages(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
""" Constants used by Home Assistant components. """
|
""" Constants used by Home Assistant components. """
|
||||||
|
|
||||||
__version__ = "0.11.0.dev0"
|
__version__ = "0.12.0.dev0"
|
||||||
|
|
||||||
# Can be used to specify a catch all when registering state or event listeners.
|
# Can be used to specify a catch all when registering state or event listeners.
|
||||||
MATCH_ALL = '*'
|
MATCH_ALL = '*'
|
||||||
|
|
|
@ -62,7 +62,7 @@ tellcore-py==1.1.2
|
||||||
# homeassistant.components.light.vera
|
# homeassistant.components.light.vera
|
||||||
# homeassistant.components.sensor.vera
|
# homeassistant.components.sensor.vera
|
||||||
# homeassistant.components.switch.vera
|
# homeassistant.components.switch.vera
|
||||||
pyvera==0.2.3
|
pyvera==0.2.7
|
||||||
|
|
||||||
# homeassistant.components.wink
|
# homeassistant.components.wink
|
||||||
# homeassistant.components.light.wink
|
# homeassistant.components.light.wink
|
||||||
|
@ -125,6 +125,9 @@ dnspython3==1.12.0
|
||||||
# homeassistant.components.rfxtrx
|
# homeassistant.components.rfxtrx
|
||||||
https://github.com/Danielhiversen/pyRFXtrx/archive/0.2.zip#RFXtrx==0.2
|
https://github.com/Danielhiversen/pyRFXtrx/archive/0.2.zip#RFXtrx==0.2
|
||||||
|
|
||||||
|
# homeassistant.components.rpi_gpio
|
||||||
|
# RPi.GPIO==0.6.1
|
||||||
|
|
||||||
# homeassistant.components.sensor.bitcoin
|
# homeassistant.components.sensor.bitcoin
|
||||||
blockchain==1.1.2
|
blockchain==1.1.2
|
||||||
|
|
||||||
|
@ -149,10 +152,6 @@ https://github.com/HydrelioxGitHub/netatmo-api-python/archive/43ff238a0122b0939a
|
||||||
# homeassistant.components.sensor.openweathermap
|
# homeassistant.components.sensor.openweathermap
|
||||||
pyowm==2.3.0
|
pyowm==2.3.0
|
||||||
|
|
||||||
# homeassistant.components.sensor.rpi_gpio
|
|
||||||
# homeassistant.components.switch.rpi_gpio
|
|
||||||
# RPi.GPIO==0.5.11
|
|
||||||
|
|
||||||
# homeassistant.components.sensor.sabnzbd
|
# homeassistant.components.sensor.sabnzbd
|
||||||
https://github.com/jamespcole/home-assistant-nzb-clients/archive/616cad59154092599278661af17e2a9f2cf5e2a9.zip#python-sabnzbd==0.1
|
https://github.com/jamespcole/home-assistant-nzb-clients/archive/616cad59154092599278661af17e2a9f2cf5e2a9.zip#python-sabnzbd==0.1
|
||||||
|
|
||||||
|
|
113
script/nginx-hass
Normal file
113
script/nginx-hass
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
##
|
||||||
|
#
|
||||||
|
# Home Assistant - nginx Configuration File
|
||||||
|
#
|
||||||
|
# Using nginx as a proxy for Home Assistant allows you to serve Home Assisatnt
|
||||||
|
# securely over standard ports. This configuration file and instructions will
|
||||||
|
# walk you through setting up Home Assistant over a secure connection.
|
||||||
|
#
|
||||||
|
# 1) Get a domain name forwarded to your IP.
|
||||||
|
# Chances are, you have a dynamic IP Address (your ISP changes your address
|
||||||
|
# periodically). If this is true, you can use a Dynamic DNS service to obtain
|
||||||
|
# a domain and set it up to update with you IP. If you purchase your own
|
||||||
|
# domain name, you will be able to easily get a trusted SSL certificate
|
||||||
|
# later.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# 2) Install nginx on your server.
|
||||||
|
# This will vary depending on your OS. Check out Google for this. After
|
||||||
|
# installing, ensure that nginx is not running.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# 3) Obtain an SSL certificate.
|
||||||
|
#
|
||||||
|
# 3a) Using Let's Encrypt
|
||||||
|
# If you purchased your own domain, you can use https://letsencrypt.org/ to
|
||||||
|
# obtain a free, publicly trusted SSL certificate. This will allow you to
|
||||||
|
# work with services like IFTTT. Download and install per the instructions
|
||||||
|
# online and get a certificate using the following command.
|
||||||
|
#
|
||||||
|
# ./letsencrypt-auto certonly --standalone -d example.com -d www.example.com
|
||||||
|
#
|
||||||
|
# Instead of example.com, use your domain. You will need to renew this
|
||||||
|
# certificate every 90 days.
|
||||||
|
#
|
||||||
|
# 3b) Using openssl
|
||||||
|
# If you do not own your own domain, you may generate a self-signed
|
||||||
|
# certificate. This will not work with IFTTT, but it will encrypt all of your
|
||||||
|
# Home Assistant traffic.
|
||||||
|
#
|
||||||
|
# openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 9999
|
||||||
|
# sudo cp key.pem cert.pem /etc/nginx/ssl
|
||||||
|
# sudo chmod 600 /etc/nginx/ssl/key.pem /etc/nginx/ssl/cert.pem
|
||||||
|
# sudo chown root:root /etc/nginx/ssl/key.pem /etc/nginx/ssl/cert.pem
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# 4) Create dhparams file
|
||||||
|
# As a fair warning, this file will take a while to generate.
|
||||||
|
#
|
||||||
|
# cd /etc/nginx/ssl
|
||||||
|
# sudo openssl dhparam -out dhparams.pem 2048
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# 5) Install this configuration file in nginx.
|
||||||
|
#
|
||||||
|
# cp nginx-hass /etc/nginx/sites-available/hass
|
||||||
|
# cd /etc/nginx/sites-enabled
|
||||||
|
# sudo unlink default
|
||||||
|
# sudo ln ../sites-available/hass default
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# 6) Double check this configuration to ensure all settings are correct and
|
||||||
|
# start nginx.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# 7) Forward ports 443 and 80 to your server on your router. Do not forward
|
||||||
|
# port 8123.
|
||||||
|
#
|
||||||
|
##
|
||||||
|
|
||||||
|
server {
|
||||||
|
# Update this line to be your domain
|
||||||
|
server_name example.com;
|
||||||
|
|
||||||
|
|
||||||
|
# These shouldn't need to be changed
|
||||||
|
listen 80 default_server;
|
||||||
|
listen [::]:80 default_server ipv6only=on;
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
server {
|
||||||
|
# Update this line to be your domain
|
||||||
|
server_name example.com;
|
||||||
|
|
||||||
|
# Ensure these lines point to your SSL certificate and key
|
||||||
|
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
|
||||||
|
# Use these lines instead if you created a self-signed certificate
|
||||||
|
# ssl_certificate /etc/nginx/ssl/cert.pem;
|
||||||
|
# ssl_certificate_key /etc/nginx/ssl/key.pem;
|
||||||
|
|
||||||
|
# Ensure this line points to your dhparams file
|
||||||
|
ssl_dhparam /etc/nginx/ssl/dhparams.pem;
|
||||||
|
|
||||||
|
|
||||||
|
# These shouldn't need to be changed
|
||||||
|
listen 443 default_server;
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
|
||||||
|
ssl on;
|
||||||
|
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||||
|
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_session_cache shared:SSL:10m;
|
||||||
|
|
||||||
|
proxy_buffering off;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://localhost:8123;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_redirect http:// https://;
|
||||||
|
}
|
||||||
|
}
|
|
@ -203,3 +203,21 @@ class TestLocative(unittest.TestCase):
|
||||||
|
|
||||||
state = hass.states.get('{}.{}'.format('device_tracker', data['device']))
|
state = hass.states.get('{}.{}'.format('device_tracker', data['device']))
|
||||||
self.assertEqual(state.state, 'work')
|
self.assertEqual(state.state, 'work')
|
||||||
|
|
||||||
|
def test_exit_first(self, update_config):
|
||||||
|
""" Test when an exit message is sent first on a new device """
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'latitude': 40.7855,
|
||||||
|
'longitude': -111.7367,
|
||||||
|
'device': 'new_device',
|
||||||
|
'id': 'Home',
|
||||||
|
'trigger': 'exit'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Exit Home
|
||||||
|
req = requests.get(_url(data))
|
||||||
|
self.assertEqual(200, req.status_code)
|
||||||
|
|
||||||
|
state = hass.states.get('{}.{}'.format('device_tracker', data['device']))
|
||||||
|
self.assertEqual(state.state, 'not_home')
|
||||||
|
|
99
tests/components/test_input_boolean.py
Normal file
99
tests/components/test_input_boolean.py
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
"""
|
||||||
|
tests.components.test_input_boolean
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Tests input_boolean component.
|
||||||
|
"""
|
||||||
|
# pylint: disable=too-many-public-methods,protected-access
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from homeassistant.components import input_boolean
|
||||||
|
from homeassistant.const import (
|
||||||
|
STATE_ON, STATE_OFF, ATTR_ICON, ATTR_FRIENDLY_NAME)
|
||||||
|
|
||||||
|
from tests.common import get_test_home_assistant
|
||||||
|
|
||||||
|
|
||||||
|
class TestInputBoolean(unittest.TestCase):
|
||||||
|
""" Test the input boolean module. """
|
||||||
|
|
||||||
|
def setUp(self): # pylint: disable=invalid-name
|
||||||
|
self.hass = get_test_home_assistant()
|
||||||
|
|
||||||
|
def tearDown(self): # pylint: disable=invalid-name
|
||||||
|
""" Stop down stuff we started. """
|
||||||
|
self.hass.stop()
|
||||||
|
|
||||||
|
def test_config(self):
|
||||||
|
"""Test config."""
|
||||||
|
self.assertFalse(input_boolean.setup(self.hass, {
|
||||||
|
'input_boolean': None
|
||||||
|
}))
|
||||||
|
|
||||||
|
self.assertFalse(input_boolean.setup(self.hass, {
|
||||||
|
'input_boolean': {
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
self.assertFalse(input_boolean.setup(self.hass, {
|
||||||
|
'input_boolean': {
|
||||||
|
'name with space': None
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
def test_methods(self):
|
||||||
|
""" Test is_on, turn_on, turn_off methods. """
|
||||||
|
self.assertTrue(input_boolean.setup(self.hass, {
|
||||||
|
'input_boolean': {
|
||||||
|
'test_1': None,
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
entity_id = 'input_boolean.test_1'
|
||||||
|
|
||||||
|
self.assertFalse(
|
||||||
|
input_boolean.is_on(self.hass, entity_id))
|
||||||
|
|
||||||
|
input_boolean.turn_on(self.hass, entity_id)
|
||||||
|
|
||||||
|
self.hass.pool.block_till_done()
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
input_boolean.is_on(self.hass, entity_id))
|
||||||
|
|
||||||
|
input_boolean.turn_off(self.hass, entity_id)
|
||||||
|
|
||||||
|
self.hass.pool.block_till_done()
|
||||||
|
|
||||||
|
self.assertFalse(
|
||||||
|
input_boolean.is_on(self.hass, entity_id))
|
||||||
|
|
||||||
|
def test_config_options(self):
|
||||||
|
count_start = len(self.hass.states.entity_ids())
|
||||||
|
|
||||||
|
self.assertTrue(input_boolean.setup(self.hass, {
|
||||||
|
'input_boolean': {
|
||||||
|
'test_1': None,
|
||||||
|
'test_2': {
|
||||||
|
'name': 'Hello World',
|
||||||
|
'icon': 'work',
|
||||||
|
'initial': True,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
|
self.assertEqual(count_start + 2, len(self.hass.states.entity_ids()))
|
||||||
|
|
||||||
|
state_1 = self.hass.states.get('input_boolean.test_1')
|
||||||
|
state_2 = self.hass.states.get('input_boolean.test_2')
|
||||||
|
|
||||||
|
self.assertIsNotNone(state_1)
|
||||||
|
self.assertIsNotNone(state_2)
|
||||||
|
|
||||||
|
self.assertEqual(STATE_OFF, state_1.state)
|
||||||
|
self.assertNotIn(ATTR_ICON, state_1.attributes)
|
||||||
|
self.assertNotIn(ATTR_FRIENDLY_NAME, state_1.attributes)
|
||||||
|
|
||||||
|
self.assertEqual(STATE_ON, state_2.state)
|
||||||
|
self.assertEqual('Hello World',
|
||||||
|
state_2.attributes.get(ATTR_FRIENDLY_NAME))
|
||||||
|
self.assertEqual('work', state_2.attributes.get(ATTR_ICON))
|
Loading…
Add table
Add a link
Reference in a new issue