From 149f37bb3be6daa09c8deeb0c32868a12b2b2a83 Mon Sep 17 00:00:00 2001 From: Alex Cartwright Date: Tue, 9 Dec 2025 17:20:38 +0000 Subject: [PATCH] Add methods to set device tag profiles This includes 2 helper functions to mark a Pet as Indoor or Outdoor mode on a given Flap device --- surepy/client.py | 36 ++++++++++++++++++++++++++++++++++-- surepy/const.py | 3 +++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/surepy/client.py b/surepy/client.py index c4bc1a8..bd006c0 100644 --- a/surepy/client.py +++ b/surepy/client.py @@ -23,6 +23,9 @@ import aiohttp import async_timeout +from surepy.entities.devices import Flap +from surepy.entities.pet import Pet + from .const import ( ACCEPT, ACCEPT_ENCODING, @@ -43,6 +46,8 @@ ORIGIN, PET_RESOURCE, POSITION_RESOURCE, + PROFILE_INDOOR, + PROFILE_OUTDOOR, REFERER, SUREPY_USER_AGENT, USER_AGENT, @@ -412,13 +417,40 @@ async def set_curfew( # return None raise SurePetcareError("ERROR SETTING CURFEW - PLEASE CHECK IMMEDIATELY!") - async def _add_tag_to_device(self, device_id: int, tag_id: int) -> dict[str, Any] | None: + async def set_device_tag_profile( + self, device_id: int, tag_id: int, profile: int + ) -> dict[str, Any] | None: + """Set the profile for a tag on a device""" + data = {"profile": profile} + + if response := await self._add_tag_to_device( + device_id=device_id, tag_id=tag_id, data=data + ): + return response + + raise SurePetcareError(f"ERROR SETTING PROFILE FOR TAG {tag_id} ON DEVICE {device_id}") + + async def set_pet_indoor_mode(self, device: Flap, pet: Pet) -> dict[str, Any] | None: + """Set pet to indoor-only mode on a device (can enter but not exit)""" + if pet.tag_id is None: + raise SurePetcareError(f"Pet {pet.name} does not have a tag_id") + return await self.set_device_tag_profile(device.id, pet.tag_id, profile=PROFILE_INDOOR) + + async def set_pet_outdoor_mode(self, device: Flap, pet: Pet) -> dict[str, Any] | None: + """Set pet to outdoor/normal mode on a device (can enter and exit)""" + if pet.tag_id is None: + raise SurePetcareError(f"Pet {pet.name} does not have a tag_id") + return await self.set_device_tag_profile(device.id, pet.tag_id, profile=PROFILE_OUTDOOR) + + async def _add_tag_to_device( + self, device_id: int, tag_id: int, data: dict[str, Any] | None = None + ) -> dict[str, Any] | None: """Add the specified tag ID to the specified device ID""" resource = DEVICE_TAG_RESOURCE.format( BASE_RESOURCE=BASE_RESOURCE, device_id=device_id, tag_id=tag_id ) - if response := await self.call(method="PUT", resource=resource): + if response := await self.call(method="PUT", resource=resource, json=data): return response async def _remove_tag_from_device(self, device_id: int, tag_id: int) -> dict[str, Any] | None: diff --git a/surepy/const.py b/surepy/const.py index 68f1c67..4c33f31 100644 --- a/surepy/const.py +++ b/surepy/const.py @@ -20,6 +20,9 @@ ATTRIBUTES_RESOURCE: str = f"{BASE_RESOURCE}/start" DEVICE_TAG_RESOURCE: str = "{BASE_RESOURCE}/device/{device_id}/tag/{tag_id}" +# Pet profile modes for device tags +PROFILE_OUTDOOR = 2 # pet can enter and exit +PROFILE_INDOOR = 3 # pet can enter but cannot exit API_TIMEOUT = 45