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