|
40 | 40 | SOMFY_CLIENT_SECRET, |
41 | 41 | SUPPORTED_SERVERS, |
42 | 42 | ) |
43 | | -from pyoverkiz.enums import APIType, Server |
| 43 | +from pyoverkiz.enums import APIType, CommandMode, Server |
44 | 44 | from pyoverkiz.exceptions import ( |
45 | 45 | AccessDeniedToGatewayException, |
46 | 46 | ActionGroupSetupNotFoundException, |
|
75 | 75 | UnknownUserException, |
76 | 76 | ) |
77 | 77 | from pyoverkiz.models import ( |
| 78 | + Action, |
78 | 79 | ActionGroup, |
79 | | - Command, |
80 | 80 | Device, |
81 | 81 | Event, |
82 | 82 | Execution, |
|
91 | 91 | State, |
92 | 92 | ) |
93 | 93 | from pyoverkiz.obfuscate import obfuscate_sensitive_data |
| 94 | +from pyoverkiz.serializers import prepare_payload |
94 | 95 | from pyoverkiz.types import JSON |
95 | 96 |
|
96 | 97 | _LOGGER = logging.getLogger(__name__) |
@@ -659,40 +660,42 @@ async def get_api_version(self) -> str: |
659 | 660 |
|
660 | 661 | @retry_on_too_many_executions |
661 | 662 | @retry_on_auth_error |
662 | | - async def execute_command( |
| 663 | + async def execute_action_group( |
663 | 664 | self, |
664 | | - device_url: str, |
665 | | - command: Command | str, |
| 665 | + actions: list[Action], |
| 666 | + mode: CommandMode | None = None, |
666 | 667 | label: str | None = "python-overkiz-api", |
667 | 668 | ) -> str: |
668 | | - """Send a command.""" |
669 | | - if isinstance(command, str): |
670 | | - command = Command(command) |
| 669 | + """Execute a non-persistent action group. |
671 | 670 |
|
672 | | - response: str = await self.execute_commands(device_url, [command], label) |
| 671 | + The executed action group does not have to be persisted on the server before use. |
| 672 | + Per-session rate-limit : 1 calls per 28min 48s period for all operations of the same category (exec) |
| 673 | + """ |
| 674 | + # Build a logical (snake_case) payload using model helpers and convert it |
| 675 | + # to the exact JSON schema expected by the API (camelCase + small fixes). |
| 676 | + payload = {"label": label, "actions": [a.to_payload() for a in actions]} |
| 677 | + |
| 678 | + # Prepare final payload with camelCase keys and special abbreviation handling |
| 679 | + final_payload = prepare_payload(payload) |
| 680 | + |
| 681 | + if mode == CommandMode.GEOLOCATED: |
| 682 | + url = "exec/apply/geolocated" |
| 683 | + elif mode == CommandMode.INTERNAL: |
| 684 | + url = "exec/apply/internal" |
| 685 | + elif mode == CommandMode.HIGH_PRIORITY: |
| 686 | + url = "exec/apply/highPriority" |
| 687 | + else: |
| 688 | + url = "exec/apply" |
673 | 689 |
|
674 | | - return response |
| 690 | + response: dict = await self.__post(url, final_payload) |
| 691 | + |
| 692 | + return cast(str, response["execId"]) |
675 | 693 |
|
676 | 694 | @retry_on_auth_error |
677 | 695 | async def cancel_command(self, exec_id: str) -> None: |
678 | 696 | """Cancel a running setup-level execution.""" |
679 | 697 | await self.__delete(f"/exec/current/setup/{exec_id}") |
680 | 698 |
|
681 | | - @retry_on_auth_error |
682 | | - async def execute_commands( |
683 | | - self, |
684 | | - device_url: str, |
685 | | - commands: list[Command], |
686 | | - label: str | None = "python-overkiz-api", |
687 | | - ) -> str: |
688 | | - """Send several commands in one call.""" |
689 | | - payload = { |
690 | | - "label": label, |
691 | | - "actions": [{"deviceURL": device_url, "commands": commands}], |
692 | | - } |
693 | | - response: dict = await self.__post("exec/apply", payload) |
694 | | - return cast(str, response["execId"]) |
695 | | - |
696 | 699 | @retry_on_auth_error |
697 | 700 | async def get_action_groups(self) -> list[ActionGroup]: |
698 | 701 | """List the action groups (scenarios).""" |
|
0 commit comments