using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Accessors; using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Replies; using static InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Constants; using static InnovEnergy.Lib.Protocols.Modbus.Protocol.FunctionCode; namespace InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Commands; using MbFc = MbByte; internal class ReadHoldingRegistersCommandFrame : ModbusFrame { internal const Int32 Size = 6; public MbAddress ReadAddress => Data.AddressAt(2); public MbWord NbToRead => Data.WordAt(4); public Int32 ExpectedResponseSize => ReadHoldingRegistersResponseFrame.ExpectedSize(NbToRead); public ReadHoldingRegistersCommandFrame(Byte slave, UInt16 readAddress, UInt16 nValues) : base(Size) { if (nValues > MaxRegs) throw new ArgumentOutOfRangeException($"Maximum number of registers ({MaxRegs}) exceeeded!", nameof(nValues)); SlaveAddress.Set(slave); FunctionCode.Set(ReadHoldingRegisters); ReadAddress .Set(readAddress); NbToRead .Set(nValues); } private ReadHoldingRegistersCommandFrame(ArraySegment data) : base(data) { if (data.Count != Size) throw new ArgumentException($"Expecting an array of size {Size}", nameof(data)); AssertFunctionCode(ReadHoldingRegisters); } public ReadHoldingRegistersResponseFrame VerifyResponse(ModbusFrame response) { if (response.SlaveAddress != SlaveAddress) throw new UnexpectedResponseFieldException(nameof(response.SlaveAddress), SlaveAddress.ToString(), response.SlaveAddress); var r = ReadHoldingRegistersResponseFrame.Parse(response.Data); if (r.RegistersRead.Count != NbToRead) throw new UnexpectedResponseFieldException(nameof(r.RegistersRead), NbToRead.ToString(), r.RegistersRead.Count); return r; } public static ReadHoldingRegistersCommandFrame Parse(ArraySegment data) { return new ReadHoldingRegistersCommandFrame(data); } }