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), )
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" )
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)
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)
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})
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, )
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])
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, )
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(), )
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")
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, }, )
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, )
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, {}))