using Modbus.Device;
using System.Net.Sockets;

namespace ModbusReadRegisters
{
    internal class Program
    {
        private const string IpAddress = "127.0.0.1"; // Replace with your Modbus device IP
        private const int Port = 502; // Default Modbus TCP port
        private const byte SlaveId = 1; // Modbus slave ID
        private const ushort StartAddress = 0; // Starting address to read
        private const ushort NumRegisters = 16; // Number of registers to read
        private const ushort CoilStartAddress = 0; // Starting address to write coils

        private static void Main(string[] args)
        {
            try
            {
                using (TcpClient client = new TcpClient(IpAddress, Port))
                {
                    // Build a client, read registers, write to coils
                    ModbusIpMaster master = ModbusIpMaster.CreateIp(client);
                    ushort[] registers = ReadHoldingRegisters(master, SlaveId, StartAddress, NumRegisters);
                    DisplayRegisters(registers, StartAddress);
                    WriteCoilsBasedOnRegisters(master, registers, CoilStartAddress);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("An error occurred: " + ex.Message);
            }
        }

        // Fetch holding register values with modbus TCP
        private static ushort[] ReadHoldingRegisters(ModbusIpMaster master, byte slaveId, ushort startAddress, ushort numRegisters)
        {
            return master.ReadHoldingRegisters(slaveId, startAddress, numRegisters);
        }

        // Print registers we found and their values
        private static void DisplayRegisters(ushort[] registers, ushort startAddress)
        {
            Console.WriteLine($"Read {registers.Length} registers starting at address {startAddress}:");
            for (int i = 0; i < registers.Length; i++)
            {
                Console.WriteLine($"Register {startAddress + i}: {registers[i]}");
            }
        }

        // If a register is occupied, write 1 to coil
        private static void WriteCoilsBasedOnRegisters(ModbusIpMaster master, ushort[] registers, ushort coilStartAddress)
        {
            for (int i = 0; i < registers.Length; i++)
            {
                bool coilValue = registers[i] > 0;
                master.WriteSingleCoil((ushort)(coilStartAddress + i), coilValue);
                Console.WriteLine($"Wrote {(coilValue ? 1 : 0)} to coil address {coilStartAddress + i}");
            }
        }
    }
}