第三版底层数采通信库,持续更新

Shun 1c1a3c33a9 请自阅 il y a 2 ans
doc 6e0634c1d8 请自阅 il y a 2 ans
src 09f9857234 优化示例 il y a 2 ans
.gitignore 43b5f9ef90 first commit il y a 2 ans
README.md 1c1a3c33a9 请自阅 il y a 2 ans

README.md

阐述

  1. 所有协议公共函数支持同步异步
  2. 所有协议读取写入协议参数统一
  3. 全部都是统一入参出参
  4. 支持多点转发,多点解析
  5. 支持快速对接,与配置
  6. 支持虚拟点位
  7. 所有采集协议支持订阅模式
  8. 采集与转发协议接口统一
  9. 事件结果统一

YSAI.Core

  1. 处理
  2. 反射
  3. 转发
  4. 脚本
  5. 订阅
  6. 订阅
  7. 虚拟地址
  8. TCP
  9. UDP
  10. HTTP
  11. WS
  12. 串口

YSAI.Model

  1. 特性
  2. 数据结构
  3. 接口
  4. 枚举
  5. 模型工具

扩展工具

  1. [ YSAI.Rpc ]基于DotNetty实现的RPC(远程过程调用) 支持一对多,支持身份验证
  2. [ YSAI.Redis ]非关系型数据库,用于数据快速出站入站存储
  3. [ YSAI.Log ]Verbose(详细信息)、Debug(调试)、Info(信息)、Warning(警告)、Error(异常或错误)、Fatal(致命错误或异常)
  4. [ YSAI.Unility ]公共快捷方便方法集合 (字节、枚举、文件、字符串、验证、比对、转换、反射、扩展、Json、Xml、Ftp、System ...)

采集协议

  1. Opc(工业标准通信协议) [UA、DA、DAHttp]
  2. Can(工业标准通信协议)
  3. DB(数据库) [SqlServer、MySql、Oracle、SQLite]
  4. Modbus(工业标准通信协议) [Rtu、Ascii、Tcp、Udp]
  5. Siemens(西门子) [S7200、S7200Smart、S7300、S7400、S71200、S71500]
  6. Beckhoff(倍福) [ADS]
  7. Mitsubishi(三菱) [A1E、QNA3E]
  8. Omron(欧姆龙) [FINS]
  9. AllenBradley(罗克韦尔)
  10. Mewtocol(松下) [Tcp、Serial]
namespace YSAI.Model.@interface
{
    /// <summary>
    /// 数采接口
    /// </summary>
    public interface IDaq : IOn, IOff, IRead, IWrite, ISubscribe, IGetStatus, IEvent, IGetParam, ICreateInstance, IDisposable
    { }
}

转发协议

  1. Kafka [AdminClient、Producer、Consumer]
  2. Mqtt [Client [ Publish、Subscribe ]、Service、WSService]
  3. RabbitMQ [Publish、Subscribe]
  4. Netty [Client [ Publish、Subscribe ]、Service]
  5. NetMQ [Publish、Subscribe]
namespace YSAI.Model.@interface
{
    /// <summary>
    /// 转发接口
    /// </summary>
    public interface IRelay : IOn, IOff, IProducer, IConsumer, IGetStatus, IEvent, IGetParam, ICreateInstance, IDisposable
    { }
}

协议服务端(用于数据模拟)

  1. Mqtt服务端
  2. MqttWebSocket服务端
  3. OpcUa服务端
  4. Socket服务端
  5. WebSocket服务端

创建实例合集

//实例创建的几种方式
//以OPCUA 采集协议为例
using YSAI.Model.@interface;
using YSAI.Opc.ua.client;

OpcUaClientOperate? operate = null;
IDaq? daq = null;

//无参实例
operate = new OpcUaClientOperate();
//无参实例调函数创建实例,与无参实例配合使用
operate = new OpcUaClientOperate().CreateInstance(new OpcUaClientData.Basics()).GetRData<OpcUaClientOperate>();
//有参实例
operate = new OpcUaClientOperate(new OpcUaClientData.Basics());
//有参单例
operate = OpcUaClientOperate.Instance(new OpcUaClientData.Basics());
//接口 - 无参实例
daq = new OpcUaClientOperate();
//接口 - 无参实例调函数创建实例,与无参实例配合使用
daq = new OpcUaClientOperate().CreateInstance(new OpcUaClientData.Basics()).GetRData<OpcUaClientOperate>();
//接口 - 有参实例
daq = new OpcUaClientOperate(new OpcUaClientData.Basics());
//接口 - 有参单例
daq = OpcUaClientOperate.Instance(new OpcUaClientData.Basics());

using (operate)
{
    //使用完直接释放
}

using (daq)
{
    //使用完直接释放
}

采集应用

  1. 上 “NUGET” 搜索
  2. 安装对应的协议包
  3. 应用代码如下
  4. 协议包内还有内部公共方法,请自行研究使用
//采集协议
//以OPCUA 采集协议为例
using System.Collections.Concurrent;
using YSAI.Core.script;
using YSAI.Log;
using YSAI.Model.data;
using YSAI.Model.@enum;
using YSAI.Opc.ua.client;
using YSAI.Unility;

using (OpcUaClientOperate operate = new OpcUaClientOperate(new OpcUaClientData.Basics
{
    ServerUrl = "opc.tcp://127.0.0.1:6688",
    UserName = "user",
    Password = "password",
}))
{
    //点位地址
    Address address = new Address();
    address.SN = Guid.NewGuid().ToString();
    address.CreationTime = DateTime.Now.ToLocalTime();
    address.AddressArray = new List<AddressDetails>
    {
         new AddressDetails()                                        //地址详情参数介绍
        {
            SN=$"",                                                  //可以理解成唯一标识符(可以存机台号、组名、车间、厂)
            AddressAnotherName="",                                   //地址别名
            AddressDataType=DataType.String,                         //数据类型
            AddressDescribe="",                                      //地址描述
            AddressExtendParam=new object(),                         //扩展数据
            AddressName="",                                          //实际地址[ 不能为空 ]
            AddressPropertyName="",                                  //属性名称
            AddressType=AddressType.Reality,                         //地址类型
            IsEnable=true,                                           //是否启用
            AddressRelayParam=new AddressRelay                       //转发参数
            {
                ISns = new List<string> { "ISN1", "ISN2" },          //实例SN
                Topic = $"topic",                                    //主题
                ContentFormat="Value:{0}"                            //内容格式
            },
            AddressParseParam=new AddressParse                       //脚本解析实例
            {
                ScriptParam=new ScriptData.Basics                    //脚本解析基础数据
                {
                    ScriptCode = @"function Convert(addressname,value) { return '【这是调用脚本解析】传入的地址是:'+ addressname + '----传入的参数是:' + value; }",  //脚本代码
                    ScriptFunction = "Convert",                                                                                                                        //脚本入口
                    ScriptType = ScriptData.ScriptType.JavaScript                                                                                                      //脚本类型
                }
            },
            //AddressParseParam = new AddressParse                  //反射解析
            //{                      
            //    ReflectionParam = new object[]                    //反射解析的参数
            //    {
            //        new ReflectionData.Basics                     //反射解析基础数据
            //        {
            //                                                      //反射解析的基础数据
            //        },
            //        "SN"                                          //反射解析的SN
            //    }
            // },
         }
    };

    #region 打开
    OperateResult result = operate.On();
    LogHelper.Info(result.ToJson().JsonFormatting());  //转成JSON.JSON格式化 
    #endregion 打开

    #region 读取
    //读取
    result = operate.Read(address);
    LogHelper.Info(result.ToJson().JsonFormatting());   //转成JSON.JSON格式化 
    #endregion 读取

    #region 订阅
    operate.OnEvent += delegate (object? sender, EventResult e)
	{
    LogHelper.Info(e.ToJson().JsonFormatting());    //转成JSON.JSON格式化
	};
    result = operate.Subscribe(address);
    LogHelper.Info(result.ToJson().JsonFormatting());   //转成JSON.JSON格式化 
    #endregion 订阅

    #region 写入
    ConcurrentDictionary<string, object> value = new ConcurrentDictionary<string, object>
    {
        ["地址"] = "string 值",
        ["地址"] = (float)1.1f,
        ["地址"] = (double)2.2d,
        ["地址"] = (int)3,
        ["地址"] = true
    };
    result = operate.Write(value);
    LogHelper.Info(result.ToJson().JsonFormatting());   //转成JSON.JSON格式化 
    #endregion 写入

    #region 关闭
    result = operate.Off();
    LogHelper.Info(result.ToJson().JsonFormatting());   //转成JSON.JSON格式化 
    #endregion 关闭

    #region 获取状态
    result = operate.GetStatus();
    LogHelper.Info(result.ToJson().JsonFormatting());   //转成JSON.JSON格式化 
    #endregion 获取状态

    #region 获取参数
    result = operate.GetParam();
    LogHelper.Info(result.GetRData<ParamStructure>().ToJson().JsonFormatting());   //转成JSON.JSON格式化 
    #endregion 获取参数
}

转发应用

  1. 上 “NUGET” 搜索
  2. 安装对应的协议包
  3. 应用代码如下
  4. 协议包内还有内部公共方法,请自行研究使用
//转发协议
//以MQTT为例
using YSAI.Log;
using YSAI.Model.data;
using YSAI.Mqtt.client;
using YSAI.Unility;

using (MqttClientOperate operate = new MqttClientOperate(new MqttClientData.Basics
{
    Ip = "127.0.0.1",
    Port = 11819,
    UserName = "user",
    Password = "password"
}))
{
    #region 打开
    OperateResult result = operate.On();
    LogHelper.Info(result.ToJson().JsonFormatting());   //转成JSON.JSON格式化  
    #endregion 打开

    #region 生产
    result = operate.Produce("主题", "内容");
    LogHelper.Info(result.ToJson().JsonFormatting());   //转成JSON.JSON格式化  
    #endregion 生产

    #region 消费
    operate.OnEvent += delegate (object? sender, EventResult e)
    {
        LogHelper.Info(e.ToJson().JsonFormatting());   //转成JSON.JSON格式化 
    };
    result = operate.Subscribe("主题");
    LogHelper.Info(result.ToJson().JsonFormatting());   //转成JSON.JSON格式化  
    #endregion 消费

    #region 关闭
    result = operate.Off();
    LogHelper.Info(result.ToJson().JsonFormatting());   //转成JSON.JSON格式化  
    #endregion 关闭

    #region 获取状态
    result = operate.GetStatus();
    LogHelper.Info(result.ToJson().JsonFormatting());   //转成JSON.JSON格式化 
    #endregion 获取状态

    #region 获取参数
    result = operate.GetParam();
    LogHelper.Info(result.GetRData<ParamStructure>().ToJson().JsonFormatting());   //转成JSON.JSON格式化 
    #endregion 获取参数
}

更新表

2023-02-15

  1. 项目启动
  2. 库框架搭建
  3. 采集订阅流程实现多线程队列形式,处理速度大大提升
//更新,无休眠时间
while(true)
{
	//三大步骤
	1.优化
	2.更新
	3.提交
}

2023-09-20

  1. 采集订阅模式关闭优化
  2. 底层通信库性能提升

2023-09-23

  1. 日志记录优化,更详细的日志记录

2023-09-24

  1. 新增公用库方法
  2. 版本更新
  3. MqttService参数类型修改

2023-09-25

  1. CanLib 文件位置更换
  2. Pack 生成位置更换

2023-09-27

  1. Mqtt 客户端 修改内部公共方法函数名
  2. 转发协议包修改

2023-10-08

  1. 反射新增类库,分为内外使用
  2. 修改转发库获取不到状态问题
  3. 版本更新,提交NUGET
  4. 新增边端 结构参数解析JSON

2023-10-10

  1. 解决OPCUA问题
  2. OPCUA版本更新

2023-10-11 ~ 2023-10-12

  1. 修改 OPCUA 订阅流程逻辑,解决超时问题
  2. 修改 OPCUA 工具显示问题
  3. OPCUA 工具新增 导出 Core 地址对象
  4. 版本更新
  5. 细节更新
  6. 结果类型新增
  7. 单例模式下新增实例数量限制

2023-10-13

  1. 解决RMQ内存增加问题
  2. 新增微秒延时
  3. 版本更新
  4. 新增对象比对方法
  5. 修改 override bool Equals 方法

2023-10-15

  1. 优化细节
  2. 移除 override bool Equals 方法,直接使用对象比对
  3. 版本更新

2023-10-16

  1. 自定义订阅修改
  2. 修改对象比对
  3. 版本更新

2023-10-17

  1. 订阅函数变化更新 新增订阅源数据比对更新,使比对更合理
  2. S7读取修改

2023-10-19

  1. 移除多余脚本代码(只做简单脚本计算)
  2. 优化OPCUA
  3. 版本更新

2023-10-20 ~ 2023-10-23

  1. 新增json字符串判断
  2. 修改opcua当断线重连自动订阅
  3. 修改传输协议的数据格式
  4. 新增新的传输协议 Netty 客户端服务端
  5. 细节优化
  6. 版本更新

2023-10-24 ~ 2023-10-25

  1. 新增数据类型DataTime、Time、Date
  2. 新增倍福客户端
  3. 版本更新,细节优化

2023-10-26

  1. 修改CORE的系统与Unility时间工具
  2. 整体细节优化
  3. 版本更新

2023-10-30

  1. 移除S7非标服务端
  2. 移除Modbus 非标服务端
  3. 底层通信新增字节数从末尾从前移除0x00
  4. 多余代码清理
  5. 版本更新

2023-10-31

  1. OpcUa新增根据设置值自动分配订阅组
  2. OpcDa新增根据设置值自动分配订阅组
  3. 细节优化

2023-11-01

  1. 新增三个特性 单位、验证、展示
  2. 新增获取库参数接口方法【GetParam】
  3. 移除单独生成库配置文件
  4. 细节优化
  5. 新增结构参数类
  6. 版本更新

2023-11-02

  1. 新增创建单例接口方法,为了在反射或获取参数的情况下使用所有功能

2023-11-03

  1. 底层通信读取等待结果新增分批读取
  2. 新增三菱PLC数据采集
  3. 细节优化
  4. 版本更新

2023-11-06

  1. 三菱PLC采集优化
  2. 新增欧姆龙PLC FINS协议采集
  3. 版本更新

2023-11-08

  1. 新增 NETMQ 传输协议(不保证消息质量模式)
  2. 优化函数运行时间,使用 struct 直接操作底层,性能提升
  3. 细节优化,版本更新
  4. 修改所有协议获取参数重复代码,移植至Core

2023-11-09

  1. 新增 AllenBradley PLC采集
  2. 新增S7类型读取流程
  3. 优化CORE内部结构代码
  4. 优化所有采集协议的读取代码
  5. 修改采集协议的OFF方法,新添加订阅OFF
  6. 新增S7、AllenBradley、Mitsubishi、Omron、ModBus 测试服务端(非标准)
  7. 版本更新

2023-11-10

  1. 自定义订阅细节修改,移除不必要的事件
  2. 新增松下PLC
  3. 修改获取参数函数细节
  4. 移除不必要的事件跳转
  5. OpcUa Da 属性BUG修改

2023-11-13

  1. 展示特性中新增详细提示字段,方面展示时了解与指导此属性的详情
  2. Serilog 更新至最新版本
  3. 修改版本规则 ( 年.天.秒 ) ( 23.317.30964 ) -- 23年,第317天,当天的30964秒时生成的版本
  4. 生成nuget包位置更新

2023-11-14

  1. 修改S7库名称,现使用Siemens
  2. 所有库新增详细描述
  3. 等待.net8发布,集成.net8
  4. OPCUA 移除默认XML文件,使用动态创建
  5. 新增版本更新工具,一键更新版本

2023-11-15

  1. 所有库 统一更新,支持 net6.0 、net8.0
  2. mqttwsservice 细节优化

2023-11-16

  1. RPC远程过程调用工具编写
  2. 底层SOCKET WEBSOCKET 修改断线重连规则
  3. 版本更新

2023-11-21

  1. 新增基于DotNetty实现的RPC(远程过程调用) 支持一对多,支持身份验证
  2. RabbitMQ 依赖库更新

2023-11-23

  1. 移除Core中的Redis
  2. 新增 扩展工具 Redis
  3. 修改RPC扩展工具细节
  4. 新增 XML 序列化 反序列化 扩展方法
  5. 新增HEX扩展转换
  6. 版本更新

2023-11-24

  1. 整体框架调整 Core、Model、Extend、Daq、Relay
  2. 实现底层数据转发功能支持热加载热更新
  3. 优化数据解析流程,优化转发流程

2023-11-27

  1. 优化数据结构
  2. 测试底层转发流程(成功)
  3. 测试底层解析流程(成功)
  4. 修改脚本解析默认参数传两个
  5. 修改反射解析默认参数传两个
  6. 新增 动态转发 打开失败重试流程
  7. 版本更新

2023-11-28

  1. 优化数据类型
  2. 优化地址处理函数,严格数据质量
  3. OPCUA 新增当订阅的地址点没有在服务器创建订阅,则重新订阅

2023-11-30

  1. 修改所有协议的函数开始返回的SN
  2. 优化解析,当解析失败异常,则返回空数据,为了更好的判断数据质量
  3. OPCUA新增是否重连,重连间隔参数

2023-12-4

  1. 修改地址处理的细节,让数据质量更准确
  2. 对象比较器更换至[CompareNETObjects]
  3. 新增示例代码
  4. 修改PACK生成代码位置,与主代码不存在引用关系