Home Assistant Unofficial Reference 2024.12.1
notify.py
Go to the documentation of this file.
1 """Support for command line notification services."""
2 
3 from __future__ import annotations
4 
5 import logging
6 import subprocess
7 from typing import Any, cast
8 
9 from homeassistant.components.notify import BaseNotificationService
10 from homeassistant.const import CONF_COMMAND
11 from homeassistant.core import HomeAssistant
12 from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
13 from homeassistant.util.process import kill_subprocess
14 
15 from .const import CONF_COMMAND_TIMEOUT
16 
17 _LOGGER = logging.getLogger(__name__)
18 
19 
21  hass: HomeAssistant,
22  config: ConfigType,
23  discovery_info: DiscoveryInfoType | None = None,
24 ) -> CommandLineNotificationService | None:
25  """Get the Command Line notification service."""
26  if not discovery_info:
27  return None
28 
29  discovery_info = cast(DiscoveryInfoType, discovery_info)
30  notify_config = discovery_info
31  command: str = notify_config[CONF_COMMAND]
32  timeout: int = notify_config[CONF_COMMAND_TIMEOUT]
33 
34  return CommandLineNotificationService(command, timeout)
35 
36 
37 class CommandLineNotificationService(BaseNotificationService):
38  """Implement the notification service for the Command Line service."""
39 
40  def __init__(self, command: str, timeout: int) -> None:
41  """Initialize the service."""
42  self.commandcommand = command
43  self._timeout_timeout = timeout
44 
45  def send_message(self, message: str = "", **kwargs: Any) -> None:
46  """Send a message to a command line."""
47  with subprocess.Popen( # noqa: S602 # shell by design
48  self.commandcommand,
49  universal_newlines=True,
50  stdin=subprocess.PIPE,
51  close_fds=False, # required for posix_spawn
52  shell=True,
53  ) as proc:
54  try:
55  proc.communicate(input=message, timeout=self._timeout_timeout)
56  if proc.returncode != 0:
57  _LOGGER.error(
58  "Command failed (with return code %s): %s",
59  proc.returncode,
60  self.commandcommand,
61  )
62  except subprocess.TimeoutExpired:
63  _LOGGER.error("Timeout for command: %s", self.commandcommand)
64  kill_subprocess(proc)
65  except subprocess.SubprocessError:
66  _LOGGER.error("Error trying to exec command: %s", self.commandcommand)
CommandLineNotificationService|None get_service(HomeAssistant hass, ConfigType config, DiscoveryInfoType|None discovery_info=None)
Definition: notify.py:24
None kill_subprocess(subprocess.Popen[Any] process)
Definition: process.py:9