Add Somfy MyLink support for Covers (#22514)

* Added MyLink component

* Updated requirements.txt

* Fix lint issues

* Removed ‘Scene’ functionality

* Removed state restoration, as state is no longer tracked

* Add component manifest

* Remove documentation links in Docstring

* Removed redundant try/except block

* Removed default dict

* Removed features already implemented in default CoverDevice

* Removed attributes for tracking state

* Simplified loading of covers

No options exist other than reversal, so just check reversal status directly and update if needed

* Reimplemented is_closed property

* Import ENTITY_ID_FORMAT from base component

* Removed misc unused vars

* Update module docstrings to one line

* Removed too many blank lines, giving one back :)

* Return none on TimeoutError

* Added component to .coveragerc
This commit is contained in:
Ben Dews
2019-04-09 16:31:34 +10:00
committed by Martin Hjelmare
parent 43487aa0d6
commit 6ee23bdf4e
5 changed files with 162 additions and 0 deletions

View File

@ -539,6 +539,7 @@ omit =
homeassistant/components/sochain/sensor.py
homeassistant/components/socialblade/sensor.py
homeassistant/components/solaredge/sensor.py
homeassistant/components/somfy_mylink/*
homeassistant/components/sonarr/sensor.py
homeassistant/components/songpal/media_player.py
homeassistant/components/sonos/*

View File

@ -0,0 +1,63 @@
"""Component for the Somfy MyLink device supporting the Synergy API."""
import logging
import voluptuous as vol
from homeassistant.const import CONF_HOST, CONF_PORT
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.discovery import async_load_platform
_LOGGER = logging.getLogger(__name__)
REQUIREMENTS = ['somfy-mylink-synergy==1.0.4']
CONF_ENTITY_CONFIG = 'entity_config'
CONF_SYSTEM_ID = 'system_id'
CONF_REVERSE = 'reverse'
CONF_DEFAULT_REVERSE = 'default_reverse'
DATA_SOMFY_MYLINK = 'somfy_mylink_data'
DOMAIN = 'somfy_mylink'
SOMFY_MYLINK_COMPONENTS = [
'cover'
]
def validate_entity_config(values):
"""Validate config entry for CONF_ENTITY."""
entity_config_schema = vol.Schema({
vol.Optional(CONF_REVERSE): cv.boolean
})
if not isinstance(values, dict):
raise vol.Invalid('expected a dictionary')
entities = {}
for entity_id, config in values.items():
entity = cv.entity_id(entity_id)
config = entity_config_schema(config)
entities[entity] = config
return entities
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_SYSTEM_ID): cv.string,
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_PORT, default=44100): cv.port,
vol.Optional(CONF_DEFAULT_REVERSE, default=False): cv.boolean,
vol.Optional(CONF_ENTITY_CONFIG, default={}): validate_entity_config
})
}, extra=vol.ALLOW_EXTRA)
async def async_setup(hass, config):
"""Set up the MyLink platform."""
from somfy_mylink_synergy import SomfyMyLinkSynergy
host = config[DOMAIN][CONF_HOST]
port = config[DOMAIN][CONF_PORT]
system_id = config[DOMAIN][CONF_SYSTEM_ID]
entity_config = config[DOMAIN][CONF_ENTITY_CONFIG]
entity_config[CONF_DEFAULT_REVERSE] = config[DOMAIN][CONF_DEFAULT_REVERSE]
somfy_mylink = SomfyMyLinkSynergy(system_id, host, port)
hass.data[DATA_SOMFY_MYLINK] = somfy_mylink
for component in SOMFY_MYLINK_COMPONENTS:
hass.async_create_task(async_load_platform(
hass, component, DOMAIN, entity_config,
config))
return True

View File

@ -0,0 +1,85 @@
"""Cover Platform for the Somfy MyLink component."""
import logging
from homeassistant.components.cover import ENTITY_ID_FORMAT, CoverDevice
from homeassistant.util import slugify
from . import CONF_DEFAULT_REVERSE, DATA_SOMFY_MYLINK
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['somfy_mylink']
async def async_setup_platform(hass,
config,
async_add_entities,
discovery_info=None):
"""Discover and configure Somfy covers."""
if discovery_info is None:
return
somfy_mylink = hass.data[DATA_SOMFY_MYLINK]
cover_list = []
try:
mylink_status = await somfy_mylink.status_info()
except TimeoutError:
_LOGGER.error("Unable to connect to the Somfy MyLink device, "
"please check your settings")
return
for cover in mylink_status['result']:
entity_id = ENTITY_ID_FORMAT.format(slugify(cover['name']))
entity_config = discovery_info.get(entity_id, {})
default_reverse = discovery_info[CONF_DEFAULT_REVERSE]
cover_config = {}
cover_config['target_id'] = cover['targetID']
cover_config['name'] = cover['name']
cover_config['reverse'] = entity_config.get('reverse', default_reverse)
cover_list.append(SomfyShade(somfy_mylink, **cover_config))
_LOGGER.info('Adding Somfy Cover: %s with targetID %s',
cover_config['name'], cover_config['target_id'])
async_add_entities(cover_list)
class SomfyShade(CoverDevice):
"""Object for controlling a Somfy cover."""
def __init__(self, somfy_mylink, target_id='AABBCC', name='SomfyShade',
reverse=False, device_class='window'):
"""Initialize the cover."""
self.somfy_mylink = somfy_mylink
self._target_id = target_id
self._name = name
self._reverse = reverse
self._device_class = device_class
@property
def name(self):
"""Return the name of the cover."""
return self._name
@property
def is_closed(self):
"""Return if the cover is closed."""
pass
@property
def device_class(self):
"""Return the class of this device, from component DEVICE_CLASSES."""
return self._device_class
async def async_open_cover(self, **kwargs):
"""Wrap Homeassistant calls to open the cover."""
if not self._reverse:
await self.somfy_mylink.move_up(self._target_id)
else:
await self.somfy_mylink.move_down(self._target_id)
async def async_close_cover(self, **kwargs):
"""Wrap Homeassistant calls to close the cover."""
if not self._reverse:
await self.somfy_mylink.move_down(self._target_id)
else:
await self.somfy_mylink.move_up(self._target_id)
async def async_stop_cover(self, **kwargs):
"""Stop the cover."""
await self.somfy_mylink.move_stop(self._target_id)

View File

@ -0,0 +1,10 @@
{
"domain": "somfy_mylink",
"name": "Somfy MyLink",
"documentation": "https://www.home-assistant.io/components/somfy_mylink",
"requirements": [
"somfy-mylink-synergy==1.0.4"
],
"dependencies": [],
"codeowners": []
}

View File

@ -1598,6 +1598,9 @@ solaredge==0.0.2
# homeassistant.components.honeywell
somecomfort==0.5.2
# homeassistant.components.somfy_mylink
somfy-mylink-synergy==1.0.4
# homeassistant.components.speedtestdotnet
speedtest-cli==2.1.1