def test_update_properties(mocker): alarm = Paradox() alarm.panel = mocker.MagicMock() ps = mocker.patch("paradox.lib.ps") alarm._on_status_update(converted_status) print(ps)
async def test_update_properties(mocker): alarm = Paradox() alarm.panel = mocker.MagicMock() ps = mocker.patch("paradox.lib.ps") alarm._on_status_update(converted_status) await asyncio.sleep(0.01)
def main(args): global alarm, interface_manager if 'config' in args and args.config is not None: import os config_file = os.path.abspath(args.config) cfg.load(config_file) else: cfg.load() config_logger(logger) logger.info("Starting Paradox Alarm Interface") logger.info("Console Log level set to {}".format( cfg.LOGGING_LEVEL_CONSOLE)) interface_manager = InterfaceManager(config=cfg) interface_manager.start() time.sleep(1) signal.signal(signal.SIGINT, exit_handler) # Start interacting with the alarm alarm = Paradox() interface_manager.set_alarm(alarm) retry = 1 while alarm is not None: logger.info("Starting...") retry_time_wait = 2 ^ retry retry_time_wait = 30 if retry_time_wait > 30 else retry_time_wait try: if alarm.connect(): retry = 1 alarm.loop() else: logger.error("Unable to connect to alarm") time.sleep(retry_time_wait) except ConnectionError as e: # Connection to IP Module or MQTT lost logger.error("Connection to panel lost: %s. Restarting" % str(e)) time.sleep(retry_time_wait) except OSError: # Connection to IP Module or MQTT lost logger.exception("Restarting") time.sleep(retry_time_wait) except (KeyboardInterrupt, SystemExit): break # break exits the retry loop except Exception: logger.exception("Restarting") time.sleep(retry_time_wait) retry += 1 exit_handler()
def alarm(mocker): mocker.patch('paradox.lib.utils.main_thread_loop', asyncio.get_event_loop()) # conn = mocker.patch("paradox.interfaces.mqtt.core.MQTTConnection") # conn.connected = True alarm = Paradox(None) mocker.spy(alarm.storage, 'update_container_object') alarm.panel = MagicMock() return alarm
def main(): logger.info("Starting Paradox Alarm Interface") logger.info("Console Log level set to {}".format(cfg.LOGGING_LEVEL_CONSOLE)) interface_manager = InterfaceManager(config=cfg) interface_manager.start() time.sleep(1) # Load a connection to the alarm if cfg.CONNECTION_TYPE == "Serial": logger.info("Using Serial Connection") from paradox.connections.serial_connection import SerialCommunication connection = SerialCommunication(port=cfg.SERIAL_PORT) elif cfg.CONNECTION_TYPE == 'IP': logger.info("Using IP Connection") from paradox.connections.ip_connection import IPConnection connection = IPConnection(host=cfg.IP_CONNECTION_HOST, port=cfg.IP_CONNECTION_PORT, password=cfg.IP_CONNECTION_PASSWORD) else: logger.error("Invalid connection type: {}".format(cfg.CONNECTION_TYPE)) sys.exit(-1) # Start interacting with the alarm alarm = Paradox(connection=connection, interface=interface_manager) retry = 1 while True: logger.info("Starting...") retry_time_wait = 2 ^ retry retry_time_wait = 30 if retry_time_wait > 30 else retry_time_wait try: alarm.disconnect() if alarm.connect(): retry = 1 interface_manager.set_alarm(alarm) alarm.loop() else: logger.error("Unable to connect to alarm") time.sleep(retry_time_wait) except (ConnectionError, OSError): # Connection to IP Module or MQTT lost logger.exception("Restarting") time.sleep(retry_time_wait) except (KeyboardInterrupt, SystemExit): logger.info("Exit start") if alarm: alarm.disconnect() break # break exits the retry loop except Exception: logger.exception("Restarting") time.sleep(retry_time_wait) retry += 1 interface_manager.stop() logger.info("Good bye!")
def test_on_labels_load(): alarm = Paradox(None) alarm._on_labels_load( data=dict(partition={1: dict(id=1, label="Partition 1", key="Partition_1")}) ) assert isinstance(alarm.storage.get_container("partition"), ElementTypeContainer) assert alarm.storage.get_container_object("partition", "Partition_1") == dict( id=1, label="Partition 1", key="Partition_1" )
def test_current_alarm(mocker): alarm = Paradox(None) mocker.spy(alarm.storage, 'update_container_object') alarm.panel = Panel_EVO192(alarm, 5) send_initial_status(alarm) payload = binascii.unhexlify('e2ff1cc414130b010f2c1801030000000000024f66666963652020202020202020202000d9') raw = LiveEvent.parse(payload) alarm.handle_event_message(raw) alarm.storage.update_container_object.assert_any_call('partition', 'Partition_1', { 'current_state': 'triggered' })
def test_partitions(mocker): alarm = Paradox() alarm.panel = mocker.MagicMock() alarm.panel.property_map = { "arm": dict(level=EventLevel.INFO, message={"True": "{Type} {label} is armed", "False": "{Type} {label} is disarmed"}), } event = mocker.MagicMock() mocker.patch("paradox.lib.ps.sendChange") mocker.patch("paradox.lib.ps.sendEvent") mocker.patch('paradox.event.ChangeEvent', return_value=event) ps.sendMessage("labels_loaded", data=dict( partition={ 1: dict( id=1, label='Partition 1', key='Partition_1' ) } )) assert isinstance(alarm.panel, mocker.MagicMock) alarm.storage.update_container_object("partition", "Partition_1", dict(arm=True)) ps.sendChange.assert_called_once_with(Change('partition', 'Partition_1', 'arm', True, initial=True)) ps.sendChange.reset_mock() assert isinstance(alarm.panel, mocker.MagicMock) ps.sendMessage("status_update", status=dict( partition={ 1: dict( arm=False ) } )) assert isinstance(alarm.panel, mocker.MagicMock) ps.sendChange.assert_any_call(Change('partition', 'Partition_1', 'current_state', 'disarmed', initial=True)) ps.sendChange.assert_any_call(Change('partition', 'Partition_1', 'target_state', 'disarmed', initial=True)) ps.sendChange.assert_any_call(Change('partition', 'Partition_1', 'arm', False, initial=False)) assert ps.sendChange.call_count == 3 assert ps.sendEvent.call_count == 0
def main(args): global alarm, interface_manager if 'config' in args and args.config is not None: import os config_file = os.path.abspath(args.config) cfg.load(config_file) else: cfg.load() config_logger(logger) logger.info(f"Starting Paradox Alarm Interface {VERSION}") logger.info(f"Config loaded from {cfg.CONFIG_FILE_LOCATION}") logger.info(f"Console Log level set to {cfg.LOGGING_LEVEL_CONSOLE}") signal.signal(signal.SIGINT, exit_handler) signal.signal(signal.SIGTERM, exit_handler) # Start interacting with the alarm alarm = Paradox() interface_manager = InterfaceManager(alarm, config=cfg) interface_manager.start() loop = asyncio.get_event_loop() loop.run_until_complete(run_loop(alarm)) exit_handler()
async def dump_memory(file, memory): alarm = Paradox() if not await alarm.connect(): logger.error("Failed to connect") await alarm.dump_memory(file, memory) await alarm.disconnect()
def test_convert_raw_status(mocker): mocker.patch('paradox.lib.ps') p = Paradox() status = convert_raw_status(message_parser_output) assert status["zone"] == { 1: dict(open=False, tamper=False, low_battery=False, generated_alarm=False, presently_in_alarm=False, activated_entry_delay=False, activated_intellizone_delay=False, bypassed=False, shutted_down=False, tx_delay=False, supervision_trouble=False), 2: dict(open=False, tamper=False, low_battery=False, generated_alarm=False, presently_in_alarm=False, activated_entry_delay=False, activated_intellizone_delay=False, bypassed=False, shutted_down=False, tx_delay=False, supervision_trouble=False) } assert status["partition"] == message_parser_output["partition_status"] assert status["door"] == {1: dict(open=False), 2: dict(open=False)} assert status["bus-module"] == {1: dict(trouble=False), 2: dict(trouble=False)} assert status["system"]["troubles"] == message_parser_output["system"]["troubles"] a = json.dumps(converted_status, sort_keys=True, indent=2, default=str) b = json.dumps(status, sort_keys=True, indent=2, default=str) assert a == b
async def test_control_doors(mocker): alarm = Paradox() alarm.panel = mocker.Mock(spec=Panel) alarm.panel.control_doors = CoroutineMock() alarm.storage.get_container("door").deep_merge( {1: { "id": 1, "key": "Door 1" }}) assert await alarm.control_door("1", "unlock") alarm.panel.control_doors.assert_called_once_with([1], "unlock") alarm.panel.control_doors.reset_mock() assert await alarm.control_door("Door 1", "unlock") alarm.panel.control_doors.assert_called_once_with([1], "unlock")
async def setup_panel(mocker): mocker.patch.multiple( cfg, LOGGING_LEVEL_CONSOLE=logging.DEBUG, LOGGING_DUMP_PACKETS=True ) mocker.patch("paradox.lib.utils.main_thread_loop", asyncio.get_event_loop()) # cfg.LOGGING_LEVEL_CONSOLE = logging.DEBUG # cfg.LOGGING_DUMP_PACKETS = True logger.setLevel(logging.DEBUG) alarm = Paradox() # alarm.work_loop.set_debug(True) alarm.run_state = RunState.RUN start_communication_response = Container( fields=Container(value=Container(product_id="MAGELLAN_MG5050")) ) alarm.panel = create_panel(alarm, start_communication_response) await send_initial_status(alarm) con = MockConnection(alarm.on_connection_message) alarm._connection = con alarm._register_connection_handlers() return alarm, con
def test_partitions_callable_prop(mocker): alarm = Paradox() alarm.panel = mocker.MagicMock() alarm.panel.property_map = { "arm": dict(level=EventLevel.INFO, message={ "True": "{Type} {label} is armed", "False": "{Type} {label} is disarmed" }), } alarm._on_labels_load(data=dict( partition={1: dict(id=1, label='Partition 1', key='Partition_1')})) sendChange = mocker.patch("paradox.data.memory_storage.ps.sendChange") alarm._on_status_update(status=dict(partition={1: dict(arm=False)})) sendChange.assert_any_call( Change('partition', 'Partition_1', 'arm', False, initial=True)) sendChange.reset_mock() alarm.storage.update_container_object("partition", "Partition_1", dict(arm=lambda old: not old)) sendChange.assert_any_call(Change('partition', 'Partition_1', 'arm', True))
def test_current_state_armed_away(mocker): alarm = Paradox(None) mocker.spy(alarm.storage, 'update_container_object') alarm.panel = MagicMock() send_initial_status(alarm) sendMessage("status_update", status=dict( partition={ 1: dict( arm=True ) } )) alarm.storage.update_container_object.assert_any_call('partition', 'Partition_1', { 'current_state': 'armed_away', 'target_state': 'armed_away' })
def test_on_labels_load(): alarm = Paradox(None) alarm._on_labels_load(data=dict( partition={ 1: dict( id=1, label='Partition 1', key='Partition_1' ) } )) assert isinstance(alarm.storage.get_container('partition'), ElementTypeContainer) assert alarm.storage.get_container_object('partition', 'Partition_1') == dict( id=1, label='Partition 1', key='Partition_1' )
async def test_send_panic(mocker): alarm = Paradox() alarm.panel = mocker.Mock(spec=Panel) alarm.panel.send_panic = CoroutineMock() alarm.storage.get_container("partition").deep_merge( {1: { "id": 1, "key": "Partition 1" }}) alarm.storage.get_container("user").deep_merge( {3: { "id": 3, "key": "User 3" }}) assert await alarm.send_panic("1", "fire", "3") alarm.panel.send_panic.assert_called_once_with([1], "fire", 3) alarm.panel.send_panic.reset_mock() assert await alarm.send_panic("Partition 1", "fire", "User 3") alarm.panel.send_panic.assert_called_once_with([1], "fire", 3)
def test_partitions_callable_prop(mocker): alarm = Paradox() alarm.panel = mocker.MagicMock() alarm.panel.property_map = { "arm": dict(level=EventLevel.INFO, message={"True": "{Type} {label} is armed", "False": "{Type} {label} is disarmed"}), } event = mocker.MagicMock() mocker.patch.object(ps, "sendChange") mocker.patch.object(ps, "sendEvent") mocker.patch('paradox.event.ChangeEvent', return_value=event) ps.sendMessage("labels_loaded", data=dict( partition={ 1: dict( id=1, label='Partition 1', key='Partition_1' ) } )) ps.sendMessage("status_update", status=dict( partition={ 1: dict( arm=False ) } )) ps.sendChange.assert_any_call(Change('partition', 'Partition_1', 'arm', False, initial=True)) ps.sendChange.reset_mock() alarm.storage.update_container_object("partition", "Partition_1", dict(arm=lambda old: not old)) ps.sendChange.assert_any_call(Change('partition', 'Partition_1', 'arm', True)) ps.sendEvent.call_count = 0
def test_convert_raw_status(mocker): mocker.patch.object(ps, 'sendChange') mocker.patch.object(ps, 'sendEvent') connection = mocker.stub(name='Connection_stub') p = Paradox(connection) status = convert_raw_status(evo_status) assert status["zone"] == { 1: dict(open=False, tamper=False, low_battery=False, generated_alarm=False, presently_in_alarm=False, activated_entry_delay=False, activated_intellizone_delay=False, bypassed=False, shutted_down=False, tx_delay=False, supervision_trouble=False), 2: dict(open=False, tamper=False, low_battery=False, generated_alarm=False, presently_in_alarm=False, activated_entry_delay=False, activated_intellizone_delay=False, bypassed=False, shutted_down=False, tx_delay=False, supervision_trouble=False) } assert status["partition"] == evo_status["partition_status"] assert status["door"] == {1: dict(open=False), 2: dict(open=False)} assert status["bus-module"] == { 1: dict(trouble=False), 2: dict(trouble=False) } assert status["system"]["power"] == { "vdc": 16.5, "battery": 13.4, "dc": 13.5 } assert status["system"]["date"] == { 'time': datetime.datetime(2019, 10, 11, 21, 12, 2), 'weekday': 6 } assert status["system"]["troubles"] == evo_status["system"]["troubles"]
def test_partitions(mocker): alarm = Paradox() alarm.panel = mocker.MagicMock() alarm.panel.property_map = { "arm": dict( level=EventLevel.INFO, message={ "True": "{Type} {label} is armed", "False": "{Type} {label} is disarmed", }, ), } alarm._on_labels_load(data=dict( partition={1: dict(id=1, label="Partition 1", key="Partition_1")})) sendChange = mocker.patch("paradox.data.memory_storage.ps.sendChange") alarm.storage.update_container_object("partition", "Partition_1", dict(arm=True)) sendChange.assert_called_once_with( Change("partition", "Partition_1", "arm", True, initial=True)) sendChange.reset_mock() assert isinstance(alarm.panel, mocker.MagicMock) alarm._on_status_update(status=dict(partition={1: dict(arm=False)})) assert isinstance(alarm.panel, mocker.MagicMock) sendChange.assert_any_call( Change("partition", "Partition_1", "current_state", "disarmed", initial=True)) sendChange.assert_any_call( Change("partition", "Partition_1", "target_state", "disarmed", initial=True)) sendChange.assert_any_call( Change("partition", "Partition_1", "arm", False, initial=False))
def make_paradox(self) -> Paradox: if self._serial_port: config.CONNECTION_TYPE = 'Serial' config.SERIAL_PORT = self._serial_port config.SERIAL_BAUD = self._serial_baud self.debug('using serial connection on %s:%s', config.SERIAL_PORT, config.SERIAL_BAUD) else: # IP connection, e.g. 192.168.1.2:10000:paradox config.CONNECTION_TYPE = 'IP' config.IP_CONNECTION_HOST = self._ip_host config.IP_CONNECTION_PORT = self._ip_port config.IP_CONNECTION_PASSWORD = self._ip_password.encode() self.debug('using IP connection on %s:%s', config.IP_CONNECTION_HOST, config.IP_CONNECTION_PORT) return Paradox()
async def setup_panel(mocker): mocker.patch.object(cfg, "LOGGING_LEVEL_CONSOLE", logging.DEBUG) mocker.patch.object(cfg, "LOGGING_DUMP_PACKETS", True) mocker.patch("paradox.lib.utils.main_thread_loop", asyncio.get_event_loop()) # cfg.LOGGING_LEVEL_CONSOLE = logging.DEBUG # cfg.LOGGING_DUMP_PACKETS = True logger.setLevel(logging.DEBUG) alarm = Paradox() #alarm.work_loop.set_debug(True) alarm.run_state = RunState.RUN alarm.panel = create_panel(alarm, 'MAGELLAN_MG5050') await send_initial_status(alarm) con = MockConnection(alarm.on_connection_message) alarm._connection = con alarm._register_connection_handlers() return alarm, con
async def test_current_alarm(mocker): mocker.patch('paradox.lib.utils.main_thread_loop', asyncio.get_event_loop()) alarm = Paradox(None) alarm.panel = Panel_EVO192(alarm, 5) mocker.spy(alarm.storage, 'update_container_object') send_initial_status(alarm) payload = binascii.unhexlify('e2ff1cc414130b010f2c1801030000000000024f66666963652020202020202020202000d9') raw = LiveEvent.parse(payload) alarm.handle_event_message(raw) await asyncio.sleep(0.01) alarm.storage.update_container_object.assert_any_call('partition', 'Partition_1', { 'current_state': 'triggered' }) alarm.panel = None
def main(args): global alarm, interface_manager time.tzset() if "config" in args and args.config is not None: import os config_file = os.path.abspath(args.config) cfg.load(config_file) else: cfg.load() config_logger(logger) logger.info(f"Starting Paradox Alarm Interface {VERSION}") logger.info(f"Config loaded from {cfg.CONFIG_FILE_LOCATION}") logger.info(f"Console Log level set to {cfg.LOGGING_LEVEL_CONSOLE}") # Registering additional encodings register_encodings() # Start interacting with the alarm alarm = Paradox() loop = asyncio.get_event_loop() for signame in ("SIGINT", "SIGTERM"): sig = getattr(signal, signame) loop.add_signal_handler( sig, lambda: asyncio.ensure_future(exit_handler(signame))) interface_manager = InterfaceManager(alarm, config=cfg) interface_manager.start() loop = asyncio.get_event_loop() loop.run_until_complete(run_loop()) sys.exit(0)
async def test_current_alarm(mocker): mocker.patch("paradox.lib.utils.main_thread_loop", asyncio.get_event_loop()) alarm = Paradox(None) alarm.panel = create_evo192_panel(alarm) mocker.spy(alarm.storage, "update_container_object") send_initial_status(alarm) payload = binascii.unhexlify( "e2ff1cc414130b010f2c1801030000000000024f66666963652020202020202020202000d9" ) raw = LiveEvent.parse(payload) alarm.handle_event_message(raw) await asyncio.sleep(0.01) alarm.storage.update_container_object.assert_any_call( "partition", "Partition_1", {"current_state": "triggered"}) alarm.panel = None
def main(args): global alarm, interface_manager if 'config' in args and args.config is not None: import os config_file = os.path.abspath(args.config) cfg.load(config_file) else: cfg.load() config_logger(logger) logger.info("Starting Paradox Alarm Interface") logger.info("Console Log level set to {}".format( cfg.LOGGING_LEVEL_CONSOLE)) interface_manager = InterfaceManager(config=cfg) interface_manager.start() time.sleep(1) # Load a connection to the alarm if cfg.CONNECTION_TYPE == "Serial": logger.info("Using Serial Connection") from paradox.connections.serial_connection import SerialCommunication connection = SerialCommunication(port=cfg.SERIAL_PORT, baud=cfg.SERIAL_BAUD) elif cfg.CONNECTION_TYPE == 'IP': logger.info("Using IP Connection") from paradox.connections.ip_connection import IPConnection connection = IPConnection(host=cfg.IP_CONNECTION_HOST, port=cfg.IP_CONNECTION_PORT, password=cfg.IP_CONNECTION_PASSWORD) else: logger.error("Invalid connection type: {}".format(cfg.CONNECTION_TYPE)) sys.exit(-1) signal.signal(signal.SIGINT, exit_handler) # Start interacting with the alarm alarm = Paradox(connection=connection, interface=interface_manager) retry = 1 while True: logger.info("Starting...") retry_time_wait = 2 ^ retry retry_time_wait = 30 if retry_time_wait > 30 else retry_time_wait try: if alarm.connect(): retry = 1 interface_manager.set_alarm(alarm) alarm.loop() else: logger.error("Unable to connect to alarm") time.sleep(retry_time_wait) except ConnectionError as e: # Connection to IP Module or MQTT lost logger.error("Connection to panel lost: %s. Restarting" % str(e)) time.sleep(retry_time_wait) except OSError: # Connection to IP Module or MQTT lost logger.exception("Restarting") time.sleep(retry_time_wait) except (KeyboardInterrupt, SystemExit): break # break exits the retry loop except Exception: logger.exception("Restarting") time.sleep(retry_time_wait) retry += 1 exit_handler()