Skip to content

Commit 4d620be

Browse files
committed
add service to set pet location, see #5
1 parent bba9b0d commit 4d620be

File tree

3 files changed

+88
-11
lines changed

3 files changed

+88
-11
lines changed

__init__.py

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,18 @@
1616
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
1717
from surepy import Surepy
1818
from surepy.entities import SurepyEntity
19-
from surepy.enums import EntityType, LockState
19+
from surepy.enums import EntityType, Location, LockState
2020
from surepy.exceptions import SurePetcareAuthenticationError, SurePetcareError
2121
import voluptuous as vol
2222

2323
# pylint: disable=import-error
2424
from .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

const.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
SURE_BATT_VOLTAGE_LOW = 1.25
1818
SURE_BATT_VOLTAGE_DIFF = SURE_BATT_VOLTAGE_FULL - SURE_BATT_VOLTAGE_LOW
1919

20-
# lock state service
20+
# services
2121
SERVICE_SET_LOCK_STATE = "set_lock_state"
2222
ATTR_FLAP_ID = "flap_id"
2323
ATTR_LOCK_STATE = "lock_state"
24+
25+
SERVICE_PET_LOCATION = "set_pet_location"
26+
ATTR_PET_ID = "pet_id"
27+
ATTR_WHERE = "where"

services.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,20 @@ set_lock_state:
1616
selector:
1717
select:
1818
{ options: ["locked_all", "locked_in", "locked_out", "unlocked"] }
19+
set_pet_location:
20+
name: Set Pet location
21+
description: Sets the location of a pet
22+
fields:
23+
pet_id:
24+
name: Pet ID
25+
description: Pet ID to set the location for
26+
required: true
27+
example: 31337
28+
selector:
29+
text:
30+
where:
31+
name: Location
32+
description: Current location of the pet
33+
required: true
34+
example: "Inside"
35+
selector: { select: { options: ["Inside", "Outside"] } }

0 commit comments

Comments
 (0)