## 阐述
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. 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]
```sharp
namespace YSAI.Core.@interface
{
///
/// 数采接口
///
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
```sharp
namespace YSAI.Core.@interface
{
///
/// 转发接口
///
public interface IRelay : IOn, IOff, IProducer, IConsumer, IGetStatus, IEvent, IGetParam, ICreateInstance, IDisposable
{ }
}
```
## 应用
```sharp
1.上 NUGET 搜索 YSAI
2.安装对应的协议包
3.应用代码如下
4.协议包内还有内部公共方法,请自行研究使用
------------------------------------------------------
//实例创建的几种方式
//第一种方式
BeckhoffOperate beckhoffOperate1 = new BeckhoffOperate();
//第二种方式(单例模式)
BeckhoffOperate? beckhoffOperate2 = new BeckhoffOperate().CreateInstance(new BeckhoffData.Basics()).GetRData();
//第三种方式(单例模式)
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())
{
//使用完直接释放这个单例
}
//第九种方式
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();
//第二种与第三种就是直接创建单例模式,但第二种是为了在反射的情况下使用单例模式,第二种也是为第一种情况而产生
------------------------------------------------------
//采集协议
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
{
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() { "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 value = new ConcurrentDictionary
{
["地址"] = "值"
};
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. 采集订阅流程实现多线程队列形式,处理速度大大提升
```sharp
//更新,无休眠时间
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包位置更新