From 1fc4284a29602168708036c69d8d9fdea25bbc65 Mon Sep 17 00:00:00 2001 From: Will Hughes Date: Mon, 4 Jan 2021 01:43:16 +1300 Subject: [PATCH] Add service to lock/unlock Sure Petcare pet flaps (#44557) * Add service to lock/unlock Sure Petcare pet flaps Adds a service to the Sure Petcare pet flaps to allow lock, unlocking, locking in and locking out pets using the pet flap * Linting * Changes from code review --- .../components/surepetcare/__init__.py | 47 +++++++++++++++++++ homeassistant/components/surepetcare/const.py | 5 ++ .../components/surepetcare/services.yaml | 9 ++++ 3 files changed, 61 insertions(+) create mode 100644 homeassistant/components/surepetcare/services.yaml diff --git a/homeassistant/components/surepetcare/__init__.py b/homeassistant/components/surepetcare/__init__.py index bd951ab2641..8ba6809ee05 100644 --- a/homeassistant/components/surepetcare/__init__.py +++ b/homeassistant/components/surepetcare/__init__.py @@ -4,6 +4,7 @@ from typing import Any, Dict, List from surepy import ( MESTART_RESOURCE, + SureLockStateID, SurePetcare, SurePetcareAuthenticationError, SurePetcareError, @@ -24,6 +25,8 @@ from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.event import async_track_time_interval from .const import ( + ATTR_FLAP_ID, + ATTR_LOCK_STATE, CONF_FEEDERS, CONF_FLAPS, CONF_PARENT, @@ -32,6 +35,7 @@ from .const import ( DATA_SURE_PETCARE, DEFAULT_SCAN_INTERVAL, DOMAIN, + SERVICE_SET_LOCK_STATE, SPC, SURE_API_TIMEOUT, TOPIC_UPDATE, @@ -143,6 +147,38 @@ async def async_setup(hass, config) -> bool: hass.helpers.discovery.async_load_platform("sensor", DOMAIN, {}, config) ) + async def handle_set_lock_state(call): + """Call when setting the lock state.""" + await spc.set_lock_state(call.data[ATTR_FLAP_ID], call.data[ATTR_LOCK_STATE]) + await spc.async_update() + + lock_state_service_schema = vol.Schema( + { + vol.Required(ATTR_FLAP_ID): vol.All( + cv.positive_int, vol.In(conf[CONF_FLAPS]) + ), + vol.Required(ATTR_LOCK_STATE): vol.All( + cv.string, + vol.Lower, + vol.In( + [ + SureLockStateID.UNLOCKED.name.lower(), + SureLockStateID.LOCKED_IN.name.lower(), + SureLockStateID.LOCKED_OUT.name.lower(), + SureLockStateID.LOCKED_ALL.name.lower(), + ] + ), + ), + } + ) + + hass.services.async_register( + DOMAIN, + SERVICE_SET_LOCK_STATE, + handle_set_lock_state, + schema=lock_state_service_schema, + ) + return True @@ -185,3 +221,14 @@ class SurePetcareAPI: _LOGGER.error("Unable to retrieve data from surepetcare.io: %s", error) async_dispatcher_send(self.hass, TOPIC_UPDATE) + + async def set_lock_state(self, flap_id: int, state: str) -> None: + """Update the lock state of a flap.""" + if state == SureLockStateID.UNLOCKED.name.lower(): + await self.surepy.unlock(flap_id) + elif state == SureLockStateID.LOCKED_IN.name.lower(): + await self.surepy.lock_in(flap_id) + elif state == SureLockStateID.LOCKED_OUT.name.lower(): + await self.surepy.lock_out(flap_id) + elif state == SureLockStateID.LOCKED_ALL.name.lower(): + await self.surepy.lock(flap_id) diff --git a/homeassistant/components/surepetcare/const.py b/homeassistant/components/surepetcare/const.py index 165e0bfd98a..86215c12ade 100644 --- a/homeassistant/components/surepetcare/const.py +++ b/homeassistant/components/surepetcare/const.py @@ -31,3 +31,8 @@ BATTERY_ICON = "mdi:battery" 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 +SERVICE_SET_LOCK_STATE = "set_lock_state" +ATTR_FLAP_ID = "flap_id" +ATTR_LOCK_STATE = "lock_state" diff --git a/homeassistant/components/surepetcare/services.yaml b/homeassistant/components/surepetcare/services.yaml new file mode 100644 index 00000000000..145256efe86 --- /dev/null +++ b/homeassistant/components/surepetcare/services.yaml @@ -0,0 +1,9 @@ +set_lock_state: + description: Sets lock state + fields: + flap_id: + description: Flap ID to lock/unlock + example: "123456" + lock_state: + description: New lock state - unlocked, locked_in, locked_out or locked_all + example: "unlocked"