Innovenergy_trunk/csharp/Lib/Protocols/Modbus/Clients/ModbusTcpClient.cs

172 lines
6.2 KiB
C#

using System.Diagnostics;
using InnovEnergy.Lib.Protocols.Modbus.Connections;
using InnovEnergy.Lib.Protocols.Modbus.Conversions;
using InnovEnergy.Lib.Protocols.Modbus.Protocol;
using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Commands;
using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Replies;
using InnovEnergy.Lib.Protocols.Modbus.Tcp;
using static InnovEnergy.Lib.Protocols.Modbus.Protocol.MultiRegisterEndianness;
namespace InnovEnergy.Lib.Protocols.Modbus.Clients;
using UInt16s = IReadOnlyList<UInt16>;
using Coils = IReadOnlyList<Boolean>;
public class ModbusTcpClient : ModbusClient
{
public const UInt16 DefaultPort = 502;
private UInt16 _Id;
[DebuggerStepThrough]
private UInt16 NextId() => unchecked(++_Id);
public ModbusTcpClient(ModbusConnection connection,
Byte slaveId,
RegisterIndexing registerIndexing = RegisterIndexing.OneBased,
MultiRegisterEndianness endianness = LittleEndian) : base(connection, slaveId, registerIndexing, endianness)
{
}
public override IReadOnlyList<Boolean> ReadDiscreteInputs(UInt16 readAddress, UInt16 nValues)
{
var wireReadAddress = LogicToWire(readAddress);
var id = NextId(); // TODO: check response id
var cmd = new ReadDiscreteInputsCommandFrame(SlaveId, wireReadAddress, nValues);
var hdr = new MbapHeader(id, cmd.Data.Count);
var frm = new ModbusTcpFrame(hdr, cmd);
Connection.Transmit(frm.Data);
var hData = Connection.Receive(MbapHeader.Size).ToArray(); // TODO: optimize .ToArray() ?
var rxHdr = new MbapHeader(hData);
var fData = Connection.Receive(rxHdr.FrameLength).ToArray(); // TODO: optimize .ToArray() ?
var rxFrm = ReadDiscreteInputResponseFrame.Parse(fData);
return cmd.VerifyResponse(rxFrm).Inputs;
}
public override ModbusRegisters ReadInputRegisters(UInt16 readAddress, UInt16 nValues)
{
var wireReadAddress = LogicToWire(readAddress);
var id = NextId(); // TODO: check response id
var cmd = new ReadInputRegistersCommandFrame(SlaveId, wireReadAddress, nValues);
var hdr = new MbapHeader(id, cmd.Data.Count);
var frm = new ModbusTcpFrame(hdr, cmd);
Connection.Transmit(frm.Data);
var hData = Connection.Receive(MbapHeader.Size).ToArray();
var rxHdr = new MbapHeader(hData);
var fData = Connection.Receive(rxHdr.FrameLength).ToArray();
var rxFrm = ReadInputRegistersResponseFrame.Parse(fData);
var verified = cmd.VerifyResponse(rxFrm);
return new ModbusRegisters(readAddress, verified.RegistersRead.ToArray());
}
public override ModbusRegisters ReadHoldingRegisters(UInt16 readAddress, UInt16 nValues)
{
var wireReadAddress = LogicToWire(readAddress);
var id = NextId(); // TODO: check response id
var cmd = new ReadHoldingRegistersCommandFrame(SlaveId, wireReadAddress, nValues);
var hdr = new MbapHeader(id, cmd.Data.Count);
var frm = new ModbusTcpFrame(hdr, cmd);
Connection.Transmit(frm.Data);
var hData = Connection.Receive(MbapHeader.Size).ToArray();
var rxHdr = new MbapHeader(hData);
var fData = Connection.Receive(rxHdr.FrameLength).ToArray();
var rxFrm = ReadHoldingRegistersResponseFrame.Parse(fData);
var verified = cmd.VerifyResponse(rxFrm);
return new ModbusRegisters(readAddress, verified.RegistersRead.ToArray()); // TODO
}
public override UInt16 WriteMultipleCoils(UInt16 writeAddress, Coils coils)
{
var wireWriteAddress = LogicToWire(writeAddress);
var id = NextId(); // TODO: check response id
var cmd = new WriteCoilsCommandFrame(SlaveId, wireWriteAddress, coils);
var hdr = new MbapHeader(id, cmd.Data.Count);
var frm = new ModbusTcpFrame(hdr, cmd);
Connection.Transmit(frm.Data);
var hData = Connection.Receive(MbapHeader.Size).ToArray();
var rxHdr = new MbapHeader(hData);
var fData = Connection.Receive(rxHdr.FrameLength).ToArray();
var rxFrm = WriteCoilsResponseFrame.Parse(fData);
return cmd.VerifyResponse(rxFrm).NbWritten;
}
public override UInt16 WriteRegisters(UInt16 writeAddress, UInt16s values)
{
var wireWriteAddress = LogicToWire(writeAddress);
var id = NextId(); // TODO: check response id
var cmd = new WriteRegistersCommandFrame(SlaveId, wireWriteAddress, values);
var hdr = new MbapHeader(id, cmd.Data.Count);
var frm = new ModbusTcpFrame(hdr, cmd);
Connection.Transmit(frm.Data);
var hData = Connection.Receive(MbapHeader.Size).ToArray();
var rxHdr = new MbapHeader(hData);
var fData = Connection.Receive(rxHdr.FrameLength).ToArray();
var rxFrm = WriteRegistersResponseFrame.Parse(fData);
var verified = cmd.VerifyResponse(rxFrm);
return verified.NbWritten;
}
public override ModbusRegisters ReadWriteRegisters(UInt16 readAddress, UInt16 nbToRead, UInt16 writeAddress, UInt16s registersToWrite)
{
var wireReadAddress = LogicToWire(readAddress);
var wireWriteAddress = LogicToWire(writeAddress);
var id = NextId(); // TODO: check response id
var cmd = new ReadWriteRegistersCommandFrame(SlaveId,
wireReadAddress,
nbToRead,
wireWriteAddress,
registersToWrite);
var hdr = new MbapHeader(id, cmd.Data.Count);
var frm = new ModbusTcpFrame(hdr, cmd);
Connection.Transmit(frm.Data);
var hData = Connection.Receive(MbapHeader.Size).ToArray();
var rxHdr = new MbapHeader(hData);
var fData = Connection.Receive(rxHdr.FrameLength).ToArray();
var rxFrm = ReadWriteRegistersResponseFrame.Parse(fData);
var verified = cmd.VerifyResponse(rxFrm);
return new ModbusRegisters(readAddress, verified.RegistersRead.ToArray()); // TODO
}
}