Repository: craigjmidwinter/total-connect-client

Issue:
new result code: failed to bypass zone
In working on the ability to bypass zones, got this error:

Error fetching totalconnect data: ('unknown result code -4504', OrderedDict([('ResultCode', -4504), ('ResultData', 'Failed to Bypass Zone')]))

See https://github.com/home-assistant/core/issues/88186



Comments:

Patch:
diff --git a/RESULT_CODES.md b/RESULT_CODES.md
index 764293c..ba2c2a7 100644
--- a/RESULT_CODES.md
+++ b/RESULT_CODES.md
@@ -19,7 +19,7 @@ ResultCode | ResultData | Notes
 -4104 | Failed to Connect with Security System | 
 -4106 | Invalid user code. Please try again. | When disarming.  https://github.com/craigjmidwinter/total-connect-client/issues/85
 -4114 | System User Code not available/invalid in Database | https://github.com/craigjmidwinter/total-connect-client/issues/36 Also happens attempting a code for an incorrect location/device.
--4504 | Failed to Bypass Zone | Happens when requesting to bypass a non-existent zone.
+-4504 | Failed to Bypass Zone | Happens when requesting to bypass a non-existent zone, or when trying to bypass a zone than cannot be bypassed (i.e. smoke detector).
 -9001 | Authorization Failed to Perform Notification Configuration | Received when trying getAllSensorsMaskStatus
 -10026 | Unable to load your scenes, please try syncing your panel in the Locations menu.  If your panel is still not connecting, please contact your Security Dealer for support | 
 -12104 | Automation - We are unable to load your automation devices, please try again or contact your security dealer for support | GetAutomationDeviceStatus with location module flag Automation = 0
diff --git a/pyproject.toml b/pyproject.toml
index c97442d..9b48fb0 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta:__legacy__"
 
 [project]
 name="total_connect_client"
-version="2023.1"
+version="2023.2"
 authors = [
   { name="Craig J. Midwinter", email="craig.j.midwinter@gmail.com" },
 ]
diff --git a/total_connect_client/client.py b/total_connect_client/client.py
index 6122fe7..3d0a28e 100644
--- a/total_connect_client/client.py
+++ b/total_connect_client/client.py
@@ -23,6 +23,7 @@ from .const import ArmType, _ResultCode
 from .exceptions import (
     AuthenticationError,
     BadResultCodeError,
+    FailedToBypassZone,
     FeatureNotSupportedError,
     InvalidSessionError,
     RetryableTotalConnectError,
@@ -179,6 +180,8 @@ class TotalConnectClient:
             raise UsercodeInvalid(rc.name, response)
         if rc == _ResultCode.FEATURE_NOT_SUPPORTED:
             raise FeatureNotSupportedError(rc.name, response)
+        if rc == _ResultCode.FAILED_TO_BYPASS_ZONE:
+            raise FailedToBypassZone(rc.name, response)            
         raise BadResultCodeError(rc.name, response)
 
     def _send_one_request(self, operation_name, args):
diff --git a/total_connect_client/const.py b/total_connect_client/const.py
index 7b99ec8..ef7495f 100644
--- a/total_connect_client/const.py
+++ b/total_connect_client/const.py
@@ -157,6 +157,7 @@ class _ResultCode(Enum):
 
     BAD_USER_OR_PASSWORD = -50004
     INVALID_SESSIONID = -30002
+    FAILED_TO_BYPASS_ZONE = -4504
     COMMAND_FAILED = -4502
     USER_CODE_UNAVAILABLE = -4114
     USER_CODE_INVALID = -4106
diff --git a/total_connect_client/exceptions.py b/total_connect_client/exceptions.py
index c50fdde..824d3a8 100644
--- a/total_connect_client/exceptions.py
+++ b/total_connect_client/exceptions.py
@@ -46,3 +46,7 @@ class UsercodeUnavailable(TotalConnectError):
 
 class ServiceUnavailable(TotalConnectError):
     """The TotalConnect service is unavailable or unreachable."""
+
+
+class FailedToBypassZone(TotalConnectError):
+    """Failed to bypass zone because it is non-existent or it cannot be bypassed."""
diff --git a/total_connect_client/location.py b/total_connect_client/location.py
index 891348e..9646ab3 100644
--- a/total_connect_client/location.py
+++ b/total_connect_client/location.py
@@ -324,5 +324,5 @@ class TotalConnectLocation:
                 zone = TotalConnectZone(zonedata)
                 self.zones[zid] = zone
 
-            if zone.is_low_battery() and self.auto_bypass_low_battery:
+            if zone.is_low_battery() and zone.can_be_bypassed and self.auto_bypass_low_battery:
                 self.zone_bypass(zid)


Test patch:
diff --git a/tests/test_client_zone_bypass.py b/tests/test_client_zone_bypass.py
index 0deeef3..a546683 100644
--- a/tests/test_client_zone_bypass.py
+++ b/tests/test_client_zone_bypass.py
@@ -8,7 +8,7 @@ from common import create_client
 from const import LOCATION_INFO_BASIC_NORMAL
 
 from total_connect_client.const import _ResultCode
-from total_connect_client.exceptions import BadResultCodeError
+from total_connect_client.exceptions import FailedToBypassZone
 
 RESPONSE_ZONE_BYPASS_SUCCESS = {
     "ResultCode": _ResultCode.SUCCESS.value,
@@ -17,7 +17,7 @@ RESPONSE_ZONE_BYPASS_SUCCESS = {
 
 # guessing on the response...don't know for sure
 RESPONSE_ZONE_BYPASS_FAILURE = {
-    "ResultCode": _ResultCode.COMMAND_FAILED.value,
+    "ResultCode": _ResultCode.FAILED_TO_BYPASS_ZONE.value,
     "ResultData": "None",
 }
 
@@ -65,7 +65,7 @@ class TestTotalConnectClient(unittest.TestCase):
             assert zone.is_bypassed() is False
 
             # try to bypass the zone
-            with pytest.raises(BadResultCodeError):
+            with pytest.raises(FailedToBypassZone):
                 location.zone_bypass("1")
 
             # should not be bypassed