Skip to content

Commit

Permalink
Fix unhandled exception with V3 systems that are missing base station (
Browse files Browse the repository at this point in the history
…#128)

info
  • Loading branch information
bachya authored Feb 27, 2020
1 parent 6b6ff1a commit c40ef9f
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 38 deletions.
80 changes: 51 additions & 29 deletions simplipy/system/v3.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Define a V3 (new) SimpliSafe system."""
from enum import Enum
import logging
from typing import Dict
from typing import Callable, Dict

import voluptuous as vol

Expand Down Expand Up @@ -64,21 +64,38 @@
)


class SystemV3(System): # pylint: disable=too-many-public-methods
def guard_missing_base_station_status(prop) -> Callable:
"""Define a guard against missing base station status."""

def decorator(system: "SystemV3") -> None:
"""Decorate."""
if system.settings_info.get("basestationStatus") is None:
_LOGGER.error(
"SimpliSafe cloud didn't return expected data for property %s: %s",
prop.__name__,
system.settings_info,
)
return None
return prop(system)

return decorator


class SystemV3(System):
"""Define a V3 (new) system."""

def __init__(self, request, get_subscription_data, location_info) -> None:
"""Initialize."""
super().__init__(request, get_subscription_data, location_info)
self._settings_info: dict = {}
self.settings_info: dict = {}

@property
def alarm_duration(self) -> int:
"""Return the number of seconds an activated alarm will sound for.
:rtype: ``int``
"""
return self._settings_info["settings"]["normal"][
return self.settings_info["settings"]["normal"][
SYSTEM_PROPERTIES_VALUE_MAP["alarm_duration"]
]

Expand All @@ -89,18 +106,19 @@ def alarm_volume(self) -> int:
:rtype: ``int``
"""
return int(
self._settings_info["settings"]["normal"][
self.settings_info["settings"]["normal"][
SYSTEM_PROPERTIES_VALUE_MAP["alarm_volume"]
]
)

@property
@property # type: ignore
@guard_missing_base_station_status
def battery_backup_power_level(self) -> int:
"""Return the power rating of the battery backup.
:rtype: ``int``
"""
return self._settings_info["basestationStatus"]["backupBattery"]
return self.settings_info["basestationStatus"]["backupBattery"]

@property
def chime_volume(self) -> int:
Expand All @@ -109,7 +127,7 @@ def chime_volume(self) -> int:
:rtype: ``int``
"""
return int(
self._settings_info["settings"]["normal"][
self.settings_info["settings"]["normal"][
SYSTEM_PROPERTIES_VALUE_MAP["chime_volume"]
]
)
Expand All @@ -120,7 +138,7 @@ def entry_delay_away(self) -> int:
:rtype: ``int``
"""
return self._settings_info["settings"]["normal"][
return self.settings_info["settings"]["normal"][
SYSTEM_PROPERTIES_VALUE_MAP["entry_delay_away"]
]

Expand All @@ -130,7 +148,7 @@ def entry_delay_home(self) -> int:
:rtype: ``int``
"""
return self._settings_info["settings"]["normal"][
return self.settings_info["settings"]["normal"][
SYSTEM_PROPERTIES_VALUE_MAP["entry_delay_home"]
]

Expand All @@ -140,7 +158,7 @@ def exit_delay_away(self) -> int:
:rtype: ``int``
"""
return self._settings_info["settings"]["normal"][
return self.settings_info["settings"]["normal"][
SYSTEM_PROPERTIES_VALUE_MAP["exit_delay_away"]
]

Expand All @@ -150,25 +168,26 @@ def exit_delay_home(self) -> int:
:rtype: ``int``
"""
return self._settings_info["settings"]["normal"][
return self.settings_info["settings"]["normal"][
SYSTEM_PROPERTIES_VALUE_MAP["exit_delay_home"]
]

@property
@property # type: ignore
@guard_missing_base_station_status
def gsm_strength(self) -> int:
"""Return the signal strength of the cell antenna.
:rtype: ``int``
"""
return self._settings_info["basestationStatus"]["gsmRssi"]
return self.settings_info["basestationStatus"]["gsmRssi"]

@property
def light(self) -> bool:
"""Return whether the base station light is on.
:rtype: ``bool``
"""
return self._settings_info["settings"]["normal"][
return self.settings_info["settings"]["normal"][
SYSTEM_PROPERTIES_VALUE_MAP["light"]
]

Expand All @@ -188,47 +207,50 @@ def power_outage(self) -> bool:
"""
return self._location_info["system"]["powerOutage"]

@property
@property # type: ignore
@guard_missing_base_station_status
def rf_jamming(self) -> bool:
"""Return whether the base station is noticing RF jamming.
:rtype: ``bool``
"""
return self._settings_info["basestationStatus"]["rfJamming"]
return self.settings_info["basestationStatus"]["rfJamming"]

@property
def voice_prompt_volume(self) -> int:
"""Return the volume level of the voice prompt.
:rtype: ``int``
"""
return self._settings_info["settings"]["normal"][
return self.settings_info["settings"]["normal"][
SYSTEM_PROPERTIES_VALUE_MAP["voice_prompt_volume"]
]

@property
@property # type: ignore
@guard_missing_base_station_status
def wall_power_level(self) -> int:
"""Return the power rating of the A/C outlet.
:rtype: ``int``
"""
return self._settings_info["basestationStatus"]["wallPower"]
return self.settings_info["basestationStatus"]["wallPower"]

@property
def wifi_ssid(self) -> str:
"""Return the ssid of the base station.
:rtype: ``str``
"""
return self._settings_info["settings"]["normal"]["wifiSSID"]
return self.settings_info["settings"]["normal"]["wifiSSID"]

@property
@property # type: ignore
@guard_missing_base_station_status
def wifi_strength(self) -> int:
"""Return the signal strength of the wifi antenna.
:rtype: ``int``
"""
return self._settings_info["basestationStatus"]["wifiRssi"]
return self.settings_info["basestationStatus"]["wifiRssi"]

async def _get_entities_payload(self, cached: bool = True) -> dict:
"""Update sensors to the latest values."""
Expand All @@ -249,7 +271,7 @@ async def _get_settings(self, cached: bool = True) -> None:
)

if settings_resp:
self._settings_info = settings_resp
self.settings_info = settings_resp

async def _set_state(self, value: Enum) -> None:
"""Set the state of the system."""
Expand All @@ -266,7 +288,7 @@ async def _set_state(self, value: Enum) -> None:

async def _set_updated_pins(self, pins: dict) -> None:
"""Post new PINs."""
self._settings_info = await self._request(
self.settings_info = await self._request(
"post",
f"ss3/subscriptions/{self.system_id}/settings/pins",
json=create_pin_payload(pins),
Expand All @@ -285,13 +307,13 @@ async def get_pins(self, cached: bool = True) -> Dict[str, str]:
await self._get_settings(cached)

pins: Dict[str, str] = {
CONF_MASTER_PIN: self._settings_info["settings"]["pins"]["master"]["pin"],
CONF_DURESS_PIN: self._settings_info["settings"]["pins"]["duress"]["pin"],
CONF_MASTER_PIN: self.settings_info["settings"]["pins"]["master"]["pin"],
CONF_DURESS_PIN: self.settings_info["settings"]["pins"]["duress"]["pin"],
}

user_pin: dict
for user_pin in [
p for p in self._settings_info["settings"]["pins"]["users"] if p["pin"]
p for p in self.settings_info["settings"]["pins"]["users"] if p["pin"]
]:
pins[user_pin["name"]] = user_pin["pin"]

Expand Down Expand Up @@ -333,4 +355,4 @@ async def set_properties(self, properties: dict) -> None:
)

if settings_resp:
self._settings_info = settings_resp
self.settings_info = settings_resp
18 changes: 9 additions & 9 deletions tests/test_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,15 +492,15 @@ async def test_properties_v3(aresponses, v3_server):

# Test "setting" various system properties by overriding their values, then
# calling the update functions:
system._settings_info["settings"]["normal"]["alarmDuration"] = 0
system._settings_info["settings"]["normal"]["alarmVolume"] = 0
system._settings_info["settings"]["normal"]["doorChime"] = 0
system._settings_info["settings"]["normal"]["entryDelayAway"] = 0
system._settings_info["settings"]["normal"]["entryDelayHome"] = 0
system._settings_info["settings"]["normal"]["exitDelayAway"] = 0
system._settings_info["settings"]["normal"]["exitDelayHome"] = 1000
system._settings_info["settings"]["normal"]["light"] = False
system._settings_info["settings"]["normal"]["voicePrompts"] = 0
system.settings_info["settings"]["normal"]["alarmDuration"] = 0
system.settings_info["settings"]["normal"]["alarmVolume"] = 0
system.settings_info["settings"]["normal"]["doorChime"] = 0
system.settings_info["settings"]["normal"]["entryDelayAway"] = 0
system.settings_info["settings"]["normal"]["entryDelayHome"] = 0
system.settings_info["settings"]["normal"]["exitDelayAway"] = 0
system.settings_info["settings"]["normal"]["exitDelayHome"] = 1000
system.settings_info["settings"]["normal"]["light"] = False
system.settings_info["settings"]["normal"]["voicePrompts"] = 0

await system.set_properties(
{
Expand Down

0 comments on commit c40ef9f

Please sign in to comment.