diff --git a/package-lock.json b/package-lock.json index 03e8308e..7ddff8c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,8 +7,8 @@ "name": "@seamapi/python", "devDependencies": { "@seamapi/fake-seam-connect": "1.83.0", - "@seamapi/nextlove-sdk-generator": "1.18.0", - "@seamapi/types": "1.384.0", + "@seamapi/nextlove-sdk-generator": "^1.18.1", + "@seamapi/types": "1.405.0", "del": "^7.1.0", "prettier": "^3.2.5" } @@ -453,9 +453,9 @@ } }, "node_modules/@seamapi/nextlove-sdk-generator": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/@seamapi/nextlove-sdk-generator/-/nextlove-sdk-generator-1.18.0.tgz", - "integrity": "sha512-lINrwlr3pJUWawFvEXezY89VxS4mafgkqeBGTiLRZSXTDLzqEl8QD6UKN0CHKirwHCjPFj8MUsGDyz7pCzbCmQ==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/@seamapi/nextlove-sdk-generator/-/nextlove-sdk-generator-1.18.1.tgz", + "integrity": "sha512-TsK2AY2B/44JNEbWf30/UWfP7Y0T1bxZ3X6AH/buhUKHAzNfiipw133iAN2p6e2fu6sa9zbrjM1cmvwU+lDhiw==", "dev": true, "license": "MIT", "dependencies": { @@ -475,9 +475,9 @@ } }, "node_modules/@seamapi/types": { - "version": "1.384.0", - "resolved": "https://registry.npmjs.org/@seamapi/types/-/types-1.384.0.tgz", - "integrity": "sha512-pFQF4O7LaLu9J2yfNxtiuN/kCYX5WH0Sdccx6BC1rYQqwQSD1m5/yXTq14iCBa6z2R8Fw09WRU5Zp+NjHtleQQ==", + "version": "1.405.0", + "resolved": "https://registry.npmjs.org/@seamapi/types/-/types-1.405.0.tgz", + "integrity": "sha512-kcNY2tltFbmjI+KVn8qlRjFxQEd1eQAq0sacZ/TZ8uNu/jNlXSng8DkkfEHNvcTWd3v8h9FnY8xagweQZ/nBTg==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index 9abcf0dd..791195fa 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,8 @@ }, "devDependencies": { "@seamapi/fake-seam-connect": "1.83.0", - "@seamapi/nextlove-sdk-generator": "1.18.0", - "@seamapi/types": "1.384.0", + "@seamapi/nextlove-sdk-generator": "^1.18.1", + "@seamapi/types": "1.405.0", "del": "^7.1.0", "prettier": "^3.2.5" } diff --git a/seam/routes/__init__.py b/seam/routes/__init__.py index 9eb6facb..692f027f 100644 --- a/seam/routes/__init__.py +++ b/seam/routes/__init__.py @@ -4,7 +4,6 @@ from .access_codes import AccessCodes from .acs import Acs from .action_attempts import ActionAttempts -from .bridges import Bridges from .client_sessions import ClientSessions from .connect_webviews import ConnectWebviews from .connected_accounts import ConnectedAccounts @@ -25,7 +24,6 @@ def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): self.access_codes = AccessCodes(client=client, defaults=defaults) self.acs = Acs(client=client, defaults=defaults) self.action_attempts = ActionAttempts(client=client, defaults=defaults) - self.bridges = Bridges(client=client, defaults=defaults) self.client_sessions = ClientSessions(client=client, defaults=defaults) self.connect_webviews = ConnectWebviews(client=client, defaults=defaults) self.connected_accounts = ConnectedAccounts(client=client, defaults=defaults) diff --git a/seam/routes/access_codes.py b/seam/routes/access_codes.py index 510e987f..b618b98c 100644 --- a/seam/routes/access_codes.py +++ b/seam/routes/access_codes.py @@ -202,6 +202,8 @@ def list( *, access_code_ids: Optional[List[str]] = None, device_id: Optional[str] = None, + limit: Optional[float] = None, + page_cursor: Optional[str] = None, user_identifier_key: Optional[str] = None ) -> List[AccessCode]: json_payload = {} @@ -210,6 +212,10 @@ def list( json_payload["access_code_ids"] = access_code_ids if device_id is not None: json_payload["device_id"] = device_id + if limit is not None: + json_payload["limit"] = limit + if page_cursor is not None: + json_payload["page_cursor"] = page_cursor if user_identifier_key is not None: json_payload["user_identifier_key"] = user_identifier_key @@ -229,6 +235,29 @@ def pull_backup_access_code(self, *, access_code_id: str) -> AccessCode: return AccessCode.from_dict(res["access_code"]) + def report_device_constraints( + self, + *, + device_id: str, + max_code_length: Optional[int] = None, + min_code_length: Optional[int] = None, + supported_code_lengths: Optional[List[int]] = None + ) -> None: + json_payload = {} + + if device_id is not None: + json_payload["device_id"] = device_id + if max_code_length is not None: + json_payload["max_code_length"] = max_code_length + if min_code_length is not None: + json_payload["min_code_length"] = min_code_length + if supported_code_lengths is not None: + json_payload["supported_code_lengths"] = supported_code_lengths + + self.client.post("/access_codes/report_device_constraints", json=json_payload) + + return None + def update( self, *, diff --git a/seam/routes/acs_access_groups.py b/seam/routes/acs_access_groups.py index a60a3b75..232325d8 100644 --- a/seam/routes/acs_access_groups.py +++ b/seam/routes/acs_access_groups.py @@ -8,13 +8,21 @@ def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): self.client = client self.defaults = defaults - def add_user(self, *, acs_access_group_id: str, acs_user_id: str) -> None: + def add_user( + self, + *, + acs_access_group_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: json_payload = {} if acs_access_group_id is not None: json_payload["acs_access_group_id"] = acs_access_group_id if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id + if user_identity_id is not None: + json_payload["user_identity_id"] = user_identity_id self.client.post("/acs/access_groups/add_user", json=json_payload) @@ -31,7 +39,11 @@ def get(self, *, acs_access_group_id: str) -> AcsAccessGroup: return AcsAccessGroup.from_dict(res["acs_access_group"]) def list( - self, *, acs_system_id: Optional[str] = None, acs_user_id: Optional[str] = None + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None ) -> List[AcsAccessGroup]: json_payload = {} @@ -39,6 +51,8 @@ def list( json_payload["acs_system_id"] = acs_system_id if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id + if user_identity_id is not None: + json_payload["user_identity_id"] = user_identity_id res = self.client.post("/acs/access_groups/list", json=json_payload) @@ -68,13 +82,21 @@ def list_users(self, *, acs_access_group_id: str) -> List[AcsUser]: return [AcsUser.from_dict(item) for item in res["acs_users"]] - def remove_user(self, *, acs_access_group_id: str, acs_user_id: str) -> None: + def remove_user( + self, + *, + acs_access_group_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: json_payload = {} if acs_access_group_id is not None: json_payload["acs_access_group_id"] = acs_access_group_id if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id + if user_identity_id is not None: + json_payload["user_identity_id"] = user_identity_id self.client.post("/acs/access_groups/remove_user", json=json_payload) diff --git a/seam/routes/acs_credentials.py b/seam/routes/acs_credentials.py index 61686732..64cd15e3 100644 --- a/seam/routes/acs_credentials.py +++ b/seam/routes/acs_credentials.py @@ -8,13 +8,21 @@ def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): self.client = client self.defaults = defaults - def assign(self, *, acs_credential_id: str, acs_user_id: str) -> None: + def assign( + self, + *, + acs_credential_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: json_payload = {} if acs_credential_id is not None: json_payload["acs_credential_id"] = acs_credential_id if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id + if user_identity_id is not None: + json_payload["user_identity_id"] = user_identity_id self.client.post("/acs/credentials/assign", json=json_payload) @@ -24,7 +32,8 @@ def create( self, *, access_method: str, - acs_user_id: str, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, allowed_acs_entrance_ids: Optional[List[str]] = None, assa_abloy_vostio_metadata: Optional[Dict[str, Any]] = None, code: Optional[str] = None, @@ -33,12 +42,15 @@ def create( is_multi_phone_sync_credential: Optional[bool] = None, salto_space_metadata: Optional[Dict[str, Any]] = None, starts_at: Optional[str] = None, + user_identity_id: Optional[str] = None, visionline_metadata: Optional[Dict[str, Any]] = None ) -> AcsCredential: json_payload = {} if access_method is not None: json_payload["access_method"] = access_method + if acs_system_id is not None: + json_payload["acs_system_id"] = acs_system_id if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id if allowed_acs_entrance_ids is not None: @@ -61,6 +73,8 @@ def create( json_payload["salto_space_metadata"] = salto_space_metadata if starts_at is not None: json_payload["starts_at"] = starts_at + if user_identity_id is not None: + json_payload["user_identity_id"] = user_identity_id if visionline_metadata is not None: json_payload["visionline_metadata"] = visionline_metadata @@ -131,13 +145,21 @@ def list_accessible_entrances(self, *, acs_credential_id: str) -> List[AcsEntran return [AcsEntrance.from_dict(item) for item in res["acs_entrances"]] - def unassign(self, *, acs_credential_id: str, acs_user_id: str) -> None: + def unassign( + self, + *, + acs_credential_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: json_payload = {} if acs_credential_id is not None: json_payload["acs_credential_id"] = acs_credential_id if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id + if user_identity_id is not None: + json_payload["user_identity_id"] = user_identity_id self.client.post("/acs/credentials/unassign", json=json_payload) diff --git a/seam/routes/acs_encoders.py b/seam/routes/acs_encoders.py index a1cdf417..5bb0c772 100644 --- a/seam/routes/acs_encoders.py +++ b/seam/routes/acs_encoders.py @@ -10,6 +10,34 @@ def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): self.client = client self.defaults = defaults + def encode_access_method( + self, + *, + access_method_id: str, + acs_encoder_id: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + json_payload = {} + + if access_method_id is not None: + json_payload["access_method_id"] = access_method_id + if acs_encoder_id is not None: + json_payload["acs_encoder_id"] = acs_encoder_id + + res = self.client.post("/acs/encoders/encode_access_method", json=json_payload) + + wait_for_action_attempt = ( + self.defaults.get("wait_for_action_attempt") + if wait_for_action_attempt is None + else wait_for_action_attempt + ) + + return resolve_action_attempt( + client=self.client, + action_attempt=ActionAttempt.from_dict(res["action_attempt"]), + wait_for_action_attempt=wait_for_action_attempt, + ) + def encode_credential( self, *, diff --git a/seam/routes/acs_entrances.py b/seam/routes/acs_entrances.py index bbe4758e..1d8fff50 100644 --- a/seam/routes/acs_entrances.py +++ b/seam/routes/acs_entrances.py @@ -18,13 +18,21 @@ def get(self, *, acs_entrance_id: str) -> AcsEntrance: return AcsEntrance.from_dict(res["acs_entrance"]) - def grant_access(self, *, acs_entrance_id: str, acs_user_id: str) -> None: + def grant_access( + self, + *, + acs_entrance_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: json_payload = {} if acs_entrance_id is not None: json_payload["acs_entrance_id"] = acs_entrance_id if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id + if user_identity_id is not None: + json_payload["user_identity_id"] = user_identity_id self.client.post("/acs/entrances/grant_access", json=json_payload) @@ -34,7 +42,8 @@ def list( self, *, acs_credential_id: Optional[str] = None, - acs_system_id: Optional[str] = None + acs_system_id: Optional[str] = None, + location_id: Optional[str] = None ) -> List[AcsEntrance]: json_payload = {} @@ -42,6 +51,8 @@ def list( json_payload["acs_credential_id"] = acs_credential_id if acs_system_id is not None: json_payload["acs_system_id"] = acs_system_id + if location_id is not None: + json_payload["location_id"] = location_id res = self.client.post("/acs/entrances/list", json=json_payload) diff --git a/seam/routes/acs_users.py b/seam/routes/acs_users.py index c1a04b6f..9452bd1c 100644 --- a/seam/routes/acs_users.py +++ b/seam/routes/acs_users.py @@ -57,21 +57,41 @@ def create( return AcsUser.from_dict(res["acs_user"]) - def delete(self, *, acs_user_id: str) -> None: + def delete( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: json_payload = {} + if acs_system_id is not None: + json_payload["acs_system_id"] = acs_system_id if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id + if user_identity_id is not None: + json_payload["user_identity_id"] = user_identity_id self.client.post("/acs/users/delete", json=json_payload) return None - def get(self, *, acs_user_id: str) -> AcsUser: + def get( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> AcsUser: json_payload = {} + if acs_system_id is not None: + json_payload["acs_system_id"] = acs_system_id if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id + if user_identity_id is not None: + json_payload["user_identity_id"] = user_identity_id res = self.client.post("/acs/users/get", json=json_payload) @@ -112,11 +132,21 @@ def list( return [AcsUser.from_dict(item) for item in res["acs_users"]] - def list_accessible_entrances(self, *, acs_user_id: str) -> List[AcsEntrance]: + def list_accessible_entrances( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> List[AcsEntrance]: json_payload = {} + if acs_system_id is not None: + json_payload["acs_system_id"] = acs_system_id if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id + if user_identity_id is not None: + json_payload["user_identity_id"] = user_identity_id res = self.client.post( "/acs/users/list_accessible_entrances", json=json_payload @@ -125,7 +155,11 @@ def list_accessible_entrances(self, *, acs_user_id: str) -> List[AcsEntrance]: return [AcsEntrance.from_dict(item) for item in res["acs_entrances"]] def remove_from_access_group( - self, *, acs_access_group_id: str, acs_user_id: str + self, + *, + acs_access_group_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None ) -> None: json_payload = {} @@ -133,36 +167,68 @@ def remove_from_access_group( json_payload["acs_access_group_id"] = acs_access_group_id if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id + if user_identity_id is not None: + json_payload["user_identity_id"] = user_identity_id self.client.post("/acs/users/remove_from_access_group", json=json_payload) return None - def revoke_access_to_all_entrances(self, *, acs_user_id: str) -> None: + def revoke_access_to_all_entrances( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: json_payload = {} + if acs_system_id is not None: + json_payload["acs_system_id"] = acs_system_id if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id + if user_identity_id is not None: + json_payload["user_identity_id"] = user_identity_id self.client.post("/acs/users/revoke_access_to_all_entrances", json=json_payload) return None - def suspend(self, *, acs_user_id: str) -> None: + def suspend( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: json_payload = {} + if acs_system_id is not None: + json_payload["acs_system_id"] = acs_system_id if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id + if user_identity_id is not None: + json_payload["user_identity_id"] = user_identity_id self.client.post("/acs/users/suspend", json=json_payload) return None - def unsuspend(self, *, acs_user_id: str) -> None: + def unsuspend( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: json_payload = {} + if acs_system_id is not None: + json_payload["acs_system_id"] = acs_system_id if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id + if user_identity_id is not None: + json_payload["user_identity_id"] = user_identity_id self.client.post("/acs/users/unsuspend", json=json_payload) @@ -171,20 +237,24 @@ def unsuspend(self, *, acs_user_id: str) -> None: def update( self, *, - acs_user_id: str, access_schedule: Optional[Dict[str, Any]] = None, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, email: Optional[str] = None, email_address: Optional[str] = None, full_name: Optional[str] = None, hid_acs_system_id: Optional[str] = None, - phone_number: Optional[str] = None + phone_number: Optional[str] = None, + user_identity_id: Optional[str] = None ) -> None: json_payload = {} - if acs_user_id is not None: - json_payload["acs_user_id"] = acs_user_id if access_schedule is not None: json_payload["access_schedule"] = access_schedule + if acs_system_id is not None: + json_payload["acs_system_id"] = acs_system_id + if acs_user_id is not None: + json_payload["acs_user_id"] = acs_user_id if email is not None: json_payload["email"] = email if email_address is not None: @@ -195,6 +265,8 @@ def update( json_payload["hid_acs_system_id"] = hid_acs_system_id if phone_number is not None: json_payload["phone_number"] = phone_number + if user_identity_id is not None: + json_payload["user_identity_id"] = user_identity_id self.client.post("/acs/users/update", json=json_payload) diff --git a/seam/routes/bridges.py b/seam/routes/bridges.py deleted file mode 100644 index bdfd49b1..00000000 --- a/seam/routes/bridges.py +++ /dev/null @@ -1,28 +0,0 @@ -from typing import Optional, Any, List, Dict, Union -from ..client import SeamHttpClient -from .models import AbstractBridges - - -class Bridges(AbstractBridges): - def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): - self.client = client - self.defaults = defaults - - def get(self, *, bridge_id: str) -> None: - json_payload = {} - - if bridge_id is not None: - json_payload["bridge_id"] = bridge_id - - self.client.post("/bridges/get", json=json_payload) - - return None - - def list( - self, - ) -> None: - json_payload = {} - - self.client.post("/bridges/list", json=json_payload) - - return None diff --git a/seam/routes/connected_accounts.py b/seam/routes/connected_accounts.py index 589bd9f4..64436869 100644 --- a/seam/routes/connected_accounts.py +++ b/seam/routes/connected_accounts.py @@ -38,6 +38,7 @@ def list( self, *, custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_ids: Optional[List[str]] = None, limit: Optional[int] = None, page_cursor: Optional[str] = None, user_identifier_key: Optional[str] = None @@ -46,6 +47,8 @@ def list( if custom_metadata_has is not None: json_payload["custom_metadata_has"] = custom_metadata_has + if customer_ids is not None: + json_payload["customer_ids"] = customer_ids if limit is not None: json_payload["limit"] = limit if page_cursor is not None: diff --git a/seam/routes/devices.py b/seam/routes/devices.py index ada54638..19c1d2ad 100644 --- a/seam/routes/devices.py +++ b/seam/routes/devices.py @@ -42,6 +42,7 @@ def list( connected_account_ids: Optional[List[str]] = None, created_before: Optional[str] = None, custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_ids: Optional[List[str]] = None, device_ids: Optional[List[str]] = None, device_type: Optional[str] = None, device_types: Optional[List[str]] = None, @@ -49,6 +50,7 @@ def list( include_if: Optional[List[str]] = None, limit: Optional[float] = None, manufacturer: Optional[str] = None, + page_cursor: Optional[str] = None, unstable_location_id: Optional[str] = None, user_identifier_key: Optional[str] = None ) -> List[Device]: @@ -64,6 +66,8 @@ def list( json_payload["created_before"] = created_before if custom_metadata_has is not None: json_payload["custom_metadata_has"] = custom_metadata_has + if customer_ids is not None: + json_payload["customer_ids"] = customer_ids if device_ids is not None: json_payload["device_ids"] = device_ids if device_type is not None: @@ -78,6 +82,8 @@ def list( json_payload["limit"] = limit if manufacturer is not None: json_payload["manufacturer"] = manufacturer + if page_cursor is not None: + json_payload["page_cursor"] = page_cursor if unstable_location_id is not None: json_payload["unstable_location_id"] = unstable_location_id if user_identifier_key is not None: diff --git a/seam/routes/devices_unmanaged.py b/seam/routes/devices_unmanaged.py index 353cb99e..6c6730a4 100644 --- a/seam/routes/devices_unmanaged.py +++ b/seam/routes/devices_unmanaged.py @@ -30,6 +30,7 @@ def list( connected_account_ids: Optional[List[str]] = None, created_before: Optional[str] = None, custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_ids: Optional[List[str]] = None, device_ids: Optional[List[str]] = None, device_type: Optional[str] = None, device_types: Optional[List[str]] = None, @@ -37,6 +38,7 @@ def list( include_if: Optional[List[str]] = None, limit: Optional[float] = None, manufacturer: Optional[str] = None, + page_cursor: Optional[str] = None, unstable_location_id: Optional[str] = None, user_identifier_key: Optional[str] = None ) -> List[UnmanagedDevice]: @@ -52,6 +54,8 @@ def list( json_payload["created_before"] = created_before if custom_metadata_has is not None: json_payload["custom_metadata_has"] = custom_metadata_has + if customer_ids is not None: + json_payload["customer_ids"] = customer_ids if device_ids is not None: json_payload["device_ids"] = device_ids if device_type is not None: @@ -66,6 +70,8 @@ def list( json_payload["limit"] = limit if manufacturer is not None: json_payload["manufacturer"] = manufacturer + if page_cursor is not None: + json_payload["page_cursor"] = page_cursor if unstable_location_id is not None: json_payload["unstable_location_id"] = unstable_location_id if user_identifier_key is not None: diff --git a/seam/routes/events.py b/seam/routes/events.py index f769a542..4bd0840b 100644 --- a/seam/routes/events.py +++ b/seam/routes/events.py @@ -38,6 +38,7 @@ def list( between: Optional[List[str]] = None, connect_webview_id: Optional[str] = None, connected_account_id: Optional[str] = None, + customer_ids: Optional[List[str]] = None, device_id: Optional[str] = None, device_ids: Optional[List[str]] = None, event_ids: Optional[List[str]] = None, @@ -63,6 +64,8 @@ def list( json_payload["connect_webview_id"] = connect_webview_id if connected_account_id is not None: json_payload["connected_account_id"] = connected_account_id + if customer_ids is not None: + json_payload["customer_ids"] = customer_ids if device_id is not None: json_payload["device_id"] = device_id if device_ids is not None: diff --git a/seam/routes/locks.py b/seam/routes/locks.py index 6b7fea24..cac924f3 100644 --- a/seam/routes/locks.py +++ b/seam/routes/locks.py @@ -32,6 +32,7 @@ def list( connected_account_ids: Optional[List[str]] = None, created_before: Optional[str] = None, custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_ids: Optional[List[str]] = None, device_ids: Optional[List[str]] = None, device_type: Optional[str] = None, device_types: Optional[List[str]] = None, @@ -39,6 +40,7 @@ def list( include_if: Optional[List[str]] = None, limit: Optional[float] = None, manufacturer: Optional[str] = None, + page_cursor: Optional[str] = None, unstable_location_id: Optional[str] = None, user_identifier_key: Optional[str] = None ) -> List[Device]: @@ -54,6 +56,8 @@ def list( json_payload["created_before"] = created_before if custom_metadata_has is not None: json_payload["custom_metadata_has"] = custom_metadata_has + if customer_ids is not None: + json_payload["customer_ids"] = customer_ids if device_ids is not None: json_payload["device_ids"] = device_ids if device_type is not None: @@ -68,6 +72,8 @@ def list( json_payload["limit"] = limit if manufacturer is not None: json_payload["manufacturer"] = manufacturer + if page_cursor is not None: + json_payload["page_cursor"] = page_cursor if unstable_location_id is not None: json_payload["unstable_location_id"] = unstable_location_id if user_identifier_key is not None: diff --git a/seam/routes/models.py b/seam/routes/models.py index e760ff14..c983fe50 100644 --- a/seam/routes/models.py +++ b/seam/routes/models.py @@ -273,10 +273,6 @@ class AcsSystem: acs_access_group_count: float acs_system_id: str acs_user_count: float - can_add_acs_users_to_acs_access_groups: bool - can_automate_enrollment: bool - can_create_acs_access_groups: bool - can_remove_acs_users_from_acs_access_groups: bool connected_account_id: str connected_account_ids: List[str] created_at: str @@ -301,14 +297,6 @@ def from_dict(d: Dict[str, Any]): acs_access_group_count=d.get("acs_access_group_count", None), acs_system_id=d.get("acs_system_id", None), acs_user_count=d.get("acs_user_count", None), - can_add_acs_users_to_acs_access_groups=d.get( - "can_add_acs_users_to_acs_access_groups", None - ), - can_automate_enrollment=d.get("can_automate_enrollment", None), - can_create_acs_access_groups=d.get("can_create_acs_access_groups", None), - can_remove_acs_users_from_acs_access_groups=d.get( - "can_remove_acs_users_from_acs_access_groups", None - ), connected_account_id=d.get("connected_account_id", None), connected_account_ids=d.get("connected_account_ids", None), created_at=d.get("created_at", None), @@ -336,6 +324,7 @@ class AcsUser: access_schedule: Dict[str, Any] acs_system_id: str acs_user_id: str + connected_account_id: str created_at: str display_name: str email: str @@ -345,10 +334,9 @@ class AcsUser: external_type_display_name: str full_name: str hid_acs_system_id: str - is_latest_desired_state_synced_with_provider: bool is_managed: bool is_suspended: bool - latest_desired_state_synced_with_provider_at: str + last_successful_sync_at: str pending_mutations: List[Dict[str, Any]] phone_number: str user_identity_email_address: str @@ -364,6 +352,7 @@ def from_dict(d: Dict[str, Any]): access_schedule=DeepAttrDict(d.get("access_schedule", None)), acs_system_id=d.get("acs_system_id", None), acs_user_id=d.get("acs_user_id", None), + connected_account_id=d.get("connected_account_id", None), created_at=d.get("created_at", None), display_name=d.get("display_name", None), email=d.get("email", None), @@ -373,14 +362,9 @@ def from_dict(d: Dict[str, Any]): external_type_display_name=d.get("external_type_display_name", None), full_name=d.get("full_name", None), hid_acs_system_id=d.get("hid_acs_system_id", None), - is_latest_desired_state_synced_with_provider=d.get( - "is_latest_desired_state_synced_with_provider", None - ), is_managed=d.get("is_managed", None), is_suspended=d.get("is_suspended", None), - latest_desired_state_synced_with_provider_at=d.get( - "latest_desired_state_synced_with_provider_at", None - ), + last_successful_sync_at=d.get("last_successful_sync_at", None), pending_mutations=d.get("pending_mutations", None), phone_number=d.get("phone_number", None), user_identity_email_address=d.get("user_identity_email_address", None), @@ -657,12 +641,14 @@ class SeamEvent: workspace_id: str code: str backup_access_code_id: str + access_grant_id: str + acs_entrance_id: str + access_method_id: str acs_system_id: str acs_credential_id: str acs_user_id: str acs_encoder_id: str acs_access_group_id: str - acs_entrance_id: str client_session_id: str connect_webview_id: str action_attempt_id: str @@ -711,12 +697,14 @@ def from_dict(d: Dict[str, Any]): workspace_id=d.get("workspace_id", None), code=d.get("code", None), backup_access_code_id=d.get("backup_access_code_id", None), + access_grant_id=d.get("access_grant_id", None), + acs_entrance_id=d.get("acs_entrance_id", None), + access_method_id=d.get("access_method_id", None), acs_system_id=d.get("acs_system_id", None), acs_credential_id=d.get("acs_credential_id", None), acs_user_id=d.get("acs_user_id", None), acs_encoder_id=d.get("acs_encoder_id", None), acs_access_group_id=d.get("acs_access_group_id", None), - acs_entrance_id=d.get("acs_entrance_id", None), client_session_id=d.get("client_session_id", None), connect_webview_id=d.get("connect_webview_id", None), action_attempt_id=d.get("action_attempt_id", None), @@ -863,6 +851,34 @@ def from_dict(d: Dict[str, Any]): ) +@dataclass +class PhoneRegistration: + is_being_activated: bool + phone_registration_id: str + provider_name: str + provider_state: Any + + @staticmethod + def from_dict(d: Dict[str, Any]): + return PhoneRegistration( + is_being_activated=d.get("is_being_activated", None), + phone_registration_id=d.get("phone_registration_id", None), + provider_name=d.get("provider_name", None), + provider_state=d.get("provider_state", None), + ) + + +@dataclass +class PhoneSession: + provider_sessions: List[Dict[str, Any]] + + @staticmethod + def from_dict(d: Dict[str, Any]): + return PhoneSession( + provider_sessions=d.get("provider_sessions", None), + ) + + @dataclass class ThermostatSchedule: climate_preset_key: str @@ -870,11 +886,12 @@ class ThermostatSchedule: device_id: str ends_at: str errors: List[Dict[str, Any]] + is_override_allowed: bool max_override_period_minutes: int name: str starts_at: str thermostat_schedule_id: str - unstable_is_override_allowed: bool + workspace_id: str @staticmethod def from_dict(d: Dict[str, Any]): @@ -884,11 +901,12 @@ def from_dict(d: Dict[str, Any]): device_id=d.get("device_id", None), ends_at=d.get("ends_at", None), errors=d.get("errors", None), + is_override_allowed=d.get("is_override_allowed", None), max_override_period_minutes=d.get("max_override_period_minutes", None), name=d.get("name", None), starts_at=d.get("starts_at", None), thermostat_schedule_id=d.get("thermostat_schedule_id", None), - unstable_is_override_allowed=d.get("unstable_is_override_allowed", None), + workspace_id=d.get("workspace_id", None), ) @@ -1034,6 +1052,7 @@ class UnmanagedAcsUser: access_schedule: Dict[str, Any] acs_system_id: str acs_user_id: str + connected_account_id: str created_at: str display_name: str email: str @@ -1043,10 +1062,9 @@ class UnmanagedAcsUser: external_type_display_name: str full_name: str hid_acs_system_id: str - is_latest_desired_state_synced_with_provider: bool is_managed: bool is_suspended: bool - latest_desired_state_synced_with_provider_at: str + last_successful_sync_at: str pending_mutations: List[Dict[str, Any]] phone_number: str user_identity_email_address: str @@ -1062,6 +1080,7 @@ def from_dict(d: Dict[str, Any]): access_schedule=DeepAttrDict(d.get("access_schedule", None)), acs_system_id=d.get("acs_system_id", None), acs_user_id=d.get("acs_user_id", None), + connected_account_id=d.get("connected_account_id", None), created_at=d.get("created_at", None), display_name=d.get("display_name", None), email=d.get("email", None), @@ -1071,14 +1090,9 @@ def from_dict(d: Dict[str, Any]): external_type_display_name=d.get("external_type_display_name", None), full_name=d.get("full_name", None), hid_acs_system_id=d.get("hid_acs_system_id", None), - is_latest_desired_state_synced_with_provider=d.get( - "is_latest_desired_state_synced_with_provider", None - ), is_managed=d.get("is_managed", None), is_suspended=d.get("is_suspended", None), - latest_desired_state_synced_with_provider_at=d.get( - "latest_desired_state_synced_with_provider_at", None - ), + last_successful_sync_at=d.get("last_successful_sync_at", None), pending_mutations=d.get("pending_mutations", None), phone_number=d.get("phone_number", None), user_identity_email_address=d.get("user_identity_email_address", None), @@ -1193,6 +1207,7 @@ def from_dict(d: Dict[str, Any]): class Workspace: company_name: str connect_partner_name: str + connect_webview_customization: Dict[str, Any] is_sandbox: bool is_suspended: bool name: str @@ -1203,6 +1218,9 @@ def from_dict(d: Dict[str, Any]): return Workspace( company_name=d.get("company_name", None), connect_partner_name=d.get("connect_partner_name", None), + connect_webview_customization=DeepAttrDict( + d.get("connect_webview_customization", None) + ), is_sandbox=d.get("is_sandbox", None), is_suspended=d.get("is_suspended", None), name=d.get("name", None), @@ -1269,7 +1287,13 @@ def update( class AbstractAcsAccessGroups(abc.ABC): @abc.abstractmethod - def add_user(self, *, acs_access_group_id: str, acs_user_id: str) -> None: + def add_user( + self, + *, + acs_access_group_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: raise NotImplementedError() @abc.abstractmethod @@ -1278,7 +1302,11 @@ def get(self, *, acs_access_group_id: str) -> AcsAccessGroup: @abc.abstractmethod def list( - self, *, acs_system_id: Optional[str] = None, acs_user_id: Optional[str] = None + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None ) -> List[AcsAccessGroup]: raise NotImplementedError() @@ -1293,14 +1321,26 @@ def list_users(self, *, acs_access_group_id: str) -> List[AcsUser]: raise NotImplementedError() @abc.abstractmethod - def remove_user(self, *, acs_access_group_id: str, acs_user_id: str) -> None: + def remove_user( + self, + *, + acs_access_group_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: raise NotImplementedError() class AbstractAcsCredentials(abc.ABC): @abc.abstractmethod - def assign(self, *, acs_credential_id: str, acs_user_id: str) -> None: + def assign( + self, + *, + acs_credential_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: raise NotImplementedError() @abc.abstractmethod @@ -1308,7 +1348,8 @@ def create( self, *, access_method: str, - acs_user_id: str, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, allowed_acs_entrance_ids: Optional[List[str]] = None, assa_abloy_vostio_metadata: Optional[Dict[str, Any]] = None, code: Optional[str] = None, @@ -1317,6 +1358,7 @@ def create( is_multi_phone_sync_credential: Optional[bool] = None, salto_space_metadata: Optional[Dict[str, Any]] = None, starts_at: Optional[str] = None, + user_identity_id: Optional[str] = None, visionline_metadata: Optional[Dict[str, Any]] = None ) -> AcsCredential: raise NotImplementedError() @@ -1347,7 +1389,13 @@ def list_accessible_entrances(self, *, acs_credential_id: str) -> List[AcsEntran raise NotImplementedError() @abc.abstractmethod - def unassign(self, *, acs_credential_id: str, acs_user_id: str) -> None: + def unassign( + self, + *, + acs_credential_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: raise NotImplementedError() @abc.abstractmethod @@ -1363,6 +1411,16 @@ def update( class AbstractAcsEncoders(abc.ABC): + @abc.abstractmethod + def encode_access_method( + self, + *, + access_method_id: str, + acs_encoder_id: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + @abc.abstractmethod def encode_credential( self, @@ -1444,7 +1502,13 @@ def get(self, *, acs_entrance_id: str) -> AcsEntrance: raise NotImplementedError() @abc.abstractmethod - def grant_access(self, *, acs_entrance_id: str, acs_user_id: str) -> None: + def grant_access( + self, + *, + acs_entrance_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: raise NotImplementedError() @abc.abstractmethod @@ -1452,7 +1516,8 @@ def list( self, *, acs_credential_id: Optional[str] = None, - acs_system_id: Optional[str] = None + acs_system_id: Optional[str] = None, + location_id: Optional[str] = None ) -> List[AcsEntrance]: raise NotImplementedError() @@ -1504,11 +1569,23 @@ def create( raise NotImplementedError() @abc.abstractmethod - def delete(self, *, acs_user_id: str) -> None: + def delete( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: raise NotImplementedError() @abc.abstractmethod - def get(self, *, acs_user_id: str) -> AcsUser: + def get( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> AcsUser: raise NotImplementedError() @abc.abstractmethod @@ -1527,38 +1604,68 @@ def list( raise NotImplementedError() @abc.abstractmethod - def list_accessible_entrances(self, *, acs_user_id: str) -> List[AcsEntrance]: + def list_accessible_entrances( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> List[AcsEntrance]: raise NotImplementedError() @abc.abstractmethod def remove_from_access_group( - self, *, acs_access_group_id: str, acs_user_id: str + self, + *, + acs_access_group_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None ) -> None: raise NotImplementedError() @abc.abstractmethod - def revoke_access_to_all_entrances(self, *, acs_user_id: str) -> None: + def revoke_access_to_all_entrances( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: raise NotImplementedError() @abc.abstractmethod - def suspend(self, *, acs_user_id: str) -> None: + def suspend( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: raise NotImplementedError() @abc.abstractmethod - def unsuspend(self, *, acs_user_id: str) -> None: + def unsuspend( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: raise NotImplementedError() @abc.abstractmethod def update( self, *, - acs_user_id: str, access_schedule: Optional[Dict[str, Any]] = None, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, email: Optional[str] = None, email_address: Optional[str] = None, full_name: Optional[str] = None, hid_acs_system_id: Optional[str] = None, - phone_number: Optional[str] = None + phone_number: Optional[str] = None, + user_identity_id: Optional[str] = None ) -> None: raise NotImplementedError() @@ -1579,19 +1686,6 @@ def list(self, *, action_attempt_ids: List[str]) -> List[ActionAttempt]: raise NotImplementedError() -class AbstractBridges(abc.ABC): - - @abc.abstractmethod - def get(self, *, bridge_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - ) -> None: - raise NotImplementedError() - - class AbstractClientSessions(abc.ABC): @abc.abstractmethod @@ -1713,6 +1807,7 @@ def list( self, *, custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_ids: Optional[List[str]] = None, limit: Optional[int] = None, page_cursor: Optional[str] = None, user_identifier_key: Optional[str] = None @@ -1762,6 +1857,7 @@ def list( connected_account_ids: Optional[List[str]] = None, created_before: Optional[str] = None, custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_ids: Optional[List[str]] = None, device_ids: Optional[List[str]] = None, device_type: Optional[str] = None, device_types: Optional[List[str]] = None, @@ -1769,6 +1865,7 @@ def list( include_if: Optional[List[str]] = None, limit: Optional[float] = None, manufacturer: Optional[str] = None, + page_cursor: Optional[str] = None, unstable_location_id: Optional[str] = None, user_identifier_key: Optional[str] = None ) -> List[UnmanagedDevice]: @@ -1802,6 +1899,7 @@ def list( between: Optional[List[str]] = None, connect_webview_id: Optional[str] = None, connected_account_id: Optional[str] = None, + customer_ids: Optional[List[str]] = None, device_id: Optional[str] = None, device_ids: Optional[List[str]] = None, event_ids: Optional[List[str]] = None, @@ -1831,6 +1929,7 @@ def list( connected_account_ids: Optional[List[str]] = None, created_before: Optional[str] = None, custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_ids: Optional[List[str]] = None, device_ids: Optional[List[str]] = None, device_type: Optional[str] = None, device_types: Optional[List[str]] = None, @@ -1838,6 +1937,7 @@ def list( include_if: Optional[List[str]] = None, limit: Optional[float] = None, manufacturer: Optional[str] = None, + page_cursor: Optional[str] = None, unstable_location_id: Optional[str] = None, user_identifier_key: Optional[str] = None ) -> List[Device]: @@ -1946,6 +2046,30 @@ def create_sandbox_phone( raise NotImplementedError() +class AbstractThermostatsDailyPrograms(abc.ABC): + + @abc.abstractmethod + def create( + self, *, device_id: str, name: str, periods: List[Dict[str, Any]] + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def delete(self, *, thermostat_daily_program_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + name: str, + periods: List[Dict[str, Any]], + thermostat_daily_program_id: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + class AbstractThermostatsSchedules(abc.ABC): @abc.abstractmethod @@ -2078,6 +2202,7 @@ def create( name: str, company_name: Optional[str] = None, connect_partner_name: Optional[str] = None, + connect_webview_customization: Optional[Dict[str, Any]] = None, is_sandbox: Optional[bool] = None, webview_logo_shape: Optional[str] = None, webview_primary_button_color: Optional[str] = None, @@ -2145,6 +2270,7 @@ def add_acs_user(self, *, acs_user_id: str, user_identity_id: str) -> None: def create( self, *, + acs_system_ids: Optional[List[str]] = None, email_address: Optional[str] = None, full_name: Optional[str] = None, phone_number: Optional[str] = None, @@ -2157,7 +2283,9 @@ def delete(self, *, user_identity_id: str) -> None: raise NotImplementedError() @abc.abstractmethod - def generate_instant_key(self, *, user_identity_id: str) -> InstantKey: + def generate_instant_key( + self, *, user_identity_id: str, max_use_count: Optional[float] = None + ) -> InstantKey: raise NotImplementedError() @abc.abstractmethod @@ -2301,6 +2429,8 @@ def list( *, access_code_ids: Optional[List[str]] = None, device_id: Optional[str] = None, + limit: Optional[float] = None, + page_cursor: Optional[str] = None, user_identifier_key: Optional[str] = None ) -> List[AccessCode]: raise NotImplementedError() @@ -2309,6 +2439,17 @@ def list( def pull_backup_access_code(self, *, access_code_id: str) -> AccessCode: raise NotImplementedError() + @abc.abstractmethod + def report_device_constraints( + self, + *, + device_id: str, + max_code_length: Optional[int] = None, + min_code_length: Optional[int] = None, + supported_code_lengths: Optional[List[int]] = None + ) -> None: + raise NotImplementedError() + @abc.abstractmethod def update( self, @@ -2374,6 +2515,7 @@ def list( connected_account_ids: Optional[List[str]] = None, created_before: Optional[str] = None, custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_ids: Optional[List[str]] = None, device_ids: Optional[List[str]] = None, device_type: Optional[str] = None, device_types: Optional[List[str]] = None, @@ -2381,6 +2523,7 @@ def list( include_if: Optional[List[str]] = None, limit: Optional[float] = None, manufacturer: Optional[str] = None, + page_cursor: Optional[str] = None, unstable_location_id: Optional[str] = None, user_identifier_key: Optional[str] = None ) -> List[Device]: @@ -2426,6 +2569,7 @@ def list( connected_account_ids: Optional[List[str]] = None, created_before: Optional[str] = None, custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_ids: Optional[List[str]] = None, device_ids: Optional[List[str]] = None, device_type: Optional[str] = None, device_types: Optional[List[str]] = None, @@ -2433,6 +2577,7 @@ def list( include_if: Optional[List[str]] = None, limit: Optional[float] = None, manufacturer: Optional[str] = None, + page_cursor: Optional[str] = None, unstable_location_id: Optional[str] = None, user_identifier_key: Optional[str] = None ) -> List[Device]: @@ -2441,6 +2586,11 @@ def list( class AbstractThermostats(abc.ABC): + @property + @abc.abstractmethod + def daily_programs(self) -> AbstractThermostatsDailyPrograms: + raise NotImplementedError() + @property @abc.abstractmethod def schedules(self) -> AbstractThermostatsSchedules: @@ -2529,6 +2679,7 @@ def list( connected_account_ids: Optional[List[str]] = None, created_before: Optional[str] = None, custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_ids: Optional[List[str]] = None, device_ids: Optional[List[str]] = None, device_type: Optional[str] = None, device_types: Optional[List[str]] = None, @@ -2536,6 +2687,7 @@ def list( include_if: Optional[List[str]] = None, limit: Optional[float] = None, manufacturer: Optional[str] = None, + page_cursor: Optional[str] = None, unstable_location_id: Optional[str] = None, user_identifier_key: Optional[str] = None ) -> List[Device]: @@ -2612,6 +2764,22 @@ def update_climate_preset( ) -> None: raise NotImplementedError() + @abc.abstractmethod + def update_weekly_program( + self, + *, + device_id: str, + friday_program_id: Optional[str] = None, + monday_program_id: Optional[str] = None, + saturday_program_id: Optional[str] = None, + sunday_program_id: Optional[str] = None, + thursday_program_id: Optional[str] = None, + tuesday_program_id: Optional[str] = None, + wednesday_program_id: Optional[str] = None, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + class AbstractAcs(abc.ABC): @@ -2651,7 +2819,6 @@ class AbstractRoutes(abc.ABC): access_codes: AbstractAccessCodes acs: AbstractAcs action_attempts: AbstractActionAttempts - bridges: AbstractBridges client_sessions: AbstractClientSessions connect_webviews: AbstractConnectWebviews connected_accounts: AbstractConnectedAccounts diff --git a/seam/routes/noise_sensors.py b/seam/routes/noise_sensors.py index 168d6e88..2087c911 100644 --- a/seam/routes/noise_sensors.py +++ b/seam/routes/noise_sensors.py @@ -30,6 +30,7 @@ def list( connected_account_ids: Optional[List[str]] = None, created_before: Optional[str] = None, custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_ids: Optional[List[str]] = None, device_ids: Optional[List[str]] = None, device_type: Optional[str] = None, device_types: Optional[List[str]] = None, @@ -37,6 +38,7 @@ def list( include_if: Optional[List[str]] = None, limit: Optional[float] = None, manufacturer: Optional[str] = None, + page_cursor: Optional[str] = None, unstable_location_id: Optional[str] = None, user_identifier_key: Optional[str] = None ) -> List[Device]: @@ -52,6 +54,8 @@ def list( json_payload["created_before"] = created_before if custom_metadata_has is not None: json_payload["custom_metadata_has"] = custom_metadata_has + if customer_ids is not None: + json_payload["customer_ids"] = customer_ids if device_ids is not None: json_payload["device_ids"] = device_ids if device_type is not None: @@ -66,6 +70,8 @@ def list( json_payload["limit"] = limit if manufacturer is not None: json_payload["manufacturer"] = manufacturer + if page_cursor is not None: + json_payload["page_cursor"] = page_cursor if unstable_location_id is not None: json_payload["unstable_location_id"] = unstable_location_id if user_identifier_key is not None: diff --git a/seam/routes/thermostats.py b/seam/routes/thermostats.py index e73bf1fb..ada02d3a 100644 --- a/seam/routes/thermostats.py +++ b/seam/routes/thermostats.py @@ -1,6 +1,7 @@ from typing import Optional, Any, List, Dict, Union from ..client import SeamHttpClient from .models import AbstractThermostats, ActionAttempt, Device +from .thermostats_daily_programs import ThermostatsDailyPrograms from .thermostats_schedules import ThermostatsSchedules from .thermostats_simulate import ThermostatsSimulate from ..modules.action_attempts import resolve_action_attempt @@ -10,9 +11,16 @@ class Thermostats(AbstractThermostats): def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): self.client = client self.defaults = defaults + self._daily_programs = ThermostatsDailyPrograms( + client=client, defaults=defaults + ) self._schedules = ThermostatsSchedules(client=client, defaults=defaults) self._simulate = ThermostatsSimulate(client=client, defaults=defaults) + @property + def daily_programs(self) -> ThermostatsDailyPrograms: + return self._daily_programs + @property def schedules(self) -> ThermostatsSchedules: return self._schedules @@ -220,6 +228,7 @@ def list( connected_account_ids: Optional[List[str]] = None, created_before: Optional[str] = None, custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_ids: Optional[List[str]] = None, device_ids: Optional[List[str]] = None, device_type: Optional[str] = None, device_types: Optional[List[str]] = None, @@ -227,6 +236,7 @@ def list( include_if: Optional[List[str]] = None, limit: Optional[float] = None, manufacturer: Optional[str] = None, + page_cursor: Optional[str] = None, unstable_location_id: Optional[str] = None, user_identifier_key: Optional[str] = None ) -> List[Device]: @@ -242,6 +252,8 @@ def list( json_payload["created_before"] = created_before if custom_metadata_has is not None: json_payload["custom_metadata_has"] = custom_metadata_has + if customer_ids is not None: + json_payload["customer_ids"] = customer_ids if device_ids is not None: json_payload["device_ids"] = device_ids if device_type is not None: @@ -256,6 +268,8 @@ def list( json_payload["limit"] = limit if manufacturer is not None: json_payload["manufacturer"] = manufacturer + if page_cursor is not None: + json_payload["page_cursor"] = page_cursor if unstable_location_id is not None: json_payload["unstable_location_id"] = unstable_location_id if user_identifier_key is not None: @@ -447,3 +461,49 @@ def update_climate_preset( self.client.post("/thermostats/update_climate_preset", json=json_payload) return None + + def update_weekly_program( + self, + *, + device_id: str, + friday_program_id: Optional[str] = None, + monday_program_id: Optional[str] = None, + saturday_program_id: Optional[str] = None, + sunday_program_id: Optional[str] = None, + thursday_program_id: Optional[str] = None, + tuesday_program_id: Optional[str] = None, + wednesday_program_id: Optional[str] = None, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + json_payload = {} + + if device_id is not None: + json_payload["device_id"] = device_id + if friday_program_id is not None: + json_payload["friday_program_id"] = friday_program_id + if monday_program_id is not None: + json_payload["monday_program_id"] = monday_program_id + if saturday_program_id is not None: + json_payload["saturday_program_id"] = saturday_program_id + if sunday_program_id is not None: + json_payload["sunday_program_id"] = sunday_program_id + if thursday_program_id is not None: + json_payload["thursday_program_id"] = thursday_program_id + if tuesday_program_id is not None: + json_payload["tuesday_program_id"] = tuesday_program_id + if wednesday_program_id is not None: + json_payload["wednesday_program_id"] = wednesday_program_id + + res = self.client.post("/thermostats/update_weekly_program", json=json_payload) + + wait_for_action_attempt = ( + self.defaults.get("wait_for_action_attempt") + if wait_for_action_attempt is None + else wait_for_action_attempt + ) + + return resolve_action_attempt( + client=self.client, + action_attempt=ActionAttempt.from_dict(res["action_attempt"]), + wait_for_action_attempt=wait_for_action_attempt, + ) diff --git a/seam/routes/thermostats_daily_programs.py b/seam/routes/thermostats_daily_programs.py new file mode 100644 index 00000000..efb660be --- /dev/null +++ b/seam/routes/thermostats_daily_programs.py @@ -0,0 +1,68 @@ +from typing import Optional, Any, List, Dict, Union +from ..client import SeamHttpClient +from .models import AbstractThermostatsDailyPrograms, ActionAttempt + +from ..modules.action_attempts import resolve_action_attempt + + +class ThermostatsDailyPrograms(AbstractThermostatsDailyPrograms): + def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): + self.client = client + self.defaults = defaults + + def create( + self, *, device_id: str, name: str, periods: List[Dict[str, Any]] + ) -> None: + json_payload = {} + + if device_id is not None: + json_payload["device_id"] = device_id + if name is not None: + json_payload["name"] = name + if periods is not None: + json_payload["periods"] = periods + + self.client.post("/thermostats/daily_programs/create", json=json_payload) + + return None + + def delete(self, *, thermostat_daily_program_id: str) -> None: + json_payload = {} + + if thermostat_daily_program_id is not None: + json_payload["thermostat_daily_program_id"] = thermostat_daily_program_id + + self.client.post("/thermostats/daily_programs/delete", json=json_payload) + + return None + + def update( + self, + *, + name: str, + periods: List[Dict[str, Any]], + thermostat_daily_program_id: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + json_payload = {} + + if name is not None: + json_payload["name"] = name + if periods is not None: + json_payload["periods"] = periods + if thermostat_daily_program_id is not None: + json_payload["thermostat_daily_program_id"] = thermostat_daily_program_id + + res = self.client.post("/thermostats/daily_programs/update", json=json_payload) + + wait_for_action_attempt = ( + self.defaults.get("wait_for_action_attempt") + if wait_for_action_attempt is None + else wait_for_action_attempt + ) + + return resolve_action_attempt( + client=self.client, + action_attempt=ActionAttempt.from_dict(res["action_attempt"]), + wait_for_action_attempt=wait_for_action_attempt, + ) diff --git a/seam/routes/user_identities.py b/seam/routes/user_identities.py index 77901923..a6f04c9d 100644 --- a/seam/routes/user_identities.py +++ b/seam/routes/user_identities.py @@ -38,6 +38,7 @@ def add_acs_user(self, *, acs_user_id: str, user_identity_id: str) -> None: def create( self, *, + acs_system_ids: Optional[List[str]] = None, email_address: Optional[str] = None, full_name: Optional[str] = None, phone_number: Optional[str] = None, @@ -45,6 +46,8 @@ def create( ) -> UserIdentity: json_payload = {} + if acs_system_ids is not None: + json_payload["acs_system_ids"] = acs_system_ids if email_address is not None: json_payload["email_address"] = email_address if full_name is not None: @@ -68,11 +71,15 @@ def delete(self, *, user_identity_id: str) -> None: return None - def generate_instant_key(self, *, user_identity_id: str) -> InstantKey: + def generate_instant_key( + self, *, user_identity_id: str, max_use_count: Optional[float] = None + ) -> InstantKey: json_payload = {} if user_identity_id is not None: json_payload["user_identity_id"] = user_identity_id + if max_use_count is not None: + json_payload["max_use_count"] = max_use_count res = self.client.post( "/user_identities/generate_instant_key", json=json_payload diff --git a/seam/routes/workspaces.py b/seam/routes/workspaces.py index 652fb48a..c41b28bf 100644 --- a/seam/routes/workspaces.py +++ b/seam/routes/workspaces.py @@ -16,6 +16,7 @@ def create( name: str, company_name: Optional[str] = None, connect_partner_name: Optional[str] = None, + connect_webview_customization: Optional[Dict[str, Any]] = None, is_sandbox: Optional[bool] = None, webview_logo_shape: Optional[str] = None, webview_primary_button_color: Optional[str] = None, @@ -30,6 +31,10 @@ def create( json_payload["company_name"] = company_name if connect_partner_name is not None: json_payload["connect_partner_name"] = connect_partner_name + if connect_webview_customization is not None: + json_payload["connect_webview_customization"] = ( + connect_webview_customization + ) if is_sandbox is not None: json_payload["is_sandbox"] = is_sandbox if webview_logo_shape is not None: