import serial
from modbus_tk import modbus_rtu
from modbus_tk.defines import READ_HOLDING_REGISTERS
from time import sleep, time ,strftime ,localtime

def poll_modbus_channels():
    """Poll each Modbus channel 100 times to evaluate performance."""
    # Configurations for Modbus RTU
    config = {
        "baud": 9600,
        "COM": "/dev/ttyS0"
    }

    print(config)

    try:
        # Open the serial port
        serial_port = serial.Serial(
            port=config["COM"],
            baudrate=config["baud"],
            bytesize=8,
            parity='N',
            stopbits=1,
            timeout=0.5  # Timeout duration
        )

        # Initialize Modbus master
        master = modbus_rtu.RtuMaster(serial_port)
        master.set_timeout(0.5)  # Set Modbus timeout
        master.set_verbose(True)  # Enable detailed logs

        print("Starting Modbus channel polling...")
        # Correctly adjusting the time by 8 hours
        time_adjusted_correct = strftime("%Y-%m-%d %H:%M:%S", localtime(time() + 8*3600))
        print("执行时间 :" , time_adjusted_correct)

        # Iterate over Modbus ID range (1 to 247)
        for modbus_id in range(1, 2):
            if modbus_id in [] : continue
            success_count = 0
            failure_count = 0

            continue_failure_num =0 
            ts1 = time() 
            for attempt in range(10):
                try:
                    # Attempt to read holding register
                    response = master.execute(modbus_id, READ_HOLDING_REGISTERS, 6, 2)
                    success_count += 1
                    continue_failure_num =0 
                except Exception as e:
                    failure_count += 1
                    continue_failure_num +=1
                if continue_failure_num >= 50 :
                    break
            tsdiff = time() - ts1
            # Print summary after 100 attempts
            print(f"Modbus ID {modbus_id}: {success_count} 次成功, {failure_count} 次失败. 总耗时 {tsdiff}秒")

        print("Completed all channel polling.")

    except serial.SerialException as se:
        print(f"Serial port error: {se}")
    except Exception as e:
        print(f"Unexpected error: {e}")
    finally:
        if serial_port and serial_port.is_open:
            serial_port.close()
            print("Serial port closed.")

if __name__ == "__main__":
    poll_modbus_channels()
