Esempio n. 1
0
async def ws_get_statistics_during_period(
    opp: OpenPeerPower, connection: websocket_api.ActiveConnection, msg: dict
) -> None:
    """Handle statistics websocket command."""
    start_time_str = msg["start_time"]
    end_time_str = msg.get("end_time")

    start_time = dt_util.parse_datetime(start_time_str)
    if start_time:
        start_time = dt_util.as_utc(start_time)
    else:
        connection.send_error(msg["id"], "invalid_start_time", "Invalid start_time")
        return

    if end_time_str:
        end_time = dt_util.parse_datetime(end_time_str)
        if end_time:
            end_time = dt_util.as_utc(end_time)
        else:
            connection.send_error(msg["id"], "invalid_end_time", "Invalid end_time")
            return
    else:
        end_time = None

    statistics = await opp.async_add_executor_job(
        statistics_during_period,
        opp,
        start_time,
        end_time,
        msg.get("statistic_id"),
    )
    connection.send_result(msg["id"], {"statistics": statistics})
Esempio n. 2
0
    async def ws_update_item(self, opp: OpenPeerPower,
                             connection: websocket_api.ActiveConnection,
                             msg: dict) -> None:
        """Update a item."""
        data = dict(msg)
        msg_id = data.pop("id")
        item_id = data.pop(self.item_id_key)
        data.pop("type")

        try:
            item = await self.storage_collection.async_update_item(
                item_id, data)
            connection.send_result(msg_id, item)
        except ItemNotFound:
            connection.send_error(
                msg["id"],
                websocket_api.const.ERR_NOT_FOUND,
                f"Unable to find {self.item_id_key} {item_id}",
            )
        except vol.Invalid as err:
            connection.send_error(
                msg["id"],
                websocket_api.const.ERR_INVALID_FORMAT,
                humanize_error(data, err),
            )
        except ValueError as err:
            connection.send_error(msg_id,
                                  websocket_api.const.ERR_INVALID_FORMAT,
                                  str(err))
Esempio n. 3
0
def ws_list_person(opp: OpenPeerPowerType,
                   connection: websocket_api.ActiveConnection, msg):
    """List persons."""
    yaml, storage = opp.data[DOMAIN]
    connection.send_result(msg[ATTR_ID], {
        "storage": storage.async_items(),
        "config": yaml.async_items()
    })
Esempio n. 4
0
async def websocket_update_prefs(
    opp: OpenPeerPower, connection: ActiveConnection, msg: dict
) -> None:
    """Handle request for account info."""
    prefs = opp.data[DATA_CAMERA_PREFS]

    changes = dict(msg)
    changes.pop("id")
    changes.pop("type")
    entity_id = changes.pop("entity_id")
    await prefs.async_update(entity_id, **changes)

    connection.send_result(msg["id"], prefs.get(entity_id).as_dict())
Esempio n. 5
0
    async def ws_delete_item(self, opp: OpenPeerPower,
                             connection: websocket_api.ActiveConnection,
                             msg: dict) -> None:
        """Delete a item."""
        try:
            await self.storage_collection.async_delete_item(
                msg[self.item_id_key])
        except ItemNotFound:
            connection.send_error(
                msg["id"],
                websocket_api.const.ERR_NOT_FOUND,
                f"Unable to find {self.item_id_key} {msg[self.item_id_key]}",
            )

        connection.send_result(msg["id"])
Esempio n. 6
0
 async def ws_create_item(self, opp: OpenPeerPower,
                          connection: websocket_api.ActiveConnection,
                          msg: dict) -> None:
     """Create a item."""
     try:
         data = dict(msg)
         data.pop("id")
         data.pop("type")
         item = await self.storage_collection.async_create_item(data)
         connection.send_result(msg["id"], item)
     except vol.Invalid as err:
         connection.send_error(
             msg["id"],
             websocket_api.const.ERR_INVALID_FORMAT,
             humanize_error(data, err),
         )
     except ValueError as err:
         connection.send_error(msg["id"],
                               websocket_api.const.ERR_INVALID_FORMAT,
                               str(err))
Esempio n. 7
0
async def ws_camera_stream(
    opp: OpenPeerPower, connection: ActiveConnection, msg: dict
) -> None:
    """Handle get camera stream websocket command.

    Async friendly.
    """
    try:
        entity_id = msg["entity_id"]
        camera = _get_camera_from_entity_id(opp, entity_id)
        url = await _async_stream_endpoint_url(opp, camera, fmt=msg["format"])
        connection.send_result(msg["id"], {"url": url})
    except OpenPeerPowerError as ex:
        _LOGGER.error("Error requesting stream: %s", ex)
        connection.send_error(msg["id"], "start_stream_failed", str(ex))
    except asyncio.TimeoutError:
        _LOGGER.error("Timeout getting stream source")
        connection.send_error(
            msg["id"], "start_stream_failed", "Timeout getting stream source"
        )
Esempio n. 8
0
 def ws_list_item(self, opp: OpenPeerPower,
                  connection: websocket_api.ActiveConnection,
                  msg: dict) -> None:
     """List items."""
     connection.send_result(msg["id"],
                            self.storage_collection.async_items())
Esempio n. 9
0
async def handle_info(opp: OpenPeerPower,
                      connection: websocket_api.ActiveConnection, msg: dict):
    """Handle an info request via a subscription."""
    registrations: dict[str, SystemHealthRegistration] = opp.data[DOMAIN]
    data = {}
    pending_info = {}

    for domain, domain_data in zip(
            registrations,
            await
            asyncio.gather(*(get_integration_info(opp, registration)
                             for registration in registrations.values())),
    ):
        for key, value in domain_data["info"].items():
            if asyncio.iscoroutine(value):
                value = asyncio.create_task(value)
            if isinstance(value, asyncio.Task):
                pending_info[(domain, key)] = value
                domain_data["info"][key] = {"type": "pending"}
            else:
                domain_data["info"][key] = _format_value(value)

        data[domain] = domain_data

    # Confirm subscription
    connection.send_result(msg["id"])

    stop_event = asyncio.Event()
    connection.subscriptions[msg["id"]] = stop_event.set

    # Send initial data
    connection.send_message(
        websocket_api.messages.event_message(msg["id"], {
            "type": "initial",
            "data": data
        }))

    # If nothing pending, wrap it up.
    if not pending_info:
        connection.send_message(
            websocket_api.messages.event_message(msg["id"],
                                                 {"type": "finish"}))
        return

    tasks = [asyncio.create_task(stop_event.wait()), *pending_info.values()]
    pending_lookup = {val: key for key, val in pending_info.items()}

    # One task is the stop_event.wait() and is always there
    while len(tasks) > 1 and not stop_event.is_set():
        # Wait for first completed task
        done, tasks = await asyncio.wait(tasks,
                                         return_when=asyncio.FIRST_COMPLETED)

        if stop_event.is_set():
            for task in tasks:
                task.cancel()
            return

        # Update subscription of all finished tasks
        for result in done:
            domain, key = pending_lookup[result]
            event_msg = {
                "type": "update",
                "domain": domain,
                "key": key,
            }

            if result.exception():
                exception = result.exception()
                _LOGGER.error(
                    "Error fetching system info for %s - %s",
                    domain,
                    key,
                    exc_info=(type(exception), exception,
                              exception.__traceback__),
                )
                event_msg["success"] = False
                event_msg["error"] = {"type": "failed", "error": "unknown"}
            else:
                event_msg["success"] = True
                event_msg["data"] = _format_value(result.result())

            connection.send_message(
                websocket_api.messages.event_message(msg["id"], event_msg))

    connection.send_message(
        websocket_api.messages.event_message(msg["id"], {"type": "finish"}))
Esempio n. 10
0
async def websocket_get_prefs(
    opp: OpenPeerPower, connection: ActiveConnection, msg: dict
) -> None:
    """Handle request for account info."""
    prefs = opp.data[DATA_CAMERA_PREFS].get(msg["entity_id"])
    connection.send_result(msg["id"], prefs.as_dict())