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

187 lines
6.4 KiB
C#
Raw Normal View History

2023-02-16 12:57:06 +00:00
using System.Diagnostics;
2023-05-04 07:32:35 +00:00
using InnovEnergy.Lib.Protocols.Modbus.Channels;
using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Accessors;
2023-02-16 12:57:06 +00:00
using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Commands;
using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Replies;
using InnovEnergy.Lib.Protocols.Modbus.Tcp;
using InnovEnergy.Lib.Utils;
2023-02-16 12:57:06 +00:00
namespace InnovEnergy.Lib.Protocols.Modbus.Clients;
2023-05-04 07:32:35 +00:00
using UInt16s = IReadOnlyCollection<UInt16>;
using Booleans = IReadOnlyCollection<Boolean>;
2023-02-16 12:57:06 +00:00
public class ModbusTcpClient : ModbusClient
{
public const UInt16 DefaultPort = 502;
private UInt16 _Id;
[DebuggerStepThrough]
private UInt16 NextId() => unchecked(++_Id);
2023-05-04 07:32:35 +00:00
public ModbusTcpClient(Channel channel, Byte slaveId) : base(channel, slaveId)
2023-02-16 12:57:06 +00:00
{
}
2023-05-04 07:32:35 +00:00
public override MbData ReadCoils(UInt16 readAddress, UInt16 nValues)
{
var id = NextId(); // TODO: check response id
var cmd = new ReadCoilsCommandFrame(SlaveId, readAddress, nValues);
var hdr = new MbapHeader(id, cmd.Data.Count);
var frm = new ModbusTcpFrame(hdr, cmd);
2023-05-04 07:32:35 +00:00
Channel.Write(frm.Data);
2023-05-04 07:32:35 +00:00
var hData = Channel.Read(MbapHeader.Size).ToArray();
var rxHdr = new MbapHeader(hData);
2023-05-04 07:32:35 +00:00
var rxFrm = Channel
.Read(rxHdr.FrameLength)
.ToArray() // TODO: optimize .ToArray() ?
.Apply(ReadCoilsResponseFrame.Parse)
.Apply(cmd.VerifyResponse);
return new MbData(rxFrm.Coils.RawData, readAddress, Endian);
}
2023-05-04 07:32:35 +00:00
public override MbData ReadDiscreteInputs(UInt16 readAddress, UInt16 nValues)
2023-02-16 12:57:06 +00:00
{
var id = NextId(); // TODO: check response id
var cmd = new ReadDiscreteInputsCommandFrame(SlaveId, readAddress, nValues);
2023-02-16 12:57:06 +00:00
var hdr = new MbapHeader(id, cmd.Data.Count);
var frm = new ModbusTcpFrame(hdr, cmd);
2023-05-04 07:32:35 +00:00
Channel.Write(frm.Data);
2023-02-16 12:57:06 +00:00
2023-05-04 07:32:35 +00:00
var hData = Channel.Read(MbapHeader.Size).ToArray(); // TODO: optimize .ToArray() ?
2023-02-16 12:57:06 +00:00
var rxHdr = new MbapHeader(hData);
2023-05-04 07:32:35 +00:00
var rxFrm = Channel
.Read(rxHdr.FrameLength)
.ToArray() // TODO: optimize .ToArray() ?
.Apply(ReadDiscreteInputsResponseFrame.Parse)
.Apply(cmd.VerifyResponse);
return new MbData(rxFrm.Inputs.RawData, readAddress, Endian);
2023-02-16 12:57:06 +00:00
}
2023-05-04 07:32:35 +00:00
public override MbData ReadInputRegisters(UInt16 readAddress, UInt16 nValues)
2023-02-16 12:57:06 +00:00
{
var id = NextId(); // TODO: check response id
var cmd = new ReadInputRegistersCommandFrame(SlaveId, readAddress, nValues);
2023-02-16 12:57:06 +00:00
var hdr = new MbapHeader(id, cmd.Data.Count);
var frm = new ModbusTcpFrame(hdr, cmd);
2023-05-04 07:32:35 +00:00
Channel.Write(frm.Data);
2023-02-16 12:57:06 +00:00
2023-05-04 07:32:35 +00:00
var hData = Channel.Read(MbapHeader.Size).ToArray();
2023-02-16 12:57:06 +00:00
var rxHdr = new MbapHeader(hData);
2023-05-04 07:32:35 +00:00
var rxFrm = Channel
.Read(rxHdr.FrameLength)
.ToArray()
.Apply(ReadInputRegistersResponseFrame.Parse)
.Apply(cmd.VerifyResponse);
2023-02-16 12:57:06 +00:00
2023-05-04 07:32:35 +00:00
return new MbData(rxFrm.RegistersRead.RawData, readAddress, Endian);
2023-02-16 12:57:06 +00:00
}
2023-05-04 07:32:35 +00:00
public override MbData ReadHoldingRegisters(UInt16 readAddress, UInt16 nValues)
2023-02-16 12:57:06 +00:00
{
var id = NextId(); // TODO: check response id
2023-05-04 07:32:35 +00:00
var cmd = new ReadHoldingRegistersCommandFrame(SlaveId, readAddress, nValues);
2023-02-16 12:57:06 +00:00
var hdr = new MbapHeader(id, cmd.Data.Count);
var frm = new ModbusTcpFrame(hdr, cmd);
2023-05-04 07:32:35 +00:00
Channel.Write(frm.Data);
2023-02-16 12:57:06 +00:00
2023-05-04 07:32:35 +00:00
var hData = Channel.Read(MbapHeader.Size).ToArray();
2023-02-16 12:57:06 +00:00
var rxHdr = new MbapHeader(hData);
2023-05-04 07:32:35 +00:00
var rxFrm = Channel
.Read(rxHdr.FrameLength)
.ToArray()
.Apply(ReadHoldingRegistersResponseFrame.Parse)
.Apply(cmd.VerifyResponse);
2023-02-16 12:57:06 +00:00
2023-05-04 07:32:35 +00:00
return new MbData(rxFrm.RegistersRead.RawData, readAddress, Endian);
2023-02-16 12:57:06 +00:00
}
2023-05-04 07:32:35 +00:00
public override UInt16 WriteCoils(UInt16 writeAddress, Booleans coils)
2023-02-16 12:57:06 +00:00
{
var id = NextId(); // TODO: check response id
var cmd = new WriteCoilsCommandFrame(SlaveId, writeAddress, coils);
2023-02-16 12:57:06 +00:00
var hdr = new MbapHeader(id, cmd.Data.Count);
var frm = new ModbusTcpFrame(hdr, cmd);
2023-05-04 07:32:35 +00:00
Channel.Write(frm.Data);
2023-02-16 12:57:06 +00:00
2023-05-04 07:32:35 +00:00
var hData = Channel.Read(MbapHeader.Size).ToArray();
2023-02-16 12:57:06 +00:00
var rxHdr = new MbapHeader(hData);
2023-05-04 07:32:35 +00:00
var rxFrm = Channel
.Read(rxHdr.FrameLength)
.ToArray()
.Apply(WriteCoilsResponseFrame.Parse)
.Apply(cmd.VerifyResponse);
2023-02-16 12:57:06 +00:00
2023-05-04 07:32:35 +00:00
return rxFrm.NbWritten;
2023-02-16 12:57:06 +00:00
}
2023-02-16 12:57:06 +00:00
public override UInt16 WriteRegisters(UInt16 writeAddress, UInt16s values)
{
var id = NextId(); // TODO: check response id
var cmd = new WriteRegistersCommandFrame(SlaveId, writeAddress, values);
2023-02-16 12:57:06 +00:00
var hdr = new MbapHeader(id, cmd.Data.Count);
var frm = new ModbusTcpFrame(hdr, cmd);
2023-05-04 07:32:35 +00:00
Channel.Write(frm.Data);
2023-02-16 12:57:06 +00:00
2023-05-04 07:32:35 +00:00
var hData = Channel.Read(MbapHeader.Size).ToArray();
2023-02-16 12:57:06 +00:00
var rxHdr = new MbapHeader(hData);
2023-05-04 07:32:35 +00:00
var rxFrm = Channel
.Read(rxHdr.FrameLength)
.ToArray()
.Apply(WriteRegistersResponseFrame.Parse)
.Apply(cmd.VerifyResponse);
2023-02-16 12:57:06 +00:00
2023-05-04 07:32:35 +00:00
return rxFrm.NbWritten;
2023-02-16 12:57:06 +00:00
}
2023-05-04 07:32:35 +00:00
public override MbData ReadWriteRegisters(UInt16 readAddress, UInt16 nbToRead, UInt16 writeAddress, UInt16s registersToWrite)
2023-02-16 12:57:06 +00:00
{
var id = NextId(); // TODO: check response id
var cmd = new ReadWriteRegistersCommandFrame(SlaveId,
readAddress,
nbToRead,
writeAddress,
registersToWrite);
2023-02-16 12:57:06 +00:00
var hdr = new MbapHeader(id, cmd.Data.Count);
var frm = new ModbusTcpFrame(hdr, cmd);
2023-05-04 07:32:35 +00:00
Channel.Write(frm.Data);
2023-02-16 12:57:06 +00:00
2023-05-04 07:32:35 +00:00
var hData = Enumerable.ToArray(Channel.Read(MbapHeader.Size));
2023-02-16 12:57:06 +00:00
var rxHdr = new MbapHeader(hData);
2023-05-04 07:32:35 +00:00
var fData = Enumerable.ToArray(Channel.Read(rxHdr.FrameLength));
var rxFrm = fData
.Apply(ReadWriteRegistersResponseFrame.Parse)
.Apply(cmd.VerifyResponse);
2023-02-16 12:57:06 +00:00
2023-05-04 07:32:35 +00:00
return new MbData(rxFrm.RegistersRead.RawData, readAddress, Endian);
2023-02-16 12:57:06 +00:00
}
}