Add processes services to System Bridge (#103564)
* Add processes services to System Bridge * Update import and fixes from model updates * Change log level from info to debug for process retrieval * Add exception handling for process not found * Consistency * Change HomeAssistantError to ServiceValidationError * Update homeassistant/components/system_bridge/__init__.py --------- Co-authored-by: Erik Montnemery <erik@montnemery.com>pull/113236/head
parent
0ccd813a99
commit
081a38a21c
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
|||
import asyncio
|
||||
from dataclasses import asdict
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from systembridgeconnector.exceptions import (
|
||||
AuthenticationException,
|
||||
|
@ -14,6 +15,7 @@ from systembridgeconnector.exceptions import (
|
|||
from systembridgeconnector.version import Version
|
||||
from systembridgemodels.keyboard_key import KeyboardKey
|
||||
from systembridgemodels.keyboard_text import KeyboardText
|
||||
from systembridgemodels.modules.processes import Process
|
||||
from systembridgemodels.open_path import OpenPath
|
||||
from systembridgemodels.open_url import OpenUrl
|
||||
import voluptuous as vol
|
||||
|
@ -24,6 +26,7 @@ from homeassistant.const import (
|
|||
CONF_COMMAND,
|
||||
CONF_ENTITY_ID,
|
||||
CONF_HOST,
|
||||
CONF_ID,
|
||||
CONF_NAME,
|
||||
CONF_PATH,
|
||||
CONF_PORT,
|
||||
|
@ -37,7 +40,11 @@ from homeassistant.core import (
|
|||
ServiceResponse,
|
||||
SupportsResponse,
|
||||
)
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
from homeassistant.exceptions import (
|
||||
ConfigEntryAuthFailed,
|
||||
ConfigEntryNotReady,
|
||||
ServiceValidationError,
|
||||
)
|
||||
from homeassistant.helpers import (
|
||||
config_validation as cv,
|
||||
device_registry as dr,
|
||||
|
@ -64,6 +71,8 @@ CONF_BRIDGE = "bridge"
|
|||
CONF_KEY = "key"
|
||||
CONF_TEXT = "text"
|
||||
|
||||
SERVICE_GET_PROCESS_BY_ID = "get_process_by_id"
|
||||
SERVICE_GET_PROCESSES_BY_NAME = "get_processes_by_name"
|
||||
SERVICE_OPEN_PATH = "open_path"
|
||||
SERVICE_POWER_COMMAND = "power_command"
|
||||
SERVICE_OPEN_URL = "open_url"
|
||||
|
@ -202,6 +211,52 @@ async def async_setup_entry(
|
|||
raise vol.Invalid(f"Could not find device {device}") from exception
|
||||
raise vol.Invalid(f"Device {device} does not exist")
|
||||
|
||||
async def handle_get_process_by_id(service_call: ServiceCall) -> ServiceResponse:
|
||||
"""Handle the get process by id service call."""
|
||||
_LOGGER.debug("Get process by id: %s", service_call.data)
|
||||
coordinator: SystemBridgeDataUpdateCoordinator = hass.data[DOMAIN][
|
||||
service_call.data[CONF_BRIDGE]
|
||||
]
|
||||
processes: list[Process] = coordinator.data.processes
|
||||
|
||||
# Find process.id from list, raise ServiceValidationError if not found
|
||||
try:
|
||||
return asdict(
|
||||
next(
|
||||
process
|
||||
for process in processes
|
||||
if process.id == service_call.data[CONF_ID]
|
||||
)
|
||||
)
|
||||
except StopIteration as exception:
|
||||
raise ServiceValidationError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="process_not_found",
|
||||
translation_placeholders={"id": service_call.data[CONF_ID]},
|
||||
) from exception
|
||||
|
||||
async def handle_get_processes_by_name(
|
||||
service_call: ServiceCall,
|
||||
) -> ServiceResponse:
|
||||
"""Handle the get process by name service call."""
|
||||
_LOGGER.debug("Get process by name: %s", service_call.data)
|
||||
coordinator: SystemBridgeDataUpdateCoordinator = hass.data[DOMAIN][
|
||||
service_call.data[CONF_BRIDGE]
|
||||
]
|
||||
processes: list[Process] = coordinator.data.processes
|
||||
# Find processes from list
|
||||
items: list[dict[str, Any]] = [
|
||||
asdict(process)
|
||||
for process in processes
|
||||
if process.name is not None
|
||||
and service_call.data[CONF_NAME].lower() in process.name.lower()
|
||||
]
|
||||
|
||||
return {
|
||||
"count": len(items),
|
||||
"processes": list(items),
|
||||
}
|
||||
|
||||
async def handle_open_path(service_call: ServiceCall) -> ServiceResponse:
|
||||
"""Handle the open path service call."""
|
||||
_LOGGER.debug("Open path: %s", service_call.data)
|
||||
|
@ -256,6 +311,32 @@ async def async_setup_entry(
|
|||
)
|
||||
return asdict(response)
|
||||
|
||||
hass.services.async_register(
|
||||
DOMAIN,
|
||||
SERVICE_GET_PROCESS_BY_ID,
|
||||
handle_get_process_by_id,
|
||||
schema=vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_BRIDGE): valid_device,
|
||||
vol.Required(CONF_ID): cv.positive_int,
|
||||
},
|
||||
),
|
||||
supports_response=SupportsResponse.ONLY,
|
||||
)
|
||||
|
||||
hass.services.async_register(
|
||||
DOMAIN,
|
||||
SERVICE_GET_PROCESSES_BY_NAME,
|
||||
handle_get_processes_by_name,
|
||||
schema=vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_BRIDGE): valid_device,
|
||||
vol.Required(CONF_NAME): cv.string,
|
||||
},
|
||||
),
|
||||
supports_response=SupportsResponse.ONLY,
|
||||
)
|
||||
|
||||
hass.services.async_register(
|
||||
DOMAIN,
|
||||
SERVICE_OPEN_PATH,
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
get_process_by_id:
|
||||
fields:
|
||||
bridge:
|
||||
required: true
|
||||
selector:
|
||||
device:
|
||||
integration: system_bridge
|
||||
id:
|
||||
required: true
|
||||
example: 1234
|
||||
selector:
|
||||
number:
|
||||
get_processes_by_name:
|
||||
fields:
|
||||
bridge:
|
||||
required: true
|
||||
selector:
|
||||
device:
|
||||
integration: system_bridge
|
||||
name:
|
||||
required: true
|
||||
example: "chrome.exe"
|
||||
selector:
|
||||
text:
|
||||
open_path:
|
||||
fields:
|
||||
bridge:
|
||||
|
|
|
@ -86,6 +86,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"exceptions": {
|
||||
"process_not_found": {
|
||||
"message": "Could not find process with id {id}."
|
||||
}
|
||||
},
|
||||
"issues": {
|
||||
"unsupported_version": {
|
||||
"title": "System Bridge Upgrade Required",
|
||||
|
@ -107,6 +112,34 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"get_process_by_id": {
|
||||
"name": "Get process by ID",
|
||||
"description": "Gets a process by the ID.",
|
||||
"fields": {
|
||||
"bridge": {
|
||||
"name": "[%key:component::system_bridge::services::open_path::fields::bridge::name%]",
|
||||
"description": "[%key:component::system_bridge::services::open_path::fields::bridge::description%]"
|
||||
},
|
||||
"id": {
|
||||
"name": "ID",
|
||||
"description": "ID of the process to get."
|
||||
}
|
||||
}
|
||||
},
|
||||
"get_processes_by_name": {
|
||||
"name": "Get processes by name",
|
||||
"description": "Gets a list of processes by the name.",
|
||||
"fields": {
|
||||
"bridge": {
|
||||
"name": "[%key:component::system_bridge::services::open_path::fields::bridge::name%]",
|
||||
"description": "[%key:component::system_bridge::services::open_path::fields::bridge::description%]"
|
||||
},
|
||||
"name": {
|
||||
"name": "Name",
|
||||
"description": "Name of the process to get."
|
||||
}
|
||||
}
|
||||
},
|
||||
"open_url": {
|
||||
"name": "Open URL",
|
||||
"description": "Opens a URL on the server using the default application.",
|
||||
|
|
Loading…
Reference in New Issue