Forráskód Böngészése

1. 修改获取参数函数细节
2. 移除不必要的事件跳转

Shun 2 éve
szülő
commit
29eb0417e9

+ 2 - 1
README.md

@@ -450,4 +450,5 @@ while(true)
 7. 版本更新
 
 #### 2023-11-10
-1. 自定义订阅细节修改,移除不必要的事件
+1. 自定义订阅细节修改,移除不必要的事件
+2. 新增松下PLC

+ 1 - 11
src/YSAI.AllenBradley/AllenBradleyOperate.cs

@@ -606,16 +606,6 @@ namespace YSAI.AllenBradley
         /// </summary>
         private SubscribeOperate subscribeOperate;
 
-        /// <summary>
-        /// 事件抛出
-        /// </summary>
-        /// <param name="sender">自定义订阅对象</param>
-        /// <param name="e">返回的参数</param>
-        private void SubscribeOperate_OnEvent(object? sender, EventResult e)
-        {
-            OnEventHandler(this, e);
-        }
-
         public OperateResult Subscribe(Address address)
         {
             string SN = Depart("Subscribe");
@@ -634,7 +624,7 @@ namespace YSAI.AllenBradley
                         TaskHandleInterval = basics.TaskHandleInterval,
                         TaskNumber = basics.TaskNumber
                     });
-                    subscribeOperate.OnEvent += SubscribeOperate_OnEvent;
+                    subscribeOperate.OnEvent += OnEventHandler;
                     OperateResult operateResult = subscribeOperate.On();
                     return Break(SN, operateResult.State, operateResult.Message);
                 }

+ 1 - 11
src/YSAI.Can/CanOperate.cs

@@ -403,7 +403,7 @@ namespace YSAI.Can
                         TaskHandleInterval = basics.TaskHandleInterval,
                         TaskNumber = basics.TaskNumber
                     });
-                    subscribeOperate.OnEvent += SubscribeOperate_OnEvent;
+                    subscribeOperate.OnEvent += OnEventHandler;
                     OperateResult operateResult = subscribeOperate.On();
                     return Break("Subscribe", operateResult.State, operateResult.Message);
                 }
@@ -450,16 +450,6 @@ namespace YSAI.Can
             return Task.Run(() => UnSubscribe(address));
         }
 
-        /// <summary>
-        /// 事件抛出
-        /// </summary>
-        /// <param name="sender">自定义订阅对象</param>
-        /// <param name="e">返回的参数</param>
-        private void SubscribeOperate_OnEvent(object? sender, EventResult e)
-        {
-            OnEventHandler(this, e);
-        }
-
         public OperateResult GetStatus()
         {
             return Break(Depart("GetStatus"), CanState, CanState ? "已连接" : "未连接");

+ 1 - 1
src/YSAI.Core/YSAI.Core.csproj

@@ -5,7 +5,7 @@
     <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
     <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
-    <Version>1.0.0.90</Version>
+    <Version>1.0.0.91</Version>
     <Authors>Shun</Authors>
     <Company>YSAI</Company>
     <Product>SCADA</Product>

+ 1 - 2
src/YSAI.Core/data/ParamStructure.cs

@@ -100,8 +100,7 @@ namespace YSAI.Core.data
             /// <summary>
             /// 初始值
             /// </summary>
-            public object? Initial
-            { get { return Default; } }
+            public object? Initial { get; set; }
 
             /// <summary>
             /// 描述

+ 24 - 12
src/YSAI.Core/handler/ParamHandler.cs

@@ -83,10 +83,6 @@ namespace YSAI.Core.handler
                             }
                         }
                     };
-                    if (Properties != null && Properties.Count > 0)
-                    {
-                        paramStructure.Subset[0].Propertie.AddRange(Properties);
-                    }
                     foreach (var lib in libInstanceParams)
                     {
                         //默认值
@@ -116,9 +112,8 @@ namespace YSAI.Core.handler
 
                             Regex = verifyAttribute?.Regex ?? null,
                             FailTips = verifyAttribute?.FailTips ?? null,
-
-                            Default = Default
                         };
+
                         switch (displayAttribute?.DataCate)
                         {
                             case Core.data.ParamStructure.dataCate.select:
@@ -150,10 +145,19 @@ namespace YSAI.Core.handler
                                     Key = "否",
                                     Value = false,
                                 });
+
+                                propertie.Default = Default;
+                                break;
+
+                            default:
+                                propertie.Default = Default;
                                 break;
                         }
                         paramStructure.Subset[0].Propertie.Add(propertie);
                     }
+
+
+
                     //移除组
                     if (RGroups != null && RGroups.Count > 0)
                     {
@@ -163,6 +167,13 @@ namespace YSAI.Core.handler
                             paramStructure.Subset[0].Propertie.RemoveRange(item.RIndex, item.RCount);
                         }
                     }
+
+                    //添加
+                    if (Properties != null && Properties.Count > 0)
+                    {
+                        paramStructure.Subset[0].Propertie.AddRange(Properties);
+                    }
+
                     return new OperateResult(true, paramStructure.ToJson().JsonFormatting(), timeTool.StopRecord().milliseconds, paramStructure, Core.@enum.ResultType.Object);
                 }
                 else
@@ -184,12 +195,6 @@ namespace YSAI.Core.handler
                             Propertie = new List<ParamStructure.propertie>()
                         });
 
-                        //子集中需要添加项
-                        if (subclass[i].Properties != null && subclass[i].Properties.Count > 0)
-                        {
-                            paramStructure.Subset[i].Propertie.AddRange(subclass[i].Properties);
-                        }
-
                         foreach (var lib in libInstanceParams)
                         {
                             //默认值
@@ -257,6 +262,7 @@ namespace YSAI.Core.handler
                             }
                             paramStructure.Subset[i].Propertie.Add(propertie);
                         }
+
                         //移除组
                         if (subclass[i].RGroups != null && subclass[i].RGroups.Count > 0)
                         {
@@ -266,6 +272,12 @@ namespace YSAI.Core.handler
                                 paramStructure.Subset[i].Propertie.RemoveRange(item.RIndex, item.RCount);
                             }
                         }
+
+                        //子集中需要添加项
+                        if (subclass[i].Properties != null && subclass[i].Properties.Count > 0)
+                        {
+                            paramStructure.Subset[i].Propertie.AddRange(subclass[i].Properties);
+                        }
                     }
                     return new OperateResult(true, paramStructure.ToJson().JsonFormatting(), timeTool.StopRecord().milliseconds, paramStructure, Core.@enum.ResultType.Object);
                 }

+ 101 - 1
src/YSAI.Mewtocol/MewtocolData.cs

@@ -1,4 +1,11 @@
-using YSAI.Core.subscription;
+using MewtocolNet;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using System.ComponentModel;
+using System.IO.Ports;
+using YSAI.Core.attribute;
+using YSAI.Core.subscription;
+using YSAI.Unility;
 
 namespace YSAI.Mewtocol
 {
@@ -10,7 +17,100 @@ namespace YSAI.Mewtocol
         /// </summary>
         public class Basics : SubscribeData.SCData
         {
+            /// <summary>
+            /// 唯一标识符
+            /// </summary>
+            [Description("唯一标识符")]
+            public string? SN { get; set; } = Guid.NewGuid().ToUpperNString();
 
+            /// <summary>
+            /// 站号
+            /// </summary>
+            [Description("站号")]
+            [Display(true, true, true, Core.data.ParamStructure.dataCate.unmber)]
+            public int StationNumber { get; set; } = 238;
+
+            /// <summary>
+            /// 协议类型
+            /// </summary>
+            [Description("协议类型")]
+            [JsonConverter(typeof(StringEnumConverter))]
+            [Display(true, true, true, Core.data.ParamStructure.dataCate.select)]
+            public ProtocolType ProtocolType { get; set; } = ProtocolType.Tcp;
+
+            /// <summary>
+            /// 超时时间
+            /// </summary>
+            [Description("超时时间")]
+            [Unit("ms")]
+            [Display(true, true, true, Core.data.ParamStructure.dataCate.unmber)]
+            public int Timeout { get; set; } = 1000;
+
+
+            /// <summary>
+            /// ip地址
+            /// </summary>
+            [Description("IP")]
+            [Verify(@"^(25[0-4]|2[0-4]\\d]|[01]?\\d{2}|[1-9])\\.(25[0-5]|2[0-4]\\d]|[01]?\\d?\\d)\\.(25[0-5]|2[0-4]\\d]|[01]?\\d?\\d)\\.(25[0-4]|2[0-4]\\d]|[01]?\\d{2}|[1-9])$", "输入有误")]
+            [Display(true, true, true, Core.data.ParamStructure.dataCate.text)]
+            public string? Ip { get; set; } = "127.0.0.1";
+
+            /// <summary>
+            /// 端口
+            /// </summary>
+            [Description("端口")]
+            [Display(true, true, true, Core.data.ParamStructure.dataCate.unmber)]
+            public int Port { get; set; } = 6688;
+
+
+
+
+            /// <summary>
+            /// 串口号
+            /// </summary>
+            [Description("串口号")]
+            [Display(true, true, true, Core.data.ParamStructure.dataCate.text)]
+            public string? PortName { get; set; }
+
+            /// <summary>
+            /// 波特率
+            /// </summary>
+            [Description("波特率")]
+            [Display(true, true, true, Core.data.ParamStructure.dataCate.select)]
+            public BaudRate BaudRate { get; set; } = BaudRate._19200;
+
+            /// <summary>
+            /// 校验位
+            /// </summary>
+            [Description("校验位")]
+            [JsonConverter(typeof(StringEnumConverter))]
+            [Display(true, true, true, Core.data.ParamStructure.dataCate.select)]
+            public Parity ParityBit { get; set; } = Parity.Even;
+
+            /// <summary>
+            /// 数据位
+            /// </summary>
+            [Description("数据位")]
+            [Display(true, true, true, Core.data.ParamStructure.dataCate.select)]
+            public DataBits DataBit { get; set; } = DataBits.Eight;
+
+            /// <summary>
+            /// 停止位
+            /// </summary>
+            [Description("停止位")]
+            [JsonConverter(typeof(StringEnumConverter))]
+            [Display(true, true, true, Core.data.ParamStructure.dataCate.select)]
+            public StopBits StopBit { get; set; } = StopBits.One;
+
+
+        }
+        /// <summary>
+        /// 协议类型
+        /// </summary>
+        public enum ProtocolType
+        {
+            Tcp,
+            Serial
         }
     }
 }

+ 931 - 2
src/YSAI.Mewtocol/MewtocolOperate.cs

@@ -1,10 +1,939 @@
-namespace YSAI.Mewtocol
+using MewtocolNet;
+using MewtocolNet.Registers;
+using System.Collections.Concurrent;
+using YSAI.Core.data;
+using YSAI.Core.handler;
+using YSAI.Core.@interface;
+using YSAI.Core.subscription;
+using YSAI.Core.virtualAddress;
+using YSAI.Log;
+using YSAI.Unility;
+
+namespace YSAI.Mewtocol
 {
     /// <summary>
     /// 松下PLC 操作
     /// </summary>
-    public class MewtocolOperate
+    public class MewtocolOperate : IBaseAbstract, IDaq
     {
+        protected override string TAG => "MewtocolOperate";
+
+        /// <summary>
+        /// 锁
+        /// </summary>
+        private static readonly object Lock = new object();
+
+        /// <summary>
+        /// 自身对象集合
+        /// </summary>
+        private static List<MewtocolOperate> ThisObjList = new List<MewtocolOperate>(); //自身对象集合
+
+        /// <summary>
+        /// 单例模式
+        /// </summary>
+        /// <returns></returns>
+        public static MewtocolOperate Instance(MewtocolData.Basics basics)
+        {
+            if (ThisObjList.Count >= MaxInstanceCount)
+            {
+                throw new Exception(ExceedMaxInstanceCountTips);
+            }
+            MewtocolOperate? exp = ThisObjList.FirstOrDefault(c => c.basics.Comparer(basics).result);
+            if (exp == null)
+            {
+                lock (Lock)
+                {
+                    if (ThisObjList.Count(c => c.basics.Comparer(basics).result) > 0)
+                    {
+                        return ThisObjList.First(c => c.basics.Comparer(basics).result);
+                    }
+                    else
+                    {
+                        MewtocolOperate exp2 = new MewtocolOperate(basics);
+                        ThisObjList.Add(exp2);
+                        return exp2;
+                    }
+                }
+            }
+            return exp;
+        }
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="basics">基础数据</param>
+        public MewtocolOperate(MewtocolData.Basics basics)
+        {
+            this.basics = basics;
+        }
+
+        public MewtocolOperate()
+        { }
+
+        /// <summary>
+        /// 基础数据
+        /// </summary>
+        private MewtocolData.Basics basics;
+
+        /// <summary>
+        /// 松下PLC通信 网口
+        /// </summary>
+        private IPlcEthernet MTcp;
+        private MewtocolNet.Mewtocol.PostInit<IPlcEthernet> mmpi;
+
+        /// <summary>
+        /// 松下PLC通信 串口
+        /// </summary>
+        private IPlcSerial MSerial;
+        private MewtocolNet.Mewtocol.PostInit<IPlcSerial> mmps;
+
+        /// <summary>
+        /// 虚拟地址
+        /// </summary>
+        private VirtualAddressManage VAM = new VirtualAddressManage();
+
+        /// <summary>
+        /// 实现订阅功能
+        /// </summary>
+        private SubscribeOperate subscribeOperate;
+
+        public OperateResult Read(Address address)
+        {
+            string SN = Depart("Read");
+            try
+            {
+                //节点数据
+                ConcurrentDictionary<string, AddressValue> param = new ConcurrentDictionary<string, AddressValue>();
+                switch (basics.ProtocolType)
+                {
+                    case MewtocolData.ProtocolType.Tcp:
+                        if (MTcp == null)
+                        {
+                            return Break(SN, false, "未连接");
+                        }
+                        //循环添加项集合
+                        foreach (var item in address.AddressArray)
+                        {
+                            if (!item.IsEnable) continue;
+                            //是不是虚拟地址
+                            bool IsVA = false;
+                            //初始化虚拟地址
+                            VAM.InitVirtualAddress(item, out IsVA);
+                            //值
+                            string? Value = string.Empty;
+
+                            if (IsVA)
+                            {
+                                Value = VAM.Read(item);
+                            }
+                            else
+                            {
+                                try
+                                {
+                                    switch (item.AddressDataType)
+                                    {
+                                        case Core.@enum.DataType.String:
+                                            mmpi.WithRegisters(c =>
+                                            {
+                                                //字符串 必须放数据长度
+                                                //地址名,长度
+                                                string[] strings = item.AddressName.Split(',');
+                                                c.String(strings[0], int.Parse(strings[1])).AsArray(1).Build(out IArrayRegister<string>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Byte:
+                                            mmpi.WithRegisters(c =>
+                                            {
+                                                c.Struct<byte>(item.AddressName).Build(out IRegister<byte>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Bool:
+                                            mmpi.WithRegisters(c =>
+                                            {
+                                                c.Bool(item.AddressName).Build(out IRegister<bool>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Short:
+                                        case Core.@enum.DataType.Int16:
+                                            mmpi.WithRegisters(c =>
+                                            {
+                                                c.Struct<short>(item.AddressName).Build(out IRegister<short>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Ushort:
+                                        case Core.@enum.DataType.UInt16:
+                                            mmpi.WithRegisters(c =>
+                                            {
+                                                c.Struct<ushort>(item.AddressName).Build(out IRegister<ushort>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Int:
+                                        case Core.@enum.DataType.Int32:
+                                            mmpi.WithRegisters(c =>
+                                            {
+                                                c.Struct<Word>(item.AddressName).Build(out IRegister<Word>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Uint:
+                                        case Core.@enum.DataType.UInt32:
+                                            mmpi.WithRegisters(c =>
+                                            {
+                                                c.Struct<DWord>(item.AddressName).Build(out IRegister<DWord>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Double:
+                                            mmpi.WithRegisters(c =>
+                                            {
+                                                c.Struct<double>(item.AddressName).Build(out IRegister<double>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Float:
+                                            mmpi.WithRegisters(c =>
+                                            {
+                                                c.Struct<float>(item.AddressName).Build(out IRegister<float>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        default:
+                                            LogHelper.Error($"[ {item.AddressName} ]读取失败:不支持{item.AddressDataType}类型读取");
+                                            break;
+                                    }
+                                }
+                                catch (Exception ex)
+                                {
+                                    LogHelper.Error($"[ {item.AddressName} ]读取异常:{ex.Message}");
+                                }
+                            }
+                            //数据处理
+                            AddressValue addressValue = Core.handler.AddressHandler.ExecuteDispose(item, Value);
+
+                            //数据添加
+                            param.AddOrUpdate(item.AddressName, addressValue, (k, v) => addressValue);
+                        }
+                        break;
+                    case MewtocolData.ProtocolType.Serial:
+                        if (MSerial == null)
+                        {
+                            return Break(SN, false, "未连接");
+                        }
+
+                        //循环添加项集合
+                        foreach (var item in address.AddressArray)
+                        {
+                            if (!item.IsEnable) continue;
+                            //是不是虚拟地址
+                            bool IsVA = false;
+                            //初始化虚拟地址
+                            VAM.InitVirtualAddress(item, out IsVA);
+                            //值
+                            string? Value = string.Empty;
+
+                            if (IsVA)
+                            {
+                                Value = VAM.Read(item);
+                            }
+                            else
+                            {
+                                try
+                                {
+                                    switch (item.AddressDataType)
+                                    {
+                                        case Core.@enum.DataType.String:
+                                            mmps.WithRegisters(c =>
+                                            {
+                                                //字符串 必须放数据长度
+                                                //地址名,长度
+                                                string[] strings = item.AddressName.Split(',');
+                                                c.String(strings[0], int.Parse(strings[1])).AsArray(0).Build(out IArrayRegister<string>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Byte:
+                                            mmps.WithRegisters(c =>
+                                            {
+                                                c.Struct<byte>(item.AddressName).Build(out IRegister<byte>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Bool:
+                                            mmps.WithRegisters(c =>
+                                            {
+                                                c.Bool(item.AddressName).Build(out IRegister<bool>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Short:
+                                        case Core.@enum.DataType.Int16:
+                                            mmps.WithRegisters(c =>
+                                            {
+                                                c.Struct<short>(item.AddressName).Build(out IRegister<short>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Ushort:
+                                        case Core.@enum.DataType.UInt16:
+                                            mmps.WithRegisters(c =>
+                                            {
+                                                c.Struct<ushort>(item.AddressName).Build(out IRegister<ushort>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Int:
+                                        case Core.@enum.DataType.Int32:
+                                            mmps.WithRegisters(c =>
+                                            {
+                                                c.Struct<Word>(item.AddressName).Build(out IRegister<Word>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Uint:
+                                        case Core.@enum.DataType.UInt32:
+                                            mmps.WithRegisters(c =>
+                                            {
+                                                c.Struct<DWord>(item.AddressName).Build(out IRegister<DWord>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Double:
+                                            mmps.WithRegisters(c =>
+                                            {
+                                                c.Struct<double>(item.AddressName).Build(out IRegister<double>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        case Core.@enum.DataType.Float:
+                                            mmps.WithRegisters(c =>
+                                            {
+                                                c.Struct<float>(item.AddressName).Build(out IRegister<float>? mValue);
+                                                Value = mValue?.ValueStr ?? string.Empty;
+                                            });
+                                            break;
+                                        default:
+                                            LogHelper.Error($"[ {item.AddressName} ]读取失败:不支持{item.AddressDataType}类型读取");
+                                            break;
+                                    }
+                                }
+                                catch (Exception ex)
+                                {
+                                    LogHelper.Error($"[ {item.AddressName} ]读取异常:{ex.Message}");
+                                }
+                            }
+                            //数据处理
+                            AddressValue addressValue = Core.handler.AddressHandler.ExecuteDispose(item, Value);
+
+                            //数据添加
+                            param.AddOrUpdate(item.AddressName, addressValue, (k, v) => addressValue);
+                        }
+                        break;
+                }
+                if (param.Count > 0)
+                {
+                    //返回读取的数据
+                    return Break(SN, true, RData: param, RType: Core.@enum.ResultType.KeyValue);
+                }
+                else
+                {
+                    return Break(SN, false, "读取失败");
+                }
+            }
+            catch (Exception ex)
+            {
+                return Break(SN, false, ex.Message, Exception: ex);
+            }
+        }
+
+        public Task<OperateResult> ReadAsync(Address address)
+        {
+            return Task.Run(() => Read(address));
+        }
+
+        public OperateResult Write<V>(ConcurrentDictionary<string, V> Values)
+        {
+            string SN = Depart("Write");
+            try
+            {
+                //失败消息
+                List<string> FailMessage = new List<string>();
+
+                switch (basics.ProtocolType)
+                {
+                    case MewtocolData.ProtocolType.Tcp:
+                        if (MTcp == null)
+                        {
+                            return Break(SN, false, "未连接");
+                        }
+
+
+                        foreach (var item in Values)
+                        {
+                            KeyValuePair<string, V> Param = item;
+                            //判断是不是虚拟点
+                            if (VAM.IsVirtualAddress(Param.Key))
+                            {
+                                if (!VAM.Write(Param.Key, Param.Value.ToString()))
+                                {
+                                    FailMessage.Add($"{Param.Key},写入失败");
+                                }
+                            }
+                            else
+                            {
+                                bool RState = false;
+                                object obj = Param.Value;
+                                if (obj is byte)
+                                {
+                                    mmpi.WithRegisters(c =>
+                                    {
+                                        c.Struct<byte>(Param.Key).Build(out IRegister<byte>? mValue);
+                                        RState = mValue.WriteAsync((byte)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                else if (obj is bool)
+                                {
+                                    mmpi.WithRegisters(c =>
+                                    {
+                                        c.Bool(Param.Key).Build(out IRegister<bool>? mValue);
+                                        RState = mValue.WriteAsync((bool)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                else if (obj is string)
+                                {
+                                    mmpi.WithRegisters(c =>
+                                    {
+                                        //字符串 必须放数据长度
+                                        //地址名,长度
+                                        string[] strings = Param.Key.Split(',');
+                                        c.String(strings[0], int.Parse(strings[1])).AsArray(1).Build(out IArrayRegister<string>? mValue);
+                                        RState = mValue.WriteAsync(new string[] { obj.ToString() }).Wait(basics.Timeout); ;
+                                    });
+                                }
+                                else if (obj is Int16)
+                                {
+                                    mmpi.WithRegisters(c =>
+                                    {
+                                        c.Struct<short>(Param.Key).Build(out IRegister<short>? mValue);
+                                        RState = mValue.WriteAsync((short)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                else if (obj is UInt16)
+                                {
+                                    mmpi.WithRegisters(c =>
+                                    {
+                                        c.Struct<ushort>(Param.Key).Build(out IRegister<ushort>? mValue);
+                                        RState = mValue.WriteAsync((ushort)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                else if (obj is Int32)
+                                {
+                                    mmpi.WithRegisters(c =>
+                                    {
+                                        c.Struct<Word>(Param.Key).Build(out IRegister<Word>? mValue);
+                                        RState = mValue.WriteAsync((Word)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                else if (obj is UInt32)
+                                {
+                                    mmpi.WithRegisters(c =>
+                                    {
+                                        c.Struct<DWord>(Param.Key).Build(out IRegister<DWord>? mValue);
+                                        RState = mValue.WriteAsync((DWord)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                else if (obj is float)
+                                {
+                                    mmpi.WithRegisters(c =>
+                                    {
+                                        c.Struct<float>(Param.Key).Build(out IRegister<float>? mValue);
+                                        RState = mValue.WriteAsync((float)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                else if (obj is double)
+                                {
+                                    mmps.WithRegisters(c =>
+                                    {
+                                        c.Struct<double>(Param.Key).Build(out IRegister<double>? mValue);
+                                        RState = mValue.WriteAsync((double)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                if (!RState)
+                                {
+                                    FailMessage.Add($"{Param.Key},写入失败");
+                                }
+                            }
+                        }
+                        break;
+                    case MewtocolData.ProtocolType.Serial:
+                        if (MSerial == null)
+                        {
+                            return Break(SN, false, "未连接");
+                        }
+
+                        foreach (var item in Values)
+                        {
+                            KeyValuePair<string, V> Param = item;
+                            //判断是不是虚拟点
+                            if (VAM.IsVirtualAddress(Param.Key))
+                            {
+                                if (!VAM.Write(Param.Key, Param.Value.ToString()))
+                                {
+                                    FailMessage.Add($"{Param.Key},写入失败");
+                                }
+                            }
+                            else
+                            {
+                                bool RState = false;
+                                object obj = Param.Value;
+                                if (obj is byte)
+                                {
+                                    mmps.WithRegisters(c =>
+                                    {
+                                        c.Struct<byte>(Param.Key).Build(out IRegister<byte>? mValue);
+                                        RState = mValue.WriteAsync((byte)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                else if (obj is bool)
+                                {
+                                    mmps.WithRegisters(c =>
+                                    {
+                                        c.Bool(Param.Key).Build(out IRegister<bool>? mValue);
+                                        RState = mValue.WriteAsync((bool)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                else if (obj is string)
+                                {
+                                    mmps.WithRegisters(c =>
+                                    {
+                                        //字符串 必须放数据长度
+                                        //地址名,长度
+                                        string[] strings = Param.Key.Split(',');
+                                        c.String(strings[0], int.Parse(strings[1])).AsArray(1).Build(out IArrayRegister<string>? mValue);
+                                        RState = mValue.WriteAsync(new string[] { obj.ToString() }).Wait(basics.Timeout); ;
+                                    });
+                                }
+                                else if (obj is Int16)
+                                {
+                                    mmps.WithRegisters(c =>
+                                    {
+                                        c.Struct<short>(Param.Key).Build(out IRegister<short>? mValue);
+                                        RState = mValue.WriteAsync((short)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                else if (obj is UInt16)
+                                {
+                                    mmps.WithRegisters(c =>
+                                    {
+                                        c.Struct<ushort>(Param.Key).Build(out IRegister<ushort>? mValue);
+                                        RState = mValue.WriteAsync((ushort)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                else if (obj is Int32)
+                                {
+                                    mmps.WithRegisters(c =>
+                                    {
+                                        c.Struct<Word>(Param.Key).Build(out IRegister<Word>? mValue);
+                                        RState = mValue.WriteAsync((Word)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                else if (obj is UInt32)
+                                {
+                                    mmps.WithRegisters(c =>
+                                    {
+                                        c.Struct<DWord>(Param.Key).Build(out IRegister<DWord>? mValue);
+                                        RState = mValue.WriteAsync((DWord)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                else if (obj is float)
+                                {
+                                    mmps.WithRegisters(c =>
+                                    {
+                                        c.Struct<float>(Param.Key).Build(out IRegister<float>? mValue);
+                                        RState = mValue.WriteAsync((float)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                else if (obj is double)
+                                {
+                                    mmps.WithRegisters(c =>
+                                    {
+                                        c.Struct<double>(Param.Key).Build(out IRegister<double>? mValue);
+                                        RState = mValue.WriteAsync((double)obj).Wait(basics.Timeout);
+                                    });
+                                }
+                                if (!RState)
+                                {
+                                    FailMessage.Add($"{Param.Key},写入失败");
+                                }
+                            }
+                        }
+
+                        break;
+                }
+                if (FailMessage.Count > 0)
+                {
+                    return Break(SN, false, FailMessage.ToJson());
+                }
+                return Break(SN, true, "写入成功");
+            }
+            catch (Exception ex)
+            {
+                return Break(SN, false, ex.Message, Exception: ex);
+            }
+        }
+
+        public Task<OperateResult> WriteAsync<V>(ConcurrentDictionary<string, V> Values)
+        {
+            return Task.Run(() => Write(Values));
+        }
+
+        public OperateResult Subscribe(Address address)
+        {
+            string SN = Depart("Subscribe");
+            try
+            {
+                if (subscribeOperate == null)
+                {
+                    subscribeOperate = SubscribeOperate.Instance(new SubscribeData.Basics()
+                    {
+                        Address = address,
+                        ChangeOut = basics.ChangeOut,
+                        Function = Read,
+                        AllOut = basics.AllOut,
+                        HandleInterval = basics.HandleInterval,
+                        SN = basics.SN,
+                        TaskHandleInterval = basics.TaskHandleInterval,
+                        TaskNumber = basics.TaskNumber
+                    });
+                    subscribeOperate.OnEvent += OnEventHandler;
+                    OperateResult operateResult = subscribeOperate.On();
+                    return Break(SN, operateResult.State, operateResult.Message);
+                }
+                else
+                {
+                    OperateResult operateResult = subscribeOperate.Subscribe(address);
+                    return Break(SN, operateResult.State, operateResult.Message);
+                }
+            }
+            catch (Exception ex)
+            {
+                return Break(SN, false, ex.Message, Exception: ex);
+            }
+        }
+
+        public Task<OperateResult> SubscribeAsync(Address address)
+        {
+            return Task.Run(() => Subscribe(address));
+        }
+
+        public OperateResult UnSubscribe(Address address)
+        {
+            string SN = Depart("UnSubscribe");
+            try
+            {
+                if (subscribeOperate != null)
+                {
+                    OperateResult operateResult = subscribeOperate.UnSubscribe(address);
+                    return Break(SN, operateResult.State, operateResult.Message);
+                }
+                else
+                {
+                    return Break(SN, false, "当前尚未订阅");
+                }
+            }
+            catch (Exception ex)
+            {
+                return Break(SN, false, ex.Message, Exception: ex);
+            }
+        }
+
+        public Task<OperateResult> UnSubscribeAsync(Address address)
+        {
+            return Task.Run(() => UnSubscribe(address));
+        }
+
+        public OperateResult On()
+        {
+            string SN = Depart("On");
+            try
+            {
+                switch (basics.ProtocolType)
+                {
+                    case MewtocolData.ProtocolType.Tcp:
+                        if (MTcp != null)
+                        {
+                            return Break(SN, false, "已连接");
+                        }
+                        mmpi = MewtocolNet.Mewtocol.Ethernet(basics.Ip, basics.Port, basics.StationNumber);
+                        MTcp = mmpi.Build();
+                        if (MTcp.ConnectAsync().Wait(basics.Timeout))
+                        {
+                            //没有超时
+                            if (!MTcp.IsConnected)
+                            {
+                                return Break(SN, false, "连接失败");
+                            }
+                        }
+                        else
+                        {
+                            //超时了
+                            return Break(SN, false, "连接超时");
+                        }
+                        break;
+                    case MewtocolData.ProtocolType.Serial:
+                        if (MSerial != null)
+                        {
+                            return Break(SN, false, "已连接");
+                        }
+                        mmps = MewtocolNet.Mewtocol.Serial(basics.PortName, basics.BaudRate, basics.DataBit, basics.ParityBit, basics.StopBit, basics.StationNumber);
+                        MSerial = mmps.Build();
+                        if (MSerial.ConnectAsync().Wait(basics.Timeout))
+                        {
+                            //没有超时
+                            if (!MSerial.IsConnected)
+                            {
+                                return Break(SN, false, "连接失败");
+                            }
+                        }
+                        else
+                        {
+                            //超时了
+                            return Break(SN, false, "连接超时");
+                        }
+                        break;
+                }
+                return Break(SN, true);
+            }
+            catch (Exception ex)
+            {
+                return Break(SN, false, ex.Message, Exception: ex);
+            }
+        }
+
+        public Task<OperateResult> OnAsync()
+        {
+            return Task.Run(() => On());
+        }
+
+        public OperateResult Off()
+        {
+            string SN = Depart("Off");
+            try
+            {
+                switch (basics.ProtocolType)
+                {
+                    case MewtocolData.ProtocolType.Tcp:
+                        if (MTcp == null)
+                        {
+                            return Break(SN, false, "未连接");
+                        }
+
+                        if (subscribeOperate != null)
+                        {
+                            OperateResult operateResult = subscribeOperate.Off();
+                            if (!operateResult.State)
+                            {
+                                return Break(SN, false, operateResult.Message);
+                            }
+                            subscribeOperate = null;
+                        }
+                        if (MTcp.DisconnectAsync().Wait(basics.Timeout))
+                        {
+                            MTcp.Dispose();
+                            MTcp = null;
+                            mmpi = null;
+                        }
+                        else
+                        {
+                            return Break(SN, false, "关闭超时");
+                        }
+                        break;
+                    case MewtocolData.ProtocolType.Serial:
+                        if (MSerial == null)
+                        {
+                            return Break(SN, false, "未连接");
+                        }
+
+                        if (subscribeOperate != null)
+                        {
+                            OperateResult operateResult = subscribeOperate.Off();
+                            if (!operateResult.State)
+                            {
+                                return Break(SN, false, operateResult.Message);
+                            }
+                            subscribeOperate = null;
+                        }
+                        if (MSerial.DisconnectAsync().Wait(basics.Timeout))
+                        {
+                            MSerial.Dispose();
+                            MSerial = null;
+                            mmps = null;
+                        }
+                        else
+                        {
+                            return Break(SN, false, "关闭超时");
+                        }
+                        break;
+                }
+                return Break(SN, true);
+            }
+            catch (Exception ex)
+            {
+                return Break(SN, false, ex.Message, Exception: ex);
+            }
+        }
+
+        public Task<OperateResult> OffAsync()
+        {
+            return Task.Run(() => Off());
+        }
+
+        public void Dispose()
+        {
+            Off();
+            GC.Collect();
+            GC.SuppressFinalize(this);
+            ThisObjList.Remove(this);
+        }
+
+        public OperateResult GetStatus()
+        {
+            switch (basics.ProtocolType)
+            {
+                case MewtocolData.ProtocolType.Tcp:
+                    return Break(Depart("GetStatus"), MTcp?.IsConnected ?? false, MTcp?.IsConnected ?? false ? "已连接" : "未连接");
+                case MewtocolData.ProtocolType.Serial:
+                    return Break(Depart("GetStatus"), MSerial?.IsConnected ?? false, MSerial?.IsConnected ?? false ? "已连接" : "未连接");
+                default:
+                    return Break(Depart("GetStatus"), false, "未连接");
+            }
+        }
+
+        public Task<OperateResult> GetStatusAsync()
+        {
+            return Task.Run(() => GetStatus());
+        }
+
+        public OperateResult GetParam()
+        {
+            string SN = Depart("GetParam");
+            try
+            {
+                //名称
+                string name = TAG.Replace("Operate", string.Empty).Replace("Client", string.Empty);
+                //命名空间
+                string nameSpace = "YSAI.Mewtocol.MewtocolOperate";
+                //获取参数
+                OperateResult operateResult = ParamHandler.Get(new MewtocolData.Basics(), name, subclass: new List<ParamHandler.SubClass>
+                {
+                    new ParamHandler.SubClass
+                    {
+                        Name= "Mewtocol-Tcp",
+                        Properties=new List<ParamStructure.propertie>
+                        {
+                            new ParamStructure.propertie
+                            {
+                                PropertyName = "ServiceName",
+                                Description = "命名空间",
+                                Show = false,
+                                Use = false,
+                                Default = nameSpace,
+                                DataCate = null
+                            }
+                        },
+                        RGroups=new List<ParamHandler.RGroup>
+                        {
+                            new ParamHandler.RGroup
+                            {
+                                RIndex=2,
+                                RCount=1
+                            },
+                             new ParamHandler.RGroup
+                            {
+                                RIndex=6,
+                                RCount=5
+                            }
+                        }
+                    },new ParamHandler.SubClass
+                    {
+                        Name= "Mewtocol-Serial",
+                        Properties=new List<ParamStructure.propertie>
+                        {
+                            new ParamStructure.propertie
+                            {
+                                PropertyName = "ServiceName",
+                                Description = "命名空间",
+                                Show = false,
+                                Use = false,
+                                Default = nameSpace,
+                                DataCate = null
+                            }
+                        },
+                        RGroups=new List<ParamHandler.RGroup>
+                        {
+                            new ParamHandler.RGroup
+                            {
+                                RIndex=2,
+                                RCount=1
+                            },
+                             new ParamHandler.RGroup
+                            {
+                                RIndex=4,
+                                RCount=2
+                            }
+                        }
+                    }
+                });
+                return Break(SN, operateResult);
+            }
+            catch (Exception ex)
+            {
+                return Break(SN, false, ex.Message, Exception: ex);
+            }
+        }
+
+        public Task<OperateResult> GetParamAsync()
+        {
+            return Task.Run(() => GetParam());
+        }
+
+        public OperateResult CreateInstance<T>(T Basics)
+        {
+            string SN = Depart("CreateInstance");
+            try
+            {
+                //先判断对象类型是否一致
+                if (typeof(T).FullName.Equals(typeof(MewtocolData.Basics).FullName))
+                {
+                    return Break(SN, true, RData: Instance(Basics as MewtocolData.Basics));
+                }
+                else
+                {
+                    return Break(SN, false, "对象类型错误,无法创建实例");
+                }
+            }
+            catch (Exception ex)
+            {
+                return Break(SN, false, ex.Message, Exception: ex);
+            }
+        }
+
+        public Task<OperateResult> CreateInstanceAsync<T>(T Basics)
+        {
+            return Task.Run(() => CreateInstance(Basics));
+        }
+
+
+
+
+
+
+
+
 
     }
 }

+ 13 - 0
src/YSAI.Mewtocol/Properties/PublishProfiles/FolderProfile.pubxml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Release</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>..\YSAI.Publish\Release\net6.0\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <_TargetId>Folder</_TargetId>
+  </PropertyGroup>
+</Project>

+ 2 - 1
src/YSAI.Mewtocol/YSAI.Mewtocol.csproj

@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
 	<PropertyGroup>
 		<TargetFramework>net6.0</TargetFramework>
@@ -13,6 +13,7 @@
 	</PropertyGroup>
 
 	<ItemGroup>
+		<PackageReference Include="Mewtocol.NET" Version="0.8.0" />
 		<PackageReference Include="YSAI.Core" Version="1.0.0.90" />
 	</ItemGroup>
 

+ 2 - 10
src/YSAI.Mitsubishi/MitsubishiOperate.cs

@@ -924,15 +924,7 @@ namespace YSAI.Mitsubishi
         /// 实现订阅功能
         /// </summary>
         private SubscribeOperate subscribeOperate;
-        /// <summary>
-        /// 事件抛出
-        /// </summary>
-        /// <param name="sender">自定义订阅对象</param>
-        /// <param name="e">返回的参数</param>
-        private void SubscribeOperate_OnEvent(object? sender, EventResult e)
-        {
-            OnEventHandler(this, e);
-        }
+
         public OperateResult Subscribe(Address address)
         {
             string SN = Depart("Subscribe");
@@ -951,7 +943,7 @@ namespace YSAI.Mitsubishi
                         TaskHandleInterval = basics.TaskHandleInterval,
                         TaskNumber = basics.TaskNumber
                     });
-                    subscribeOperate.OnEvent += SubscribeOperate_OnEvent;
+                    subscribeOperate.OnEvent += OnEventHandler;
                     OperateResult operateResult = subscribeOperate.On();
                     return Break(SN, operateResult.State, operateResult.Message);
                 }

+ 1 - 11
src/YSAI.Modbus/ModbusOperate.cs

@@ -2137,7 +2137,7 @@ namespace YSAI.Modbus
                         TaskHandleInterval = basics.TaskHandleInterval,
                         TaskNumber = basics.TaskNumber
                     });
-                    subscribeOperate.OnEvent += SubscribeOperate_OnEvent;
+                    subscribeOperate.OnEvent += OnEventHandler;
                     OperateResult operateResult = subscribeOperate.On();
                     return Break("Subscribe", operateResult.State, operateResult.Message);
                 }
@@ -2184,16 +2184,6 @@ namespace YSAI.Modbus
             return Task.Run(() => UnSubscribe(address));
         }
 
-        /// <summary>
-        /// 事件抛出
-        /// </summary>
-        /// <param name="sender">自定义订阅对象</param>
-        /// <param name="e">返回的参数</param>
-        private void SubscribeOperate_OnEvent(object? sender, EventResult e)
-        {
-            OnEventHandler(this, e);
-        }
-
         public OperateResult GetStatus()
         {
             if (modbusMaster == null)

+ 1 - 11
src/YSAI.Omron/OmronOperate.cs

@@ -878,16 +878,6 @@ namespace YSAI.Omron
         /// </summary>
         private SubscribeOperate subscribeOperate;
 
-        /// <summary>
-        /// 事件抛出
-        /// </summary>
-        /// <param name="sender">自定义订阅对象</param>
-        /// <param name="e">返回的参数</param>
-        private void SubscribeOperate_OnEvent(object? sender, EventResult e)
-        {
-            OnEventHandler(this, e);
-        }
-
         public OperateResult Subscribe(Address address)
         {
             string SN = Depart("Subscribe");
@@ -906,7 +896,7 @@ namespace YSAI.Omron
                         TaskHandleInterval = basics.TaskHandleInterval,
                         TaskNumber = basics.TaskNumber
                     });
-                    subscribeOperate.OnEvent += SubscribeOperate_OnEvent;
+                    subscribeOperate.OnEvent += OnEventHandler;
                     OperateResult operateResult = subscribeOperate.On();
                     return Break(SN, operateResult.State, operateResult.Message);
                 }

+ 1 - 11
src/YSAI.Opc/da/http/OpcDaHttpOperate.cs

@@ -469,7 +469,7 @@ namespace YSAI.Opc.da.http
                         TaskHandleInterval = basics.TaskHandleInterval,
                         TaskNumber = basics.TaskNumber
                     });
-                    subscribeOperate.OnEvent += SubscribeOperate_OnEvent;
+                    subscribeOperate.OnEvent += OnEventHandler;
                     OperateResult operateResult = subscribeOperate.On();
                     return Break("Subscribe", operateResult.State, operateResult.Message);
                 }
@@ -516,16 +516,6 @@ namespace YSAI.Opc.da.http
             return Task.Run(() => UnSubscribe(address));
         }
 
-        /// <summary>
-        /// 事件抛出
-        /// </summary>
-        /// <param name="sender">自定义订阅对象</param>
-        /// <param name="e">返回的参数</param>
-        private void SubscribeOperate_OnEvent(object? sender, EventResult e)
-        {
-            OnEventHandler(this, e);
-        }
-
         public OperateResult GetStatus()
         {
             return Break(Depart("GetStatus"), true, "已连接");

+ 1 - 11
src/YSAI.S7/S7Operate.cs

@@ -368,7 +368,7 @@ namespace YSAI.S7
                         TaskHandleInterval = basics.TaskHandleInterval,
                         TaskNumber = basics.TaskNumber
                     });
-                    subscribeOperate.OnEvent += SubscribeOperate_OnEvent;
+                    subscribeOperate.OnEvent += OnEventHandler;
                     OperateResult operateResult = subscribeOperate.On();
                     return Break("Subscribe", operateResult.State, operateResult.Message);
                 }
@@ -415,16 +415,6 @@ namespace YSAI.S7
             return Task.Run(() => UnSubscribe(address));
         }
 
-        /// <summary>
-        /// 事件抛出
-        /// </summary>
-        /// <param name="sender">自定义订阅对象</param>
-        /// <param name="e">返回的参数</param>
-        private void SubscribeOperate_OnEvent(object? sender, EventResult e)
-        {
-            OnEventHandler(this, e);
-        }
-
         public OperateResult GetStatus()
         {
             Depart("GetStatus");

+ 119 - 111
src/YSAI.Test.Console/Program.cs

@@ -1,67 +1,75 @@
 
-//using YSAI.Beckhoff;
-//using YSAI.Can;
-//using YSAI.Core.data;
-//using YSAI.DB;
-//using YSAI.Kafka;
-//using YSAI.Log;
-//using YSAI.Mitsubishi;
-//using YSAI.Modbus;
-//using YSAI.Mqtt.client;
-//using YSAI.NetMQ;
-//using YSAI.Netty.client;
-//using YSAI.Omron;
-//using YSAI.Opc.da.client;
-//using YSAI.Opc.da.http;
-//using YSAI.Opc.ua.client;
-//using YSAI.RabbitMQ;
-//using YSAI.S7;
-//using YSAI.Unility;
+using YSAI.AllenBradley;
+using YSAI.Beckhoff;
+using YSAI.Can;
+using YSAI.Core.data;
+using YSAI.DB;
+using YSAI.Kafka;
+using YSAI.Log;
+using YSAI.Mewtocol;
+using YSAI.Mitsubishi;
+using YSAI.Modbus;
+using YSAI.Mqtt.client;
+using YSAI.NetMQ;
+using YSAI.Netty.client;
+using YSAI.Omron;
+using YSAI.Opc.da.client;
+using YSAI.Opc.da.http;
+using YSAI.Opc.ua.client;
+using YSAI.RabbitMQ;
+using YSAI.S7;
+using YSAI.Unility;
+
+OperateResult operateResult = new BeckhoffOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"BeckhoffOperate.log");
+
+operateResult = new CanOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"CanOperate.log");
 
-//OperateResult operateResult = new BeckhoffOperate().GetParam();
-//LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"BeckhoffOperate.log");
+operateResult = new DBOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"DBOperate.log");
 
-//operateResult = new CanOperate().GetParam();
-//LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"CanOperate.log");
+operateResult = new ModbusOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"ModbusOperate.log");
 
-//operateResult = new DBOperate().GetParam();
-//LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"DBOperate.log");
+operateResult = new OpcUaClientOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"OpcUaClientOperate.log");
 
-//operateResult = new ModbusOperate().GetParam();
-//LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"ModbusOperate.log");
+operateResult = new OpcDaClientOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"OpcDaClientOperate.log");
 
-//operateResult = new OpcUaClientOperate().GetParam();
-//LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"OpcUaClientOperate.log");
+operateResult = new OpcDaHttpOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"OpcDaHttpOperate.log");
 
-//operateResult = new OpcDaClientOperate().GetParam();
-//LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"OpcDaClientOperate.log");
+operateResult = new S7Operate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"S7Operate.log");
 
-//operateResult = new OpcDaHttpOperate().GetParam();
-//LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"OpcDaHttpOperate.log");
+operateResult = new KafkaOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"KafkaOperate.log");
 
-//operateResult = new S7Operate().GetParam();
-//LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"S7Operate.log");
+operateResult = new MqttClientOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"MqttClientOperate.log");
 
-//operateResult = new KafkaOperate().GetParam();
-//LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"KafkaOperate.log");
+operateResult = new NettyClientOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"NettyClientOperate.log");
 
-//operateResult = new MqttClientOperate().GetParam();
-//LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"MqttClientOperate.log");
+operateResult = new RabbitMQOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"RabbitMQOperate.log");
 
-//operateResult = new NettyClientOperate().GetParam();
-//LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"NettyClientOperate.log");
+operateResult = new MitsubishiOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"MitsubishiOperate.log");
 
-//operateResult = new RabbitMQOperate().GetParam();
-//LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"RabbitMQOperate.log");
+operateResult = new OmronOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"OmronOperate.log");
 
-//operateResult = new MitsubishiOperate().GetParam();
-//LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"MitsubishiOperate.log");
+operateResult = new NetMQOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"NetMQOperate.log");
 
-//operateResult = new OmronOperate().GetParam();
-//LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"OmronOperate.log");
+operateResult = new AllenBradleyOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"AllenBradleyOperate.log");
 
-//operateResult = new NetMQOperate().GetParam();
-//LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"NetMQOperate.log");
+operateResult = new MewtocolOperate().GetParam();
+LogHelper.Verbose(operateResult.RData.ToJson().JsonFormatting(), $"MewtocolOperate.log");
 
 //using System.Collections.Concurrent;
 //using YSAI.Beckhoff;
@@ -355,71 +363,71 @@
 //    LogHelper.Info(result.ToJson().JsonFormatting());
 //}
 
-using S7.Net;
-using System.Collections.Concurrent;
-using YSAI.Core.data;
-using YSAI.Core.@enum;
-using YSAI.S7;
-using YSAI.Unility;
+//using S7.Net;
+//using System.Collections.Concurrent;
+//using YSAI.Core.data;
+//using YSAI.Core.@enum;
+//using YSAI.S7;
+//using YSAI.Unility;
+
+//S7Operate s7ClientOperate = S7Operate.Instance(new S7Data.Basics()
+//{
+//    Ip = "192.168.2.20",
+//    Port = 102,
+//    Rack = 0,
+//    Slot = 1,
+//    S7CpuType = CpuType.S71200,
+//    ChangeOut = true,
+//    HandleInterval = 1000,
+//    SN = Guid.NewGuid().ToString()
+//}); ;
 
-S7Operate s7ClientOperate = S7Operate.Instance(new S7Data.Basics()
-{
-    Ip = "192.168.2.20",
-    Port = 102,
-    Rack = 0,
-    Slot = 1,
-    S7CpuType = CpuType.S71200,
-    ChangeOut = true,
-    HandleInterval = 1000,
-    SN = Guid.NewGuid().ToString()
-}); ;
+////打开
+//OperateResult operateResult = s7ClientOperate.On();
+//Console.WriteLine(operateResult.Message);
 
-//打开
-OperateResult operateResult = s7ClientOperate.On();
-Console.WriteLine(operateResult.Message);
-
-//点位地址
-Address address = new Address();
-address.SN = Guid.NewGuid().ToString();
-address.CreationTime = DateTime.Now.ToLocalTime();
-address.AddressArray = new List<AddressDetails>();
-address.AddressArray.Add(new AddressDetails()
-{
-    AddressName = "DB71.DBD4",
-    AddressDataType = YSAI.Core.@enum.DataType.Uint,
-    AddressType = AddressType.Reality
-});
-
-//读取
-operateResult = s7ClientOperate.Read(address);
-Console.WriteLine(operateResult.Message);
-if (operateResult.State)
-{
-    foreach (var item in operateResult.RData as ConcurrentDictionary<string, AddressValue>)
-    {
-        Console.WriteLine(item.Key);
-        Console.WriteLine(item.Value.Value);
-    }
-}
-
-//订阅
-s7ClientOperate.OnEvent += S7ClientOperate_OnEvent;
-s7ClientOperate.Subscribe(address);
-
-while (true)
-{
-    string value = Console.ReadLine();
-    //写入
-    ConcurrentDictionary<string, uint> keyValuePairs = new ConcurrentDictionary<string, uint>();
-    keyValuePairs.TryAdd("DB71.DBD4", string.IsNullOrWhiteSpace(value) ? uint.MaxValue : uint.Parse(value));
-    operateResult = s7ClientOperate.Write(keyValuePairs);
-    Console.WriteLine(operateResult.Message);
-}
-
-void S7ClientOperate_OnEvent(object? sender, EventResult e)
-{
-    Console.WriteLine(e.ToJson());
-}
+////点位地址
+//Address address = new Address();
+//address.SN = Guid.NewGuid().ToString();
+//address.CreationTime = DateTime.Now.ToLocalTime();
+//address.AddressArray = new List<AddressDetails>();
+//address.AddressArray.Add(new AddressDetails()
+//{
+//    AddressName = "DB71.DBD4",
+//    AddressDataType = YSAI.Core.@enum.DataType.Uint,
+//    AddressType = AddressType.Reality
+//});
+
+////读取
+//operateResult = s7ClientOperate.Read(address);
+//Console.WriteLine(operateResult.Message);
+//if (operateResult.State)
+//{
+//    foreach (var item in operateResult.RData as ConcurrentDictionary<string, AddressValue>)
+//    {
+//        Console.WriteLine(item.Key);
+//        Console.WriteLine(item.Value.Value);
+//    }
+//}
+
+////订阅
+//s7ClientOperate.OnEvent += S7ClientOperate_OnEvent;
+//s7ClientOperate.Subscribe(address);
+
+//while (true)
+//{
+//    string value = Console.ReadLine();
+//    //写入
+//    ConcurrentDictionary<string, uint> keyValuePairs = new ConcurrentDictionary<string, uint>();
+//    keyValuePairs.TryAdd("DB71.DBD4", string.IsNullOrWhiteSpace(value) ? uint.MaxValue : uint.Parse(value));
+//    operateResult = s7ClientOperate.Write(keyValuePairs);
+//    Console.WriteLine(operateResult.Message);
+//}
+
+//void S7ClientOperate_OnEvent(object? sender, EventResult e)
+//{
+//    Console.WriteLine(e.ToJson());
+//}
 
 //WsServiceOperate wsServiceOperate = WsServiceOperate.Instance(new WsServiceData.Basics
 //{

+ 2 - 0
src/YSAI.Test.Console/YSAI.Test.Console.csproj

@@ -9,10 +9,12 @@
   </PropertyGroup>
 
 	<ItemGroup>
+		<ProjectReference Include="..\YSAI.AllenBradley\YSAI.AllenBradley.csproj" />
 		<ProjectReference Include="..\YSAI.Beckhoff\YSAI.Beckhoff.csproj" />
 		<ProjectReference Include="..\YSAI.Can\YSAI.Can.csproj" />
 		<ProjectReference Include="..\YSAI.DB\YSAI.DB.csproj" />
 		<ProjectReference Include="..\YSAI.Kafka\YSAI.Kafka.csproj" />
+		<ProjectReference Include="..\YSAI.Mewtocol\YSAI.Mewtocol.csproj" />
 		<ProjectReference Include="..\YSAI.Mitsubishi\YSAI.Mitsubishi.csproj" />
 		<ProjectReference Include="..\YSAI.Modbus\YSAI.Modbus.csproj" />
 		<ProjectReference Include="..\YSAI.Mqtt\YSAI.Mqtt.csproj" />