ModbusSlaveNetwork.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6. using NModbus.Extensions;
  7. using NModbus.Logging;
  8. namespace NModbus.Device
  9. {
  10. public abstract class ModbusSlaveNetwork : ModbusDevice, IModbusSlaveNetwork
  11. {
  12. private readonly IModbusLogger _logger;
  13. private readonly IDictionary<byte, IModbusSlave> _slaves = new ConcurrentDictionary<byte, IModbusSlave>();
  14. protected ModbusSlaveNetwork(IModbusTransport transport, IModbusFactory modbusFactory, IModbusLogger logger)
  15. : base(transport)
  16. {
  17. ModbusFactory = modbusFactory;
  18. _logger = logger ?? throw new ArgumentNullException(nameof(logger));
  19. }
  20. protected IModbusFactory ModbusFactory { get; }
  21. protected IModbusLogger Logger
  22. {
  23. get { return _logger; }
  24. }
  25. /// <summary>
  26. /// Start slave listening for requests.
  27. /// </summary>
  28. public abstract Task ListenAsync(CancellationToken cancellationToken = new CancellationToken());
  29. /// <summary>
  30. /// Apply the request.
  31. /// </summary>
  32. /// <param name="request"></param>
  33. protected IModbusMessage ApplyRequest(IModbusMessage request)
  34. {
  35. //Check for broadcast requests
  36. if (request.SlaveAddress == 0)
  37. {
  38. //Grab each slave
  39. foreach (var slave in _slaves.Values)
  40. {
  41. try
  42. {
  43. //Apply the request
  44. slave.ApplyRequest(request);
  45. }
  46. catch (Exception ex)
  47. {
  48. Logger.Error($"Error applying request to slave {slave.UnitId}: {ex.Message}");
  49. }
  50. }
  51. }
  52. else
  53. {
  54. //Attempt to find a slave for this address
  55. IModbusSlave slave = GetSlave(request.SlaveAddress);
  56. // only service requests addressed to our slaves
  57. if (slave == null)
  58. {
  59. Console.WriteLine($"NModbus Slave Network ignoring request intended for NModbus Slave {request.SlaveAddress}");
  60. }
  61. else
  62. {
  63. // perform action
  64. return slave.ApplyRequest(request);
  65. }
  66. }
  67. return null;
  68. }
  69. public void AddSlave(IModbusSlave slave)
  70. {
  71. if (slave == null) throw new ArgumentNullException(nameof(slave));
  72. _slaves.Add(slave.UnitId, slave);
  73. Logger.Information($"Slave {slave.UnitId} added to slave network.");
  74. }
  75. public void RemoveSlave(byte unitId)
  76. {
  77. _slaves.Remove(unitId);
  78. Logger.Information($"Slave {unitId} removed from slave network.");
  79. }
  80. public IModbusSlave GetSlave(byte unitId)
  81. {
  82. return _slaves.GetValueOrDefault(unitId);
  83. }
  84. }
  85. }