mirror of
https://github.com/home-assistant/core.git
synced 2025-06-25 01:21:51 +02:00
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:
committed by
Martin Hjelmare
parent
43487aa0d6
commit
6ee23bdf4e
@ -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/*
|
||||
|
63
homeassistant/components/somfy_mylink/__init__.py
Executable file
63
homeassistant/components/somfy_mylink/__init__.py
Executable 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
|
85
homeassistant/components/somfy_mylink/cover.py
Executable file
85
homeassistant/components/somfy_mylink/cover.py
Executable 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)
|
10
homeassistant/components/somfy_mylink/manifest.json
Normal file
10
homeassistant/components/somfy_mylink/manifest.json
Normal 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": []
|
||||
}
|
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user