Skip to content

Commit

Permalink
refactor!: migrate the integration to elmo_iess_alarm namespace (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
palazzem authored Sep 11, 2023
2 parents 3eaed04 + b3a3f41 commit 8ac9118
Show file tree
Hide file tree
Showing 25 changed files with 72 additions and 68 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/building.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,20 @@ jobs:
run: hatch -v build -t sdist

- name: Log package content
run: tar -tvf dist/econnect_alarm-$PKG_VERSION.tar.gz
run: tar -tvf dist/elmo_iess_alarm-$PKG_VERSION.tar.gz

- name: Install the package
run: pip install dist/econnect_alarm-$PKG_VERSION.tar.gz
run: pip install dist/elmo_iess_alarm-$PKG_VERSION.tar.gz

- name: Test if the package is built correctly
run: python -c "import custom_components.econnect_alarm"
run: python -c "import custom_components.elmo_iess_alarm"

- name: Build the release package
run: hatch -v build -t zipped-directory

- name: Upload release archive
uses: actions/upload-artifact@v3
with:
name: econnect-alarm-${{ env.PKG_VERSION }}.zip
path: dist/econnect_alarm-${{ env.PKG_VERSION }}.zip
name: elmo-iess-alarm-${{ env.PKG_VERSION }}.zip
path: dist/elmo_iess_alarm-${{ env.PKG_VERSION }}.zip
if-no-files-found: error
6 changes: 3 additions & 3 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ jobs:

- name: Build Integration ZIP package
run: |
cd ${{ github.workspace }}/custom_components/econnect_alarm
zip hacs_econnect_alarm.zip -r ./
cd ${{ github.workspace }}/custom_components/elmo_iess_alarm
zip hacs_elmo_iess_alarm.zip -r ./
- name: Upload ZIP package release
uses: softprops/[email protected]
with:
files: ${{ github.workspace }}/custom_components/econnect_alarm/hacs_econnect_alarm.zip
files: ${{ github.workspace }}/custom_components/elmo_iess_alarm/hacs_elmo_iess_alarm.zip
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repos:
- id: check-toml
- id: check-yaml
- id: end-of-file-fixer
exclude: custom_components/econnect_alarm/manifest.json
exclude: custom_components/elmo_iess_alarm/manifest.json
- id: mixed-line-ending
- id: trailing-whitespace

Expand Down
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Home Assistant e-Connect Integration (Elmo)
# Home Assistant Elmo/IESS Integration

[![Linting](https://github.com/palazzem/ha-econnect-alarm/actions/workflows/linting.yaml/badge.svg)](https://github.com/palazzem/ha-econnect-alarm/actions/workflows/linting.yaml)
[![Testing](https://github.com/palazzem/ha-econnect-alarm/actions/workflows/testing.yaml/badge.svg)](https://github.com/palazzem/ha-econnect-alarm/actions/workflows/testing.yaml)
Expand All @@ -7,12 +7,12 @@



This project is a [Home Assistant](https://www.home-assistant.io/) integration for your Elmo-like Alarm connected to
[e-Connect cloud](https://e-connect.elmospa.com/it/).
This project is a [Home Assistant](https://www.home-assistant.io/) integration for your Elmo/IESS Alarm connected to
[e-Connect cloud](https://e-connect.elmospa.com/it/) or [Metronet](https://metronet.iessonline.com/).

## Supported Systems

This Home Assistant integration targets Elmo-like alarm systems. The following systems are known to work:
This integration supports Elmo/IESS alarm systems. The following systems are known to work:
- [Elmo e-Connect](https://e-connect.elmospa.com/)
- [IESS Metronet](https://www.iessonline.com/)

Expand All @@ -38,7 +38,7 @@ If you are curious about the project and want to know more, check out our [Disco

1. Create a new folder in your configuration folder (where the `configuration.yaml` lives) called `custom_components`
2. Download the [latest version](https://github.com/palazzem/ha-econnect-alarm/releases) into the `custom_components`
folder so that the full path from your config folder is `custom_components/econnect_alarm/`
folder so that the full path from your config folder is `custom_components/elmo_iess_alarm/`
3. Restart Home Assistant. If it's your only custom component you'll see a warning in your logs.
4. Once Home Assistant is started, from the UI go to Configuration > Integrations > Add Integrations. Search for
"E-connect Alarm". After selecting, dependencies will be downloaded and it could take up to a minute.
Expand All @@ -47,24 +47,26 @@ If you are curious about the project and want to know more, check out our [Disco

<img src="https://github-production-user-asset-6210df.s3.amazonaws.com/1560405/267038244-a5a590f3-8982-4f01-8ad0-5e7b00222643.png" width="400">

- Username: is your username to access e-connect via web or app.
- Password: is your password to access e-connect via web or app.
- Username: is your username to access Elmo/IESS via web or app.
- Password: is your password to access Elmo/IESS via web or app.
- System: pick the brand of alarm system you are using.
- Domain name (optional): domain used to access your login page via web. For 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`.

### Options

<img src="https://user-images.githubusercontent.com/1560405/110982667-1ad67880-8369-11eb-9930-a35028680d70.png" width="400"/>
<img src="https://github.com/palazzem/ha-econnect-alarm/assets/1560405/1e99bf57-a29f-4a33-b503-56d3af6b0169" width="400"/>

From the integration page, you can configure some options to alter the integration behavior. Click on "Options".

<img src="https://user-images.githubusercontent.com/1560405/110982987-7e60a600-8369-11eb-8a89-48d527c7040c.png" width="400"/>
<img src="https://github.com/palazzem/ha-econnect-alarm/assets/1560405/1469369b-ca95-4ae7-9a67-fd6ca8fbb21d" width="400"/>

- Armed areas while at home (optional): list areas you want to arm when you select Arm Home. If not set, that mode is not
available and no actions are taken when you click the button.
- Armed areas at night (optional): list areas you want to arm when you select Arm Night. If not set, that mode is not available
and no actions are taken when you click the button.
- Armed areas on vacation (optional): list areas you want to arm when you select Arm Vacation. If not set, that mode is not available
and no actions are taken when you click the button.

### Automations

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ async def async_update_data():
coordinator = DataUpdateCoordinator(
hass,
_LOGGER,
name="econnect_alarm",
name="elmo_iess_alarm",
update_interval=timedelta(seconds=SCAN_INTERVAL),
update_method=async_update_data,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_d
"""Platform setup with the forwarded config entry."""
device = hass.data[DOMAIN][entry.entry_id][KEY_DEVICE]
coordinator = hass.data[DOMAIN][entry.entry_id][KEY_COORDINATOR]
unique_id = entry.entry_id
unique_id = f"{DOMAIN}_{entry.entry_id}"
async_add_devices(
[
EconnectAlarm(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
DataUpdateCoordinator,
)

from custom_components.econnect_alarm.devices import AlarmDevice
from custom_components.elmo_iess_alarm.devices import AlarmDevice

from .const import DOMAIN, KEY_COORDINATOR, KEY_DEVICE

Expand All @@ -28,11 +28,11 @@ async def async_setup_entry(
sensors = []
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}_{query.SECTORS}_{sector_id}"
unique_id = f"{entry.entry_id}_{DOMAIN}_{query.SECTORS}_{sector_id}"
sensors.append(EconnectDoorWindowSensor(coordinator, device, unique_id, sector_id, query.SECTORS, name))

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

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

@property
def unique_id(self) -> str:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
CONF_AREAS_ARM_HOME = "areas_arm_home"
CONF_AREAS_ARM_NIGHT = "areas_arm_night"
CONF_AREAS_ARM_VACATION = "areas_arm_vacation"
DOMAIN = "econnect_alarm"
DOMAIN = "elmo_iess_alarm"
KEY_DEVICE = "device"
KEY_COORDINATOR = "coordinator"
KEY_UNSUBSCRIBER = "options_unsubscriber"
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Exceptions raised by econnect_alarm component."""
"""Exceptions raised by elmo_iess_alarm component."""
from homeassistant.exceptions import HomeAssistantError


Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Helper methods to reuse common logic across econnect_alarm module."""
"""Helper methods to reuse common logic across elmo_iess_alarm module."""
from elmo.api.client import ElmoClient
from homeassistant import core
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"domain": "econnect_alarm",
"name": "E-connect Alarm",
"domain": "elmo_iess_alarm",
"name": "Elmo/IESS Alarm",
"after_dependencies": [],
"codeowners": [
"@palazzem"
Expand All @@ -12,7 +12,7 @@
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/palazzem/ha-econnect-alarm/issues",
"loggers": [
"custom_components.econnect_alarm"
"custom_components.elmo_iess_alarm"
],
"requirements": [
"econnect-python==0.6.0"
Expand Down
2 changes: 1 addition & 1 deletion hacs.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"render_readme": true,
"hide_default_branch": true,
"zip_release": true,
"filename": "hacs_econnect_alarm.zip"
"filename": "hacs_elmo_iess_alarm.zip"
}
16 changes: 9 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ requires = [
build-backend = "hatchling.build"

[project]
name = "econnect-alarm"
name = "elmo-iess-alarm"
dynamic = ["version"]
description = "Home Assistant integration that provides a full-fledged Alarm Panel to control your Elmo alarm system."
description = "Home Assistant integration that provides a full-fledged Alarm Panel to control your Elmo/IESS alarm systems."
readme = "README.md"
requires-python = ">=3.11"
license = "Apache-2.0"
Expand All @@ -19,6 +19,8 @@ keywords = [
"alarm-system",
"econnect",
"elmo",
"metronet",
"iess",
]
authors = [
{ name = "Emanuele Palazzetti", email = "[email protected]" },
Expand Down Expand Up @@ -58,8 +60,8 @@ lint = [
]

all = [
"econnect-alarm[dev]",
"econnect-alarm[lint]",
"elmo-iess-alarm[dev]",
"elmo-iess-alarm[lint]",
]

[project.urls]
Expand All @@ -68,7 +70,7 @@ Issues = "https://github.com/palazzem/ha-econnect-alarm/issues"
Source = "https://github.com/palazzem/ha-econnect-alarm"

[tool.hatch.version]
path = "custom_components/econnect_alarm/manifest.json"
path = "custom_components/elmo_iess_alarm/manifest.json"
pattern = '"version":\s"(?P<version>[^"]+)"'

[tool.hatch.metadata]
Expand All @@ -78,7 +80,7 @@ allow-direct-references = true
asyncio_mode = "auto"

[tool.hatch.build.targets.sdist]
only-include = ["custom_components/econnect_alarm"]
only-include = ["custom_components/elmo_iess_alarm"]

[tool.hatch.build.targets.zipped-directory]
only-include = ["custom_components/econnect_alarm"]
only-include = ["custom_components/elmo_iess_alarm"]
8 changes: 4 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from elmo.api.client import ElmoClient
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator

from custom_components.econnect_alarm.alarm_control_panel import EconnectAlarm
from custom_components.econnect_alarm.devices import AlarmDevice
from custom_components.elmo_iess_alarm.alarm_control_panel import EconnectAlarm
from custom_components.elmo_iess_alarm.devices import AlarmDevice

from .fixtures import responses as r

Expand Down Expand Up @@ -35,11 +35,11 @@ def alarm_entity(hass, client):
EconnectAlarm: Initialized test instance of the EconnectAlarm entity.
"""
device = AlarmDevice(client)
coordinator = DataUpdateCoordinator(hass, logging.getLogger(__name__), name="econnect_alarm")
coordinator = DataUpdateCoordinator(hass, logging.getLogger(__name__), name="elmo_iess_alarm")
entity = EconnectAlarm(name="Test Alarm", device=device, coordinator=coordinator, unique_id="test_id")
# Set up the fixture
entity.hass = hass
entity.entity_id = "econnect_alarm.test_id"
entity.entity_id = "elmo_iess_alarm.test_id"
yield entity


Expand Down
42 changes: 21 additions & 21 deletions tests/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from requests.models import Response
from voluptuous.error import MultipleInvalid

from custom_components.econnect_alarm.const import DOMAIN
from custom_components.elmo_iess_alarm.const import DOMAIN


async def test_form_fields(hass):
Expand All @@ -22,9 +22,9 @@ async def test_form_fields(hass):
assert form["data_schema"].schema["domain"] == str


@patch("custom_components.econnect_alarm.async_setup", return_value=True)
@patch("custom_components.econnect_alarm.async_setup_entry", return_value=True)
@patch("custom_components.econnect_alarm.helpers.ElmoClient")
@patch("custom_components.elmo_iess_alarm.async_setup", return_value=True)
@patch("custom_components.elmo_iess_alarm.async_setup_entry", return_value=True)
@patch("custom_components.elmo_iess_alarm.helpers.ElmoClient")
async def test_form_submit_successful(mock_client, mock_setup_entry, mock_setup, hass):
"""Test a properly submitted form initializes an ElmoClient."""
form = await hass.config_entries.flow.async_init(DOMAIN, context={"source": config_entries.SOURCE_USER})
Expand Down Expand Up @@ -59,9 +59,9 @@ async def test_form_submit_successful(mock_client, mock_setup_entry, mock_setup,
assert ("test-username", "test-password") == client.auth.call_args.args


@patch("custom_components.econnect_alarm.async_setup", return_value=True)
@patch("custom_components.econnect_alarm.async_setup_entry", return_value=True)
@patch("custom_components.econnect_alarm.helpers.ElmoClient")
@patch("custom_components.elmo_iess_alarm.async_setup", return_value=True)
@patch("custom_components.elmo_iess_alarm.async_setup_entry", return_value=True)
@patch("custom_components.elmo_iess_alarm.helpers.ElmoClient")
async def test_form_submit_with_defaults(mock_client, mock_setup_entry, mock_setup, hass):
"""Test a properly submitted form with defaults."""
form = await hass.config_entries.flow.async_init(DOMAIN, context={"source": config_entries.SOURCE_USER})
Expand Down Expand Up @@ -100,8 +100,8 @@ async def test_form_supported_systems(hass):
}


@patch("custom_components.econnect_alarm.async_setup", return_value=True)
@patch("custom_components.econnect_alarm.async_setup_entry", return_value=True)
@patch("custom_components.elmo_iess_alarm.async_setup", return_value=True)
@patch("custom_components.elmo_iess_alarm.async_setup_entry", return_value=True)
async def test_form_submit_required_fields(mock_setup_entry, mock_setup, hass):
"""Test the form has the expected required fields."""
form = await hass.config_entries.flow.async_init(DOMAIN, context={"source": config_entries.SOURCE_USER})
Expand All @@ -118,10 +118,10 @@ async def test_form_submit_required_fields(mock_setup_entry, mock_setup, hass):
assert "required key not provided @ data['password']" in errors


@patch("custom_components.econnect_alarm.async_setup", return_value=True)
@patch("custom_components.econnect_alarm.async_setup_entry", return_value=True)
@patch("custom_components.elmo_iess_alarm.async_setup", return_value=True)
@patch("custom_components.elmo_iess_alarm.async_setup_entry", return_value=True)
@patch(
"custom_components.econnect_alarm.helpers.ElmoClient.auth",
"custom_components.elmo_iess_alarm.helpers.ElmoClient.auth",
side_effect=CredentialError,
)
async def test_form_submit_wrong_credential(mock_client, mock_setup_entry, mock_setup, hass):
Expand All @@ -142,10 +142,10 @@ async def test_form_submit_wrong_credential(mock_client, mock_setup_entry, mock_
assert result["errors"]["base"] == "invalid_auth"


@patch("custom_components.econnect_alarm.async_setup", return_value=True)
@patch("custom_components.econnect_alarm.async_setup_entry", return_value=True)
@patch("custom_components.elmo_iess_alarm.async_setup", return_value=True)
@patch("custom_components.elmo_iess_alarm.async_setup_entry", return_value=True)
@patch(
"custom_components.econnect_alarm.helpers.ElmoClient.auth",
"custom_components.elmo_iess_alarm.helpers.ElmoClient.auth",
side_effect=ConnectionError,
)
async def test_form_submit_connection_error(mock_client, mock_setup_entry, mock_setup, hass):
Expand All @@ -166,8 +166,8 @@ async def test_form_submit_connection_error(mock_client, mock_setup_entry, mock_
assert result["errors"]["base"] == "cannot_connect"


@patch("custom_components.econnect_alarm.async_setup", return_value=True)
@patch("custom_components.econnect_alarm.async_setup_entry", return_value=True)
@patch("custom_components.elmo_iess_alarm.async_setup", return_value=True)
@patch("custom_components.elmo_iess_alarm.async_setup_entry", return_value=True)
async def test_form_client_errors(mock_setup_entry, mock_setup, hass):
"""Test the right error is raised for 4xx API errors."""
form = await hass.config_entries.flow.async_init(DOMAIN, context={"source": config_entries.SOURCE_USER})
Expand All @@ -179,7 +179,7 @@ async def test_form_client_errors(mock_setup_entry, mock_setup, hass):
err = HTTPError(response=r)

with patch(
"custom_components.econnect_alarm.helpers.ElmoClient.auth",
"custom_components.elmo_iess_alarm.helpers.ElmoClient.auth",
side_effect=err,
):
result = await hass.config_entries.flow.async_configure(
Expand All @@ -196,8 +196,8 @@ async def test_form_client_errors(mock_setup_entry, mock_setup, hass):
assert result["errors"]["base"] == "client_error"


@patch("custom_components.econnect_alarm.async_setup", return_value=True)
@patch("custom_components.econnect_alarm.async_setup_entry", return_value=True)
@patch("custom_components.elmo_iess_alarm.async_setup", return_value=True)
@patch("custom_components.elmo_iess_alarm.async_setup_entry", return_value=True)
async def test_form_server_errors(mock_setup_entry, mock_setup, hass):
"""Test the right error is raised for 5xx API errors."""
form = await hass.config_entries.flow.async_init(DOMAIN, context={"source": config_entries.SOURCE_USER})
Expand All @@ -209,7 +209,7 @@ async def test_form_server_errors(mock_setup_entry, mock_setup, hass):
err = HTTPError(response=r)

with patch(
"custom_components.econnect_alarm.helpers.ElmoClient.auth",
"custom_components.elmo_iess_alarm.helpers.ElmoClient.auth",
side_effect=err,
):
result = await hass.config_entries.flow.async_configure(
Expand Down
Loading

0 comments on commit 8ac9118

Please sign in to comment.