1616from homeassistant .helpers .update_coordinator import DataUpdateCoordinator , UpdateFailed
1717from surepy import Surepy
1818from surepy .entities import SurepyEntity
19- from surepy .enums import EntityType , LockState
19+ from surepy .enums import EntityType , Location , LockState
2020from surepy .exceptions import SurePetcareAuthenticationError , SurePetcareError
2121import voluptuous as vol
2222
2323# pylint: disable=import-error
2424from .const import (
2525 ATTR_FLAP_ID ,
2626 ATTR_LOCK_STATE ,
27+ ATTR_PET_ID ,
28+ ATTR_WHERE ,
2729 DOMAIN ,
30+ SERVICE_PET_LOCATION ,
2831 SERVICE_SET_LOCK_STATE ,
2932 SPC ,
3033 SURE_API_TIMEOUT ,
@@ -130,19 +133,25 @@ def __init__(
130133
131134 self .states : dict [int , Any ] = {}
132135
136+ async def set_pet_location (self , pet_id : int , location : Location ) -> None :
137+ """Update the lock state of a flap."""
138+
139+ await self .surepy .sac .set_pet_location (pet_id , location )
140+
133141 async def set_lock_state (self , flap_id : int , state : str ) -> None :
134142 """Update the lock state of a flap."""
135143
136144 # https://github.com/PyCQA/pylint/issues/2062
137145 # pylint: disable=no-member
138- if state == LockState .UNLOCKED .name .lower ():
139- await self .surepy .sac .unlock (flap_id )
140- elif state == LockState .LOCKED_IN .name .lower ():
141- await self .surepy .sac .lock_in (flap_id )
142- elif state == LockState .LOCKED_OUT .name .lower ():
143- await self .surepy .sac .lock_out (flap_id )
144- elif state == LockState .LOCKED_ALL .name .lower ():
145- await self .surepy .sac .lock (flap_id )
146+ lock_states = {
147+ LockState .UNLOCKED .name .lower (): self .surepy .sac .unlock ,
148+ LockState .LOCKED_IN .name .lower (): self .surepy .sac .lock_in ,
149+ LockState .LOCKED_OUT .name .lower (): self .surepy .sac .lock_out ,
150+ LockState .LOCKED_ALL .name .lower (): self .surepy .sac .lock ,
151+ }
152+
153+ # elegant functions dict to choose the right function | idea by @janiversen
154+ await lock_states [state .lower ()](flap_id )
146155
147156 async def async_setup (self ) -> bool :
148157 """Set up the Sure Petcare integration."""
@@ -174,6 +183,54 @@ async def async_setup(self) -> bool:
174183 # )
175184 # )
176185
186+ surepy_entities : list [SurepyEntity ] = self .coordinator .data .values ()
187+
188+ pet_ids = [
189+ entity .id for entity in surepy_entities if entity .type == EntityType .PET
190+ ]
191+
192+ pet_location_service_schema = vol .Schema (
193+ {
194+ vol .Required (ATTR_PET_ID ): vol .Any (cv .positive_int , vol .In (pet_ids )),
195+ vol .Required (ATTR_WHERE ): vol .Any (
196+ cv .string ,
197+ vol .In (
198+ [
199+ # https://github.com/PyCQA/pylint/issues/2062
200+ # pylint: disable=no-member
201+ Location .INSIDE .name .title (),
202+ Location .OUTSIDE .name .title (),
203+ # Location.UNKNOWN.name.title(),
204+ ]
205+ ),
206+ ),
207+ }
208+ )
209+
210+ async def handle_set_pet_location (call : Any ) -> None :
211+ """Call when setting the lock state."""
212+
213+ try :
214+
215+ if (pet_id := int (call .data .get (ATTR_PET_ID ))) and (
216+ where := str (call .data .get (ATTR_WHERE ))
217+ ):
218+
219+ await self .set_pet_location (pet_id , Location [where .upper ()])
220+ await self .coordinator .async_request_refresh ()
221+
222+ except ValueError as error :
223+ _LOGGER .error (
224+ "🐾 \x1b [38;2;255;26;102m·\x1b [0m arguments of wrong type: %s" , error
225+ )
226+
227+ self .hass .services .async_register (
228+ DOMAIN ,
229+ SERVICE_PET_LOCATION ,
230+ handle_set_pet_location ,
231+ schema = pet_location_service_schema ,
232+ )
233+
177234 async def handle_set_lock_state (call : Any ) -> None :
178235 """Call when setting the lock state."""
179236
@@ -183,7 +240,6 @@ async def handle_set_lock_state(call: Any) -> None:
183240 await self .set_lock_state (flap_id , lock_state )
184241 await self .coordinator .async_request_refresh ()
185242
186- surepy_entities : list [SurepyEntity ] = self .coordinator .data .values ()
187243 flap_ids = [
188244 entity .id
189245 for entity in surepy_entities
0 commit comments