mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 14:17:45 +00:00
Merge pull request #257 from persandstrom/verisure
Support for Verisure
This commit is contained in:
commit
6e41eee6cd
@ -6,7 +6,7 @@ Component to interface with various sensors that can be monitored.
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from homeassistant.helpers.entity_component import EntityComponent
|
from homeassistant.helpers.entity_component import EntityComponent
|
||||||
from homeassistant.components import wink, zwave, isy994
|
from homeassistant.components import wink, zwave, isy994, verisure
|
||||||
|
|
||||||
DOMAIN = 'sensor'
|
DOMAIN = 'sensor'
|
||||||
DEPENDENCIES = []
|
DEPENDENCIES = []
|
||||||
@ -18,7 +18,8 @@ ENTITY_ID_FORMAT = DOMAIN + '.{}'
|
|||||||
DISCOVERY_PLATFORMS = {
|
DISCOVERY_PLATFORMS = {
|
||||||
wink.DISCOVER_SENSORS: 'wink',
|
wink.DISCOVER_SENSORS: 'wink',
|
||||||
zwave.DISCOVER_SENSORS: 'zwave',
|
zwave.DISCOVER_SENSORS: 'zwave',
|
||||||
isy994.DISCOVER_SENSORS: 'isy994'
|
isy994.DISCOVER_SENSORS: 'isy994',
|
||||||
|
verisure.DISCOVER_SENSORS: 'verisure'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
83
homeassistant/components/sensor/verisure.py
Normal file
83
homeassistant/components/sensor/verisure.py
Normal 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()
|
@ -11,7 +11,7 @@ from homeassistant.helpers.entity import ToggleEntity
|
|||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, ATTR_ENTITY_ID)
|
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'
|
DOMAIN = 'switch'
|
||||||
DEPENDENCIES = []
|
DEPENDENCIES = []
|
||||||
@ -32,6 +32,7 @@ DISCOVERY_PLATFORMS = {
|
|||||||
discovery.SERVICE_WEMO: 'wemo',
|
discovery.SERVICE_WEMO: 'wemo',
|
||||||
wink.DISCOVER_SWITCHES: 'wink',
|
wink.DISCOVER_SWITCHES: 'wink',
|
||||||
isy994.DISCOVER_SWITCHES: 'isy994',
|
isy994.DISCOVER_SWITCHES: 'isy994',
|
||||||
|
verisure.DISCOVER_SWITCHES: 'verisure'
|
||||||
}
|
}
|
||||||
|
|
||||||
PROP_TO_ATTR = {
|
PROP_TO_ATTR = {
|
||||||
|
70
homeassistant/components/switch/verisure.py
Normal file
70
homeassistant/components/switch/verisure.py
Normal 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()
|
128
homeassistant/components/verisure.py
Normal file
128
homeassistant/components/verisure.py
Normal 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()
|
@ -110,3 +110,5 @@ paho-mqtt>=1.1
|
|||||||
# PyModbus (modbus)
|
# PyModbus (modbus)
|
||||||
https://github.com/bashwork/pymodbus/archive/python3.zip#pymodbus>=1.2.0
|
https://github.com/bashwork/pymodbus/archive/python3.zip#pymodbus>=1.2.0
|
||||||
|
|
||||||
|
# Verisure
|
||||||
|
https://github.com/persandstrom/python-verisure/archive/master.zip
|
||||||
|
Loading…
x
Reference in New Issue
Block a user