Merge pull request #257 from persandstrom/verisure

Support for Verisure
This commit is contained in:
Paulus Schoutsen 2015-08-16 21:06:24 -07:00
commit 6e41eee6cd
6 changed files with 288 additions and 3 deletions

View File

@ -6,7 +6,7 @@ Component to interface with various sensors that can be monitored.
import logging
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.components import wink, zwave, isy994
from homeassistant.components import wink, zwave, isy994, verisure
DOMAIN = 'sensor'
DEPENDENCIES = []
@ -18,7 +18,8 @@ ENTITY_ID_FORMAT = DOMAIN + '.{}'
DISCOVERY_PLATFORMS = {
wink.DISCOVER_SENSORS: 'wink',
zwave.DISCOVER_SENSORS: 'zwave',
isy994.DISCOVER_SENSORS: 'isy994'
isy994.DISCOVER_SENSORS: 'isy994',
verisure.DISCOVER_SENSORS: 'verisure'
}

View File

@ -0,0 +1,83 @@
"""
homeassistant.components.sensor.verisure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Interfaces with Verisure sensors.
"""
import logging
import homeassistant.components.verisure as verisure
from homeassistant.helpers.entity import Entity
from homeassistant.const import TEMP_CELCIUS
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None):
""" Sets up the Verisure platform. """
if not verisure.MY_PAGES:
_LOGGER.error('A connection has not been made to Verisure mypages.')
return False
sensors = []
sensors.extend([
VerisureClimateDevice(value)
for value in verisure.get_climate_status().values()
])
sensors.extend([
VerisureAlarmDevice(value)
for value in verisure.get_alarm_status().values()
])
add_devices(sensors)
class VerisureClimateDevice(Entity):
""" represents a Verisure climate sensor within home assistant. """
def __init__(self, climate_status):
self._id = climate_status.id
self._device = verisure.MY_PAGES.DEVICE_CLIMATE
@property
def name(self):
""" Returns the name of the device. """
return verisure.STATUS[self._device][self._id].location
@property
def state(self):
""" Returns the state of the device. """
# remove ° character
return verisure.STATUS[self._device][self._id].temperature[:-1]
@property
def unit_of_measurement(self):
""" Unit of measurement of this entity """
return TEMP_CELCIUS # can verisure report in fahrenheit?
def update(self):
verisure.update()
class VerisureAlarmDevice(Entity):
""" represents a Verisure alarm status within home assistant. """
def __init__(self, alarm_status):
self._id = alarm_status.id
self._device = verisure.MY_PAGES.DEVICE_ALARM
@property
def name(self):
""" Returns the name of the device. """
return 'Alarm {}'.format(self._id)
@property
def state(self):
""" Returns the state of the device. """
return verisure.STATUS[self._device][self._id].label
def update(self):
verisure.update()

View File

@ -11,7 +11,7 @@ from homeassistant.helpers.entity import ToggleEntity
from homeassistant.const import (
STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, ATTR_ENTITY_ID)
from homeassistant.components import group, discovery, wink, isy994
from homeassistant.components import group, discovery, wink, isy994, verisure
DOMAIN = 'switch'
DEPENDENCIES = []
@ -32,6 +32,7 @@ DISCOVERY_PLATFORMS = {
discovery.SERVICE_WEMO: 'wemo',
wink.DISCOVER_SWITCHES: 'wink',
isy994.DISCOVER_SWITCHES: 'isy994',
verisure.DISCOVER_SWITCHES: 'verisure'
}
PROP_TO_ATTR = {

View File

@ -0,0 +1,70 @@
"""
homeassistant.components.switch.verisure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Support for Verisure Smartplugs
Configuration:
switch:
platform: verisure
Variables:
"""
import logging
import homeassistant.components.verisure as verisure
from homeassistant.components.switch import SwitchDevice
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None):
""" Sets up the Arduino platform. """
if not verisure.MY_PAGES:
_LOGGER.error('A connection has not been made to Verisure mypages.')
return False
switches = []
switches.extend([
VerisureSmartplug(value)
for value in verisure.get_smartplug_status().values()
])
add_devices(switches)
class VerisureSmartplug(SwitchDevice):
""" Represents a Verisure smartplug. """
def __init__(self, smartplug_status):
self._id = smartplug_status.id
self.status_on = verisure.MY_PAGES.SMARTPLUG_ON
self.status_off = verisure.MY_PAGES.SMARTPLUG_OFF
@property
def name(self):
""" Get the name (location) of the smartplug. """
return verisure.get_smartplug_status()[self._id].location
@property
def is_on(self):
""" Returns True if on """
plug_status = verisure.get_smartplug_status()[self._id].status
return plug_status == self.status_on
def turn_on(self):
""" Set smartplug status on """
verisure.MY_PAGES.set_smartplug_status(
self._id,
self.status_on)
def turn_off(self):
""" Set smartplug status off """
verisure.MY_PAGES.set_smartplug_status(
self._id,
self.status_off)
def update(self):
verisure.update()

View File

@ -0,0 +1,128 @@
"""
components.verisure
~~~~~~~~~~~~~~~~~~
"""
import logging
from datetime import timedelta
from homeassistant import bootstrap
from homeassistant.loader import get_component
from homeassistant.helpers import validate_config
from homeassistant.util import Throttle
from homeassistant.const import (
EVENT_PLATFORM_DISCOVERED,
ATTR_SERVICE, ATTR_DISCOVERED,
CONF_USERNAME, CONF_PASSWORD)
DOMAIN = "verisure"
DISCOVER_SENSORS = 'verisure.sensors'
DISCOVER_SWITCHES = 'verisure.switches'
DEPENDENCIES = []
REQUIREMENTS = [
'https://github.com/persandstrom/python-verisure/archive/master.zip'
]
_LOGGER = logging.getLogger(__name__)
MY_PAGES = None
STATUS = {}
VERISURE_LOGIN_ERROR = None
VERISURE_ERROR = None
# if wrong password was given don't try again
WRONG_PASSWORD_GIVEN = False
MIN_TIME_BETWEEN_REQUESTS = timedelta(seconds=5)
def setup(hass, config):
""" Setup the Verisure component. """
if not validate_config(config,
{DOMAIN: [CONF_USERNAME, CONF_PASSWORD]},
_LOGGER):
return False
from verisure import MyPages, LoginError, Error
STATUS[MyPages.DEVICE_ALARM] = {}
STATUS[MyPages.DEVICE_CLIMATE] = {}
STATUS[MyPages.DEVICE_SMARTPLUG] = {}
global MY_PAGES
MY_PAGES = MyPages(
config[DOMAIN][CONF_USERNAME],
config[DOMAIN][CONF_PASSWORD])
global VERISURE_LOGIN_ERROR, VERISURE_ERROR
VERISURE_LOGIN_ERROR = LoginError
VERISURE_ERROR = Error
try:
MY_PAGES.login()
except (ConnectionError, Error) as ex:
_LOGGER.error('Could not log in to verisure mypages, %s', ex)
return False
update()
# Load components for the devices in the ISY controller that we support
for comp_name, discovery in ((('sensor', DISCOVER_SENSORS),
('switch', DISCOVER_SWITCHES))):
component = get_component(comp_name)
bootstrap.setup_component(hass, component.DOMAIN, config)
hass.bus.fire(EVENT_PLATFORM_DISCOVERED,
{ATTR_SERVICE: discovery,
ATTR_DISCOVERED: {}})
return True
def get_alarm_status():
''' return a list of status overviews for alarm components '''
return STATUS[MY_PAGES.DEVICE_ALARM]
def get_climate_status():
''' return a list of status overviews for alarm components '''
return STATUS[MY_PAGES.DEVICE_CLIMATE]
def get_smartplug_status():
''' return a list of status overviews for alarm components '''
return STATUS[MY_PAGES.DEVICE_SMARTPLUG]
def reconnect():
''' reconnect to verisure mypages '''
try:
MY_PAGES.login()
except VERISURE_LOGIN_ERROR as ex:
_LOGGER.error("Could not login to Verisure mypages, %s", ex)
global WRONG_PASSWORD_GIVEN
WRONG_PASSWORD_GIVEN = True
except (ConnectionError, VERISURE_ERROR) as ex:
_LOGGER.error("Could not login to Verisure mypages, %s", ex)
@Throttle(MIN_TIME_BETWEEN_REQUESTS)
def update():
''' Updates the status of verisure components '''
if WRONG_PASSWORD_GIVEN:
# Is there any way to inform user?
return
try:
for overview in MY_PAGES.get_overview(MY_PAGES.DEVICE_ALARM):
STATUS[MY_PAGES.DEVICE_ALARM][overview.id] = overview
for overview in MY_PAGES.get_overview(MY_PAGES.DEVICE_CLIMATE):
STATUS[MY_PAGES.DEVICE_CLIMATE][overview.id] = overview
for overview in MY_PAGES.get_overview(MY_PAGES.DEVICE_SMARTPLUG):
STATUS[MY_PAGES.DEVICE_SMARTPLUG][overview.id] = overview
except ConnectionError as ex:
_LOGGER.error('Caught connection error %s, tries to reconnect', ex)
reconnect()

View File

@ -110,3 +110,5 @@ paho-mqtt>=1.1
# PyModbus (modbus)
https://github.com/bashwork/pymodbus/archive/python3.zip#pymodbus>=1.2.0
# Verisure
https://github.com/persandstrom/python-verisure/archive/master.zip