mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 01:08:12 +00:00
Initial Verisure cleanups (#44639)
This commit is contained in:
parent
9cc768b34c
commit
ee194b9411
@ -493,6 +493,7 @@ homeassistant/components/utility_meter/* @dgomes
|
||||
homeassistant/components/velbus/* @Cereal2nd @brefra
|
||||
homeassistant/components/velux/* @Julius2342
|
||||
homeassistant/components/vera/* @vangorra
|
||||
homeassistant/components/verisure/* @frenck
|
||||
homeassistant/components/versasense/* @flamm3blemuff1n
|
||||
homeassistant/components/version/* @fabaff @ludeeus
|
||||
homeassistant/components/vesync/* @markperdue @webdjoe @thegardenmonkey
|
||||
|
@ -1,7 +1,5 @@
|
||||
"""Support for Verisure devices."""
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
import threading
|
||||
|
||||
from jsonpath import jsonpath
|
||||
import verisure
|
||||
@ -18,30 +16,27 @@ from homeassistant.helpers import discovery
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.util import Throttle
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ATTR_DEVICE_SERIAL = "device_serial"
|
||||
|
||||
CONF_ALARM = "alarm"
|
||||
CONF_CODE_DIGITS = "code_digits"
|
||||
CONF_DOOR_WINDOW = "door_window"
|
||||
CONF_GIID = "giid"
|
||||
CONF_HYDROMETERS = "hygrometers"
|
||||
CONF_LOCKS = "locks"
|
||||
CONF_DEFAULT_LOCK_CODE = "default_lock_code"
|
||||
CONF_MOUSE = "mouse"
|
||||
CONF_SMARTPLUGS = "smartplugs"
|
||||
CONF_THERMOMETERS = "thermometers"
|
||||
CONF_SMARTCAM = "smartcam"
|
||||
|
||||
DOMAIN = "verisure"
|
||||
|
||||
MIN_SCAN_INTERVAL = timedelta(minutes=1)
|
||||
DEFAULT_SCAN_INTERVAL = timedelta(minutes=1)
|
||||
|
||||
SERVICE_CAPTURE_SMARTCAM = "capture_smartcam"
|
||||
SERVICE_DISABLE_AUTOLOCK = "disable_autolock"
|
||||
SERVICE_ENABLE_AUTOLOCK = "enable_autolock"
|
||||
from .const import (
|
||||
ATTR_DEVICE_SERIAL,
|
||||
CONF_ALARM,
|
||||
CONF_CODE_DIGITS,
|
||||
CONF_DEFAULT_LOCK_CODE,
|
||||
CONF_DOOR_WINDOW,
|
||||
CONF_GIID,
|
||||
CONF_HYDROMETERS,
|
||||
CONF_LOCKS,
|
||||
CONF_MOUSE,
|
||||
CONF_SMARTCAM,
|
||||
CONF_SMARTPLUGS,
|
||||
CONF_THERMOMETERS,
|
||||
DEFAULT_SCAN_INTERVAL,
|
||||
DOMAIN,
|
||||
LOGGER,
|
||||
MIN_SCAN_INTERVAL,
|
||||
SERVICE_CAPTURE_SMARTCAM,
|
||||
SERVICE_DISABLE_AUTOLOCK,
|
||||
SERVICE_ENABLE_AUTOLOCK,
|
||||
)
|
||||
|
||||
HUB = None
|
||||
|
||||
@ -101,9 +96,9 @@ def setup(hass, config):
|
||||
device_id = service.data[ATTR_DEVICE_SERIAL]
|
||||
try:
|
||||
await hass.async_add_executor_job(HUB.smartcam_capture, device_id)
|
||||
_LOGGER.debug("Capturing new image from %s", ATTR_DEVICE_SERIAL)
|
||||
LOGGER.debug("Capturing new image from %s", ATTR_DEVICE_SERIAL)
|
||||
except verisure.Error as ex:
|
||||
_LOGGER.error("Could not capture image, %s", ex)
|
||||
LOGGER.error("Could not capture image, %s", ex)
|
||||
|
||||
hass.services.register(
|
||||
DOMAIN, SERVICE_CAPTURE_SMARTCAM, capture_smartcam, schema=DEVICE_SERIAL_SCHEMA
|
||||
@ -114,9 +109,9 @@ def setup(hass, config):
|
||||
device_id = service.data[ATTR_DEVICE_SERIAL]
|
||||
try:
|
||||
await hass.async_add_executor_job(HUB.disable_autolock, device_id)
|
||||
_LOGGER.debug("Disabling autolock on%s", ATTR_DEVICE_SERIAL)
|
||||
LOGGER.debug("Disabling autolock on%s", ATTR_DEVICE_SERIAL)
|
||||
except verisure.Error as ex:
|
||||
_LOGGER.error("Could not disable autolock, %s", ex)
|
||||
LOGGER.error("Could not disable autolock, %s", ex)
|
||||
|
||||
hass.services.register(
|
||||
DOMAIN, SERVICE_DISABLE_AUTOLOCK, disable_autolock, schema=DEVICE_SERIAL_SCHEMA
|
||||
@ -127,9 +122,9 @@ def setup(hass, config):
|
||||
device_id = service.data[ATTR_DEVICE_SERIAL]
|
||||
try:
|
||||
await hass.async_add_executor_job(HUB.enable_autolock, device_id)
|
||||
_LOGGER.debug("Enabling autolock on %s", ATTR_DEVICE_SERIAL)
|
||||
LOGGER.debug("Enabling autolock on %s", ATTR_DEVICE_SERIAL)
|
||||
except verisure.Error as ex:
|
||||
_LOGGER.error("Could not enable autolock, %s", ex)
|
||||
LOGGER.error("Could not enable autolock, %s", ex)
|
||||
|
||||
hass.services.register(
|
||||
DOMAIN, SERVICE_ENABLE_AUTOLOCK, enable_autolock, schema=DEVICE_SERIAL_SCHEMA
|
||||
@ -147,8 +142,6 @@ class VerisureHub:
|
||||
|
||||
self.config = domain_config
|
||||
|
||||
self._lock = threading.Lock()
|
||||
|
||||
self.session = verisure.Session(
|
||||
domain_config[CONF_USERNAME], domain_config[CONF_PASSWORD]
|
||||
)
|
||||
@ -160,7 +153,7 @@ class VerisureHub:
|
||||
try:
|
||||
self.session.login()
|
||||
except verisure.Error as ex:
|
||||
_LOGGER.error("Could not log in to verisure, %s", ex)
|
||||
LOGGER.error("Could not log in to verisure, %s", ex)
|
||||
return False
|
||||
if self.giid:
|
||||
return self.set_giid()
|
||||
@ -171,7 +164,7 @@ class VerisureHub:
|
||||
try:
|
||||
self.session.logout()
|
||||
except verisure.Error as ex:
|
||||
_LOGGER.error("Could not log out from verisure, %s", ex)
|
||||
LOGGER.error("Could not log out from verisure, %s", ex)
|
||||
return False
|
||||
return True
|
||||
|
||||
@ -180,7 +173,7 @@ class VerisureHub:
|
||||
try:
|
||||
self.session.set_giid(self.giid)
|
||||
except verisure.Error as ex:
|
||||
_LOGGER.error("Could not set installation GIID, %s", ex)
|
||||
LOGGER.error("Could not set installation GIID, %s", ex)
|
||||
return False
|
||||
return True
|
||||
|
||||
@ -189,9 +182,9 @@ class VerisureHub:
|
||||
try:
|
||||
self.overview = self.session.get_overview()
|
||||
except verisure.ResponseError as ex:
|
||||
_LOGGER.error("Could not read overview, %s", ex)
|
||||
LOGGER.error("Could not read overview, %s", ex)
|
||||
if ex.status_code == HTTP_SERVICE_UNAVAILABLE: # Service unavailable
|
||||
_LOGGER.info("Trying to log in again")
|
||||
LOGGER.info("Trying to log in again")
|
||||
self.login()
|
||||
else:
|
||||
raise
|
||||
@ -217,7 +210,7 @@ class VerisureHub:
|
||||
def get(self, jpath, *args):
|
||||
"""Get values from the overview that matches the jsonpath."""
|
||||
res = jsonpath(self.overview, jpath % args)
|
||||
return res if res else []
|
||||
return res or []
|
||||
|
||||
def get_first(self, jpath, *args):
|
||||
"""Get first value from the overview that matches the jsonpath."""
|
||||
@ -227,4 +220,4 @@ class VerisureHub:
|
||||
def get_image_info(self, jpath, *args):
|
||||
"""Get values from the imageseries that matches the jsonpath."""
|
||||
res = jsonpath(self.imageseries, jpath % args)
|
||||
return res if res else []
|
||||
return res or []
|
||||
|
@ -1,5 +1,4 @@
|
||||
"""Support for Verisure alarm control panels."""
|
||||
import logging
|
||||
from time import sleep
|
||||
|
||||
import homeassistant.components.alarm_control_panel as alarm
|
||||
@ -13,9 +12,8 @@ from homeassistant.const import (
|
||||
STATE_ALARM_DISARMED,
|
||||
)
|
||||
|
||||
from . import CONF_ALARM, CONF_CODE_DIGITS, CONF_GIID, HUB as hub
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
from . import HUB as hub
|
||||
from .const import CONF_ALARM, CONF_CODE_DIGITS, CONF_GIID, LOGGER
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
@ -32,12 +30,12 @@ def set_arm_state(state, code=None):
|
||||
transaction_id = hub.session.set_arm_state(code, state)[
|
||||
"armStateChangeTransactionId"
|
||||
]
|
||||
_LOGGER.info("verisure set arm state %s", state)
|
||||
LOGGER.info("verisure set arm state %s", state)
|
||||
transaction = {}
|
||||
while "result" not in transaction:
|
||||
sleep(0.5)
|
||||
transaction = hub.session.get_arm_state_transaction(transaction_id)
|
||||
hub.update_overview(no_throttle=True)
|
||||
hub.update_overview()
|
||||
|
||||
|
||||
class VerisureAlarm(alarm.AlarmControlPanelEntity):
|
||||
@ -58,7 +56,7 @@ class VerisureAlarm(alarm.AlarmControlPanelEntity):
|
||||
if giid in aliass:
|
||||
return "{} alarm".format(aliass[giid])
|
||||
|
||||
_LOGGER.error("Verisure installation giid not found: %s", giid)
|
||||
LOGGER.error("Verisure installation giid not found: %s", giid)
|
||||
|
||||
return "{} alarm".format(hub.session.installations[0]["alias"])
|
||||
|
||||
@ -93,7 +91,7 @@ class VerisureAlarm(alarm.AlarmControlPanelEntity):
|
||||
elif status == "ARMED_AWAY":
|
||||
self._state = STATE_ALARM_ARMED_AWAY
|
||||
elif status != "PENDING":
|
||||
_LOGGER.error("Unknown alarm state %s", status)
|
||||
LOGGER.error("Unknown alarm state %s", status)
|
||||
self._changed_by = hub.get_first("$.armState.name")
|
||||
|
||||
def alarm_disarm(self, code=None):
|
||||
|
@ -1,14 +1,12 @@
|
||||
"""Support for Verisure cameras."""
|
||||
import errno
|
||||
import logging
|
||||
import os
|
||||
|
||||
from homeassistant.components.camera import Camera
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
|
||||
|
||||
from . import CONF_SMARTCAM, HUB as hub
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
from . import HUB as hub
|
||||
from .const import CONF_SMARTCAM, LOGGER
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
@ -17,16 +15,14 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
return False
|
||||
directory_path = hass.config.config_dir
|
||||
if not os.access(directory_path, os.R_OK):
|
||||
_LOGGER.error("file path %s is not readable", directory_path)
|
||||
LOGGER.error("file path %s is not readable", directory_path)
|
||||
return False
|
||||
hub.update_overview()
|
||||
smartcams = []
|
||||
smartcams.extend(
|
||||
[
|
||||
VerisureSmartcam(hass, device_label, directory_path)
|
||||
for device_label in hub.get("$.customerImageCameras[*].deviceLabel")
|
||||
]
|
||||
)
|
||||
smartcams = [
|
||||
VerisureSmartcam(hass, device_label, directory_path)
|
||||
for device_label in hub.get("$.customerImageCameras[*].deviceLabel")
|
||||
]
|
||||
|
||||
add_entities(smartcams)
|
||||
|
||||
|
||||
@ -47,9 +43,9 @@ class VerisureSmartcam(Camera):
|
||||
"""Return image response."""
|
||||
self.check_imagelist()
|
||||
if not self._image:
|
||||
_LOGGER.debug("No image to display")
|
||||
LOGGER.debug("No image to display")
|
||||
return
|
||||
_LOGGER.debug("Trying to open %s", self._image)
|
||||
LOGGER.debug("Trying to open %s", self._image)
|
||||
with open(self._image, "rb") as file:
|
||||
return file.read()
|
||||
|
||||
@ -63,14 +59,14 @@ class VerisureSmartcam(Camera):
|
||||
return
|
||||
new_image_id = image_ids[0]
|
||||
if new_image_id in ("-1", self._image_id):
|
||||
_LOGGER.debug("The image is the same, or loading image_id")
|
||||
LOGGER.debug("The image is the same, or loading image_id")
|
||||
return
|
||||
_LOGGER.debug("Download new image %s", new_image_id)
|
||||
LOGGER.debug("Download new image %s", new_image_id)
|
||||
new_image_path = os.path.join(
|
||||
self._directory_path, "{}{}".format(new_image_id, ".jpg")
|
||||
)
|
||||
hub.session.download_image(self._device_label, new_image_id, new_image_path)
|
||||
_LOGGER.debug("Old image_id=%s", self._image_id)
|
||||
LOGGER.debug("Old image_id=%s", self._image_id)
|
||||
self.delete_image(self)
|
||||
|
||||
self._image_id = new_image_id
|
||||
@ -83,7 +79,7 @@ class VerisureSmartcam(Camera):
|
||||
)
|
||||
try:
|
||||
os.remove(remove_image)
|
||||
_LOGGER.debug("Deleting old image %s", remove_image)
|
||||
LOGGER.debug("Deleting old image %s", remove_image)
|
||||
except OSError as error:
|
||||
if error.errno != errno.ENOENT:
|
||||
raise
|
||||
|
28
homeassistant/components/verisure/const.py
Normal file
28
homeassistant/components/verisure/const.py
Normal file
@ -0,0 +1,28 @@
|
||||
"""Constants for the Verisure integration."""
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
DOMAIN = "verisure"
|
||||
|
||||
LOGGER = logging.getLogger(__package__)
|
||||
|
||||
ATTR_DEVICE_SERIAL = "device_serial"
|
||||
|
||||
CONF_ALARM = "alarm"
|
||||
CONF_CODE_DIGITS = "code_digits"
|
||||
CONF_DOOR_WINDOW = "door_window"
|
||||
CONF_GIID = "giid"
|
||||
CONF_HYDROMETERS = "hygrometers"
|
||||
CONF_LOCKS = "locks"
|
||||
CONF_DEFAULT_LOCK_CODE = "default_lock_code"
|
||||
CONF_MOUSE = "mouse"
|
||||
CONF_SMARTPLUGS = "smartplugs"
|
||||
CONF_THERMOMETERS = "thermometers"
|
||||
CONF_SMARTCAM = "smartcam"
|
||||
|
||||
DEFAULT_SCAN_INTERVAL = timedelta(minutes=1)
|
||||
MIN_SCAN_INTERVAL = timedelta(minutes=1)
|
||||
|
||||
SERVICE_CAPTURE_SMARTCAM = "capture_smartcam"
|
||||
SERVICE_DISABLE_AUTOLOCK = "disable_autolock"
|
||||
SERVICE_ENABLE_AUTOLOCK = "enable_autolock"
|
@ -1,13 +1,11 @@
|
||||
"""Support for Verisure locks."""
|
||||
import logging
|
||||
from time import monotonic, sleep
|
||||
|
||||
from homeassistant.components.lock import LockEntity
|
||||
from homeassistant.const import ATTR_CODE, STATE_LOCKED, STATE_UNLOCKED
|
||||
|
||||
from . import CONF_CODE_DIGITS, CONF_DEFAULT_LOCK_CODE, CONF_LOCKS, HUB as hub
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
from . import HUB as hub
|
||||
from .const import CONF_CODE_DIGITS, CONF_DEFAULT_LOCK_CODE, CONF_LOCKS, LOGGER
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
@ -83,7 +81,7 @@ class VerisureDoorlock(LockEntity):
|
||||
elif status == "LOCKED":
|
||||
self._state = STATE_LOCKED
|
||||
elif status != "PENDING":
|
||||
_LOGGER.error("Unknown lock state %s", status)
|
||||
LOGGER.error("Unknown lock state %s", status)
|
||||
self._changed_by = hub.get_first(
|
||||
"$.doorLockStatusList[?(@.deviceLabel=='%s')].userString",
|
||||
self._device_label,
|
||||
@ -101,7 +99,7 @@ class VerisureDoorlock(LockEntity):
|
||||
|
||||
code = kwargs.get(ATTR_CODE, self._default_lock_code)
|
||||
if code is None:
|
||||
_LOGGER.error("Code required but none provided")
|
||||
LOGGER.error("Code required but none provided")
|
||||
return
|
||||
|
||||
self.set_lock_state(code, STATE_UNLOCKED)
|
||||
@ -113,7 +111,7 @@ class VerisureDoorlock(LockEntity):
|
||||
|
||||
code = kwargs.get(ATTR_CODE, self._default_lock_code)
|
||||
if code is None:
|
||||
_LOGGER.error("Code required but none provided")
|
||||
LOGGER.error("Code required but none provided")
|
||||
return
|
||||
|
||||
self.set_lock_state(code, STATE_LOCKED)
|
||||
@ -124,7 +122,7 @@ class VerisureDoorlock(LockEntity):
|
||||
transaction_id = hub.session.set_lock_state(
|
||||
code, self._device_label, lock_state
|
||||
)["doorLockStateChangeTransactionId"]
|
||||
_LOGGER.debug("Verisure doorlock %s", state)
|
||||
LOGGER.debug("Verisure doorlock %s", state)
|
||||
transaction = {}
|
||||
attempts = 0
|
||||
while "result" not in transaction:
|
||||
|
@ -3,5 +3,5 @@
|
||||
"name": "Verisure",
|
||||
"documentation": "https://www.home-assistant.io/integrations/verisure",
|
||||
"requirements": ["jsonpath==0.82", "vsure==1.5.4"],
|
||||
"codeowners": []
|
||||
"codeowners": ["@frenck"]
|
||||
}
|
||||
|
@ -2,7 +2,8 @@
|
||||
from homeassistant.const import PERCENTAGE, TEMP_CELSIUS
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
from . import CONF_HYDROMETERS, CONF_MOUSE, CONF_THERMOMETERS, HUB as hub
|
||||
from . import HUB as hub
|
||||
from .const import CONF_HYDROMETERS, CONF_MOUSE, CONF_THERMOMETERS
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
|
Loading…
x
Reference in New Issue
Block a user