1 """Class for helpers and communication with the OverKiz API."""
3 from __future__
import annotations
5 from typing
import Any, cast
6 from urllib.parse
import urlparse
8 from pyoverkiz.enums
import OverkizCommand, Protocol
9 from pyoverkiz.exceptions
import OverkizException
10 from pyoverkiz.models
import Command, Device, StateDefinition
11 from pyoverkiz.types
import StateType
as OverkizStateType
15 from .coordinator
import OverkizDataUpdateCoordinator
19 COMMANDS_WITHOUT_DELAY = [
20 OverkizCommand.IDENTIFY,
23 OverkizCommand.ON_WITH_TIMER,
29 """Representation of an Overkiz device with execution handler."""
32 self, device_url: str, coordinator: OverkizDataUpdateCoordinator
34 """Initialize the executor."""
41 """Return Overkiz device linked to this entity."""
45 """Return Overkiz device sharing the same base url."""
46 return self.
coordinatorcoordinator.data.get(f
"{self.base_device_url}#{index}")
49 """Select first existing command in a list of commands."""
50 existing_commands = self.
devicedevice.definition.commands
51 return next((c
for c
in commands
if c
in existing_commands),
None)
54 """Return True if a command exists in a list of commands."""
58 """Select first existing definition state in a list of states."""
59 for existing_state
in self.
devicedevice.definition.states:
60 if existing_state.qualified_name
in states:
65 """Select first existing active state in a list of states."""
67 if current_state := self.
devicedevice.states[state]:
68 return current_state.value
73 """Return True if a state exists in self."""
74 return self.
select_stateselect_state(*states)
is not None
77 """Select first existing active state in a list of states."""
78 for attribute
in attributes:
79 if current_attribute := self.
devicedevice.attributes[attribute]:
80 return current_attribute.value
85 self, command_name: str, *args: Any, refresh_afterwards: bool =
True
87 """Execute device command in async context.
89 :param refresh_afterwards: Whether to refresh the device state after the command is executed.
90 If several commands are executed, it will be refreshed only once.
92 parameters = [arg
for arg
in args
if arg
is not None]
96 self.
devicedevice.protocol == Protocol.RTS
97 and command_name
not in COMMANDS_WITHOUT_DELAY
102 exec_id = await self.
coordinatorcoordinator.client.execute_command(
103 self.
devicedevice.device_url,
104 Command(command_name, parameters),
108 except OverkizException
as exception:
112 self.
coordinatorcoordinator.executions[exec_id] = {
113 "device_url": self.
devicedevice.device_url,
114 "command_name": command_name,
116 if refresh_afterwards:
120 self, commands_to_cancel: list[OverkizCommand]
122 """Cancel running execution by command."""
130 for exec_id, execution
in reversed(self.
coordinatorcoordinator.executions.items())
131 if execution.get(
"device_url") == self.
devicedevice.device_url
132 and execution.get(
"command_name")
in commands_to_cancel
142 executions = cast(Any, await self.
coordinatorcoordinator.client.get_current_executions())
148 for execution
in executions
150 for action
in reversed(execution.action_group.get(
"actions"))
151 for command
in action.get(
"commands")
152 if action.get(
"device_url") == self.
devicedevice.device_url
153 and command.get(
"name")
in commands_to_cancel
165 """Cancel running execution via execution id."""
166 await self.
coordinatorcoordinator.client.cancel_command(exec_id)
169 """Retrieve gateway id from device url.
171 device URL (<protocol>://<gatewayId>/<deviceAddress>[#<subsystemId>])
None async_execute_command(self, str command_name, *Any args, bool refresh_afterwards=True)
bool async_cancel_command(self, list[OverkizCommand] commands_to_cancel)
None __init__(self, str device_url, OverkizDataUpdateCoordinator coordinator)
None async_cancel_execution(self, str exec_id)
OverkizStateType select_state(self, *str states)
OverkizStateType select_attribute(self, *str attributes)
bool has_state(self, *str states)
Device|None linked_device(self, int index)
str|None select_command(self, *str commands)
bool has_command(self, *str commands)
StateDefinition|None select_definition_state(self, *str states)