SiemensS7Plc.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. using System;
  2. using System.ComponentModel;
  3. using System.Threading.Tasks;
  4. using HslCommunication.Profinet.Siemens;
  5. using Newtonsoft.Json;
  6. using TeamAAS.Communication.Attributes;
  7. using TeamAAS.Communication.Base;
  8. namespace TeamAAS.Communication.PLCs
  9. {
  10. [Communication("西门子 S7", "PLC", "HslCommunication SiemensS7Net")]
  11. public class SiemensS7Plc : PlcCommunicationBase
  12. {
  13. [JsonIgnore] private SiemensS7Net _s7;
  14. [JsonIgnore] private bool _connected;
  15. public override string PlcVendor => "西门子 S7";
  16. private string _ipAddress = "127.0.0.1";
  17. [Category("II.连接配置"), DisplayName("IP 地址"), Description("PLC IP 地址")]
  18. public string IpAddress
  19. {
  20. get { return _ipAddress; }
  21. set { if (SetProperty(ref _ipAddress, value)) Notify(nameof(EndpointUrl)); }
  22. }
  23. private int _port = 102;
  24. [Category("II.连接配置"), DisplayName("端口"), Description("PLC 端口(默认 102)")]
  25. public int Port
  26. {
  27. get { return _port; }
  28. set { if (SetProperty(ref _port, value)) Notify(nameof(EndpointUrl)); }
  29. }
  30. private SiemensPLCS _plcType = SiemensPLCS.S1200;
  31. [Category("III.PLC 配置"), DisplayName("CPU 型号"), Description("西门子 S7 CPU 型号")]
  32. public SiemensPLCS PlcType
  33. {
  34. get { return _plcType; }
  35. set { SetProperty(ref _plcType, value); }
  36. }
  37. public override string EndpointUrl
  38. {
  39. get { return $"tcp://{IpAddress}:{Port}"; }
  40. set
  41. {
  42. if (!string.IsNullOrWhiteSpace(value) && value.StartsWith("tcp://"))
  43. {
  44. var uri = new Uri(value);
  45. IpAddress = uri.Host;
  46. Port = uri.Port;
  47. }
  48. }
  49. }
  50. [JsonIgnore, Browsable(false)]
  51. public override bool IsConnected => _connected;
  52. public override event Action<object, bool> ConnectChangedEvent;
  53. public override event Action<object, string> DataReceivedEvent;
  54. public SiemensS7Plc() { }
  55. public override void Connect()
  56. {
  57. if (string.IsNullOrWhiteSpace(IpAddress))
  58. throw new InvalidOperationException("西门子 PLC IP 不能为空。");
  59. if (Port <= 0)
  60. throw new InvalidOperationException("西门子 PLC 端口必须大于 0。");
  61. Disconnect();
  62. _s7 = new SiemensS7Net(PlcType, IpAddress) { Port = Port, ConnectTimeOut = 2000 };
  63. var result = _s7.ConnectServer();
  64. if (!result.IsSuccess)
  65. {
  66. _s7 = null;
  67. throw new InvalidOperationException("西门子 PLC 连接失败: " + result.Message);
  68. }
  69. Driver = _s7;
  70. _connected = true;
  71. ConnectChangedEvent?.Invoke(this, true);
  72. Notify(nameof(IsConnected));
  73. }
  74. public override Task ConnectAsync() => Task.Run(() => Connect());
  75. public override void Disconnect()
  76. {
  77. _connected = false;
  78. Driver = null;
  79. if (_s7 != null)
  80. {
  81. try { _s7.ConnectClose(); } catch { }
  82. _s7 = null;
  83. }
  84. ConnectChangedEvent?.Invoke(this, false);
  85. Notify(nameof(IsConnected));
  86. }
  87. public override void Dispose() => Disconnect();
  88. }
  89. }