using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;
using AMWD.Protocols.Modbus.Common.Contracts;
using AMWD.Protocols.Modbus.Common.Events;
using AMWD.Protocols.Modbus.Common.Models;
using AMWD.Protocols.Modbus.Common.Protocols;
namespace AMWD.Protocols.Modbus.Common.Utils
{
///
/// Implements a virtual Modbus client.
///
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public class VirtualModbusClient : ModbusClientBase
{
#region Constructor
///
/// Initializes a new instance of the class.
///
/// DO NOT MODIFY connection or protocol.
public VirtualModbusClient()
: base(new VirtualConnection())
{
Protocol = new VirtualProtocol();
TypedProtocol.CoilWritten += (sender, e) => CoilWritten?.Invoke(this, e);
TypedProtocol.RegisterWritten += (sender, e) => RegisterWritten?.Invoke(this, e);
}
#endregion Constructor
#region Events
///
/// Indicates that a -value received through a remote client has been written.
///
public event EventHandler CoilWritten;
///
/// Indicates that a -value received from a remote client has been written.
///
public event EventHandler RegisterWritten;
#endregion Events
#region Properties
internal VirtualProtocol TypedProtocol
=> Protocol as VirtualProtocol;
#endregion Properties
#region Device Handling
///
/// Adds a device to the virtual client.
///
/// The unit id of the device.
/// if the device was added successfully, otherwise.
public bool AddDevice(byte unitId)
=> TypedProtocol.AddDevice(unitId);
///
/// Removes a device from the virtual client.
///
/// The unit id of the device.
/// if the device was removed successfully, otherwise.
public bool RemoveDevice(byte unitId)
=> TypedProtocol.RemoveDevice(unitId);
#endregion Device Handling
#region Entity Handling
///
/// Gets a from the specified .
///
/// The unit ID of the device.
/// The address of the .
public Coil GetCoil(byte unitId, ushort address)
=> TypedProtocol.GetCoil(unitId, address);
///
/// Sets a to the specified .
///
/// The unit ID of the device.
/// The to set.
public void SetCoil(byte unitId, Coil coil)
=> TypedProtocol.SetCoil(unitId, coil);
///
/// Gets a from the specified .
///
/// The unit ID of the device.
/// The address of the .
public DiscreteInput GetDiscreteInput(byte unitId, ushort address)
=> TypedProtocol.GetDiscreteInput(unitId, address);
///
/// Sets a to the specified .
///
/// The unit ID of the device.
/// The to set.
public void SetDiscreteInput(byte unitId, DiscreteInput discreteInput)
=> TypedProtocol.SetDiscreteInput(unitId, discreteInput);
///
/// Gets a from the specified .
///
/// The unit ID of the device.
/// The address of the .
public HoldingRegister GetHoldingRegister(byte unitId, ushort address)
=> TypedProtocol.GetHoldingRegister(unitId, address);
///
/// Sets a to the specified .
///
/// The unit ID of the device.
/// The to set.
public void SetHoldingRegister(byte unitId, HoldingRegister holdingRegister)
=> TypedProtocol.SetHoldingRegister(unitId, holdingRegister);
///
/// Gets a from the specified .
///
/// The unit ID of the device.
/// The address of the .
public InputRegister GetInputRegister(byte unitId, ushort address)
=> TypedProtocol.GetInputRegister(unitId, address);
///
/// Sets a to the specified .
///
/// The unit ID of the device.
/// The to set.
public void SetInputRegister(byte unitId, InputRegister inputRegister)
=> TypedProtocol.SetInputRegister(unitId, inputRegister);
#endregion Entity Handling
#region Methods
///
protected override void Dispose(bool disposing)
{
TypedProtocol.Dispose();
base.Dispose(disposing);
}
#endregion Methods
#region Connection
internal class VirtualConnection : IModbusConnection
{
public string Name => nameof(VirtualConnection);
public TimeSpan IdleTimeout { get; set; }
public TimeSpan ConnectTimeout { get; set; }
public TimeSpan ReadTimeout { get; set; }
public TimeSpan WriteTimeout { get; set; }
public void Dispose()
{ /* nothing to do */ }
public Task> InvokeAsync(
IReadOnlyList request,
Func, bool> validateResponseComplete,
CancellationToken cancellationToken = default) => Task.FromResult(request);
}
#endregion Connection
}
}