1 """Support for custom shell commands to turn a switch on/off."""
3 from __future__
import annotations
6 from datetime
import datetime, timedelta
7 from typing
import TYPE_CHECKING, Any, cast
26 from .const
import CONF_COMMAND_TIMEOUT, LOGGER, TRIGGER_ENTITY_OPTIONS
27 from .utils
import async_call_shell_with_timeout, async_check_output_or_log
35 async_add_entities: AddEntitiesCallback,
36 discovery_info: DiscoveryInfoType |
None =
None,
38 """Find and return switches controlled by shell commands."""
39 if not discovery_info:
43 discovery_info = cast(DiscoveryInfoType, discovery_info)
44 entities: dict[str, dict[str, Any]] = {
45 slugify(discovery_info[CONF_NAME]): discovery_info
48 for object_id, switch_config
in entities.items():
49 trigger_entity_config = {
50 CONF_NAME:
Template(switch_config.get(CONF_NAME, object_id), hass),
51 **{k: v
for k, v
in switch_config.items()
if k
in TRIGGER_ENTITY_OPTIONS},
56 trigger_entity_config,
58 switch_config[CONF_COMMAND_ON],
59 switch_config[CONF_COMMAND_OFF],
60 switch_config.get(CONF_COMMAND_STATE),
61 switch_config.get(CONF_VALUE_TEMPLATE),
62 switch_config[CONF_COMMAND_TIMEOUT],
63 switch_config.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL),
71 """Representation a switch that can be toggled using shell commands."""
73 _attr_should_poll =
False
81 command_state: str |
None,
82 value_template: Template |
None,
84 scan_interval: timedelta,
86 """Initialize the switch."""
99 """Call when entity about to be added to hass."""
107 name=f
"Command Line Cover - {self.name}",
108 cancel_on_shutdown=
True,
112 async
def _switch(self, command: str) -> bool:
113 """Execute the actual commands."""
114 LOGGER.debug(
"Running command: %s", command)
119 LOGGER.error(
"Command failed: %s", command)
124 """Execute state command for return value."""
125 LOGGER.debug(
"Running state value command: %s", command)
129 """Execute state command for return code."""
130 LOGGER.debug(
"Running state code command: %s", command)
133 command, self.
_timeout_timeout, log_return_code=
False
140 """Return true if we do optimistic updates."""
144 """Query for state."""
152 """Update the state of the entity."""
157 "Updating Command Line Switch %s took longer than the scheduled update interval %s",
167 """Update device state."""
172 value = self.
_value_template_value_template.async_render_with_possible_json_value(
177 self.
_attr_is_on_attr_is_on = (value
or payload).lower() ==
"true"
182 """Update the entity.
184 Only used by the generic entity update service.
189 """Turn the device on."""
196 """Turn the device off."""
bool _switch(self, str command)
None async_added_to_hass(self)
bool _async_query_state_code(self, str command)
None _update_entity_state(self, datetime|None now=None)
str|int|None _async_query_state(self)
str|None _async_query_state_value(self, str command)
None async_turn_on(self, **Any kwargs)
None async_turn_off(self, **Any kwargs)
None __init__(self, ConfigType config, str object_id, str command_on, str command_off, str|None command_state, Template|None value_template, int timeout, timedelta scan_interval)
None async_write_ha_state(self)
None async_on_remove(self, CALLBACK_TYPE func)
str|UndefinedType|None name(self)
None _process_manual_data(self, Any|None value=None)
None async_setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback async_add_entities, DiscoveryInfoType|None discovery_info=None)
int async_call_shell_with_timeout(str command, int timeout, *bool log_return_code=True)
str|None async_check_output_or_log(str command, int timeout)
CALLBACK_TYPE async_track_time_interval(HomeAssistant hass, Callable[[datetime], Coroutine[Any, Any, None]|None] action, timedelta interval, *str|None name=None, bool|None cancel_on_shutdown=None)