ReadCoilsInputsRequest.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. using System;
  2. using System.IO;
  3. using System.Net;
  4. namespace NModbus.Message
  5. {
  6. public class ReadCoilsInputsRequest : AbstractModbusMessage, IModbusRequest
  7. {
  8. public ReadCoilsInputsRequest()
  9. {
  10. }
  11. public ReadCoilsInputsRequest(byte functionCode, byte slaveAddress, ushort startAddress, ushort numberOfPoints)
  12. : base(slaveAddress, functionCode)
  13. {
  14. StartAddress = startAddress;
  15. NumberOfPoints = numberOfPoints;
  16. }
  17. public ushort StartAddress
  18. {
  19. get => MessageImpl.StartAddress.Value;
  20. set => MessageImpl.StartAddress = value;
  21. }
  22. public override int MinimumFrameSize => 6;
  23. public ushort NumberOfPoints
  24. {
  25. get => MessageImpl.NumberOfPoints.Value;
  26. set
  27. {
  28. if (value > Modbus.MaximumDiscreteRequestResponseSize)
  29. {
  30. string msg = $"Maximum amount of data {Modbus.MaximumDiscreteRequestResponseSize} coils.";
  31. throw new ArgumentOutOfRangeException(nameof(NumberOfPoints), msg);
  32. }
  33. MessageImpl.NumberOfPoints = value;
  34. }
  35. }
  36. public override string ToString()
  37. {
  38. string msg = $"Read {NumberOfPoints} {(FunctionCode == ModbusFunctionCodes.ReadCoils ? "coils" : "inputs")} starting at address {StartAddress}.";
  39. return msg;
  40. }
  41. public void ValidateResponse(IModbusMessage response)
  42. {
  43. var typedResponse = (ReadCoilsInputsResponse)response;
  44. // best effort validation - the same response for a request for 1 vs 6 coils (same byte count) will pass validation.
  45. var expectedByteCount = (NumberOfPoints + 7) / 8;
  46. if (expectedByteCount != typedResponse.ByteCount)
  47. {
  48. string msg = $"Unexpected byte count. Expected {expectedByteCount}, received {typedResponse.ByteCount}.";
  49. throw new IOException(msg);
  50. }
  51. }
  52. protected override void InitializeUnique(byte[] frame)
  53. {
  54. StartAddress = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(frame, 2));
  55. NumberOfPoints = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(frame, 4));
  56. }
  57. }
  58. }