Updated apps
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant, ServiceCall, SupportsResponse
|
||||
from homeassistant.exceptions import ServiceValidationError
|
||||
from homeassistant.helpers import label_registry as lr
|
||||
|
||||
from .const import (
|
||||
CONF_ACTION_NAME,
|
||||
CONF_ALLOWED_SERVICE_PARAMS,
|
||||
CONF_CHUNK_SIZE,
|
||||
CONF_CREATE_FILE,
|
||||
CONF_IGNORED_LABELS,
|
||||
CONF_PARSE_CONFIG,
|
||||
CONF_REPORT_PATH,
|
||||
CONF_SEND_NOTIFICATION,
|
||||
CONF_SERVICE_DATA,
|
||||
CONF_SERVICE_NAME,
|
||||
DOMAIN,
|
||||
LABELS_SERVICE_NAME,
|
||||
REPORT_SERVICE_NAME,
|
||||
)
|
||||
from .utils.logger import _LOGGER
|
||||
from .utils.report import async_report_to_file, async_report_to_notification
|
||||
from .utils.utils import get_config
|
||||
|
||||
|
||||
class WatchmanServicesSetup:
|
||||
"""Class to handle Integration Services."""
|
||||
|
||||
def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None:
|
||||
"""Initialise services."""
|
||||
self.hass = hass
|
||||
self.config_entry = config_entry
|
||||
self.coordinator = config_entry.runtime_data.coordinator
|
||||
|
||||
self.setup_services()
|
||||
|
||||
def setup_services(self) -> None:
|
||||
"""Initialise the services in Hass."""
|
||||
self.hass.services.async_register(
|
||||
DOMAIN,
|
||||
REPORT_SERVICE_NAME,
|
||||
self.async_handle_report,
|
||||
supports_response=SupportsResponse.OPTIONAL
|
||||
)
|
||||
self.hass.services.async_register(
|
||||
DOMAIN,
|
||||
LABELS_SERVICE_NAME,
|
||||
self.async_handle_set_ignored_labels,
|
||||
)
|
||||
|
||||
async def async_handle_set_ignored_labels(self, call: ServiceCall) -> None:
|
||||
"""Set ignored labels."""
|
||||
labels = call.data.get("labels", [])
|
||||
registry = lr.async_get(self.hass)
|
||||
existing_labels = {l.label_id for l in registry.async_list_labels()}
|
||||
|
||||
invalid_labels = [l for l in labels if l not in existing_labels]
|
||||
if invalid_labels:
|
||||
raise ServiceValidationError(
|
||||
f"The following labels do not exist: {', '.join(invalid_labels)}"
|
||||
)
|
||||
|
||||
self.hass.config_entries.async_update_entry(
|
||||
self.config_entry,
|
||||
data={**self.config_entry.data, CONF_IGNORED_LABELS: labels}
|
||||
)
|
||||
|
||||
async def async_handle_report(self, call: ServiceCall) -> dict[str, Any]:
|
||||
"""Handle the action call."""
|
||||
path = get_config(self.hass, CONF_REPORT_PATH)
|
||||
send_notification = call.data.get(CONF_SEND_NOTIFICATION, False)
|
||||
create_file = call.data.get(CONF_CREATE_FILE, True)
|
||||
action_data = call.data.get(CONF_SERVICE_DATA, None)
|
||||
chunk_size = call.data.get(CONF_CHUNK_SIZE, 0)
|
||||
|
||||
# validate action params
|
||||
for param in call.data:
|
||||
if param not in CONF_ALLOWED_SERVICE_PARAMS:
|
||||
raise ServiceValidationError(f"Unknown action parameter: `{param}`.")
|
||||
|
||||
action_name = call.data.get(
|
||||
CONF_ACTION_NAME, call.data.get(CONF_SERVICE_NAME, None)
|
||||
)
|
||||
|
||||
if action_data and not action_name:
|
||||
raise ServiceValidationError(
|
||||
f"Missing [{CONF_ACTION_NAME}] parameter. The [{CONF_SERVICE_DATA}] parameter can only be used "
|
||||
f"in conjunction with [{CONF_ACTION_NAME}] parameter."
|
||||
)
|
||||
|
||||
_LOGGER.debug(f"User requested report params={call.data}")
|
||||
|
||||
if call.data.get(CONF_PARSE_CONFIG, False):
|
||||
# Blocking wait for a fresh scan
|
||||
await self.coordinator.async_force_parse()
|
||||
else:
|
||||
# FIX: Ensure sensors perform a FULL check to match the generated report,
|
||||
# ignoring the incremental optimization.
|
||||
self.coordinator._force_full_rescan = True
|
||||
await self.coordinator.async_request_refresh()
|
||||
|
||||
# call notification action even when send notification = False
|
||||
if send_notification or action_name:
|
||||
await async_report_to_notification(
|
||||
self.hass, action_name, action_data, chunk_size
|
||||
)
|
||||
|
||||
if create_file:
|
||||
try:
|
||||
await async_report_to_file(self.hass, path)
|
||||
except OSError as exception:
|
||||
raise ServiceValidationError(
|
||||
f"Unable to write report to file '{exception.filename}': {exception.strerror} [Error:{exception.errno}]"
|
||||
)
|
||||
|
||||
return await self.coordinator.async_get_detailed_report_data()
|
||||
Reference in New Issue
Block a user