예제 #1
0
    def async_on_node_ready(node: ZwaveNode) -> None:
        """Handle node ready event."""
        LOGGER.debug("Processing node %s", node)

        # register (or update) node in device registry
        register_node_in_dev_reg(hass, entry, dev_reg, client, node)

        # run discovery on all node values and create/update entities
        for disc_info in async_discover_values(node):
            LOGGER.debug("Discovered entity: %s", disc_info)

            # This migration logic was added in 2021.3 to handle a breaking change to
            # the value_id format. Some time in the future, this call (as well as the
            # helper functions) can be removed.
            async_migrate_discovered_value(ent_reg, client, disc_info)
            async_dispatcher_send(
                hass, f"{DOMAIN}_{entry.entry_id}_add_{disc_info.platform}",
                disc_info)
        # add listener for stateless node value notification events
        node.on(
            "value notification",
            lambda event: async_on_value_notification(event[
                "value_notification"]),
        )
        # add listener for stateless node notification events
        node.on("notification",
                lambda event: async_on_notification(event["notification"]))
예제 #2
0
    async def async_on_node_ready(node: ZwaveNode) -> None:
        """Handle node ready event."""
        LOGGER.debug("Processing node %s", node)
        # register (or update) node in device registry
        device = register_node_in_dev_reg(
            hass, entry, dev_reg, client, node, remove_device
        )
        # We only want to create the defaultdict once, even on reinterviews
        if device.id not in registered_unique_ids:
            registered_unique_ids[device.id] = defaultdict(set)

        value_updates_disc_info: dict[str, ZwaveDiscoveryInfo] = {}

        # run discovery on all node values and create/update entities
        await asyncio.gather(
            *(
                async_handle_discovery_info(device, disc_info, value_updates_disc_info)
                for disc_info in async_discover_node_values(
                    node, device, discovered_value_ids
                )
            )
        )

        # add listeners to handle new values that get added later
        for event in ("value added", "value updated", "metadata updated"):
            entry.async_on_unload(
                node.on(
                    event,
                    lambda event: hass.async_create_task(
                        async_on_value_added(value_updates_disc_info, event["value"])
                    ),
                )
            )

        # add listener for stateless node value notification events
        entry.async_on_unload(
            node.on(
                "value notification",
                lambda event: async_on_value_notification(event["value_notification"]),
            )
        )
        # add listener for stateless node notification events
        entry.async_on_unload(
            node.on(
                "notification",
                lambda event: async_on_notification(event["notification"]),
            )
        )
예제 #3
0
파일: api.py 프로젝트: MatthiasLohr/core
async def websocket_subscribe_node_statistics(
    hass: HomeAssistant,
    connection: ActiveConnection,
    msg: dict,
    node: Node,
) -> None:
    """Subsribe to the statistics updates for a node."""
    @callback
    def async_cleanup() -> None:
        """Remove signal listeners."""
        for unsub in unsubs:
            unsub()

    @callback
    def forward_stats(event: dict) -> None:
        statistics: NodeStatistics = event["statistics_updated"]
        connection.send_message(
            websocket_api.event_message(
                msg[ID],
                {
                    "event": event["event"],
                    "source": "node",
                    "node_id": node.node_id,
                    **_get_node_statistics_dict(statistics),
                },
            ))

    msg[DATA_UNSUBSCRIBE] = unsubs = [
        node.on("statistics updated", forward_stats)
    ]
    connection.subscriptions[msg["id"]] = async_cleanup

    connection.send_result(msg[ID], _get_node_statistics_dict(node.statistics))
예제 #4
0
파일: __init__.py 프로젝트: jhofker/core-1
    def async_on_node_ready(node: ZwaveNode) -> None:
        """Handle node ready event."""
        LOGGER.debug("Processing node %s", node)

        # register (or update) node in device registry
        register_node_in_dev_reg(hass, entry, dev_reg, client, node)

        # run discovery on all node values and create/update entities
        for disc_info in async_discover_values(node):
            LOGGER.debug("Discovered entity: %s", disc_info)
            async_dispatcher_send(
                hass, f"{DOMAIN}_{entry.entry_id}_add_{disc_info.platform}",
                disc_info)
        # add listener for stateless node value notification events
        node.on(
            "value notification",
            lambda event: async_on_value_notification(event[
                "value_notification"]),
        )
        # add listener for stateless node notification events
        node.on("notification",
                lambda event: async_on_notification(event["notification"]))
예제 #5
0
async def websocket_subscribe_firmware_update_status(
    hass: HomeAssistant,
    connection: ActiveConnection,
    msg: dict,
    node: Node,
) -> None:
    """Subscribe to the status of a firmware update."""

    @callback
    def async_cleanup() -> None:
        """Remove signal listeners."""
        for unsub in unsubs:
            unsub()

    @callback
    def forward_progress(event: dict) -> None:
        progress: FirmwareUpdateProgress = event["firmware_update_progress"]
        connection.send_message(
            websocket_api.event_message(
                msg[ID],
                {
                    "event": event["event"],
                    **_get_firmware_update_progress_dict(progress),
                },
            )
        )

    @callback
    def forward_finished(event: dict) -> None:
        finished: FirmwareUpdateFinished = event["firmware_update_finished"]
        connection.send_message(
            websocket_api.event_message(
                msg[ID],
                {
                    "event": event["event"],
                    "status": finished.status,
                    "wait_time": finished.wait_time,
                },
            )
        )

    msg[DATA_UNSUBSCRIBE] = unsubs = [
        node.on("firmware update progress", forward_progress),
        node.on("firmware update finished", forward_finished),
    ]
    connection.subscriptions[msg["id"]] = async_cleanup

    progress = node.firmware_update_progress
    connection.send_result(
        msg[ID], _get_firmware_update_progress_dict(progress) if progress else None
    )
예제 #6
0
async def websocket_refresh_node_info(
    hass: HomeAssistant,
    connection: ActiveConnection,
    msg: dict,
    node: Node,
) -> None:
    """Re-interview a node."""

    @callback
    def async_cleanup() -> None:
        """Remove signal listeners."""
        for unsub in unsubs:
            unsub()

    @callback
    def forward_event(event: dict) -> None:
        connection.send_message(
            websocket_api.event_message(msg[ID], {"event": event["event"]})
        )

    @callback
    def forward_stage(event: dict) -> None:
        connection.send_message(
            websocket_api.event_message(
                msg[ID], {"event": event["event"], "stage": event["stageName"]}
            )
        )

    connection.subscriptions[msg["id"]] = async_cleanup
    msg[DATA_UNSUBSCRIBE] = unsubs = [
        node.on("interview started", forward_event),
        node.on("interview completed", forward_event),
        node.on("interview stage completed", forward_stage),
        node.on("interview failed", forward_event),
    ]

    result = await node.async_refresh_info()
    connection.send_result(msg[ID], result)
예제 #7
0
async def websocket_subscribe_firmware_update_status(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    node: Node,
) -> None:
    """Subsribe to the status of a firmware update."""

    @callback
    def async_cleanup() -> None:
        """Remove signal listeners."""
        for unsub in unsubs:
            unsub()

    @callback
    def forward_progress(event: dict) -> None:
        progress: FirmwareUpdateProgress = event["firmware_update_progress"]
        connection.send_message(
            websocket_api.event_message(
                msg[ID],
                {
                    "event": event["event"],
                    "sent_fragments": progress.sent_fragments,
                    "total_fragments": progress.total_fragments,
                },
            )
        )

    @callback
    def forward_finished(event: dict) -> None:
        finished: FirmwareUpdateFinished = event["firmware_update_finished"]
        connection.send_message(
            websocket_api.event_message(
                msg[ID],
                {
                    "event": event["event"],
                    "status": finished.status,
                    "wait_time": finished.wait_time,
                },
            )
        )

    unsubs = [
        node.on("firmware update progress", forward_progress),
        node.on("firmware update finished", forward_finished),
    ]
    connection.subscriptions[msg["id"]] = async_cleanup

    connection.send_result(msg[ID])
예제 #8
0
    async def async_on_node_ready(node: ZwaveNode) -> None:
        """Handle node ready event."""
        LOGGER.debug("Processing node %s", node)

        platform_setup_tasks = entry_opp_data[DATA_PLATFORM_SETUP]

        # register (or update) node in device registry
        device = register_node_in_dev_reg(opp, entry, dev_reg, client, node)
        # We only want to create the defaultdict once, even on reinterviews
        if device.id not in registered_unique_ids:
            registered_unique_ids[device.id] = defaultdict(set)

        value_updates_disc_info = []

        # run discovery on all node values and create/update entities
        for disc_info in async_discover_values(node):
            platform = disc_info.platform

            # This migration logic was added in 2021.3 to handle a breaking change to
            # the value_id format. Some time in the future, this call (as well as the
            # helper functions) can be removed.
            async_migrate_discovered_value(
                opp,
                ent_reg,
                registered_unique_ids[device.id][platform],
                device,
                client,
                disc_info,
            )

            if platform not in platform_setup_tasks:
                platform_setup_tasks[platform] = opp.async_create_task(
                    opp.config_entries.async_forward_entry_setup(
                        entry, platform))

            await platform_setup_tasks[platform]

            LOGGER.debug("Discovered entity: %s", disc_info)
            async_dispatcher_send(opp,
                                  f"{DOMAIN}_{entry.entry_id}_add_{platform}",
                                  disc_info)

            # Capture discovery info for values we want to watch for updates
            if disc_info.assumed_state:
                value_updates_disc_info.append(disc_info)

        # add listener for value updated events if necessary
        if value_updates_disc_info:
            unsubscribe_callbacks.append(
                node.on(
                    "value updated",
                    lambda event: async_on_value_updated(
                        value_updates_disc_info, event["value"]),
                ))

        # add listener for stateless node value notification events
        unsubscribe_callbacks.append(
            node.on(
                "value notification",
                lambda event: async_on_value_notification(event[
                    "value_notification"]),
            ))
        # add listener for stateless node notification events
        unsubscribe_callbacks.append(
            node.on(
                "notification",
                lambda event: async_on_notification(event["notification"]),
            ))
예제 #9
0
파일: __init__.py 프로젝트: vog31/core
    def async_on_node_ready(node: ZwaveNode) -> None:
        """Handle node ready event."""
        LOGGER.debug("Processing node %s", node)

        # register (or update) node in device registry
        register_node_in_dev_reg(hass, entry, dev_reg, client, node)

        # run discovery on all node values and create/update entities
        for disc_info in async_discover_values(node):
            LOGGER.debug("Discovered entity: %s", disc_info)

            # This migration logic was added in 2021.3 to handle a breaking change to
            # the value_id format. Some time in the future, this code block
            # (as well as get_old_value_id helper and migrate_entity closure) can be
            # removed.
            value_ids = [
                # 2021.2.* format
                get_old_value_id(disc_info.primary_value),
                # 2021.3.0b0 format
                disc_info.primary_value.value_id,
            ]

            new_unique_id = get_unique_id(
                client.driver.controller.home_id,
                disc_info.primary_value.value_id,
            )

            for value_id in value_ids:
                old_unique_id = get_unique_id(
                    client.driver.controller.home_id,
                    f"{disc_info.primary_value.node.node_id}.{value_id}",
                )
                # Most entities have the same ID format, but notification binary sensors
                # have a state key in their ID so we need to handle them differently
                if (disc_info.platform == "binary_sensor"
                        and disc_info.platform_hint == "notification"):
                    for state_key in disc_info.primary_value.metadata.states:
                        # ignore idle key (0)
                        if state_key == "0":
                            continue

                        migrate_entity(
                            disc_info.platform,
                            f"{old_unique_id}.{state_key}",
                            f"{new_unique_id}.{state_key}",
                        )

                    # Once we've iterated through all state keys, we can move on to the
                    # next item
                    continue

                migrate_entity(disc_info.platform, old_unique_id,
                               new_unique_id)

            async_dispatcher_send(
                hass, f"{DOMAIN}_{entry.entry_id}_add_{disc_info.platform}",
                disc_info)
        # add listener for stateless node value notification events
        node.on(
            "value notification",
            lambda event: async_on_value_notification(event[
                "value_notification"]),
        )
        # add listener for stateless node notification events
        node.on("notification",
                lambda event: async_on_notification(event["notification"]))