lixun 2 роки тому
батько
коміт
621f2fc609

+ 28 - 34
src/YSAI.DAQ/YSAI.Core/config/ReflectionConfig.json

@@ -1,40 +1,34 @@
 {
-    "DllDatas": [
+  "DllDatas": [
+    {
+      "DllPath": "YSAI.RelayManage.dll",
+      "IsAbsolutePath": false,
+      "NamespaceDatas": [
         {
-            "DllPath": "YSAI.RelayManage.dll",
-            "IsAbsolutePath": false,
-            "NamespaceDatas": [
+          "Namespace": "YSAI.RelayManage",
+          "ClassDatas": [
+            {
+              "SN": "YSAI.RelayManage.RelayManageOperate[Instance]",
+              "ClassName": "RelayManageOperate",
+              "ConstructorParam": null,
+              "MethodDatas": [
                 {
-                    "Namespace": "YSAI.RelayManage",
-                    "ClassDatas": [
-                        {
-                            "SN": "YSAI.RelayManage.RelayManageOperate[Instance]",
-                            "ClassName": "RelayManageOperate",
-                            "ConstructorParam": null,
-                            "MethodDatas": [
-                                {
-                                    "SN": "[Produce]",
-                                    "WhetherExecute": false,
-                                    "MethodName": "Produce",
-                                    "MethodParam": null
-                                },
-                                {
-                                    "SN": "[Dispose]",
-                                    "WhetherExecute": false,
-                                    "MethodName": "Dispose",
-                                    "MethodParam": null
-                                }
-                            ],
-                            "EventDatas": [
-                                {
-                                    "SN": "[OnEvent]",
-                                    "EventName": "OnEvent"
-                                }
-                            ]
-                        }
-                    ]
+                  "SN": "[Produce]",
+                  "WhetherExecute": false,
+                  "MethodName": "Produce",
+                  "MethodParam": null
                 }
-            ]
+              ],
+              "EventDatas": [
+                {
+                  "SN": "[OnEvent]",
+                  "EventName": "OnEvent"
+                }
+              ]
+            }
+          ]
         }
-    ]
+      ]
+    }
+  ]
 }

+ 2 - 14
src/YSAI.DAQ/YSAI.Core/data/AddressHandler.cs

@@ -28,7 +28,7 @@ namespace YSAI.Core.data
         /// <summary>
         /// 反射操作
         /// </summary>
-        public static ReflectionOperate reflectionOperate = ReflectionOperate.Instance();
+        public readonly static ReflectionOperate reflectionOperate = ReflectionOperate.Instance();
 
         /// <summary>
         /// 动态对象,用于转发失败存入本地记录
@@ -74,18 +74,6 @@ namespace YSAI.Core.data
             return null;
         }
 
-        /// <summary>
-        /// 执行数据解析
-        /// 收到的底层数据,调用此方法,直接返回
-        /// </summary>
-        /// <param name="addressDetails">地址详情数据</param>
-        /// <param name="value">底层硬件返回的值</param>
-        /// <returns></returns>
-        public static Task<AddressValue?> ExecuteAsync(AddressDetails addressDetails, string value)
-        {
-            return Task.Run(() => Execute(addressDetails, value));
-        }
-
         /// <summary>
         /// 数据解析
         /// </summary>
@@ -212,7 +200,7 @@ namespace YSAI.Core.data
             {
                 if (!eventResult.State)
                 {
-                    LogHelper.Error(eventResult.ToJson(), logName);
+                    LogHelper.Error(eventResult.ToJson().JsonFormatting(), logName);
                 }
             }
         }

+ 4 - 0
src/YSAI.DAQ/YSAI.Core/enum/Enums.cs

@@ -159,6 +159,10 @@ namespace YSAI.Core.@enum
         /// </summary>
         Enum,
         /// <summary>
+        /// 包罗万象
+        /// </summary>
+        All,
+        /// <summary>
         /// 无返回参数
         /// </summary>
         NULL

+ 30 - 3
src/YSAI.DAQ/YSAI.Core/reflection/ReflectionOperate.cs

@@ -189,6 +189,10 @@ namespace YSAI.Core.reflection
         /// value (个个Dll反射的结果)
         /// </summary>
         private ConcurrentDictionary<string, ReflectionEventResult> EventIocContainer = new ConcurrentDictionary<string, ReflectionEventResult>();
+        /// <summary>
+        /// 对象容器
+        /// </summary>
+        private ConcurrentDictionary<string, object> ObjectIocContainer = new ConcurrentDictionary<string, object>();
 
         /// <summary>
         /// 初始化
@@ -229,6 +233,13 @@ namespace YSAI.Core.reflection
                             {
                                 //创建该对象的实例
                                 object? instanceObject = CreateInstance(NamespaceAndClassNameType, ClassData.ConstructorParam);
+                                if (instanceObject != null)
+                                {
+                                    if (!ObjectIocContainer.ContainsKey(NamespaceAndClassNameType.FullName))
+                                    {
+                                        ObjectIocContainer.TryAdd(NamespaceAndClassNameType.FullName, instanceObject);
+                                    }
+                                }
                                 if (ClassData.MethodDatas != null)
                                 {
                                     //遍历方法
@@ -241,7 +252,7 @@ namespace YSAI.Core.reflection
                                             //结果数据
                                             ReflectionMethodResult reflectResult = new ReflectionMethodResult()
                                             {
-                                                InstanceObject = instanceObject,
+                                                InstanceObject = ObjectIocContainer[NamespaceAndClassNameType.FullName],
                                                 Method = methodInfo
                                             };
                                             //存在直接更新,不存在新增
@@ -251,7 +262,7 @@ namespace YSAI.Core.reflection
                                             if (MethodData.WhetherExecute)
                                             {
                                                 //执行此函数,不管返回结果
-                                                methodInfo?.Invoke(instanceObject, ParamTypeConvert(MethodData.MethodParam, methodInfo));
+                                                methodInfo?.Invoke(ObjectIocContainer[NamespaceAndClassNameType.FullName], ParamTypeConvert(MethodData.MethodParam, methodInfo));
                                             }
                                         }
                                         else
@@ -272,7 +283,7 @@ namespace YSAI.Core.reflection
                                             //结果数据
                                             ReflectionEventResult reflectResult = new ReflectionEventResult()
                                             {
-                                                InstanceObject = instanceObject,
+                                                InstanceObject = ObjectIocContainer[NamespaceAndClassNameType.FullName],
                                                 Event = eventInfo
                                             };
                                             //存在直接更新,不存在新增
@@ -517,6 +528,21 @@ namespace YSAI.Core.reflection
             }
         }
 
+
+        /// <summary>
+        /// 获取反射的实例
+        /// </summary>
+        /// <param name="SN"></param>
+        /// <returns></returns>
+        public object? ReflectionInstance(string SN = "YSAI.RelayManage.RelayManageOperate")
+        {
+            if (ObjectIocContainer.Count > 0)
+            {
+                return ObjectIocContainer[SN];
+            }
+            return null;
+        }
+
         /// <summary>
         /// 获取所有事件
         /// </summary>
@@ -545,6 +571,7 @@ namespace YSAI.Core.reflection
 
         public void Dispose()
         {
+            ObjectIocContainer.Clear();
             MethodIocContainer.Clear();
             EventIocContainer.Clear();
             GC.Collect();

+ 15 - 0
src/YSAI.DAQ/YSAI.DaqManage/DaqManageData.cs

@@ -41,6 +41,21 @@ namespace YSAI.DaqManage
             /// 接口名称
             /// </summary>
             public string? InterfaceFullName { get; set; } = "YSAI.Core.interface.unify.IDaq";
+
+            /// <summary>
+            /// 配置监控格式
+            /// </summary>
+            public string? ConfigWatcherFormat { get; set; } = "*.Daq.Config.json";
+
+            /// <summary>
+            /// 配置替换格式
+            /// </summary>
+            public string? ConfigReplaceFormat { get; set; } = ".Daq.Config.json";
+
+            /// <summary>
+            /// 自动打开,创建实例成功后
+            /// </summary>
+            public bool AutoOn { get; set; } = true;
         }
     }
 }

+ 171 - 48
src/YSAI.DAQ/YSAI.DaqManage/DaqManageOperate.cs

@@ -1,5 +1,4 @@
 using Newtonsoft.Json.Linq;
-using StackExchange.Redis;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
@@ -13,6 +12,7 @@ using System.Text;
 using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using YSAI.Core.data;
+using YSAI.Core.@enum;
 using YSAI.Core.@interface.unify;
 using YSAI.Unility;
 
@@ -156,6 +156,11 @@ namespace YSAI.DaqManage
                     //检索
                     Search();
 
+                    //创建文件
+                    if (!Directory.Exists(basics.LibFolder))
+                    {
+                        Directory.CreateDirectory(basics.LibFolder);
+                    }
                     //文件夹监控
                     watcherLibFolder = new FileSystemWatcher(basics.LibFolder);
                     //监控的配置
@@ -167,11 +172,15 @@ namespace YSAI.DaqManage
                     //启动监听
                     watcherLibFolder.EnableRaisingEvents = true;
 
-
+                    //创建文件
+                    if (!Directory.Exists(basics.LibConfigFolder))
+                    {
+                        Directory.CreateDirectory(basics.LibConfigFolder);
+                    }
                     //文件夹监视
                     watcherLibConfigFolder = new FileSystemWatcher(basics.LibConfigFolder);
                     //监控的配置
-                    watcherLibConfigFolder.Filter = ".*.Config-*.json";
+                    watcherLibConfigFolder.Filter = basics.ConfigWatcherFormat;
                     //当文件夹中新增文件
                     watcherLibConfigFolder.Created += delegate (object sender, FileSystemEventArgs e) { Watcher_Created(sender, e, 1); };
                     //当文件夹中删除文件
@@ -195,17 +204,17 @@ namespace YSAI.DaqManage
         private void Watcher_Deleted(object sender, FileSystemEventArgs e, int Type)
         {
             //程序集SN
-            string TypeSN = string.Empty;
+            string TypeIocSN = string.Empty;
             switch (Type)
             {
                 case 0:
                     OnEventHandler?.Invoke(this, new EventResult(true, $"{e.Name} 文件被删除,移除此库程序集,并移除所有实例"));
                     //程序集SN
-                    TypeSN = e.Name.Replace(".dll", string.Empty);
+                    TypeIocSN = e.Name.Replace(".dll", string.Empty);
 
                     foreach (var item in InstanceIoc)
                     {
-                        if (item.Key.Contains(TypeSN))
+                        if (item.Key.Contains(TypeIocSN))
                         {
                             InstanceIoc[item.Key].Dispose();
                             if (InstanceIoc.Remove(item.Key, out _))
@@ -221,7 +230,7 @@ namespace YSAI.DaqManage
 
                     foreach (var item in TypeIoc)
                     {
-                        if (item.Key.Contains(TypeSN))
+                        if (item.Key.Contains(TypeIocSN))
                         {
                             if (TypeIoc.Remove(item.Key, out _))
                             {
@@ -236,31 +245,26 @@ namespace YSAI.DaqManage
                     break;
                 case 1:
                     OnEventHandler?.Invoke(this, new EventResult(true, $"{e.Name} 文件被删除,移除对应配置实例"));
+                    //实例的SN
+                    string InstanceIocSN = e.Name.Replace(basics.ConfigReplaceFormat, string.Empty);
                     //程序集SN
-                    TypeSN = e.Name.Split('-')[0].Replace(".Config", string.Empty);
-                    //分割
-                    string[] strs = e.Name.Split('-');
-                    if (strs.Length > 1)
+                    TypeIocSN = InstanceIocSN.Replace($".{InstanceIocSN.Split('.')[InstanceIocSN.Split('.').Length - 1]}", string.Empty);
+                    if (InstanceIoc.ContainsKey(InstanceIocSN))
                     {
-                        //获取配置实例SN
-                        string SN = $"{TypeSN}:{e.Name.Split('-')[1].Split('.')[0]}";
-                        if (InstanceIoc.ContainsKey(SN))
+                        InstanceIoc[InstanceIocSN].Dispose();
+                        if (InstanceIoc.Remove(InstanceIocSN, out _))
                         {
-                            InstanceIoc[SN].Dispose();
-                            if (InstanceIoc.Remove(SN, out _))
-                            {
-                                OnEventHandler?.Invoke(this, new EventResult(true, $"{e.Name} 移除配置实例成功"));
-                            }
-                            else
-                            {
-                                OnEventHandler?.Invoke(this, new EventResult(false, $"{e.Name} 移除配置实例失败"));
-                            }
+                            OnEventHandler?.Invoke(this, new EventResult(true, $"{e.Name} 移除配置实例成功"));
                         }
                         else
                         {
-                            OnEventHandler?.Invoke(this, new EventResult(false, $"{e.Name} 移除配置实例失败 {TypeSN} 实例不存在"));
+                            OnEventHandler?.Invoke(this, new EventResult(false, $"{e.Name} 移除配置实例失败"));
                         }
                     }
+                    else
+                    {
+                        OnEventHandler?.Invoke(this, new EventResult(false, $"{e.Name} 移除配置实例失败 {TypeIocSN} 实例不存在"));
+                    }
                     break;
             }
         }
@@ -303,31 +307,26 @@ namespace YSAI.DaqManage
                                 srdPreview.Close();
                                 srdPreview.Dispose();
 
-                                //获取程序集SN
-                                string TypeSN = e.Name.Split('-')[0].Replace(".Config", string.Empty);
-                                //分割
-                                string[] strs = e.Name.Split('-');
-                                if (strs.Length > 1)
+                                //实例的SN
+                                string InstanceIocSN = e.Name.Replace(basics.ConfigReplaceFormat, string.Empty);
+                                //程序集SN
+                                string TypeIocSN = InstanceIocSN.Replace($".{InstanceIocSN.Split('.')[InstanceIocSN.Split('.').Length - 1]}", string.Empty);
+                                //判断是否存在此程序集SN
+                                if (TypeIoc.ContainsKey(TypeIocSN))
                                 {
-                                    //获取配置实例SN
-                                    string SN = $"{TypeSN}:{strs[1].Split('.')[0]}";
-                                    //判断是否存在此程序集SN
-                                    if (TypeIoc.ContainsKey(TypeSN))
+                                    if (!InstanceIoc.ContainsKey(InstanceIocSN))
                                     {
-                                        if (!InstanceIoc.ContainsKey(SN))
-                                        {
-                                            ConfigCreateInstance(TypeIoc[TypeSN], temp);
-                                        }
-                                        else
-                                        {
-                                            OnEventHandler?.Invoke(this, new EventResult(false, $" {e.Name} 此配置实例已存在"));
-                                        }
+                                        ConfigCreateInstance(TypeIoc[TypeIocSN], temp);
                                     }
                                     else
                                     {
-                                        OnEventHandler?.Invoke(this, new EventResult(false, $" {e.Name} 新增对应配置创建实例失败 {TypeSN} 程序集不存在"));
+                                        OnEventHandler?.Invoke(this, new EventResult(false, $" {e.Name} 此配置实例已存在"));
                                     }
                                 }
+                                else
+                                {
+                                    OnEventHandler?.Invoke(this, new EventResult(false, $" {e.Name} 新增对应配置创建实例失败 {TypeIocSN} 程序集不存在"));
+                                }
                                 fs.Close();
                                 fs.Dispose();
                             }
@@ -432,23 +431,35 @@ namespace YSAI.DaqManage
             //获取结构参数
             JObject? jsonObject = Newtonsoft.Json.JsonConvert.DeserializeObject<JObject>(content);
             //获取唯一标识符
-            string SN = $"{type.FullName}.{jsonObject[basics.LibConfigSNKey]}";
+            string InstanceIocSN = $"{type.FullName}.{jsonObject[basics.LibConfigSNKey]}";
             //获取实例
             IDaq? instance = CreateInstance(type, new object[] { jsonObject }) as IDaq;
             //实例不为空
             if (instance != null)
             {
                 //把这个实例添加到容器中
-                InstanceIoc.TryAdd(SN, instance);
+                InstanceIoc.TryAdd(InstanceIocSN, instance);
                 //事件注册
                 instance.OnEvent += Instance_OnEvent;
-                //抛出信息
-                OnEventHandler?.Invoke(this, new EventResult(true, $"{SN} 实例创建成功"));
+
+                //自动打开
+                if (basics.AutoOn)
+                {
+                    //执行打开方法
+                    OperateResult operateResult = instance.On();
+                    //抛出信息
+                    OnEventHandler?.Invoke(this, new EventResult(operateResult.State, $"{InstanceIocSN} 实例创建成功,自动打开{(operateResult.State ? "成功" : "失败")}"));
+                }
+                else
+                {
+                    //抛出信息
+                    OnEventHandler?.Invoke(this, new EventResult(true, $"{InstanceIocSN} 实例创建成功"));
+                }
             }
             else
             {
                 //抛出信息
-                OnEventHandler?.Invoke(this, new EventResult(false, $"{SN} 实例创建失败"));
+                OnEventHandler?.Invoke(this, new EventResult(false, $"{InstanceIocSN} 实例创建失败"));
             }
         }
         /// <summary>
@@ -591,7 +602,7 @@ namespace YSAI.DaqManage
             }
             catch (Exception ex)
             {
-                return Break("Dispose", false,ex.Message);
+                return Break("Dispose", false, ex.Message);
             }
         }
         /// <summary>
@@ -603,6 +614,19 @@ namespace YSAI.DaqManage
         {
             return Task.Run(() => Dispose(SN));
         }
+
+        /// <summary>
+        /// 实例列表
+        /// </summary>
+        /// <returns>实例数组</returns>
+        public List<string>? InstanceList()
+        {
+            if (InstanceIoc != null)
+            {
+                return InstanceIoc.Keys.ToList();
+            }
+            return null;
+        }
         /// <summary>
         /// 移除实例
         /// </summary>
@@ -785,6 +809,7 @@ namespace YSAI.DaqManage
         {
             return Task.Run(() => UnSubscribe(address, SN));
         }
+        
         /// <summary>
         /// 打开
         /// </summary>
@@ -819,6 +844,55 @@ namespace YSAI.DaqManage
             }
         }
         /// <summary>
+        /// 打开所有
+        /// </summary>
+        /// <param name="SN">实例的唯一标识符</param>
+        /// <returns>统一出参</returns>
+        public Task<OperateResult> OnAllAsync()
+        {
+            return Task.Run(() => OnAll());
+        }
+        /// <summary>
+        /// 打开所有
+        /// </summary>
+        /// <param name="SN">实例的唯一标识符</param>
+        /// <returns>统一出参</returns>
+        public OperateResult OnAll()
+        {
+            Depart("OnAll");
+            try
+            {
+                if (InstanceIoc != null && InstanceIoc.Count > 0)
+                {
+                    List<string> FailMessage = new List<string>();
+                    foreach (var item in InstanceIoc)
+                    {
+                        OperateResult operateResult = item.Value.On();
+                        if (!operateResult.State)
+                        {
+                            FailMessage.Add(operateResult.Message);
+                        }
+                    }
+                    if (FailMessage.Count > 0)
+                    {
+                        return Break("OnAll", false, $"存在{FailMessage.Count}个异常信息,请查看RData", FailMessage, ResultType.All);
+                    }
+                    else
+                    {
+                        return Break("OnAll", true);
+                    }
+                }
+                else
+                {
+                    return Break("OnAll", false, "实例为空");
+                }
+            }
+            catch (Exception ex)
+            {
+                return Break("OnAll", false, ex.Message);
+            }
+        }
+        /// <summary>
         /// 关闭
         /// </summary>
         /// <param name="SN">实例的唯一标识符</param>
@@ -851,5 +925,54 @@ namespace YSAI.DaqManage
                 return Break("Off", false, ex.Message);
             }
         }
+        /// <summary>
+        /// 关闭所有
+        /// </summary>
+        /// <param name="SN">实例的唯一标识符</param>
+        /// <returns>统一出参</returns>
+        public Task<OperateResult> OffAllAsync()
+        {
+            return Task.Run(() => OffAll());
+        }
+        /// <summary>
+        /// 关闭所有
+        /// </summary>
+        /// <param name="SN">实例的唯一标识符</param>
+        /// <returns>统一出参</returns>
+        public OperateResult OffAll()
+        {
+            Depart("OffAll");
+            try
+            {
+                if (InstanceIoc != null && InstanceIoc.Count > 0)
+                {
+                    List<string> FailMessage = new List<string>();
+                    foreach (var item in InstanceIoc)
+                    {
+                        OperateResult operateResult = item.Value.Off();
+                        if (!operateResult.State)
+                        {
+                            FailMessage.Add(operateResult.Message);
+                        }
+                    }
+                    if (FailMessage.Count > 0)
+                    {
+                        return Break("OffAll", false, $"存在{FailMessage.Count}个异常信息,请查看RData", FailMessage, ResultType.All);
+                    }
+                    else
+                    {
+                        return Break("OffAll", true);
+                    }
+                }
+                else
+                {
+                    return Break("OffAll", false, "实例为空");
+                }
+            }
+            catch (Exception ex)
+            {
+                return Break("OffAll", false, ex.Message);
+            }
+        }
     }
 }

+ 0 - 2
src/YSAI.DAQ/YSAI.Manage.Core/base/ManageBaseOperate.cs

@@ -37,8 +37,6 @@ namespace YSAI.Manage.Core.@base
 
         private static List<ManageBaseOperate> ThisObjList = new List<ManageBaseOperate>(); //自身对象集合
 
-        
-
         /// <summary>
         /// 数据库采集对象集合
         /// </summary>

+ 17 - 1
src/YSAI.DAQ/YSAI.RelayManage/RelayManageData.cs

@@ -31,13 +31,28 @@ namespace YSAI.RelayManage
             /// 配置文件名称的格式 * 与配置数据中的SN一致
             /// 库配置:命名空间 + 类名.SN.Config.json
             /// </summary>
-            public string? ConfigFileNameFormat { get; set; } = "{0}.*.Config.json";
+            public string? ConfigFileNameFormat { get; set; } = "{0}.*.Relay.Config.json";
+
+            /// <summary>
+            /// 配置监控格式
+            /// </summary>
+            public string? ConfigWatcherFormat { get; set; } = "*.Relay.Config.json";
+
+            /// <summary>
+            /// 配置替换格式
+            /// </summary>
+            public string? ConfigReplaceFormat { get; set; } = ".Relay.Config.json";
 
             /// <summary>
             /// 接口名称
             /// </summary>
             public string? InterfaceFullName { get; set; } = "YSAI.Core.interface.unify.IRelay";
 
+            /// <summary>
+            /// 自动打开,创建实例成功后
+            /// </summary>
+            public bool AutoOn { get; set; } = true;
+
             /// <summary>
             /// 任务处理数量
             /// </summary>
@@ -48,6 +63,7 @@ namespace YSAI.RelayManage
             /// </summary>
             [Description("任务处理完成休眠时间(毫秒)")]
             public int TaskHandleAccomplishSleepTime { get; set; } = 500;
+            
         }
     }
 }

+ 177 - 46
src/YSAI.DAQ/YSAI.RelayManage/RelayManageOperate.cs

@@ -178,6 +178,11 @@ namespace YSAI.RelayManage
                     //检索
                     Search();
 
+                    //创建文件
+                    if (!Directory.Exists(basics.LibFolder))
+                    {
+                        Directory.CreateDirectory(basics.LibFolder);
+                    }
                     //文件夹监控
                     watcherLibFolder = new FileSystemWatcher(basics.LibFolder);
                     //监控的配置
@@ -189,11 +194,15 @@ namespace YSAI.RelayManage
                     //启动监听
                     watcherLibFolder.EnableRaisingEvents = true;
 
-
+                    //创建文件
+                    if (!Directory.Exists(basics.LibConfigFolder))
+                    {
+                        Directory.CreateDirectory(basics.LibConfigFolder);
+                    }
                     //文件夹监视
                     watcherLibConfigFolder = new FileSystemWatcher(basics.LibConfigFolder);
                     //监控的配置
-                    watcherLibConfigFolder.Filter = ".*.Config.json";
+                    watcherLibConfigFolder.Filter = basics.ConfigWatcherFormat;
                     //当文件夹中新增文件
                     watcherLibConfigFolder.Created += delegate (object sender, FileSystemEventArgs e) { Watcher_Created(sender, e, 1); };
                     //当文件夹中删除文件
@@ -217,17 +226,17 @@ namespace YSAI.RelayManage
         private void Watcher_Deleted(object sender, FileSystemEventArgs e, int Type)
         {
             //程序集SN
-            string TypeSN = string.Empty;
+            string TypeIocSN = string.Empty;
             switch (Type)
             {
                 case 0:
                     OnEventHandler?.Invoke(this, new EventResult(true, $"{e.Name} 文件被删除,移除此库程序集,并移除所有实例"));
                     //程序集SN
-                    TypeSN = e.Name.Replace(".dll", string.Empty);
+                    TypeIocSN = e.Name.Replace(".dll", string.Empty);
 
                     foreach (var item in InstanceIoc)
                     {
-                        if (item.Key.Contains(TypeSN))
+                        if (item.Key.Contains(TypeIocSN))
                         {
                             InstanceIoc[item.Key].Dispose();
                             if (InstanceIoc.Remove(item.Key, out _))
@@ -243,7 +252,7 @@ namespace YSAI.RelayManage
 
                     foreach (var item in TypeIoc)
                     {
-                        if (item.Key.Contains(TypeSN))
+                        if (item.Key.Contains(TypeIocSN))
                         {
                             if (TypeIoc.Remove(item.Key, out _))
                             {
@@ -258,31 +267,26 @@ namespace YSAI.RelayManage
                     break;
                 case 1:
                     OnEventHandler?.Invoke(this, new EventResult(true, $"{e.Name} 文件被删除,移除对应配置实例"));
+                    //实例的SN
+                    string InstanceIocSN = e.Name.Replace(basics.ConfigReplaceFormat, string.Empty);
                     //程序集SN
-                    TypeSN = e.Name.Split('-')[0].Replace(".Config", string.Empty);
-                    //分割
-                    string[] strs = e.Name.Split('-');
-                    if (strs.Length > 1)
+                    TypeIocSN = InstanceIocSN.Replace($".{InstanceIocSN.Split('.')[InstanceIocSN.Split('.').Length - 1]}", string.Empty);
+                    if (InstanceIoc.ContainsKey(InstanceIocSN))
                     {
-                        //获取配置实例SN
-                        string SN = $"{TypeSN}:{e.Name.Split('-')[1].Split('.')[0]}";
-                        if (InstanceIoc.ContainsKey(SN))
+                        InstanceIoc[InstanceIocSN].Dispose();
+                        if (InstanceIoc.Remove(InstanceIocSN, out _))
                         {
-                            InstanceIoc[SN].Dispose();
-                            if (InstanceIoc.Remove(SN, out _))
-                            {
-                                OnEventHandler?.Invoke(this, new EventResult(true, $"{e.Name} 移除配置实例成功"));
-                            }
-                            else
-                            {
-                                OnEventHandler?.Invoke(this, new EventResult(false, $"{e.Name} 移除配置实例失败"));
-                            }
+                            OnEventHandler?.Invoke(this, new EventResult(true, $"{e.Name} 移除配置实例成功"));
                         }
                         else
                         {
-                            OnEventHandler?.Invoke(this, new EventResult(false, $"{e.Name} 移除配置实例失败 {TypeSN} 实例不存在"));
+                            OnEventHandler?.Invoke(this, new EventResult(false, $"{e.Name} 移除配置实例失败"));
                         }
                     }
+                    else
+                    {
+                        OnEventHandler?.Invoke(this, new EventResult(false, $"{e.Name} 移除配置实例失败 {TypeIocSN} 实例不存在"));
+                    }
                     break;
             }
         }
@@ -325,31 +329,26 @@ namespace YSAI.RelayManage
                                 srdPreview.Close();
                                 srdPreview.Dispose();
 
-                                //获取程序集SN
-                                string TypeSN = e.Name.Split('-')[0].Replace(".Config", string.Empty);
-                                //分割
-                                string[] strs = e.Name.Split('-');
-                                if (strs.Length > 1)
+                                //实例的SN
+                                string InstanceIocSN = e.Name.Replace(basics.ConfigReplaceFormat, string.Empty);
+                                //程序集SN
+                                string TypeIocSN = InstanceIocSN.Replace($".{InstanceIocSN.Split('.')[InstanceIocSN.Split('.').Length - 1]}", string.Empty);
+                                //判断是否存在此程序集SN
+                                if (TypeIoc.ContainsKey(TypeIocSN))
                                 {
-                                    //获取配置实例SN
-                                    string SN = $"{TypeSN}:{strs[1].Split('.')[0]}";
-                                    //判断是否存在此程序集SN
-                                    if (TypeIoc.ContainsKey(TypeSN))
+                                    if (!InstanceIoc.ContainsKey(InstanceIocSN))
                                     {
-                                        if (!InstanceIoc.ContainsKey(SN))
-                                        {
-                                            ConfigCreateInstance(TypeIoc[TypeSN], temp);
-                                        }
-                                        else
-                                        {
-                                            OnEventHandler?.Invoke(this, new EventResult(false, $" {e.Name} 此配置实例已存在"));
-                                        }
+                                        ConfigCreateInstance(TypeIoc[TypeIocSN], temp);
                                     }
                                     else
                                     {
-                                        OnEventHandler?.Invoke(this, new EventResult(false, $" {e.Name} 新增对应配置创建实例失败 {TypeSN} 程序集不存在"));
+                                        OnEventHandler?.Invoke(this, new EventResult(false, $" {e.Name} 此配置实例已存在"));
                                     }
                                 }
+                                else
+                                {
+                                    OnEventHandler?.Invoke(this, new EventResult(false, $" {e.Name} 新增对应配置创建实例失败 {TypeIocSN} 程序集不存在"));
+                                }
                                 fs.Close();
                                 fs.Dispose();
                             }
@@ -454,24 +453,46 @@ namespace YSAI.RelayManage
             //获取结构参数
             JObject? jsonObject = Newtonsoft.Json.JsonConvert.DeserializeObject<JObject>(content);
             //获取唯一标识符
-            string SN = $"{type.FullName}.{jsonObject[basics.LibConfigSNKey]}";
+            string InstanceIocSN = $"{type.FullName}.{jsonObject[basics.LibConfigSNKey]}";
             //获取实例
             IRelay? instance = CreateInstance(type, new object[] { jsonObject }) as IRelay;
             //实例不为空
             if (instance != null)
             {
                 //把这个实例添加到容器中
-                InstanceIoc.TryAdd(SN, instance);
-                //抛出信息
-                OnEventHandler?.Invoke(this, new EventResult(true, $"{SN} 实例创建成功"));
+                InstanceIoc.TryAdd(InstanceIocSN, instance);
+                //自动打开
+                if (basics.AutoOn)
+                {
+                    //执行打开方法
+                    OperateResult operateResult = instance.On();
+                    //抛出信息
+                    OnEventHandler?.Invoke(this, new EventResult(operateResult.State, $"{InstanceIocSN} 实例创建成功,自动打开{(operateResult.State ? "成功" : "失败")}"));
+                }
+                else
+                {
+                    //抛出信息
+                    OnEventHandler?.Invoke(this, new EventResult(true, $"{InstanceIocSN} 实例创建成功"));
+                }
             }
             else
             {
                 //抛出信息
-                OnEventHandler?.Invoke(this, new EventResult(false, $"{SN} 实例创建失败"));
+                OnEventHandler?.Invoke(this, new EventResult(false, $"{InstanceIocSN} 实例创建失败"));
             }
         }
         /// <summary>
+        /// 实例事件信息
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        /// <exception cref="NotImplementedException"></exception>
+        private void Instance_OnEvent(object? sender, EventResult e)
+        {
+            //抛出信息
+            OnEventHandler?.Invoke(this, e);
+        }
+        /// <summary>
         /// 创建实例
         /// </summary>
         /// <param name="NamespaceAndClassNameType">类型</param>
@@ -616,6 +637,18 @@ namespace YSAI.RelayManage
             return Task.Run(() => Dispose(SN));
         }
         /// <summary>
+        /// 实例列表
+        /// </summary>
+        /// <returns>实例数组</returns>
+        public List<string>? InstanceList()
+        {
+            if (InstanceIoc != null)
+            {
+                return InstanceIoc.Keys.ToList();
+            }
+            return null;
+        }
+        /// <summary>
         /// 移除实例
         /// </summary>
         /// <param name="SN">实例的唯一标识符</param>
@@ -689,6 +722,55 @@ namespace YSAI.RelayManage
             }
         }
         /// <summary>
+        /// 打开所有
+        /// </summary>
+        /// <param name="SN">实例的唯一标识符</param>
+        /// <returns>统一出参</returns>
+        public Task<OperateResult> OnAllAsync()
+        {
+            return Task.Run(() => OnAll());
+        }
+        /// <summary>
+        /// 打开所有
+        /// </summary>
+        /// <param name="SN">实例的唯一标识符</param>
+        /// <returns>统一出参</returns>
+        public OperateResult OnAll()
+        {
+            Depart("OnAll");
+            try
+            {
+                if (InstanceIoc != null && InstanceIoc.Count > 0)
+                {
+                    List<string> FailMessage = new List<string>();
+                    foreach (var item in InstanceIoc)
+                    {
+                        OperateResult operateResult = item.Value.On();
+                        if (!operateResult.State)
+                        {
+                            FailMessage.Add(operateResult.Message);
+                        }
+                    }
+                    if (FailMessage.Count > 0)
+                    {
+                        return Break("OnAll", false, $"存在{FailMessage.Count}个异常信息,请查看RData", FailMessage, ResultType.All);
+                    }
+                    else
+                    {
+                        return Break("OnAll", true);
+                    }
+                }
+                else
+                {
+                    return Break("OnAll", false,"实例为空");
+                }
+            }
+            catch (Exception ex)
+            {
+                return Break("OnAll", false, ex.Message);
+            }
+        }
+        /// <summary>
         /// 关闭
         /// </summary>
         /// <param name="SN">实例的唯一标识符</param>
@@ -721,6 +803,55 @@ namespace YSAI.RelayManage
                 return Break("Off", false, ex.Message);
             }
         }
+        /// <summary>
+        /// 关闭所有
+        /// </summary>
+        /// <param name="SN">实例的唯一标识符</param>
+        /// <returns>统一出参</returns>
+        public Task<OperateResult> OffAllAsync()
+        {
+            return Task.Run(() => OffAll());
+        }
+        /// <summary>
+        /// 关闭所有
+        /// </summary>
+        /// <param name="SN">实例的唯一标识符</param>
+        /// <returns>统一出参</returns>
+        public OperateResult OffAll()
+        {
+            Depart("OffAll");
+            try
+            {
+                if (InstanceIoc != null && InstanceIoc.Count > 0)
+                {
+                    List<string> FailMessage = new List<string>();
+                    foreach (var item in InstanceIoc)
+                    {
+                        OperateResult operateResult = item.Value.Off();
+                        if (!operateResult.State)
+                        {
+                            FailMessage.Add(operateResult.Message);
+                        }
+                    }
+                    if (FailMessage.Count > 0)
+                    {
+                        return Break("OffAll", false, $"存在{FailMessage.Count}个异常信息,请查看RData", FailMessage, ResultType.All);
+                    }
+                    else
+                    {
+                        return Break("OffAll", true);
+                    }
+                }
+                else
+                {
+                    return Break("OffAll", false, "实例为空");
+                }
+            }
+            catch (Exception ex)
+            {
+                return Break("OffAll", false, ex.Message);
+            }
+        }
 
         /// <summary>
         /// 任务处理

+ 84 - 24
src/YSAI.DAQ/YSAI.Test.Console/Program.cs

@@ -1,5 +1,8 @@
-using YSAI.Core.data;
+using System.Collections.Concurrent;
+using YSAI.Core.data;
+using YSAI.Core.@enum;
 using YSAI.Core.reflection;
+using YSAI.Core.script;
 using YSAI.DaqManage;
 using YSAI.Mqtt.client;
 using YSAI.Mqtt.service.websocket;
@@ -17,45 +20,102 @@ foreach (var item in ints)
         LoginPassword = "ysai",
         Uri = "ysai"
     });
-    mqttWebSocketServiceOperate.OnEvent += MqttWebSocketServiceOperate_OnEvent;
     mqttWebSocketServiceOperate.On();
 }
 
 
-
-
-RelayManageOperate manageOperate = new RelayManageOperate();
+DaqManageOperate manageOperate = new DaqManageOperate();
 manageOperate.OnEvent += ManageOperate_OnEvent;
 
 
 
-
-
-
-
-
-
 while (manageOperate != null)
 {
     Console.Read();
-
-    OperateResult operateResult = manageOperate.On("YSAI.Mqtt.client.MqttClientOperate.MQTT一号转发");
-    Console.WriteLine(operateResult.Message);
-    operateResult = manageOperate.On("YSAI.Mqtt.client.MqttClientOperate.MQTT二号转发");
-    Console.WriteLine(operateResult.Message);
-
-    operateResult = manageOperate.Produce("Message", "66666666666666666666666666666666666");
+    //添加订阅
+    Address address = new Address();
+    address.AddressArray = new List<AddressDetails>()
+            {
+                new AddressDetails()
+                {
+                    AddressName = "a.a.a",
+                    AddressDataType = DataType.Bool,
+                    AddressDescribe = "一个动态的布尔类型",
+                    AddressAnotherName = "test",
+                    AddressPropertyName = "aaa",
+                    AddressType = AddressType.Reality
+                },
+                new AddressDetails()
+                {
+                    AddressName = "a.a.h",
+                    AddressDataType = DataType.String,
+                    AddressDescribe = "一个动态的字符串类型",
+                    AddressAnotherName = "test",
+                    AddressPropertyName = "aah",
+                    AddressType = AddressType.Reality,
+                    AddressParseParam = new AddressParse()
+                    {
+                        ParseType = ParseType.ScriptAnalysis,
+                        Script = new ScriptData.Basics()
+                        {
+                            ScriptCode = @"function Convert(value) 
+                                            {
+                                                return '这是脚本测试,传入的参数是:' + value;
+                                            }",
+                            ScriptFunction = "Convert",
+                            ScriptType = ScriptData.ScriptType.JavaScript
+                        }
+                    }
+                },
+                new AddressDetails()
+                 {
+                     AddressName = "a.a.g",
+                     AddressDataType = DataType.Double,
+                     AddressDescribe = "一个动态的浮点类型",
+                     AddressAnotherName = "test",
+                     AddressPropertyName = "aag",
+                     AddressType = AddressType.Reality,
+                     AddressParseParam = new AddressParse()
+                     {
+                         ParseType = ParseType.ScriptAnalysis,
+                         Script = new ScriptData.Basics()
+                         {
+                             ScriptCode = @"function Convert(value) 
+                                            {
+                                                return value*1000;
+                                            }",
+                             ScriptFunction = "Convert",
+                             ScriptType = ScriptData.ScriptType.JavaScript
+                         }
+                     }
+                 },
+                new AddressDetails()
+                 {
+                     AddressName = "OPCDA_VirtualAddress",
+                     AddressDataType =DataType.String,
+                     AddressDescribe = "虚拟地址",
+                     AddressAnotherName = "test",
+                     AddressPropertyName = "OPCDA_VirtualAddress",
+                     AddressType = AddressType.Virtual
+                 },
+                new AddressDetails()
+                  {
+                      AddressName = "OPCDA_VirtualDynamicAddress",
+                      AddressDataType = DataType.String,
+                      AddressDescribe = "虚拟动态地址",
+                      AddressAnotherName = "test",
+                      AddressPropertyName = "OPCDA_VirtualDynamicAddress",
+                      AddressType =AddressType.VirtualDynamic
+                  }
+            };
+    OperateResult operateResult = manageOperate.Subscribe(address, $"YSAI.Opc.da.client.OpcDaClientOperate.OPCDA1");
     Console.WriteLine(operateResult.Message);
-    
 }
 
 
-void MqttWebSocketServiceOperate_OnEvent(object? sender, EventResult e)
+
+ void ManageOperate_OnEvent(object? sender, YSAI.Core.data.EventResult e)
 {
     Console.ForegroundColor = ConsoleColor.Green;
     Console.WriteLine(e.Message);
-}
-void ManageOperate_OnEvent(object? sender, YSAI.Core.data.EventResult e)
-{
-    Console.WriteLine(e.Message);
 }

+ 1 - 0
src/YSAI.DAQ/YSAI.Test.Console/YSAI.Test.Console.csproj

@@ -5,6 +5,7 @@
     <TargetFramework>net6.0</TargetFramework>
     <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
+    <PlatformTarget>x86</PlatformTarget>
   </PropertyGroup>
 
 	<ItemGroup>

+ 1 - 1
src/YSAI.DAQ/YSAI.Test/YSAI.Test.csproj

@@ -11,7 +11,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.1" />
     <PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
     <PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
     <PackageReference Include="coverlet.collector" Version="6.0.0">