Skip to content

Commit

Permalink
feat: add an alias to the control panel and binary sensor entities (#49)
Browse files Browse the repository at this point in the history
Co-authored-by: Emanuele Palazzetti <[email protected]>
  • Loading branch information
xtimmy86x and palazzem authored Sep 25, 2023
1 parent 9f7fea2 commit 9117840
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 10 deletions.
3 changes: 2 additions & 1 deletion custom_components/elmo_iess_alarm/alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

from .const import DOMAIN, KEY_COORDINATOR, KEY_DEVICE
from .decorators import set_device_state
from .helpers import generate_entity_name

_LOGGER = logging.getLogger(__name__)

Expand All @@ -38,7 +39,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_d
async_add_devices(
[
EconnectAlarm(
"Alarm Panel",
generate_entity_name(entry),
device,
coordinator,
unique_id,
Expand Down
15 changes: 12 additions & 3 deletions custom_components/elmo_iess_alarm/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from custom_components.elmo_iess_alarm.devices import AlarmDevice

from .const import DOMAIN, KEY_COORDINATOR, KEY_DEVICE
from .helpers import generate_entity_name


async def async_setup_entry(
Expand All @@ -29,11 +30,19 @@ async def async_setup_entry(
inventory = await hass.async_add_executor_job(device._connection._get_descriptions)
for sector_id, name in inventory[query.SECTORS].items():
unique_id = f"{entry.entry_id}_{DOMAIN}_{query.SECTORS}_{sector_id}"
sensors.append(EconnectDoorWindowSensor(coordinator, device, unique_id, sector_id, query.SECTORS, name))
sensors.append(
EconnectDoorWindowSensor(
coordinator, device, unique_id, sector_id, query.SECTORS, generate_entity_name(entry, name)
)
)

for sensor_id, name in inventory[query.INPUTS].items():
unique_id = f"{entry.entry_id}_{DOMAIN}_{query.INPUTS}_{sensor_id}"
sensors.append(EconnectDoorWindowSensor(coordinator, device, unique_id, sensor_id, query.INPUTS, name))
sensors.append(
EconnectDoorWindowSensor(
coordinator, device, unique_id, sensor_id, query.INPUTS, generate_entity_name(entry, name)
)
)

async_add_entities(sensors)

Expand All @@ -56,7 +65,7 @@ def __init__(
self._unique_id = unique_id
self._sensor_id = sensor_id
self._sensor_type = sensor_type
self._name = f"{DOMAIN} {name}"
self._name = name

@property
def unique_id(self) -> str:
Expand Down
5 changes: 5 additions & 0 deletions custom_components/elmo_iess_alarm/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
CONF_AREAS_ARM_NIGHT,
CONF_AREAS_ARM_VACATION,
CONF_DOMAIN,
CONF_SYSTEM_NAME,
CONF_SYSTEM_URL,
DOMAIN,
SUPPORTED_SYSTEMS,
Expand Down Expand Up @@ -84,6 +85,10 @@ async def async_step_user(self, user_input=None):
CONF_DOMAIN,
description={"suggested_value": user_input.get(CONF_DOMAIN)},
): str,
vol.Optional(
CONF_SYSTEM_NAME,
description={"suggested_value": user_input.get(CONF_SYSTEM_NAME)},
): str,
}
),
errors=errors,
Expand Down
1 change: 1 addition & 0 deletions custom_components/elmo_iess_alarm/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
}
CONF_DOMAIN = "domain"
CONF_SYSTEM_URL = "system_base_url"
CONF_SYSTEM_NAME = "system_name"
CONF_AREAS_ARM_HOME = "areas_arm_home"
CONF_AREAS_ARM_NIGHT = "areas_arm_night"
CONF_AREAS_ARM_VACATION = "areas_arm_vacation"
Expand Down
28 changes: 27 additions & 1 deletion custom_components/elmo_iess_alarm/helpers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
"""Helper methods to reuse common logic across elmo_iess_alarm module."""
from typing import Union

from elmo.api.client import ElmoClient
from homeassistant import core
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME

from .const import CONF_DOMAIN, CONF_SYSTEM_URL
from .const import CONF_DOMAIN, CONF_SYSTEM_NAME, CONF_SYSTEM_URL, DOMAIN
from .exceptions import InvalidAreas


Expand Down Expand Up @@ -67,3 +70,26 @@ async def validate_credentials(hass: core.HomeAssistant, config: dict):
client = ElmoClient(config.get(CONF_SYSTEM_URL), domain=config.get(CONF_DOMAIN))
await hass.async_add_executor_job(client.auth, config.get(CONF_USERNAME), config.get(CONF_PASSWORD))
return True


def generate_entity_name(entry: ConfigEntry, name: Union[str, None] = None) -> str:
"""Generate a name for the entity based on system configuration or username.
Args:
entry (ConfigEntry): The configuration entry from Home Assistant containing system
configuration or username.
Returns:
str: The generated entity name, which is a combination of the domain and either the configured
system name or the username.
Example:
>>> entry.data = {"system_name": "Seaside Home"}
>>> generate_entity_name(entry, "window")
"elmo_iess_alarm_seaside_home_window"
"""
if CONF_SYSTEM_NAME in entry.data:
entity_system_name = f"{DOMAIN} {entry.data[CONF_SYSTEM_NAME]} {name or ''}".strip()
else:
entity_system_name = f"{DOMAIN} {entry.data[CONF_USERNAME]} {name or ''}".strip()
return entity_system_name
2 changes: 1 addition & 1 deletion custom_components/elmo_iess_alarm/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@
"econnect-python==0.6.0"
],
"version": "1.0.0"
}
}
3 changes: 2 additions & 1 deletion custom_components/elmo_iess_alarm/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"data": {
"domain": "Domain name (optional)",
"username": "[%key:common::config_flow::data::username%]",
"password": "[%key:common::config_flow::data::password%]"
"password": "[%key:common::config_flow::data::password%]",
"system_name": "[%key:common::config_flow::data::system_name%]"
},
"description": "Provide your credentials and the domain used to access your login page via web.\n\nFor instance, if you access to `https://connect.elmospa.com/vendor/`, you must set the domain to `vendor`. In case you don't have a vendor defined, set it to `default`.\n\nYou can configure the system selecting \"Options\" after installing the integration.",
"title": "Configure your Elmo/IESS system"
Expand Down
3 changes: 2 additions & 1 deletion custom_components/elmo_iess_alarm/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"data": {
"domain": "Domain name (optional)",
"username": "Username",
"password": "Password"
"password": "Password",
"system_name": "Name of the control panel (optional)"
},
"description": "Provide your credentials and the domain used to access your login page via web.\n\nFor instance, if you access to `https://connect.elmospa.com/vendor/`, you must set the domain to `vendor`. In case you don't have a vendor defined, set it to `default`.\n\nYou can configure the system selecting \"Options\" after installing the integration.",
"title": "Configure your Elmo/IESS system"
Expand Down
3 changes: 2 additions & 1 deletion custom_components/elmo_iess_alarm/translations/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"data": {
"domain": "Nome dominio (opzionale)",
"username": "Nome utente",
"password": "Password"
"password": "Password",
"system_name": "Nome dell'impianto (opzionale)"
},
"description": "Fornisci le tue credenziali e il dominio utilizzato per accedere alla tua pagina di login via web.\n\nAd esempio, se accedi a `https://connect.elmospa.com/installatore/`, devi impostare il dominio su `installatore`. Nel caso in cui non hai un installatore definito, impostalo su `default`.\n\nPuoi configurare il sistema selezionando \"Opzioni\" dopo aver installato l'integrazione.",
"title": "Configura il tuo sistema Elmo/IESS"
Expand Down
17 changes: 17 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,20 @@ def client():
server.add(responses.POST, "https://example.com/api/areas", body=r.AREAS, status=200)
server.add(responses.POST, "https://example.com/api/inputs", body=r.INPUTS, status=200)
yield client


@pytest.fixture(scope="function")
def config_entry():
"""Creates a mock config entry for testing purposes.
This config entry is designed to emulate the behavior of a real config entry for
testing purposes.
"""

class MockConfigEntry:
def __init__(self):
self.data = {
"username": "test_user",
}

return MockConfigEntry()
32 changes: 31 additions & 1 deletion tests/test_helpers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import pytest

from custom_components.elmo_iess_alarm.exceptions import InvalidAreas
from custom_components.elmo_iess_alarm.helpers import parse_areas_config
from custom_components.elmo_iess_alarm.helpers import (
generate_entity_name,
parse_areas_config,
)


def test_parse_areas_config_valid_input():
Expand Down Expand Up @@ -31,3 +34,30 @@ def test_parse_areas_config_raises_value_error():

def test_parse_areas_config_whitespace():
assert parse_areas_config(" 3 , 4 ") == [3, 4]


def test_generate_entity_name_empty(config_entry):
assert generate_entity_name(config_entry) == "elmo_iess_alarm test_user"


def test_generate_entity_name_with_name(config_entry):
assert generate_entity_name(config_entry, "window") == "elmo_iess_alarm test_user window"


def test_generate_entity_name_with_none(config_entry):
assert generate_entity_name(config_entry, None) == "elmo_iess_alarm test_user"


def test_generate_entity_name_empty_system(config_entry):
config_entry.data["system_name"] = "Home"
assert generate_entity_name(config_entry) == "elmo_iess_alarm Home"


def test_generate_entity_name_with_name_system(config_entry):
config_entry.data["system_name"] = "Home"
assert generate_entity_name(config_entry, "window") == "elmo_iess_alarm Home window"


def test_generate_entity_name_with_none_system(config_entry):
config_entry.data["system_name"] = "Home"
assert generate_entity_name(config_entry, None) == "elmo_iess_alarm Home"

0 comments on commit 9117840

Please sign in to comment.