lixun 2 anni fa
parent
commit
fb03640740

+ 1 - 9
src/YSAI.DAQ/YSAI.Core/data/AddressManage.cs

@@ -25,14 +25,6 @@ namespace YSAI.Core.data
         /// </summary>
         public object? InstanceParam { get; set; }
 
-        /// <summary>
-        /// Modbus 读取类型
-        /// </summary>
-        public ModbusReadType MRType { get; set; } = ModbusReadType.NULL;
-
-        /// <summary>
-        /// Modbus 写入类型
-        /// </summary>
-        public ModbusWriteType MWType { get; set; } = ModbusWriteType.NULL;
+        
     }
 }

+ 1 - 62
src/YSAI.DAQ/YSAI.Core/enum/Enums.cs

@@ -228,66 +228,5 @@ namespace YSAI.Core.@enum
         [Description("转发库")]
         Relay
     }
-    /// <summary>
-    /// Modbus读取类型
-    /// </summary>
-    public enum ModbusReadType
-    {
-        /// <summary>
-        /// 读取从1到2000个连续线圈状态
-        /// </summary>
-        [Description("读取从1到2000个连续线圈状态")]
-        Coils,
-        /// <summary>
-        /// 读取从1到2000个连续离散输入状态
-        /// </summary>
-        [Description("读取从1到2000个连续离散输入状态")]
-        Inputs,
-        /// <summary>
-        /// 读取保持寄存器的连续块
-        /// </summary>
-        [Description("读取保持寄存器的连续块")]
-        HoldingRegisters,
-        /// <summary>
-        /// 读取输入寄存器的连续块
-        /// </summary>
-        [Description("读取输入寄存器的连续块")]
-        InputRegisters,
-        /// <summary>
-        /// 空
-        /// </summary>
-        [Description("空")]
-        NULL
-    }
-    /// <summary>
-    /// Modbus写入类型
-    /// </summary>
-    public enum ModbusWriteType
-    {
-        /// <summary>
-        /// 写入单线圈值
-        /// </summary>
-        [Description("写入单线圈值")]
-        SingleCoil,
-        /// <summary>
-        /// 写入单个保持寄存器
-        /// </summary>
-        [Description("写入单个保持寄存器")]
-        SingleRegister,
-        /// <summary>
-        /// 将1块写入123个连续寄存器
-        /// </summary>
-        [Description("将1块写入123个连续寄存器")]
-        MultipleRegisters,
-        /// <summary>
-        /// 写入线圈序列
-        /// </summary>
-        [Description("写入线圈序列")]
-        MultipleCoils,
-        /// <summary>
-        /// 空
-        /// </summary>
-        [Description("空")]
-        NULL
-    }
+   
 }

+ 15 - 37
src/YSAI.DAQ/YSAI.Core/interface/only/IModbus.cs

@@ -12,7 +12,7 @@ namespace YSAI.Core.@interface.only
     /// <summary>
     /// MODBUS 接口
     /// </summary>
-    public interface IModbusClient : IOn, IOff, IDisposable
+    public interface IModbusClient : IOn, IOff,IRead, IDisposable
     {
         /// <summary>
         /// 读取从1到2000个连续线圈状态。
@@ -92,42 +92,7 @@ namespace YSAI.Core.@interface.only
         /// <returns>统一出参</returns>
         Task<OperateResult> ReadInputRegistersAsync(Address address, int DataType = 5);
 
-        /// <summary>
-        /// 读取保持寄存器的连续块。默认返回数据类型 5
-        /// </summary>
-        /// <param name="address">
-        /// 地址数据
-        /// modbus 读取特殊,如果读取单个地址就 直接在 Address 等于具体的地址,如果需要连续读取,就设置从第几位开始,往下读多少位Address=1,10,以逗号分隔
-        /// </param>
-        /// <returns>统一出参</returns>
-        OperateResult ReadHoldingRegisters(Address address);
-        /// <summary>
-        /// 读取保持寄存器的连续块。默认返回数据类型 5
-        /// </summary>
-        /// <param name="address">
-        /// 地址数据
-        /// modbus 读取特殊,如果读取单个地址就 直接在 Address 等于具体的地址,如果需要连续读取,就设置从第几位开始,往下读多少位Address=1,10,以逗号分隔
-        /// </param>
-        /// <returns>统一出参</returns>
-        Task<OperateResult> ReadHoldingRegistersAsync(Address address);
-        /// <summary>
-        /// 读取输入寄存器的连续块。默认返回数据类型 5
-        /// </summary>
-        /// <param name="address">
-        /// 地址数据
-        /// modbus 读取特殊,如果读取单个地址就 直接在 Address 等于具体的地址,如果需要连续读取,就设置从第几位开始,往下读多少位Address=1,10,以逗号分隔
-        /// </param>
-        /// <returns>统一出参</returns>
-        OperateResult ReadInputRegisters(Address address);
-        /// <summary>
-        /// 读取输入寄存器的连续块。默认返回数据类型 5
-        /// </summary>
-        /// <param name="address">
-        /// 地址数据
-        /// modbus 读取特殊,如果读取单个地址就 直接在 Address 等于具体的地址,如果需要连续读取,就设置从第几位开始,往下读多少位Address=1,10,以逗号分隔
-        /// </param>
-        /// <returns>统一出参</returns>
-        Task<OperateResult> ReadInputRegistersAsync(Address address);
+       
 
         /// <summary>
         /// 写入单线圈值。
@@ -177,5 +142,18 @@ namespace YSAI.Core.@interface.only
         /// <param name="Values">地址数据</param>
         /// <returns>统一出参</returns>
         Task<OperateResult> WriteMultipleCoilsAsync(ConcurrentDictionary<ushort, bool[]> Values);
+
+        /// <summary>
+        /// 异步写入
+        /// </summary>
+        /// <param name="Values">写入的数据点,与数据类型</param>
+        /// <returns>统一泛型结果</returns>
+        Task<OperateResult> WriteAsync(ConcurrentDictionary<ushort, object> Values);
+        /// <summary>
+        /// 写入
+        /// </summary>
+        /// <param name="Values">写入的数据点,与数据类型</param>
+        /// <returns>统一泛型结果</returns>
+        OperateResult Write(ConcurrentDictionary<ushort, object> Values);
     }
 }

+ 5 - 2
src/YSAI.DAQ/YSAI.Core/interface/unify/IOrAbstract.cs

@@ -35,16 +35,19 @@ namespace YSAI.Core.@interface.unify
         /// 出发,记录运行时间
         /// </summary>
         /// <param name="MethodName">方法名</param>
-        protected void Depart(string MethodName)
+        /// <returns>返回方法名</returns>
+        protected string Depart(string MethodName)
         {
             RunTimeTool.Instance($"{ClassName}.{MethodName}").StartRecord();
+            return MethodName;
         }
 
         /// <summary>
         /// 出发,记录运行时间
         /// </summary>
         /// <param name="MethodName">方法名</param>
-        protected Task DepartAsync(string MethodName)
+        /// <returns>返回方法名</returns>
+        protected Task<string> DepartAsync(string MethodName)
         {
             return Task.Run(() => Depart(MethodName));
         }

+ 279 - 165
src/YSAI.DAQ/YSAI.Manage.Core/base/ManageBaseOperate.cs

@@ -1,10 +1,12 @@
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using OpcDaComRcw.Dx;
+using S7.Net.Types;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Data.Entity.Core.Metadata.Edm;
 using System.Reflection.Emit;
+using System.Text;
 using System.Xml.Linq;
 using YSAI.Core.data;
 using YSAI.Core.@enum;
@@ -65,12 +67,7 @@ namespace YSAI.Manage.Core.@base
         /// 休眠时间(毫秒)
         /// </summary>
         int SleepTime { get; set; } = 100;
-        /// <summary>
-        /// 执行方法的委托,读取方法,每个通信设备都应该存在
-        /// Address:请求参数
-        /// Task<OperateResult>:操作结果
-        /// </summary>
-        Func<Address, OperateResult>? Function { get; set; }
+
         /// <summary>
         /// 数据变化抛出 false则为实时数据
         /// 只抛出变化项
@@ -133,8 +130,6 @@ namespace YSAI.Manage.Core.@base
         /// </summary>
         private OperateResult operateResult { get; set; }
 
-
-
         #region 私有函数
         /// <summary>
         /// 初始化管理
@@ -208,22 +203,6 @@ namespace YSAI.Manage.Core.@base
                                     operateResult = modbusClientOperate.On();
                                     if (operateResult.State)
                                     {
-                                        Func<Address, OperateResult>? Function = null;
-                                        switch (manage.MRType)
-                                        {
-                                            case ModbusReadType.Coils:
-                                                Function = modbusClientOperate.ReadCoils;
-                                                break;
-                                            case ModbusReadType.Inputs:
-                                                Function = modbusClientOperate.ReadInputs;
-                                                break;
-                                            case ModbusReadType.HoldingRegisters:
-                                                Function = modbusClientOperate.ReadHoldingRegisters;
-                                                break;
-                                            case ModbusReadType.InputRegisters:
-                                                Function = modbusClientOperate.ReadInputRegisters;
-                                                break;
-                                        }
                                         //创建一个自定义订阅
                                         SubscribeOperate subscribeOperate = SubscribeOperate.Instance(new SubscribeData.Basics()
                                         {
@@ -232,7 +211,7 @@ namespace YSAI.Manage.Core.@base
                                             DataChangeOut = DataChangeOut,
                                             SameDataOut = SameDataOut,
                                             SleepTime = SleepTime,
-                                            Function = Function
+                                            Function = modbusClientOperate.Read
                                         });
 
                                         //事件注册(永远保持一个事件注册)
@@ -457,7 +436,45 @@ namespace YSAI.Manage.Core.@base
             return FaliMessage;
         }
 
+        /// <summary>
+        /// 写入管理
+        /// </summary>
+        /// <typeparam name="V">数据类型</typeparam>
+        /// <param name="data">数据</param>
+        /// <param name="Name">数采类型</param>
+        /// <param name="SN">实例SN</param>
+        /// <returns></returns>
+        private OperateResult WriteHandler<V>(ConcurrentDictionary<string, V> data, DaqType? Name,string SN)
+        {
+            switch (Name)
+            {
+                case DaqType.OpcUa:
+                    operateResult = OpcUaDaqObjArray[SN].Write(data);
+                    if (!operateResult.State)
+                    {
+                        return Break("Write", false, $"[ {Name.ToString()} ] {operateResult.Message}");
+                    }
+                    break;
+                case DaqType.OpcDa:
+                    operateResult = OpcDaDaqObjArray[SN].Write(data);
+                    if (!operateResult.State)
+                    {
+                        return Break("Write", false, $"[ {Name.ToString()} ] {operateResult.Message}");
+                    }
+                    break;
+                case DaqType.S7:
+                    operateResult = S7DaqObjArray[SN].Write(data);
+                    if (!operateResult.State)
+                    {
+                        return Break("Write", false, $"[ {Name.ToString()} ] {operateResult.Message}");
+                    }
+                    break;
+            }
+            return Break("Write",true);
+        }
+
         #endregion
+
         #region 事件管理
         /// <summary>
         /// OPCUA客户端的全局事件
@@ -514,7 +531,7 @@ namespace YSAI.Manage.Core.@base
                 List<string> strings = InHandler();
                 if (strings.Count > 0)
                 {
-                    return Break("Init", false, "存在一个或多个初始化错误", RData: strings.ToJson(), RType: ResultType.Json);
+                    return Break("Init", false, "存在一个或多个初始化错误", RData: strings, RType: ResultType.Json);
                 }
                 else
                 {
@@ -548,23 +565,7 @@ namespace YSAI.Manage.Core.@base
                 {
                     case DaqType.DB:
                         //判断是否有此实例
-                        if (DBDaqObjArray.ContainsKey(SN))
-                        {
-                            //判断是否有此自定义订阅
-                            if (SubscribeObjArray.ContainsKey(SN))
-                            {
-                               operateResult = SubscribeObjArray[SN].On();
-                                if (!operateResult.State)
-                                {
-                                    return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] {operateResult.Message}");
-                                }
-                            }
-                            else
-                            {
-                                return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 订阅不存在");
-                            }
-                        }
-                        else
+                        if (!DBDaqObjArray.ContainsKey(SN))
                         {
                             return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
                         }
@@ -572,23 +573,7 @@ namespace YSAI.Manage.Core.@base
                     case DaqType.Modbus:
 
                         //判断是否有此实例
-                        if (DBDaqObjArray.ContainsKey(SN))
-                        {
-                            //判断是否有此自定义订阅
-                            if (SubscribeObjArray.ContainsKey(SN))
-                            {
-                                operateResult = SubscribeObjArray[SN].On();
-                                if (!operateResult.State)
-                                {
-                                    return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] {operateResult.Message}");
-                                }
-                            }
-                            else
-                            {
-                                return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 订阅不存在");
-                            }
-                        }
-                        else
+                        if (!DBDaqObjArray.ContainsKey(SN))
                         {
                             return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
                         }
@@ -596,81 +581,69 @@ namespace YSAI.Manage.Core.@base
                         break;
                     case DaqType.OpcUa:
                         //判断是否有此实例
-                        if (OpcUaDaqObjArray.ContainsKey(SN))
-                        {
-                            //OPCUA 自带订阅功能
-                            ConcurrentDictionary<string, List<AddressDetails>> sub = new ConcurrentDictionary<string, List<AddressDetails>>();
-                            sub.TryAdd(addressManage.SN, addressManage.AddressArray);
-                            operateResult = OpcUaDaqObjArray[SN].AddSubscribe(sub);
-                            if (!operateResult.State)
-                            {
-                                return Break("On", operateResult.State, operateResult.Message);
-                            }
-                        }
-                        else
+                        if (!OpcUaDaqObjArray.ContainsKey(SN))
                         {
                             return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
                         }
                         break;
                     case DaqType.OpcDa:
                         //判断是否有此实例
-                        if (OpcDaDaqObjArray.ContainsKey(SN))
-                        {
-                            operateResult = OpcDaDaqObjArray[SN].UpdateGroupSubscribedState(SN, true);
-                            if (!operateResult.State)
-                            {
-                                return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] {operateResult.Message}");
-                            }
-                        }
-                        else
+                        if (!OpcDaDaqObjArray.ContainsKey(SN))
                         {
                             return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
                         }
                         break;
                     case DaqType.OpcDaHttp:
                         //判断是否有此实例
-                        if (DBDaqObjArray.ContainsKey(SN))
+                        if (!DBDaqObjArray.ContainsKey(SN))
                         {
-                            //判断是否有此自定义订阅
-                            if (SubscribeObjArray.ContainsKey(SN))
-                            {
-                                operateResult = SubscribeObjArray[SN].On();
-                                if (!operateResult.State)
-                                {
-                                    return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] {operateResult.Message}");
-                                }
-                            }
-                            else
-                            {
-                                return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 订阅不存在");
-                            }
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
                         }
-                        else
+                        break;
+                    case DaqType.S7:
+                        //判断是否有此实例
+                        if (!DBDaqObjArray.ContainsKey(SN))
                         {
                             return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
                         }
                         break;
+                }
+
+                switch (Name)
+                {
+                    case DaqType.OpcUa:
+                        //OPCUA 自带订阅功能
+                        ConcurrentDictionary<string, List<AddressDetails>> sub = new ConcurrentDictionary<string, List<AddressDetails>>();
+                        sub.TryAdd(addressManage.SN, addressManage.AddressArray);
+                        operateResult = OpcUaDaqObjArray[SN].AddSubscribe(sub);
+                        if (!operateResult.State)
+                        {
+                            return Break("On", operateResult.State, operateResult.Message);
+                        }
+                        break;
+                    case DaqType.OpcDa:
+                        operateResult = OpcDaDaqObjArray[SN].UpdateGroupSubscribedState(SN, true);
+                        if (!operateResult.State)
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] {operateResult.Message}");
+                        }
+                        break;
+                    case DaqType.DB:
+                    case DaqType.Modbus:
+                    case DaqType.OpcDaHttp:
                     case DaqType.S7:
-                        //判断是否有此实例
-                        if (DBDaqObjArray.ContainsKey(SN))
+                        //判断是否有此自定义订阅
+                        if (SubscribeObjArray.ContainsKey(SN))
                         {
-                            //判断是否有此自定义订阅
-                            if (SubscribeObjArray.ContainsKey(SN))
-                            {
-                                operateResult = SubscribeObjArray[SN].On();
-                                if (!operateResult.State)
-                                {
-                                    return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] {operateResult.Message}");
-                                }
-                            }
-                            else
+                            operateResult = SubscribeObjArray[SN].On();
+                            if (!operateResult.State)
                             {
-                                return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 订阅不存在");
+                                return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] {operateResult.Message}");
                             }
                         }
                         else
                         {
-                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 订阅不存在");
                         }
                         break;
                 }
@@ -696,60 +669,85 @@ namespace YSAI.Manage.Core.@base
                 switch (Name)
                 {
                     case DaqType.DB:
-
-                        operateResult = SubscribeObjArray[SN].Off();
-                        if (!operateResult.State)
+                        //判断是否有此实例
+                        if (!DBDaqObjArray.ContainsKey(SN))
                         {
-                            return Break("Off", false, operateResult.Message);
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
                         }
-
                         break;
                     case DaqType.Modbus:
-
-                        operateResult = SubscribeObjArray[SN].Off();
-                        if (!operateResult.State)
+                        //判断是否有此实例
+                        if (!ModbusDaqObjArray.ContainsKey(SN))
                         {
-                            return Break("Off", false, operateResult.Message);
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
                         }
-
                         break;
                     case DaqType.OpcUa:
+                        //判断是否有此实例
+                        if (!OpcUaDaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
+                        break;
+                    case DaqType.OpcDa:
+                        //判断是否有此实例
+                        if (!OpcDaDaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
+                        break;
+                    case DaqType.OpcDaHttp:
+                        //判断是否有此实例
+                        if (!OpcDaHttpDaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
+                        break;
+                    case DaqType.S7:
+                        //判断是否有此实例
+                        if (!S7DaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
+                        break;
+                }
 
+                switch (Name)
+                {
+                    case DaqType.OpcUa:
                         operateResult = OpcUaDaqObjArray[SN].RemoveSubscribe(basics.AManages.FirstOrDefault(c => c.DType.Equals(Name) && c.SN.Equals(SN)).AddressArray);
                         if (!operateResult.State)
                         {
                             return Break("Off", false, operateResult.Message);
                         }
-
                         break;
                     case DaqType.OpcDa:
-
                         operateResult = OpcDaDaqObjArray[SN].UpdateGroupSubscribedState(SN, false);
                         if (!operateResult.State)
                         {
                             return Break("Off", false, operateResult.Message);
                         }
-
                         break;
+                    case DaqType.DB:
+                    case DaqType.Modbus:
                     case DaqType.OpcDaHttp:
-
-                        operateResult = SubscribeObjArray[SN].Off();
-                        if (!operateResult.State)
+                    case DaqType.S7:
+                        //判断是否有此自定义订阅
+                        if (SubscribeObjArray.ContainsKey(SN))
                         {
-                            return Break("Off", false, operateResult.Message);
+                            operateResult = SubscribeObjArray[SN].Off();
+                            if (!operateResult.State)
+                            {
+                                return Break("Off", false, $"[ {Name.ToString} ] [ {SN} ] {operateResult.Message}");
+                            }
                         }
-
-                        break;
-                    case DaqType.S7:
-
-                        operateResult = SubscribeObjArray[SN].Off();
-                        if (!operateResult.State)
+                        else
                         {
-                            return Break("Off", false, operateResult.Message);
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 订阅不存在");
                         }
-
                         break;
                 }
+
                 return Break("Off", true);
             }
             catch (Exception ex)
@@ -779,6 +777,54 @@ namespace YSAI.Manage.Core.@base
                     return Break("Read", false, $"[ {Name.ToString()} ] 未查询到({AddressName})地址配置数据");
                 }
 
+                switch (Name)
+                {
+                    case DaqType.DB:
+                        //判断是否有此实例
+                        if (!DBDaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
+                        break;
+                    case DaqType.Modbus:
+
+                        //判断是否有此实例
+                        if (!DBDaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
+
+                        break;
+                    case DaqType.OpcUa:
+                        //判断是否有此实例
+                        if (!OpcUaDaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
+                        break;
+                    case DaqType.OpcDa:
+                        //判断是否有此实例
+                        if (!OpcDaDaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
+                        break;
+                    case DaqType.OpcDaHttp:
+                        //判断是否有此实例
+                        if (!DBDaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
+                        break;
+                    case DaqType.S7:
+                        //判断是否有此实例
+                        if (!DBDaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
+                        break;
+                }
+
                 switch (Name)
                 {
                     case DaqType.DB:
@@ -789,36 +835,10 @@ namespace YSAI.Manage.Core.@base
                         }
                         break;
                     case DaqType.Modbus:
-                        switch (addressManage.MRType)
+                        operateResult = ModbusDaqObjArray[SN].Read(addressManage);
+                        if (operateResult.State)
                         {
-                            case ModbusReadType.Coils:
-                                operateResult = ModbusDaqObjArray[SN].ReadCoils(addressManage);
-                                if (operateResult.State)
-                                {
-                                    return Break("Read", true, RData: operateResult.RData, RType: operateResult.RType);
-                                }
-                                break;
-                            case ModbusReadType.Inputs:
-                                operateResult = ModbusDaqObjArray[SN].ReadInputs(addressManage);
-                                if (operateResult.State)
-                                {
-                                    return Break("Read", true, RData: operateResult.RData, RType: operateResult.RType);
-                                }
-                                break;
-                            case ModbusReadType.HoldingRegisters:
-                                operateResult = ModbusDaqObjArray[SN].ReadHoldingRegisters(addressManage);
-                                if (operateResult.State)
-                                {
-                                    return Break("Read", true, RData: operateResult.RData, RType: operateResult.RType);
-                                }
-                                break;
-                            case ModbusReadType.InputRegisters:
-                                operateResult = ModbusDaqObjArray[SN].ReadInputRegisters(addressManage);
-                                if (operateResult.State)
-                                {
-                                    return Break("Read", true, RData: operateResult.RData, RType: operateResult.RType);
-                                }
-                                break;
+                            return Break("Read", true, RData: operateResult.RData, RType: operateResult.RType);
                         }
                         break;
                     case DaqType.OpcUa:
@@ -850,6 +870,7 @@ namespace YSAI.Manage.Core.@base
                         }
                         break;
                 }
+
                 return Break("Read", false, $"[ {Name.ToString()} ] [ {AddressName} ] {operateResult.Message}");
             }
             catch (Exception ex)
@@ -882,19 +903,112 @@ namespace YSAI.Manage.Core.@base
                 switch (Name)
                 {
                     case DaqType.DB:
-                        return Break("Write",false,$"[ {Name.ToString()} ] 目前不支持写入功能");
+                        //判断是否有此实例
+                        if (!DBDaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
+                        break;
                     case DaqType.Modbus:
 
+                        //判断是否有此实例
+                        if (!DBDaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
+
                         break;
                     case DaqType.OpcUa:
+                        //判断是否有此实例
+                        if (!OpcUaDaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
                         break;
                     case DaqType.OpcDa:
+                        //判断是否有此实例
+                        if (!OpcDaDaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
                         break;
                     case DaqType.OpcDaHttp:
+                        //判断是否有此实例
+                        if (!DBDaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
                         break;
                     case DaqType.S7:
+                        //判断是否有此实例
+                        if (!DBDaqObjArray.ContainsKey(SN))
+                        {
+                            return Break("On", false, $"[ {Name.ToString} ] [ {SN} ] 实例不存在");
+                        }
                         break;
                 }
+
+                switch (Name)
+                {
+                    case DaqType.OpcDaHttp:
+                    case DaqType.DB:
+                        return Break("Write",false,$"[ {Name.ToString()} ] 目前不支持写入功能");
+                    case DaqType.Modbus:
+                        ConcurrentDictionary<ushort, object> pairs = new ConcurrentDictionary<ushort, object>();
+                        try
+                        {
+                            switch (DType)
+                            {
+                                case DataType.String:
+                                    pairs.TryAdd(int.Parse(AddressName).ToUshort(),Value);
+                                    break;
+                                case DataType.Bool:
+                                    pairs.TryAdd(int.Parse(AddressName).ToUshort(), bool.Parse(Value));
+                                    break;
+                                case DataType.Double:
+                                    pairs.TryAdd(int.Parse(AddressName).ToUshort(), double.Parse(Value));
+                                    break;
+                                case DataType.Int:
+                                    pairs.TryAdd(int.Parse(AddressName).ToUshort(), int.Parse(Value));
+                                    break;
+                                default:
+                                    return Break("Write", false, "值类型错误");
+                            }
+                        }
+                        catch (Exception ex)
+                        {
+                            return Break("Write", false, $"数据类型转换异常:{ex.Message}");
+                        }
+                        operateResult = ModbusDaqObjArray[SN].Write(pairs);
+                        if (!operateResult.State)
+                        {
+                            return Break("Write", false, $"[ {Name.ToString()} ] {operateResult.Message}");
+                        }
+                        break;
+                    default:
+                        switch (DType)
+                        {
+                            case DataType.String:
+                                ConcurrentDictionary<string, string> str = new ConcurrentDictionary<string, string>();
+                                str.TryAdd(AddressName, Value);
+                                return WriteHandler(str, Name, SN);
+                            case DataType.Bool:
+                                ConcurrentDictionary<string, bool> bo = new ConcurrentDictionary<string, bool>();
+                                bo.TryAdd(AddressName, bool.Parse(Value));
+                                return WriteHandler(bo, Name, SN);
+                            case DataType.Double:
+                                ConcurrentDictionary<string, double> dou = new ConcurrentDictionary<string, double>();
+                                dou.TryAdd(AddressName, double.Parse(Value));
+                                return WriteHandler(dou, Name, SN);
+                            case DataType.Int:
+                                ConcurrentDictionary<string, int> ints = new ConcurrentDictionary<string, int>();
+                                ints.TryAdd(AddressName, int.Parse(Value));
+                                return WriteHandler(ints, Name, SN);
+                            default:
+                                return Break("Write", false, "值类型错误");
+                        }
+                }
+
                 return Break("Write", true);
             }
             catch (Exception ex)

+ 1 - 1
src/YSAI.DAQ/YSAI.Manage/appsettings.json

@@ -6,5 +6,5 @@
     }
   },
   "AllowedHosts": "*",
-  "AutoInit": true
+  "AutoInit": false
 }

+ 80 - 6
src/YSAI.DAQ/YSAI.Modbus/client/ModbusClientData.cs

@@ -1,13 +1,7 @@
 using Newtonsoft.Json;
 using Newtonsoft.Json.Converters;
-using System;
-using System.Collections.Generic;
 using System.ComponentModel;
 using System.IO.Ports;
-using System.Linq;
-using System.Numerics;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace YSAI.Modbus.client
 {
@@ -228,6 +222,7 @@ namespace YSAI.Modbus.client
                 }
             }
         }
+
         /// <summary>
         /// 基础数据
         /// </summary>
@@ -254,15 +249,31 @@ namespace YSAI.Modbus.client
             /// </summary>
             [Description("读取超时时间")]
             public int ReadTimeOut { get; set; } = 2000;
+
+            /// <summary>
+            /// 读取类型
+            /// </summary>
+            [Description("读取类型")]
+            public ModbusReadType MRType { get; set; } = ModbusReadType.NULL;
+
+            /// <summary>
+            /// 写入类型
+            /// </summary>
+            [Description("写入类型")]
+            public ModbusWriteType MWType { get; set; } = ModbusWriteType.NULL;
+
             /// <summary>
             /// 写入超时时间
             /// </summary>
             [Description("写入超时时间")]
             public int WriteTimeOut { get; set; } = 2000;
+
             [Description("TCP参数")]
             public TcpParam? TcpParam { get; set; }
+
             [Description("UDP参数")]
             public UdpParam? UdpParam { get; set; }
+
             [Description("串口参数")]
             public SerialPortParam? SerialPortParam { get; set; }
 
@@ -312,5 +323,68 @@ namespace YSAI.Modbus.client
             }
 
         }
+
+        /// <summary>
+        /// Modbus读取类型
+        /// </summary>
+        public enum ModbusReadType
+        {
+            /// <summary>
+            /// 读取从1到2000个连续线圈状态
+            /// </summary>
+            [Description("读取从1到2000个连续线圈状态")]
+            Coils,
+            /// <summary>
+            /// 读取从1到2000个连续离散输入状态
+            /// </summary>
+            [Description("读取从1到2000个连续离散输入状态")]
+            Inputs,
+            /// <summary>
+            /// 读取保持寄存器的连续块
+            /// </summary>
+            [Description("读取保持寄存器的连续块")]
+            HoldingRegisters,
+            /// <summary>
+            /// 读取输入寄存器的连续块
+            /// </summary>
+            [Description("读取输入寄存器的连续块")]
+            InputRegisters,
+            /// <summary>
+            /// 空
+            /// </summary>
+            [Description("空")]
+            NULL
+        }
+        /// <summary>
+        /// Modbus写入类型
+        /// </summary>
+        public enum ModbusWriteType
+        {
+            /// <summary>
+            /// 写入单线圈值
+            /// </summary>
+            [Description("写入单线圈值")]
+            SingleCoil,
+            /// <summary>
+            /// 写入单个保持寄存器
+            /// </summary>
+            [Description("写入单个保持寄存器")]
+            SingleRegister,
+            /// <summary>
+            /// 将1块写入123个连续寄存器
+            /// </summary>
+            [Description("将1块写入123个连续寄存器")]
+            MultipleRegisters,
+            /// <summary>
+            /// 写入线圈序列
+            /// </summary>
+            [Description("写入线圈序列")]
+            MultipleCoils,
+            /// <summary>
+            /// 空
+            /// </summary>
+            [Description("空")]
+            NULL
+        }
     }
 }

+ 60 - 20
src/YSAI.DAQ/YSAI.Modbus/client/ModbusClientOperate.cs

@@ -560,26 +560,6 @@ namespace YSAI.Modbus.client
             return Task.Run(() => ReadInputRegisters(address, DataType));
         }
 
-        public OperateResult ReadHoldingRegisters(Address address)
-        {
-            return ReadInputRegisters(address,5);
-        }
-
-        public Task<OperateResult> ReadHoldingRegistersAsync(Address address)
-        {
-            return Task.Run(() => ReadHoldingRegisters(address));
-        }
-
-        public OperateResult ReadInputRegisters(Address address)
-        {
-            return ReadInputRegisters(address, 5);
-        }
-
-        public Task<OperateResult> ReadInputRegistersAsync(Address address)
-        {
-            return Task.Run(() => ReadInputRegisters(address));
-        }
-
         public OperateResult WriteSingleCoil(ConcurrentDictionary<ushort, bool> Values)
         {
             //开始记录运行时间
@@ -687,5 +667,65 @@ namespace YSAI.Modbus.client
         {
             return Task.Run(() => WriteMultipleCoils(Values));
         }
+
+        public Task<OperateResult> ReadAsync(Address address)
+        {
+            return Task.Run(() => Read(address));
+        }
+
+        public OperateResult Read(Address address)
+        {
+            switch (basics.MRType)
+            {
+                case ModbusReadType.Coils:
+                    return ReadCoils(address);
+                case ModbusReadType.Inputs:
+                    return ReadInputs(address);
+                case ModbusReadType.HoldingRegisters:
+                    return ReadHoldingRegisters(address);
+                case ModbusReadType.InputRegisters:
+                    return ReadInputRegisters(address);
+                default:
+                    return Break(Depart("Read"), false, "读取类型错误");
+            }
+        }
+
+        public Task<OperateResult> WriteAsync(ConcurrentDictionary<ushort, object> Values)
+        {
+            return Task.Run(()=>Write(Values));
+        }
+
+        public OperateResult Write(ConcurrentDictionary<ushort, object> Values)
+        {
+            Depart("Write");
+            try
+            {
+                switch (basics.MWType)
+                {
+                    case ModbusWriteType.SingleCoil:
+                        ConcurrentDictionary<ushort, bool> wsc = new ConcurrentDictionary<ushort, bool>();
+                        foreach (var item in Values) { wsc.TryAdd(item.Key, (bool)item.Value); }
+                        return WriteSingleCoil(wsc);
+                    case ModbusWriteType.SingleRegister:
+                        ConcurrentDictionary<ushort, ushort> wsr = new ConcurrentDictionary<ushort, ushort>();
+                        foreach (var item in Values) { wsr.TryAdd(item.Key, (ushort)item.Value); }
+                        return WriteSingleRegister(wsr);
+                    case ModbusWriteType.MultipleRegisters:
+                        ConcurrentDictionary<ushort, ushort[]> wmr = new ConcurrentDictionary<ushort, ushort[]>();
+                        foreach (var item in Values) { wmr.TryAdd(item.Key, (ushort[])item.Value); }
+                        return WriteMultipleRegisters(wmr);
+                    case ModbusWriteType.MultipleCoils:
+                        ConcurrentDictionary<ushort, bool[]> wmc = new ConcurrentDictionary<ushort, bool[]>();
+                        foreach (var item in Values) { wmc.TryAdd(item.Key, (bool[])item.Value); }
+                        return WriteMultipleCoils(wmc);
+                    default:
+                        return Break("Write", false, "写入类型错误");
+                }
+            }
+            catch (Exception)
+            {
+                return Break("Write", false, "写入类型错误");
+            }
+        }
     }
 }

+ 65 - 0
src/YSAI.DAQ/YSAI.Unility/ExtensionTool.cs

@@ -5,6 +5,7 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Runtime.CompilerServices;
 using System.Security.Cryptography;
 using System.Text;
 using System.Text.RegularExpressions;
@@ -664,5 +665,69 @@ namespace YSAI.Unility
                 return await stream.ReadToEndAsync();
             }
         }
+        /// <summary>
+        /// string转ushort数组
+        /// </summary>
+        /// <param name="inString"></param>
+        /// <returns></returns>
+        public static ushort[] ToUshort(this string inString)
+        {
+            if (inString.Length % 2 == 1) { inString += " "; }
+            char[] bufChar = inString.ToCharArray();
+            byte[] outByte = new byte[bufChar.Length];
+            byte[] bufByte = new byte[2];
+            ushort[] outShort = new ushort[bufChar.Length / 2];
+            for (int i = 0, j = 0; i < bufChar.Length; i += 2, j++)
+            {
+                bufByte[0] = BitConverter.GetBytes(bufChar[i])[0];
+                bufByte[1] = BitConverter.GetBytes(bufChar[i + 1])[0];
+                outShort[j] = BitConverter.ToUInt16(bufByte, 0);
+            }
+            return outShort;
+        }
+        /// <summary>
+        /// int转ushort
+        /// </summary>
+        /// <param name="inString"></param>
+        /// <returns></returns>
+        public static ushort ToUshort(this int inInit)
+        {
+            return (ushort)inInit;
+        }
+        /// <summary>
+        /// double转ushort
+        /// </summary>
+        /// <param name="inString"></param>
+        /// <returns></returns>
+        public static ushort ToUshort(this double inDouble)
+        {
+            return (ushort)inDouble;
+        }
+        /// <summary>
+        /// float转ushort
+        /// </summary>
+        /// <param name="inString"></param>
+        /// <returns></returns>
+        public static ushort ToUshort(this float inFloat)
+        {
+            return (ushort)inFloat;
+        }
+        /// <summary>
+        /// ushort数组转string
+        /// </summary>
+        /// <param name="inUshort"></param>
+        /// <returns></returns>
+        public static string ToString(this ushort[] inUshort)
+        {
+            byte[] outByte = new byte[inUshort.Length * 2];
+            for (int i = 0; i < inUshort.Length; i++)
+            {
+                byte[] bufByte = BitConverter.GetBytes(inUshort[i]);
+                outByte[i * 2] = bufByte[0];
+                outByte[i * 2 + 1] = bufByte[1];
+            }
+            string str = ASCIIEncoding.ASCII.GetString(outByte).Trim();
+            return str;
+        }
     }
 }