Skip to content

Commit

Permalink
Update zone_status logic to fix #75 (#76)
Browse files Browse the repository at this point in the history
* Update zone_status logic to fix
#75

* Update tox.ini to avoid pytest-dev/pytest#6951
until fixed.
  • Loading branch information
austinmroczek committed Apr 18, 2020
1 parent 2375877 commit 718c0d9
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 32 deletions.
24 changes: 22 additions & 2 deletions ALARM_STATUS.md
Expand Up @@ -28,14 +28,34 @@ Code | Status
## ZoneStatus
ZoneStatus is reported per Zone.

Status code we have seen are in the table below:

Code | Status
------------ | -------------
0 | Normal
1 | Bypassed
2 | Fault
8 | Tamper
8 | Trouble/Tampered
10 | Fault + Trouble
64 | Low Battery
72 | Trouble (low battery)
65 | Low Battery + Bypassed
72 | Trouble + Low Battery
256 | Alarm/Triggered

Fault is only returned when "Sensor Events" are enabled for a specific zone in Total Connect, otherwise Normal is returned.

The returned ZoneStatus code appears to be an integer that contains a number of individual bit flags.

Bit | Integer | Status
------------ | ------------- | -------------
1 | 1 | Bypassed
2 | 2 | Fault
3 | 4 | ???
4 | 8 | Tamper/Trouble
5 | 16 | ???
6 | 32 | ???
7 | 64 | Low Battery
8 | 128 | ???
9 | 256 | Triggered

So a status code of 10 ( = 2 + 8) is both faulted and troubled. Bypassed and low battery is 65 (1 + 64). Troubled and low battery is 72 (8 + 64).
10 changes: 5 additions & 5 deletions tests/test_total_connect_zone.py
Expand Up @@ -34,7 +34,7 @@
"PartitionId": "1",
"ZoneTypeId": TotalConnectClient.ZONE_TYPE_SECURITY,
"CanBeBypassed": 1,
"ZoneStatus": TotalConnectClient.ZONE_STATUS_TAMPER,
"ZoneStatus": TotalConnectClient.ZONE_STATUS_TROUBLE,
}

ZONE_LOW_BATTERY = {
Expand All @@ -50,15 +50,15 @@
"PartitionId": "1",
"ZoneTypeId": TotalConnectClient.ZONE_TYPE_SECURITY,
"CanBeBypassed": 1,
"ZoneStatus": TotalConnectClient.ZONE_STATUS_BYPASSED_LOW_BATTERY,
"ZoneStatus": 65,
}

ZONE_TROUBLE_LOW_BATTERY = {
"ZoneDescription": "Trouble Low Battery",
"PartitionId": "1",
"ZoneTypeId": TotalConnectClient.ZONE_TYPE_SECURITY,
"CanBeBypassed": 1,
"ZoneStatus": TotalConnectClient.ZONE_STATUS_TROUBLE_LOW_BATTERY,
"ZoneStatus": 72,
}

ZONE_TRIGGERED = {
Expand Down Expand Up @@ -157,7 +157,7 @@ def tests_tampered(self):
self.assertFalse(self.zone_tampered.is_faulted())
self.assertTrue(self.zone_tampered.is_tampered())
self.assertFalse(self.zone_tampered.is_low_battery())
self.assertFalse(self.zone_tampered.is_troubled())
self.assertTrue(self.zone_tampered.is_troubled())
self.assertFalse(self.zone_tampered.is_triggered())

def tests_low_battery(self):
Expand All @@ -182,7 +182,7 @@ def tests_trouble_low_battery(self):
"""Zone with low battery and trouble."""
self.assertFalse(self.zone_trouble_low_battery.is_bypassed())
self.assertFalse(self.zone_trouble_low_battery.is_faulted())
self.assertFalse(self.zone_trouble_low_battery.is_tampered())
self.assertTrue(self.zone_trouble_low_battery.is_tampered())
self.assertTrue(self.zone_trouble_low_battery.is_low_battery())
self.assertTrue(self.zone_trouble_low_battery.is_troubled())
self.assertFalse(self.zone_trouble_low_battery.is_triggered())
Expand Down
35 changes: 10 additions & 25 deletions total_connect_client/TotalConnectClient.py
Expand Up @@ -5,7 +5,6 @@

import zeep


ARM_TYPE_AWAY = 0
ARM_TYPE_STAY = 1
ARM_TYPE_STAY_INSTANT = 2
Expand All @@ -15,10 +14,8 @@
ZONE_STATUS_NORMAL = 0
ZONE_STATUS_BYPASSED = 1
ZONE_STATUS_FAULT = 2
ZONE_STATUS_TAMPER = 8
ZONE_STATUS_TROUBLE = 8 # is also Tampered
ZONE_STATUS_LOW_BATTERY = 64
ZONE_STATUS_BYPASSED_LOW_BATTERY = 65
ZONE_STATUS_TROUBLE_LOW_BATTERY = 72
ZONE_STATUS_TRIGGERED = 256

ZONE_TYPE_SECURITY = 0
Expand Down Expand Up @@ -80,7 +77,7 @@ def request(self, request, attempts=0):
attempts += 1
response = eval(self.soap_base + request)

if response.ResultCode in (self.SUCCESS, self.FEATURE_NOT_SUPPORTED,):
if response.ResultCode in (self.SUCCESS, self.FEATURE_NOT_SUPPORTED):
return zeep.helpers.serialize_object(response)
if response.ResultCode == self.INVALID_SESSION:
logging.debug(
Expand Down Expand Up @@ -246,20 +243,12 @@ def arm(self, arm_type, location_id):

def arm_custom(self, arm_type, location_id):
"""Arm custom the system. Return true if successul."""
ZONE_INFO = {
"ZoneID": "12",
"ByPass": False,
"ZoneStatus": ZONE_STATUS_NORMAL,
}
ZONE_INFO = {"ZoneID": "12", "ByPass": False, "ZoneStatus": ZONE_STATUS_NORMAL}

ZONES_LIST = {}
ZONES_LIST[0] = ZONE_INFO

CUSTOM_ARM_SETTINGS = {
"ArmMode": "1",
"ArmDelay": "5",
"ZonesList": ZONES_LIST,
}
CUSTOM_ARM_SETTINGS = {"ArmMode": "1", "ArmDelay": "5", "ZonesList": ZONES_LIST}

result = self.request(
f"CustomArmSecuritySystem(self.token, "
Expand Down Expand Up @@ -643,35 +632,31 @@ def __str__(self):

def is_bypassed(self):
"""Return true if the zone is bypassed."""
return self.status in (ZONE_STATUS_BYPASSED, ZONE_STATUS_BYPASSED_LOW_BATTERY)
return self.status & ZONE_STATUS_BYPASSED > 0

def bypass(self):
"""Set is_bypassed status."""
self.status = ZONE_STATUS_BYPASSED

def is_faulted(self):
"""Return true if the zone is faulted."""
return self.status == ZONE_STATUS_FAULT
return self.status & ZONE_STATUS_FAULT > 0

def is_tampered(self):
"""Return true if zone is tampered."""
return self.status == ZONE_STATUS_TAMPER
return self.status & ZONE_STATUS_TROUBLE > 0

def is_low_battery(self):
"""Return true if low battery."""
return self.status in (
ZONE_STATUS_LOW_BATTERY,
ZONE_STATUS_BYPASSED_LOW_BATTERY,
ZONE_STATUS_TROUBLE_LOW_BATTERY,
)
return self.status & ZONE_STATUS_LOW_BATTERY > 0

def is_troubled(self):
"""Return true if zone is troubled."""
return self.status == ZONE_STATUS_TROUBLE_LOW_BATTERY
return self.status & ZONE_STATUS_TROUBLE > 0

def is_triggered(self):
"""Return true if zone is triggered."""
return self.status == ZONE_STATUS_TRIGGERED
return self.status & ZONE_STATUS_TRIGGERED > 0

def is_type_button(self):
"""Return true if zone is a button."""
Expand Down

0 comments on commit 718c0d9

Please sign in to comment.