import time import sys import os import argparse import tkinter as tk from .core.network import UdpHandler from .core.dispatcher import MessageDispatcher from .core.scheduler import TrafficScheduler from .core.controller import RadarController from .utils.printer import dump_message from .gui.main_window import BusMonitorApp #Configuration RX_IP = os.getenv("PYBM_RX_IP", "127.0.0.1") RX_PORT = int(os.getenv("PYBM_RX_PORT", str(61553))) TARGET_IP = os.getenv("PYBM_TARGET_IP", "127.0.0.1") TARGET_PORT = int(os.getenv("PYBM_TARGET_PORT", "51553")) def main_cli(): """Command-line interface mode (original behavior)""" print("--------------------------------------------------") print(" PyBusMonitor1553 - Active Controller (CLI Mode)") print("--------------------------------------------------") # 1. Initialize Components dispatcher = MessageDispatcher() network = UdpHandler(rx_ip=RX_IP, rx_port=RX_PORT) # 2. Initialize Radar Logic Controller radar_ctrl = RadarController() # 3. Initialize Scheduler with the Controller scheduler = TrafficScheduler(network, radar_ctrl, TARGET_IP, TARGET_PORT) # 4. Define the callback for received messages def on_packet(data, addr): header, messages = dispatcher.parse_packet(data) if messages: for msg in messages: if msg.IS_TRANSMIT: print(f"\n[RX] {msg.__class__.__name__} from RT{header.ta if header else '?'}") dump_message(msg) elif header and header.errors != 0: print(f"[RX] Server Error Code: {header.errors}") # 5. Start everything network.register_callback(on_packet) network.start() scheduler.start() print(f"System Running.") print(f"RX: {RX_IP}:{RX_PORT} | TX: {TARGET_IP}:{TARGET_PORT}") print("Press Ctrl+C to stop.") try: while True: time.sleep(1) except KeyboardInterrupt: print("\nStopping...") finally: scheduler.stop() network.stop() sys.exit(0) def main_gui(): """Graphical user interface mode""" # Enable quiet mode for scheduler from .core import scheduler as sched_module sched_module.QUIET_MODE = True print("--------------------------------------------------") print(" PyBusMonitor1553 - Active Controller (GUI Mode)") print("--------------------------------------------------") # Initialize Tkinter root = tk.Tk() app = BusMonitorApp(root) # Initialize Components dispatcher = MessageDispatcher() network = UdpHandler(rx_ip=RX_IP, rx_port=RX_PORT) radar_ctrl = RadarController() scheduler = TrafficScheduler(network, radar_ctrl, TARGET_IP, TARGET_PORT) # Counters for status bar tx_count = [0] rx_count = [0] # Define the callback for received messages def on_packet(data, addr): header, messages = dispatcher.parse_packet(data) rx_count[0] += 1 if messages: for msg in messages: if msg.IS_TRANSMIT: msg_name = msg.__class__.__name__ # Convert MsgB6 -> B6, MsgA1 -> A1, etc. short_name = msg_name.replace("Msg", "") # Extract raw words if available raw_words = [] if hasattr(msg, '_raw_data') and msg._raw_data: import struct data_bytes = msg._raw_data for i in range(0, len(data_bytes), 2): if i + 1 < len(data_bytes): word = struct.unpack('RT messages (A messages) msg_name = msg.__class__.__name__ short_name = msg_name.replace("Msg", "") # Extract raw words from current message state raw_words = [] if hasattr(msg, '_data'): raw_words = list(msg._data)[:32] # Copy first 32 words # Accoda aggiornamento invece di usare root.after() diretto app.queue_message_update(short_name, msg, raw_words) scheduler.register_sent_callback(on_message_sent) # Wire up menu actions def on_connect(): network.start() scheduler.start() app.update_connection_status(True, tx_count[0], rx_count[0], "") def on_disconnect(): scheduler.stop() network.stop() app.update_connection_status(False, tx_count[0], rx_count[0], "") app._on_connect = on_connect app._on_disconnect = on_disconnect # Start networking network.register_callback(on_packet) network.start() scheduler.start() # Update initial status app.update_connection_status(True, 0, 0, "") print(f"GUI Running.") print(f"RX: {RX_IP}:{RX_PORT} | TX: {TARGET_IP}:{TARGET_PORT}") # Handle window close def on_closing(): scheduler.stop() network.stop() root.destroy() root.protocol("WM_DELETE_WINDOW", on_closing) # Run the GUI main loop try: root.mainloop() except KeyboardInterrupt: on_closing() def main(): """Main entry point with mode selection""" global TARGET_IP, TARGET_PORT parser = argparse.ArgumentParser( description='PyBusMonitor1553 - MIL-STD-1553 Bus Monitor', formatter_class=argparse.RawDescriptionHelpFormatter, epilog=''' Examples: python -m pybusmonitor1553 # Launch GUI mode (default) python -m pybusmonitor1553 --cli # Launch CLI mode python -m pybusmonitor1553 --gui # Launch GUI mode explicitly ''' ) parser.add_argument('--cli', action='store_true', help='Run in command-line interface mode') parser.add_argument('--gui', action='store_true', help='Run in graphical user interface mode (default)') parser.add_argument('--target', type=str, default=None, help=f'Target IP address (default: {TARGET_IP})') parser.add_argument('--port', type=int, default=None, help=f'Target port (default: {TARGET_PORT})') args = parser.parse_args() # Update globals if specified if args.target: TARGET_IP = args.target if args.port: TARGET_PORT = args.port if args.cli: main_cli() else: main_gui() if __name__ == "__main__": main()