nasWebio ed1366f463
Add NASweb integration (#98118)
* Add NASweb integration

* Fix DeviceInfo import

* Remove commented out code

* Change class name for uniquness

* Drop CoordinatorEntity inheritance

* Rename class Output to more descriptive: RelaySwitch

* Update required webio-api version

* Implement on-the-fly addition/removal of entities

* Set coordinator name matching device name

* Set entities with too old status as unavailable

* Drop Optional in favor of modern typing

* Fix spelling of a variable

* Rename commons to more fitting name: helper

* Remove redundant code

* Let unload fail when there is no coordinator

* Fix bad docstring

* Rename cord to coordinator for clarity

* Remove default value for pop and let it raise exception

* Drop workaround and use get_url from helper.network

* Use webhook to send data from device

* Deinitialize coordinator when no longer needed

* Use Python formattable string

* Use dataclass to store integration data in hass.data

* Raise ConfigEntryNotReady when appropriate

* Refactor NASwebData class

* Move RelaySwitch to switch.py

* Fix ConfigFlow tests

* Create issues when entry fails to load

* Respond when correctly received status update

* Depend on webhook instead of http

* Create issue when status is not received during entry set up

* Make issue_id unique across integration entries

* Remove unnecessary initializations

* Inherit CoordinatorEntity to avoid code duplication

* Optimize property access via assignment in __init__

* Use preexisting mechanism to fill schema with user input

* Fix translation strings

* Handle unavailable or unreachable internal url

* Implement custom coordinator for push driven data updates

* Move module-specific constants to respective modules

* Fix requirements_all.txt

* Fix CODEOWNERS file

* Raise ConfigEntryError instead of issue creation

* Fix entity registry import

* Use HassKey as key in hass.data

* Use typed ConfigEntry

* Store runtime data in config entry

* Rewrite to be more Pythonic

* Move add/remove of switch entities to switch.py

* Skip unnecessary check

* Remove unnecessary type hints

* Remove unnecessary nonlocal

* Use a more descriptive docstring

* Add docstrings to NASwebCoordinator

* Fix formatting

* Use correct return type

* Fix tests to align with changed code

* Remove commented code

* Use serial number as config entry id

* Catch AbortFlow exception

* Update tests to check ConfigEntry Unique ID

* Remove unnecessary form abort
2024-11-08 12:03:32 +01:00

65 lines
2.0 KiB
Python

"""Dataclass storing integration data in hass.data[DOMAIN]."""
from dataclasses import dataclass, field
import logging
from aiohttp.hdrs import METH_POST
from homeassistant.components.webhook import (
async_generate_id,
async_register as webhook_register,
async_unregister as webhook_unregister,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.network import get_url
from .const import DOMAIN, WEBHOOK_URL
from .coordinator import NotificationCoordinator
_LOGGER = logging.getLogger(__name__)
@dataclass
class NASwebData:
"""Class storing integration data."""
notify_coordinator: NotificationCoordinator = field(
default_factory=NotificationCoordinator
)
webhook_id = ""
def is_initialized(self) -> bool:
"""Return True if instance was initialized and is ready for use."""
return bool(self.webhook_id)
def can_be_deinitialized(self) -> bool:
"""Return whether this instance can be deinitialized."""
return not self.notify_coordinator.has_coordinators()
def initialize(self, hass: HomeAssistant) -> None:
"""Initialize NASwebData instance."""
if self.is_initialized():
return
new_webhook_id = async_generate_id()
webhook_register(
hass,
DOMAIN,
"NASweb",
new_webhook_id,
self.notify_coordinator.handle_webhook_request,
allowed_methods=[METH_POST],
)
self.webhook_id = new_webhook_id
_LOGGER.debug("Registered webhook: %s", self.webhook_id)
def deinitialize(self, hass: HomeAssistant) -> None:
"""Deinitialize NASwebData instance."""
if not self.is_initialized():
return
webhook_unregister(hass, self.webhook_id)
def get_webhook_url(self, hass: HomeAssistant) -> str:
"""Return webhook url for Push API."""
hass_url = get_url(hass, allow_external=False)
return WEBHOOK_URL.format(internal_url=hass_url, webhook_id=self.webhook_id)