diff --git a/paradox/hardware/panel.py b/paradox/hardware/panel.py index 4298bf10..0f3ab558 100644 --- a/paradox/hardware/panel.py +++ b/paradox/hardware/panel.py @@ -100,7 +100,13 @@ def get_error_message(error_code) -> str: elif error_code == 0x1C: message = "Invalid label number" else: - message = error_str + # Include the hex form so unknown codes can be looked up easily + # in Paradox docs / issues (e.g. "29 (0x1D)" reported by panels + # in response to PGM and panic commands on some EVO firmwares). + if isinstance(error_code, int): + message = f"{error_str} (0x{error_code:02X})" + else: + message = error_str return message diff --git a/tests/hardware/evo/test_pgm.py b/tests/hardware/evo/test_pgm.py index 88687bcd..70491868 100644 --- a/tests/hardware/evo/test_pgm.py +++ b/tests/hardware/evo/test_pgm.py @@ -68,6 +68,19 @@ def test_pgm4_deactivate_and_monitor(): assert a == expected_out +def test_pgm5_activate_and_monitor(): + # PGM 5 maps to bit 4 of the bitmap (byte offset 6 = 0x10). + # Onboard PGM 5 is the only dry relay on the EVO192 mainboard; see + # https://github.com/ParadoxAlarmInterface/pai/issues/580 + expected_out = unhexlify("4013060000001000000000000000030000006c") + + pgms = [5] + + a = PerformPGMAction.build({"fields": {"value": {"pgms": pgms, "command": "on"}}}) + + assert a == expected_out + + def test_pgm_flags_1(): parser = PGMFlags(1) assert parser.sizeof() == 4