diff --git a/homeassistant/components/alarm_control_panel/verisure.py b/homeassistant/components/alarm_control_panel/verisure.py
index 32f28865a4181f343ddd8adc029475badb3f9774..66764f58c2695a98432182e9364007f3e258b369 100644
--- a/homeassistant/components/alarm_control_panel/verisure.py
+++ b/homeassistant/components/alarm_control_panel/verisure.py
@@ -5,6 +5,7 @@ For more details about this platform, please refer to the documentation at
 https://home-assistant.io/components/alarm_control_panel.verisure/
 """
 import logging
+from time import sleep
 
 import homeassistant.components.alarm_control_panel as alarm
 from homeassistant.components.verisure import HUB as hub
@@ -20,20 +21,29 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
     """Set up the Verisure platform."""
     alarms = []
     if int(hub.config.get(CONF_ALARM, 1)):
-        hub.update_alarms()
-        alarms.extend([
-            VerisureAlarm(value.id)
-            for value in hub.alarm_status.values()
-            ])
+        hub.update_overview()
+        alarms.append(VerisureAlarm())
     add_devices(alarms)
 
 
+def set_arm_state(state, code=None):
+    """Send set arm state command."""
+    transaction_id = hub.session.set_arm_state(code, state)[
+        'armStateChangeTransactionId']
+    _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)
+    # pylint: disable=unexpected-keyword-arg
+    hub.update_overview(no_throttle=True)
+
+
 class VerisureAlarm(alarm.AlarmControlPanel):
     """Representation of a Verisure alarm status."""
 
-    def __init__(self, device_id):
-        """Initialize the Verisure alarm panel."""
-        self._id = device_id
+    def __init__(self):
+        """Initalize the Verisure alarm panel."""
         self._state = STATE_UNKNOWN
         self._digits = hub.config.get(CONF_CODE_DIGITS)
         self._changed_by = None
@@ -41,18 +51,13 @@ class VerisureAlarm(alarm.AlarmControlPanel):
     @property
     def name(self):
         """Return the name of the device."""
-        return 'Alarm {}'.format(self._id)
+        return '{} alarm'.format(hub.session.installations[0]['alias'])
 
     @property
     def state(self):
         """Return the state of the device."""
         return self._state
 
-    @property
-    def available(self):
-        """Return True if entity is available."""
-        return hub.available
-
     @property
     def code_format(self):
         """Return the code format as regex."""
@@ -65,33 +70,26 @@ class VerisureAlarm(alarm.AlarmControlPanel):
 
     def update(self):
         """Update alarm status."""
-        hub.update_alarms()
-
-        if hub.alarm_status[self._id].status == 'unarmed':
+        hub.update_overview()
+        status = hub.get_first("$.armState.statusType")
+        if status == 'DISARMED':
             self._state = STATE_ALARM_DISARMED
-        elif hub.alarm_status[self._id].status == 'armedhome':
+        elif status == 'ARMED_HOME':
             self._state = STATE_ALARM_ARMED_HOME
-        elif hub.alarm_status[self._id].status == 'armed':
+        elif status == 'ARMED_AWAY':
             self._state = STATE_ALARM_ARMED_AWAY
-        elif hub.alarm_status[self._id].status != 'pending':
-            _LOGGER.error(
-                "Unknown alarm state %s", hub.alarm_status[self._id].status)
-        self._changed_by = hub.alarm_status[self._id].name
+        elif status != 'PENDING':
+            _LOGGER.error('Unknown alarm state %s', status)
+        self._changed_by = hub.get_first("$.armState.name")
 
     def alarm_disarm(self, code=None):
         """Send disarm command."""
-        hub.my_pages.alarm.set(code, 'DISARMED')
-        _LOGGER.info("Verisure alarm disarming")
-        hub.my_pages.alarm.wait_while_pending()
+        set_arm_state('DISARMED', code)
 
     def alarm_arm_home(self, code=None):
         """Send arm home command."""
-        hub.my_pages.alarm.set(code, 'ARMED_HOME')
-        _LOGGER.info("Verisure alarm arming home")
-        hub.my_pages.alarm.wait_while_pending()
+        set_arm_state('ARMED_HOME', code)
 
     def alarm_arm_away(self, code=None):
         """Send arm away command."""
-        hub.my_pages.alarm.set(code, 'ARMED_AWAY')
-        _LOGGER.info("Verisure alarm arming away")
-        hub.my_pages.alarm.wait_while_pending()
+        set_arm_state('ARMED_AWAY', code)
diff --git a/homeassistant/components/binary_sensor/verisure.py b/homeassistant/components/binary_sensor/verisure.py
new file mode 100644
index 0000000000000000000000000000000000000000..f6c0123ad0a4f752edc392f74f67f07f97cc3ba5
--- /dev/null
+++ b/homeassistant/components/binary_sensor/verisure.py
@@ -0,0 +1,59 @@
+"""
+Interfaces with Verisure sensors.
+
+For more details about this platform, please refer to the documentation at
+https://home-assistant.io/components/binary_sensor.verisure/
+"""
+import logging
+
+from homeassistant.components.verisure import HUB as hub
+from homeassistant.components.binary_sensor import BinarySensorDevice
+from homeassistant.components.verisure import CONF_DOOR_WINDOW
+
+_LOGGER = logging.getLogger(__name__)
+
+
+def setup_platform(hass, config, add_devices, discovery_info=None):
+    """Setup Verisure binary sensors."""
+    sensors = []
+    hub.update_overview()
+
+    if int(hub.config.get(CONF_DOOR_WINDOW, 1)):
+        sensors.extend([
+            VerisureDoorWindowSensor(device_label)
+            for device_label in hub.get(
+                "$.doorWindow.doorWindowDevice[*].deviceLabel")])
+    add_devices(sensors)
+
+
+class VerisureDoorWindowSensor(BinarySensorDevice):
+    """Verisure door window sensor."""
+
+    def __init__(self, device_label):
+        """Initialize the modbus coil sensor."""
+        self._device_label = device_label
+
+    @property
+    def name(self):
+        """Return the name of the binary sensor."""
+        return hub.get_first(
+            "$.doorWindow.doorWindowDevice[?(@.deviceLabel=='%s')].area",
+            self._device_label) + " door window"
+
+    @property
+    def is_on(self):
+        """Return the state of the sensor."""
+        return hub.get_first(
+            "$.doorWindow.doorWindowDevice[?(@.deviceLabel=='%s')].state",
+            self._device_label) == "OPEN"
+
+    @property
+    def available(self):
+        """Return True if entity is available."""
+        return hub.get_first(
+            "$.doorWindow.doorWindowDevice[?(@.deviceLabel=='%s')]",
+            self._device_label) is not None
+
+    def update(self):
+        """Update the state of the sensor."""
+        hub.update_overview()
diff --git a/homeassistant/components/camera/verisure.py b/homeassistant/components/camera/verisure.py
index 1c2e7e382fe94223338339592e2ee6790d0d70e6..fbe91ad91a82b8e8955f9a45e6153fdede5164fd 100644
--- a/homeassistant/components/camera/verisure.py
+++ b/homeassistant/components/camera/verisure.py
@@ -24,22 +24,23 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
     if not os.access(directory_path, os.R_OK):
         _LOGGER.error("file path %s is not readable", directory_path)
         return False
-    hub.update_smartcam()
+    hub.update_overview()
     smartcams = []
     smartcams.extend([
-        VerisureSmartcam(hass, value.deviceLabel, directory_path)
-        for value in hub.smartcam_status.values()])
+        VerisureSmartcam(hass, device_label, directory_path)
+        for device_label in hub.get(
+            "$.customerImageCameras[*].deviceLabel")])
     add_devices(smartcams)
 
 
 class VerisureSmartcam(Camera):
     """Representation of a Verisure camera."""
 
-    def __init__(self, hass, device_id, directory_path):
+    def __init__(self, hass, device_label, directory_path):
         """Initialize Verisure File Camera component."""
         super().__init__()
 
-        self._device_id = device_id
+        self._device_label = device_label
         self._directory_path = directory_path
         self._image = None
         self._image_id = None
@@ -58,28 +59,27 @@ class VerisureSmartcam(Camera):
 
     def check_imagelist(self):
         """Check the contents of the image list."""
-        hub.update_smartcam_imagelist()
-        if (self._device_id not in hub.smartcam_dict or
-                not hub.smartcam_dict[self._device_id]):
+        hub.update_smartcam_imageseries()
+        image_ids = hub.get_image_info(
+            "$.imageSeries[?(@.deviceLabel=='%s')].image[0].imageId",
+            self._device_label)
+        if not image_ids:
             return
-        images = hub.smartcam_dict[self._device_id]
-        new_image_id = images[0]
-        _LOGGER.debug("self._device_id=%s, self._images=%s, "
-                      "self._new_image_id=%s", self._device_id,
-                      images, new_image_id)
+        new_image_id = image_ids[0]
         if (new_image_id == '-1' or
                 self._image_id == new_image_id):
             _LOGGER.debug("The image is the same, or loading image_id")
             return
         _LOGGER.debug("Download new image %s", new_image_id)
-        hub.my_pages.smartcam.download_image(
-            self._device_id, new_image_id, self._directory_path)
+        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)
         self.delete_image(self)
 
         self._image_id = new_image_id
-        self._image = os.path.join(
-            self._directory_path, '{}{}'.format(self._image_id, '.jpg'))
+        self._image = new_image_path
 
     def delete_image(self, event):
         """Delete an old image."""
@@ -95,4 +95,6 @@ class VerisureSmartcam(Camera):
     @property
     def name(self):
         """Return the name of this camera."""
-        return hub.smartcam_status[self._device_id].location
+        return hub.get_first(
+            "$.customerImageCameras[?(@.deviceLabel=='%s')].area",
+            self._device_label) + " camera"
diff --git a/homeassistant/components/lock/verisure.py b/homeassistant/components/lock/verisure.py
index e4fa2104da6317f9ead7f3ce180b789469bd6b6a..7a24dd6bb378317120c4260d054716daef4bae92 100644
--- a/homeassistant/components/lock/verisure.py
+++ b/homeassistant/components/lock/verisure.py
@@ -5,7 +5,8 @@ For more details about this platform, please refer to the documentation at
 https://home-assistant.io/components/verisure/
 """
 import logging
-
+from time import sleep
+from time import time
 from homeassistant.components.verisure import HUB as hub
 from homeassistant.components.verisure import (CONF_LOCKS, CONF_CODE_DIGITS)
 from homeassistant.components.lock import LockDevice
@@ -19,28 +20,32 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
     """Set up the Verisure platform."""
     locks = []
     if int(hub.config.get(CONF_LOCKS, 1)):
-        hub.update_locks()
+        hub.update_overview()
         locks.extend([
-            VerisureDoorlock(device_id)
-            for device_id in hub.lock_status
-        ])
+            VerisureDoorlock(device_label)
+            for device_label in hub.get(
+                "$.doorLockStatusList[*].deviceLabel")])
+
     add_devices(locks)
 
 
 class VerisureDoorlock(LockDevice):
     """Representation of a Verisure doorlock."""
 
-    def __init__(self, device_id):
+    def __init__(self, device_label):
         """Initialize the Verisure lock."""
-        self._id = device_id
+        self._device_label = device_label
         self._state = STATE_UNKNOWN
         self._digits = hub.config.get(CONF_CODE_DIGITS)
         self._changed_by = None
+        self._change_timestamp = 0
 
     @property
     def name(self):
         """Return the name of the lock."""
-        return '{}'.format(hub.lock_status[self._id].location)
+        return hub.get_first(
+            "$.doorLockStatusList[?(@.deviceLabel=='%s')].area",
+            self._device_label) + " lock"
 
     @property
     def state(self):
@@ -50,7 +55,9 @@ class VerisureDoorlock(LockDevice):
     @property
     def available(self):
         """Return True if entity is available."""
-        return hub.available
+        return hub.get_first(
+            "$.doorLockStatusList[?(@.deviceLabel=='%s')]",
+            self._device_label) is not None
 
     @property
     def changed_by(self):
@@ -64,32 +71,52 @@ class VerisureDoorlock(LockDevice):
 
     def update(self):
         """Update lock status."""
-        hub.update_locks()
-
-        if hub.lock_status[self._id].status == 'unlocked':
+        if time() - self._change_timestamp < 10:
+            return
+        hub.update_overview()
+        status = hub.get_first(
+            "$.doorLockStatusList[?(@.deviceLabel=='%s')].lockedState",
+            self._device_label)
+        if status == 'UNLOCKED':
             self._state = STATE_UNLOCKED
-        elif hub.lock_status[self._id].status == 'locked':
+        elif status == 'LOCKED':
             self._state = STATE_LOCKED
-        elif hub.lock_status[self._id].status != 'pending':
-            _LOGGER.error(
-                "Unknown lock state %s", hub.lock_status[self._id].status)
-        self._changed_by = hub.lock_status[self._id].name
+        elif status != 'PENDING':
+            _LOGGER.error('Unknown lock state %s', status)
+        self._changed_by = hub.get_first(
+            "$.doorLockStatusList[?(@.deviceLabel=='%s')].userString",
+            self._device_label)
 
     @property
     def is_locked(self):
         """Return true if lock is locked."""
-        return hub.lock_status[self._id].status
+        return self._state == STATE_LOCKED
 
     def unlock(self, **kwargs):
         """Send unlock command."""
-        hub.my_pages.lock.set(kwargs[ATTR_CODE], self._id, 'UNLOCKED')
-        _LOGGER.debug("Verisure doorlock unlocking")
-        hub.my_pages.lock.wait_while_pending()
-        self.update()
+        if self._state == STATE_UNLOCKED:
+            return
+        self.set_lock_state(kwargs[ATTR_CODE], STATE_UNLOCKED)
 
     def lock(self, **kwargs):
         """Send lock command."""
-        hub.my_pages.lock.set(kwargs[ATTR_CODE], self._id, 'LOCKED')
-        _LOGGER.debug("Verisure doorlock locking")
-        hub.my_pages.lock.wait_while_pending()
-        self.update()
+        if self._state == STATE_LOCKED:
+            return
+        self.set_lock_state(kwargs[ATTR_CODE], STATE_LOCKED)
+
+    def set_lock_state(self, code, state):
+        """Send set lock state command."""
+        lock_state = 'lock' if state == STATE_LOCKED else 'unlock'
+        transaction_id = hub.session.set_lock_state(
+            code,
+            self._device_label,
+            lock_state)['doorLockStateChangeTransactionId']
+        _LOGGER.debug("Verisure doorlock %s", state)
+        transaction = {}
+        while 'result' not in transaction:
+            sleep(0.5)
+            transaction = hub.session.get_lock_state_transaction(
+                transaction_id)
+        if transaction['result'] == 'OK':
+            self._state = state
+            self._change_timestamp = time()
diff --git a/homeassistant/components/sensor/verisure.py b/homeassistant/components/sensor/verisure.py
index 4b22512fd4dcd03565ef0767645fe6f1a8d343d7..5ab999ccabfea784a0d9a9286aa19ecaeb9b344f 100644
--- a/homeassistant/components/sensor/verisure.py
+++ b/homeassistant/components/sensor/verisure.py
@@ -18,31 +18,25 @@ _LOGGER = logging.getLogger(__name__)
 def setup_platform(hass, config, add_devices, discovery_info=None):
     """Set up the Verisure platform."""
     sensors = []
+    hub.update_overview()
 
     if int(hub.config.get(CONF_THERMOMETERS, 1)):
-        hub.update_climate()
         sensors.extend([
-            VerisureThermometer(value.id)
-            for value in hub.climate_status.values()
-            if hasattr(value, 'temperature') and value.temperature
-            ])
+            VerisureThermometer(device_label)
+            for device_label in hub.get(
+                '$.climateValues[?(@.temperature)].deviceLabel')])
 
     if int(hub.config.get(CONF_HYDROMETERS, 1)):
-        hub.update_climate()
         sensors.extend([
-            VerisureHygrometer(value.id)
-            for value in hub.climate_status.values()
-            if hasattr(value, 'humidity') and value.humidity
-            ])
+            VerisureHygrometer(device_label)
+            for device_label in hub.get(
+                '$.climateValues[?(@.humidity)].deviceLabel')])
 
     if int(hub.config.get(CONF_MOUSE, 1)):
-        hub.update_mousedetection()
         sensors.extend([
-            VerisureMouseDetection(value.deviceLabel)
-            for value in hub.mouse_status.values()
-            # is this if needed?
-            if hasattr(value, 'amountText') and value.amountText
-            ])
+            VerisureMouseDetection(device_label)
+            for device_label in hub.get(
+                "$.eventCounts[?(@.deviceType=='MOUSE1')].deviceLabel")])
 
     add_devices(sensors)
 
@@ -50,26 +44,30 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
 class VerisureThermometer(Entity):
     """Representation of a Verisure thermometer."""
 
-    def __init__(self, device_id):
+    def __init__(self, device_label):
         """Initialize the sensor."""
-        self._id = device_id
+        self._device_label = device_label
 
     @property
     def name(self):
         """Return the name of the device."""
-        return '{} {}'.format(
-            hub.climate_status[self._id].location, 'Temperature')
+        return hub.get_first(
+            "$.climateValues[?(@.deviceLabel=='%s')].deviceArea",
+            self._device_label) + " temperature"
 
     @property
     def state(self):
         """Return the state of the device."""
-        # Remove ° character
-        return hub.climate_status[self._id].temperature[:-1]
+        return hub.get_first(
+            "$.climateValues[?(@.deviceLabel=='%s')].temperature",
+            self._device_label)
 
     @property
     def available(self):
         """Return True if entity is available."""
-        return hub.available
+        return hub.get_first(
+            "$.climateValues[?(@.deviceLabel=='%s')].temperature",
+            self._device_label) is not None
 
     @property
     def unit_of_measurement(self):
@@ -78,71 +76,80 @@ class VerisureThermometer(Entity):
 
     def update(self):
         """Update the sensor."""
-        hub.update_climate()
+        hub.update_overview()
 
 
 class VerisureHygrometer(Entity):
     """Representation of a Verisure hygrometer."""
 
-    def __init__(self, device_id):
+    def __init__(self, device_label):
         """Initialize the sensor."""
-        self._id = device_id
+        self._device_label = device_label
 
     @property
     def name(self):
-        """Return the name of the sensor."""
-        return '{} {}'.format(
-            hub.climate_status[self._id].location, 'Humidity')
+        """Return the name of the device."""
+        return hub.get_first(
+            "$.climateValues[?(@.deviceLabel=='%s')].deviceArea",
+            self._device_label) + " humidity"
 
     @property
     def state(self):
-        """Return the state of the sensor."""
-        # remove % character
-        return hub.climate_status[self._id].humidity[:-1]
+        """Return the state of the device."""
+        return hub.get_first(
+            "$.climateValues[?(@.deviceLabel=='%s')].humidity",
+            self._device_label)
 
     @property
     def available(self):
         """Return True if entity is available."""
-        return hub.available
+        return hub.get_first(
+            "$.climateValues[?(@.deviceLabel=='%s')].humidity",
+            self._device_label) is not None
 
     @property
     def unit_of_measurement(self):
-        """Return the unit of measurement of this sensor."""
-        return "%"
+        """Return the unit of measurement of this entity."""
+        return '%'
 
     def update(self):
         """Update the sensor."""
-        hub.update_climate()
+        hub.update_overview()
 
 
 class VerisureMouseDetection(Entity):
     """Representation of a Verisure mouse detector."""
 
-    def __init__(self, device_id):
+    def __init__(self, device_label):
         """Initialize the sensor."""
-        self._id = device_id
+        self._device_label = device_label
 
     @property
     def name(self):
-        """Return the name of the sensor."""
-        return '{} {}'.format(
-            hub.mouse_status[self._id].location, 'Mouse')
+        """Return the name of the device."""
+        return hub.get_first(
+            "$.eventCounts[?(@.deviceLabel=='%s')].area",
+            self._device_label) + " mouse"
 
     @property
     def state(self):
-        """Return the state of the sensor."""
-        return hub.mouse_status[self._id].count
+        """Return the state of the device."""
+        return hub.get_first(
+            "$.eventCounts[?(@.deviceLabel=='%s')].detections",
+            self._device_label)
 
     @property
     def available(self):
         """Return True if entity is available."""
-        return hub.available
+        return hub.get_first(
+            "$.eventCounts[?(@.deviceLabel=='%s')]",
+            self._device_label) is not None
 
     @property
     def unit_of_measurement(self):
-        """Return the unit of measurement of this sensor."""
-        return "Mice"
+        """Return the unit of measurement of this entity."""
+        return 'Mice'
 
     def update(self):
         """Update the sensor."""
-        hub.update_mousedetection()
+        hub.update_overview()
diff --git a/homeassistant/components/switch/verisure.py b/homeassistant/components/switch/verisure.py
index 3aeb092f35b1d92f8ef7ab8b159e85c93dcd0c2b..597e1aa595973cb5195dd5d776e1f759e75fa62a 100644
--- a/homeassistant/components/switch/verisure.py
+++ b/homeassistant/components/switch/verisure.py
@@ -5,6 +5,7 @@ For more details about this platform, please refer to the documentation at
 https://home-assistant.io/components/switch.verisure/
 """
 import logging
+from time import time
 
 from homeassistant.components.verisure import HUB as hub
 from homeassistant.components.verisure import CONF_SMARTPLUGS
@@ -18,11 +19,11 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
     if not int(hub.config.get(CONF_SMARTPLUGS, 1)):
         return False
 
-    hub.update_smartplugs()
+    hub.update_overview()
     switches = []
     switches.extend([
-        VerisureSmartplug(value.deviceLabel)
-        for value in hub.smartplug_status.values()])
+        VerisureSmartplug(device_label)
+        for device_label in hub.get('$.smartPlugs[*].deviceLabel')])
     add_devices(switches)
 
 
@@ -31,35 +32,46 @@ class VerisureSmartplug(SwitchDevice):
 
     def __init__(self, device_id):
         """Initialize the Verisure device."""
-        self._id = device_id
+        self._device_label = device_id
+        self._change_timestamp = 0
+        self._state = False
 
     @property
     def name(self):
         """Return the name or location of the smartplug."""
-        return hub.smartplug_status[self._id].location
+        return hub.get_first(
+            "$.smartPlugs[?(@.deviceLabel == '%s')].area",
+            self._device_label) + " switch"
 
     @property
     def is_on(self):
         """Return true if on."""
-        return hub.smartplug_status[self._id].status == 'on'
+        if time() - self._change_timestamp < 10:
+            return self._state
+        self._state = hub.get_first(
+            "$.smartPlugs[?(@.deviceLabel == '%s')].currentState",
+            self._device_label) == "ON"
+        return self._state
 
     @property
     def available(self):
         """Return True if entity is available."""
-        return hub.available
+        return hub.get_first(
+            "$.smartPlugs[?(@.deviceLabel == '%s')]",
+            self._device_label) is not None
 
     def turn_on(self):
         """Set smartplug status on."""
-        hub.my_pages.smartplug.set(self._id, 'on')
-        hub.my_pages.smartplug.wait_while_updating(self._id, 'on')
-        self.update()
+        hub.session.set_smartplug_state(self._device_label, True)
+        self._state = True
+        self._change_timestamp = time()
 
     def turn_off(self):
         """Set smartplug status off."""
-        hub.my_pages.smartplug.set(self._id, 'off')
-        hub.my_pages.smartplug.wait_while_updating(self._id, 'off')
-        self.update()
+        hub.session.set_smartplug_state(self._device_label, False)
+        self._state = False
+        self._change_timestamp = time()
 
     def update(self):
         """Get the latest date of the smartplug."""
-        hub.update_smartplugs()
+        hub.update_overview()
diff --git a/homeassistant/components/verisure.py b/homeassistant/components/verisure.py
index 72837b07019994cc9929fda3039abd5d2db85c6f..1ec1f9e537dd81618146a2976a10bbb3ebe03ef3 100644
--- a/homeassistant/components/verisure.py
+++ b/homeassistant/components/verisure.py
@@ -6,19 +6,19 @@ https://home-assistant.io/components/verisure/
 """
 import logging
 import threading
-import time
 import os.path
 from datetime import timedelta
 
 import voluptuous as vol
 
-from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
+from homeassistant.const import (CONF_PASSWORD, CONF_USERNAME,
+                                 EVENT_HOMEASSISTANT_STOP)
 from homeassistant.helpers import discovery
 from homeassistant.util import Throttle
 import homeassistant.config as conf_util
 import homeassistant.helpers.config_validation as cv
 
-REQUIREMENTS = ['vsure==0.11.1']
+REQUIREMENTS = ['vsure==1.3.6', 'jsonpath==0.75']
 
 _LOGGER = logging.getLogger(__name__)
 
@@ -26,6 +26,7 @@ ATTR_DEVICE_SERIAL = 'device_serial'
 
 CONF_ALARM = 'alarm'
 CONF_CODE_DIGITS = 'code_digits'
+CONF_DOOR_WINDOW = 'door_window'
 CONF_HYDROMETERS = 'hygrometers'
 CONF_LOCKS = 'locks'
 CONF_MOUSE = 'mouse'
@@ -45,6 +46,7 @@ CONFIG_SCHEMA = vol.Schema({
         vol.Required(CONF_USERNAME): cv.string,
         vol.Optional(CONF_ALARM, default=True): cv.boolean,
         vol.Optional(CONF_CODE_DIGITS, default=4): cv.positive_int,
+        vol.Optional(CONF_DOOR_WINDOW, default=True): cv.boolean,
         vol.Optional(CONF_HYDROMETERS, default=True): cv.boolean,
         vol.Optional(CONF_LOCKS, default=True): cv.boolean,
         vol.Optional(CONF_MOUSE, default=True): cv.boolean,
@@ -66,9 +68,12 @@ def setup(hass, config):
     HUB = VerisureHub(config[DOMAIN], verisure)
     if not HUB.login():
         return False
+    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP,
+                         lambda event: HUB.logout())
+    HUB.update_overview()
 
     for component in ('sensor', 'switch', 'alarm_control_panel', 'lock',
-                      'camera'):
+                      'camera', 'binary_sensor'):
         discovery.load_platform(hass, component, DOMAIN, {}, config)
 
     descriptions = conf_util.load_yaml_config_file(
@@ -93,132 +98,73 @@ class VerisureHub(object):
 
     def __init__(self, domain_config, verisure):
         """Initialize the Verisure hub."""
-        self.alarm_status = {}
-        self.lock_status = {}
-        self.climate_status = {}
-        self.mouse_status = {}
-        self.smartplug_status = {}
-        self.smartcam_status = {}
-        self.smartcam_dict = {}
+        self.overview = {}
+        self.imageseries = {}
 
         self.config = domain_config
         self._verisure = verisure
 
         self._lock = threading.Lock()
 
-        # When MyPages is brought up from maintenance it sometimes give us a
-        # "wrong password" message. We will continue to retry after maintenance
-        # regardless of that error.
-        self._disable_wrong_password_error = False
-        self._password_retries = 1
-        self._reconnect_timeout = time.time()
-
-        self.my_pages = verisure.MyPages(
+        self.session = verisure.Session(
             domain_config[CONF_USERNAME],
             domain_config[CONF_PASSWORD])
 
+        import jsonpath
+        self.jsonpath = jsonpath.jsonpath
+
     def login(self):
-        """Login to Verisure MyPages."""
+        """Login to Verisure."""
         try:
-            self.my_pages.login()
+            self.session.login()
         except self._verisure.Error as ex:
-            _LOGGER.error("Could not log in to verisure mypages, %s", ex)
+            _LOGGER.error('Could not log in to verisure, %s', ex)
             return False
         return True
 
-    @Throttle(timedelta(seconds=1))
-    def update_alarms(self):
-        """Update the status of the alarm."""
-        self.update_component(
-            self.my_pages.alarm.get,
-            self.alarm_status)
-
-    @Throttle(timedelta(seconds=1))
-    def update_locks(self):
-        """Update the status of the locks."""
-        self.update_component(
-            self.my_pages.lock.get,
-            self.lock_status)
+    def logout(self):
+        """Logout from Verisure."""
+        try:
+            self.session.logout()
+        except self._verisure.Error as ex:
+            _LOGGER.error('Could not log out from verisure, %s', ex)
+            return False
+        return True
 
     @Throttle(timedelta(seconds=60))
-    def update_climate(self):
-        """Update the status of the climate units."""
-        self.update_component(
-            self.my_pages.climate.get,
-            self.climate_status)
+    def update_overview(self):
+        """Update the overview."""
+        try:
+            self.overview = self.session.get_overview()
+        except self._verisure.ResponseError as ex:
+            _LOGGER.error('Could not read overview, %s', ex)
+            if ex.status_code == 503:  # Service unavailable
+                _LOGGER.info('Trying to log in again')
+                self.login()
+            else:
+                raise
 
     @Throttle(timedelta(seconds=60))
-    def update_mousedetection(self):
-        """Update the status of the mouse detectors."""
-        self.update_component(
-            self.my_pages.mousedetection.get,
-            self.mouse_status)
-
-    @Throttle(timedelta(seconds=1))
-    def update_smartplugs(self):
-        """Update the status of the smartplugs."""
-        self.update_component(
-            self.my_pages.smartplug.get,
-            self.smartplug_status)
-
-    @Throttle(timedelta(seconds=30))
-    def update_smartcam(self):
-        """Update the status of the smartcam."""
-        self.update_component(
-            self.my_pages.smartcam.get,
-            self.smartcam_status)
-
-    @Throttle(timedelta(seconds=30))
-    def update_smartcam_imagelist(self):
-        """Update the imagelist for the camera."""
-        _LOGGER.debug("Running update imagelist")
-        self.smartcam_dict = self.my_pages.smartcam.get_imagelist()
-        _LOGGER.debug("New dict: %s", self.smartcam_dict)
+    def update_smartcam_imageseries(self):
+        """Update the image series."""
+        self.imageseries = self.session.get_camera_imageseries()
 
     @Throttle(timedelta(seconds=30))
     def smartcam_capture(self, device_id):
         """Capture a new image from a smartcam."""
-        self.my_pages.smartcam.capture(device_id)
-
-    @property
-    def available(self):
-        """Return True if hub is available."""
-        return self._password_retries >= 0
-
-    def update_component(self, get_function, status):
-        """Update the status of Verisure components."""
-        try:
-            for overview in get_function():
-                try:
-                    status[overview.id] = overview
-                except AttributeError:
-                    status[overview.deviceLabel] = overview
-        except self._verisure.Error as ex:
-            _LOGGER.info("Caught connection error %s, tries to reconnect", ex)
-            self.reconnect()
-
-    def reconnect(self):
-        """Reconnect to Verisure MyPages."""
-        if (self._reconnect_timeout > time.time() or
-                not self._lock.acquire(blocking=False) or
-                self._password_retries < 0):
-            return
-        try:
-            self.my_pages.login()
-            self._disable_wrong_password_error = False
-            self._password_retries = 1
-        except self._verisure.LoginError as ex:
-            _LOGGER.error("Wrong user name or password for Verisure MyPages")
-            if self._disable_wrong_password_error:
-                self._reconnect_timeout = time.time() + 60*60
-            else:
-                self._password_retries = self._password_retries - 1
-        except self._verisure.MaintenanceError:
-            self._disable_wrong_password_error = True
-            self._reconnect_timeout = time.time() + 60*60
-            _LOGGER.error("Verisure MyPages down for maintenance")
-        except self._verisure.Error as ex:
-            _LOGGER.error("Could not login to Verisure MyPages, %s", ex)
-            self._reconnect_timeout = time.time() + 60
-        finally:
-            self._lock.release()
+        self.session.capture_image(device_id)
+
+    def get(self, jpath, *args):
+        """Get values from the overview that matches the jsonpath."""
+        res = self.jsonpath(self.overview, jpath % args)
+        return res if res else []
+
+    def get_first(self, jpath, *args):
+        """Get first value from the overview that matches the jsonpath."""
+        res = self.get(jpath, *args)
+        return res[0] if res else None
+
+    def get_image_info(self, jpath, *args):
+        """Get values from the imageseries that matches the jsonpath."""
+        res = self.jsonpath(self.imageseries, jpath % args)
+        return res if res else []
diff --git a/requirements_all.txt b/requirements_all.txt
index 161386db61dddfeb14dc56c02d416c54eea9ef48..ee2de706846e851c680496d1aa1e8cd394c1c987 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -327,6 +327,9 @@ insteonlocal==0.52
 # homeassistant.components.insteon_plm
 insteonplm==0.7.4
 
+# homeassistant.components.verisure
+jsonpath==0.75
+
 # homeassistant.components.media_player.kodi
 # homeassistant.components.notify.kodi
 jsonrpc-async==0.6
@@ -893,7 +896,7 @@ uvcclient==0.10.0
 volvooncall==0.3.3
 
 # homeassistant.components.verisure
-vsure==0.11.1
+vsure==1.3.6
 
 # homeassistant.components.sensor.vasttrafik
 vtjp==0.1.14