Ejemplo n.º 1
0
async def websocket_subscribe_heal_network_progress(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    entry: ConfigEntry,
    client: Client,
) -> None:
    """Subscribe to heal Z-Wave network status updates."""
    controller = client.driver.controller

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

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

    connection.subscriptions[msg["id"]] = async_cleanup
    unsubs = [
        controller.on("heal network progress", partial(forward_event, "progress")),
        controller.on("heal network done", partial(forward_event, "result")),
    ]

    connection.send_result(msg[ID])
Ejemplo n.º 2
0
async def websocket_get_config_parameters(
    opp: OpenPeerPower, connection: ActiveConnection, msg: dict, node: Node
) -> None:
    """Get a list of configuration parameters for a Z-Wave node."""
    values = node.get_configuration_values()
    result = {}
    for value_id, zwave_value in values.items():
        metadata = zwave_value.metadata
        result[value_id] = {
            "property": zwave_value.property_,
            "property_key": zwave_value.property_key,
            "configuration_value_type": zwave_value.configuration_value_type.value,
            "metadata": {
                "description": metadata.description,
                "label": metadata.label,
                "type": metadata.type,
                "min": metadata.min,
                "max": metadata.max,
                "unit": metadata.unit,
                "writeable": metadata.writeable,
                "readable": metadata.readable,
            },
            "value": zwave_value.value,
        }
        if zwave_value.metadata.states:
            result[value_id]["metadata"]["states"] = zwave_value.metadata.states

    connection.send_result(
        msg[ID],
        result,
    )
Ejemplo n.º 3
0
async def websocket_refresh_node_values(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    node: Node,
) -> None:
    """Refresh node values."""
    await node.async_refresh_values()
    connection.send_result(msg[ID])
Ejemplo n.º 4
0
async def websocket_abort_firmware_update(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    node: Node,
) -> None:
    """Abort a firmware update."""
    await node.async_abort_firmware_update()
    connection.send_result(msg[ID])
Ejemplo n.º 5
0
async def websocket_install_config_update(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    entry: ConfigEntry,
    client: Client,
) -> None:
    """Check for config updates."""
    success = await client.driver.async_install_config_update()
    connection.send_result(msg[ID], success)
Ejemplo n.º 6
0
async def websocket_subscribe(opp: OpenPeerPower, connection: ActiveConnection,
                              msg: dict):
    """Subscribe to supervisor events."""
    @callback
    def forward_messages(data):
        """Forward events to websocket."""
        connection.send_message(websocket_api.event_message(msg[WS_ID], data))

    connection.subscriptions[msg[WS_ID]] = async_dispatcher_connect(
        opp, EVENT_SUPERVISOR_EVENT, forward_messages)
    connection.send_message(websocket_api.result_message(msg[WS_ID]))
Ejemplo n.º 7
0
async def websocket_update_log_config(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    entry: ConfigEntry,
    client: Client,
) -> None:
    """Update the driver log config."""
    await client.driver.async_update_log_config(LogConfig(**msg[CONFIG]))
    connection.send_result(
        msg[ID],
    )
Ejemplo n.º 8
0
async def websocket_ping_node(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    node: Node,
) -> None:
    """Ping a Z-Wave JS node."""
    result = await node.async_ping()
    connection.send_result(
        msg[ID],
        result,
    )
Ejemplo n.º 9
0
async def websocket_get_log_config(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    entry: ConfigEntry,
    client: Client,
) -> None:
    """Get log configuration for the Z-Wave JS driver."""
    result = await client.driver.async_get_log_config()
    connection.send_result(
        msg[ID],
        dataclasses.asdict(result),
    )
Ejemplo n.º 10
0
async def websocket_data_collection_status(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    entry: ConfigEntry,
    client: Client,
) -> None:
    """Return data collection preference and status."""
    result = {
        OPTED_IN: entry.data.get(CONF_DATA_COLLECTION_OPTED_IN),
        ENABLED: await client.driver.async_is_statistics_enabled(),
    }
    connection.send_result(msg[ID], result)
Ejemplo n.º 11
0
async def websocket_stop_healing_network(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    entry: ConfigEntry,
    client: Client,
) -> None:
    """Stop healing the Z-Wave network."""
    controller = client.driver.controller
    result = await controller.async_stop_healing_network()
    connection.send_result(
        msg[ID],
        result,
    )
Ejemplo n.º 12
0
async def websocket_network_adapters(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
) -> None:
    """Return network preferences."""
    network: Network = opp.data[DOMAIN]
    connection.send_result(
        msg["id"],
        {
            ATTR_ADAPTERS: network.adapters,
            ATTR_CONFIGURED_ADAPTERS: network.configured_adapters,
        },
    )
Ejemplo n.º 13
0
async def websocket_stop_exclusion(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    entry: ConfigEntry,
    client: Client,
) -> None:
    """Cancel removing a node from the Z-Wave network."""
    controller = client.driver.controller
    result = await controller.async_stop_exclusion()
    connection.send_result(
        msg[ID],
        result,
    )
Ejemplo n.º 14
0
async def websocket_network_adapters_configure(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
) -> None:
    """Update network config."""
    network: Network = opp.data[DOMAIN]

    await network.async_reconfig(msg["config"])

    connection.send_result(
        msg["id"],
        {ATTR_CONFIGURED_ADAPTERS: network.configured_adapters},
    )
Ejemplo n.º 15
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])
Ejemplo n.º 16
0
    async def async_get_node_func(
        opp: OpenPeerPower,
        connection: ActiveConnection,
        msg: dict,
        entry: ConfigEntry,
        client: Client,
    ) -> None:
        """Provide user specific data and store to function."""
        node_id = msg[NODE_ID]
        node = client.driver.controller.nodes.get(node_id)

        if node is None:
            connection.send_error(msg[ID], ERR_NOT_FOUND, f"Node {node_id} not found")
            return
        await orig_func(opp, connection, msg, node)
Ejemplo n.º 17
0
async def websocket_heal_node(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    entry: ConfigEntry,
    client: Client,
) -> None:
    """Heal a node on the Z-Wave network."""
    controller = client.driver.controller
    node_id = msg[NODE_ID]
    result = await controller.async_heal_node(node_id)
    connection.send_result(
        msg[ID],
        result,
    )
Ejemplo n.º 18
0
async def websocket_remove_node(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    entry: ConfigEntry,
    client: Client,
) -> None:
    """Remove a node from the Z-Wave network."""
    controller = client.driver.controller

    @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 node_removed(event: dict) -> None:
        node = event["node"]
        node_details = {
            "node_id": node.node_id,
        }

        connection.send_message(
            websocket_api.event_message(
                msg[ID], {"event": "node removed", "node": node_details}
            )
        )

    connection.subscriptions[msg["id"]] = async_cleanup
    unsubs = [
        controller.on("exclusion started", forward_event),
        controller.on("exclusion failed", forward_event),
        controller.on("exclusion stopped", forward_event),
        controller.on("node removed", node_removed),
    ]

    result = await controller.async_begin_exclusion()
    connection.send_result(
        msg[ID],
        result,
    )
Ejemplo n.º 19
0
async def websocket_check_for_config_updates(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    entry: ConfigEntry,
    client: Client,
) -> None:
    """Check for config updates."""
    config_update = await client.driver.async_check_for_config_updates()
    connection.send_result(
        msg[ID],
        {
            "update_available": config_update.update_available,
            "new_version": config_update.new_version,
        },
    )
Ejemplo n.º 20
0
async def websocket_node_status(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    node: Node,
) -> None:
    """Get the status of a Z-Wave JS node."""
    data = {
        "node_id": node.node_id,
        "is_routing": node.is_routing,
        "status": node.status,
        "is_secure": node.is_secure,
        "ready": node.ready,
    }
    connection.send_result(
        msg[ID],
        data,
    )
Ejemplo n.º 21
0
async def websocket_update_data_collection_preference(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    entry: ConfigEntry,
    client: Client,
) -> None:
    """Update preference for data collection and enable/disable collection."""
    opted_in = msg[OPTED_IN]
    update_data_collection_preference(opp, entry, opted_in)

    if opted_in:
        await async_enable_statistics(client)
    else:
        await client.driver.async_disable_statistics()

    connection.send_result(
        msg[ID],
    )
Ejemplo n.º 22
0
async def websocket_refresh_node_cc_values(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    node: Node,
) -> None:
    """Refresh node values for a particular CommandClass."""
    command_class_id = msg[COMMAND_CLASS_ID]

    try:
        command_class = CommandClass(command_class_id)
    except ValueError:
        connection.send_error(
            msg[ID], ERR_NOT_FOUND, f"Command class {command_class_id} not found"
        )
        return

    await node.async_refresh_cc_values(command_class)
    connection.send_result(msg[ID])
Ejemplo n.º 23
0
async def websocket_network_status(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    entry: ConfigEntry,
    client: Client,
) -> None:
    """Get the status of the Z-Wave JS network."""
    controller = client.driver.controller
    data = {
        "client": {
            "ws_server_url": client.ws_server_url,
            "state": "connected" if client.connected else "disconnected",
            "driver_version": client.version.driver_version,
            "server_version": client.version.server_version,
        },
        "controller": {
            "home_id": controller.home_id,
            "library_version": controller.library_version,
            "type": controller.controller_type,
            "own_node_id": controller.own_node_id,
            "is_secondary": controller.is_secondary,
            "is_using_home_id_from_other_network": controller.is_using_home_id_from_other_network,
            "is_sis_present": controller.is_SIS_present,
            "was_real_primary": controller.was_real_primary,
            "is_static_update_controller": controller.is_static_update_controller,
            "is_slave": controller.is_slave,
            "serial_api_version": controller.serial_api_version,
            "manufacturer_id": controller.manufacturer_id,
            "product_id": controller.product_id,
            "product_type": controller.product_type,
            "supported_function_types": controller.supported_function_types,
            "suc_node_id": controller.suc_node_id,
            "supports_timers": controller.supports_timers,
            "is_heal_network_active": controller.is_heal_network_active,
            "nodes": list(client.driver.controller.nodes),
        },
    }
    connection.send_result(
        msg[ID],
        data,
    )
Ejemplo n.º 24
0
    async def async_get_entry_func(
        opp: OpenPeerPower, connection: ActiveConnection, msg: dict
    ) -> None:
        """Provide user specific data and store to function."""
        entry_id = msg[ENTRY_ID]
        entry = opp.config_entries.async_get_entry(entry_id)
        if entry is None:
            connection.send_error(
                msg[ID], ERR_NOT_FOUND, f"Config entry {entry_id} not found"
            )
            return

        if entry.state is not ConfigEntryState.LOADED:
            connection.send_error(
                msg[ID], ERR_NOT_LOADED, f"Config entry {entry_id} not loaded"
            )
            return

        client = opp.data[DOMAIN][entry_id][DATA_CLIENT]
        await orig_func(opp, connection, msg, entry, client)
Ejemplo n.º 25
0
async def websocket_node_metadata(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    node: Node,
) -> None:
    """Get the metadata of a Z-Wave JS node."""
    data = {
        "node_id": node.node_id,
        "exclusion": node.device_config.metadata.exclusion,
        "inclusion": node.device_config.metadata.inclusion,
        "manual": node.device_config.metadata.manual,
        "wakeup": node.device_config.metadata.wakeup,
        "reset": node.device_config.metadata.reset,
        "device_database_url": node.device_database_url,
    }
    connection.send_result(
        msg[ID],
        data,
    )
Ejemplo n.º 26
0
async def websocket_supervisor_api(opp: OpenPeerPower,
                                   connection: ActiveConnection, msg: dict):
    """Websocket handler to call Supervisor API."""
    supervisor: OppIO = opp.data[DOMAIN]
    try:
        result = await supervisor.send_command(
            msg[ATTR_ENDPOINT],
            method=msg[ATTR_METHOD],
            timeout=msg.get(ATTR_TIMEOUT, 10),
            payload=msg.get(ATTR_DATA, {}),
        )

        if result.get(ATTR_RESULT) == "error":
            raise opp.components.oppio.OppioAPIError(result.get("message"))
    except opp.components.oppio.OppioAPIError as err:
        _LOGGER.error("Failed to to call %s - %s", msg[ATTR_ENDPOINT], err)
        connection.send_error(msg[WS_ID],
                              code=websocket_api.ERR_UNKNOWN_ERROR,
                              message=str(err))
    else:
        connection.send_result(msg[WS_ID], result.get(ATTR_DATA, {}))
Ejemplo n.º 27
0
async def websocket_refresh_node_info(
    opp: OpenPeerPower,
    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
    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)
Ejemplo n.º 28
0
async def websocket_remove_failed_node(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    entry: ConfigEntry,
    client: Client,
) -> None:
    """Remove a failed node from the Z-Wave network."""
    controller = client.driver.controller
    node_id = msg[NODE_ID]

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

    @callback
    def node_removed(event: dict) -> None:
        node = event["node"]
        node_details = {
            "node_id": node.node_id,
        }

        connection.send_message(
            websocket_api.event_message(
                msg[ID], {"event": "node removed", "node": node_details}
            )
        )

    connection.subscriptions[msg["id"]] = async_cleanup
    unsub = controller.on("node removed", node_removed)

    result = await controller.async_remove_failed_node(node_id)
    connection.send_result(
        msg[ID],
        result,
    )
Ejemplo n.º 29
0
async def websocket_subscribe_logs(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    entry: ConfigEntry,
    client: Client,
) -> None:
    """Subscribe to log message events from the server."""
    driver = client.driver

    @callback
    def async_cleanup() -> None:
        """Remove signal listeners."""
        opp.async_create_task(driver.async_stop_listening_logs())
        unsub()

    @callback
    def forward_event(event: dict) -> None:
        log_msg: LogMessage = event["log_message"]
        connection.send_message(
            websocket_api.event_message(
                msg[ID],
                {
                    "timestamp": log_msg.timestamp,
                    "level": log_msg.level,
                    "primary_tags": log_msg.primary_tags,
                    "message": log_msg.formatted_message,
                },
            )
        )

    unsub = driver.on("logging", forward_event)
    connection.subscriptions[msg["id"]] = async_cleanup

    await driver.async_start_listening_logs()
    connection.send_result(msg[ID])
Ejemplo n.º 30
0
async def websocket_set_config_parameter(
    opp: OpenPeerPower,
    connection: ActiveConnection,
    msg: dict,
    node: Node,
) -> None:
    """Set a config parameter value for a Z-Wave node."""
    property_ = msg[PROPERTY]
    property_key = msg.get(PROPERTY_KEY)
    value = msg[VALUE]

    try:
        zwave_value, cmd_status = await async_set_config_parameter(
            node, value, property_, property_key=property_key
        )
    except (InvalidNewValue, NotFoundError, NotImplementedError, SetValueFailed) as err:
        code = ERR_UNKNOWN_ERROR
        if isinstance(err, NotFoundError):
            code = ERR_NOT_FOUND
        elif isinstance(err, (InvalidNewValue, NotImplementedError)):
            code = ERR_NOT_SUPPORTED

        connection.send_error(
            msg[ID],
            code,
            str(err),
        )
        return

    connection.send_result(
        msg[ID],
        {
            VALUE_ID: zwave_value.value_id,
            STATUS: cmd_status,
        },
    )