Skip to content

Commit

Permalink
Code quality improvements based on core feedback (#385)
Browse files Browse the repository at this point in the history
  • Loading branch information
iMicknl authored Feb 19, 2021
1 parent 3c43f1f commit 744f920
Show file tree
Hide file tree
Showing 22 changed files with 80 additions and 79 deletions.
46 changes: 27 additions & 19 deletions custom_components/tahoma/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
DEFAULT_UPDATE_INTERVAL,
DOMAIN,
HUB_MANUFACTURER,
IGNORED_TAHOMA_TYPES,
IGNORED_TAHOMA_DEVICES,
SUPPORTED_ENDPOINTS,
TAHOMA_TYPES,
TAHOMA_DEVICE_TO_PLATFORM,
)
from .coordinator import TahomaDataUpdateCoordinator

Expand Down Expand Up @@ -95,7 +95,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):

username = entry.data.get(CONF_USERNAME)
password = entry.data.get(CONF_PASSWORD)
hub = entry.data.get(CONF_HUB) or DEFAULT_HUB
hub = entry.data.get(CONF_HUB, DEFAULT_HUB)
endpoint = SUPPORTED_ENDPOINTS[hub]

session = async_get_clientsession(hass)
Expand All @@ -112,47 +112,55 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
scenarios = await client.get_scenarios()
gateways = await client.get_gateways()
except BadCredentialsException:
_LOGGER.error("invalid_auth")
_LOGGER.error("Invalid authentication.")
return False
except TooManyRequestsException as exception:
_LOGGER.error("too_many_requests")
_LOGGER.error("Too many requests, try again later.")
raise ConfigEntryNotReady from exception
except (TimeoutError, ClientError, ServerDisconnectedError) as exception:
_LOGGER.error("cannot_connect")
_LOGGER.error("Failed to connect.")
raise ConfigEntryNotReady from exception
except MaintenanceException as exception:
_LOGGER.error("server_in_maintenance")
_LOGGER.error("Server is down for maintenance.")
raise ConfigEntryNotReady from exception
except Exception as exception: # pylint: disable=broad-except
_LOGGER.exception(exception)
return False

update_interval = entry.options.get(CONF_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL)
update_interval = timedelta(
seconds=entry.options.get(CONF_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL)
)

tahoma_coordinator = TahomaDataUpdateCoordinator(
hass,
_LOGGER,
name="events",
name="device events",
client=client,
devices=devices,
update_interval=timedelta(seconds=update_interval),
update_interval=update_interval,
)

_LOGGER.debug(
"Initialized DataUpdateCoordinator with %s interval.", str(update_interval)
)

await tahoma_coordinator.async_refresh()

entities = defaultdict(list)
entities[SCENE] = scenarios
platforms = defaultdict(list)
platforms[SCENE] = scenarios

hass.data[DOMAIN][entry.entry_id] = {
"entities": entities,
"platforms": platforms,
"coordinator": tahoma_coordinator,
"update_listener": entry.add_update_listener(update_listener),
}

for device in tahoma_coordinator.data.values():
platform = TAHOMA_TYPES.get(device.widget) or TAHOMA_TYPES.get(device.ui_class)
platform = TAHOMA_DEVICE_TO_PLATFORM.get(
device.widget
) or TAHOMA_DEVICE_TO_PLATFORM.get(device.ui_class)
if platform:
entities[platform].append(device)
platforms[platform].append(device)
_LOGGER.debug(
"Added device (%s - %s - %s - %s)",
device.controllable_name,
Expand All @@ -161,8 +169,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
device.deviceurl,
)
elif (
device.widget not in IGNORED_TAHOMA_TYPES
and device.ui_class not in IGNORED_TAHOMA_TYPES
device.widget not in IGNORED_TAHOMA_DEVICES
and device.ui_class not in IGNORED_TAHOMA_DEVICES
):
_LOGGER.debug(
"Unsupported device detected (%s - %s - %s - %s)",
Expand All @@ -175,7 +183,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
if device.widget == HOMEKIT_STACK:
print_homekit_setup_code(device)

for platform in entities:
for platform in platforms:
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, platform)
)
Expand Down Expand Up @@ -253,7 +261,7 @@ async def handle_get_execution_history(call):

async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
"""Unload a config entry."""
entities_per_platform = hass.data[DOMAIN][entry.entry_id]["entities"]
entities_per_platform = hass.data[DOMAIN][entry.entry_id]["platforms"]

unload_ok = all(
await asyncio.gather(
Expand Down
6 changes: 3 additions & 3 deletions custom_components/tahoma/alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
)

from .const import DOMAIN
from .tahoma_device import TahomaDevice
from .tahoma_entity import TahomaEntity

COMMAND_ALARM_OFF = "alarmOff"
COMMAND_ALARM_ON = "alarmOn"
Expand Down Expand Up @@ -81,12 +81,12 @@ async def async_setup_entry(hass, entry, async_add_entities):

entities = [
TahomaAlarmControlPanel(device.deviceurl, coordinator)
for device in data["entities"].get(ALARM_CONTROL_PANEL)
for device in data["platforms"].get(ALARM_CONTROL_PANEL)
]
async_add_entities(entities)


class TahomaAlarmControlPanel(TahomaDevice, AlarmControlPanelEntity):
class TahomaAlarmControlPanel(TahomaEntity, AlarmControlPanelEntity):
"""Representation of a TaHoma Alarm Control Panel."""

@property
Expand Down
6 changes: 3 additions & 3 deletions custom_components/tahoma/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
)

from .const import DOMAIN
from .tahoma_device import TahomaDevice
from .tahoma_entity import TahomaEntity

CORE_ASSEMBLY_STATE = "core:AssemblyState"
CORE_BUTTON_STATE = "core:ButtonState"
Expand Down Expand Up @@ -65,12 +65,12 @@ async def async_setup_entry(hass, entry, async_add_entities):

entities = [
TahomaBinarySensor(device.deviceurl, coordinator)
for device in data["entities"].get(BINARY_SENSOR)
for device in data["platforms"].get(BINARY_SENSOR)
]
async_add_entities(entities)


class TahomaBinarySensor(TahomaDevice, BinarySensorEntity):
class TahomaBinarySensor(TahomaEntity, BinarySensorEntity):
"""Representation of a TaHoma Binary Sensor."""

@property
Expand Down
2 changes: 1 addition & 1 deletion custom_components/tahoma/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ async def async_setup_entry(hass, entry, async_add_entities):
data = hass.data[DOMAIN][entry.entry_id]
coordinator = data["coordinator"]

climate_devices = [device for device in data["entities"].get(CLIMATE)]
climate_devices = [device for device in data["platforms"].get(CLIMATE)]

entities = [
TYPE[device.widget](device.deviceurl, coordinator)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
)
from homeassistant.const import TEMP_CELSIUS

from ..tahoma_device import TahomaDevice
from ..tahoma_device import TahomaEntity

COMMAND_SET_HEATING_LEVEL = "setHeatingLevel"

Expand All @@ -36,7 +36,7 @@
MAP_HVAC_MODES = {HVAC_MODE_HEAT: PRESET_COMFORT, HVAC_MODE_OFF: PRESET_OFF}


class AtlanticElectricalHeater(TahomaDevice, ClimateEntity):
class AtlanticElectricalHeater(TahomaEntity, ClimateEntity):
"""Representation of TaHoma IO Atlantic Electrical Heater."""

@property
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
)
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS

from ..tahoma_device import TahomaDevice
from ..tahoma_device import TahomaEntity

BOOST_ON_STATE = "on"
BOOST_OFF_STATE = "off"
Expand Down Expand Up @@ -70,7 +70,7 @@
MAP_REVERSE_PRESET_MODES = {v: k for k, v in MAP_PRESET_MODES.items()}


class AtlanticPassAPCDHW(TahomaDevice, ClimateEntity):
class AtlanticPassAPCDHW(TahomaEntity, ClimateEntity):
"""Representation of TaHoma IO Atlantic Electrical Heater."""

@property
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS

from ..coordinator import TahomaDataUpdateCoordinator
from ..tahoma_device import TahomaDevice
from ..tahoma_device import TahomaEntity

_LOGGER = logging.getLogger(__name__)

Expand All @@ -21,7 +21,7 @@
CORE_LEVEL_STATE = "core:LevelState"


class DimmerExteriorHeating(TahomaDevice, ClimateEntity):
class DimmerExteriorHeating(TahomaEntity, ClimateEntity):
"""Representation of TaHoma IO Atlantic Electrical Heater."""

def __init__(self, device_url: str, coordinator: TahomaDataUpdateCoordinator):
Expand Down
4 changes: 2 additions & 2 deletions custom_components/tahoma/climate_devices/somfy_thermostat.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from homeassistant.helpers.event import async_track_state_change

from ..coordinator import TahomaDataUpdateCoordinator
from ..tahoma_device import TahomaDevice
from ..tahoma_device import TahomaEntity

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -73,7 +73,7 @@
}


class SomfyThermostat(TahomaDevice, ClimateEntity):
class SomfyThermostat(TahomaEntity, ClimateEntity):
"""Representation of Somfy Smart Thermostat."""

def __init__(self, device_url: str, coordinator: TahomaDataUpdateCoordinator):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
)
from homeassistant.const import TEMP_CELSIUS

from ..tahoma_device import TahomaDevice
from ..tahoma_device import TahomaEntity

_LOGGER = logging.getLogger(__name__)

Expand All @@ -21,7 +21,7 @@
PRESET_MY = "My"


class StatelessExteriorHeating(TahomaDevice, ClimateEntity):
class StatelessExteriorHeating(TahomaEntity, ClimateEntity):
"""Representation of TaHoma Stateless Exterior Heating device."""

@property
Expand Down
17 changes: 7 additions & 10 deletions custom_components/tahoma/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@


class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for TaHoma."""
"""Handle a config flow for Somfy TaHoma."""

VERSION = 1
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL
Expand All @@ -52,7 +52,7 @@ async def async_validate_input(self, user_input):
username = user_input.get(CONF_USERNAME)
password = user_input.get(CONF_PASSWORD)

hub = user_input.get(CONF_HUB) or DEFAULT_HUB
hub = user_input.get(CONF_HUB, DEFAULT_HUB)
endpoint = SUPPORTED_ENDPOINTS[hub]

async with TahomaClient(username, password, api_url=endpoint) as client:
Expand Down Expand Up @@ -113,15 +113,11 @@ async def async_step_import(self, import_config: dict):


class OptionsFlowHandler(config_entries.OptionsFlow):
"""Handle a option flow for TaHoma."""
"""Handle a option flow for Somfy TaHoma."""

def __init__(self, config_entry):
"""Initialize options flow."""
self.config_entry = config_entry
self.options = dict(config_entry.options)

if self.options.get(CONF_UPDATE_INTERVAL) is None:
self.options[CONF_UPDATE_INTERVAL] = DEFAULT_UPDATE_INTERVAL

async def async_step_init(self, user_input=None):
"""Manage the Somfy TaHoma options."""
Expand All @@ -130,16 +126,17 @@ async def async_step_init(self, user_input=None):
async def async_step_update_interval(self, user_input=None):
"""Manage the options regarding interval updates."""
if user_input is not None:
self.options[CONF_UPDATE_INTERVAL] = user_input[CONF_UPDATE_INTERVAL]
return self.async_create_entry(title="", data=self.options)
return self.async_create_entry(title="", data=user_input)

return self.async_show_form(
step_id="update_interval",
data_schema=vol.Schema(
{
vol.Required(
CONF_UPDATE_INTERVAL,
default=self.options.get(CONF_UPDATE_INTERVAL),
default=self.config_entry.options.get(
CONF_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL
),
): vol.All(cv.positive_int, vol.Clamp(min=MIN_UPDATE_INTERVAL))
}
),
Expand Down
4 changes: 2 additions & 2 deletions custom_components/tahoma/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@
MIN_UPDATE_INTERVAL = 30
DEFAULT_UPDATE_INTERVAL = 30

IGNORED_TAHOMA_TYPES = [
IGNORED_TAHOMA_DEVICES = [
"ProtocolGateway",
"Pod",
]

# Used to map the Somfy widget and ui_class to the Home Assistant platform
TAHOMA_TYPES = {
TAHOMA_DEVICE_TO_PLATFORM = {
"AdjustableSlatsRollerShutter": COVER,
"AirFlowSensor": BINARY_SENSOR, # widgetName, uiClass is AirSensor (sensor)
"AirSensor": SENSOR,
Expand Down
15 changes: 5 additions & 10 deletions custom_components/tahoma/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,24 +59,19 @@ def __init__(
self.devices: Dict[str, Device] = {d.deviceurl: d for d in devices}
self.executions: Dict[str, Dict[str, str]] = {}

_LOGGER.debug(
"Initialized DataUpdateCoordinator with %s interval.", str(update_interval)
)

async def _async_update_data(self) -> Dict[str, Device]:
"""Fetch TaHoma data via event listener."""
try:
events = await self.client.fetch_events()
except BadCredentialsException as exception:
raise UpdateFailed("invalid_auth") from exception
raise UpdateFailed("Invalid authentication.") from exception
except TooManyRequestsException as exception:
raise UpdateFailed("too_many_requests") from exception
raise UpdateFailed("Too many requests, try again later.") from exception
except MaintenanceException as exception:
raise UpdateFailed("server_in_maintenance") from exception
raise UpdateFailed("Server is down for maintenance.") from exception
except TimeoutError as exception:
raise UpdateFailed("cannot_connect") from exception
except (ServerDisconnectedError, NotAuthenticatedException) as exception:
_LOGGER.debug(exception)
raise UpdateFailed("Failed to connect.") from exception
except (ServerDisconnectedError, NotAuthenticatedException):
self.executions = {}
await self.client.login()
self.devices = await self._get_devices()
Expand Down
6 changes: 3 additions & 3 deletions custom_components/tahoma/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import voluptuous as vol

from .const import DOMAIN
from .tahoma_device import TahomaDevice
from .tahoma_entity import TahomaEntity

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -116,7 +116,7 @@ async def async_setup_entry(hass, entry, async_add_entities):

entities = [
TahomaCover(device.deviceurl, coordinator)
for device in data["entities"].get(COVER)
for device in data["platforms"].get(COVER)
]

async_add_entities(entities)
Expand All @@ -138,7 +138,7 @@ async def async_setup_entry(hass, entry, async_add_entities):
)


class TahomaCover(TahomaDevice, CoverEntity):
class TahomaCover(TahomaEntity, CoverEntity):
"""Representation of a TaHoma Cover."""

@property
Expand Down
Loading

0 comments on commit 744f920

Please sign in to comment.