Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,7 @@ omit =
homeassistant/components/overkiz/coordinator.py
homeassistant/components/overkiz/entity.py
homeassistant/components/overkiz/executor.py
homeassistant/components/overkiz/lock.py
homeassistant/components/overkiz/sensor.py
homeassistant/components/ovo_energy/__init__.py
homeassistant/components/ovo_energy/const.py
Expand Down
14 changes: 14 additions & 0 deletions homeassistant/components/overkiz/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
"""The Overkiz (by Somfy) integration."""
from __future__ import annotations

from collections import defaultdict
from dataclasses import dataclass
import logging

Expand All @@ -10,6 +13,7 @@
MaintenanceException,
TooManyRequestsException,
)
from pyoverkiz.models import Device

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
Expand All @@ -21,6 +25,7 @@
from .const import (
CONF_HUB,
DOMAIN,
OVERKIZ_DEVICE_TO_PLATFORM,
PLATFORMS,
UPDATE_INTERVAL,
UPDATE_INTERVAL_ALL_ASSUMED_STATE,
Expand All @@ -35,6 +40,7 @@ class HomeAssistantOverkizData:
"""Overkiz data stored in the Home Assistant data object."""

coordinator: OverkizDataUpdateCoordinator
platforms: dict[str, Device]


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
Expand Down Expand Up @@ -85,8 +91,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
)
coordinator.update_interval = UPDATE_INTERVAL_ALL_ASSUMED_STATE

platforms: dict[str, Device] = defaultdict(list)

hass.data.setdefault(DOMAIN, {})[entry.entry_id] = HomeAssistantOverkizData(
coordinator=coordinator,
platforms=platforms,
)

# Map Overkiz device to Home Assistant platform
Expand All @@ -96,6 +105,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
device,
)

if platform := OVERKIZ_DEVICE_TO_PLATFORM.get(
device.widget
) or OVERKIZ_DEVICE_TO_PLATFORM.get(device.ui_class):
Comment thread
bdraco marked this conversation as resolved.
platforms[platform].append(device)

hass.config_entries.async_setup_platforms(entry, PLATFORMS)

device_registry = await dr.async_get_registry(hass)
Expand Down
6 changes: 6 additions & 0 deletions homeassistant/components/overkiz/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,16 @@
UPDATE_INTERVAL_ALL_ASSUMED_STATE: Final = timedelta(minutes=60)

PLATFORMS: list[Platform] = [
Platform.LOCK,
Platform.SENSOR,
]

IGNORED_OVERKIZ_DEVICES: list[UIClass | UIWidget] = [
UIClass.PROTOCOL_GATEWAY,
UIClass.POD,
]

# Used to map the Somfy widget and ui_class to the Home Assistant platform
OVERKIZ_DEVICE_TO_PLATFORM: dict[UIClass | UIWidget, Platform] = {
UIClass.DOOR_LOCK: Platform.LOCK,
}
52 changes: 52 additions & 0 deletions homeassistant/components/overkiz/lock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Support for Overkiz locks."""
from __future__ import annotations

from typing import Any

from pyoverkiz.enums import OverkizCommand, OverkizCommandParam, OverkizState

from homeassistant.components.lock import LockEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from . import HomeAssistantOverkizData
from .const import DOMAIN
from .entity import OverkizEntity


async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing return value typing.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iMicknl

diff --git a/.strict-typing b/.strict-typing
index 8f7ca3311c..fa2addb86b 100644
--- a/.strict-typing
+++ b/.strict-typing
@@ -101,6 +101,7 @@ homeassistant.components.number.*
 homeassistant.components.onewire.*
 homeassistant.components.open_meteo.*
 homeassistant.components.openuv.*
+homeassistant.components.overkiz.*
 homeassistant.components.persistent_notification.*
 homeassistant.components.pi_hole.*
 homeassistant.components.proximity.*

and run python3 -m script.hassfest, you will get some additional feedback from mypy

"""Set up the Overkiz locks from a config entry."""
data: HomeAssistantOverkizData = hass.data[DOMAIN][entry.entry_id]

entities: list[OverkizLock] = [
OverkizLock(device.device_url, data.coordinator)
for device in data.platforms[Platform.LOCK]
]

async_add_entities(entities)


class OverkizLock(OverkizEntity, LockEntity):
"""Representation of an Overkiz Lock."""

async def async_lock(self, **_: Any) -> None:
"""Lock method."""
await self.executor.async_execute_command(OverkizCommand.LOCK)

async def async_unlock(self, **_: Any) -> None:
"""Unlock method."""
await self.executor.async_execute_command(OverkizCommand.UNLOCK)

@property
def is_locked(self) -> bool | None:
"""Return a boolean for the state of the lock."""
return (
self.executor.select_state(OverkizState.CORE_LOCKED_UNLOCKED)
== OverkizCommandParam.LOCKED
)
2 changes: 1 addition & 1 deletion homeassistant/components/overkiz/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

from pyoverkiz.enums import OverkizAttribute, OverkizState, UIWidget

from homeassistant.components.overkiz import HomeAssistantOverkizData
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
Expand All @@ -26,6 +25,7 @@
from homeassistant.helpers.entity import DeviceInfo, EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from . import HomeAssistantOverkizData
from .const import DOMAIN, IGNORED_OVERKIZ_DEVICES
from .coordinator import OverkizDataUpdateCoordinator
from .entity import OverkizDescriptiveEntity, OverkizEntity, OverkizSensorDescription
Expand Down
8 changes: 6 additions & 2 deletions homeassistant/components/overkiz/translations/en.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
{
"config": {
"abort": {
"already_configured": "Device is already configured"
"already_configured": "Account is already configured"
Comment thread
epenet marked this conversation as resolved.
},
"error": {
"cannot_connect": "Failed to connect",
"invalid_auth": "Invalid authentication",
"server_in_maintenance": "Server is down for maintenance",
"too_many_requests": "Too many requests, try again later.",
"unknown": "Unexpected error"
},
"step": {
"user": {
"data": {
"host": "Host",
"hub": "Hub",
"password": "Password",
"username": "Username"
}
},
"description": "The Overkiz platform is used by various vendors like Somfy (Connexoon / TaHoma), Hitachi (Hi Kumo), Rexel (Energeasy Connect) and Atlantic (Cozytouch). Enter your application credentials and select your hub."
}
}
}
Expand Down