1
mirror of https://github.com/home-assistant/core synced 2024-08-02 23:40:32 +02:00

Surepetcare, service to set pet location (#56198)

* Surepetcare, add handle_set_pet_location

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* Surepetcare, add handle_set_pet_location

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* Surepetcare, add handle_set_pet_location

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
This commit is contained in:
Daniel Hjelseth Høyer 2021-09-18 17:48:58 +02:00 committed by GitHub
parent 811feb69ba
commit f97cce6f57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 113 additions and 41 deletions

View File

@ -5,7 +5,7 @@ from datetime import timedelta
import logging
from surepy import Surepy, SurepyEntity
from surepy.enums import LockState
from surepy.enums import EntityType, Location, LockState
from surepy.exceptions import SurePetcareAuthenticationError, SurePetcareError
import voluptuous as vol
@ -20,17 +20,21 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.service import ServiceCall
from homeassistant.helpers.typing import ConfigType
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import (
ATTR_FLAP_ID,
ATTR_LOCATION,
ATTR_LOCK_STATE,
ATTR_PET_NAME,
CONF_FEEDERS,
CONF_FLAPS,
CONF_PETS,
DOMAIN,
SERVICE_SET_LOCK_STATE,
SERVICE_SET_PET_LOCATION,
SURE_API_TIMEOUT,
)
@ -91,12 +95,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.data.setdefault(DOMAIN, {})
try:
surepy = Surepy(
entry.data[CONF_USERNAME],
entry.data[CONF_PASSWORD],
auth_token=entry.data[CONF_TOKEN],
api_timeout=SURE_API_TIMEOUT,
session=async_get_clientsession(hass),
hass.data[DOMAIN][entry.entry_id] = coordinator = SurePetcareDataCoordinator(
entry,
hass,
)
except SurePetcareAuthenticationError:
_LOGGER.error("Unable to connect to surepetcare.io: Wrong credentials!")
@ -105,40 +106,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
_LOGGER.error("Unable to connect to surepetcare.io: Wrong %s!", error)
return False
async def _update_method() -> dict[int, SurepyEntity]:
"""Get the latest data from Sure Petcare."""
try:
return await surepy.get_entities(refresh=True)
except SurePetcareError as err:
raise UpdateFailed(f"Unable to fetch data: {err}") from err
coordinator = DataUpdateCoordinator(
hass,
_LOGGER,
name=DOMAIN,
update_method=_update_method,
update_interval=SCAN_INTERVAL,
)
hass.data[DOMAIN][entry.entry_id] = coordinator
await coordinator.async_config_entry_first_refresh()
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
lock_states = {
LockState.UNLOCKED.name.lower(): surepy.sac.unlock,
LockState.LOCKED_IN.name.lower(): surepy.sac.lock_in,
LockState.LOCKED_OUT.name.lower(): surepy.sac.lock_out,
LockState.LOCKED_ALL.name.lower(): surepy.sac.lock,
}
async def handle_set_lock_state(call):
"""Call when setting the lock state."""
flap_id = call.data[ATTR_FLAP_ID]
state = call.data[ATTR_LOCK_STATE]
await lock_states[state](flap_id)
await coordinator.async_request_refresh()
lock_state_service_schema = vol.Schema(
{
vol.Required(ATTR_FLAP_ID): vol.All(
@ -147,18 +118,35 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
vol.Required(ATTR_LOCK_STATE): vol.All(
cv.string,
vol.Lower,
vol.In(lock_states.keys()),
vol.In(coordinator.lock_states.keys()),
),
}
)
hass.services.async_register(
DOMAIN,
SERVICE_SET_LOCK_STATE,
handle_set_lock_state,
coordinator.handle_set_lock_state,
schema=lock_state_service_schema,
)
set_pet_location_schema = vol.Schema(
{
vol.Optional(ATTR_PET_NAME): vol.In(coordinator.get_pets().values()),
vol.Required(ATTR_LOCATION): vol.In(
[
Location.INSIDE.name.title(),
Location.OUTSIDE.name.title(),
]
),
}
)
hass.services.async_register(
DOMAIN,
SERVICE_SET_PET_LOCATION,
coordinator.handle_set_pet_location,
schema=set_pet_location_schema,
)
return True
@ -169,3 +157,64 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
class SurePetcareDataCoordinator(DataUpdateCoordinator):
"""Handle Surepetcare data."""
def __init__(self, entry: ConfigEntry, hass: HomeAssistant) -> None:
"""Initialize the data handler."""
self.surepy = Surepy(
entry.data[CONF_USERNAME],
entry.data[CONF_PASSWORD],
auth_token=entry.data[CONF_TOKEN],
api_timeout=SURE_API_TIMEOUT,
session=async_get_clientsession(hass),
)
self.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,
}
super().__init__(
hass,
_LOGGER,
name=DOMAIN,
update_interval=SCAN_INTERVAL,
)
async def _async_update_data(self) -> dict[int, SurepyEntity]:
"""Get the latest data from Sure Petcare."""
try:
return await self.surepy.get_entities(refresh=True)
except SurePetcareError as err:
raise UpdateFailed(f"Unable to fetch data: {err}") from err
async def handle_set_lock_state(self, call: ServiceCall) -> None:
"""Call when setting the lock state."""
flap_id = call.data[ATTR_FLAP_ID]
state = call.data[ATTR_LOCK_STATE]
await self.lock_states[state](flap_id)
await self.async_request_refresh()
def get_pets(self) -> dict[int, str]:
"""Get pets."""
names = {}
for surepy_entity in self.data.values():
if surepy_entity.type == EntityType.PET and surepy_entity.name:
names[surepy_entity.id] = surepy_entity.name
return names
async def handle_set_pet_location(self, call: ServiceCall) -> None:
"""Call when setting the pet location."""
pet_name = call.data[ATTR_PET_NAME]
location = call.data[ATTR_LOCATION]
for device_id, device_name in self.get_pets().items():
if pet_name == device_name:
await self.surepy.sac.set_pet_location(
device_id, Location[location.upper()]
)
await self.async_request_refresh()
return
_LOGGER.error("Unknown pet %s", pet_name)

View File

@ -13,7 +13,10 @@ SURE_BATT_VOLTAGE_FULL = 1.6 # voltage
SURE_BATT_VOLTAGE_LOW = 1.25 # voltage
SURE_BATT_VOLTAGE_DIFF = SURE_BATT_VOLTAGE_FULL - SURE_BATT_VOLTAGE_LOW
# lock state service
# state service
SERVICE_SET_LOCK_STATE = "set_lock_state"
SERVICE_SET_PET_LOCATION = "set_pet_location"
ATTR_FLAP_ID = "flap_id"
ATTR_LOCATION = "location"
ATTR_LOCK_STATE = "lock_state"
ATTR_PET_NAME = "pet_name"

View File

@ -20,3 +20,23 @@ set_lock_state:
- 'locked_in'
- 'locked_out'
- 'unlocked'
set_pet_location:
name: Set pet location
description: Set pet location
fields:
pet_name:
description: Name of pet
example: My_cat
required: true
selector:
text:
location:
description: Pet location (Inside or Outside)
example: inside
required: true
selector:
select:
options:
- 'Inside'
- 'Outside'