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; using MbFc = MbByte; internal class ReadDiscreteInputsCommandFrame : ModbusFrame { private const Int32 Size = 6; private MbAddress ReadAddress => Data.AddressAt(2); private MbWord QuantityOfInputs => Data.WordAt(4); public ReadDiscreteInputsCommandFrame(Byte slave, UInt16 readAddress, UInt16 nBits) : base(Size) { if (nBits > MaxDiscreteInputs) throw new ArgumentOutOfRangeException($"Maximum number of registers ({MaxDiscreteInputs}) exceeeded!", nameof(nBits)); SlaveAddress .Set(slave); FunctionCode .Set(ReadDiscreteInputs); ReadAddress .Set(readAddress); QuantityOfInputs.Set(nBits); } private ReadDiscreteInputsCommandFrame(ArraySegment data) : base(data) { if (data.Count != Size) throw new ArgumentException($"Expecting an array of size {Size}", nameof(data)); AssertFunctionCode(ReadDiscreteInputs); } public ReadDiscreteInputResponseFrame VerifyResponse(ReadDiscreteInputResponseFrame 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 ReadDiscreteInputsCommandFrame Parse(ArraySegment data) { return new ReadDiscreteInputsCommandFrame(data); } }