Skip to content

Commit

Permalink
add service to set pet location, see #5
Browse files Browse the repository at this point in the history
  • Loading branch information
benleb committed Sep 9, 2021
1 parent bba9b0d commit 4d620be
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 11 deletions.
76 changes: 66 additions & 10 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,18 @@
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from surepy import Surepy
from surepy.entities import SurepyEntity
from surepy.enums import EntityType, LockState
from surepy.enums import EntityType, Location, LockState
from surepy.exceptions import SurePetcareAuthenticationError, SurePetcareError
import voluptuous as vol

# pylint: disable=import-error
from .const import (
ATTR_FLAP_ID,
ATTR_LOCK_STATE,
ATTR_PET_ID,
ATTR_WHERE,
DOMAIN,
SERVICE_PET_LOCATION,
SERVICE_SET_LOCK_STATE,
SPC,
SURE_API_TIMEOUT,
Expand Down Expand Up @@ -130,19 +133,25 @@ def __init__(

self.states: dict[int, Any] = {}

async def set_pet_location(self, pet_id: int, location: Location) -> None:
"""Update the lock state of a flap."""

await self.surepy.sac.set_pet_location(pet_id, location)

async def set_lock_state(self, flap_id: int, state: str) -> None:
"""Update the lock state of a flap."""

# https://github.com/PyCQA/pylint/issues/2062
# pylint: disable=no-member
if state == LockState.UNLOCKED.name.lower():
await self.surepy.sac.unlock(flap_id)
elif state == LockState.LOCKED_IN.name.lower():
await self.surepy.sac.lock_in(flap_id)
elif state == LockState.LOCKED_OUT.name.lower():
await self.surepy.sac.lock_out(flap_id)
elif state == LockState.LOCKED_ALL.name.lower():
await self.surepy.sac.lock(flap_id)
lock_states = {
LockState.UNLOCKED.name.lower(): self.surepy.sac.unlock,
LockState.LOCKED_IN.name.lower(): self.surepy.sac.lock_in,
LockState.LOCKED_OUT.name.lower(): self.surepy.sac.lock_out,
LockState.LOCKED_ALL.name.lower(): self.surepy.sac.lock,
}

# elegant functions dict to choose the right function | idea by @janiversen
await lock_states[state.lower()](flap_id)

async def async_setup(self) -> bool:
"""Set up the Sure Petcare integration."""
Expand Down Expand Up @@ -174,6 +183,54 @@ async def async_setup(self) -> bool:
# )
# )

surepy_entities: list[SurepyEntity] = self.coordinator.data.values()

pet_ids = [
entity.id for entity in surepy_entities if entity.type == EntityType.PET
]

pet_location_service_schema = vol.Schema(
{
vol.Required(ATTR_PET_ID): vol.Any(cv.positive_int, vol.In(pet_ids)),
vol.Required(ATTR_WHERE): vol.Any(
cv.string,
vol.In(
[
# https://github.com/PyCQA/pylint/issues/2062
# pylint: disable=no-member
Location.INSIDE.name.title(),
Location.OUTSIDE.name.title(),
# Location.UNKNOWN.name.title(),
]
),
),
}
)

async def handle_set_pet_location(call: Any) -> None:
"""Call when setting the lock state."""

try:

if (pet_id := int(call.data.get(ATTR_PET_ID))) and (
where := str(call.data.get(ATTR_WHERE))
):

await self.set_pet_location(pet_id, Location[where.upper()])
await self.coordinator.async_request_refresh()

except ValueError as error:
_LOGGER.error(
"🐾 \x1b[38;2;255;26;102m·\x1b[0m arguments of wrong type: %s", error
)

self.hass.services.async_register(
DOMAIN,
SERVICE_PET_LOCATION,
handle_set_pet_location,
schema=pet_location_service_schema,
)

async def handle_set_lock_state(call: Any) -> None:
"""Call when setting the lock state."""

Expand All @@ -183,7 +240,6 @@ async def handle_set_lock_state(call: Any) -> None:
await self.set_lock_state(flap_id, lock_state)
await self.coordinator.async_request_refresh()

surepy_entities: list[SurepyEntity] = self.coordinator.data.values()
flap_ids = [
entity.id
for entity in surepy_entities
Expand Down
6 changes: 5 additions & 1 deletion const.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
SURE_BATT_VOLTAGE_LOW = 1.25
SURE_BATT_VOLTAGE_DIFF = SURE_BATT_VOLTAGE_FULL - SURE_BATT_VOLTAGE_LOW

# lock state service
# services
SERVICE_SET_LOCK_STATE = "set_lock_state"
ATTR_FLAP_ID = "flap_id"
ATTR_LOCK_STATE = "lock_state"

SERVICE_PET_LOCATION = "set_pet_location"
ATTR_PET_ID = "pet_id"
ATTR_WHERE = "where"
17 changes: 17 additions & 0 deletions services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,20 @@ set_lock_state:
selector:
select:
{ options: ["locked_all", "locked_in", "locked_out", "unlocked"] }
set_pet_location:
name: Set Pet location
description: Sets the location of a pet
fields:
pet_id:
name: Pet ID
description: Pet ID to set the location for
required: true
example: 31337
selector:
text:
where:
name: Location
description: Current location of the pet
required: true
example: "Inside"
selector: { select: { options: ["Inside", "Outside"] } }

0 comments on commit 4d620be

Please sign in to comment.