using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Accessors; using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Replies; using InnovEnergy.Lib.Utils; namespace InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Commands; internal class ReadCoilsCommandFrame : ModbusFrame { private const Int32 Size = 6; private MbWord ReadAddress => Data.WordAt(2); private MbWord QuantityOfInputs => Data.WordAt(4); public ReadCoilsCommandFrame(Byte slave, UInt16 readAddress, UInt16 nBits) : base(Size) { if (nBits > Constants.MaxCoils) throw new ArgumentOutOfRangeException($"Maximum number of registers ({Constants.MaxCoils}) exceeeded!", nameof(nBits)); SlaveAddress .Set(slave); FunctionCode .Set(Protocol.FunctionCode.ReadCoils); ReadAddress .Set(readAddress); QuantityOfInputs.Set(nBits); } private ReadCoilsCommandFrame(ArraySegment data) : base(data) { if (data.Count != Size) throw new ArgumentException($"Expecting an array of size {Size}", nameof(data)); AssertFunctionCode(Protocol.FunctionCode.ReadCoils); } public ReadCoilsResponseFrame VerifyResponse(ReadCoilsResponseFrame response) { if (response.SlaveAddress != SlaveAddress) throw new UnexpectedResponseFieldException(nameof(response.SlaveAddress), SlaveAddress.ToString(), response.SlaveAddress); if (response.Inputs.Count != Math.Ceiling(QuantityOfInputs / 8.0).ConvertTo() * 8) throw new UnexpectedResponseFieldException(nameof(response.Inputs), QuantityOfInputs.ToString(), response.Inputs.Count); return response; } public static ReadCoilsCommandFrame Parse(ArraySegment data) { return new ReadCoilsCommandFrame(data); } }