Compare commits

...

52 Commits

Author SHA1 Message Date
Kimdiego2098
6a70ef9f31 2.1.0.1 2023-08-27 16:31:03 +08:00
Kimdiego2098
82cc4ca500 dlt645添加数据标识校验 2023-08-27 16:30:32 +08:00
Kimdiego2098
4567fa04ed 更新dlt645,添加地址/控制码的校验规则 2023-08-27 16:15:51 +08:00
Kimdiego2098
8b98b5d818 更新touchsocket 2023-08-27 15:59:57 +08:00
Kimdiego2098
176d0351af 更新 Opc.Ua Version="1.4.372.56" 2023-08-27 14:33:24 +08:00
Kimdiego2098
d63dc3384b opcda/ua浏览地址空间 初始只加载首层节点 2023-08-27 14:14:47 +08:00
Kimdiego2098
1ccd704e30 opcuaclient浏览地址空间 初始只加载首层节点 2023-08-27 13:06:03 +08:00
Diego2098
f5d23dbe79 update MqttNetLogger 2023-08-26 21:38:14 +08:00
Diego2098
75bfe53ac3 update MqttNetLogger 2023-08-26 20:40:23 +08:00
Diego2098
3308f916dd 添加在线/离线方法参数 2023-08-26 17:18:47 +08:00
Diego2098
e7140279ca 更新opcuaclient 2023-08-26 15:38:22 +08:00
Diego2098
1034719f5e 更新opcuaclient,添加checkDomain属性,去除多余代码,更新SelectEndpoint方法 2023-08-26 15:33:03 +08:00
Kimdiego2098
2c00043a7f 更新文档 2023-08-25 19:49:02 +08:00
Kimdiego2098
65c695d9ce 更新版本2.1.0 2023-08-25 19:45:28 +08:00
Kimdiego2098
57253fe46a 更新解决方案 2023-08-25 19:38:47 +08:00
Kimdiego2098
4e5c443440 更新DLT645文档 2023-08-25 19:33:33 +08:00
Kimdiego2098
0b3b73d8ec 添加DLT645_2007协议插件 2023-08-25 19:33:08 +08:00
Kimdiego2098
921eabc134 调整Test位置 2023-08-25 19:32:27 +08:00
Kimdiego2098
0faa428751 调整非主从协议的状态判断策略;OPCUA去除主动连接 2023-08-25 17:23:00 +08:00
Kimdiego2098
f71a2fdd63 crc校验优化 2023-08-22 17:01:10 +08:00
Kimdiego2098
4eb9ed8aba OPCUAClient添加是否使用SourceTime的选项 2023-08-22 16:15:34 +08:00
Kimdiego2098
d7b549abb8 更新文档 2023-08-22 12:21:45 +08:00
Kimdiego2098
95d723c578 2.0.9.3 2023-08-22 11:31:36 +08:00
Kimdiego2098
2fcd853e86 去除mqtt throw an _MqttConnectingFailedException_.报错信息 2023-08-22 11:26:22 +08:00
Kimdiego2098
07eef7c812 更新批量写入方法,注意rpc入口参数变化,mqtt等RPC接口参数变化 2023-08-22 11:23:03 +08:00
Kimdiego2098
b01e0757fa 修正部分代码格式 2023-08-21 19:59:07 +08:00
Kimdiego2098
32844a20c6 2.0.9.2 2023-08-19 12:08:49 +08:00
Kimdiego2098
5b6532c601 xml 2023-08-19 11:06:05 +08:00
Kimdiego2098
2c5b4b4027 修复TcpClient重复释放导致锁异常 2023-08-19 11:05:29 +08:00
Kimdiego2098
72d7ecf195 mas1.0.2默认中文 2023-08-18 18:36:30 +08:00
Kimdiego2098
2cfa6b4306 更新masa1.0.2 2023-08-18 13:59:17 +08:00
Kimdiego2098
6f6ffde0ab 2.0.9.1 2023-08-18 13:33:45 +08:00
Kimdiego2098
1694739a16 修改锁为EasyLock 2023-08-18 12:07:01 +08:00
Kimdiego2098
95d1e8bfca 代码文件编码统一utf-8 2023-08-18 09:57:03 +08:00
Kimdiego2098
60dec08e3c 更换DEMO Include为PackageReference 2023-08-17 15:30:35 +08:00
Kimdiego2098
a99d71be93 底层驱动添加netstandard输出 2023-08-17 15:24:07 +08:00
Kimdiego2098
f1331b6a0c 2.0.8 2023-08-17 10:58:48 +08:00
Kimdiego2098
10d66b642b 调整readme,方便copy账密 2023-08-17 10:28:47 +08:00
Kimdiego2098
cd2310e4a8 优化变量地址输入分割方法;s7读写字符串添加默认编码 2023-08-17 09:50:10 +08:00
Kimdiego2098
1b399cf6b0 优化s7读写字符串,更改特殊方法为读写共用 2023-08-16 17:20:20 +08:00
Kimdiego2098
877445bc0a 修复写入返回结果时的解析,0XFF为成功 2023-08-16 15:56:25 +08:00
Kimdiego2098
9a5b345bde 修复s7字符串打包读取 2023-08-16 15:47:37 +08:00
Kimdiego2098
fc9e8ea7b3 修复s7字符串读取 2023-08-16 15:35:15 +08:00
Kimdiego2098
32be6fcfc1 主动释放锁 2023-08-16 14:56:47 +08:00
Kimdiego2098
49847236c2 OPCUA死区不再固定传入 2023-08-16 14:21:19 +08:00
Kimdiego2098
d8424443e6 fix: 优化JsonUtils中的获取type语句顺序 2023-08-16 08:59:18 +08:00
Kimdiego2098
f3b571ec3f OPC系列增加导出excel/导入系统双选项 2023-08-15 17:38:40 +08:00
Kimdiego2098
99318bb5d7 OPCUA采集设备写入字符串,不再需要传入双引号 2023-08-15 14:15:39 +08:00
Kimdiego2098
1aa154c9aa 历史数据/报警 线程初始化时不再阻塞 2023-08-15 12:12:00 +08:00
Kimdiego2098
c65d8a445b 更改ItemGroup Condition条件 2023-08-14 17:36:59 +08:00
Kimdiego2098
80f4f85570 传播token;
更新admin解决方案
2023-08-14 16:43:30 +08:00
Kimdiego2098
5beee43a6b 优化适配器解析代码 2023-08-14 14:21:00 +08:00
276 changed files with 7720 additions and 2715 deletions

View File

@@ -22,7 +22,9 @@
[ThingsGateway演示地址](http://120.24.62.140:5000/)
账户 : **superAdmin** 密码 : **111111**
账户 : **superAdmin**
密码 : **111111**
## 赞助

View File

@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<Version>2.0.6.0</Version>
<Version>2.1.0.1</Version>
<Authors>Diego</Authors>
<Product>ThingsGateway</Product>
<Copyright>© 2023-present Diego</Copyright>

View File

@@ -18,6 +18,7 @@ using System.Reflection;
using System.Text;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
using UAParser;

View File

@@ -20,6 +20,7 @@ using System.Globalization;
using System.Reflection;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
using Yitter.IdGenerator;

View File

@@ -13,6 +13,8 @@
using System.Text;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Application;
/// <summary>

View File

@@ -16,6 +16,7 @@ using Furion.FriendlyException;
using Mapster;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Application;

View File

@@ -17,6 +17,7 @@ using Furion.FriendlyException;
using Mapster;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
using Yitter.IdGenerator;

View File

@@ -19,6 +19,7 @@ using Mapster;
using SqlSugar;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Application;

View File

@@ -17,6 +17,7 @@ using Furion.FriendlyException;
using Mapster;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Application;

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -20,19 +20,19 @@ namespace ThingsGateway.Admin.Blazor.Core;
public partial class AppBarItems
{
/// <summary>
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 链接
/// </summary>
[Parameter]
public string CONFIG_COPYRIGHT_URL { get; set; }
/// <summary>
/// <EFBFBD><EFBFBD>Ȩ
/// 版权
/// </summary>
[Parameter]
public string CONFIG_COPYRIGHT { get; set; }
/// <summary>
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 标题
/// </summary>
[Parameter]
public string CONFIG_TITLE { get; set; }

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -14,7 +14,7 @@ using Microsoft.AspNetCore.Components;
namespace ThingsGateway.Admin.Blazor.Core;
/// <summary>
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><><CDA3> <20>ı<EFBFBD><C4B1><EFBFBD>ʾ
/// 启用/停用 文本提示
/// </summary>
public partial class EnableChip
{
@@ -46,5 +46,5 @@ public partial class EnableChip
private string TextColor => Value ? "green" : "error";
private string Color => Value ? "green-lighten" : "warning-lighten";
private string Label => Value ? EnabledLabel ?? "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>" : DisabledLabel ?? "ͣ<EFBFBD><EFBFBD>";
private string Label => Value ? EnabledLabel ?? "启用" : DisabledLabel ?? "停用";
}

View File

@@ -1,18 +1,18 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Admin.Blazor.Core;
/// <summary>
/// <EFBFBD>ղ<EFBFBD>/<2F><><EFBFBD>ݷ<EFBFBD>ʽ
/// 收藏/快捷方式
/// </summary>
public partial class Favorite
{

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -22,17 +22,17 @@ public partial class Foter
{
private string Version = "";
/// <summary>
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 链接
/// </summary>
[Parameter]
public string CONFIG_COPYRIGHT_URL { get; set; }
/// <summary>
/// <EFBFBD><EFBFBD>Ȩ
/// 版权
/// </summary>
[Parameter]
public string CONFIG_COPYRIGHT { get; set; }
/// <summary>
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 标题
/// </summary>
[Parameter]
public string CONFIG_TITLE { get; set; }

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -20,23 +20,23 @@ namespace ThingsGateway.Admin.Blazor.Core;
public partial class Logo
{
/// <summary>
/// Logo<EFBFBD>߶<EFBFBD>
/// Logo高度
/// </summary>
[Parameter]
public int HeightInt { get; set; }
/// <summary>
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 链接
/// </summary>
[Parameter]
public string CONFIG_COPYRIGHT_URL { get; set; }
/// <summary>
/// <EFBFBD><EFBFBD>Ȩ
/// 版权
/// </summary>
[Parameter]
public string CONFIG_COPYRIGHT { get; set; }
/// <summary>
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 标题
/// </summary>
[Parameter]
public string CONFIG_TITLE { get; set; }

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -34,7 +34,7 @@ public partial class PageTabs
return op;
}
/// <summary>
/// Tabsʵ<EFBFBD><EFBFBD>
/// Tabs实例
/// </summary>
public PPageTabs PPageTabs { get; private set; }
@@ -46,7 +46,7 @@ public partial class PageTabs
[Parameter]
public IEnumerable<string> SelfPatterns { get; set; }
/// <summary>
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 子组件
/// </summary>
[Parameter]
public RenderFragment ChildContent { get; set; }

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -17,6 +17,7 @@ using Masa.Blazor;
using Microsoft.AspNetCore.Components;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Blazor.Core;
/// <summary>
@@ -49,11 +50,11 @@ public partial class UserMenu
var ret = str?.ToJsonWithT<UnifyResult<string>>();
if (ret?.Code != 200)
{
await PopupService.EnqueueSnackbarAsync("ע<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>", AlertTypes.Error);
await PopupService.EnqueueSnackbarAsync("注销失败", AlertTypes.Error);
}
else
{
await PopupService.EnqueueSnackbarAsync("ע<EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>", AlertTypes.Success);
await PopupService.EnqueueSnackbarAsync("注销成功", AlertTypes.Success);
await Task.Delay(500);
NavigationManager.NavigateTo(NavigationManager.Uri);
}

View File

@@ -0,0 +1,68 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using Furion.DependencyInjection;
namespace BlazorComponent.I18n;
/// <summary>
/// CookieStorage
/// </summary>
public class CookieStorage : IScoped
{
private readonly IJSRuntime _jsRuntime;
/// <summary>
/// CookieStorage
/// </summary>
/// <param name="jsRuntime"></param>
public CookieStorage(IJSRuntime jsRuntime)
{
_jsRuntime = jsRuntime;
}
/// <summary>
/// GetCookieAsync
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<string> GetCookieAsync(string key)
{
return await _jsRuntime.InvokeAsync<string>(JsInteropConstants.GetCookie, key);
}
/// <summary>
/// GetCookie
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string GetCookie(string key)
{
if (_jsRuntime is IJSInProcessRuntime jsInProcess)
{
return jsInProcess.Invoke<string>(JsInteropConstants.GetCookie, key);
}
return null;
}
/// <summary>
/// SetItemAsync
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
public async void SetItemAsync<T>(string key, T value)
{
try
{
await _jsRuntime.InvokeVoidAsync(JsInteropConstants.SetCookie, key, value?.ToString());
}
catch
{
}
}
}

View File

@@ -10,6 +10,8 @@
//------------------------------------------------------------------------------
#endregion
using BlazorComponent;
using Furion;
using Masa.Blazor;
@@ -61,6 +63,8 @@ public class Startup : AppStartup
});
options.Locale = new Locale("zh-CN", "en-US");
});
services.AddScoped<InitTimezone>();

View File

@@ -14,7 +14,7 @@
<ItemGroup>
<PackageReference Include="Masa.Blazor" Version="1.0.1" />
<PackageReference Include="Masa.Blazor" Version="1.0.2" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="7.0.10" />
</ItemGroup>

View File

@@ -857,5 +857,38 @@
设置深浅主题统一由这个方法为入口
</summary>
</member>
<member name="T:BlazorComponent.I18n.CookieStorage">
<summary>
CookieStorage
</summary>
</member>
<member name="M:BlazorComponent.I18n.CookieStorage.#ctor(Microsoft.JSInterop.IJSRuntime)">
<summary>
CookieStorage
</summary>
<param name="jsRuntime"></param>
</member>
<member name="M:BlazorComponent.I18n.CookieStorage.GetCookieAsync(System.String)">
<summary>
GetCookieAsync
</summary>
<param name="key"></param>
<returns></returns>
</member>
<member name="M:BlazorComponent.I18n.CookieStorage.GetCookie(System.String)">
<summary>
GetCookie
</summary>
<param name="key"></param>
<returns></returns>
</member>
<member name="M:BlazorComponent.I18n.CookieStorage.SetItemAsync``1(System.String,``0)">
<summary>
SetItemAsync
</summary>
<typeparam name="T"></typeparam>
<param name="key"></param>
<param name="value"></param>
</member>
</members>
</doc>

View File

@@ -20,6 +20,7 @@ using Microsoft.AspNetCore.Http;
using ThingsGateway.Admin.Application;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Blazor.Core;
@@ -153,7 +154,7 @@ public class UserResoures : IDisposable
{
if (MasaBlazor.Theme.Dark != isDark || isDark == null)
MasaBlazor.ToggleTheme();
_cookieStorage?.SetItemAsync(BlazorResourceConst.ThemeCookieKey, isDark.ToJsonString());
_cookieStorage?.SetItemAsync(BlazorResourceConst.ThemeCookieKey, MasaBlazor.Theme.Dark.ToJsonString());
}
private void InitCookie(IRequestCookieCollection cookies)

View File

@@ -48,8 +48,7 @@
var controllerTypes = App.EffectiveTypes.
Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
&& u.IsDefined(typeof(Microsoft.AspNetCore.Components.RouteAttribute), false))
.Where(it => it.Assembly != typeof(BlazorApp).Assembly)
;
.Where(it => it.Assembly != typeof(BlazorApp).Assembly);
var assemblys = controllerTypes?.Select(it => it.Assembly)?.Distinct();
return assemblys;
}

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -18,7 +18,7 @@ using ThingsGateway.Admin.Core;
namespace ThingsGateway.Admin.Blazor;
/// <summary>
/// <EFBFBD><EFBFBD>ҳ
/// 首页
/// </summary>
public partial class Index
{

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -18,7 +18,7 @@ using ThingsGateway.Admin.Core;
namespace ThingsGateway.Admin.Blazor;
/// <summary>
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 个人设置
/// </summary>
public partial class UserCenter
{
@@ -50,25 +50,25 @@ public partial class UserCenter
{
await UserCenterService.UpdateUserDefaultRazorAsync(UserManager.UserId, DefaultMenuId);
await MainLayout.StateHasChangedAsync();
await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD>", AlertTypes.Success);
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
}
async Task OnShortcutSaveAsync()
{
await UserCenterService.UpdateWorkbenchAsync(_menusChoice);
await MainLayout.StateHasChangedAsync();
await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD>", AlertTypes.Success);
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
}
async Task OnUpdatePasswordInfoAsync(FormContext context)
{
var success = context.Validate();
if (success)
{
//<EFBFBD><EFBFBD>֤<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD>
//验证成功,操作业务
_passwordInfoInput.Id = UserResoures.CurrentUser.Id;
await UserCenterService.EditPasswordAsync(_passwordInfoInput);
await MainLayout.StateHasChangedAsync();
await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>¼", AlertTypes.Success);
await PopupService.EnqueueSnackbarAsync("成功,将重新登录", AlertTypes.Success);
await Task.Delay(2000);
NavigationManager.NavigateTo(NavigationManager.Uri);
}
@@ -78,6 +78,6 @@ public partial class UserCenter
{
await UserCenterService.UpdateUserInfoAsync(_updateInfoInput);
await MainLayout.StateHasChangedAsync();
await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD>", AlertTypes.Success);
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
}
}

View File

@@ -21,6 +21,7 @@ using Microsoft.Extensions.Hosting;
using ThingsGateway.Admin.Application;
using ThingsGateway.Admin.Blazor.Core;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Blazor;

View File

@@ -12,7 +12,7 @@
using Furion.DependencyInjection;
namespace ThingsGateway.Admin.Core;
namespace ThingsGateway.Admin.Core.JsonExtensions;
/// <summary>
/// 对象拓展

View File

@@ -18,6 +18,8 @@ using System.Collections;
using System.Data;
using System.Reflection;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Core;
/// <summary>

View File

@@ -9,10 +9,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.8.40" />
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.8.40" />
<PackageReference Include="Furion.Pure" Version="4.8.8.40" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.96" />
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.8.41" />
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.8.41" />
<PackageReference Include="Furion.Pure" Version="4.8.8.41" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.102" />
<PackageReference Include="UAParser" Version="3.1.47" />
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
<PackageReference Include="MiniExcel" Version="1.31.2" />

View File

@@ -850,19 +850,19 @@
<param name="this"></param>
<param name="values"></param>
</member>
<member name="T:ThingsGateway.Admin.Core.JsonExtensions">
<member name="T:ThingsGateway.Admin.Core.JsonExtensions.JsonExtensions">
<summary>
对象拓展
</summary>
</member>
<member name="M:ThingsGateway.Admin.Core.JsonExtensions.ToJsonString(System.Object)">
<member name="M:ThingsGateway.Admin.Core.JsonExtensions.JsonExtensions.ToJsonString(System.Object)">
<summary>
转换为Json
</summary>
<param name="item"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Admin.Core.JsonExtensions.ToJsonWithT``1(System.String)">
<member name="M:ThingsGateway.Admin.Core.JsonExtensions.JsonExtensions.ToJsonWithT``1(System.String)">
<summary>
从字符串到json
</summary>

View File

@@ -89,13 +89,8 @@ public class RpcControler : IDynamicApiController
[Description("写入变量")]
public async Task<Dictionary<string, OperResult>> WriteDeviceMethods(Dictionary<string, string> objs)
{
Dictionary<string, OperResult> operResultDict = new();
foreach (KeyValuePair<string, string> obj in objs)
{
var result = await RpcCore.InvokeDeviceMethodAsync($"WebApi-{UserManager.UserAccount}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}", obj);
operResultDict.Add(obj.Key, result);
}
return operResultDict;
var result = await RpcCore.InvokeDeviceMethodAsync($"WebApi-{UserManager.UserAccount}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}", objs);
return result;
}
}

View File

@@ -80,7 +80,7 @@ public class StringToEncodingConverter : IConverter<string>
{
try
{
source = target.ToJson();
source = target.ToJsonString();
return true;
}
catch (Exception)

View File

@@ -21,7 +21,7 @@ using Newtonsoft.Json.Converters;
using System.Dynamic;
using System.Text;
using TouchSocket.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Application;
/// <summary>
@@ -76,7 +76,7 @@ public class CSharpScriptEngine : ISingleton
var expConverter = new ExpandoObjectConverter();
dynamic obj = JsonConvert.DeserializeObject<List<ExpandoObject>>(input, expConverter);
object result = runscript(obj);
var json = result.ToJson();
var json = result.ToJsonString();
return json;
}
@@ -116,7 +116,7 @@ public class CSharpScriptEngine : ISingleton
var expConverter = new ExpandoObjectConverter();
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(input, expConverter);
object result = runscript(obj);
var json = result.ToJson();
var json = result.ToJsonString();
return json;
}
@@ -136,7 +136,7 @@ public static class CSharpScriptEngineExtension
/// </summary>
public static string GetSciptListValue<T>(this T datas, string script) where T : class
{
var inPut = datas.ToJson();
var inPut = datas.ToJsonString();
if (!string.IsNullOrEmpty(script))
{
//执行脚本,获取新实体
@@ -154,7 +154,7 @@ public static class CSharpScriptEngineExtension
/// </summary>
public static string GetSciptValue<T>(this T datas, string script) where T : class
{
var inPut = datas.ToJson();
var inPut = datas.ToJsonString();
if (!string.IsNullOrEmpty(script))
{
//执行脚本,获取新实体

View File

@@ -82,18 +82,15 @@ public class DeviceVariableRunTime : DeviceVariable
/// </summary>
/// <param name="value"></param>
/// <param name="dateTime"></param>
public OperResult SetValue(object value, DateTime dateTime = default)
/// <param name="isOnline"></param>
public OperResult SetValue(object value, DateTime dateTime = default,bool isOnline=true)
{
try
{
IsOnline = isOnline;
if (value != null)
if (!IsOnline)
{
IsOnline = true;
}
else
{
IsOnline = false;
RawValue = value;
Set(value);
return OperResult.CreateSuccessResult();

View File

@@ -36,6 +36,10 @@ public abstract class CollectBase : DriverBase
/// </summary>
/// <returns></returns>
public abstract bool IsSupportRequest { get; }
/// <summary>
/// 一般底层驱动也有可能为null
/// </summary>
protected abstract IReadWriteDevice PLC { get; }
/// <summary>
/// 数据转换器
@@ -98,9 +102,9 @@ public abstract class CollectBase : DriverBase
StopBits = config.StopBits,
};
FoundataionConfig.SetValue(SerialConfigExtension.SerialProperty, data);
var serialClient = new SerialClient();
(serialClient).Setup(FoundataionConfig);
return OperResult.CreateSuccessResult((object)serialClient);
var serialSession = new SerialsSession();
(serialSession).Setup(FoundataionConfig);
return OperResult.CreateSuccessResult((object)serialSession);
case ShareChannelEnum.TcpClientEx:
FoundataionConfig.SetRemoteIPHost(new IPHost($"{config.IP}:{config.Port}"));
var tcpClient = new TcpClientEx();
@@ -153,7 +157,7 @@ public abstract class CollectBase : DriverBase
{
deviceVariableSourceRead.DeviceVariables.ForEach(it =>
{
var operResult = it.SetValue(null);
var operResult = it.SetValue(null,isOnline:false);
if (!operResult.IsSuccess)
{
_logger.LogWarning("变量值更新失败:" + operResult.Message);
@@ -177,10 +181,22 @@ public abstract class CollectBase : DriverBase
}
/// <summary>
/// 写入变量值
/// 批量写入变量值,需返回变量名称/结果
/// </summary>
/// <returns></returns>
public abstract Task<OperResult> WriteValueAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token);
public virtual async Task<Dictionary<string, OperResult>> WriteValuesAsync(Dictionary<DeviceVariableRunTime, JToken> writeInfoLists, CancellationToken token)
{
if (PLC == null)
throw new("未初始化成功");
Dictionary<string, OperResult> operResults = new();
foreach (var writeInfo in writeInfoLists)
{
var result = await PLC.WriteAsync(writeInfo.Key.VariableAddress, writeInfo.Key.DataType, writeInfo.Value.ToString(), token);
await Task.Delay(10, token); //防止密集写入
operResults.Add(writeInfo.Key.Name, result);
}
return operResults;
}
/// <summary>
/// 初始化

View File

@@ -19,6 +19,7 @@ using Newtonsoft.Json.Linq;
using System.Collections.Concurrent;
using ThingsGateway.Admin.Core.JsonExtensions;
using ThingsGateway.Foundation;
using ThingsGateway.Foundation.Extension.ConcurrentQueue;
@@ -48,92 +49,172 @@ public class RpcSingletonService : ISingleton
/// 反向RPC入口方法
/// </summary>
/// <param name="sourceDes">触发该方法的源说明</param>
/// <param name="item">指定键为变量名称,值为附带方法参数或写入值</param>
/// <param name="items">指定键为变量名称,值为附带方法参数或写入值</param>
/// <param name="isBlazor">如果是true不检查<see cref="MemoryVariable.RpcWriteEnable"/>字段</param>
/// <param name="token"><see cref="CancellationToken"/> 取消源</param>
/// <returns></returns>
public async Task<OperResult> InvokeDeviceMethodAsync(string sourceDes, KeyValuePair<string, string> item, bool isBlazor = false, CancellationToken token = default)
public async Task<Dictionary<string, OperResult>> InvokeDeviceMethodAsync(string sourceDes, Dictionary<string, string> items, bool isBlazor = false, CancellationToken token = default)
{
//避免并发过高这里延时10ms
await Task.Delay(10, token);
OperResult data = new();
var tag = _globalDeviceData.AllVariables.FirstOrDefault(it => it.Name == item.Key);
if (tag == null) return new OperResult("不存在变量:" + item.Key);
if (tag.ProtectTypeEnum == ProtectTypeEnum.ReadOnly) return new OperResult("只读变量");
if (!tag.RpcWriteEnable && !isBlazor) return new OperResult("不允许远程写入");
if (tag.IsMemoryVariable == true)
Dictionary<CollectDeviceCore, Dictionary<DeviceVariableRunTime, JToken>> WriteVariables = new();
Dictionary<CollectDeviceCore, Dictionary<DeviceVariableRunTime, string>> WriteMethods = new();
Dictionary<string, OperResult> results = new();
foreach (var item in items)
{
return tag.SetValue(item.Value);
}
var dev = _collectDeviceHostService.CollectDeviceCores.FirstOrDefault(it => it.Device.Id == tag.DeviceId);
if (dev == null) return new OperResult("系统错误,不存在对应采集设备,请稍候重试");
if (dev.Device.DeviceStatus == DeviceStatusEnum.OffLine) return new OperResult("设备已离线");
if (dev.Device.DeviceStatus == DeviceStatusEnum.Pause) return new OperResult("设备已暂停");
if (string.IsNullOrEmpty(tag.OtherMethod))
{
//写入变量
JToken tagValue;
try
{
tagValue = JToken.Parse(item.Value);
}
catch (Exception)
{
tagValue = JToken.Parse("\"" + item.Value + "\"");
}
data = await dev.InVokeWriteAsync(tag, tagValue, token);
_logQueues.Enqueue(
new RpcLog()
OperResult data = new();
var tag = _globalDeviceData.AllVariables.FirstOrDefault(it => it.Name == item.Key);
if (tag == null)
results.Add(item.Key, new("不存在变量:" + item.Key));
if (tag.ProtectTypeEnum == ProtectTypeEnum.ReadOnly)
results.Add(item.Key, new("只读变量:" + item.Key));
if (!tag.RpcWriteEnable && !isBlazor)
results.Add(item.Key, new("不允许远程写入:" + item.Key));
if (tag.IsMemoryVariable == true)
{
results.Add(item.Key, tag.SetValue(item.Value));
}
var dev = _collectDeviceHostService.CollectDeviceCores.FirstOrDefault(it => it.Device.Id == tag.DeviceId);
if (dev == null)
results.Add(item.Key, new OperResult("系统错误,不存在对应采集设备,请稍候重试"));
if (dev.Device.DeviceStatus == DeviceStatusEnum.OffLine)
results.Add(item.Key, new OperResult("设备已离线"));
if (dev.Device.DeviceStatus == DeviceStatusEnum.Pause)
results.Add(item.Key, new OperResult("设备已暂停"));
if (!results.ContainsKey(item.Key))
{
if (string.IsNullOrEmpty(tag.OtherMethod))
{
LogTime = SysDateTimeExtensions.CurrentDateTime,
OperateMessage = data.Exception,
IsSuccess = data.IsSuccess,
OperateMethod = WriteVariable,
OperateObject = tag.Name,
OperateSource = sourceDes,
ParamJson = item.Value,
ResultJson = data.Message
//写入变量
JToken tagValue;
try
{
tagValue = JToken.Parse(item.Value);
}
catch (Exception)
{
tagValue = JToken.Parse("\"" + item.Value + "\"");
}
if (WriteVariables.ContainsKey(dev))
{
WriteVariables[dev].Add(tag, tagValue);
}
else
{
WriteVariables.Add(dev, new());
WriteVariables[dev].Add(tag, tagValue);
}
}
else
{
if (WriteMethods.ContainsKey(dev))
{
WriteMethods[dev].Add(tag, item.Value);
}
else
{
WriteVariables.Add(dev, new());
WriteVariables[dev].Add(tag, item.Value);
}
}
);
if (!data.IsSuccess)
{
_logger.LogWarning($"写入变量[{tag.Name}]失败:{data.Message}");
}
}
else
foreach (var item in WriteVariables)
{
//执行变量附带的方法
var method = dev.DeviceVariableMethodSources.FirstOrDefault(it => it.DeviceVariable == tag);
try
{
data = await dev.InvokeMethodAsync(method, false, item.Value, token);
var result = await item.Key.InVokeWriteAsync(item.Value, token);
foreach (var resultItem in result)
{
string operObj;
string parJson;
if (resultItem.Key.IsNullOrEmpty())
{
operObj = items.Select(x => x.Key).ToJsonString();
parJson = items.Select(x => x.Value).ToJsonString();
}
else
{
operObj = resultItem.Key;
parJson = items[resultItem.Key];
}
_logQueues.Enqueue(
new RpcLog()
{
LogTime = SysDateTimeExtensions.CurrentDateTime,
OperateMessage = resultItem.Value.Exception,
IsSuccess = resultItem.Value.IsSuccess,
OperateMethod = WriteVariable,
OperateObject = operObj,
OperateSource = sourceDes,
ParamJson = parJson,
ResultJson = resultItem.Value.Message
}
);
if (!resultItem.Value.IsSuccess)
{
_logger.LogWarning($"写入变量[{resultItem.Key}]失败:{resultItem.Value.Message}");
}
}
results.AddRange(result);
}
catch (Exception ex)
{
data = new OperResult<string>(ex);
}
_logQueues.Enqueue(
new RpcLog()
{
LogTime = SysDateTimeExtensions.CurrentDateTime,
OperateMessage = data.Exception,
IsSuccess = data.IsSuccess,
OperateMethod = tag.OtherMethod,
OperateObject = tag.Name,
OperateSource = sourceDes,
ParamJson = item.Value?.ToString(),
ResultJson = data.Message
}
);
if (!data.IsSuccess)
{
_logger.LogWarning($"执行变量[{tag.Name}]方法[{tag.OtherMethod}]失败:{data.Message}");
_logger.LogWarning($"写入变量异常:{ex.Message + Environment.NewLine + ex.StackTrace}");
}
}
return data;
foreach (var item in WriteMethods)
{
foreach (var writeMethod in item.Value)
{
//执行变量附带的方法
var method = item.Key.DeviceVariableMethodSources.FirstOrDefault(it => it.DeviceVariable == writeMethod.Key);
OperResult<string> result;
try
{
result = await item.Key.InvokeMethodAsync(method, false, writeMethod.Value, token);
results.Add(writeMethod.Key.Name, result);
}
catch (Exception ex)
{
result = new OperResult<string>(ex);
results.Add(writeMethod.Key.Name, result);
}
_logQueues.Enqueue(
new RpcLog()
{
LogTime = SysDateTimeExtensions.CurrentDateTime,
OperateMessage = result.Exception,
IsSuccess = result.IsSuccess,
OperateMethod = writeMethod.Key.OtherMethod,
OperateObject = writeMethod.Key.Name,
OperateSource = sourceDes,
ParamJson = writeMethod.Value?.ToString(),
ResultJson = result.Message
}
);
if (!result.IsSuccess)
{
_logger.LogWarning($"执行变量[{writeMethod.Key.Name}]方法[{writeMethod.Key.OtherMethod}]失败:{result.Message}");
}
}
}
return results;
}
private async Task RpcLogInsertAsync()
{

View File

@@ -319,6 +319,39 @@
"UpdateUserId": null,
"SortCode": 0,
"ExtJson": null
},
{
"Id": 442505,
"FileName": "ThingsGateway.DLT645",
"AssembleName": "DLT645_2007",
"DriverTypeEnum": "Collect",
"FilePath": "Plugins/ThingsGateway.DLT645/ThingsGateway.DLT645.dll",
"CreateTime": "2023/8/6 18:22:33",
"CreateUser": "superAdmin",
"CreateUserId": 212725263002001,
"IsDelete": 0,
"UpdateTime": null,
"UpdateUser": null,
"UpdateUserId": null,
"SortCode": 0,
"ExtJson": null
},
{
"Id": 442506,
"FileName": "ThingsGateway.DLT645",
"AssembleName": "DLT645_2007OverTcp",
"DriverTypeEnum": "Collect",
"FilePath": "Plugins/ThingsGateway.DLT645/ThingsGateway.DLT645.dll",
"CreateTime": "2023/8/6 18:22:33",
"CreateUser": "superAdmin",
"CreateUserId": 212725263002001,
"IsDelete": 0,
"UpdateTime": null,
"UpdateUser": null,
"UpdateUserId": null,
"SortCode": 0,
"ExtJson": null
}
]
}

View File

@@ -55,7 +55,7 @@ public interface IVariableService : ITransient
/// <summary>
/// 导出
/// </summary>
Task<MemoryStream> ExportFileAsync(List<DeviceVariable> collectDeviceVariables = null);
Task<MemoryStream> ExportFileAsync(List<DeviceVariable> collectDeviceVariables = null, string deviceName = null);
/// <summary>
/// 导出
/// </summary>

View File

@@ -318,7 +318,7 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
/// <inheritdoc/>
[OperDesc("导出采集变量表", IsRecordPar = false)]
public async Task<MemoryStream> ExportFileAsync(List<DeviceVariable> deviceVariables = null)
public async Task<MemoryStream> ExportFileAsync(List<DeviceVariable> deviceVariables = null, string deviceName = null)
{
deviceVariables ??= await GetListAsync(a => !a.IsMemoryVariable);
@@ -343,7 +343,8 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
);
Dictionary<string, object> variableExport = new();
//变量实体没有包含设备名称,手动插入
variableExport.Add(ExportHelpers.DeviceName, collectDeviceDicts[devData.DeviceId].Name);
var devName = collectDeviceDicts.GetValueOrDefault(devData.DeviceId)?.Name ?? deviceName;
variableExport.Add(ExportHelpers.DeviceName, devName);
foreach (var item in data)
{

View File

@@ -37,7 +37,7 @@
<PackageReference Include="Hardware.Info" Version="11.1.1.1" />
<PackageReference Include="CS-Script" Version="4.8.1" />
<!--CS-Script与Furion冲突直接安装覆盖版本-->
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.6.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.7.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -1601,12 +1601,13 @@
最近一次值
</summary>
</member>
<member name="M:ThingsGateway.Application.DeviceVariableRunTime.SetValue(System.Object,System.DateTime)">
<member name="M:ThingsGateway.Application.DeviceVariableRunTime.SetValue(System.Object,System.DateTime,System.Boolean)">
<summary>
设置变量值与时间设置为null时只更改质量戳状态
</summary>
<param name="value"></param>
<param name="dateTime"></param>
<param name="isOnline"></param>
</member>
<member name="P:ThingsGateway.Application.DeviceVariableRunTime.ChangeTime">
<summary>
@@ -1855,6 +1856,11 @@
</summary>
<returns></returns>
</member>
<member name="P:ThingsGateway.Application.CollectBase.PLC">
<summary>
一般底层驱动也有可能为null
</summary>
</member>
<member name="P:ThingsGateway.Application.CollectBase.ThingsGatewayBitConverter">
<summary>
数据转换器
@@ -1906,9 +1912,9 @@
采集驱动读取
</summary>
</member>
<member name="M:ThingsGateway.Application.CollectBase.WriteValueAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)">
<member name="M:ThingsGateway.Application.CollectBase.WriteValuesAsync(System.Collections.Generic.Dictionary{ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken},System.Threading.CancellationToken)">
<summary>
写入变量值
批量写入变量值,需返回变量名称/结果
</summary>
<returns></returns>
</member>
@@ -2242,12 +2248,12 @@
<member name="M:ThingsGateway.Application.RpcSingletonService.#ctor(Microsoft.Extensions.Logging.ILogger{ThingsGateway.Application.RpcSingletonService})">
<inheritdoc cref="T:ThingsGateway.Application.RpcSingletonService"/>
</member>
<member name="M:ThingsGateway.Application.RpcSingletonService.InvokeDeviceMethodAsync(System.String,System.Collections.Generic.KeyValuePair{System.String,System.String},System.Boolean,System.Threading.CancellationToken)">
<member name="M:ThingsGateway.Application.RpcSingletonService.InvokeDeviceMethodAsync(System.String,System.Collections.Generic.Dictionary{System.String,System.String},System.Boolean,System.Threading.CancellationToken)">
<summary>
反向RPC入口方法
</summary>
<param name="sourceDes">触发该方法的源说明</param>
<param name="item">指定键为变量名称,值为附带方法参数或写入值</param>
<param name="items">指定键为变量名称,值为附带方法参数或写入值</param>
<param name="isBlazor">如果是true不检查<see cref="P:ThingsGateway.Application.MemoryVariable.RpcWriteEnable"/>字段</param>
<param name="token"><see cref="T:System.Threading.CancellationToken"/> 取消源</param>
<returns></returns>
@@ -3175,7 +3181,7 @@
编辑变量
</summary>
</member>
<member name="M:ThingsGateway.Application.IVariableService.ExportFileAsync(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariable})">
<member name="M:ThingsGateway.Application.IVariableService.ExportFileAsync(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariable},System.String)">
<summary>
导出
</summary>
@@ -3270,7 +3276,7 @@
<member name="M:ThingsGateway.Application.VariableService.MemoryVariableExportFileAsync(System.Collections.Generic.List{ThingsGateway.Application.MemoryVariable})">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Application.VariableService.ExportFileAsync(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariable})">
<member name="M:ThingsGateway.Application.VariableService.ExportFileAsync(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariable},System.String)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Application.VariableService.MemoryVariablePreviewAsync(Microsoft.AspNetCore.Components.Forms.IBrowserFile)">
@@ -3505,7 +3511,7 @@
执行特殊方法
</summary>
</member>
<member name="M:ThingsGateway.Application.CollectDeviceCore.InVokeWriteAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)">
<member name="M:ThingsGateway.Application.CollectDeviceCore.InVokeWriteAsync(System.Collections.Generic.Dictionary{ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken},System.Threading.CancellationToken)">
<summary>
执行变量写入
</summary>

View File

@@ -536,6 +536,7 @@ public class AlarmWorker : BackgroundService
HisAlarmTask = await Task.Factory.StartNew(async () =>
{
_logger?.LogInformation($"历史报警线程开始");
await Task.Yield();//返回线程控制,不再阻塞
try
{
await Task.Delay(500, stoppingToken.Token);
@@ -561,8 +562,14 @@ public class AlarmWorker : BackgroundService
}
catch (Exception)
{
if (stoppingToken.Token.IsCancellationRequested)
{
IsExited = true;
return;
}
try
{
_logger.LogWarning("连接历史报警表失败,尝试初始化表");
sqlSugarClient.CodeFirst.InitTables(typeof(HistoryAlarm));
isSuccess = true;
StatuString = OperResult.CreateSuccessResult();
@@ -588,7 +595,7 @@ public class AlarmWorker : BackgroundService
var cacheData = await CacheDb.GetCacheData();
if (cacheData.Count > 0)
{
var data = cacheData.SelectMany(a => a.CacheStr.FromJson<List<HistoryAlarm>>()).ToList();
var data = cacheData.SelectMany(a => a.CacheStr.FromJsonString<List<HistoryAlarm>>()).ToList();
try
{
var count = await sqlSugarClient.Insertable(data).ExecuteCommandAsync(stoppingToken.Token);
@@ -626,7 +633,7 @@ public class AlarmWorker : BackgroundService
var cacheDatas = list.ChunkTrivialBetter(500);
foreach (var a in cacheDatas)
{
await CacheDb.AddCacheData("", a.ToJson(), 50000);
await CacheDb.AddCacheData("", a.ToJsonString(), 50000);
}
}

View File

@@ -269,6 +269,7 @@ public class CollectDeviceCore
{
isInitSuccess = false;
GlobalDeviceData.CollectDevices.RemoveWhere(it => it.Id == Device.Id);
easyLock.SafeDispose();
}
}
@@ -329,11 +330,6 @@ public class CollectDeviceCore
return ThreadRunReturn.Continue;
}
if (DeviceVariableSourceReads.Count == 0 && Device.DeviceVariableRunTimes.Where(a => string.IsNullOrEmpty(a.OtherMethod)).Any())
{
//无采集变量
return ThreadRunReturn.Continue;
}
if (token.IsCancellationRequested)
return ThreadRunReturn.Break;
@@ -397,7 +393,7 @@ public class CollectDeviceCore
var read = await InvokeMethodAsync(deviceVariableMethodRead, token);
if (read.IsSuccess)
{
_logger?.LogTrace(_device.Name + "执行方法[" + deviceVariableMethodRead.MethodInfo.Name + "] 成功" + read.Content.ToJson());
_logger?.LogTrace(_device.Name + "执行方法[" + deviceVariableMethodRead.MethodInfo.Name + "] 成功" + read.Content.ToJsonString());
deviceMethodsVariableSuccessNum += 1;
}
else
@@ -437,11 +433,11 @@ public class CollectDeviceCore
if (_driver.IsConnected())
{
//更新设备活动时间
Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime, 0);
Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime, errorCount: 0);
}
else
{
Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime, 999);
Device.SetDeviceStatus(errorCount: 999);
}
}
@@ -533,7 +529,7 @@ public class CollectDeviceCore
if (!string.IsNullOrEmpty(methodResult.MethodStr))
{
string[] strs = methodResult.MethodStr?.Trim()?.Split(';');
string[] strs = methodResult.MethodStr?.Trim()?.TrimEnd(';').Split(';');
try
{
int index = 0;
@@ -545,6 +541,8 @@ public class CollectDeviceCore
}
else
{
if (strs.Length <= index)
continue;
//得到对于的方法参数值
methodResult.MethodObj[i] = methodResult.Converter.ConvertFrom(strs[index], ps[i].ParameterType);
index++;
@@ -600,8 +598,8 @@ public class CollectDeviceCore
if (!string.IsNullOrEmpty(deviceVariableMethodSource.MethodStr) || !string.IsNullOrEmpty(value))
{
string[] strs1 = deviceVariableMethodSource.MethodStr?.Trim()?.Split(';');
string[] strs2 = value?.Trim()?.Split(';');
string[] strs1 = deviceVariableMethodSource.MethodStr?.Trim()?.TrimEnd(';').Split(';');
string[] strs2 = value?.Trim()?.TrimEnd(';').Split(';');
//通过分号分割,并且合并参数
var strs = strs1?.SpliceArray(strs2);
int index = 0;
@@ -667,18 +665,25 @@ public class CollectDeviceCore
if (method.HasReturn && result != null && result.IsSuccess)
{
var content = deviceVariableMethodSource.Converter.ConvertTo(result.Content?.ToString()?.Replace($"\0", ""));
var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(content);
if (!operResult.IsSuccess)
if (isRead)
{
_logger?.LogWarning(operResult.Message, ToString());
var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(content);
if (!operResult.IsSuccess)
{
_logger?.LogWarning(operResult.Message, ToString());
}
}
}
else
{
var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(null);
if (!operResult.IsSuccess)
if (isRead&& !result.IsSuccess)
{
_logger?.LogWarning(operResult.Message, ToString());
var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(null,isOnline: false);
if (!operResult.IsSuccess)
{
_logger?.LogWarning(operResult.Message, ToString());
}
}
}
return result;
@@ -707,46 +712,46 @@ public class CollectDeviceCore
/// 执行变量写入
/// </summary>
/// <returns></returns>
internal async Task<OperResult> InVokeWriteAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token)
internal async Task<Dictionary<string, OperResult>> InVokeWriteAsync(Dictionary<DeviceVariableRunTime, JToken> writeInfoLists, CancellationToken token)
{
try
{
await easyLock.WaitAsync();
if (IsShareChannel) _driver.InitDataAdapter();
Dictionary<string, OperResult> results = new();
foreach (var deviceVariable in writeInfoLists.Keys)
{
if (!string.IsNullOrEmpty(deviceVariable.WriteExpressions))
{
var jToken = writeInfoLists[deviceVariable];
object rawdata;
if (jToken is JValue jValue)
{
rawdata = jValue.Value;
}
else
{
rawdata = jToken.ToString();
}
object data;
try
{
data = deviceVariable.WriteExpressions.GetExpressionsResult(rawdata);
writeInfoLists[deviceVariable] = JToken.FromObject(data);
}
catch (Exception ex)
{
results.Add(deviceVariable.Name, new OperResult(deviceVariable.Name + " 转换写入表达式失败:" + ex.Message));
}
}
if (!string.IsNullOrEmpty(deviceVariable.WriteExpressions))
{
var jToken = value;
object rawdata;
if (jToken is JValue jValue)
{
rawdata = jValue.Value;
}
else
{
rawdata = jToken.ToString();
}
object data;
try
{
data = deviceVariable.WriteExpressions.GetExpressionsResult(rawdata);
var result = await _driver.WriteValueAsync(deviceVariable, JToken.FromObject(data), token);
return result;
}
catch (Exception ex)
{
return new OperResult(deviceVariable.Name + " 转换写入表达式失败:" + ex.Message);
}
}
else
{
var result = await _driver.WriteValueAsync(deviceVariable, value, token);
return result;
}
}
catch (Exception ex)
{
return (new OperResult(ex));
var result = await _driver.WriteValuesAsync(writeInfoLists.
Where(a => !results.Any(b => b.Key == a.Key.Name)).
ToDictionary(item => item.Key, item => item.Value),
token);
return result;
}
finally
{
@@ -754,6 +759,8 @@ public class CollectDeviceCore
}
}
/// <summary>
/// 执行轮询特殊方法,并设置变量值
/// </summary>

View File

@@ -62,6 +62,7 @@ public class CollectDeviceThread : IAsyncDisposable
public async ValueTask DisposeAsync()
{
await StopThreadAsync();
easyLock.SafeDispose();
CollectDeviceCores.Clear();
}

View File

@@ -167,7 +167,7 @@ public class HistoryValueWorker : BackgroundService
HistoryValueTask = await Task.Factory.StartNew(async () =>
{
_logger?.LogInformation($"历史数据线程开始");
IsExited = false;
await Task.Yield();//返回线程控制,不再阻塞
try
{
var result = await GetHisDbAsync();
@@ -191,8 +191,14 @@ public class HistoryValueWorker : BackgroundService
}
catch (Exception)
{
if (stoppingToken.Token.IsCancellationRequested)
{
IsExited = true;
return;
}
try
{
_logger.LogWarning("连接历史数据表失败,尝试初始化表");
sqlSugarClient.CodeFirst.InitTables(typeof(HistoryValue));
LastIsSuccess = true;
StatuString = OperResult.CreateSuccessResult();
@@ -204,6 +210,7 @@ public class HistoryValueWorker : BackgroundService
_logger.LogWarning(ex, "连接历史数据库失败");
}
}
IsExited = false;
while (!stoppingToken.Token.IsCancellationRequested)
{
@@ -217,7 +224,7 @@ public class HistoryValueWorker : BackgroundService
//缓存值
var cacheData = await CacheDb.GetCacheData();
var data = cacheData.SelectMany(a => a.CacheStr.FromJson<List<HistoryValue>>()).ToList();
var data = cacheData.SelectMany(a => a.CacheStr.FromJsonString<List<HistoryValue>>()).ToList();
try
{
var count = await sqlSugarClient.Insertable(data).ExecuteCommandAsync(stoppingToken.Token);
@@ -250,7 +257,7 @@ public class HistoryValueWorker : BackgroundService
var cacheDatas = collecthis.ChunkTrivialBetter(500);
foreach (var a in cacheDatas)
{
await CacheDb.AddCacheData("", a.ToJson(), 50000);
await CacheDb.AddCacheData("", a.ToJsonString(), 50000);
}
}
}
@@ -277,7 +284,7 @@ public class HistoryValueWorker : BackgroundService
var cacheDatas = changehis.ChunkTrivialBetter(500);
foreach (var a in cacheDatas)
{
await CacheDb.AddCacheData("", a.ToJson(), 50000);
await CacheDb.AddCacheData("", a.ToJsonString(), 50000);
}
}
}
@@ -299,7 +306,6 @@ public class HistoryValueWorker : BackgroundService
LastIsSuccess = false;
}
}
IsExited = true;
}
}
@@ -317,9 +323,11 @@ public class HistoryValueWorker : BackgroundService
IsExited = true;
_logger?.LogError(ex, $"历史数据循环异常");
}
IsExited = true;
}
, TaskCreationOptions.LongRunning);
}
/// <summary>
/// 重启
/// </summary>

View File

@@ -225,7 +225,13 @@ public class UploadDeviceCore
{
_logger?.LogError(ex, $"{Device.Name} 释放失败");
}
isInitSuccess = false;
finally
{
isInitSuccess = false;
easyLock.SafeDispose();
}
}
/// <summary>

View File

@@ -51,6 +51,7 @@ public class UploadDeviceThread : IAsyncDisposable
public async ValueTask DisposeAsync()
{
await StopThreadAsync();
easyLock.SafeDispose();
UploadDeviceCores.Clear();
}

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -21,7 +21,7 @@ using ThingsGateway.Application;
namespace ThingsGateway.Blazor;
/// <summary>
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>excel
/// 导入excel
/// </summary>
public partial class ImportExcel
{
@@ -33,21 +33,21 @@ public partial class ImportExcel
bool isSaveImport;
/// <summary>
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 导入
/// </summary>
[Parameter]
public Func<Dictionary<string, ImportPreviewOutputBase>, Task> Import { get; set; }
/// <summary>
/// <EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD>ʾ
/// 是否显示
/// </summary>
public bool IsShowImport { get; set; }
/// <summary>
/// Ԥ<EFBFBD><EFBFBD>
/// 预览
/// </summary>
[Parameter]
public Func<IBrowserFile, Task<Dictionary<string, ImportPreviewOutputBase>>> Preview { get; set; }
/// <summary>
/// <EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 当前步数
/// </summary>
public int Step { get; set; }
@@ -75,7 +75,7 @@ public partial class ImportExcel
StateHasChanged();
await Import.Invoke(ImportPreviews);
_importFile = null;
await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD>", AlertTypes.Success);
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
}
finally
{

View File

@@ -33,7 +33,7 @@
<TcpClientPage @ref=TcpClientPage></TcpClientPage>
break;
case ChannelEnum.SerialPort:
<SerialClientPage @ref=SerialClientPage></SerialClientPage>
<SerialSessionPage @ref=SerialSessionPage></SerialSessionPage>
break;
case ChannelEnum.UdpSession:
<UdpSessionPage @ref=UdpSessionPage></UdpSessionPage>

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -38,9 +38,9 @@ public enum ChannelEnum
public partial class DefalutDebugDriverPage : DriverDebugUIBase
{
/// <summary>
/// SerialClientPage
/// SerialSessionPage
/// </summary>
public SerialClientPage SerialClientPage;
public SerialSessionPage SerialSessionPage;
/// <summary>
/// TcpClientPage
/// </summary>
@@ -54,7 +54,7 @@ public partial class DefalutDebugDriverPage : DriverDebugUIBase
/// </summary>
public UdpSessionPage UdpSessionPage;
/// <summary>
/// ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>1-TCPCLIENT<EFBFBD><EFBFBD>2-<2D><><EFBFBD>ڣ<EFBFBD>3-UDP<EFBFBD><EFBFBD>4-TCPServer
/// 选择,1-TCPCLIENT2-串口,3-UDP4-TCPServer
/// </summary>
[Parameter]
public ChannelEnum Channel { get; set; }
@@ -65,12 +65,12 @@ public partial class DefalutDebugDriverPage : DriverDebugUIBase
public override ThingsGateway.Foundation.IReadWriteDevice Plc { get; set; }
/// <summary>
/// ģ<EFBFBD><EFBFBD>
/// 模板
/// </summary>
[Parameter]
public RenderFragment ChildContent { get; set; }
/// <summary>
/// <EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD>
/// 自定义模板
/// </summary>
[Parameter]
public RenderFragment OtherContent { get; set; }
@@ -79,7 +79,7 @@ public partial class DefalutDebugDriverPage : DriverDebugUIBase
{
Plc?.SafeDispose();
TcpClientPage?.SafeDispose();
SerialClientPage?.SafeDispose();
SerialSessionPage?.SafeDispose();
TcpServerPage?.SafeDispose();
UdpSessionPage?.SafeDispose();
base.Dispose();
@@ -94,13 +94,13 @@ public partial class DefalutDebugDriverPage : DriverDebugUIBase
{
if (TcpClientPage != null)
TcpClientPage.LogAction = LogOut;
if (SerialClientPage != null)
SerialClientPage.LogAction = LogOut;
if (SerialSessionPage != null)
SerialSessionPage.LogAction = LogOut;
if (TcpServerPage != null)
TcpServerPage.LogAction = LogOut;
if (UdpSessionPage != null)
UdpSessionPage.LogAction = LogOut;
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//载入配置
StateHasChanged();
}

View File

@@ -127,7 +127,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
/// 导入设备
/// </summary>
/// <returns></returns>
public async Task DownDeviceExportAsync(CollectDevice data)
public async Task DeviceImportAsync(CollectDevice data)
{
try
{
@@ -145,7 +145,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
/// 导入变量
/// </summary>
/// <returns></returns>
public async Task DownDeviceExportAsync(List<DeviceVariable> data)
public async Task DeviceVariableImportAsync(List<DeviceVariable> data)
{
try
{
@@ -159,6 +159,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
}
}
/// <summary>
/// 导出
/// </summary>
@@ -187,6 +188,51 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
isDownExport = false;
}
}
/// <summary>
/// 导出到excel
/// </summary>
/// <returns></returns>
public async Task DownDeviceExportAsync(CollectDevice data)
{
try
{
isDownExport = true;
StateHasChanged();
using var memoryStream = await CollectDeviceService.ExportFileAsync(new List<CollectDevice>() { data });
memoryStream.Seek(0, SeekOrigin.Begin);
using var streamRef = new DotNetStreamReference(stream: memoryStream);
_helper ??= await JS.InvokeAsync<IJSObjectReference>("import", $"/_content/ThingsGateway.Admin.Blazor.Core/js/downloadFileFromStream.js");
await _helper.InvokeVoidAsync("downloadFileFromStream", $"设备导出{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx", streamRef);
}
finally
{
isDownExport = false;
}
}
/// <summary>
/// 导出到excel
/// </summary>
/// <returns></returns>
public async Task DownDeviceVariableExportAsync(List<DeviceVariable> data, string devName)
{
try
{
isDownExport = true;
StateHasChanged();
using var memoryStream = await VariableService.ExportFileAsync(data, devName);
memoryStream.Seek(0, SeekOrigin.Begin);
using var streamRef = new DotNetStreamReference(stream: memoryStream);
_helper ??= await JS.InvokeAsync<IJSObjectReference>("import", $"/_content/ThingsGateway.Admin.Blazor.Core/js/downloadFileFromStream.js");
await _helper.InvokeVoidAsync("downloadFileFromStream", $"变量导出{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx", streamRef);
}
finally
{
isDownExport = false;
}
}
/// <inheritdoc/>
public void LogOut(TouchSocket.Core.LogLevel logLevel, object source, string message, Exception exception)
{

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
@@ -17,10 +17,10 @@ using TouchSocket.Core;
namespace ThingsGateway.Blazor;
/// <inheritdoc/>
public partial class SerialClientPage
public partial class SerialSessionPage
{
/// <summary>
/// 日志输出
/// 日志输出
/// </summary>
public Action<LogLevel, object, string, Exception> LogAction;
@@ -28,18 +28,18 @@ public partial class SerialClientPage
private readonly SerialProperty serialProperty = new();
private SerialClient SerialClient { get; set; } = new();
private SerialsSession SerialsSession { get; set; } = new();
/// <inheritdoc/>
public void Dispose()
{
SerialClient.SafeDispose();
SerialsSession.SafeDispose();
}
/// <summary>
/// 获取对象
/// 获取对象
/// </summary>
/// <returns></returns>
public SerialClient GetSerialClient()
public SerialsSession GetSerialSession()
{
config?.Dispose();
config = new TouchSocketConfig();
@@ -47,16 +47,16 @@ public partial class SerialClientPage
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = TouchSocket.Core.LogLevel.Trace });
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
config.SetSerialProperty(serialProperty);
//载入配置
SerialClient.Setup(config);
return SerialClient;
//载入配置
SerialsSession.Setup(config);
return SerialsSession;
}
private async Task ConnectAsync()
{
try
{
SerialClient.Close();
await GetSerialClient().ConnectAsync();
SerialsSession.Close();
await GetSerialSession().ConnectAsync();
}
catch (Exception ex)
{
@@ -68,7 +68,7 @@ public partial class SerialClientPage
{
try
{
SerialClient.Close();
SerialsSession.Close();
}
catch (Exception ex)
{
@@ -82,8 +82,8 @@ public partial class SerialClientPage
var LogMessage = new TouchSocket.Core.LoggerGroup() { LogLevel = TouchSocket.Core.LogLevel.Trace };
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = TouchSocket.Core.LogLevel.Trace });
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
SerialClient = new SerialClient();
SerialClient.Setup(config);
SerialsSession = new SerialsSession();
SerialsSession.Setup(config);
base.OnInitialized();
}

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -23,7 +23,7 @@ namespace ThingsGateway.Blazor;
public partial class TcpClientPage
{
/// <summary>
/// <EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 日志输出
/// </summary>
public Action<LogLevel, object, string, Exception> LogAction;
@@ -33,7 +33,7 @@ public partial class TcpClientPage
/// </summary>
private string IP = "127.0.0.1";
/// <summary>
/// <EFBFBD>˿<EFBFBD>
/// 端口
/// </summary>
[Parameter]
public int Port { get; set; } = 502;
@@ -73,7 +73,7 @@ public partial class TcpClientPage
}
}
/// <summary>
/// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 获取对象
/// </summary>
/// <returns></returns>
public TcpClientEx GetTcpClient()
@@ -83,7 +83,7 @@ public partial class TcpClientPage
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = TouchSocket.Core.LogLevel.Trace });
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
config.SetRemoteIPHost(new IPHost(IP + ":" + Port)).SetBufferLength(300);
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//载入配置
TcpClientEx.Setup(config);
return TcpClientEx;
}

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -19,7 +19,7 @@ namespace ThingsGateway.Blazor;
public partial class TcpServerPage
{
/// <summary>
/// <EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 日志输出
/// </summary>
public Action<LogLevel, object, string, Exception> LogAction;
@@ -62,7 +62,7 @@ public partial class TcpServerPage
}
}
/// <summary>
/// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 获取对象
/// </summary>
/// <returns></returns>
public TcpService GetTcpServer()
@@ -73,7 +73,7 @@ public partial class TcpServerPage
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
config.SetListenIPHosts(new IPHost[] { new IPHost(ip + ":" + port) });
config.SetBufferLength(300);
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//载入配置
TcpServer.Setup(config);
return TcpServer;
}

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -19,7 +19,7 @@ namespace ThingsGateway.Blazor;
public partial class UdpSessionPage : IDisposable
{
/// <summary>
/// <EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 日志输出
/// </summary>
public Action<LogLevel, object, string, Exception> LogAction;
@@ -62,7 +62,7 @@ public partial class UdpSessionPage : IDisposable
}
}
/// <summary>
/// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 获取对象
/// </summary>
/// <returns></returns>
public UdpSession GetUdpSession()
@@ -73,7 +73,7 @@ public partial class UdpSessionPage : IDisposable
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
config.SetRemoteIPHost(new IPHost(ip + ":" + port)).SetBufferLength(300);
config.SetBindIPHost(new IPHost(0));
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//载入配置
UdpSession.Setup(config);
return UdpSession;
}

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -32,7 +32,7 @@ using ThingsGateway.Application;
namespace ThingsGateway.Blazor;
/// <summary>
/// <EFBFBD>豸״̬ҳ<EFBFBD><EFBFBD>
/// 设备状态页面
/// </summary>
public partial class DeviceStatusPage : IDisposable
{
@@ -110,7 +110,7 @@ public partial class DeviceStatusPage : IDisposable
{
try
{
var confirm = await PopupService.OpenConfirmDialogAsync("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?");
var confirm = await PopupService.OpenConfirmDialogAsync("重启", "确定重启?");
if (confirm)
{
isAllRestart = true;
@@ -142,8 +142,8 @@ public partial class DeviceStatusPage : IDisposable
}
async Task ConfigAsync(long devId, bool? isStart)
{
var str = isStart == true ? "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD>ͣ";
var confirm = await PopupService.OpenConfirmDialogAsync(str, $"ȷ<EFBFBD><EFBFBD>{str}?");
var str = isStart == true ? "启动" : "暂停";
var confirm = await PopupService.OpenConfirmDialogAsync(str, $"确定{str}?");
if (confirm)
{
CollectDeviceHostService.ConfigDeviceThread(devId, isStart == true);
@@ -167,19 +167,19 @@ public partial class DeviceStatusPage : IDisposable
memoryStream.Seek(0, SeekOrigin.Begin);
using var streamRef = new DotNetStreamReference(stream: memoryStream);
Helper ??= await JS.InvokeAsync<IJSObjectReference>("import", $"/_content/ThingsGateway.Admin.Blazor.Core/js/downloadFileFromStream.js");
await Helper.InvokeVoidAsync("downloadFileFromStream", $"<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.txt", streamRef);
await Helper.InvokeVoidAsync("downloadFileFromStream", $"报文导出{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.txt", streamRef);
}
finally
{
isDownExport = false;
}
}
//ȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//去除单个采集重启
//async Task RestartAsync(long devId)
//{
// try
// {
// var confirm = await PopupService.OpenConfirmDialogAsync("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "ȷ<><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?");
// var confirm = await PopupService.OpenConfirmDialogAsync("重启", "确定重启?");
// if (confirm)
// {
// isRestart = true;
@@ -231,8 +231,8 @@ public partial class DeviceStatusPage : IDisposable
async Task UpConfigAsync(long devId, bool? isStart)
{
var str = isStart == true ? "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD>ͣ";
var confirm = await PopupService.OpenConfirmDialogAsync(str, $"ȷ<EFBFBD><EFBFBD>{str}?");
var str = isStart == true ? "启动" : "暂停";
var confirm = await PopupService.OpenConfirmDialogAsync(str, $"确定{str}?");
if (confirm)
{
UploadDeviceHostService.ConfigDeviceThread(devId, isStart == true);
@@ -253,7 +253,7 @@ public partial class DeviceStatusPage : IDisposable
{
try
{
var confirm = await PopupService.OpenConfirmDialogAsync("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?");
var confirm = await PopupService.OpenConfirmDialogAsync("重启", "确定重启?");
if (confirm)
{
isRestart = true;

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -28,7 +28,7 @@ using ThingsGateway.Application;
namespace ThingsGateway.Blazor;
/// <summary>
/// ʵʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ
/// 实时数据页
/// </summary>
public partial class DeviceVariableRunTimePage
{
@@ -37,13 +37,13 @@ public partial class DeviceVariableRunTimePage
List<DeviceTree> _deviceGroups = new();
string _searchName;
/// <summary>
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 设备名称
/// </summary>
[Parameter]
[SupplyParameterFromQuery]
public string DeviceName { get; set; }
/// <summary>
/// <EFBFBD>ϴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 上传设备名称
/// </summary>
[Parameter]
[SupplyParameterFromQuery]
@@ -149,15 +149,23 @@ public partial class DeviceVariableRunTimePage
private EventCallback<string> WriteValueAsync;
private async Task OnWriteValueAsync(DeviceVariableRunTime tag, string value)
{
var data = await RpcCore?.InvokeDeviceMethodAsync($"BLAZOR-{UserResoures.CurrentUser.Account}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}", new KeyValuePair<string, string>(tag.Name, value), true);
if (!data.IsSuccess)
var data = await RpcCore?.InvokeDeviceMethodAsync($"BLAZOR-{UserResoures.CurrentUser.Account}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}",
new Dictionary<string, string>()
{
{ tag.Name, value}
}
, true);
if (data.Count > 0 && !data.FirstOrDefault().Value.IsSuccess)
{
throw new(data.Message);
throw new(data.FirstOrDefault().Value.Message);
}
}
private async Task WriteAsync(DeviceVariableRunTime collectVariableRunTime)
{
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD>
// 将异步方法添加到事件回调上
WriteValueAsync = EventCallback.Factory.Create<string>(this, value => OnWriteValueAsync(collectVariableRunTime, value));
await PopupService.OpenAsync(typeof(WriteValue), new Dictionary<string, object>()
{

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -19,7 +19,7 @@ using ThingsGateway.Application;
namespace ThingsGateway.Blazor;
/// <summary>
/// Ӳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣҳ<EFBFBD><EFBFBD>
/// 硬件信息页面
/// </summary>
public partial class HardwareInfoPage
{

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -25,7 +25,7 @@ using ThingsGateway.Application;
namespace ThingsGateway.Blazor;
/// <summary>
/// <EFBFBD><EFBFBD>ʷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>
/// 历史报警页面
/// </summary>
public partial class HistoryAlarmPage
{
@@ -75,7 +75,7 @@ public partial class HistoryAlarmPage
}
catch (Exception ex)
{
await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync("<EFBFBD><EFBFBD>ѯʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>" + ex.Message, AlertTypes.Warning));
await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync("查询失败,请检查网络连接:" + ex.Message, AlertTypes.Warning));
return new()
{
Current = 1,

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -23,7 +23,7 @@ using ThingsGateway.Application;
namespace ThingsGateway.Blazor;
/// <summary>
/// ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>
/// 时序库页面
/// </summary>
public partial class HistoryValuePage
{
@@ -74,7 +74,7 @@ public partial class HistoryValuePage
}
catch (Exception ex)
{
await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync("<EFBFBD><EFBFBD>ѯʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>" + ex.Message, AlertTypes.Warning));
await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync("查询失败,请检查网络连接:" + ex.Message, AlertTypes.Warning));
return new()
{
Current = 1,

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -22,7 +22,7 @@ using ThingsGateway.Application;
namespace ThingsGateway.Blazor;
/// <summary>
/// ʵʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// 实时报警
/// </summary>
public partial class RealAlarmPage
{

View File

@@ -67,9 +67,9 @@
<member name="T:ThingsGateway.Blazor.DefalutDebugDriverPage">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Blazor.DefalutDebugDriverPage.SerialClientPage">
<member name="F:ThingsGateway.Blazor.DefalutDebugDriverPage.SerialSessionPage">
<summary>
SerialClientPage
SerialSessionPage
</summary>
</member>
<member name="F:ThingsGateway.Blazor.DefalutDebugDriverPage.TcpClientPage">
@@ -116,24 +116,24 @@
</summary>
<param name="firstRender"></param>
</member>
<member name="T:ThingsGateway.Blazor.SerialClientPage">
<member name="T:ThingsGateway.Blazor.SerialSessionPage">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Blazor.SerialClientPage.LogAction">
<member name="F:ThingsGateway.Blazor.SerialSessionPage.LogAction">
<summary>
日志输出
</summary>
</member>
<member name="M:ThingsGateway.Blazor.SerialClientPage.Dispose">
<member name="M:ThingsGateway.Blazor.SerialSessionPage.Dispose">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Blazor.SerialClientPage.GetSerialClient">
<member name="M:ThingsGateway.Blazor.SerialSessionPage.GetSerialSession">
<summary>
获取对象
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Blazor.SerialClientPage.OnInitialized">
<member name="M:ThingsGateway.Blazor.SerialSessionPage.OnInitialized">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Blazor.TcpClientPage">
@@ -428,13 +428,13 @@
<member name="M:ThingsGateway.Application.DriverDebugUIBase.WriteAsync">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Application.DriverDebugUIBase.DownDeviceExportAsync(ThingsGateway.Application.CollectDevice)">
<member name="M:ThingsGateway.Application.DriverDebugUIBase.DeviceImportAsync(ThingsGateway.Application.CollectDevice)">
<summary>
导入设备
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Application.DriverDebugUIBase.DownDeviceExportAsync(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariable})">
<member name="M:ThingsGateway.Application.DriverDebugUIBase.DeviceVariableImportAsync(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariable})">
<summary>
导入变量
</summary>
@@ -447,6 +447,18 @@
<param name="values"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Application.DriverDebugUIBase.DownDeviceExportAsync(ThingsGateway.Application.CollectDevice)">
<summary>
导出到excel
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Application.DriverDebugUIBase.DownDeviceVariableExportAsync(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariable},System.String)">
<summary>
导出到excel
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Application.DriverDebugUIBase.LogOut(TouchSocket.Core.LogLevel,System.Object,System.String,System.Exception)">
<inheritdoc/>
</member>

View File

@@ -22,47 +22,47 @@ public abstract class ReadWriteDevicesSerialBase : ReadWriteDevicesClientBase
/// <summary>
/// WaitingClientEx
/// </summary>
public virtual IWaitingClient<SerialClient> WaitingClientEx { get; }
public virtual IWaitingClient<SerialsSession> WaitingClientEx { get; }
/// <summary>
/// <inheritdoc cref="ReadWriteDevicesSerialBase"/>
/// </summary>
/// <param name="serialClient"></param>
public ReadWriteDevicesSerialBase(SerialClient serialClient)
/// <param name="serialSession"></param>
public ReadWriteDevicesSerialBase(SerialsSession serialSession)
{
SerialClient = serialClient;
WaitingClientEx = SerialClient.GetWaitingClientEx(new() { BreakTrigger = true });
SerialsSession = serialSession;
WaitingClientEx = SerialsSession.GetWaitingClientEx(new() { BreakTrigger = true });
SerialClient.Connecting -= Connecting;
SerialClient.Connected -= Connected;
SerialClient.Disconnecting -= Disconnecting;
SerialClient.Disconnected -= Disconnected;
SerialClient.Connecting += Connecting;
SerialClient.Connected += Connected;
SerialClient.Disconnecting += Disconnecting;
SerialClient.Disconnected += Disconnected;
Logger = SerialClient.Logger;
SerialsSession.Connecting -= Connecting;
SerialsSession.Connected -= Connected;
SerialsSession.Disconnecting -= Disconnecting;
SerialsSession.Disconnected -= Disconnected;
SerialsSession.Connecting += Connecting;
SerialsSession.Connected += Connected;
SerialsSession.Disconnecting += Disconnecting;
SerialsSession.Disconnected += Disconnected;
Logger = SerialsSession.Logger;
}
/// <summary>
/// 串口管理对象
/// </summary>
public SerialClient SerialClient { get; }
public SerialsSession SerialsSession { get; }
/// <inheritdoc/>
public override void Connect(CancellationToken token)
{
SerialClient.Connect();
SerialsSession.Connect();
}
/// <inheritdoc/>
public override Task ConnectAsync(CancellationToken token)
{
return SerialClient.ConnectAsync();
return SerialsSession.ConnectAsync();
}
/// <inheritdoc/>
public override void Disconnect()
{
SerialClient.Close();
SerialsSession.Close();
}
/// <inheritdoc/>
@@ -71,7 +71,7 @@ public abstract class ReadWriteDevicesSerialBase : ReadWriteDevicesClientBase
try
{
waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
ResponsedData result = SerialClient.GetWaitingClientEx(waitingOptions).SendThenResponse(data, TimeOut, token);
ResponsedData result = SerialsSession.GetWaitingClientEx(waitingOptions).SendThenResponse(data, TimeOut, token);
return OperResult.CreateSuccessResult(result.Data);
}
catch (Exception ex)
@@ -86,7 +86,7 @@ public abstract class ReadWriteDevicesSerialBase : ReadWriteDevicesClientBase
try
{
waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
ResponsedData result = await SerialClient.GetWaitingClientEx(waitingOptions).SendThenResponseAsync(data, TimeOut, token);
ResponsedData result = await SerialsSession.GetWaitingClientEx(waitingOptions).SendThenResponseAsync(data, TimeOut, token);
return OperResult.CreateSuccessResult(result.Data);
}
catch (Exception ex)
@@ -98,37 +98,37 @@ public abstract class ReadWriteDevicesSerialBase : ReadWriteDevicesClientBase
/// <inheritdoc/>
public override string ToString()
{
return SerialClient.SerialProperty.ToString();
return SerialsSession.SerialProperty.ToString();
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
SerialClient.Connecting -= Connecting;
SerialClient.Connected -= Connected;
SerialClient.Disconnecting -= Disconnecting;
SerialClient.Disconnected -= Disconnected;
SerialClient.Close();
SerialClient.SafeDispose();
SerialsSession.Connecting -= Connecting;
SerialsSession.Connected -= Connected;
SerialsSession.Disconnecting -= Disconnecting;
SerialsSession.Disconnected -= Disconnected;
SerialsSession.Close();
SerialsSession.SafeDispose();
base.Dispose(disposing);
}
private void Connected(ISerialClient client, ConnectedEventArgs e)
private void Connected(ISerialSession client, ConnectedEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "连接成功");
}
private void Connecting(ISerialClient client, SerialConnectingEventArgs e)
private void Connecting(ISerialSession client, SerialConnectingEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "正在连接");
SetDataAdapter();
}
private void Disconnected(ISerialClientBase client, DisconnectEventArgs e)
private void Disconnected(ISerialSessionBase client, DisconnectEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "断开连接-" + e.Message);
}
private void Disconnecting(ISerialClientBase client, DisconnectEventArgs e)
private void Disconnecting(ISerialSessionBase client, DisconnectEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "正在主动断开连接-" + e.Message);
}

View File

@@ -15,7 +15,7 @@ namespace ThingsGateway.Foundation;
/// <summary>
/// 自增
/// </summary>
public sealed class EasyIncrementCount : DisposableObject
public sealed class EasyIncrementCount : IDisposable
{
private long current = 0;
private readonly EasyLock easyLock;
@@ -30,6 +30,11 @@ public sealed class EasyIncrementCount : DisposableObject
IncreaseTick = tick;
easyLock = new EasyLock();
}
/// <inheritdoc cref="EasyIncrementCount"/>
~EasyIncrementCount()
{
easyLock.SafeDispose();
}
/// <summary>
/// Tick
@@ -117,10 +122,10 @@ public sealed class EasyIncrementCount : DisposableObject
}
easyLock.Release();
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
public void Dispose()
{
easyLock.SafeDispose();
base.Dispose(disposing);
}
}

View File

@@ -15,11 +15,15 @@ namespace ThingsGateway.Foundation;
/// <summary>
/// EasyLock使用轻量级SemaphoreSlim锁只允许一个并发量并记录并发信息
/// </summary>
public sealed class EasyLock : DisposableObject
public sealed class EasyLock : IDisposable
{
private static long lockWaitCount;
private readonly Lazy<SemaphoreSlim> m_waiterLock = new(() => new SemaphoreSlim(1));
/// <inheritdoc/>
~EasyLock()
{
m_waiterLock.Value.SafeDispose();
}
/// <summary>
/// 当前正在等待的数量
/// </summary>
@@ -28,6 +32,13 @@ public sealed class EasyLock : DisposableObject
/// 当前锁是否在等待当中
/// </summary>
public bool IsWaitting => m_waiterLock.Value.CurrentCount == 0;
/// <inheritdoc/>
public void Dispose()
{
m_waiterLock.Value.SafeDispose();
}
/// <summary>
/// 离开锁
/// </summary>
@@ -73,10 +84,5 @@ public sealed class EasyLock : DisposableObject
await m_waiterLock.Value.WaitAsync(timeSpan, token);
Interlocked.Decrement(ref lockWaitCount);
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
m_waiterLock.Value.SafeDispose();
base.Dispose(disposing);
}
}

View File

@@ -26,10 +26,7 @@ using System.Net.Security;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using ThingsGateway.Foundation;
using TouchSocket.Resources;
using TouchSocket.Sockets;
namespace ThingsGateway.Foundation;
@@ -66,18 +63,14 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
/// </summary>
public TcpClientBaseEx()
{
this.Protocol = Protocol.TCP;
this.Protocol = Protocol.Tcp;
}
#region
private DelaySender m_delaySender;
private bool m_useDelaySender;
private Stream m_workStream;
private int m_bufferRate = 1;
private volatile bool m_online;
private Socket m_mainSocket;
#endregion
#region
@@ -234,13 +227,13 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
public TouchSocketConfig Config { get; private set; }
/// <inheritdoc/>
public TcpDataHandlingAdapter DataHandlingAdapter { get; private set; }
public SingleStreamDataHandlingAdapter DataHandlingAdapter { get; private set; }
/// <inheritdoc/>
public string IP { get; private set; }
/// <inheritdoc/>
public Socket MainSocket { get => this.m_mainSocket; }
public Socket MainSocket { get; private set; }
/// <inheritdoc/>
public bool Online { get => this.m_online; }
@@ -270,7 +263,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
public bool IsClient => true;
#endregion
private EasyLock EasyLock { get; set; } = new();
#region
/// <inheritdoc/>
@@ -278,7 +271,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
{
try
{
privateEasyLock.Wait();
EasyLock.Wait();
if (this.m_online)
{
this.PrivateOnDisconnecting(new DisconnectEventArgs(true, msg));
@@ -295,7 +288,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
finally
{
privateEasyLock.Release();
EasyLock.Release();
}
}
@@ -303,7 +296,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
{
try
{
privateEasyLock.Wait();
EasyLock.Wait();
if (this.m_online)
{
this.m_online = false;
@@ -316,7 +309,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
finally
{
privateEasyLock.Release();
EasyLock.Release();
}
}
@@ -326,34 +319,39 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
try
if (!DisposedValue)
{
privateEasyLock.Wait();
if (this.m_online)
try
{
this.m_online = false;
this.MainSocket.TryClose();
this.PrivateOnDisconnecting(new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
this.MainSocket.SafeDispose();
this.m_delaySender.SafeDispose();
this.m_workStream.SafeDispose();
this.DataHandlingAdapter.SafeDispose();
this.PluginsManager.SafeDispose();
this.PrivateOnDisconnected(new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
EasyLock.Wait();
if (this.m_online)
{
this.m_online = false;
this.MainSocket.TryClose();
this.PrivateOnDisconnecting(new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
this.MainSocket.SafeDispose();
this.m_delaySender.SafeDispose();
this.m_workStream.SafeDispose();
this.DataHandlingAdapter.SafeDispose();
this.PluginsManager.SafeDispose();
this.PrivateOnDisconnected(new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
}
}
finally
{
EasyLock.Release();
}
}
finally
{
privateEasyLock.Release();
}
EasyLock.SafeDispose();
base.Dispose(disposing);
}
#endregion
#region Connect
private EasyLock privateEasyLock { get; set; } = new();
/// <summary>
/// 建立Tcp的连接。
/// </summary>
@@ -366,7 +364,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
{
try
{
privateEasyLock.Wait();
EasyLock.Wait();
if (this.m_online)
{
return;
@@ -377,13 +375,12 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
if (this.Config == null)
{
throw new ArgumentNullException("配置文件不能为空。");
throw new ArgumentNullException(nameof(this.Config), "配置文件不能为空。");
}
var iPHost = this.Config.GetValue(TouchSocketConfigExtension.RemoteIPHostProperty) ?? throw new ArgumentNullException("iPHost不能为空。");
var iPHost = this.Config.GetValue(TouchSocketConfigExtension.RemoteIPHostProperty) ?? throw new ArgumentNullException(nameof(IPHost), "iPHost不能为空。");
this.MainSocket.SafeDispose();
var socket = this.CreateSocket(iPHost);
var args = new ConnectingEventArgs(this.MainSocket);
this.PrivateOnConnecting(args);
this.PrivateOnConnecting(new ConnectingEventArgs(socket));
if (timeout == 5000)
{
socket.Connect(iPHost.Host, iPHost.Port);
@@ -401,15 +398,6 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
throw new TimeoutException();
}
}
if (this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty) is DelaySenderOption senderOption)
{
this.m_useDelaySender = true;
this.m_delaySender.SafeDispose();
this.m_delaySender = new DelaySender(this.MainSocket, senderOption.QueueLength, this.OnDelaySenderError)
{
DelayLength = senderOption.DelayLength
};
}
this.m_online = true;
this.SetSocket(socket);
this.BeginReceive();
@@ -417,24 +405,24 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
finally
{
privateEasyLock.Release();
EasyLock.Release();
}
}
/// <summary>
/// 建立Tcp的连接。
/// </summary>
/// <param name="timeOut"></param>
/// <param name="timeout"></param>
/// <param name="token"></param>
/// <exception cref="ObjectDisposedException"></exception>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="Exception"></exception>
/// <exception cref="TimeoutException"></exception>
public async Task TcpConnectAsync(int timeOut, CancellationToken token = default)
public async Task TcpConnectAsync(int timeout, CancellationToken token = default)
{
try
{
await privateEasyLock.WaitAsync();
await EasyLock.WaitAsync();
if (this.m_online)
{
return;
@@ -454,7 +442,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
this.PrivateOnConnecting(args);
#if (NET6_0_OR_GREATER)
using CancellationTokenSource cancellationTokenSource = new(timeOut);
using CancellationTokenSource cancellationTokenSource = new(timeout);
using CancellationTokenSource stoppingToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationTokenSource.Token, token);
try
{
@@ -472,7 +460,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
using CancellationTokenSource cancellationTokenSource = new();
using CancellationTokenSource stoppingToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationTokenSource.Token, token);
var task = Task.Factory.FromAsync(socket.BeginConnect(iPHost.EndPoint, null, null), socket.EndConnect);
var result = await Task.WhenAny(task, Task.Delay(timeOut, stoppingToken.Token));
var result = await Task.WhenAny(task, Task.Delay(timeout, stoppingToken.Token));
if (result == task)
{
cancellationTokenSource.Cancel();
@@ -497,20 +485,11 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
finally
{
privateEasyLock.Release();
EasyLock.Release();
}
void success(Socket socket)
{
if (this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty) is DelaySenderOption senderOption)
{
this.m_useDelaySender = true;
this.m_delaySender.SafeDispose();
this.m_delaySender = new DelaySender(this.MainSocket, senderOption.QueueLength, this.OnDelaySenderError)
{
DelayLength = senderOption.DelayLength
};
}
this.m_online = true;
this.SetSocket(socket);
this.BeginReceive();
@@ -518,20 +497,19 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
}
/// <inheritdoc/>
public virtual ITcpClient Connect(int timeout = 5000)
{
this.TcpConnect(timeout);
return this;
}
/// <inheritdoc/>
public virtual async Task<ITcpClient> ConnectAsync(int timeOut = 5000)
public async Task<ITcpClient> ConnectAsync(int timeout = 5000)
{
await TcpConnectAsync(timeOut);
await TcpConnectAsync(timeout);
return this;
}
#endregion
/// <inheritdoc/>
@@ -543,7 +521,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
/// <inheritdoc/>
public virtual void SetDataHandlingAdapter(TcpDataHandlingAdapter adapter)
public virtual void SetDataHandlingAdapter(SingleStreamDataHandlingAdapter adapter)
{
if (!this.CanSetDataHandlingAdapter)
{
@@ -698,7 +676,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
/// 设置适配器,该方法不会检验<see cref="CanSetDataHandlingAdapter"/>的值。
/// </summary>
/// <param name="adapter"></param>
protected void SetAdapter(TcpDataHandlingAdapter adapter)
protected void SetAdapter(SingleStreamDataHandlingAdapter adapter)
{
this.ThrowIfDisposed();
if (adapter is null)
@@ -744,7 +722,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
else
{
if (this.ReceiveType == ReceiveType.Auto)
if (this.ReceiveType == ReceiveType.Iocp)
{
var eventArgs = new SocketAsyncEventArgs();
eventArgs.Completed += this.EventArgs_Completed;
@@ -757,6 +735,39 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
this.ProcessReceived(eventArgs);
}
}
else if (this.ReceiveType == ReceiveType.Bio)
{
new Thread(BeginBio)
{
IsBackground = true
}
.Start();
}
}
}
private void BeginBio()
{
while (true)
{
var byteBlock = new ByteBlock(this.BufferLength);
try
{
var r = this.MainSocket.Receive(byteBlock.Buffer);
if (r == 0)
{
this.BreakOut("远程终端主动关闭");
return;
}
byteBlock.SetLength(r);
this.HandleBuffer(byteBlock);
}
catch (Exception ex)
{
this.BreakOut(ex.Message);
return;
}
}
}
@@ -797,32 +808,46 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
private Socket CreateSocket(IPHost iPHost)
{
var socket = new Socket(iPHost.EndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
Socket socket;
if (iPHost.HostNameType == UriHostNameType.Dns)
{
socket = new Socket(SocketType.Stream, ProtocolType.Tcp)
{
ReceiveBufferSize = this.BufferLength,
SendBufferSize = this.BufferLength,
SendTimeout = this.Config.GetValue(TouchSocketConfigExtension.SendTimeoutProperty)
};
}
else
{
socket = new Socket(iPHost.EndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
{
ReceiveBufferSize = this.BufferLength,
SendBufferSize = this.BufferLength,
SendTimeout = this.Config.GetValue(TouchSocketConfigExtension.SendTimeoutProperty)
};
}
if (this.Config.GetValue(TouchSocketConfigExtension.KeepAliveValueProperty) is KeepAliveValue keepAliveValue)
{
ReceiveBufferSize = this.BufferLength,
SendBufferSize = this.BufferLength,
SendTimeout = this.Config.GetValue(TouchSocketConfigExtension.SendTimeoutProperty)
};
#if NET45_OR_GREATER
var keepAliveValue = this.Config.GetValue(TouchSocketConfigExtension.KeepAliveValueProperty);
if (keepAliveValue.Enable)
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.IOControl(IOControlCode.KeepAliveValues, keepAliveValue.KeepAliveTime, null);
}
#else
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var keepAliveValue = Config.GetValue(TouchSocketConfigExtension.KeepAliveValueProperty);
if (keepAliveValue.Enable)
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.IOControl(IOControlCode.KeepAliveValues, keepAliveValue.KeepAliveTime, null);
}
}
#endif
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, this.Config.GetValue<bool>(TouchSocketConfigExtension.NoDelayProperty));
}
var noDelay = this.Config.GetValue(TouchSocketConfigExtension.NoDelayProperty);
if (noDelay != null)
{
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, noDelay);
}
if (this.Config.GetValue(TouchSocketConfigExtension.BindIPHostProperty) != null)
{
if (this.Config.GetValue(TouchSocketConfigExtension.ReuseAddressProperty))
@@ -956,14 +981,12 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
{
length += item.Count;
}
using (var byteBlock = new ByteBlock(length))
using var byteBlock = new ByteBlock(length);
foreach (var item in transferBytes)
{
foreach (var item in transferBytes)
{
byteBlock.Write(item.Array, item.Offset, item.Count);
}
this.DataHandlingAdapter.SendInput(byteBlock.Buffer, 0, byteBlock.Len);
byteBlock.Write(item.Array, item.Offset, item.Count);
}
this.DataHandlingAdapter.SendInput(byteBlock.Buffer, 0, byteBlock.Len);
}
}
@@ -1043,9 +1066,9 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
else
{
if (this.m_useDelaySender && length < TouchSocketUtility.BigDataBoundary)
if (this.m_delaySender != null && length < m_delaySender.DelayLength)
{
this.m_delaySender.Send(new QueueDataBytes(buffer, offset, length));
this.m_delaySender.Send(QueueDataBytes.CreateNew(buffer, offset, length));
}
else
{
@@ -1087,7 +1110,12 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
this.IP = socket.RemoteEndPoint.GetIP();
this.Port = socket.RemoteEndPoint.GetPort();
this.m_mainSocket = socket;
this.MainSocket = socket;
var delaySenderOption = this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty);
if (delaySenderOption != null)
{
this.m_delaySender = new DelaySender(socket, delaySenderOption, this.OnDelaySenderError);
}
}
private void ProcessReceived(SocketAsyncEventArgs e)

View File

@@ -19,7 +19,7 @@ namespace ThingsGateway.Foundation;
internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClient> where TClient : IClient, IDefaultSender, ISender
{
private readonly Func<ResponsedData, bool> m_func;
private readonly SemaphoreSlim m_lock = new(1);
private readonly EasyLock easyLock = new();
private readonly WaitData<ResponsedData> m_waitData = new WaitData<ResponsedData>();
private readonly WaitDataAsync<ResponsedData> m_waitDataAsync = new WaitDataAsync<ResponsedData>();
@@ -55,6 +55,7 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
this.Client = default;
this.m_waitData.SafeDispose();
this.m_waitDataAsync.SafeDispose();
this.easyLock.SafeDispose();
base.Dispose(disposing);
}
@@ -69,7 +70,7 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
this.m_breaked = true;
this.Cancel();
}
private void OnSerialClientDisconnected(ISerialClientBase client, DisconnectEventArgs e)
private void OnSerialSessionDisconnected(ISerialSessionBase client, DisconnectEventArgs e)
{
this.m_breaked = true;
this.Cancel();
@@ -121,16 +122,16 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
{
try
{
m_lock.Wait();
easyLock.Wait();
this.m_breaked = false;
this.Reset();
if (this.WaitingOptions.BreakTrigger && this.Client is ITcpClientBase tcpClient)
{
tcpClient.Disconnected += this.OnDisconnected;
}
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialClientBase serialClient)
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialSessionBase serialSession)
{
serialClient.Disconnected += this.OnSerialClientDisconnected;
serialSession.Disconnected += this.OnSerialSessionDisconnected;
}
if (this.WaitingOptions.AdapterFilter == AdapterFilter.AllAdapter || this.WaitingOptions.AdapterFilter == AdapterFilter.WaitAdapter)
{
@@ -184,14 +185,14 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
}
finally
{
m_lock.Release();
easyLock.Release();
if (this.WaitingOptions.BreakTrigger && this.Client is ITcpClientBase tcpClient)
{
tcpClient.Disconnected -= this.OnDisconnected;
}
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialClientBase serialClient)
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialSessionBase serialSession)
{
serialClient.Disconnected -= this.OnSerialClientDisconnected;
serialSession.Disconnected -= this.OnSerialSessionDisconnected;
}
if (this.WaitingOptions.AdapterFilter == AdapterFilter.AllAdapter || this.WaitingOptions.AdapterFilter == AdapterFilter.WaitAdapter)
{
@@ -224,16 +225,16 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
{
try
{
await m_lock.WaitAsync();
await easyLock.WaitAsync();
this.m_breaked = false;
this.Reset();
if (this.WaitingOptions.BreakTrigger && this.Client is ITcpClientBase tcpClient)
{
tcpClient.Disconnected += this.OnDisconnected;
}
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialClientBase serialClient)
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialSessionBase serialSession)
{
serialClient.Disconnected += this.OnSerialClientDisconnected;
serialSession.Disconnected += this.OnSerialSessionDisconnected;
}
if (this.WaitingOptions.AdapterFilter == AdapterFilter.AllAdapter || this.WaitingOptions.AdapterFilter == AdapterFilter.WaitAdapter)
{
@@ -287,14 +288,14 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
}
finally
{
m_lock.Release();
easyLock.Release();
if (this.WaitingOptions.BreakTrigger && this.Client is ITcpClientBase tcpClient)
{
tcpClient.Disconnected -= this.OnDisconnected;
}
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialClientBase serialClient)
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialSessionBase serialSession)
{
serialClient.Disconnected -= this.OnSerialClientDisconnected;
serialSession.Disconnected -= this.OnSerialSessionDisconnected;
}
if (this.WaitingOptions.AdapterFilter == AdapterFilter.AllAdapter || this.WaitingOptions.AdapterFilter == AdapterFilter.WaitAdapter)
{

View File

@@ -46,19 +46,6 @@ public static class StringExtensions
}
/// <summary>
/// 将16进制的字符转换为int32。
/// </summary>
/// <param name="hexString"></param>
/// <returns></returns>
public static int ByHexStringToInt32(this string hexString)
{
if (string.IsNullOrEmpty(hexString))
{
return default;
}
return int.Parse(hexString, System.Globalization.NumberStyles.HexNumber);
}
/// <summary>
/// <inheritdoc cref="Path.Combine(string[])"/>
/// 并把\\转为/

View File

@@ -82,7 +82,7 @@ public class ByteTransformUtil
/// </summary>
public static IThingsGatewayBitConverter GetTransByAddress(ref string address, IThingsGatewayBitConverter defaultTransform)
{
var hasCache = _cache.TryGetValue(address + defaultTransform.ToJson(), out IThingsGatewayBitConverter thingsGatewayBitConverter);
var hasCache = _cache.TryGetValue(address + defaultTransform.ToJsonString(), out IThingsGatewayBitConverter thingsGatewayBitConverter);
if (hasCache)
{
return thingsGatewayBitConverter;
@@ -187,7 +187,7 @@ public class ByteTransformUtil
{
converter.StringLength = length.Value;
}
_cache.SetCache(address + defaultTransform.ToJson(), converter);
_cache.SetCache(address + defaultTransform.ToJsonString(), converter);
return converter;
}

View File

@@ -15,6 +15,17 @@ namespace ThingsGateway.Foundation.Extension;
/// <inheritdoc/>
public static class OperResultExtensions
{
/// <summary>
/// 复制信息,包含第一个泛型类
/// </summary>
public static OperResult<T1> Copy<T1, T2>(this OperResult<T1, T2> result)
{
OperResult<T1> result1 = new(result.ResultCode, result.Message)
{
Content = result.Content1
};
return result1;
}
#region Public Methods
/// <summary>

View File

@@ -13,32 +13,31 @@
namespace ThingsGateway.Foundation.Serial;
/// <summary>
/// <inheritdoc cref="ISerialClientBase"/>
/// <inheritdoc cref="ISerialSessionBase"/>
/// </summary>
public interface ISerialClient : ISerialClientBase, IClientSender, IPluginObject
public interface ISerialSession : ISerialSessionBase, IClientSender, IPluginObject
{
/// <summary>
/// 成功连接到服务器
/// 成功打开串口
/// </summary>
ConnectedEventHandler<ISerialClient> Connected { get; set; }
ConnectedEventHandler<ISerialSession> Connected { get; set; }
/// <summary>
/// 准备连接的时候
/// 准备连接串口的时候
/// </summary>
SerialConnectingEventHandler<ISerialClient> Connecting { get; set; }
SerialConnectingEventHandler<ISerialSession> Connecting { get; set; }
/// <summary>
/// 连接串口
/// </summary>
/// <exception cref="TimeoutException"></exception>
/// <exception cref="Exception"></exception>
ISerialClient Connect(int timeout = 5000);
ISerialSession Connect();
/// <summary>
/// 配置服务器
/// </summary>
/// <param name="config"></param>
/// <exception cref="Exception"></exception>
ISerialClient Setup(TouchSocketConfig config);
ISerialSession Setup(TouchSocketConfig config);
}

View File

@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Serial;
/// <summary>
/// 串口连接接口。
/// </summary>
public interface ISerialClientBase : IClient, ISender, IDefaultSender, IPluginObject, IRequsetInfoSender
public interface ISerialSessionBase : IClient, ISender, IDefaultSender, IPluginObject, IRequsetInfoSender
{
/// <summary>
/// 是否允许自由调用<see cref="SetDataHandlingAdapter"/>进行赋值。
@@ -32,24 +32,19 @@ public interface ISerialClientBase : IClient, ISender, IDefaultSender, IPluginOb
/// <summary>
/// 数据处理适配器
/// </summary>
TcpDataHandlingAdapter DataHandlingAdapter { get; }
SingleStreamDataHandlingAdapter DataHandlingAdapter { get; }
/// <summary>
/// 断开连接
/// </summary>
DisconnectEventHandler<ISerialClientBase> Disconnected { get; set; }
DisconnectEventHandler<ISerialSessionBase> Disconnected { get; set; }
/// <summary>
/// 即将断开连接(仅主动断开时有效)。
/// <para>
/// </para>
/// </summary>
DisconnectEventHandler<ISerialClientBase> Disconnecting { get; set; }
/// <summary>
/// 表示是否为客户端。
/// </summary>
bool IsClient { get; }
DisconnectEventHandler<ISerialSessionBase> Disconnecting { get; set; }
/// <summary>
/// 主通信器
@@ -77,5 +72,5 @@ public interface ISerialClientBase : IClient, ISender, IDefaultSender, IPluginOb
/// 设置数据处理适配器
/// </summary>
/// <param name="adapter"></param>
void SetDataHandlingAdapter(TcpDataHandlingAdapter adapter);
void SetDataHandlingAdapter(SingleStreamDataHandlingAdapter adapter);
}

View File

@@ -9,7 +9,18 @@
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.IO.Ports;
namespace ThingsGateway.Foundation.Serial;
@@ -28,18 +39,22 @@ public sealed class SerialDelaySender : DisposableObject
/// <summary>
/// 延迟发送器
/// </summary>
public SerialDelaySender(SerialPort serialPort, int queueLength, Action<Exception> onError)
/// <param name="serialPort"></param>
/// <param name="onError"></param>
/// <param name="delaySenderOption"></param>
public SerialDelaySender(SerialPort serialPort, DelaySenderOption delaySenderOption, Action<Exception> onError)
{
this.DelayLength = delaySenderOption.DelayLength;
this.m_serial = serialPort;
this.m_onError = onError;
this.m_queueDatas = new IntelligentDataQueue<QueueDataBytes>(queueLength);
this.m_queueDatas = new IntelligentDataQueue<QueueDataBytes>(delaySenderOption.QueueLength);
this.m_lockSlim = new ReaderWriterLockSlim();
}
/// <summary>
/// 延迟包最大尺寸默认1024*512字节
/// 延迟包最大尺寸。
/// </summary>
public int DelayLength { get; set; } = 1024 * 512;
public int DelayLength { get; private set; }
/// <summary>
/// 是否处于发送状态

View File

@@ -10,20 +10,31 @@
//------------------------------------------------------------------------------
#endregion
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.IO.Ports;
using TouchSocket.Resources;
using TouchSocket.Sockets;
namespace ThingsGateway.Foundation.Serial;
/// <inheritdoc cref="SerialClientBase"/>
public class SerialClient : SerialClientBase
/// <inheritdoc cref="SerialSessionBase"/>
public class SerialsSession : SerialSessionBase
{
/// <summary>
/// 接收到数据
/// </summary>
public ReceivedEventHandler<SerialClient> Received { get; set; }
public ReceivedEventHandler<SerialsSession> Received { get; set; }
/// <summary>
/// 接收数据
@@ -40,38 +51,46 @@ public class SerialClient : SerialClientBase
/// <summary>
/// 串口管理
/// </summary>
public class SerialClientBase : BaseSerial, ISerialClient
public class SerialSessionBase : BaseSerial, ISerialSession
{
static readonly Protocol SerialPort = new("SerialPort");
static readonly Protocol SerialPort = new("SerialSession");
/// <summary>
/// 构造函数
/// </summary>
public SerialClientBase()
public SerialSessionBase()
{
this.Protocol = SerialPort;
}
#region
private int m_bufferRate = 1;
private SerialDelaySender m_delaySender;
private SerialPort m_mainSerialPort;
private int m_bufferRate = 1;
private volatile bool m_online;
private bool m_useDelaySender;
#endregion
#region
/// <inheritdoc/>
public ConnectedEventHandler<ISerialClient> Connected { get; set; }
public ConnectedEventHandler<ISerialSession> Connected { get; set; }
/// <inheritdoc/>
public SerialConnectingEventHandler<ISerialClient> Connecting { get; set; }
public SerialConnectingEventHandler<ISerialSession> Connecting { get; set; }
/// <inheritdoc/>
public DisconnectEventHandler<ISerialClientBase> Disconnected { get; set; }
public DisconnectEventHandler<ISerialSessionBase> Disconnected { get; set; }
/// <inheritdoc/>
public DisconnectEventHandler<ISerialClientBase> Disconnecting { get; set; }
public DisconnectEventHandler<ISerialSessionBase> Disconnecting { get; set; }
private void PrivateOnConnected(object o)
{
var e = (ConnectedEventArgs)o;
this.OnConnected(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpConnectedPlugin.OnTcpConnected), this, e);
}
/// <summary>
/// 已经建立Tcp连接
@@ -89,6 +108,23 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
}
private void PrivateOnConnecting(SerialConnectingEventArgs e)
{
this.LastReceivedTime = DateTime.Now;
this.LastSendTime = DateTime.Now;
if (this.CanSetDataHandlingAdapter)
{
this.SetDataHandlingAdapter(this.Config.GetValue(TouchSocketConfigExtension.TcpDataHandlingAdapterProperty).Invoke());
}
this.OnConnecting(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpConnectingPlugin.OnTcpConnecting), this, e);
}
/// <summary>
/// 准备连接的时候此时已初始化Socket但是并未建立Tcp连接
/// </summary>
@@ -105,6 +141,16 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
}
private void PrivateOnDisconnected(DisconnectEventArgs e)
{
this.OnDisconnected(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpDisconnectedPlugin.OnTcpDisconnected), this, e);
}
/// <summary>
/// 断开连接。在客户端未设置连接状态时,不会触发
/// </summary>
@@ -121,6 +167,16 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
}
private void PrivateOnDisconnecting(DisconnectEventArgs e)
{
this.OnDisconnecting(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpDisconnectingPlugin.OnTcpDisconnecting), this, e);
}
/// <summary>
/// 即将断开连接(仅主动断开时有效)。
/// <para>
@@ -140,97 +196,61 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
}
private void PrivateOnConnected(object o)
{
var e = (ConnectedEventArgs)o;
this.OnConnected(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpConnectedPlugin.OnTcpConnected), this, e);
}
private void PrivateOnConnecting(SerialConnectingEventArgs e)
{
this.LastReceivedTime = DateTime.Now;
this.LastSendTime = DateTime.Now;
if (this.CanSetDataHandlingAdapter)
{
this.SetDataHandlingAdapter(this.Config.GetValue(TouchSocketConfigExtension.TcpDataHandlingAdapterProperty).Invoke());
}
this.OnConnecting(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpConnectingPlugin.OnTcpConnecting), this, e);
}
private void PrivateOnDisconnected(DisconnectEventArgs e)
{
this.OnDisconnected(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpDisconnectedPlugin.OnTcpDisconnected), this, e);
}
private void PrivateOnDisconnecting(DisconnectEventArgs e)
{
this.OnDisconnecting(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpDisconnectingPlugin.OnTcpDisconnecting), this, e);
}
#endregion
#region
/// <inheritdoc/>
public bool CanSend => this.m_online;
/// <inheritdoc/>
public virtual bool CanSetDataHandlingAdapter => true;
/// <inheritdoc/>
public TouchSocketConfig Config { get; private set; }
/// <inheritdoc/>
public IContainer Container { get; private set; }
/// <inheritdoc/>
public TcpDataHandlingAdapter DataHandlingAdapter { get; private set; }
/// <inheritdoc/>
public bool IsClient => true;
/// <inheritdoc/>
public DateTime LastReceivedTime { get; private set; }
/// <inheritdoc/>
public DateTime LastSendTime { get; private set; }
/// <inheritdoc/>
public SerialPort MainSerialPort { get => this.m_mainSerialPort; }
/// <inheritdoc/>
public Func<ByteBlock, bool> OnHandleRawBuffer { get; set; }
/// <inheritdoc/>
public Func<ByteBlock, IRequestInfo, bool> OnHandleReceivedData { get; set; }
/// <inheritdoc/>
public IContainer Container { get; private set; }
/// <inheritdoc/>
public virtual bool CanSetDataHandlingAdapter => true;
/// <inheritdoc/>
public TouchSocketConfig Config { get; private set; }
/// <inheritdoc/>
public SingleStreamDataHandlingAdapter DataHandlingAdapter { get; private set; }
/// <summary>
/// <inheritdoc/>
/// </summary>
public SerialProperty SerialProperty { get; private set; }
/// <inheritdoc/>
public SerialPort MainSerialPort { get; private set; }
/// <inheritdoc/>
public bool Online { get => this.m_online; }
/// <inheritdoc/>
public bool CanSend => this.m_online;
/// <inheritdoc/>
public IPluginsManager PluginsManager { get; private set; }
/// <inheritdoc/>
public ReceiveType ReceiveType { get; private set; }
/// <inheritdoc/>
public Protocol Protocol { get; set; }
/// <inheritdoc/>
public ReceiveType ReceiveType { get; private set; }
#endregion
#region
@@ -255,6 +275,21 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
}
private void BreakOut(string msg)
{
lock (this.SyncRoot)
{
if (this.m_online)
{
this.m_online = false;
this.MainSerialPort.SafeDispose();
this.m_delaySender.SafeDispose();
this.DataHandlingAdapter.SafeDispose();
this.PrivateOnDisconnected(new DisconnectEventArgs(false, msg));
}
}
}
/// <summary>
/// <inheritdoc/>
/// </summary>
@@ -279,48 +314,13 @@ public class SerialClientBase : BaseSerial, ISerialClient
base.Dispose(disposing);
}
private void BreakOut(string msg)
{
lock (this.SyncRoot)
{
if (this.m_online)
{
this.m_online = false;
this.MainSerialPort.SafeDispose();
this.m_delaySender.SafeDispose();
this.DataHandlingAdapter.SafeDispose();
this.PrivateOnDisconnected(new DisconnectEventArgs(false, msg));
}
}
}
#endregion
#region Connect
/// <inheritdoc/>
public virtual ISerialClient Connect(int timeout = 5000)
{
this.TcpConnect(timeout);
return this;
}
/// <inheritdoc/>
public Task<ISerialClient> ConnectAsync(int timeout = 5000)
{
return Task.Run(() =>
{
return this.Connect(timeout);
});
}
/// <summary>
/// 建立Tcp的连接。
/// 打开串口
/// </summary>
/// <param name="timeout"></param>
/// <exception cref="ObjectDisposedException"></exception>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="Exception"></exception>
/// <exception cref="TimeoutException"></exception>
protected void TcpConnect(int timeout)
protected void Open()
{
lock (this.SyncRoot)
{
@@ -338,42 +338,42 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
var serialProperty = this.Config.GetValue(SerialConfigExtension.SerialProperty) ?? throw new ArgumentNullException("串口配置不能为空。");
this.m_mainSerialPort.SafeDispose();
m_mainSerialPort = this.CreateSerial(serialProperty);
this.MainSerialPort.SafeDispose();
var serialPort = this.CreateSerial(serialProperty);
var args = new SerialConnectingEventArgs(this.MainSerialPort);
this.PrivateOnConnecting(args);
m_mainSerialPort.Open();
serialPort.Open();
this.m_online = true;
this.SetSerialPort(m_mainSerialPort);
if (Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty) is DelaySenderOption senderOption)
{
m_useDelaySender = true;
m_delaySender.SafeDispose();
m_delaySender = new SerialDelaySender(MainSerialPort, senderOption.QueueLength, this.OnDelaySenderError)
{
DelayLength = senderOption.DelayLength
};
}
this.SetSerialPort(serialPort);
this.BeginReceive();
this.PrivateOnConnected(new ConnectedEventArgs());
}
}
/// <inheritdoc/>
public virtual ISerialSession Connect()
{
this.Open();
return this;
}
/// <inheritdoc/>
public Task<ISerialSession> ConnectAsync()
{
return Task.Run(() =>
{
return this.Connect();
});
}
#endregion
/// <summary>
/// <inheritdoc/>
/// </summary>
public SerialProperty SerialProperty { get; private set; }
/// <inheritdoc/>
public virtual void SetDataHandlingAdapter(TcpDataHandlingAdapter adapter)
public virtual void SetDataHandlingAdapter(SingleStreamDataHandlingAdapter adapter)
{
if (!this.CanSetDataHandlingAdapter)
{
@@ -384,7 +384,7 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
/// <inheritdoc/>
public ISerialClient Setup(TouchSocketConfig config)
public ISerialSession Setup(TouchSocketConfig config)
{
if (config == null)
{
@@ -402,6 +402,67 @@ public class SerialClientBase : BaseSerial, ISerialClient
return this;
}
private void BuildConfig(TouchSocketConfig config)
{
this.Config = config;
if (!(config.GetValue(TouchSocketCoreConfigExtension.ContainerProperty) is IContainer container))
{
container = new Container();
}
if (!container.IsRegistered(typeof(ILog)))
{
container.RegisterSingleton<ILog, LoggerGroup>();
}
if (!(config.GetValue(TouchSocketCoreConfigExtension.PluginsManagerProperty) is IPluginsManager pluginsManager))
{
pluginsManager = new PluginsManager(container);
}
if (container.IsRegistered(typeof(IPluginsManager)))
{
pluginsManager = container.Resolve<IPluginsManager>();
}
else
{
container.RegisterSingleton<IPluginsManager>(pluginsManager);
}
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigureContainerProperty) is Action<IContainer> actionContainer)
{
actionContainer.Invoke(container);
}
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigurePluginsProperty) is Action<IPluginsManager> actionPluginsManager)
{
pluginsManager.Enable = true;
actionPluginsManager.Invoke(pluginsManager);
}
this.Container = container;
this.PluginsManager = pluginsManager;
}
private void PrivateHandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
{
if (this.OnHandleReceivedData?.Invoke(byteBlock, requestInfo) == false)
{
return;
}
if (this.HandleReceivedData(byteBlock, requestInfo))
{
return;
}
if (this.PluginsManager.Enable)
{
var args = new ReceivedDataEventArgs(byteBlock, requestInfo);
this.PluginsManager.Raise(nameof(ITcpReceivedPlugin.OnTcpReceived), this, args);
}
}
/// <summary>
/// 处理已接收到的数据。
/// </summary>
@@ -459,7 +520,7 @@ public class SerialClientBase : BaseSerial, ISerialClient
/// 设置适配器,该方法不会检验<see cref="CanSetDataHandlingAdapter"/>的值。
/// </summary>
/// <param name="adapter"></param>
protected void SetAdapter(TcpDataHandlingAdapter adapter)
protected void SetAdapter(SingleStreamDataHandlingAdapter adapter)
{
this.ThrowIfDisposed();
if (adapter is null)
@@ -481,7 +542,8 @@ public class SerialClientBase : BaseSerial, ISerialClient
private void BeginReceive()
{
if (this.ReceiveType == ReceiveType.Auto)
if (this.ReceiveType == ReceiveType.Iocp)
{
SerialReceivedEventArgs eventArgs = new();
var byteBlock = BytePool.Default.GetByteBlock(this.BufferLength);
@@ -493,50 +555,15 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
MainSerialPort.DataReceived += this.EventArgs_Completed;
}
else if (this.ReceiveType == ReceiveType.Bio)
{
new Thread(BeginBio)
{
IsBackground = true
}
.Start();
}
}
private void BuildConfig(TouchSocketConfig config)
{
this.Config = config;
if (!(config.GetValue(TouchSocketCoreConfigExtension.ContainerProperty) is IContainer container))
{
container = new Container();
}
if (!container.IsRegistered(typeof(ILog)))
{
container.RegisterSingleton<ILog, LoggerGroup>();
}
if (!(config.GetValue(TouchSocketCoreConfigExtension.PluginsManagerProperty) is IPluginsManager pluginsManager))
{
pluginsManager = new PluginsManager(container);
}
if (container.IsRegistered(typeof(IPluginsManager)))
{
pluginsManager = container.Resolve<IPluginsManager>();
}
else
{
container.RegisterSingleton<IPluginsManager>(pluginsManager);
}
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigureContainerProperty) is Action<IContainer> actionContainer)
{
actionContainer.Invoke(container);
}
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigurePluginsProperty) is Action<IPluginsManager> actionPluginsManager)
{
pluginsManager.Enable = true;
actionPluginsManager.Invoke(pluginsManager);
}
this.Container = container;
this.PluginsManager = pluginsManager;
}
private SerialPort CreateSerial(SerialProperty serialProperty)
{
SerialPort serialPort = new(serialProperty.PortName, serialProperty.BaudRate, serialProperty.Parity, serialProperty.DataBits, serialProperty.StopBits)
@@ -566,7 +593,84 @@ public class SerialClientBase : BaseSerial, ISerialClient
this.BreakOut(ex.Message);
}
}
private void BeginBio()
{
while (true)
{
var byteBlock = new ByteBlock(this.BufferLength);
try
{
int r = MainSerialPort.Read(byteBlock.Buffer, 0, MainSerialPort.BytesToRead);
if (r == 0)
{
this.BreakOut("远程终端主动关闭");
return;
}
byteBlock.SetLength(r);
this.HandleBuffer(byteBlock);
}
catch (Exception ex)
{
this.BreakOut(ex.Message);
return;
}
}
}
private void ProcessReceived(SerialReceivedEventArgs e)
{
if (!this.m_online)
{
e.UserToken.SafeDispose();
return;
}
if (MainSerialPort.BytesToRead > 0)
{
byte[] buffer = new byte[2048];
var byteBlock = (ByteBlock)e.UserToken;
int num = MainSerialPort.Read(buffer, 0, MainSerialPort.BytesToRead);
byteBlock.Write(buffer, byteBlock.Len, num);
this.HandleBuffer(byteBlock);
try
{
var newByteBlock = BytePool.Default.GetByteBlock(Math.Min(this.BufferLength * this.m_bufferRate, 1024 * 1024));
newByteBlock.SetLength(num);
e.UserToken = newByteBlock;
if (MainSerialPort.BytesToRead > 0)
{
this.m_bufferRate += 2;
this.ProcessReceived(e);
}
}
catch (Exception ex)
{
e.UserToken.SafeDispose();
this.BreakOut(ex.Message);
}
}
else
{
e.UserToken.SafeDispose();
this.BreakOut("远程终端主动关闭");
}
}
private void SetSerialPort(SerialPort serialPort)
{
if (serialPort == null)
{
return;
}
this.MainSerialPort = serialPort;
var delaySenderOption = this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty);
if (delaySenderOption != null)
{
this.m_delaySender = new SerialDelaySender(MainSerialPort, delaySenderOption, this.OnDelaySenderError);
}
}
/// <summary>
/// 处理数据
/// </summary>
@@ -604,24 +708,6 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
}
private void PrivateHandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
{
if (this.OnHandleReceivedData?.Invoke(byteBlock, requestInfo) == false)
{
return;
}
if (this.HandleReceivedData(byteBlock, requestInfo))
{
return;
}
if (this.PluginsManager.Enable)
{
var args = new ReceivedDataEventArgs(byteBlock, requestInfo);
this.PluginsManager.Raise(nameof(ITcpReceivedPlugin.OnTcpReceived), this, args);
}
}
#region
#region
@@ -772,9 +858,9 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
if (this.HandleSendingData(buffer, offset, length))
{
if (this.m_useDelaySender && length < TouchSocketUtility.BigDataBoundary)
if (this.m_delaySender != null && length < m_delaySender.DelayLength)
{
this.m_delaySender.Send(new QueueDataBytes(buffer, offset, length));
this.m_delaySender.Send(QueueDataBytes.CreateNew(buffer, offset, length));
}
else
{
@@ -804,52 +890,5 @@ public class SerialClientBase : BaseSerial, ISerialClient
#endregion
private void ProcessReceived(SerialReceivedEventArgs e)
{
if (!this.m_online)
{
e.UserToken.SafeDispose();
return;
}
if (MainSerialPort.BytesToRead > 0)
{
byte[] buffer = new byte[2048];
var byteBlock = (ByteBlock)e.UserToken;
int num = MainSerialPort.Read(buffer, 0, MainSerialPort.BytesToRead);
byteBlock.Write(buffer, byteBlock.Len, num);
this.HandleBuffer(byteBlock);
try
{
var newByteBlock = BytePool.Default.GetByteBlock(Math.Min(this.BufferLength * this.m_bufferRate, 1024 * 1024));
newByteBlock.SetLength(num);
e.UserToken = newByteBlock;
if (MainSerialPort.BytesToRead > 0)
{
this.m_bufferRate += 2;
this.ProcessReceived(e);
}
}
catch (Exception ex)
{
e.UserToken.SafeDispose();
this.BreakOut(ex.Message);
}
}
else
{
e.UserToken.SafeDispose();
this.BreakOut("远程终端主动关闭");
}
}
private void SetSerialPort(SerialPort serialPort)
{
if (serialPort == null)
{
return;
}
this.m_mainSerialPort = serialPort;
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>net45;netstandard2.0;net6.0;net7.0</TargetFrameworks>
<OpenApiGenerateDocuments>false</OpenApiGenerateDocuments>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
@@ -13,7 +13,7 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="TouchSocket" Version="2.0.0-beta.135" />
<PackageReference Include="TouchSocket" Version="2.0.0-beta.154" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'!='net45'">
<PackageReference Include="System.IO.Ports" Version="7.0.0" />

View File

@@ -237,13 +237,13 @@
WaitingClientEx
</summary>
</member>
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesSerialBase.#ctor(ThingsGateway.Foundation.Serial.SerialClient)">
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesSerialBase.#ctor(ThingsGateway.Foundation.Serial.SerialsSession)">
<summary>
<inheritdoc cref="T:ThingsGateway.Foundation.ReadWriteDevicesSerialBase"/>
</summary>
<param name="serialClient"></param>
<param name="serialSession"></param>
</member>
<member name="P:ThingsGateway.Foundation.ReadWriteDevicesSerialBase.SerialClient">
<member name="P:ThingsGateway.Foundation.ReadWriteDevicesSerialBase.SerialsSession">
<summary>
串口管理对象
</summary>
@@ -351,7 +351,7 @@
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesTcpServerBase.Dispose(System.Boolean)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesTcpServerBase.Received(TouchSocket.Sockets.SocketClient,TouchSocket.Sockets.IRequestInfo)">
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesTcpServerBase.Received(TouchSocket.Sockets.SocketClient,TouchSocket.Core.IRequestInfo)">
<summary>
接收解析
</summary>
@@ -588,6 +588,9 @@
<member name="M:ThingsGateway.Foundation.EasyIncrementCount.#ctor(System.Int64,System.Int64,System.Int32)">
<inheritdoc cref="T:ThingsGateway.Foundation.EasyIncrementCount"/>
</member>
<member name="M:ThingsGateway.Foundation.EasyIncrementCount.Finalize">
<inheritdoc cref="T:ThingsGateway.Foundation.EasyIncrementCount"/>
</member>
<member name="P:ThingsGateway.Foundation.EasyIncrementCount.IncreaseTick">
<summary>
Tick
@@ -623,7 +626,7 @@
重置当前序号的初始值
</summary>
</member>
<member name="M:ThingsGateway.Foundation.EasyIncrementCount.Dispose(System.Boolean)">
<member name="M:ThingsGateway.Foundation.EasyIncrementCount.Dispose">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.EasyLock">
@@ -631,6 +634,9 @@
EasyLock使用轻量级SemaphoreSlim锁只允许一个并发量并记录并发信息
</summary>
</member>
<member name="M:ThingsGateway.Foundation.EasyLock.Finalize">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.EasyLock.LockWaitCount">
<summary>
当前正在等待的数量
@@ -641,6 +647,9 @@
当前锁是否在等待当中
</summary>
</member>
<member name="M:ThingsGateway.Foundation.EasyLock.Dispose">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.EasyLock.Release">
<summary>
离开锁
@@ -666,9 +675,6 @@
进入锁
</summary>
</member>
<member name="M:ThingsGateway.Foundation.EasyLock.Dispose(System.Boolean)">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.TcpClientEx">
<summary>
简单TCP客户端
@@ -679,7 +685,7 @@
接收到数据
</summary>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientEx.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Sockets.IRequestInfo)">
<member name="M:ThingsGateway.Foundation.TcpClientEx.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Core.IRequestInfo)">
<summary>
接收数据
</summary>
@@ -815,7 +821,7 @@
<summary>
建立Tcp的连接。
</summary>
<param name="timeOut"></param>
<param name="timeout"></param>
<param name="token"></param>
<exception cref="T:System.ObjectDisposedException"></exception>
<exception cref="T:System.ArgumentNullException"></exception>
@@ -831,7 +837,7 @@
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.GetStream">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SetDataHandlingAdapter(TouchSocket.Sockets.TcpDataHandlingAdapter)">
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SetDataHandlingAdapter(TouchSocket.Core.SingleStreamDataHandlingAdapter)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.Setup(System.String)">
@@ -840,7 +846,7 @@
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.Setup(TouchSocket.Core.TouchSocketConfig)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Sockets.IRequestInfo)">
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Core.IRequestInfo)">
<summary>
处理已接收到的数据。
</summary>
@@ -869,7 +875,7 @@
</summary>
<param name="ex"></param>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SetAdapter(TouchSocket.Sockets.TcpDataHandlingAdapter)">
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SetAdapter(TouchSocket.Core.SingleStreamDataHandlingAdapter)">
<summary>
设置适配器,该方法不会检验<see cref="P:ThingsGateway.Foundation.TcpClientBaseEx.CanSetDataHandlingAdapter"/>的值。
</summary>
@@ -880,13 +886,13 @@
处理数据
</summary>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.Send(TouchSocket.Sockets.IRequestInfo)">
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.Send(TouchSocket.Core.IRequestInfo)">
<summary>
<inheritdoc/>
</summary>
<param name="requestInfo"></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"></exception>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.Send(System.Byte[],System.Int32,System.Int32)">
@@ -897,7 +903,7 @@
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.Send(System.Collections.Generic.IList{System.ArraySegment{System.Byte}})">
@@ -906,7 +912,7 @@
</summary>
<param name="transferBytes"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SendAsync(System.Byte[],System.Int32,System.Int32)">
@@ -917,16 +923,16 @@
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SendAsync(TouchSocket.Sockets.IRequestInfo)">
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SendAsync(TouchSocket.Core.IRequestInfo)">
<summary>
<inheritdoc/>
</summary>
<param name="requestInfo"></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"></exception>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SendAsync(System.Collections.Generic.IList{System.ArraySegment{System.Byte}})">
@@ -935,7 +941,7 @@
</summary>
<param name="transferBytes"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.DefaultSend(System.Byte[],System.Int32,System.Int32)">
@@ -946,7 +952,7 @@
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.DefaultSendAsync(System.Byte[],System.Int32,System.Int32)">
@@ -957,7 +963,7 @@
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="T:ThingsGateway.Foundation.WaitingClientExExtension">
@@ -1031,9 +1037,9 @@
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesTcpDataHandleAdapter`1.GetResponse(TouchSocket.Core.ByteBlock,`0,System.Byte[],System.Byte[])">
<summary>
解包获取实际数据包
<para>当不满足解析条件时,请返回<see cref="F:TouchSocket.Sockets.FilterResult.Cache"/>,此时会保存<see cref="P:TouchSocket.Core.ByteBlock.CanReadLen"/>的数据</para>
<para>当数据部分异常时,请移动<see cref="P:TouchSocket.Core.ByteBlock.Pos"/>到指定位置,然后返回<see cref="F:TouchSocket.Sockets.FilterResult.GoOn"/></para>
<para>当完全满足解析条件时,请返回<see cref="F:TouchSocket.Sockets.FilterResult.Success"/>最后将<see cref="P:TouchSocket.Core.ByteBlock.Pos"/>移至指定位置。</para>
<para>当不满足解析条件时,请返回<see cref="F:TouchSocket.Core.FilterResult.Cache"/>,此时会保存<see cref="P:TouchSocket.Core.ByteBlock.CanReadLen"/>的数据</para>
<para>当数据部分异常时,请移动<see cref="P:TouchSocket.Core.ByteBlock.Pos"/>到指定位置,然后返回<see cref="F:TouchSocket.Core.FilterResult.GoOn"/></para>
<para>当完全满足解析条件时,请返回<see cref="F:TouchSocket.Core.FilterResult.Success"/>最后将<see cref="P:TouchSocket.Core.ByteBlock.Pos"/>移至指定位置。</para>
</summary>
</member>
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesTcpDataHandleAdapter`1.GoSend(System.Byte[])">
@@ -1099,7 +1105,7 @@
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesUdpDataHandleAdapter`1.PreviewSend(System.Net.EndPoint,System.Collections.Generic.IList{System.ArraySegment{System.Byte}})">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesUdpDataHandleAdapter`1.PreviewSend(TouchSocket.Sockets.IRequestInfo)">
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesUdpDataHandleAdapter`1.PreviewSend(TouchSocket.Core.IRequestInfo)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesUdpDataHandleAdapter`1.Reset">
@@ -1283,13 +1289,6 @@
<param name="value"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Extension.String.StringExtensions.ByHexStringToInt32(System.String)">
<summary>
将16进制的字符转换为int32。
</summary>
<param name="hexString"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Extension.String.StringExtensions.CombinePathOS(System.String,System.String[])">
<summary>
<inheritdoc cref="M:System.IO.Path.Combine(System.String[])"/>
@@ -1313,6 +1312,11 @@
<member name="T:ThingsGateway.Foundation.Extension.OperResultExtensions">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Extension.OperResultExtensions.Copy``2(ThingsGateway.Foundation.OperResult{``0,``1})">
<summary>
复制信息,包含第一个泛型类
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Extension.OperResultExtensions.Copy``1(ThingsGateway.Foundation.OperResult)">
<summary>
复制信息,不包含泛型类
@@ -1834,95 +1838,89 @@
<param name="value"></param>
<returns></returns>
</member>
<member name="T:ThingsGateway.Foundation.Serial.ISerialClient">
<member name="T:ThingsGateway.Foundation.Serial.ISerialSession">
<summary>
<inheritdoc cref="T:ThingsGateway.Foundation.Serial.ISerialClientBase"/>
<inheritdoc cref="T:ThingsGateway.Foundation.Serial.ISerialSessionBase"/>
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClient.Connected">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSession.Connected">
<summary>
成功连接到服务器
成功打开串口
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClient.Connecting">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSession.Connecting">
<summary>
准备连接的时候
准备连接串口的时候
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.ISerialClient.Connect(System.Int32)">
<member name="M:ThingsGateway.Foundation.Serial.ISerialSession.Connect">
<summary>
连接串口
</summary>
<exception cref="T:System.TimeoutException"></exception>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.ISerialClient.Setup(TouchSocket.Core.TouchSocketConfig)">
<member name="M:ThingsGateway.Foundation.Serial.ISerialSession.Setup(TouchSocket.Core.TouchSocketConfig)">
<summary>
配置服务器
</summary>
<param name="config"></param>
<exception cref="T:System.Exception"></exception>
</member>
<member name="T:ThingsGateway.Foundation.Serial.ISerialClientBase">
<member name="T:ThingsGateway.Foundation.Serial.ISerialSessionBase">
<summary>
串口连接接口。
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.CanSetDataHandlingAdapter">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.CanSetDataHandlingAdapter">
<summary>
是否允许自由调用<see cref="M:ThingsGateway.Foundation.Serial.ISerialClientBase.SetDataHandlingAdapter(TouchSocket.Sockets.TcpDataHandlingAdapter)"/>进行赋值。
是否允许自由调用<see cref="M:ThingsGateway.Foundation.Serial.ISerialSessionBase.SetDataHandlingAdapter(TouchSocket.Core.SingleStreamDataHandlingAdapter)"/>进行赋值。
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.Config">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.Config">
<summary>
客户端配置
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.DataHandlingAdapter">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.DataHandlingAdapter">
<summary>
数据处理适配器
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.Disconnected">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.Disconnected">
<summary>
断开连接
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.Disconnecting">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.Disconnecting">
<summary>
即将断开连接(仅主动断开时有效)。
<para>
</para>
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.IsClient">
<summary>
表示是否为客户端。
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.MainSerialPort">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.MainSerialPort">
<summary>
主通信器
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.ReceiveType">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.ReceiveType">
<summary>
接收模式
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.SerialProperty">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.SerialProperty">
<summary>
串口描述
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.ISerialClientBase.Close(System.String)">
<member name="M:ThingsGateway.Foundation.Serial.ISerialSessionBase.Close(System.String)">
<summary>
关闭客户端。
</summary>
<param name="msg"></param>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.ISerialClientBase.SetDataHandlingAdapter(TouchSocket.Sockets.TcpDataHandlingAdapter)">
<member name="M:ThingsGateway.Foundation.Serial.ISerialSessionBase.SetDataHandlingAdapter(TouchSocket.Core.SingleStreamDataHandlingAdapter)">
<summary>
设置数据处理适配器
</summary>
@@ -1961,285 +1959,22 @@
<param name="value"></param>
<returns></returns>
</member>
<member name="T:ThingsGateway.Foundation.Serial.SerialClient">
<inheritdoc cref="T:ThingsGateway.Foundation.Serial.SerialClientBase"/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClient.Received">
<summary>
接收到数据
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClient.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Sockets.IRequestInfo)">
<summary>
接收数据
</summary>
<param name="byteBlock"></param>
<param name="requestInfo"></param>
</member>
<member name="T:ThingsGateway.Foundation.Serial.SerialClientBase">
<summary>
串口管理
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.#ctor">
<summary>
构造函数
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Connected">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Connecting">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Disconnected">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Disconnecting">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.OnConnected(TouchSocket.Sockets.ConnectedEventArgs)">
<summary>
已经建立Tcp连接
</summary>
<param name="e"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.OnConnecting(ThingsGateway.Foundation.Serial.SerialConnectingEventArgs)">
<summary>
准备连接的时候此时已初始化Socket但是并未建立Tcp连接
</summary>
<param name="e"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.OnDisconnected(TouchSocket.Sockets.DisconnectEventArgs)">
<summary>
断开连接。在客户端未设置连接状态时,不会触发
</summary>
<param name="e"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.OnDisconnecting(TouchSocket.Sockets.DisconnectEventArgs)">
<summary>
即将断开连接(仅主动断开时有效)。
<para>
当主动调用Close断开时。
</para>
</summary>
<param name="e"></param>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.CanSend">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.CanSetDataHandlingAdapter">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Config">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Container">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.DataHandlingAdapter">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.IsClient">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.LastReceivedTime">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.LastSendTime">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.MainSerialPort">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.OnHandleRawBuffer">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.OnHandleReceivedData">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Online">
<inheritdoc/>
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.PluginsManager">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Protocol">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.ReceiveType">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.Close(System.String)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.Dispose(System.Boolean)">
<summary>
<inheritdoc/>
</summary>
<param name="disposing"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.Connect(System.Int32)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.ConnectAsync(System.Int32)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.TcpConnect(System.Int32)">
<summary>
建立Tcp的连接。
</summary>
<param name="timeout"></param>
<exception cref="T:System.ObjectDisposedException"></exception>
<exception cref="T:System.ArgumentNullException"></exception>
<exception cref="T:System.Exception"></exception>
<exception cref="T:System.TimeoutException"></exception>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.SerialProperty">
<summary>
<inheritdoc/>
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.SetDataHandlingAdapter(TouchSocket.Sockets.TcpDataHandlingAdapter)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.Setup(TouchSocket.Core.TouchSocketConfig)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Sockets.IRequestInfo)">
<summary>
处理已接收到的数据。
</summary>
<param name="byteBlock">以二进制流形式传递</param>
<param name="requestInfo">以解析的数据对象传递</param>
<returns>如果返回<see langword="true"/>则表示数据已被处理,且不会再向下传递。</returns>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.HandleSendingData(System.Byte[],System.Int32,System.Int32)">
<summary>
当即将发送时,如果覆盖父类方法,则不会触发插件。
</summary>
<param name="buffer">数据缓存区</param>
<param name="offset">偏移</param>
<param name="length">长度</param>
<returns>返回值表示是否允许发送</returns>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.LoadConfig(TouchSocket.Core.TouchSocketConfig)">
<summary>
加载配置
</summary>
<param name="config"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.OnDelaySenderError(System.Exception)">
<summary>
在延迟发生错误
</summary>
<param name="ex"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.SetAdapter(TouchSocket.Sockets.TcpDataHandlingAdapter)">
<summary>
设置适配器,该方法不会检验<see cref="P:ThingsGateway.Foundation.Serial.SerialClientBase.CanSetDataHandlingAdapter"/>的值。
</summary>
<param name="adapter"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.HandleBuffer(TouchSocket.Core.ByteBlock)">
<summary>
处理数据
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.Send(TouchSocket.Sockets.IRequestInfo)">
<summary>
<inheritdoc/>
</summary>
<param name="requestInfo"></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"></exception>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.Send(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.Send(System.Collections.Generic.IList{System.ArraySegment{System.Byte}})">
<summary>
<inheritdoc/>
</summary>
<param name="transferBytes"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.SendAsync(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.SendAsync(TouchSocket.Sockets.IRequestInfo)">
<summary>
<inheritdoc/>
</summary>
<param name="requestInfo"></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"></exception>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.SendAsync(System.Collections.Generic.IList{System.ArraySegment{System.Byte}})">
<summary>
<inheritdoc/>
</summary>
<param name="transferBytes"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.DefaultSend(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.DefaultSendAsync(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="T:ThingsGateway.Foundation.Serial.SerialDelaySender">
<summary>
延迟发送器
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialDelaySender.#ctor(System.IO.Ports.SerialPort,System.Int32,System.Action{System.Exception})">
<member name="M:ThingsGateway.Foundation.Serial.SerialDelaySender.#ctor(System.IO.Ports.SerialPort,TouchSocket.Sockets.DelaySenderOption,System.Action{System.Exception})">
<summary>
延迟发送器
</summary>
<param name="serialPort"></param>
<param name="onError"></param>
<param name="delaySenderOption"></param>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialDelaySender.DelayLength">
<summary>
延迟包最大尺寸默认1024*512字节
延迟包最大尺寸。
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialDelaySender.Sending">
@@ -2291,6 +2026,263 @@
<member name="M:ThingsGateway.Foundation.Serial.SerialProperty.ToString">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.Serial.SerialsSession">
<inheritdoc cref="T:ThingsGateway.Foundation.Serial.SerialSessionBase"/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialsSession.Received">
<summary>
接收到数据
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialsSession.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Core.IRequestInfo)">
<summary>
接收数据
</summary>
<param name="byteBlock"></param>
<param name="requestInfo"></param>
</member>
<member name="T:ThingsGateway.Foundation.Serial.SerialSessionBase">
<summary>
串口管理
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.#ctor">
<summary>
构造函数
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Connected">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Connecting">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Disconnected">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Disconnecting">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.OnConnected(TouchSocket.Sockets.ConnectedEventArgs)">
<summary>
已经建立Tcp连接
</summary>
<param name="e"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.OnConnecting(ThingsGateway.Foundation.Serial.SerialConnectingEventArgs)">
<summary>
准备连接的时候此时已初始化Socket但是并未建立Tcp连接
</summary>
<param name="e"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.OnDisconnected(TouchSocket.Sockets.DisconnectEventArgs)">
<summary>
断开连接。在客户端未设置连接状态时,不会触发
</summary>
<param name="e"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.OnDisconnecting(TouchSocket.Sockets.DisconnectEventArgs)">
<summary>
即将断开连接(仅主动断开时有效)。
<para>
当主动调用Close断开时。
</para>
</summary>
<param name="e"></param>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.LastReceivedTime">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.LastSendTime">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.OnHandleRawBuffer">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.OnHandleReceivedData">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Container">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.CanSetDataHandlingAdapter">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Config">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.DataHandlingAdapter">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.SerialProperty">
<summary>
<inheritdoc/>
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.MainSerialPort">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Online">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.CanSend">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.PluginsManager">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.ReceiveType">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Protocol">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Close(System.String)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Dispose(System.Boolean)">
<summary>
<inheritdoc/>
</summary>
<param name="disposing"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Open">
<summary>
打开串口
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Connect">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.ConnectAsync">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.SetDataHandlingAdapter(TouchSocket.Core.SingleStreamDataHandlingAdapter)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Setup(TouchSocket.Core.TouchSocketConfig)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Core.IRequestInfo)">
<summary>
处理已接收到的数据。
</summary>
<param name="byteBlock">以二进制流形式传递</param>
<param name="requestInfo">以解析的数据对象传递</param>
<returns>如果返回<see langword="true"/>则表示数据已被处理,且不会再向下传递。</returns>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.HandleSendingData(System.Byte[],System.Int32,System.Int32)">
<summary>
当即将发送时,如果覆盖父类方法,则不会触发插件。
</summary>
<param name="buffer">数据缓存区</param>
<param name="offset">偏移</param>
<param name="length">长度</param>
<returns>返回值表示是否允许发送</returns>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.LoadConfig(TouchSocket.Core.TouchSocketConfig)">
<summary>
加载配置
</summary>
<param name="config"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.OnDelaySenderError(System.Exception)">
<summary>
在延迟发生错误
</summary>
<param name="ex"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.SetAdapter(TouchSocket.Core.SingleStreamDataHandlingAdapter)">
<summary>
设置适配器,该方法不会检验<see cref="P:ThingsGateway.Foundation.Serial.SerialSessionBase.CanSetDataHandlingAdapter"/>的值。
</summary>
<param name="adapter"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.HandleBuffer(TouchSocket.Core.ByteBlock)">
<summary>
处理数据
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Send(TouchSocket.Core.IRequestInfo)">
<summary>
<inheritdoc/>
</summary>
<param name="requestInfo"></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"></exception>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Send(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Send(System.Collections.Generic.IList{System.ArraySegment{System.Byte}})">
<summary>
<inheritdoc/>
</summary>
<param name="transferBytes"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.SendAsync(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.SendAsync(TouchSocket.Core.IRequestInfo)">
<summary>
<inheritdoc/>
</summary>
<param name="requestInfo"></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"></exception>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.SendAsync(System.Collections.Generic.IList{System.ArraySegment{System.Byte}})">
<summary>
<inheritdoc/>
</summary>
<param name="transferBytes"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.DefaultSend(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.DefaultSendAsync(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="T:ThingsGateway.Foundation.SerialPortExtensions">
<summary>
SocketExtension

View File

@@ -31,11 +31,11 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
private DataFormat dataFormat;
/// <inheritdoc/>
[JsonIgnore]
public Encoding Encoding { get; set; } = Encoding.UTF8;
public virtual Encoding Encoding { get; set; } = Encoding.UTF8;
/// <inheritdoc/>
public BcdFormat? BcdFormat { get; set; }
public virtual BcdFormat? BcdFormat { get; set; }
/// <inheritdoc/>
public int StringLength { get; set; }
public virtual int StringLength { get; set; }
/// <summary>
/// 构造函数
@@ -55,7 +55,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public DataFormat DataFormat
public virtual DataFormat DataFormat
{
get
{
@@ -69,9 +69,9 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
/// <inheritdoc/>
public EndianType EndianType => endianType;
public virtual EndianType EndianType => endianType;
/// <inheritdoc/>
public bool IsStringReverseByteWord { get; set; }
public virtual bool IsStringReverseByteWord { get; set; }
/// <inheritdoc/>
public virtual IThingsGatewayBitConverter CreateByDateFormat(DataFormat dataFormat)
@@ -86,7 +86,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
return byteConverter;
}
/// <inheritdoc/>
public byte[] GetBytes(bool value)
public virtual byte[] GetBytes(bool value)
{
return GetBytes(new bool[1]
{
@@ -95,13 +95,13 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public byte[] GetBytes(bool[] values)
public virtual byte[] GetBytes(bool[] values)
{
return values?.BoolArrayToByte();
}
/// <inheritdoc/>
public byte[] GetBytes(short value)
public virtual byte[] GetBytes(short value)
{
byte[] bytes = BitConverter.GetBytes(value);
if (!IsSameOfSet())
@@ -111,7 +111,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
return bytes;
}
/// <inheritdoc/>
public byte[] GetBytes(short[] value)
public virtual byte[] GetBytes(short[] value)
{
byte[] numArray = new byte[value.Length * 2];
for (int index = 0; index < value.Length; ++index)
@@ -123,7 +123,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public byte[] GetBytes(ushort value)
public virtual byte[] GetBytes(ushort value)
{
byte[] bytes = BitConverter.GetBytes(value);
if (!IsSameOfSet())
@@ -133,7 +133,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
return bytes;
}
/// <inheritdoc/>
public byte[] GetBytes(ushort[] value)
public virtual byte[] GetBytes(ushort[] value)
{
byte[] numArray = new byte[value.Length * 2];
for (int index = 0; index < value.Length; ++index)
@@ -144,12 +144,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
return numArray;
}
/// <inheritdoc/>
public byte[] GetBytes(int value)
public virtual byte[] GetBytes(int value)
{
return ByteTransDataFormat4(BitConverter.GetBytes(value));
}
/// <inheritdoc/>
public byte[] GetBytes(int[] value)
public virtual byte[] GetBytes(int[] value)
{
byte[] numArray = new byte[value.Length * 2];
for (int index = 0; index < value.Length; ++index)
@@ -160,12 +160,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
return numArray;
}
/// <inheritdoc/>
public byte[] GetBytes(uint value)
public virtual byte[] GetBytes(uint value)
{
return ByteTransDataFormat4(BitConverter.GetBytes(value));
}
/// <inheritdoc/>
public byte[] GetBytes(uint[] value)
public virtual byte[] GetBytes(uint[] value)
{
byte[] numArray = new byte[value.Length * 2];
for (int index = 0; index < value.Length; ++index)
@@ -176,12 +176,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
return numArray;
}
/// <inheritdoc/>
public byte[] GetBytes(long value)
public virtual byte[] GetBytes(long value)
{
return ByteTransDataFormat8(BitConverter.GetBytes(value));
}
/// <inheritdoc/>
public byte[] GetBytes(long[] value)
public virtual byte[] GetBytes(long[] value)
{
byte[] numArray = new byte[value.Length * 2];
for (int index = 0; index < value.Length; ++index)
@@ -192,12 +192,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
return numArray;
}
/// <inheritdoc/>
public byte[] GetBytes(ulong value)
public virtual byte[] GetBytes(ulong value)
{
return ByteTransDataFormat8(BitConverter.GetBytes(value));
}
/// <inheritdoc/>
public byte[] GetBytes(ulong[] value)
public virtual byte[] GetBytes(ulong[] value)
{
byte[] numArray = new byte[value.Length * 2];
for (int index = 0; index < value.Length; ++index)
@@ -208,12 +208,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
return numArray;
}
/// <inheritdoc/>
public byte[] GetBytes(float value)
public virtual byte[] GetBytes(float value)
{
return ByteTransDataFormat4(BitConverter.GetBytes(value));
}
/// <inheritdoc/>
public byte[] GetBytes(float[] value)
public virtual byte[] GetBytes(float[] value)
{
byte[] numArray = new byte[value.Length * 2];
for (int index = 0; index < value.Length; ++index)
@@ -224,12 +224,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
return numArray;
}
/// <inheritdoc/>
public byte[] GetBytes(double value)
public virtual byte[] GetBytes(double value)
{
return ByteTransDataFormat8(BitConverter.GetBytes(value));
}
/// <inheritdoc/>
public byte[] GetBytes(double[] value)
public virtual byte[] GetBytes(double[] value)
{
byte[] numArray = new byte[value.Length * 2];
for (int index = 0; index < value.Length; ++index)
@@ -240,7 +240,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
return numArray;
}
/// <inheritdoc/>
public byte[] GetBytes(string value)
public virtual byte[] GetBytes(string value)
{
if (value == null)
{
@@ -280,7 +280,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
/// <inheritdoc/>
public bool IsSameOfSet()
public virtual bool IsSameOfSet()
{
return !(BitConverter.IsLittleEndian ^ (endianType == EndianType.Little));
}
@@ -288,7 +288,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
/// <inheritdoc/>
public bool ToBoolean(byte[] buffer, int offset)
public virtual bool ToBoolean(byte[] buffer, int offset)
{
byte[] bytes = new byte[buffer.Length];
Array.Copy(buffer, 0, bytes, 0, buffer.Length);
@@ -296,7 +296,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public byte ToByte(byte[] buffer, int offset)
public virtual byte ToByte(byte[] buffer, int offset)
{
byte[] bytes = new byte[1];
Array.Copy(buffer, offset, bytes, 0, bytes.Length);
@@ -304,7 +304,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public byte[] ToByte(byte[] buffer, int offset, int length)
public virtual byte[] ToByte(byte[] buffer, int offset, int length)
{
byte[] bytes = new byte[length];
Array.Copy(buffer, offset, bytes, 0, bytes.Length);
@@ -317,7 +317,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <returns></returns>
public double ToDouble(byte[] buffer, int offset)
public virtual double ToDouble(byte[] buffer, int offset)
{
byte[] bytes = ByteTransDataFormat8(buffer, offset);
@@ -325,7 +325,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public short ToInt16(byte[] buffer, int offset)
public virtual short ToInt16(byte[] buffer, int offset)
{
byte[] bytes = new byte[2];
Array.Copy(buffer, offset, bytes, 0, bytes.Length);
@@ -337,7 +337,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public int ToInt32(byte[] buffer, int offset)
public virtual int ToInt32(byte[] buffer, int offset)
{
byte[] bytes = ByteTransDataFormat4(buffer, offset);
@@ -345,14 +345,14 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public long ToInt64(byte[] buffer, int offset)
public virtual long ToInt64(byte[] buffer, int offset)
{
byte[] bytes = ByteTransDataFormat8(buffer, offset);
return BitConverter.ToInt64(bytes, 0);
}
/// <inheritdoc/>
public float ToSingle(byte[] buffer, int offset)
public virtual float ToSingle(byte[] buffer, int offset)
{
byte[] bytes = ByteTransDataFormat4(buffer, offset);
@@ -360,13 +360,13 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public string ToString(byte[] buffer)
public virtual string ToString(byte[] buffer)
{
return ToString(buffer, 0, buffer.Length);
}
/// <inheritdoc/>
public string ToString(byte[] buffer, int offset, int length)
public virtual string ToString(byte[] buffer, int offset, int length)
{
byte[] numArray = buffer.SelectMiddle(offset, length);
if (BcdFormat != null)
@@ -385,7 +385,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public ushort ToUInt16(byte[] buffer, int offset)
public virtual ushort ToUInt16(byte[] buffer, int offset)
{
byte[] bytes = new byte[2];
Array.Copy(buffer, offset, bytes, 0, 2);
@@ -397,7 +397,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public uint ToUInt32(byte[] buffer, int offset)
public virtual uint ToUInt32(byte[] buffer, int offset)
{
byte[] bytes = ByteTransDataFormat4(buffer, offset);
@@ -405,7 +405,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public ulong ToUInt64(byte[] buffer, int offset)
public virtual ulong ToUInt64(byte[] buffer, int offset)
{
byte[] bytes = ByteTransDataFormat8(buffer, offset);
return BitConverter.ToUInt64(bytes, 0);
@@ -508,7 +508,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public bool[] ToBoolean(byte[] buffer, int offset, int len)
public virtual bool[] ToBoolean(byte[] buffer, int offset, int len)
{
bool[] flagArray = new bool[len];
for (int index = 0; index < len; ++index)
@@ -519,7 +519,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public double[] ToDouble(byte[] buffer, int offset, int len)
public virtual double[] ToDouble(byte[] buffer, int offset, int len)
{
double[] numArray = new double[len];
for (int index = 0; index < len; ++index)
@@ -530,7 +530,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public short[] ToInt16(byte[] buffer, int offset, int len)
public virtual short[] ToInt16(byte[] buffer, int offset, int len)
{
short[] numArray = new short[len];
for (int index = 0; index < len; ++index)
@@ -541,7 +541,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public int[] ToInt32(byte[] buffer, int offset, int len)
public virtual int[] ToInt32(byte[] buffer, int offset, int len)
{
int[] numArray = new int[len];
for (int index = 0; index < len; ++index)
@@ -552,7 +552,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public long[] ToInt64(byte[] buffer, int offset, int len)
public virtual long[] ToInt64(byte[] buffer, int offset, int len)
{
long[] numArray = new long[len];
for (int index = 0; index < len; ++index)
@@ -562,7 +562,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
return numArray;
}
/// <inheritdoc/>
public float[] ToSingle(byte[] buffer, int offset, int len)
public virtual float[] ToSingle(byte[] buffer, int offset, int len)
{
float[] numArray = new float[len];
for (int index = 0; index < len; ++index)
@@ -573,7 +573,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public ushort[] ToUInt16(byte[] buffer, int offset, int len)
public virtual ushort[] ToUInt16(byte[] buffer, int offset, int len)
{
ushort[] numArray = new ushort[len];
for (int index = 0; index < len; ++index)
@@ -584,7 +584,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public uint[] ToUInt32(byte[] buffer, int offset, int len)
public virtual uint[] ToUInt32(byte[] buffer, int offset, int len)
{
uint[] numArray = new uint[len];
for (int index = 0; index < len; ++index)
@@ -595,7 +595,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public ulong[] ToUInt64(byte[] buffer, int offset, int len)
public virtual ulong[] ToUInt64(byte[] buffer, int offset, int len)
{
ulong[] numArray = new ulong[len];
for (int index = 0; index < len; ++index)

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Foundataion\ThingsGateway.Foundation.Adapter.DLT645\ThingsGateway.Foundation.Adapter.DLT645.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>ModbusDemo</name>
<name>DLT645Test</name>
</assembly>
<members>
</members>

View File

@@ -0,0 +1,112 @@
using ThingsGateway.Foundation;
using ThingsGateway.Foundation.Adapter.DLT645;
using ThingsGateway.Foundation.Extension.Byte;
using ThingsGateway.Foundation.Serial;
using TouchSocket.Core;
using TouchSocket.Sockets;
namespace DLT645Test
{
internal class Program
{
static async Task Main(string[] args)
{
await DLT645_2007ClientAsync();
Console.ReadLine();
}
private static async Task DLT645_2007ClientAsync()
{
//链路基础配置项
var config = new TouchSocketConfig();
config.SetRemoteIPHost(new IPHost("127.0.0.1:502"))//TCP/UDP链路才需要
.SetSerialProperty(new SerialProperty() //串口链路才需要
{
PortName = "COM1"
}).SetBufferLength(1024);
var serialSession = new SerialsSession();//链路对象
serialSession.Setup(config);
//创建协议对象,构造函数需要传入对应链路对象
DLT645_2007 dlt6452007 = new(serialSession)//传入链路
{
//协议配置
DataFormat = DataFormat.ABCD,
FrameTime = 0,
CacheTimeout = 1000,
ConnectTimeOut = 3000,
TimeOut = 3000,
EnableFEHead = true,
};
#region
//测试读取写入
Console.WriteLine("dlt6452007" + dlt6452007.SerialsSession.SerialProperty.ToJsonString());
await TestAsync(dlt6452007);
#endregion
}
private static async Task TestAsync(DLT645_2007 plc)
{
//下面的方法对应PLC读写协议对象都是通用的
//注意下面的方法都带有CancellationToken传播一般是在最后一个参数默认为None
//var bytes02010100Result = await plc.ReadAsync("03010100", 20);
////返回带有是否成功等参数实际数据在data.Content中
//Console.WriteLine("bytes02010100Result" + (bytes02010100Result.IsSuccess ? bytes02010100Result.Content.ToHexString() : bytes02010100Result.Message));
//Console.WriteLine("bytes02010100Result" + (bytes02010100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToDouble(bytes02010100Result.Content, 0) : bytes02010100Result.Message));
//var bytes02020100Result = await plc.ReadAsync("02020100", 20);
////返回带有是否成功等参数实际数据在data.Content中
//Console.WriteLine("bytes02020100Result" + (bytes02020100Result.IsSuccess ? bytes02020100Result.Content.ToHexString() : bytes02020100Result.Message));
//Console.WriteLine("bytes02020100Result" + (bytes02020100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToDouble(bytes02020100Result.Content, 0) : bytes02020100Result.Message));
//var bytes02020100Result = await plc.ReadAsync("04000103", 1);
////返回带有是否成功等参数实际数据在data.Content中
//Console.WriteLine("bytes02020100Result" + (bytes02020100Result.IsSuccess ? bytes02020100Result.Content.ToHexString() : bytes02020100Result.Message));
//Console.WriteLine("bytes02020100Result" + (bytes02020100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToString(bytes02020100Result.Content) : bytes02020100Result.Message));
var test1 = await plc.ReadDeviceStationAsync();
Console.WriteLine("bytes02020100Result" + (test1.IsSuccess ? test1.Content : test1.Message));
var test2 = await plc.WriteDeviceStationAsync("311111111114");
Console.WriteLine("bytes02020100Result" + (test2.IsSuccess ? test2.Message : test2.Message));
plc.BroadcastTime(DateTime.Now);
plc.Station = "311111111114";
var test3 = await plc.WriteBaudRateAsync(19200);
Console.WriteLine("bytes02020100Result" + (test3.IsSuccess ? test3.Message : test3.Message));
var test4 = await plc.FreezeAsync(DateTime.Now);
Console.WriteLine("bytes02020100Result" + (test4.IsSuccess ? test4.Message : test4.Message));
var test5 = await plc.WritePasswordAsync(1, "66666666", "11111111");
Console.WriteLine("bytes02020100Result" + (test5.IsSuccess ? test5.Message : test5.Message));
plc.Password = "11111111";
var bytes02020100Result1 = await plc.ReadAsync("04000403", 1);
//返回带有是否成功等参数实际数据在data.Content中
Console.WriteLine("bytes02020100Result" + (bytes02020100Result1.IsSuccess ? bytes02020100Result1.Content.ToHexString() : bytes02020100Result1.Message));
Console.WriteLine("bytes02020100Result" + (bytes02020100Result1.IsSuccess ? plc.ThingsGatewayBitConverter.ToString(bytes02020100Result1.Content) : bytes02020100Result1.Message));
var test = await plc.WriteAsync("04000403", "33");
//返回带有是否成功等参数实际数据在data.Content中
Console.WriteLine("test" + test.Message);
var bytes02020100Result = await plc.ReadAsync("04000403", 1);
//返回带有是否成功等参数实际数据在data.Content中
Console.WriteLine("bytes02020100Result" + (bytes02020100Result.IsSuccess ? bytes02020100Result.Content.ToHexString() : bytes02020100Result.Message));
Console.WriteLine("bytes02020100Result" + (bytes02020100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToString(bytes02020100Result.Content) : bytes02020100Result.Message));
}
}
}

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Foundataion\ThingsGateway.Foundation.Adapter.Modbus\ThingsGateway.Foundation.Adapter.Modbus.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>OPCUAClientDemo</name>
<name>ModbusTest</name>
</assembly>
<members>
</members>

View File

@@ -12,7 +12,7 @@ namespace ModbusDemo
{
static async Task Main(string[] args)
{
//await ModbusClientAsync();
await ModbusClientAsync();
await ModbusServerAsync();
@@ -67,12 +67,12 @@ namespace ModbusDemo
var tcpClient2 = new TcpClientEx();//链路对象
var udpSession1 = new UdpSession();//链路对象
var udpSession2 = new UdpSession();//链路对象
var serialClient = new SerialClient();//链路对象
var serialSession = new SerialsSession();//链路对象
tcpClient1.Setup(config);
tcpClient2.Setup(config);
udpSession1.Setup(config);
udpSession2.Setup(config);
serialClient.Setup(config);
serialSession.Setup(config);
//创建协议对象,构造函数需要传入对应链路对象
@@ -108,7 +108,7 @@ namespace ModbusDemo
TimeOut = 3000,
IsCheckMessageId = true
};
ModbusRtu modbusRtu = new(serialClient)//传入链路
ModbusRtu modbusRtu = new(serialSession)//传入链路
{
//协议配置
DataFormat = DataFormat.ABCD,
@@ -134,7 +134,7 @@ namespace ModbusDemo
//测试读取写入
Console.WriteLine("modbusTcp" + modbusTcp.TcpClientEx.RemoteIPHost);
await TestAsync(modbusTcp);
Console.WriteLine("modbusRtu" + modbusRtu.SerialClient.SerialProperty.ToJson());
Console.WriteLine("modbusRtu" + modbusRtu.SerialsSession.SerialProperty.ToJsonString());
await TestAsync(modbusRtu);
Console.WriteLine("modbusRtuOvrTcp" + modbusRtuOvrTcp.TcpClientEx.RemoteIPHost);
await TestAsync(modbusRtuOvrTcp);

View File

@@ -7,6 +7,7 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Foundataion\ThingsGateway.Foundation.Adapter.OPCUA\ThingsGateway.Foundation.Adapter.OPCUA.csproj" />
</ItemGroup>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>OPCUAClientTest</name>
</assembly>
<members>
</members>
</doc>

View File

@@ -12,14 +12,17 @@ namespace ModbusDemo
{
OPCNode = new()
{
OPCUrl = "opc.tcp://desktop-p5gb4iq:50001/StandardServer",
OPCUrl = "opc.tcp://127.0.0.1:49320",
IsUseSecurity = true,
}
};
await oPCUAClient.ConnectAsync();
var testData1 = await oPCUAClient.ReadJTokenValueAsync(new[] { "ns=2;i=2897" });
await oPCUAClient.WriteNodeAsync("ns=2;i=2897", testData1.FirstOrDefault().Item3);
await oPCUAClient.WriteNodeAsync(new()
{
{"ns=2;i=2897", testData1.FirstOrDefault().Item3 }
});
}
}

View File

@@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Foundataion\ThingsGateway.Foundation.Adapter.Modbus\ThingsGateway.Foundation.Adapter.Modbus.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<Version>2.0.6.0</Version>
<Version>2.1.0.1</Version>
<Authors>Diego</Authors>
<Product>ThingsGateway</Product>
<Copyright>© 2023-present Diego</Copyright>

View File

@@ -0,0 +1,459 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using System.ComponentModel;
using ThingsGateway.Foundation.Extension.Byte;
using ThingsGateway.Foundation.Extension.Generic;
using ThingsGateway.Foundation.Serial;
namespace ThingsGateway.Foundation.Adapter.DLT645;
/// <summary>
/// DLT645_2007
/// </summary>
public class DLT645_2007 : ReadWriteDevicesSerialBase
{
/// <summary>
/// DLT645_2007
/// </summary>
/// <param name="serialSession"></param>
public DLT645_2007(SerialsSession serialSession) : base(serialSession)
{
ThingsGatewayBitConverter = new DLT645_2007BitConverter(EndianType.Big);
RegisterByteLength = 2;
}
/// <summary>
/// 组包缓存时间/ms
/// </summary>
[Description("组包缓存时间ms")]
public int CacheTimeout { get; set; } = 1000;
/// <summary>
/// 增加FE FE FE FE的报文头部
/// </summary>
[Description("前导符报文头")]
public bool EnableFEHead { get; set; }
/// <summary>
/// 帧前时间ms
/// </summary>
[Description("帧前时间ms")]
public int FrameTime { get; set; }
/// <summary>
/// 写入需操作员代码
/// </summary>
[Description("操作员代码")]
public string OperCode { get; set; }
/// <summary>
/// 写入密码
/// </summary>
[Description("写入密码")]
public string Password { get; set; }
/// <summary>
/// 通讯地址BCD码一般应该是12个字符
/// </summary>
[Description("通讯地址")]
public string Station { get; set; }
/// <inheritdoc/>
public override string GetAddressDescription() => base.GetAddressDescription() + Environment.NewLine;
/// <inheritdoc/>
public override async Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken token = default)
{
try
{
await ConnectAsync(token);
var commandResult = DLT645Helper.GetDLT645_2007Command(address, length, (byte)ControlCode.Read, Station);
if (commandResult.IsSuccess)
{
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
return (MessageBase)result.RequestInfo;
}
else
{
return OperResult.CreateFailedResult<byte[]>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<byte[]>(ex);
}
}
/// <inheritdoc/>
public override void SetDataAdapter()
{
var dataHandleAdapter = new DLT645_2007DataHandleAdapter
{
EnableFEHead = EnableFEHead
};
SerialsSession.SetDataHandlingAdapter(dataHandleAdapter);
}
/// <inheritdoc/>
public override async Task<OperResult> WriteAsync(string address, string value, CancellationToken token = default)
{
try
{
await ConnectAsync(token);
Password ??= string.Empty;
OperCode ??= string.Empty;
if (Password.Length < 8)
Password = Password.PadLeft(8, '0');
if (OperCode.Length < 8)
OperCode = OperCode.PadLeft(8, '0');
var data = DataTransUtil.SpliceArray(Password.ByHexStringToBytes(), OperCode.ByHexStringToBytes());
string[] strArray = value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
var commandResult = DLT645Helper.GetDLT645_2007Command(address, 1, (byte)ControlCode.Write, Station, data, strArray);
if (commandResult.IsSuccess)
{
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
return (MessageBase)result.RequestInfo;
}
else
{
return OperResult.CreateFailedResult<byte[]>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<byte[]>(ex);
}
}
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, uint value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, byte value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, double value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, float value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, long value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, ulong value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, ushort value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, short value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, int value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
#region
/// <summary>
/// 广播校时
/// </summary>
/// <param name="dateTime"></param>
/// <param name="token"></param>
/// <returns></returns>
public OperResult BroadcastTime(DateTime dateTime, CancellationToken token = default)
{
try
{
Connect(token);
string str = $"{dateTime.Second:D2}{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}{dateTime.Year % 100:D2}";
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.BroadcastTime, str.ByHexStringToBytes().Reverse().ToArray(), "999999999999".ByHexStringToBytes());
if (commandResult.IsSuccess)
{
SerialsSession.Send(commandResult.Content);
return OperResult.CreateSuccessResult();
}
else
{
return OperResult.CreateFailedResult<string>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<string>(ex);
}
}
/// <summary>
/// 冻结
/// </summary>
/// <param name="dateTime"></param>
/// <param name="token"></param>
/// <returns></returns>
public async Task<OperResult> FreezeAsync(DateTime dateTime, CancellationToken token = default)
{
try
{
await ConnectAsync(token);
string str = $"{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}";
if (Station.IsNullOrEmpty()) Station = string.Empty;
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.Freeze, str.ByHexStringToBytes().Reverse().ToArray(), Station.ByHexStringToBytes().Reverse().ToArray());
if (commandResult.IsSuccess)
{
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
var result1 = ((MessageBase)result.RequestInfo);
if (result1.IsSuccess)
{
return OperResult.CreateSuccessResult();
}
else
{
return OperResult.CreateFailedResult<string>(result1);
}
}
else
{
return OperResult.CreateFailedResult<string>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<string>(ex);
}
}
/// <summary>
/// 读取通信地址
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
public async Task<OperResult<string>> ReadDeviceStationAsync(CancellationToken token = default)
{
try
{
await ConnectAsync(token);
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.ReadStation, null, "AAAAAAAAAAAA".ByHexStringToBytes());
if (commandResult.IsSuccess)
{
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
var result1 = ((MessageBase)result.RequestInfo);
if (result1.IsSuccess)
{
var buffer = result1.Content.SelectMiddle(0, 6).BytesAdd(-0x33);
return OperResult.CreateSuccessResult(buffer.Reverse().ToArray().ToHexString());
}
else
{
return OperResult.CreateFailedResult<string>(result1);
}
}
else
{
return OperResult.CreateFailedResult<string>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<string>(ex);
}
}
/// <summary>
/// 修改波特率
/// </summary>
/// <param name="baudRate"></param>
/// <param name="token"></param>
/// <returns></returns>
public async Task<OperResult> WriteBaudRateAsync(int baudRate, CancellationToken token = default)
{
try
{
await ConnectAsync(token);
byte baudRateByte;
switch (baudRate)
{
case 600: baudRateByte = 0x02; break;
case 1200: baudRateByte = 0x04; break;
case 2400: baudRateByte = 0x08; break;
case 4800: baudRateByte = 0x10; break;
case 9600: baudRateByte = 0x20; break;
case 19200: baudRateByte = 0x40; break;
default: return new OperResult<string>($"不支持此波特率:{baudRate}");
}
if (Station.IsNullOrEmpty()) Station = string.Empty;
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteBaudRate, new byte[] { baudRateByte }, Station.ByHexStringToBytes().Reverse().ToArray());
if (commandResult.IsSuccess)
{
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
var result1 = ((MessageBase)result.RequestInfo);
if (result1.IsSuccess)
{
return OperResult.CreateSuccessResult();
}
else
{
return OperResult.CreateFailedResult<string>(result1);
}
}
else
{
return OperResult.CreateFailedResult<string>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<string>(ex);
}
}
/// <summary>
/// 更新通信地址
/// </summary>
/// <param name="station"></param>
/// <param name="token"></param>
/// <returns></returns>
public async Task<OperResult> WriteDeviceStationAsync(string station, CancellationToken token = default)
{
try
{
await ConnectAsync(token);
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteStation, station.ByHexStringToBytes().Reverse().ToArray(), "AAAAAAAAAAAA".ByHexStringToBytes());
if (commandResult.IsSuccess)
{
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
var result1 = ((MessageBase)result.RequestInfo);
if (result1.IsSuccess)
{
return OperResult.CreateSuccessResult();
}
else
{
return OperResult.CreateFailedResult<string>(result1);
}
}
else
{
return OperResult.CreateFailedResult<string>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<string>(ex);
}
}
/// <summary>
/// 修改密码
/// </summary>
/// <param name="level"></param>
/// <param name="oldPassword"></param>
/// <param name="newPassword"></param>
/// <param name="token"></param>
/// <returns></returns>
public async Task<OperResult> WritePasswordAsync(byte level, string oldPassword, string newPassword, CancellationToken token = default)
{
try
{
await ConnectAsync(token);
if (Station.IsNullOrEmpty()) Station = string.Empty;
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
string str = $"04000C{level:D2}";
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WritePassword,
str.ByHexStringToBytes().Reverse().ToArray()
.SpliceArray(oldPassword.ByHexStringToBytes().Reverse().ToArray())
.SpliceArray(newPassword.ByHexStringToBytes().Reverse().ToArray())
, Station.ByHexStringToBytes().Reverse().ToArray());
if (commandResult.IsSuccess)
{
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
var result1 = ((MessageBase)result.RequestInfo);
if (result1.IsSuccess)
{
return OperResult.CreateSuccessResult();
}
else
{
return OperResult.CreateFailedResult<string>(result1);
}
}
else
{
return OperResult.CreateFailedResult<string>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<string>(ex);
}
}
#endregion
}
/// <summary>
/// 控制码
/// </summary>
public enum ControlCode : byte
{
/// <summary>
/// 读数据
/// </summary>
Read = 0x11,
/// <summary>
/// 读后续数据
/// </summary>
ReadSub = 0x12,
/// <summary>
/// 读站号
/// </summary>
ReadStation = 0x13,
/// <summary>
/// 写数据
/// </summary>
Write = 0x14,
/// <summary>
/// 写站号
/// </summary>
WriteStation = 0x15,
/// <summary>
/// 广播校时
/// </summary>
BroadcastTime = 0x08,
/// <summary>
/// 冻结
/// </summary>
Freeze = 0x16,
/// <summary>
/// 更新波特率
/// </summary>
WriteBaudRate = 0x17,
/// <summary>
/// 更新密码
/// </summary>
WritePassword = 0x18,
}

View File

@@ -0,0 +1,146 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using System.Text;
using ThingsGateway.Foundation.Extension.Byte;
namespace ThingsGateway.Foundation.Adapter.DLT645;
/// <summary>
/// DLT645_2007Address
/// </summary>
public class DLT645_2007Address : DeviceAddressBase
{
/// <summary>
/// <inheritdoc/>
/// </summary>
public DLT645_2007Address()
{
}
/// <inheritdoc/>
public DLT645_2007Address(string address, ushort len)
{
Parse(address, len);
}
/// <inheritdoc/>
public DLT645_2007Address(string address, byte[] station)
{
Station = station;
Parse(address, 0);
}
/// <summary>
/// 数据标识
/// </summary>
public byte[] DataId { get; set; } = new byte[0];
/// <summary>
/// 反转解析
/// </summary>
public bool Reverse { get; set; } = true;
/// <summary>
/// 站号信息
/// </summary>
public byte[] Station { get; set; } = new byte[0];
/// <inheritdoc/>
public override void Parse(string address, int length)
{
var result = ParseFrom(address, length);
if (result.IsSuccess)
{
Length = result.Content.Length;
AddressStart = result.Content.AddressStart;
DataId = result.Content.DataId;
Station = result.Content.Station;
}
else
{
throw new Exception(result.Message);
}
}
/// <summary>
/// 解析地址
/// </summary>
/// <param name="address"></param>
/// <param name="length"></param>
/// <returns></returns>
public static OperResult<DLT645_2007Address> ParseFrom(string address, int length)
{
try
{
DLT645_2007Address dLT645_2007Address = new();
byte[] array;
array = new byte[0];
dLT645_2007Address.Length = length;
if (address.IndexOf(';') < 0)
{
array = address.ByHexStringToBytes().Reverse().ToArray();
}
else
{
string[] strArray = address.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
for (int index = 0; index < strArray.Length; ++index)
{
if (strArray[index].ToUpper().StartsWith("S="))
{
var station = strArray[index].Substring(2);
if (station.IsNullOrEmpty()) return new OperResult<DLT645_2007Address>("通讯地址不能为空");
if (station.Length < 12)
station = station.PadLeft(12, '0');
dLT645_2007Address.Station = station.ByHexStringToBytes().Reverse().ToArray();
}
else if (!strArray[index].Contains("r="))
{
dLT645_2007Address.Reverse = strArray[index].Substring(2).GetBoolValue();
}
else if (!strArray[index].Contains("="))
{
array = strArray[index].ByHexStringToBytes().Reverse().ToArray();
}
}
}
dLT645_2007Address.DataId = array;
return OperResult.CreateSuccessResult(dLT645_2007Address);
}
catch (Exception ex)
{
return new OperResult<DLT645_2007Address>(ex);
}
}
/// <inheritdoc/>
public override string ToString()
{
StringBuilder stringGeter = new();
if (Station.Length > 0)
{
stringGeter.Append("s=" + Station.Reverse().ToArray().ToHexString() + ";");
}
if (DataId.Length > 0)
{
stringGeter.Append(DataId.Reverse().ToArray().ToHexString() + ";");
}
if (!Reverse)
{
stringGeter.Append("s=" + Reverse.ToString() + ";");
}
return stringGeter.ToString();
}
}

View File

@@ -0,0 +1,106 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using System.Text;
using ThingsGateway.Foundation.Extension.Byte;
using ThingsGateway.Foundation.Extension.Generic;
namespace ThingsGateway.Foundation.Adapter.DLT645;
/// <summary>
/// DLT645_2007
/// </summary>
public class DLT645_2007BitConverter : ThingsGatewayBitConverter
{
/// <summary>
/// DLT645_2007
/// </summary>
public DLT645_2007BitConverter(EndianType endianType) : base(endianType)
{
}
/// <summary>
/// DLT645协议转换double
/// </summary>
/// <param name="buffer">带数据项标识</param>
/// <param name="offset"></param>
/// <returns></returns>
public override double ToDouble(byte[] buffer, int offset)
{
return Convert.ToDouble(this.ToString(buffer, offset, buffer.Length));
}
/// <inheritdoc/>
public override string ToString(byte[] buffer)
{
return this.ToString(buffer, 0, buffer.Length);
}
/// <inheritdoc/>
public override string ToString(byte[] buffer, int offset, int length)
{
buffer = buffer.SelectMiddle(offset, length);
buffer = buffer.BytesAdd(-0x33);
var dataInfos = DLT645Helper.GetDataInfos(buffer);
StringBuilder stringBuilder = new();
foreach (var dataInfo in dataInfos)
{
//实际数据
var content = buffer.SelectMiddle(4, dataInfo.ByteLength).Reverse().ToArray();
if (dataInfo.IsSigned)//可能为负数
{
if (content[0] > 0x80)//最高位是表示正负
{
content[0] = (byte)(content[0] - 0x80);
if (dataInfo.Digtal == 0)//无小数点
{
stringBuilder.AppendLine($"-{content.ToHexString()}");
}
else
{
stringBuilder.AppendLine((-(Convert.ToDouble(content.ToHexString()) / Math.Pow(10.0, dataInfo.Digtal))).ToString());
}
}
else
{
ToString(stringBuilder, dataInfo, content);
}
}
else
{
ToString(stringBuilder, dataInfo, content);
}
}
return stringBuilder.ToString();
static void ToString(StringBuilder stringBuilder, DataInfo dataInfo, byte[] content)
{
if (dataInfo.Digtal < 0)
{
stringBuilder.AppendLine($"{Encoding.ASCII.GetString(content)}");
}
else if (dataInfo.Digtal == 0)//无小数点
{
stringBuilder.AppendLine($"{content.ToHexString()}");
}
else
{
stringBuilder.AppendLine(((Convert.ToDouble(content.ToHexString()) / Math.Pow(10.0, dataInfo.Digtal))).ToString());
}
}
}
}

View File

@@ -0,0 +1,192 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using System.ComponentModel;
using ThingsGateway.Foundation.Adapter.Modbus;
using ThingsGateway.Foundation.Extension.Generic;
namespace ThingsGateway.Foundation.Adapter.DLT645;
/// <summary>
/// DLT645_2007DataHandleAdapter
/// </summary>
public class DLT645_2007DataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<DLT645_2007Message>
{
/// <summary>
/// 增加FE FE FE FE的报文头部
/// </summary>
[Description("前导符报文头")]
public bool EnableFEHead { get; set; }
/// <inheritdoc/>
public override byte[] PackCommand(byte[] command)
{
//打包时加上4个FE字节
if (EnableFEHead)
{
return DataTransUtil.SpliceArray(new byte[4] { 0xFE, 0xFE, 0xFE, 0xFE }, command);
}
return command;
}
/// <inheritdoc/>
protected override DLT645_2007Message GetInstance()
{
return new DLT645_2007Message();
}
/// <inheritdoc/>
protected override FilterResult UnpackResponse(DLT645_2007Message request, byte[] send, byte[] body, byte[] response)
{
//因为设备可能带有FE前导符开头这里找到0x68的位置
int headCodeIndex = -1;
if (response != null)
{
for (int index = 0; index < response.Length; index++)
{
if (response[index] == 0x68)
{
headCodeIndex = index;
break;
}
}
}
int sendHeadCodeIndex = 0;
if (send != null)
{
for (int index = 0; index < send.Length; index++)
{
if (send[index] == 0x68)
{
sendHeadCodeIndex = index;
break;
}
}
}
//帧起始符 地址域 帧起始符 控制码 数据域长度共10个字节
if (headCodeIndex < 0 || headCodeIndex + 10 > response.Length)
return FilterResult.Cache;
var len = 10 + response[headCodeIndex + 9] + 2;
if (response.Length - headCodeIndex < len)
{
return FilterResult.Cache;
}
if (response.Length - headCodeIndex >= len && response[len + headCodeIndex - 1] == 0x16)
{
//检查校验码
int sumCheck = 0;
for (int i = headCodeIndex; i < len + headCodeIndex - 2; i++)
sumCheck += response[i];
if ((byte)sumCheck != response[len + headCodeIndex - 2])
{
//校验错误
request.Message = "和校验错误";
request.ResultCode = ResultCode.Fail;
return FilterResult.Success;
}
if (
(response[headCodeIndex + 1] != send[sendHeadCodeIndex + 1]) ||
(response[headCodeIndex + 2] != send[sendHeadCodeIndex + 2]) ||
(response[headCodeIndex + 3] != send[sendHeadCodeIndex + 3]) ||
(response[headCodeIndex + 4] != send[sendHeadCodeIndex + 4]) ||
(response[headCodeIndex + 5] != send[sendHeadCodeIndex + 5]) ||
(response[headCodeIndex + 6] != send[sendHeadCodeIndex + 6])
)//设备地址不符合时,返回错误
{
if (
(response[headCodeIndex + 1] == 0xAA) &&
(response[headCodeIndex + 2] == 0xAA) &&
(response[headCodeIndex + 3] == 0xAA) &&
(response[headCodeIndex + 4] == 0xAA) &&
(response[headCodeIndex + 5] == 0xAA) &&
(response[headCodeIndex + 6] == 0xAA)
)//读写通讯地址例外
{
}
else
{
request.Message = "返回地址不符合规则";
request.ResultCode = ResultCode.Fail;
return FilterResult.Success;
}
}
if ((response[headCodeIndex + 8] != send[sendHeadCodeIndex + 8] + 0x80))//控制码不符合时,返回错误
{
request.Message = "返回控制码:" + $"0x{response[headCodeIndex + 8]:X2},请求控制码:" + $"0x{send[sendHeadCodeIndex + 8]:X2},不符合规则";
request.ResultCode = ResultCode.Fail;
return FilterResult.Success;
}
if ((response[headCodeIndex + 8] & 0x40) == 0x40)//控制码bit6为1时返回错误
{
byte byte1 = (byte)(response[headCodeIndex + 10] - 0x33);
var error = DLT645Helper.Get2007ErrorMessage(byte1);
request.Message = "异常控制码:" + $"0x{response[headCodeIndex + 8]:X2},错误信息:{error}";
request.ResultCode = ResultCode.Fail;
return FilterResult.Success;
}
if (send[sendHeadCodeIndex + 8] == (byte)ControlCode.Read ||
send[sendHeadCodeIndex + 8] == (byte)ControlCode.Write
)
{
//数据标识不符合时,返回错误
if (
(response[headCodeIndex + 10] == send[sendHeadCodeIndex + 10]) &&
(response[headCodeIndex + 11] == send[sendHeadCodeIndex + 11]) &&
(response[headCodeIndex + 12] == send[sendHeadCodeIndex + 12]) &&
(response[headCodeIndex + 13] == send[sendHeadCodeIndex + 13])
)
{
}
else
{
request.Message = "返回数据标识不符合规则";
request.ResultCode = ResultCode.Fail;
return FilterResult.Success;
}
}
request.Content = response.RemoveBegin(headCodeIndex + 10).RemoveLast(response.Length + 2 - len - headCodeIndex);
request.ResultCode = ResultCode.Success;
return FilterResult.Success;
}
else
{
request.ResultCode = ResultCode.Error;
return FilterResult.Success;
}
}
}

View File

@@ -0,0 +1,34 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Adapter.Modbus;
/// <summary>
/// <inheritdoc/>
/// </summary>
public class DLT645_2007Message : MessageBase, IMessage
{
/// <inheritdoc/>
public override int HeadBytesLength => -1;
/// <inheritdoc/>
public override bool CheckHeadBytes(byte[] head)
{
return true;
}
/// <inheritdoc/>
protected override void SendBytesThen()
{
BodyLength = -1;
}
}

View File

@@ -0,0 +1,416 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using System.ComponentModel;
using ThingsGateway.Foundation.Extension.Byte;
using ThingsGateway.Foundation.Extension.Generic;
namespace ThingsGateway.Foundation.Adapter.DLT645;
/// <summary>
/// DLT645_2007
/// </summary>
public class DLT645_2007OverTcp : ReadWriteDevicesTcpClientBase
{
/// <summary>
/// DLT645_2007
/// </summary>
/// <param name="tcpClient"></param>
public DLT645_2007OverTcp(TcpClientEx tcpClient) : base(tcpClient)
{
ThingsGatewayBitConverter = new DLT645_2007BitConverter(EndianType.Big);
RegisterByteLength = 2;
}
/// <summary>
/// 组包缓存时间/ms
/// </summary>
[Description("组包缓存时间ms")]
public int CacheTimeout { get; set; } = 1000;
/// <summary>
/// 增加FE FE FE FE的报文头部
/// </summary>
[Description("前导符报文头")]
public bool EnableFEHead { get; set; }
/// <summary>
/// 帧前时间ms
/// </summary>
[Description("帧前时间ms")]
public int FrameTime { get; set; }
/// <summary>
/// 写入需操作员代码
/// </summary>
[Description("操作员代码")]
public string OperCode { get; set; }
/// <summary>
/// 写入密码
/// </summary>
[Description("写入密码")]
public string Password { get; set; }
/// <summary>
/// 通讯地址BCD码一般应该是12个字符
/// </summary>
[Description("通讯地址")]
public string Station { get; set; }
/// <inheritdoc/>
public override string GetAddressDescription() => base.GetAddressDescription() + Environment.NewLine;
/// <inheritdoc/>
public override async Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken token = default)
{
try
{
await ConnectAsync(token);
var commandResult = DLT645Helper.GetDLT645_2007Command(address, length, (byte)ControlCode.Read, Station);
if (commandResult.IsSuccess)
{
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
return (MessageBase)result.RequestInfo;
}
else
{
return OperResult.CreateFailedResult<byte[]>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<byte[]>(ex);
}
}
/// <inheritdoc/>
public override void SetDataAdapter()
{
var dataHandleAdapter = new DLT645_2007DataHandleAdapter
{
EnableFEHead = EnableFEHead
};
TcpClientEx.SetDataHandlingAdapter(dataHandleAdapter);
}
/// <inheritdoc/>
public override async Task<OperResult> WriteAsync(string address, string value, CancellationToken token = default)
{
try
{
await ConnectAsync(token);
Password ??= string.Empty;
OperCode ??= string.Empty;
if (Password.Length < 8)
Password = Password.PadLeft(8, '0');
if (OperCode.Length < 8)
OperCode = OperCode.PadLeft(8, '0');
var data = DataTransUtil.SpliceArray(Password.ByHexStringToBytes(), OperCode.ByHexStringToBytes());
string[] strArray = value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
var commandResult = DLT645Helper.GetDLT645_2007Command(address, 1, (byte)ControlCode.Write, Station, data, strArray);
if (commandResult.IsSuccess)
{
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
return (MessageBase)result.RequestInfo;
}
else
{
return OperResult.CreateFailedResult<byte[]>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<byte[]>(ex);
}
}
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, uint value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, byte value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, double value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, float value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, long value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, ulong value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, ushort value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, short value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, int value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
/// <inheritdoc/>
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
#region
/// <summary>
/// 广播校时
/// </summary>
/// <param name="dateTime"></param>
/// <param name="token"></param>
/// <returns></returns>
public OperResult BroadcastTime(DateTime dateTime, CancellationToken token = default)
{
try
{
Connect(token);
string str = $"{dateTime.Second:D2}{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}{dateTime.Year % 100:D2}";
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.BroadcastTime, str.ByHexStringToBytes().Reverse().ToArray(), "999999999999".ByHexStringToBytes());
if (commandResult.IsSuccess)
{
TcpClientEx.Send(commandResult.Content);
return OperResult.CreateSuccessResult();
}
else
{
return OperResult.CreateFailedResult<string>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<string>(ex);
}
}
/// <summary>
/// 冻结
/// </summary>
/// <param name="dateTime"></param>
/// <param name="token"></param>
/// <returns></returns>
public async Task<OperResult> FreezeAsync(DateTime dateTime, CancellationToken token = default)
{
try
{
await ConnectAsync(token);
string str = $"{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}";
if (Station.IsNullOrEmpty()) Station = string.Empty;
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.Freeze, str.ByHexStringToBytes().Reverse().ToArray(), Station.ByHexStringToBytes().Reverse().ToArray());
if (commandResult.IsSuccess)
{
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
var result1 = ((MessageBase)result.RequestInfo);
if (result1.IsSuccess)
{
return OperResult.CreateSuccessResult();
}
else
{
return OperResult.CreateFailedResult<string>(result1);
}
}
else
{
return OperResult.CreateFailedResult<string>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<string>(ex);
}
}
/// <summary>
/// 读取通信地址
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
public async Task<OperResult<string>> ReadDeviceStationAsync(CancellationToken token = default)
{
try
{
await ConnectAsync(token);
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.ReadStation, null, "AAAAAAAAAAAA".ByHexStringToBytes());
if (commandResult.IsSuccess)
{
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
var result1 = ((MessageBase)result.RequestInfo);
if (result1.IsSuccess)
{
var buffer = result1.Content.SelectMiddle(0, 6).BytesAdd(-0x33);
return OperResult.CreateSuccessResult(buffer.Reverse().ToArray().ToHexString());
}
else
{
return OperResult.CreateFailedResult<string>(result1);
}
}
else
{
return OperResult.CreateFailedResult<string>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<string>(ex);
}
}
/// <summary>
/// 修改波特率
/// </summary>
/// <param name="baudRate"></param>
/// <param name="token"></param>
/// <returns></returns>
public async Task<OperResult> WriteBaudRateAsync(int baudRate, CancellationToken token = default)
{
try
{
await ConnectAsync(token);
byte baudRateByte;
switch (baudRate)
{
case 600: baudRateByte = 0x02; break;
case 1200: baudRateByte = 0x04; break;
case 2400: baudRateByte = 0x08; break;
case 4800: baudRateByte = 0x10; break;
case 9600: baudRateByte = 0x20; break;
case 19200: baudRateByte = 0x40; break;
default: return new OperResult<string>($"不支持此波特率:{baudRate}");
}
if (Station.IsNullOrEmpty()) Station = string.Empty;
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteBaudRate, new byte[] { baudRateByte }, Station.ByHexStringToBytes().Reverse().ToArray());
if (commandResult.IsSuccess)
{
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
var result1 = ((MessageBase)result.RequestInfo);
if (result1.IsSuccess)
{
return OperResult.CreateSuccessResult();
}
else
{
return OperResult.CreateFailedResult<string>(result1);
}
}
else
{
return OperResult.CreateFailedResult<string>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<string>(ex);
}
}
/// <summary>
/// 更新通信地址
/// </summary>
/// <param name="station"></param>
/// <param name="token"></param>
/// <returns></returns>
public async Task<OperResult> WriteDeviceStationAsync(string station, CancellationToken token = default)
{
try
{
await ConnectAsync(token);
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteStation, station.ByHexStringToBytes().Reverse().ToArray(), "AAAAAAAAAAAA".ByHexStringToBytes());
if (commandResult.IsSuccess)
{
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
var result1 = ((MessageBase)result.RequestInfo);
if (result1.IsSuccess)
{
return OperResult.CreateSuccessResult();
}
else
{
return OperResult.CreateFailedResult<string>(result1);
}
}
else
{
return OperResult.CreateFailedResult<string>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<string>(ex);
}
}
/// <summary>
/// 修改密码
/// </summary>
/// <param name="level"></param>
/// <param name="oldPassword"></param>
/// <param name="newPassword"></param>
/// <param name="token"></param>
/// <returns></returns>
public async Task<OperResult> WritePasswordAsync(byte level, string oldPassword, string newPassword, CancellationToken token = default)
{
try
{
await ConnectAsync(token);
if (Station.IsNullOrEmpty()) Station = string.Empty;
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
string str = $"04000C{level:D2}";
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WritePassword,
str.ByHexStringToBytes().Reverse().ToArray()
.SpliceArray(oldPassword.ByHexStringToBytes().Reverse().ToArray())
.SpliceArray(newPassword.ByHexStringToBytes().Reverse().ToArray())
, Station.ByHexStringToBytes().Reverse().ToArray());
if (commandResult.IsSuccess)
{
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
var result1 = ((MessageBase)result.RequestInfo);
if (result1.IsSuccess)
{
return OperResult.CreateSuccessResult();
}
else
{
return OperResult.CreateFailedResult<string>(result1);
}
}
else
{
return OperResult.CreateFailedResult<string>(commandResult);
}
}
catch (Exception ex)
{
return new OperResult<string>(ex);
}
}
#endregion
}

Some files were not shown because too many files have changed in this diff Show More