106 lines
2.8 KiB
Python
106 lines
2.8 KiB
Python
"""Support for Node-RED discovery."""
|
|
|
|
import logging
|
|
from typing import Any
|
|
|
|
from homeassistant.components.websocket_api.connection import ActiveConnection
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.dispatcher import (
|
|
async_dispatcher_connect,
|
|
async_dispatcher_send,
|
|
)
|
|
|
|
from .const import (
|
|
CONF_BINARY_SENSOR,
|
|
CONF_BUTTON,
|
|
CONF_COMPONENT,
|
|
CONF_NODE_ID,
|
|
CONF_NUMBER,
|
|
CONF_REMOVE,
|
|
CONF_SELECT,
|
|
CONF_SENSOR,
|
|
CONF_SERVER_ID,
|
|
CONF_SWITCH,
|
|
CONF_TEXT,
|
|
CONF_TIME,
|
|
DOMAIN,
|
|
DOMAIN_DATA,
|
|
NODERED_DISCOVERY,
|
|
NODERED_DISCOVERY_NEW,
|
|
NODERED_DISCOVERY_UPDATED,
|
|
)
|
|
|
|
SUPPORTED_COMPONENTS = [
|
|
CONF_BINARY_SENSOR,
|
|
CONF_BUTTON,
|
|
CONF_NUMBER,
|
|
CONF_SELECT,
|
|
CONF_SENSOR,
|
|
CONF_SWITCH,
|
|
CONF_TEXT,
|
|
CONF_TIME,
|
|
]
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
ALREADY_DISCOVERED = "already_discovered"
|
|
CHANGE_ENTITY_TYPE = "change_entity_type"
|
|
PLATFORMS_LOADED = "platforms_loaded"
|
|
DISCOVERY_DISPATCHED = "discovery_dispatched"
|
|
|
|
|
|
async def start_discovery(hass: HomeAssistant, hass_config: dict) -> None:
|
|
"""Initialize of Node-RED Discovery."""
|
|
|
|
async def async_device_message_received(
|
|
msg: dict[str, Any], connection: ActiveConnection
|
|
) -> None:
|
|
"""Process the received message."""
|
|
component = msg[CONF_COMPONENT]
|
|
server_id = msg[CONF_SERVER_ID]
|
|
node_id = msg[CONF_NODE_ID]
|
|
|
|
if component not in SUPPORTED_COMPONENTS:
|
|
_LOGGER.warning("Integration %s is not supported", component)
|
|
return
|
|
|
|
discovery_hash = f"{DOMAIN}-{server_id}-{node_id}"
|
|
data = hass_config
|
|
|
|
_LOGGER.debug("Discovery message: %s", msg)
|
|
|
|
if ALREADY_DISCOVERED not in data:
|
|
data[ALREADY_DISCOVERED] = set()
|
|
|
|
# Check if already discovered
|
|
already_discovered = discovery_hash in data[ALREADY_DISCOVERED]
|
|
|
|
if already_discovered:
|
|
log_text = "Removing" if CONF_REMOVE in msg else "Updating"
|
|
|
|
_LOGGER.info("%s %s %s %s", log_text, component, server_id, node_id)
|
|
|
|
async_dispatcher_send(
|
|
hass, NODERED_DISCOVERY_UPDATED.format(discovery_hash), msg, connection
|
|
)
|
|
else:
|
|
# Add component - ensure platform is set up first
|
|
_LOGGER.info("Creating %s %s %s", component, server_id, node_id)
|
|
|
|
data[ALREADY_DISCOVERED].add(discovery_hash)
|
|
|
|
async_dispatcher_send(
|
|
hass, NODERED_DISCOVERY_NEW.format(component), msg, connection
|
|
)
|
|
|
|
hass.data[DOMAIN_DATA][DISCOVERY_DISPATCHED] = async_dispatcher_connect(
|
|
hass,
|
|
NODERED_DISCOVERY,
|
|
async_device_message_received,
|
|
)
|
|
|
|
|
|
def stop_discovery(hass: HomeAssistant) -> None:
|
|
"""Remove discovery dispatcher."""
|
|
hass.data[DOMAIN_DATA][DISCOVERY_DISPATCHED]()
|