Change1
This commit is contained in:
		
							
								
								
									
										22
									
								
								src/XKRS.Device.MelsecPLC/App.config
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/XKRS.Device.MelsecPLC/App.config
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<configuration>
 | 
			
		||||
    <startup> 
 | 
			
		||||
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
 | 
			
		||||
    </startup>
 | 
			
		||||
  <runtime>
 | 
			
		||||
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
 | 
			
		||||
      <dependentAssembly>
 | 
			
		||||
        <assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
 | 
			
		||||
        <bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
 | 
			
		||||
      </dependentAssembly>
 | 
			
		||||
      <dependentAssembly>
 | 
			
		||||
        <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
 | 
			
		||||
        <bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
 | 
			
		||||
      </dependentAssembly>
 | 
			
		||||
      <dependentAssembly>
 | 
			
		||||
        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
 | 
			
		||||
        <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
 | 
			
		||||
      </dependentAssembly>
 | 
			
		||||
    </assemblyBinding>
 | 
			
		||||
  </runtime>
 | 
			
		||||
</configuration>
 | 
			
		||||
							
								
								
									
										70
									
								
								src/XKRS.Device.MelsecPLC/MelsecPLCConfig.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/XKRS.Device.MelsecPLC/MelsecPLCConfig.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using BRS.Common.Base;
 | 
			
		||||
using BRS.Common.Interface;
 | 
			
		||||
using BRS.Common.Model.Helper;
 | 
			
		||||
using BRS.UI.Device.Winform;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.ComponentModel;
 | 
			
		||||
 | 
			
		||||
namespace XKRS.Device.MelsecPLC
 | 
			
		||||
{
 | 
			
		||||
    [Device("MelsecPLC", "三菱PLC", EnumHelper.DeviceAttributeType.OperationConfig)]
 | 
			
		||||
    public class MelsecPLCOperationConfig : PLCOperationConfigBase
 | 
			
		||||
    {
 | 
			
		||||
        public int StartAddress { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int OpLength { get; set; }
 | 
			
		||||
 | 
			
		||||
        public List<int> OpValues { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Device("MelsecPLC", "三菱PLC", EnumHelper.DeviceAttributeType.InitialConfig)]
 | 
			
		||||
    public class MelsecPLCInitialConfig : PLCInitialConfigBase
 | 
			
		||||
    {
 | 
			
		||||
        [Category("PLC设置")]
 | 
			
		||||
        [Description("PLCIP地址")]
 | 
			
		||||
        [DisplayName("PLC IP")]
 | 
			
		||||
        public string PLCIpAddress { get; set; }
 | 
			
		||||
 | 
			
		||||
        [Category("PLC设置")]
 | 
			
		||||
        [Description("PLC端口号")]
 | 
			
		||||
        [DisplayName("PLC端口")]
 | 
			
		||||
        [DefaultValue(502)]
 | 
			
		||||
        public int PLCPort { get; set; } = 502;
 | 
			
		||||
 | 
			
		||||
        [Category("PLC设置")]
 | 
			
		||||
        [Description("PLC单元号")]
 | 
			
		||||
        [DisplayName("PLC单元号")]
 | 
			
		||||
        public int PLCUnitNum { get; set; } = 0;
 | 
			
		||||
 | 
			
		||||
        [Category("PLC设置")]
 | 
			
		||||
        [Description("本机网络号")]
 | 
			
		||||
        [DisplayName("本机网络号")]
 | 
			
		||||
        public int PCNetNum { get; set; } = 0;
 | 
			
		||||
 | 
			
		||||
        [Category("PLC设置")]
 | 
			
		||||
        [Description("PLC心跳地址")]
 | 
			
		||||
        [DisplayName("PLC心跳地址")]
 | 
			
		||||
        public string HeartbeatAddress { get; set; }
 | 
			
		||||
 | 
			
		||||
        [Category("PLC设置")]
 | 
			
		||||
        [Description("PLC心跳间隔")]
 | 
			
		||||
        [DisplayName("PLC心跳间隔")]
 | 
			
		||||
        public int HeartbeatCycle { get; set; } = 0;
 | 
			
		||||
 | 
			
		||||
        //[Category("PLC设置")]
 | 
			
		||||
        //[Description("PLC单元号")]
 | 
			
		||||
        //[DisplayName("断线后是否更换PLC单元号的值")]
 | 
			
		||||
        //public bool IsChangeSA1AfterReadFailed { get; set; } = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Device("MelsecPLC", "三菱PLC", EnumHelper.DeviceAttributeType.RunCtrl)]
 | 
			
		||||
    public class OmronPLCRunCtrl : CtrlPLCRunBase
 | 
			
		||||
    {
 | 
			
		||||
        public OmronPLCRunCtrl(IDevice device) : base(device) { }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										424
									
								
								src/XKRS.Device.MelsecPLC/MelsecPLCDriver.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										424
									
								
								src/XKRS.Device.MelsecPLC/MelsecPLCDriver.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,424 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using BRS.Common.Base;
 | 
			
		||||
using BRS.Common.Model;
 | 
			
		||||
using BRS.Common.Model.Helper;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using HslCommunication;
 | 
			
		||||
using HslCommunication.Profinet.Melsec;
 | 
			
		||||
using static BRS.Common.Model.Helper.EnumHelper;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
namespace XKRS.Device.MelsecPLC
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    [Device("MelsecPLC", "三菱PLC", DeviceAttributeType.Device)]
 | 
			
		||||
    public class MelsecPLCDriver : PLCBase
 | 
			
		||||
    {
 | 
			
		||||
        public MelsecPLCInitialConfig IIConfig
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return InitialConfig as MelsecPLCInitialConfig;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        private MelsecMcNet melsecMc = new MelsecMcNet();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        #region PLCBase
 | 
			
		||||
        public override List<int> Read(string startAddress, int length)
 | 
			
		||||
        {
 | 
			
		||||
            PLCItem item = new PLCItem();
 | 
			
		||||
            item.Address = startAddress;
 | 
			
		||||
            item.ItemLength = length;
 | 
			
		||||
 | 
			
		||||
            ReadItem(item);
 | 
			
		||||
            //List<int> valueList = new List<int>();
 | 
			
		||||
            //if (!string.IsNullOrWhiteSpace(item.ItemValue))
 | 
			
		||||
            //{
 | 
			
		||||
            //    valueList = item.ItemValue.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList().ConvertAll(s => int.Parse(s)).ToList();
 | 
			
		||||
            //}
 | 
			
		||||
            return item.ItemValues;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void ReadItem(PLCItem item)
 | 
			
		||||
        {
 | 
			
		||||
            item.PLCOpType = PLCOpType.Read;
 | 
			
		||||
            item.ItemValues.Clear();
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                // 读取Int变量
 | 
			
		||||
                var result = melsecMc.ReadInt32(item.Address, (ushort)item.ItemLength);
 | 
			
		||||
                if (result.IsSuccess)
 | 
			
		||||
                {
 | 
			
		||||
                    for (int i = 0; i < result.Content.Length; i++)
 | 
			
		||||
                    {
 | 
			
		||||
                        item.ItemValues.Add(result.Content[i]);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:" + item.Address + ";长度:" + item.ItemLength + ";提示:" + result.Message);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}读取异常:" + ex.GetExceptionMessage());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public override int ReadInt(string address)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                // 读取Int变量
 | 
			
		||||
                var result = melsecMc.ReadInt32(address);
 | 
			
		||||
                if (result.IsSuccess)
 | 
			
		||||
                {
 | 
			
		||||
                    return result.Content;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:" + address + ";提示:" + result.Message);
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}读取异常:" + ex.GetExceptionMessage());
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        public override string ReadString(string address, ushort length)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                // 读取String变量
 | 
			
		||||
                var result = melsecMc.ReadString(address, length);
 | 
			
		||||
                if (result.IsSuccess)
 | 
			
		||||
                {
 | 
			
		||||
                    return result.Content;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:" + address + ";提示:" + result.Message);
 | 
			
		||||
                    return "-1";
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}读取异常:" + ex.GetExceptionMessage());
 | 
			
		||||
                return "-1";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        public override float ReadFloat(string address)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                // 读取Float变量
 | 
			
		||||
                var result = melsecMc.ReadFloat(address);
 | 
			
		||||
                if (result.IsSuccess)
 | 
			
		||||
                {
 | 
			
		||||
                    return result.Content;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:" + address + ";提示:" + result.Message);
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}读取异常:" + ex.GetExceptionMessage());
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        public override void WriteItem(PLCItem item, bool waitForReply = true)
 | 
			
		||||
        {
 | 
			
		||||
            item.PLCOpType = PLCOpType.Write;
 | 
			
		||||
 | 
			
		||||
            if (item.ItemValues == null || item.ItemValues.Count < 1)
 | 
			
		||||
            {
 | 
			
		||||
                LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入值不能为空");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            int repeatTime = 3;
 | 
			
		||||
            Stopwatch sw = new Stopwatch();
 | 
			
		||||
 | 
			
		||||
            do
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    var result = melsecMc.Write(item.Address, item.ItemValues.First());
 | 
			
		||||
                    if (result.IsSuccess)
 | 
			
		||||
                    {
 | 
			
		||||
                        repeatTime = 0;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception ex)
 | 
			
		||||
                {
 | 
			
		||||
                    if (repeatTime < 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } while (repeatTime > 0);
 | 
			
		||||
            sw.Stop();
 | 
			
		||||
            LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} WriteItem:{item.GetDisplayText()},写入 {item.ItemValues.First()}完成,耗时:{sw.ElapsedMilliseconds} ms");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 写单独地址
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="address">地址</param>
 | 
			
		||||
        /// <param name="writeValue"></param>
 | 
			
		||||
        /// <param name="waitForReply"></param>
 | 
			
		||||
        public override void WriteInt(string address, int writeValue, bool waitForReply = true)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrEmpty(address))
 | 
			
		||||
            {
 | 
			
		||||
                LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            int repeatTime = 3;
 | 
			
		||||
            Stopwatch sw = new Stopwatch();
 | 
			
		||||
 | 
			
		||||
            do
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
 | 
			
		||||
                    var result = melsecMc.Write(address, writeValue);
 | 
			
		||||
                    if (result.IsSuccess)
 | 
			
		||||
                    {
 | 
			
		||||
                        repeatTime = 0;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception ex)
 | 
			
		||||
                {
 | 
			
		||||
                    if (repeatTime < 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } while (repeatTime > 0);
 | 
			
		||||
            sw.Stop();
 | 
			
		||||
            LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入 {writeValue} 完成,耗时:{sw.ElapsedMilliseconds} ms");
 | 
			
		||||
        }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 写单独地址 string值
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="address">地址</param>
 | 
			
		||||
        /// <param name="writeValue"></param>
 | 
			
		||||
        /// <param name="waitForReply"></param>
 | 
			
		||||
        public override void WriteString(string address, string writeValue, bool waitForReply = true)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrEmpty(address) || string.IsNullOrEmpty(writeValue))
 | 
			
		||||
            {
 | 
			
		||||
                LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            int repeatTime = 3;
 | 
			
		||||
            Stopwatch sw = new Stopwatch();
 | 
			
		||||
 | 
			
		||||
            do
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    var result = melsecMc.Write(address, writeValue);
 | 
			
		||||
                    if (result.IsSuccess)
 | 
			
		||||
                    {
 | 
			
		||||
                        repeatTime = 0;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception ex)
 | 
			
		||||
                {
 | 
			
		||||
                    if (repeatTime < 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } while (repeatTime > 0);
 | 
			
		||||
            sw.Stop();
 | 
			
		||||
            LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入{writeValue}完成,耗时:{sw.ElapsedMilliseconds} ms");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 写单独地址 float值
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="address">地址</param>
 | 
			
		||||
        /// <param name="writeValue"></param>
 | 
			
		||||
        /// <param name="waitForReply"></param>
 | 
			
		||||
        public override void WriteFloat(string address, float writeValue, bool waitForReply = true)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrEmpty(address))
 | 
			
		||||
            {
 | 
			
		||||
                LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            int repeatTime = 3;
 | 
			
		||||
            Stopwatch sw = new Stopwatch();
 | 
			
		||||
 | 
			
		||||
            do
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    var result = melsecMc.Write(address, writeValue);
 | 
			
		||||
                    if (result.IsSuccess)
 | 
			
		||||
                    {
 | 
			
		||||
                        repeatTime = 0;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception ex)
 | 
			
		||||
                {
 | 
			
		||||
                    if (repeatTime < 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } while (repeatTime > 0);
 | 
			
		||||
            sw.Stop();
 | 
			
		||||
            LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入{writeValue}完成,耗时:{sw.ElapsedMilliseconds} ms");
 | 
			
		||||
        }
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        #region DeviceBase
 | 
			
		||||
        protected override void Init()
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void Start()
 | 
			
		||||
        {
 | 
			
		||||
            // IConfig.ip
 | 
			
		||||
 | 
			
		||||
            melsecMc = new MelsecMcNet(IIConfig.PLCIpAddress, IIConfig.PLCPort);
 | 
			
		||||
 | 
			
		||||
            // 如果网络不太理想,配置了两个端口,一个有问题,立即切换另一个的话,可以配置如下的代码
 | 
			
		||||
            // melsecMc.GetPipeSocket().SetMultiPorts(new int[] { 6000, 6001 });
 | 
			
		||||
 | 
			
		||||
            // 连接对象
 | 
			
		||||
            OperateResult connect = melsecMc.ConnectServer();
 | 
			
		||||
            if (connect.IsSuccess)
 | 
			
		||||
            {
 | 
			
		||||
                base.Start();
 | 
			
		||||
                Task.Run(() =>
 | 
			
		||||
                {
 | 
			
		||||
                    HeartbeatMonitor();
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}已开启异常:{connect.Message}");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void Stop()
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                // 断开连接
 | 
			
		||||
                // melsecMc.RemoteStop();
 | 
			
		||||
                // OmronUDPNet.Stop();
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}关闭异常:{ex.GetExceptionMessage()}");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        //private void InitialScanClient()
 | 
			
		||||
        //{
 | 
			
		||||
        //    InitialTcpClient(ref scanClient, ref scanStream);
 | 
			
		||||
        //}
 | 
			
		||||
 | 
			
		||||
        //private void InitialOpClient()
 | 
			
		||||
        //{
 | 
			
		||||
        //    InitialTcpClient(ref opClient, ref opStream);
 | 
			
		||||
        //}
 | 
			
		||||
 | 
			
		||||
        //private void InitialTcpClient(ref TcpClient client, ref NetworkStream stream)
 | 
			
		||||
        //{
 | 
			
		||||
        //    if (client == null || !client.Connected || !client.Client.Connected)
 | 
			
		||||
        //    {
 | 
			
		||||
        //        client = new TcpClient();
 | 
			
		||||
        //        client.NoDelay = true;
 | 
			
		||||
        //        client.Client.NoDelay = true;
 | 
			
		||||
        //        client.Client.Blocking = true;
 | 
			
		||||
        //        client.Connect(plcEP);
 | 
			
		||||
 | 
			
		||||
        //        stream = client.GetStream();
 | 
			
		||||
        //    }
 | 
			
		||||
        //}
 | 
			
		||||
 | 
			
		||||
        #region IMonitor
 | 
			
		||||
        readonly byte[] scanBuffer = new byte[2048];
 | 
			
		||||
        public override List<int> GetMonitorValues(int startAddress, int length)
 | 
			
		||||
        {
 | 
			
		||||
            List<int> res = new List<int>();
 | 
			
		||||
            //var result = melsecMc.ReadInt32("D" + startAddress, (ushort)length);
 | 
			
		||||
            var result = melsecMc.ReadInt32("D" + startAddress, (ushort)length);
 | 
			
		||||
            if (result.IsSuccess)
 | 
			
		||||
            {
 | 
			
		||||
                res = new List<int>(result.Content);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:W" + startAddress + ";长度:" + length + ";提示:" + result.Message);
 | 
			
		||||
            }
 | 
			
		||||
            return res;
 | 
			
		||||
        }
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        public async void HeartbeatMonitor()
 | 
			
		||||
        {
 | 
			
		||||
            if (IIConfig.HeartbeatCycle <= 0)
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            await Task.Run(async () =>
 | 
			
		||||
            {
 | 
			
		||||
                if (!string.IsNullOrEmpty(IIConfig.HeartbeatAddress)
 | 
			
		||||
                            && IIConfig.HeartbeatCycle > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    while (CurrentState != DeviceState.DSClose && CurrentState != DeviceState.DSExcept)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (IIConfig.HeartbeatCycle <= 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            await Task.Delay(IIConfig.HeartbeatCycle * 1000);
 | 
			
		||||
                            var result = melsecMc.Write(IIConfig.HeartbeatAddress, 1);
 | 
			
		||||
                            if (!result.IsSuccess)
 | 
			
		||||
                            {
 | 
			
		||||
                                LogAsync(DateTime.Now, LogLevel.Error, $"{this.Name} 心跳监听失败");
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        catch (Exception ex)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (CurrentState == DeviceState.DSOpen)
 | 
			
		||||
                            {
 | 
			
		||||
                                LogAsync(DateTime.Now, LogLevel.Exception, $"{this.Name} 心跳监听异常,{ex.GetExceptionMessage()}");
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								src/XKRS.Device.MelsecPLC/Program.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/XKRS.Device.MelsecPLC/Program.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace XKRS.Device.MelsecPLC
 | 
			
		||||
{
 | 
			
		||||
    class Program
 | 
			
		||||
    {
 | 
			
		||||
        static void Main(string[] args)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								src/XKRS.Device.MelsecPLC/Properties/AssemblyInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/XKRS.Device.MelsecPLC/Properties/AssemblyInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Runtime.CompilerServices;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
// 有关程序集的一般信息由以下
 | 
			
		||||
// 控制。更改这些特性值可修改
 | 
			
		||||
// 与程序集关联的信息。
 | 
			
		||||
[assembly: AssemblyTitle("XKRS.Device.MelsecPLC")]
 | 
			
		||||
[assembly: AssemblyDescription("")]
 | 
			
		||||
[assembly: AssemblyConfiguration("")]
 | 
			
		||||
[assembly: AssemblyCompany("HP Inc.")]
 | 
			
		||||
[assembly: AssemblyProduct("XKRS.Device.MelsecPLC")]
 | 
			
		||||
[assembly: AssemblyCopyright("Copyright © HP Inc. 2023")]
 | 
			
		||||
[assembly: AssemblyTrademark("")]
 | 
			
		||||
[assembly: AssemblyCulture("")]
 | 
			
		||||
 | 
			
		||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
 | 
			
		||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
 | 
			
		||||
//请将此类型的 ComVisible 特性设置为 true。
 | 
			
		||||
[assembly: ComVisible(false)]
 | 
			
		||||
 | 
			
		||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
 | 
			
		||||
[assembly: Guid("887f9454-b1f3-47b8-b9f7-48beba47193d")]
 | 
			
		||||
 | 
			
		||||
// 程序集的版本信息由下列四个值组成: 
 | 
			
		||||
//
 | 
			
		||||
//      主版本
 | 
			
		||||
//      次版本
 | 
			
		||||
//      生成号
 | 
			
		||||
//      修订号
 | 
			
		||||
//
 | 
			
		||||
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
 | 
			
		||||
//通过使用 "*",如下所示:
 | 
			
		||||
// [assembly: AssemblyVersion("1.0.*")]
 | 
			
		||||
[assembly: AssemblyVersion("1.0.0.0")]
 | 
			
		||||
[assembly: AssemblyFileVersion("1.0.0.0")]
 | 
			
		||||
							
								
								
									
										26
									
								
								src/XKRS.Device.MelsecPLC/Properties/Settings.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/XKRS.Device.MelsecPLC/Properties/Settings.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// <auto-generated>
 | 
			
		||||
//     此代码由工具生成。
 | 
			
		||||
//     运行时版本:4.0.30319.42000
 | 
			
		||||
//
 | 
			
		||||
//     对此文件的更改可能会导致不正确的行为,并且如果
 | 
			
		||||
//     重新生成代码,这些更改将会丢失。
 | 
			
		||||
// </auto-generated>
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
namespace XKRS.Device.MelsecPLC.Properties {
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
 | 
			
		||||
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")]
 | 
			
		||||
    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
 | 
			
		||||
        
 | 
			
		||||
        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
 | 
			
		||||
        
 | 
			
		||||
        public static Settings Default {
 | 
			
		||||
            get {
 | 
			
		||||
                return defaultInstance;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								src/XKRS.Device.MelsecPLC/Properties/Settings.settings
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/XKRS.Device.MelsecPLC/Properties/Settings.settings
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
 | 
			
		||||
  <Profiles>
 | 
			
		||||
    <Profile Name="(Default)" />
 | 
			
		||||
  </Profiles>
 | 
			
		||||
</SettingsFile>
 | 
			
		||||
							
								
								
									
										92
									
								
								src/XKRS.Device.MelsecPLC/XKRS.Device.MelsecPLC.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								src/XKRS.Device.MelsecPLC/XKRS.Device.MelsecPLC.csproj
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
 | 
			
		||||
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
 | 
			
		||||
    <ProjectGuid>{887F9454-B1F3-47B8-B9F7-48BEBA47193D}</ProjectGuid>
 | 
			
		||||
    <OutputType>Library</OutputType>
 | 
			
		||||
    <RootNamespace>XKRS.Device.MelsecPLC</RootNamespace>
 | 
			
		||||
    <AssemblyName>XKRS.Device.MelsecPLC</AssemblyName>
 | 
			
		||||
    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
 | 
			
		||||
    <FileAlignment>512</FileAlignment>
 | 
			
		||||
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
 | 
			
		||||
    <Deterministic>true</Deterministic>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
 | 
			
		||||
    <PlatformTarget>AnyCPU</PlatformTarget>
 | 
			
		||||
    <DebugSymbols>true</DebugSymbols>
 | 
			
		||||
    <DebugType>full</DebugType>
 | 
			
		||||
    <Optimize>false</Optimize>
 | 
			
		||||
    <OutputPath>bin\Debug\</OutputPath>
 | 
			
		||||
    <DefineConstants>DEBUG;TRACE</DefineConstants>
 | 
			
		||||
    <ErrorReport>prompt</ErrorReport>
 | 
			
		||||
    <WarningLevel>4</WarningLevel>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
 | 
			
		||||
    <PlatformTarget>AnyCPU</PlatformTarget>
 | 
			
		||||
    <DebugType>pdbonly</DebugType>
 | 
			
		||||
    <Optimize>true</Optimize>
 | 
			
		||||
    <OutputPath>..\Release\</OutputPath>
 | 
			
		||||
    <DefineConstants>TRACE</DefineConstants>
 | 
			
		||||
    <ErrorReport>prompt</ErrorReport>
 | 
			
		||||
    <WarningLevel>4</WarningLevel>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <StartupObject />
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Reference Include="HslCommunication, Version=10.6.1.0, Culture=neutral, PublicKeyToken=3d72ad3b6b5ec0e3, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\..\packages\HslCommunication.10.6.1\lib\net451\HslCommunication.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="System" />
 | 
			
		||||
    <Reference Include="System.Core" />
 | 
			
		||||
    <Reference Include="System.Windows.Forms" />
 | 
			
		||||
    <Reference Include="System.Xml.Linq" />
 | 
			
		||||
    <Reference Include="System.Data.DataSetExtensions" />
 | 
			
		||||
    <Reference Include="Microsoft.CSharp" />
 | 
			
		||||
    <Reference Include="System.Data" />
 | 
			
		||||
    <Reference Include="System.Net.Http" />
 | 
			
		||||
    <Reference Include="System.Xml" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Compile Include="MelsecPLCConfig.cs" />
 | 
			
		||||
    <Compile Include="MelsecPLCDriver.cs" />
 | 
			
		||||
    <Compile Include="Program.cs" />
 | 
			
		||||
    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
			
		||||
    <Compile Include="Properties\Settings.Designer.cs">
 | 
			
		||||
      <AutoGen>True</AutoGen>
 | 
			
		||||
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
 | 
			
		||||
      <DependentUpon>Settings.settings</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <None Include="App.config" />
 | 
			
		||||
    <None Include="packages.config" />
 | 
			
		||||
    <None Include="Properties\Settings.settings">
 | 
			
		||||
      <Generator>SettingsSingleFileGenerator</Generator>
 | 
			
		||||
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
 | 
			
		||||
    </None>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\BRS.Common.Device\BRS.Common.Device.csproj">
 | 
			
		||||
      <Project>{987308dd-8baa-463a-94e2-77d62e01a5bf}</Project>
 | 
			
		||||
      <Name>BRS.Common.Device</Name>
 | 
			
		||||
    </ProjectReference>
 | 
			
		||||
    <ProjectReference Include="..\BRS.Common.Model\BRS.Common.Model.csproj">
 | 
			
		||||
      <Project>{1a3cbfe7-3f78-42c3-95c5-10360450dbea}</Project>
 | 
			
		||||
      <Name>BRS.Common.Model</Name>
 | 
			
		||||
    </ProjectReference>
 | 
			
		||||
    <ProjectReference Include="..\BRS.UI.Device.Winform\BRS.UI.Device.Winform.csproj">
 | 
			
		||||
      <Project>{e6429c64-92b3-46a2-b35e-579856d47f62}</Project>
 | 
			
		||||
      <Name>BRS.UI.Device.Winform</Name>
 | 
			
		||||
    </ProjectReference>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <WCFMetadata Include="Connected Services\" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										5
									
								
								src/XKRS.Device.MelsecPLC/packages.config
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/XKRS.Device.MelsecPLC/packages.config
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<packages>
 | 
			
		||||
  <package id="HslCommunication" version="10.6.1" targetFramework="net461" />
 | 
			
		||||
  <package id="Newtonsoft.Json" version="12.0.3" targetFramework="net461" />
 | 
			
		||||
</packages>
 | 
			
		||||
		Reference in New Issue
	
	Block a user