from pymodbus.client import ModbusSerialClient

class Modbus:
    def __init__(self, port='/dev/ttySC0', baudrate=38400, bytesize=8, parity='E', stopbits=1):
        self.client = ModbusSerialClient(
            method='rtu',
            port=port,
            baudrate=baudrate,
            bytesize=bytesize,
            parity=parity,
            stopbits=stopbits
        )

    def connect(self):
        return self.client.connect()

    def close(self):
        self.client.close()

    # FC1: Read Coil Status
    def read_coil(self, address, quantity, slave_id):
        result = self.client.read_coils(address, quantity, slave_id)

        if not result.isError():
            print(f"Successfully FC1 read coils: {result.bits}")
        else:
            print(f"Failed FC1 to read coils from address {address}")

    # FC2: Read Discrete Inputs
    def read_discrete_input(self, address, quantity, slave_id):
        result = self.client.read_discrete_inputs(address, quantity, slave_id)

        if not result.isError():
            print(f"Successfully FC2 read discrete inputs: {result.bits}")
        else:
            print(f"Failed FC3 to read discrete inputs from address {address}")

    # FC3: Read Holding Registers
    def read_holding_register(self, address, quantity, slave_id):
        result = self.client.read_holding_registers(address, quantity, slave_id)

        if not result.isError():
            print(f"Successfully FC3 read: {result.registers}")
        else:
            print(f"Failed FC3 to read from address {address}")

    # FC4: Read Input Registers
    def read_input_register(self, address, quantity, slave_id):
        result = self.client.read_input_registers(address, quantity, slave_id)

        if not result.isError():
            print(f"Successfully FC2 read discrete inputs: {result.registers}")
        else:
            print(f"Failed FC3 to read discrete inputs from address {address}")

    # FC5: Write Single Coil
    def write_coil(self, address, value, slave_id):
        result = self.client.write_coil(address, value, slave_id)

        if not result.isError():
            print(f"Successfully FC5 wrote value {value} to coil address {address}")
        else:
            print(f"Failed FC5 to write value to coil address {address}")

    # FC6: Write Single Register
    def write_register(self, address, value, slave_id):
        result = self.client.write_register(address, value, slave_id)

        if not result.isError():
            print(f"Successfully FC6 wrote value {value} to coil address {address}")
        else:
            print(f"Failed FC6 to write value to coil address {address}")

    # FC15: Write Multiple
    def write_multiple_coils(self, address, value, slave_id):
        result = self.client.write_coils(address, value, slave_id)

        if not result.isError():
            print(f"Successfully FC15 wrote value {value} to coil address {address}")
        else:
            print(f"Failed FC15 to write value to coil address {address}")

    # FC16: Write Multiple Registers
    def write_multiple_registers(self, address, value, slave_id):
        result = self.client.write_registers(address, value, slave_id)

        if not result.isError():
            print(f"Successfully FC16 wrote value {value} to coil address {address}")
        else:
            print(f"Failed FC16 to write value to coil address {address}")
