using System;
using System.IO;
using System.Linq;
using System.Net;
using NModbus.Data;
using NModbus.Unme.Common;
namespace NModbus.Message
{
///
/// Write Multiple Coils request.
///
public class WriteMultipleCoilsRequest : AbstractModbusMessageWithData, IModbusRequest
{
///
/// Write Multiple Coils request.
///
public WriteMultipleCoilsRequest()
{
}
///
/// Write Multiple Coils request.
///
public WriteMultipleCoilsRequest(byte slaveAddress, ushort startAddress, DiscreteCollection data)
: base(slaveAddress, ModbusFunctionCodes.WriteMultipleCoils)
{
StartAddress = startAddress;
NumberOfPoints = (ushort)data.Count;
ByteCount = (byte)((data.Count + 7) / 8);
Data = data;
}
public byte ByteCount
{
get => MessageImpl.ByteCount!.Value;
set => MessageImpl.ByteCount = value;
}
public ushort NumberOfPoints
{
get => MessageImpl.NumberOfPoints!.Value;
set
{
if (value > Modbus.MaximumDiscreteRequestResponseSize)
{
string msg = $"Maximum amount of data {Modbus.MaximumDiscreteRequestResponseSize} coils.";
throw new ArgumentOutOfRangeException("NumberOfPoints", msg);
}
MessageImpl.NumberOfPoints = value;
}
}
public ushort StartAddress
{
get => MessageImpl.StartAddress!.Value;
set => MessageImpl.StartAddress = value;
}
public override int MinimumFrameSize => 7;
public override string ToString()
{
string msg = $"Write {NumberOfPoints} coils starting at address {StartAddress}.";
return msg;
}
public void ValidateResponse(IModbusMessage response)
{
var typedResponse = (WriteMultipleCoilsResponse)response;
if (StartAddress != typedResponse.StartAddress)
{
string msg = $"Unexpected start address in response. Expected {StartAddress}, received {typedResponse.StartAddress}.";
throw new IOException(msg);
}
if (NumberOfPoints != typedResponse.NumberOfPoints)
{
string msg = $"Unexpected number of points in response. Expected {NumberOfPoints}, received {typedResponse.NumberOfPoints}.";
throw new IOException(msg);
}
}
protected override void InitializeUnique(byte[] frame)
{
if (frame.Length < MinimumFrameSize + frame[6])
{
throw new FormatException("Message frame does not contain enough bytes.");
}
StartAddress = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(frame, 2));
NumberOfPoints = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(frame, 4));
ByteCount = frame[6];
Data = new DiscreteCollection(frame.Slice(7, ByteCount).ToArray());
}
}
}