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

Shun ca7457108e 请自阅 преди 2 години
doc 6e0634c1d8 请自阅 преди 2 години
src 893cceb1bc 版本更新 преди 2 години
.gitignore 43b5f9ef90 first commit преди 2 години
README.md ca7457108e 请自阅 преди 2 години

README.md

阐述

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

YSAI.Core

  1. Http
  2. Tcp客户端
  3. Tcp服务端
  4. Udp
  5. WS客户端
  6. WS服务端
  7. 串口
  8. 脚本
  9. Redis
  10. 反射
  11. 自定义订阅
  12. 虚拟点

YSAI.Log

  1. Verbose [详细信息]
  2. Debug [调试]
  3. Info [信息]
  4. Warning [警告]
  5. Error [异常或错误]
  6. Fatal [致命错误或异常]

YSAI.Unility

  1. 公共快捷方便方法集合 [字节、枚举、文件、字符串、验证、比对、转换、反射、Json、Xml、Ftp、System ...]

扩展工具

  1. [ YSAI.Rpc ]基于DotNetty实现的RPC(远程过程调用) 支持一对多,支持身份验证

采集协议

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

转发协议

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

应用


1.上 NUGET 搜索 YSAI
2.安装对应的协议包
3.应用代码如下
4.协议包内还有内部公共方法,请自行研究使用

------------------------------------------------------

//实例创建的几种方式

//第一种方式
BeckhoffOperate beckhoffOperate1 = new BeckhoffOperate();

//第二种方式(单例模式)
BeckhoffOperate? beckhoffOperate2 = new BeckhoffOperate().CreateInstance(new BeckhoffData.Basics()).GetRData<BeckhoffOperate>();

//第三种方式(单例模式)
BeckhoffOperate beckhoffOperate3 = BeckhoffOperate.Instance(new BeckhoffData.Basics());

//第四种方式
IDaq daq1 = new BeckhoffOperate(new BeckhoffData.Basics());

//第五种方式
IDaq daq2 = BeckhoffOperate.Instance(new BeckhoffData.Basics());

//第六种方式
using (BeckhoffOperate beckhoffOperate4 = new BeckhoffOperate())
{
    //使用完直接释放
}

//第七种方式
using (BeckhoffOperate beckhoffOperate5 = BeckhoffOperate.Instance(new BeckhoffData.Basics()))
{
    //使用完直接释放这个单例
}

//第八种方式
using (BeckhoffOperate? beckhoffOperate6 = new BeckhoffOperate().CreateInstance(new BeckhoffData.Basics()).GetRData<BeckhoffOperate>())
{
    //使用完直接释放这个单例
}

//第九种方式
using (IDaq daq3 = new BeckhoffOperate(new BeckhoffData.Basics()))
{
    //使用完直接释放
}

//第十种方式
using (IDaq daq4 = BeckhoffOperate.Instance(new BeckhoffData.Basics()))
{
    //使用完直接释放这个单例
}

//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
//第一种的应用场景是获取库参数信息时当这个对象已经实例化了,但是实际功能无法使用,就可以直接使用 CreateInstance 创建一个单例模式
//先获取参数
beckhoffOperate1.GetParam();
//在生成单例后赋值,这样当前实例就已经可以使用所有功能,并且是单例的存在
beckhoffOperate1 = beckhoffOperate1.CreateInstance(new BeckhoffData.Basics()).GetRData<BeckhoffOperate>();
//第二种与第三种就是直接创建单例模式,但第二种是为了在反射的情况下使用单例模式,第二种也是为第一种情况而产生

------------------------------------------------------

//采集协议
using (类 operate = new 类(new 类数据.Basics
{

    //采集对象参数

}))
{
    //打开
    OperateResult result = operate.On();
    LogHelper.Info(result.ToJson().JsonFormatting());

    //点位地址
    Address address = new Address();
    address.SN = Guid.NewGuid().ToString();
    address.CreationTime = DateTime.Now.ToLocalTime();
    address.AddressArray = new List<AddressDetails>
    {
        new AddressDetails()//S7点位地址
        {
            SN=$"{Guid.NewGuid().ToNString()} - Factory",
            AddressName = "DB71.DBD4",
            AddressDataType = YSAI.Core.@enum.DataType.Float
        },
         new AddressDetails()//OpcUa点位地址
        {
            SN=$"{Guid.NewGuid().ToNString()} - Factory",
            AddressName = "ns=2;s=Scalar_Simulation_Float",
            AddressDataType = YSAI.Core.@enum.DataType.Float
        },
         new AddressDetails()//OpcDa点位地址
        {
            SN=$"{Guid.NewGuid().ToNString()} - Factory",
            AddressName = "a.a.a",
            AddressDataType = YSAI.Core.@enum.DataType.Float
        },
         new AddressDetails()//Modbus点位地址
        {
            SN=$"{Guid.NewGuid().ToNString()} - Factory",
            AddressName = "0,2",
            AddressDataType = YSAI.Core.@enum.DataType.Float
        },
         new AddressDetails()  //DB点位地址
        {
            SN=$"{Guid.NewGuid().ToNString()} - Factory",
            AddressName = "数据库采集",
            AddressDataType = YSAI.Core.@enum.DataType.String,
            AddressExtendParam=new DBData.ExtendParam.Read()
            {
               Sql = @"SELECT A,B,C,D FORM TABLE ORDER BY YPBH DESC  LIMIT 0,1",
               ColumnName = new List<string>() { "A", "B", "C", "D"}
            }
         },
         new AddressDetails()  //OpcDaHttp点位地址
        {
            SN=$"{Guid.NewGuid().ToNString()} - Factory",
            AddressName = "a.a.a",
            AddressDataType = YSAI.Core.@enum.DataType.String,
            AddressExtendParam=new OpcDaHttpData.ExtendParam.Read()
            {
               GroupName="YF75ZDHPJ",
               ReadInterval=1000,
               ServerName="OPC.SimaticNET.1"
            }
         },
         new AddressDetails()  //地址详情参数介绍
        {
            SN=$"A88",                                              //可以理解成唯一标识符(可以存机台号、组名、车间、厂)
            AddressAnotherName="A_Name",                            //地址别名
            AddressDataType=YSAI.Core.@enum.DataType.Float,         //数据类型
            AddressDescribe="NameDescribe",                         //地址描述
            AddressExtendParam=new object(),                        //扩展数据
            AddressName="Name",                                     //地址名称
            //AddressParseParam=new AddressParse                    //地址解析参数
            //{
            //    ParseType=ParseType.ScriptAnalysis,               //解析类型
            //    Script=new YSAI.Core.script.ScriptData.Basics     //脚本解析数据
            //    {
            //    }
            //},
             AddressParseParam=new AddressParse                     //地址解析参数
            {
                ParseType=ParseType.MethodAnalysis,                 //解析类型
                ReflectionSN="反射SN"
            },
             AddressPropertyName="Name1",                           //地址别名
             AddressType=AddressType.Reality,                       //地址类型
             IsEnable=true                                          //是否启用
         }
    };

    //读取
    result = operate.Read(address);
    LogHelper.Info(result.ToJson().JsonFormatting());

    //订阅
    operate.OnEvent += delegate (object? sender, EventResult e)
    {
        LogHelper.Info(e.ToJson().JsonFormatting());
    };
    result = operate.Subscribe(address);
    LogHelper.Info(result.ToJson().JsonFormatting());

    //写入
    ConcurrentDictionary<string, string> value = new ConcurrentDictionary<string, string>
    {
        ["地址"] = "值"
    };
    result = operate.Write(value);
    LogHelper.Info(result.ToJson().JsonFormatting());

    //关闭
    result = operate.Off();
    LogHelper.Info(result.ToJson().JsonFormatting());
}

------------------------------------------------------

//转发协议
using (类 operate = new 类(new 类数据.Basics
{

    //转发对象参数

}))
{
    //打开
    OperateResult result = operate.On();
    LogHelper.Info(result.ToJson().JsonFormatting());

    //生产
    result = operate.Produce("主题", "内容");
    LogHelper.Info(result.ToJson().JsonFormatting());

    //消费
    operate.OnEvent += delegate (object? sender, EventResult e)
    {
        LogHelper.Info(e.ToJson().JsonFormatting());
    };
    result = operate.Subscribe("主题");
    LogHelper.Info(result.ToJson().JsonFormatting());

    //关闭
    result = operate.Off();
    LogHelper.Info(result.ToJson().JsonFormatting());
}

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

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

更新表

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. 优化数据解析流程,优化转发流程