Initial Verisure cleanups (#44639)

This commit is contained in:
Franck Nijhof 2020-12-30 09:55:18 +01:00 committed by GitHub
parent 9cc768b34c
commit ee194b9411
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 92 additions and 77 deletions

View File

@ -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

View File

@ -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 []

View File

@ -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):

View File

@ -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

View 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"

View File

@ -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:

View File

@ -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"]
}

View File

@ -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):