Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Homee integration to Core #133738

Merged
merged 25 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8c46740
Add homee integration
Taraman17 Dec 21, 2024
a2d49ed
remove old pymee copy
Taraman17 Dec 21, 2024
c79860c
Merge branch 'dev' into homee_initial
Taraman17 Dec 21, 2024
f9fd1f2
fix first review
Taraman17 Dec 22, 2024
e60d62d
Merge branch 'dev' into homee_initial
Taraman17 Dec 22, 2024
4ef3a6e
fix second review
Taraman17 Dec 23, 2024
2afcc55
Merge branch 'dev' into homee_initial
Taraman17 Dec 23, 2024
efa36fd
Fix tests
Taraman17 Dec 23, 2024
9bfebe4
Merge branch 'homee_initial' of https://github.com/Taraman17/ha-core …
Taraman17 Dec 23, 2024
1fcb4d2
Merge branch 'dev' into homee_initial
Taraman17 Dec 23, 2024
906574c
fix more review comments
Taraman17 Dec 30, 2024
0860016
Merge branch 'dev' into homee_initial
Taraman17 Dec 30, 2024
329eea3
Merge branch 'homee_initial' of https://github.com/Taraman17/ha-core …
Taraman17 Dec 30, 2024
ac175e7
change DeviceInfo import
Taraman17 Dec 30, 2024
cd10b4a
Another review fix.
Taraman17 Jan 2, 2025
1d532e4
Merge branch 'dev' into homee_initial
Taraman17 Jan 2, 2025
757c252
Bump pyHomee to v1.2.0
Taraman17 Jan 2, 2025
7626aaa
Merge branch 'homee_initial' of https://github.com/Taraman17/ha-core …
Taraman17 Jan 2, 2025
654e3f9
long time but always forgotten change of Homee device name.
Taraman17 Jan 2, 2025
77fef68
Use typed NodeState iso int
Taraman17 Jan 2, 2025
1d1de40
Merge branch 'dev' into homee_initial
Taraman17 Jan 2, 2025
38d8597
fix _on_connection_changed, self._node.state is not writable
Taraman17 Jan 2, 2025
0e5a138
Fix
joostlek Jan 3, 2025
758ba74
Fix
joostlek Jan 3, 2025
319a7c0
Fix test coverage
joostlek Jan 3, 2025
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
2 changes: 2 additions & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,8 @@ build.json @home-assistant/supervisor
/tests/components/homeassistant_sky_connect/ @home-assistant/core
/homeassistant/components/homeassistant_yellow/ @home-assistant/core
/tests/components/homeassistant_yellow/ @home-assistant/core
/homeassistant/components/homee/ @Taraman17
/tests/components/homee/ @Taraman17
/homeassistant/components/homekit/ @bdraco
/tests/components/homekit/ @bdraco
/homeassistant/components/homekit_controller/ @Jc2k @bdraco
Expand Down
69 changes: 69 additions & 0 deletions homeassistant/components/homee/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"""The Homee integration."""

import logging

from pyHomee import Homee

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr

from .const import DOMAIN

_LOGGER = logging.getLogger(__name__)

PLATFORMS = [Platform.COVER]

type HomeeConfigEntry = ConfigEntry[Homee]


async def async_setup_entry(hass: HomeAssistant, entry: HomeeConfigEntry) -> bool:
"""Set up homee from a config entry."""
# Create the Homee api object using host, user,
# password & pyHomee instance from the config
homee = Homee(

Check warning on line 25 in homeassistant/components/homee/__init__.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/homee/__init__.py#L25

Added line #L25 was not covered by tests
host=entry.data[CONF_HOST],
user=entry.data[CONF_USERNAME],
password=entry.data[CONF_PASSWORD],
device="pymee_" + hass.config.location_name,
reconnect_interval=10,
max_retries=100,
)

# Start the homee websocket connection as a new task
# and wait until we are connected
hass.loop.create_task(homee.run())
await homee.wait_until_connected()

Check warning on line 37 in homeassistant/components/homee/__init__.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/homee/__init__.py#L36-L37

Added lines #L36 - L37 were not covered by tests

entry.runtime_data = homee
entry.async_on_unload(homee.disconnect)

Check warning on line 40 in homeassistant/components/homee/__init__.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/homee/__init__.py#L39-L40

Added lines #L39 - L40 were not covered by tests

# create device register entry
device_registry = dr.async_get(hass)
device_registry.async_get_or_create(

Check warning on line 44 in homeassistant/components/homee/__init__.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/homee/__init__.py#L43-L44

Added lines #L43 - L44 were not covered by tests
config_entry_id=entry.entry_id,
connections={
(dr.CONNECTION_NETWORK_MAC, dr.format_mac(homee.settings.mac_address))
},
identifiers={(DOMAIN, homee.settings.uid)},
manufacturer="homee",
name=homee.settings.homee_name,
model="homee",
sw_version=homee.settings.version,
)

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

Check warning on line 56 in homeassistant/components/homee/__init__.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/homee/__init__.py#L56

Added line #L56 was not covered by tests

return True

Check warning on line 58 in homeassistant/components/homee/__init__.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/homee/__init__.py#L58

Added line #L58 was not covered by tests


async def async_unload_entry(hass: HomeAssistant, entry: HomeeConfigEntry) -> bool:
"""Unload a homee config entry."""
# Unload platforms
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)


async def async_update_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Reload homee integration after config change."""
await hass.config_entries.async_reload(entry.entry_id)

Check warning on line 69 in homeassistant/components/homee/__init__.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/homee/__init__.py#L69

Added line #L69 was not covered by tests
Taraman17 marked this conversation as resolved.
Show resolved Hide resolved
106 changes: 106 additions & 0 deletions homeassistant/components/homee/config_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
"""Config flow for homee integration."""

import logging
from typing import Any

from pyHomee import (
Homee,
HomeeAuthFailedException as HomeeAuthenticationFailedException,
HomeeConnectionFailedException,
)
import voluptuous as vol

from homeassistant import exceptions
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.data_entry_flow import AbortFlow

from .const import DOMAIN

_LOGGER = logging.getLogger(__name__)

AUTH_SCHEMA = vol.Schema(
{
vol.Required(CONF_HOST): str,
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
}
)


class HomeeConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for homee."""

VERSION = 1

def __init__(self) -> None:
"""Initialize the config flow."""
self.homee: Homee = None
self.all_devices: bool = True
self.debug_data: bool = False
Taraman17 marked this conversation as resolved.
Show resolved Hide resolved

async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle the initial user step."""

errors = {}
if user_input is not None:
self.homee = Homee(
user_input[CONF_HOST],
user_input[CONF_USERNAME],
user_input[CONF_PASSWORD],
)

try:
await self.homee.get_access_token()
_LOGGER.info("Got access token for homee")
Taraman17 marked this conversation as resolved.
Show resolved Hide resolved
except HomeeConnectionFailedException:
errors["base"] = "cannot_connect"
except HomeeAuthenticationFailedException:
errors["base"] = "invalid_auth"
except Exception: # pylint: disable=broad-except
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"

Check warning on line 64 in homeassistant/components/homee/config_flow.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/homee/config_flow.py#L62-L64

Added lines #L62 - L64 were not covered by tests
else:
self.hass.loop.create_task(self.homee.run())
_LOGGER.debug("Homee task created")
await self.homee.wait_until_connected()
_LOGGER.info("Homee connected")
self.homee.disconnect()
_LOGGER.debug("Homee disconnecting")
await self.homee.wait_until_disconnected()
_LOGGER.info("Homee config successfully tested")

await self.async_set_unique_id(self.homee.settings.uid)
Taraman17 marked this conversation as resolved.
Show resolved Hide resolved
try:
self._abort_if_unique_id_configured()
except AbortFlow:
return self.async_abort(reason="already_configured")
Taraman17 marked this conversation as resolved.
Show resolved Hide resolved
else:
_LOGGER.info(
"Created new homee entry with ID %s", self.homee.settings.uid
)

return self.async_create_entry(
title=f"{self.homee.settings.uid} ({self.homee.host})",
Taraman17 marked this conversation as resolved.
Show resolved Hide resolved
data={
CONF_HOST: self.homee.host,
CONF_USERNAME: self.homee.user,
CONF_PASSWORD: self.homee.password,
},
Taraman17 marked this conversation as resolved.
Show resolved Hide resolved
)

return self.async_show_form(
step_id="user",
data_schema=AUTH_SCHEMA,
errors=errors,
)


class CannotConnect(exceptions.HomeAssistantError):
"""Error to indicate we cannot connect."""


class InvalidAuth(exceptions.HomeAssistantError):
"""Error to indicate there is invalid auth."""
Taraman17 marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 4 additions & 0 deletions homeassistant/components/homee/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""Constants for the homee integration."""

# General
DOMAIN = "homee"
Loading