from pymodbus.client import ModbusSerialClient import time import traceback import argparse import serial.tools.list_ports from src.hardware import Hardware from src.logic import loop def get_first_available_com_port(): ports = list(serial.tools.list_ports.comports()) return ports[0].device if ports else 'COM3' def main(): parser = argparse.ArgumentParser(description='UNO Relay Modbus Controller') parser.add_argument('--com_port', type=str, default=get_first_available_com_port(), help='COM port for the Modbus connection') parser.add_argument('--slave_id', type=int, default=1, help='Slave ID for the Modbus device') parser.add_argument('--cycle_time', type=float, default=0.05, help='Cycle time in seconds for the main loop') args = parser.parse_args() com_port = args.com_port slave_id = args.slave_id cycle_time = args.cycle_time while True: try: client = ModbusSerialClient( port=com_port, baudrate=57600, bytesize=8, parity='N', stopbits=1, timeout=1 ) client.connect() time.sleep(3) hardware = Hardware(client, slave_id) while True: start_time = time.time() hardware.update() loop(hardware) execution_time = time.time() - start_time if execution_time > cycle_time: print(f"Warning: Loop execution time ({execution_time:.4f}s) exceeded cycle time ({cycle_time:.4f}s)") sleep_time = max(0, cycle_time - execution_time) time.sleep(sleep_time) except KeyboardInterrupt: print("Stopped by user") break except Exception as e: print(f"Error: {e}") print(traceback.format_exc()) time.sleep(5) finally: if 'client' in locals(): client.close() if __name__ == "__main__": main()