diff --git a/homeassistant/components/comelit/__init__.py b/homeassistant/components/comelit/__init__.py index 4a105072802..28d87f5b284 100644 --- a/homeassistant/components/comelit/__init__.py +++ b/homeassistant/components/comelit/__init__.py @@ -1,10 +1,11 @@ """Comelit integration.""" + from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_HOST, CONF_PIN, Platform +from homeassistant.const import CONF_HOST, CONF_PIN, CONF_PORT, Platform from homeassistant.core import HomeAssistant -from .const import DOMAIN +from .const import DEFAULT_PORT, DOMAIN from .coordinator import ComelitSerialBridge PLATFORMS = [Platform.COVER, Platform.LIGHT] @@ -12,7 +13,12 @@ PLATFORMS = [Platform.COVER, Platform.LIGHT] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Comelit platform.""" - coordinator = ComelitSerialBridge(hass, entry.data[CONF_HOST], entry.data[CONF_PIN]) + coordinator = ComelitSerialBridge( + hass, + entry.data[CONF_HOST], + entry.data.get(CONF_PORT, DEFAULT_PORT), + entry.data[CONF_PIN], + ) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/comelit/config_flow.py b/homeassistant/components/comelit/config_flow.py index b0c8e5aabe5..66ab9ae88b3 100644 --- a/homeassistant/components/comelit/config_flow.py +++ b/homeassistant/components/comelit/config_flow.py @@ -9,10 +9,11 @@ import voluptuous as vol from homeassistant import core, exceptions from homeassistant.config_entries import ConfigEntry, ConfigFlow -from homeassistant.const import CONF_HOST, CONF_PIN +from homeassistant.const import CONF_HOST, CONF_PIN, CONF_PORT from homeassistant.data_entry_flow import FlowResult +import homeassistant.helpers.config_validation as cv -from .const import _LOGGER, DOMAIN +from .const import _LOGGER, DEFAULT_PORT, DOMAIN DEFAULT_HOST = "192.168.1.252" DEFAULT_PIN = "111111" @@ -23,8 +24,9 @@ def user_form_schema(user_input: dict[str, Any] | None) -> vol.Schema: user_input = user_input or {} return vol.Schema( { - vol.Optional(CONF_HOST, default=DEFAULT_HOST): str, - vol.Optional(CONF_PIN, default=DEFAULT_PIN): str, + vol.Required(CONF_HOST, default=DEFAULT_HOST): cv.string, + vol.Required(CONF_PORT, default=DEFAULT_PORT): cv.port, + vol.Optional(CONF_PIN, default=DEFAULT_PIN): cv.positive_int, } ) @@ -37,7 +39,7 @@ async def validate_input( ) -> dict[str, str]: """Validate the user input allows us to connect.""" - api = ComeliteSerialBridgeApi(data[CONF_HOST], data[CONF_PIN]) + api = ComeliteSerialBridgeApi(data[CONF_HOST], data[CONF_PORT], data[CONF_PIN]) try: await api.login() @@ -58,6 +60,7 @@ class ComelitConfigFlow(ConfigFlow, domain=DOMAIN): VERSION = 1 _reauth_entry: ConfigEntry | None _reauth_host: str + _reauth_port: int async def async_step_user( self, user_input: dict[str, Any] | None = None @@ -94,6 +97,8 @@ class ComelitConfigFlow(ConfigFlow, domain=DOMAIN): self.context["entry_id"] ) self._reauth_host = entry_data[CONF_HOST] + self._reauth_port = entry_data.get(CONF_PORT, DEFAULT_PORT) + self.context["title_placeholders"] = {"host": self._reauth_host} return await self.async_step_reauth_confirm() @@ -107,7 +112,12 @@ class ComelitConfigFlow(ConfigFlow, domain=DOMAIN): if user_input is not None: try: await validate_input( - self.hass, {CONF_HOST: self._reauth_host} | user_input + self.hass, + { + CONF_HOST: self._reauth_host, + CONF_PORT: self._reauth_port, + } + | user_input, ) except CannotConnect: errors["base"] = "cannot_connect" @@ -121,6 +131,7 @@ class ComelitConfigFlow(ConfigFlow, domain=DOMAIN): self._reauth_entry, data={ CONF_HOST: self._reauth_host, + CONF_PORT: self._reauth_port, CONF_PIN: user_input[CONF_PIN], }, ) diff --git a/homeassistant/components/comelit/const.py b/homeassistant/components/comelit/const.py index e08caa55f76..7bd49440eb3 100644 --- a/homeassistant/components/comelit/const.py +++ b/homeassistant/components/comelit/const.py @@ -4,3 +4,8 @@ import logging _LOGGER = logging.getLogger(__package__) DOMAIN = "comelit" +DEFAULT_PORT = 80 + +# Entity states +STATE_OFF = 0 +STATE_ON = 1 diff --git a/homeassistant/components/comelit/coordinator.py b/homeassistant/components/comelit/coordinator.py index a9c281c10c0..02a8d805d19 100644 --- a/homeassistant/components/comelit/coordinator.py +++ b/homeassistant/components/comelit/coordinator.py @@ -21,13 +21,14 @@ class ComelitSerialBridge(DataUpdateCoordinator): config_entry: ConfigEntry - def __init__(self, hass: HomeAssistant, host: str, pin: int) -> None: + def __init__(self, hass: HomeAssistant, host: str, port: int, pin: int) -> None: """Initialize the scanner.""" self._host = host + self._port = port self._pin = pin - self.api = ComeliteSerialBridgeApi(host, pin) + self.api = ComeliteSerialBridgeApi(host, port, pin) super().__init__( hass=hass, @@ -53,18 +54,16 @@ class ComelitSerialBridge(DataUpdateCoordinator): "hw_version": "20003101", } - def platform_device_info( - self, device: ComelitSerialBridgeObject, platform: str - ) -> dr.DeviceInfo: + def platform_device_info(self, device: ComelitSerialBridgeObject) -> dr.DeviceInfo: """Set platform device info.""" return dr.DeviceInfo( identifiers={ - (DOMAIN, f"{self.config_entry.entry_id}-{platform}-{device.index}") + (DOMAIN, f"{self.config_entry.entry_id}-{device.type}-{device.index}") }, via_device=(DOMAIN, self.config_entry.entry_id), name=device.name, - model=f"{BRIDGE} {platform}", + model=f"{BRIDGE} {device.type}", **self.basic_device_info, ) diff --git a/homeassistant/components/comelit/cover.py b/homeassistant/components/comelit/cover.py index 48478f075d3..08e1136ca9e 100644 --- a/homeassistant/components/comelit/cover.py +++ b/homeassistant/components/comelit/cover.py @@ -53,7 +53,7 @@ class ComelitCoverEntity( self._device = device super().__init__(coordinator) self._attr_unique_id = f"{config_entry_entry_id}-{device.index}" - self._attr_device_info = coordinator.platform_device_info(device, COVER) + self._attr_device_info = coordinator.platform_device_info(device) # Device doesn't provide a status so we assume UNKNOWN at first startup self._last_action: int | None = None self._last_state: str | None = None @@ -97,11 +97,11 @@ class ComelitCoverEntity( async def async_close_cover(self, **kwargs: Any) -> None: """Close cover.""" - await self._api.cover_move(self._device.index, COVER_CLOSE) + await self._api.set_device_status(COVER, self._device.index, COVER_CLOSE) async def async_open_cover(self, **kwargs: Any) -> None: """Open cover.""" - await self._api.cover_move(self._device.index, COVER_OPEN) + await self._api.set_device_status(COVER, self._device.index, COVER_OPEN) async def async_stop_cover(self, **_kwargs: Any) -> None: """Stop the cover.""" @@ -109,7 +109,7 @@ class ComelitCoverEntity( return action = COVER_OPEN if self.is_closing else COVER_CLOSE - await self._api.cover_move(self._device.index, action) + await self._api.set_device_status(COVER, self._device.index, action) @callback def _handle_coordinator_update(self) -> None: diff --git a/homeassistant/components/comelit/light.py b/homeassistant/components/comelit/light.py index a59422f7b04..30981cd2820 100644 --- a/homeassistant/components/comelit/light.py +++ b/homeassistant/components/comelit/light.py @@ -4,7 +4,7 @@ from __future__ import annotations from typing import Any from aiocomelit import ComelitSerialBridgeObject -from aiocomelit.const import LIGHT, LIGHT_OFF, LIGHT_ON +from aiocomelit.const import LIGHT from homeassistant.components.light import LightEntity from homeassistant.config_entries import ConfigEntry @@ -12,7 +12,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .const import DOMAIN +from .const import DOMAIN, STATE_OFF, STATE_ON from .coordinator import ComelitSerialBridge @@ -49,22 +49,22 @@ class ComelitLightEntity(CoordinatorEntity[ComelitSerialBridge], LightEntity): self._device = device super().__init__(coordinator) self._attr_unique_id = f"{config_entry_entry_id}-{device.index}" - self._attr_device_info = self.coordinator.platform_device_info(device, LIGHT) + self._attr_device_info = self.coordinator.platform_device_info(device) async def _light_set_state(self, state: int) -> None: """Set desired light state.""" - await self.coordinator.api.light_switch(self._device.index, state) + await self.coordinator.api.set_device_status(LIGHT, self._device.index, state) await self.coordinator.async_request_refresh() async def async_turn_on(self, **kwargs: Any) -> None: """Turn the light on.""" - await self._light_set_state(LIGHT_ON) + await self._light_set_state(STATE_ON) async def async_turn_off(self, **kwargs: Any) -> None: """Turn the entity off.""" - await self._light_set_state(LIGHT_OFF) + await self._light_set_state(STATE_OFF) @property def is_on(self) -> bool: """Return True if entity is on.""" - return self.coordinator.data[LIGHT][self._device.index].status == LIGHT_ON + return self.coordinator.data[LIGHT][self._device.index].status == STATE_ON diff --git a/homeassistant/components/comelit/manifest.json b/homeassistant/components/comelit/manifest.json index 3e49996e50e..7da4f70ce99 100644 --- a/homeassistant/components/comelit/manifest.json +++ b/homeassistant/components/comelit/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/comelit", "iot_class": "local_polling", "loggers": ["aiocomelit"], - "requirements": ["aiocomelit==0.0.9"] + "requirements": ["aiocomelit==0.2.0"] } diff --git a/requirements_all.txt b/requirements_all.txt index e130adfe58d..a9cd582a6ea 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -210,7 +210,7 @@ aiobafi6==0.9.0 aiobotocore==2.6.0 # homeassistant.components.comelit -aiocomelit==0.0.9 +aiocomelit==0.2.0 # homeassistant.components.dhcp aiodiscover==1.5.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 3ed5cec5beb..6e56127849f 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -191,7 +191,7 @@ aiobafi6==0.9.0 aiobotocore==2.6.0 # homeassistant.components.comelit -aiocomelit==0.0.9 +aiocomelit==0.2.0 # homeassistant.components.dhcp aiodiscover==1.5.1 diff --git a/tests/components/comelit/const.py b/tests/components/comelit/const.py index 36955b0b0a9..a21ddbd425a 100644 --- a/tests/components/comelit/const.py +++ b/tests/components/comelit/const.py @@ -1,13 +1,15 @@ """Common stuff for Comelit SimpleHome tests.""" + from homeassistant.components.comelit.const import DOMAIN -from homeassistant.const import CONF_DEVICES, CONF_HOST, CONF_PIN +from homeassistant.const import CONF_DEVICES, CONF_HOST, CONF_PIN, CONF_PORT MOCK_CONFIG = { DOMAIN: { CONF_DEVICES: [ { CONF_HOST: "fake_host", - CONF_PIN: "1234", + CONF_PORT: 80, + CONF_PIN: 1234, } ] } diff --git a/tests/components/comelit/test_config_flow.py b/tests/components/comelit/test_config_flow.py index 10f68f4d7c1..4e3831809cb 100644 --- a/tests/components/comelit/test_config_flow.py +++ b/tests/components/comelit/test_config_flow.py @@ -6,7 +6,7 @@ import pytest from homeassistant.components.comelit.const import DOMAIN from homeassistant.config_entries import SOURCE_REAUTH, SOURCE_USER -from homeassistant.const import CONF_HOST, CONF_PIN +from homeassistant.const import CONF_HOST, CONF_PIN, CONF_PORT from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType @@ -39,7 +39,8 @@ async def test_user(hass: HomeAssistant) -> None: ) assert result["type"] == FlowResultType.CREATE_ENTRY assert result["data"][CONF_HOST] == "fake_host" - assert result["data"][CONF_PIN] == "1234" + assert result["data"][CONF_PORT] == 80 + assert result["data"][CONF_PIN] == 1234 assert not result["result"].unique_id await hass.async_block_till_done() @@ -66,6 +67,10 @@ async def test_exception_connection(hass: HomeAssistant, side_effect, error) -> with patch( "aiocomelit.api.ComeliteSerialBridgeApi.login", side_effect=side_effect, + ), patch( + "aiocomelit.api.ComeliteSerialBridgeApi.logout", + ), patch( + "homeassistant.components.comelit.async_setup_entry" ): result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input=MOCK_USER_DATA