Exemple #1
0
async def websocket_set_config_parameter(hass: HomeAssistant,
                                         connection: ActiveConnection,
                                         msg: dict) -> None:
    """Set a config parameter value for a Z-Wave node."""
    entry_id = msg[ENTRY_ID]
    node_id = msg[NODE_ID]
    property_ = msg[PROPERTY]
    property_key = msg.get(PROPERTY_KEY)
    value = msg[VALUE]
    client = hass.data[DOMAIN][entry_id][DATA_CLIENT]
    node = client.driver.controller.nodes[node_id]
    try:
        result = 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],
        str(result),
    )
Exemple #2
0
 async def with_error_handling(
     hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any]
 ) -> None:
     try:
         await func(hass, connection, msg)
     except DeviceNotFound:
         connection.send_error(
             msg["id"], websocket_api.const.ERR_NOT_FOUND, "Device not found"
         )
Exemple #3
0
def websocket_remove_device(hass: HomeAssistant, connection: ActiveConnection,
                            msg: dict) -> None:
    """Delete device."""
    device_id = msg["device_id"]
    dev_registry = dr.async_get(hass)

    if not (device := dev_registry.async_get(device_id)):
        connection.send_error(msg["id"], websocket_api.const.ERR_NOT_FOUND,
                              "Device not found")
        return
    async def async_get_mass_func(hass: HomeAssistant,
                                  connection: ActiveConnection,
                                  msg: dict) -> None:
        """Lookup mass object in hass data and provide to function."""
        mass = hass.data.get(DOMAIN)
        if mass is None:
            connection.send_error(msg[ID], ERR_NOT_LOADED,
                                  "Music Assistant is not (yet) loaded")
            return

        await orig_func(hass, connection, msg, mass)
Exemple #5
0
 async def async_get_entry_func(hass: HomeAssistant,
                                connection: ActiveConnection,
                                msg: dict) -> None:
     """Provide user specific data and store to function."""
     entry_id = msg[ENTRY_ID]
     entry = hass.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
     client = hass.data[DOMAIN][entry_id][DATA_CLIENT]
     await orig_func(hass, connection, msg, entry, client)
Exemple #6
0
    async def async_get_node_func(
        hass: HomeAssistant,
        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(hass, connection, msg, node)
async def websocket_get_version(
    hass: HomeAssistant, connection: ActiveConnection, msg: dict
) -> None:
    """Handle get version command."""
    integration = await async_get_integration(hass, "frontend")

    frontend = None

    for req in integration.requirements:
        if req.startswith("home-assistant-frontend=="):
            frontend = req.split("==", 1)[1]

    if frontend is None:
        connection.send_error(msg["id"], "unknown_version", "Version not found")
    else:
        connection.send_result(msg["id"], {"version": frontend})
Exemple #8
0
 async def async_handle_failed_command_func(
     hass: HomeAssistant,
     connection: ActiveConnection,
     msg: dict,
     *args: Any,
     **kwargs: Any,
 ) -> None:
     """Handle FailedCommand within function and send relevant error."""
     try:
         await orig_func(hass, connection, msg, *args, **kwargs)
     except FailedCommand as err:
         # Unsubscribe to callbacks
         if unsubs := msg.get(DATA_UNSUBSCRIBE):
             for unsub in unsubs:
                 unsub()
         connection.send_error(msg[ID], err.error_code, err.args[0])
async def websocket_library_remove(
    hass: HomeAssistant,
    connection: ActiveConnection,
    msg: dict,
    mass: MusicAssistant,
) -> None:
    """Remove item from library."""
    item = await mass.music.get_item_by_uri(msg[URI])
    if not item:
        connection.send_error(msg[ID], ERR_NOT_FOUND, f"Item not found: {msg[URI]}")

    await mass.music.remove_from_library(item.media_type, item.item_id, item.provider)

    connection.send_result(
        msg[ID],
        "OK",
    )
async def websocket_playerqueue_items(
    hass: HomeAssistant,
    connection: ActiveConnection,
    msg: dict,
    mass: MusicAssistant,
) -> None:
    """Return player queue items."""
    queue = mass.players.get_player_queue(msg[QUEUE_ID])
    if queue is None:
        connection.send_error(msg[ID], ERR_NOT_FOUND,
                              f"Queue not found: {msg[QUEUE_ID]}")
        return
    result = [x.to_dict() for x in queue.items]

    await connection.send_big_result(
        msg[ID],
        result,
    )
async def websocket_playerqueue(
    hass: HomeAssistant,
    connection: ActiveConnection,
    msg: dict,
    mass: MusicAssistant,
) -> None:
    """Return single player queue details by id."""
    item = mass.players.get_player_queue(msg[QUEUE_ID])
    if item is None:
        connection.send_error(msg[ID], ERR_NOT_FOUND,
                              f"Queue not found: {msg[QUEUE_ID]}")
        return
    result = item.to_dict()

    connection.send_result(
        msg[ID],
        result,
    )
Exemple #12
0
async def websocket_refresh_node_cc_values(
    hass: HomeAssistant,
    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])
Exemple #13
0
def websocket_get_config_parameters(hass: HomeAssistant,
                                    connection: ActiveConnection,
                                    msg: dict) -> None:
    """Get a list of configuration parameters for a Z-Wave node."""
    entry_id = msg[ENTRY_ID]
    node_id = msg[NODE_ID]
    client = hass.data[DOMAIN][entry_id][DATA_CLIENT]
    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

    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,
    )
Exemple #14
0
async def websocket_supervisor_api(
    hass: HomeAssistant, connection: ActiveConnection, msg: dict
):
    """Websocket handler to call Supervisor API."""
    supervisor: HassIO = hass.data[DOMAIN]
    result = False
    try:
        result = await supervisor.send_command(
            msg[ATTR_ENDPOINT],
            method=msg[ATTR_METHOD],
            timeout=msg.get(ATTR_TIMEOUT, 10),
            payload=msg.get(ATTR_DATA, {}),
        )
    except hass.components.hassio.HassioAPIError 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, {}))
async def websocket_playlist(
    hass: HomeAssistant,
    connection: ActiveConnection,
    msg: dict,
    mass: MusicAssistant,
) -> None:
    """Return track."""
    item = await mass.music.playlists.get(
        msg[ITEM_ID], msg[PROVIDER], lazy=msg[LAZY], force_refresh=msg[REFRESH]
    )
    if item is None:
        connection.send_error(
            msg[ID],
            ERR_NOT_FOUND,
            f"playlist not found: {msg[PROVIDER]}/{msg[ITEM_ID]}",
        )
        return
    connection.send_result(
        msg[ID],
        item.to_dict(),
    )
Exemple #16
0
async def websocket_remove_device(hass: HomeAssistant,
                                  connection: ActiveConnection,
                                  msg: dict) -> None:
    """Delete device."""
    device_id = msg["device_id"]
    dev_registry = await hass.helpers.device_registry.async_get_registry()

    device = dev_registry.async_get(device_id)
    if not device:
        connection.send_error(msg["id"], websocket_api.const.ERR_NOT_FOUND,
                              "Device not found")
        return

    for config_entry in device.config_entries:
        config_entry = hass.config_entries.async_get_entry(config_entry)
        # Only delete the device if it belongs to a Tasmota device entry
        if config_entry.domain == DOMAIN:
            dev_registry.async_remove_device(device_id)
            connection.send_message(websocket_api.result_message(msg["id"]))
            return

    connection.send_error(msg["id"], websocket_api.const.ERR_NOT_FOUND,
                          "Non Tasmota device")
Exemple #17
0
async def websocket_set_config_parameter(
    hass: HomeAssistant,
    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,
        },
    )
Exemple #18
0
def websocket_node_status(
    hass: HomeAssistant, connection: ActiveConnection, msg: dict
) -> None:
    """Get the status of a Z-Wave JS node."""
    entry_id = msg[ENTRY_ID]
    client = hass.data[DOMAIN][entry_id][DATA_CLIENT]
    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

    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,
    )
Exemple #19
0
async def websocket_supervisor_api(hass: HomeAssistant,
                                   connection: ActiveConnection, msg: dict):
    """Websocket handler to call Supervisor API."""
    if not connection.user.is_admin and not WS_NO_ADMIN_ENDPOINTS.match(
            msg[ATTR_ENDPOINT]):
        raise Unauthorized()
    supervisor: HassIO = hass.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 HassioAPIError(result.get("message"))
    except HassioAPIError 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, {}))