using System; using System.Collections.Generic; using NModbus; namespace Samples { public class SlaveStorage : ISlaveDataStore { private readonly SparsePointSource _coilDiscretes; private readonly SparsePointSource _coilInputs; private readonly SparsePointSource _holdingRegisters; private readonly SparsePointSource _inputRegisters; public SlaveStorage() { _coilDiscretes = new SparsePointSource(); _coilInputs = new SparsePointSource(); _holdingRegisters = new SparsePointSource(); _inputRegisters = new SparsePointSource(); } public SparsePointSource CoilDiscretes { get { return _coilDiscretes; } } public SparsePointSource CoilInputs { get { return _coilInputs; } } public SparsePointSource HoldingRegisters { get { return _holdingRegisters; } } public SparsePointSource InputRegisters { get { return _inputRegisters; } } IPointSource ISlaveDataStore.CoilDiscretes { get { return _coilDiscretes; } } IPointSource ISlaveDataStore.CoilInputs { get { return _coilInputs; } } IPointSource ISlaveDataStore.HoldingRegisters { get { return _holdingRegisters; } } IPointSource ISlaveDataStore.InputRegisters { get { return _inputRegisters; } } } /// /// Sparse storage for points. /// public class SparsePointSource : IPointSource { private readonly Dictionary _values = new Dictionary(); public event EventHandler> StorageOperationOccurred; /// /// Gets or sets the value of an individual point wih tout /// /// /// public TPoint this[ushort registerIndex] { get { TPoint value; if (_values.TryGetValue(registerIndex, out value)) return value; return default(TPoint); } set { _values[registerIndex] = value; } } public TPoint[] ReadPoints(ushort startAddress, ushort numberOfPoints) { var points = new TPoint[numberOfPoints]; for (ushort index = 0; index < numberOfPoints; index++) { points[index] = this[(ushort) (index + startAddress)]; } StorageOperationOccurred?.Invoke(this, new StorageEventArgs(PointOperation.Read, startAddress, points)); return points; } public void WritePoints(ushort startAddress, TPoint[] points) { for (ushort index = 0; index < points.Length; index++) { this[(ushort) (index + startAddress)] = points[index]; } StorageOperationOccurred?.Invoke(this, new StorageEventArgs(PointOperation.Write, startAddress, points)); } } public class StorageEventArgs : EventArgs { private readonly PointOperation _pointOperation; private readonly ushort _startingAddress; private readonly TPoint[] _points; public StorageEventArgs(PointOperation pointOperation, ushort startingAddress, TPoint[] points) { _pointOperation = pointOperation; _startingAddress = startingAddress; _points = points; } public ushort StartingAddress { get { return _startingAddress; } } public TPoint[] Points { get { return _points; } } public PointOperation Operation { get { return _pointOperation; } } } public enum PointOperation { Read, Write } }