core/homeassistant/components/surepetcare/__init__.py

169 lines
5.3 KiB
Python
Raw Normal View History

"""The surepetcare integration."""
2021-03-18 13:31:38 +00:00
from __future__ import annotations
from datetime import timedelta
import logging
2021-03-18 13:31:38 +00:00
from typing import Any
from surepy import Surepy
from surepy.enums import LockState
from surepy.exceptions import SurePetcareAuthenticationError, SurePetcareError
import voluptuous as vol
from homeassistant.const import CONF_PASSWORD, CONF_SCAN_INTERVAL, CONF_USERNAME
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.dispatcher import async_dispatcher_send
from homeassistant.helpers.event import async_track_time_interval
from .const import (
ATTR_FLAP_ID,
ATTR_LOCK_STATE,
Sure Petcare new features various improvements (#31437) * add typing * 100% battery_level is enough * human-friendly datetime * better enum usage * add online and learning mode attrs * use max two decimals in attrs * use legacy style debug logging * remove str usage of enums * add feeder * add feeder and adapt to new surepy version * use ProductID instead of ThingID * various changes and improvements * add connectivity sensors for all devices & proper support for multiple hubs * remove "side effects"/exception catching in attribs * correct unique ids, reorder classes * move Flap class from binary_sensor to sensor and add a sensore base class * comments cleanup, minor typing and logging fixes * remove commented code * remove commented code * add typing * 100% battery_level is enough * human-friendly datetime * better enum usage * add online and learning mode attrs * use max two decimals in attrs * use legacy style debug logging * remove str usage of enums * add feeder * add feeder and adapt to new surepy version * use ProductID instead of ThingID * various changes and improvements * add connectivity sensors for all devices & proper support for multiple hubs * remove "side effects"/exception catching in attribs * correct unique ids, reorder classes * move Flap class from binary_sensor to sensor and add a sensore base class * comments cleanup, minor typing and logging fixes * remove commented code * remove commented code * fix spelling in comment to make the CI happy (seriously?!) * fix manifest file * fix requirements_all.txt file * add missing docstrings * fix available property * remove typing from self * remove commented code * remove is_on property from sensor * jump to new surepy version * remove useles init methods
2020-02-09 16:46:00 +00:00
CONF_FEEDERS,
CONF_FLAPS,
CONF_PETS,
DOMAIN,
SERVICE_SET_LOCK_STATE,
SPC,
SURE_API_TIMEOUT,
TOPIC_UPDATE,
)
_LOGGER = logging.getLogger(__name__)
PLATFORMS = ["binary_sensor", "sensor"]
SCAN_INTERVAL = timedelta(minutes=3)
CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.Schema(
vol.All(
{
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_FEEDERS): vol.All(
cv.ensure_list, [cv.positive_int]
),
vol.Optional(CONF_FLAPS): vol.All(
cv.ensure_list, [cv.positive_int]
),
vol.Optional(CONF_PETS): vol.All(cv.ensure_list, [cv.positive_int]),
vol.Optional(CONF_SCAN_INTERVAL): cv.time_period,
},
cv.deprecated(CONF_FEEDERS),
cv.deprecated(CONF_FLAPS),
cv.deprecated(CONF_PETS),
cv.deprecated(CONF_SCAN_INTERVAL),
)
)
},
extra=vol.ALLOW_EXTRA,
)
async def async_setup(hass: HomeAssistant, config: dict) -> bool:
"""Set up the Sure Petcare integration."""
conf = config[DOMAIN]
hass.data.setdefault(DOMAIN, {})
try:
surepy = Surepy(
conf[CONF_USERNAME],
conf[CONF_PASSWORD],
auth_token=None,
api_timeout=SURE_API_TIMEOUT,
session=async_get_clientsession(hass),
)
except SurePetcareAuthenticationError:
_LOGGER.error("Unable to connect to surepetcare.io: Wrong credentials!")
return False
except SurePetcareError as error:
_LOGGER.error("Unable to connect to surepetcare.io: Wrong %s!", error)
return False
spc = SurePetcareAPI(hass, surepy)
hass.data[DOMAIN][SPC] = spc
await spc.async_update()
async_track_time_interval(hass, spc.async_update, SCAN_INTERVAL)
# load platforms
hass.async_create_task(
hass.helpers.discovery.async_load_platform("binary_sensor", DOMAIN, {}, config)
)
hass.async_create_task(
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(
[
# https://github.com/PyCQA/pylint/issues/2062
# pylint: disable=no-member
LockState.UNLOCKED.name.lower(),
LockState.LOCKED_IN.name.lower(),
LockState.LOCKED_OUT.name.lower(),
LockState.LOCKED_ALL.name.lower(),
]
),
),
}
)
hass.services.async_register(
DOMAIN,
SERVICE_SET_LOCK_STATE,
handle_set_lock_state,
schema=lock_state_service_schema,
)
return True
class SurePetcareAPI:
"""Define a generic Sure Petcare object."""
def __init__(self, hass: HomeAssistant, surepy: Surepy) -> None:
"""Initialize the Sure Petcare object."""
self.hass = hass
self.surepy = surepy
self.states = {}
async def async_update(self, _: Any = None) -> None:
"""Get the latest data from Sure Petcare."""
Sure Petcare new features various improvements (#31437) * add typing * 100% battery_level is enough * human-friendly datetime * better enum usage * add online and learning mode attrs * use max two decimals in attrs * use legacy style debug logging * remove str usage of enums * add feeder * add feeder and adapt to new surepy version * use ProductID instead of ThingID * various changes and improvements * add connectivity sensors for all devices & proper support for multiple hubs * remove "side effects"/exception catching in attribs * correct unique ids, reorder classes * move Flap class from binary_sensor to sensor and add a sensore base class * comments cleanup, minor typing and logging fixes * remove commented code * remove commented code * add typing * 100% battery_level is enough * human-friendly datetime * better enum usage * add online and learning mode attrs * use max two decimals in attrs * use legacy style debug logging * remove str usage of enums * add feeder * add feeder and adapt to new surepy version * use ProductID instead of ThingID * various changes and improvements * add connectivity sensors for all devices & proper support for multiple hubs * remove "side effects"/exception catching in attribs * correct unique ids, reorder classes * move Flap class from binary_sensor to sensor and add a sensore base class * comments cleanup, minor typing and logging fixes * remove commented code * remove commented code * fix spelling in comment to make the CI happy (seriously?!) * fix manifest file * fix requirements_all.txt file * add missing docstrings * fix available property * remove typing from self * remove commented code * remove is_on property from sensor * jump to new surepy version * remove useles init methods
2020-02-09 16:46:00 +00:00
try:
self.states = await self.surepy.get_entities()
except SurePetcareError as error:
_LOGGER.error("Unable to fetch data: %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."""
# https://github.com/PyCQA/pylint/issues/2062
# pylint: disable=no-member
if state == LockState.UNLOCKED.name.lower():
await self.surepy.unlock(flap_id)
elif state == LockState.LOCKED_IN.name.lower():
await self.surepy.lock_in(flap_id)
elif state == LockState.LOCKED_OUT.name.lower():
await self.surepy.lock_out(flap_id)
elif state == LockState.LOCKED_ALL.name.lower():
await self.surepy.lock(flap_id)