using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Accessors; using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Replies; using static InnovEnergy.Lib.Protocols.Modbus.Protocol.FunctionCode; namespace InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Commands; using UInt16s = IReadOnlyCollection; using MbFc = MbByte; internal class WriteRegistersCommandFrame : ModbusFrame { internal new const Int32 MinSize = 7; public MbWord WriteAddress => Data.WordAt(2); public MbWord NbOfRegisters => Data.WordAt(4); public MbByte ByteCount => Data.ByteAt(6); public MbWords RegistersToWrite => Data.WordsAt(7); public Int32 ExpectedResponseSize => WriteRegistersResponseFrame.ExpectedSize(); public WriteRegistersCommandFrame(Byte slave, UInt16 writeAddress, UInt16s registersToWrite) : base(MinSize + registersToWrite.Count * 2) { var n = registersToWrite.Count; SlaveAddress .Set(slave); FunctionCode .Set(WriteMultipleRegisters); WriteAddress .Set(writeAddress); NbOfRegisters .Set(n); ByteCount .Set(2 * n); RegistersToWrite.Set(registersToWrite); } private WriteRegistersCommandFrame(ArraySegment data) : base(data) { if (data.Count < MinSize) throw new ArgumentOutOfRangeException($"Expecting an array of size {MinSize} or more!", nameof(data)); AssertFunctionCode(WriteMultipleRegisters); var expectedSize = ByteCount + MinSize; if (data.Count != expectedSize) throw new ArgumentException($"Expecting an array of size {expectedSize}", nameof(data)); if (ByteCount != RegistersToWrite.Count * 2) throw new ArgumentException(nameof(RegistersToWrite)); } public WriteRegistersResponseFrame VerifyResponse(WriteRegistersResponseFrame response) { if (response.SlaveAddress != SlaveAddress) throw new UnexpectedResponseFieldException(nameof(response.SlaveAddress), SlaveAddress.ToString(), response.SlaveAddress); if (response.NbWritten != NbOfRegisters) throw new UnexpectedResponseFieldException(nameof(response.NbWritten), NbOfRegisters, response.NbWritten); if (response.WriteAddress != WriteAddress) throw new UnexpectedResponseFieldException(nameof(response.WriteAddress), WriteAddress, response.WriteAddress); return response; } public static WriteRegistersCommandFrame Parse(ArraySegment data) { return new WriteRegistersCommandFrame(data); } }