2023-02-16 12:57:06 +00:00
|
|
|
using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Accessors;
|
|
|
|
using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Replies;
|
|
|
|
using InnovEnergy.Lib.Utils;
|
|
|
|
using static InnovEnergy.Lib.Protocols.Modbus.Protocol.FunctionCode;
|
|
|
|
using static InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Constants;
|
|
|
|
|
|
|
|
|
|
|
|
namespace InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Commands;
|
|
|
|
|
2023-05-04 07:32:35 +00:00
|
|
|
using Booleans = IReadOnlyCollection<Boolean>;
|
2023-02-16 12:57:06 +00:00
|
|
|
using MbFc = MbByte<FunctionCode>;
|
|
|
|
|
|
|
|
public class WriteCoilsCommandFrame : ModbusFrame
|
|
|
|
{
|
|
|
|
private new const Int32 MinSize = 7;
|
|
|
|
|
2023-03-10 12:46:46 +00:00
|
|
|
private MbWord WriteAddress => Data.WordAt(2);
|
|
|
|
private MbWord NbOfCoils => Data.WordAt(4);
|
|
|
|
private MbByte ByteCount => Data.ByteAt(6);
|
2023-05-04 07:32:35 +00:00
|
|
|
private MbBits CoilsToWrite => Data.BitsAt(7);
|
2023-02-16 12:57:06 +00:00
|
|
|
|
|
|
|
public WriteCoilsCommandFrame(Byte slave, UInt16 writeAddress, Booleans coils) : base(MinSize + NbBytes(coils))
|
|
|
|
{
|
|
|
|
if (coils.Count > MaxCoils)
|
|
|
|
throw new ArgumentOutOfRangeException($"Maximum number of Coils to write ({MaxCoils}) exceeded!", nameof(coils));
|
|
|
|
|
|
|
|
SlaveAddress.Set(slave);
|
|
|
|
FunctionCode.Set(WriteMultipleCoils);
|
|
|
|
WriteAddress.Set(writeAddress);
|
|
|
|
NbOfCoils .Set(coils.Count);
|
|
|
|
ByteCount .Set(NbBytes(coils));
|
|
|
|
CoilsToWrite.Set(coils);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private WriteCoilsCommandFrame(ArraySegment<Byte> data) : base(data)
|
|
|
|
{
|
|
|
|
if (data.Count < MinSize)
|
|
|
|
throw new ArgumentOutOfRangeException($"Expecting an array of size {MinSize} or more!", nameof(data));
|
|
|
|
|
|
|
|
AssertFunctionCode(WriteMultipleCoils);
|
|
|
|
|
|
|
|
var expectedSize = ByteCount + MinSize;
|
|
|
|
if (data.Count != expectedSize)
|
|
|
|
throw new ArgumentException($"Expecting an array of size {expectedSize}", nameof(data));
|
|
|
|
|
|
|
|
if (ByteCount != CoilsToWrite.Count / 8)
|
|
|
|
throw new ArgumentException(nameof(CoilsToWrite));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public WriteCoilsResponseFrame VerifyResponse(WriteCoilsResponseFrame response)
|
|
|
|
{
|
|
|
|
if (response.SlaveAddress != SlaveAddress)
|
|
|
|
throw new UnexpectedResponseFieldException(nameof(response.SlaveAddress), SlaveAddress.ToString(), response.SlaveAddress);
|
|
|
|
|
|
|
|
if (response.NbWritten != NbOfCoils)
|
|
|
|
throw new UnexpectedResponseFieldException(nameof(response.NbWritten), NbOfCoils, response.NbWritten);
|
|
|
|
|
|
|
|
if (response.WriteAddress != WriteAddress)
|
|
|
|
throw new UnexpectedResponseFieldException(nameof(response.WriteAddress), WriteAddress, response.WriteAddress);
|
|
|
|
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static WriteCoilsCommandFrame Parse(ArraySegment<Byte> data)
|
|
|
|
{
|
|
|
|
return new WriteCoilsCommandFrame(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static Int32 NbBytes(Booleans coils)
|
|
|
|
{
|
|
|
|
return Math.Ceiling(coils.Count / 8.0).ConvertTo<Int32>();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|