Compare commits
145 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d324537b47 | ||
![]() |
d0c05685f7 | ||
![]() |
1063c930b5 | ||
![]() |
79cbd44366 | ||
![]() |
7fdac1c5cb | ||
![]() |
0c0cf72ebb | ||
![]() |
8e2fe175ed | ||
![]() |
d1cff037c9 | ||
![]() |
fc88a2fafa | ||
![]() |
45fcceb056 | ||
![]() |
7043477038 | ||
![]() |
7dd685cf54 | ||
![]() |
5f5e4969c0 | ||
![]() |
8a53fd19e9 | ||
![]() |
baf4714c36 | ||
![]() |
7ba9ac7a5b | ||
![]() |
85b8f26e8e | ||
![]() |
594a0f1410 | ||
![]() |
d317d757d7 | ||
![]() |
fdf0ba6318 | ||
![]() |
15bf7de5fa | ||
![]() |
d3402b058e | ||
![]() |
e7dfdd4031 | ||
![]() |
b2dd7b6364 | ||
![]() |
9bd6d9abbf | ||
![]() |
cd14428fea | ||
![]() |
19d9f03c2b | ||
![]() |
0d57e72bbf | ||
![]() |
329516a61b | ||
![]() |
d566869589 | ||
![]() |
9cb8d8e6c7 | ||
![]() |
9de3c57e5d | ||
![]() |
f32ff92b0b | ||
![]() |
88d71e271e | ||
![]() |
fd9c14612a | ||
![]() |
e26e5a160f | ||
![]() |
b836bfed22 | ||
![]() |
a4b598c6d0 | ||
![]() |
c9ab755839 | ||
![]() |
9920edba53 | ||
![]() |
12bd7280d1 | ||
![]() |
d30ea7f63b | ||
![]() |
ebd3390db6 | ||
![]() |
9a374a9ebc | ||
![]() |
b1bc22cb08 | ||
![]() |
4930d53890 | ||
![]() |
c31327b5bc | ||
![]() |
3f2aa1f1e1 | ||
![]() |
6e78c00a96 | ||
![]() |
c27dde085e | ||
![]() |
d26cc308c0 | ||
![]() |
fb1efdf290 | ||
![]() |
3c99f2a472 | ||
![]() |
affe9a44e0 | ||
![]() |
43730fa519 | ||
![]() |
d39aa22b09 | ||
![]() |
e232a6b6ea | ||
![]() |
71ebb36fe9 | ||
![]() |
78a0b86327 | ||
![]() |
2636c16a97 | ||
![]() |
fd77c0242d | ||
![]() |
e74819a900 | ||
![]() |
9b7f696c9b | ||
![]() |
0230d614e7 | ||
![]() |
252d99ad78 | ||
![]() |
1ffc200350 | ||
![]() |
807d89b2b2 | ||
![]() |
4013afa1f1 | ||
![]() |
a580927ceb | ||
![]() |
bf2cf52034 | ||
![]() |
81bb8b7c31 | ||
![]() |
a825007fb5 | ||
![]() |
988124d96a | ||
![]() |
f0de815296 | ||
![]() |
0e2d58c887 | ||
![]() |
b155382626 | ||
![]() |
f362d740af | ||
![]() |
4a85e31a4f | ||
![]() |
302c270ad5 | ||
![]() |
3c1517d0f3 | ||
![]() |
f9fb222044 | ||
![]() |
e8edc02ba3 | ||
![]() |
95a44e3053 | ||
![]() |
74a9fe9a87 | ||
![]() |
4d03f9ea1a | ||
![]() |
67c96ca991 | ||
![]() |
88fb793c68 | ||
![]() |
d6d02d8cc5 | ||
![]() |
c5a3f8e2e3 | ||
![]() |
27e8653a1a | ||
![]() |
863beda82c | ||
![]() |
bac84c3ecd | ||
![]() |
2fca2ad9f8 | ||
![]() |
dd75286fe0 | ||
![]() |
7f91792cf1 | ||
![]() |
0e0ccad311 | ||
![]() |
0691f72e67 | ||
![]() |
7e38a51720 | ||
![]() |
34ca8243a3 | ||
![]() |
112fea7632 | ||
![]() |
378763e4ee | ||
![]() |
517bd0394d | ||
![]() |
70adb97fb5 | ||
![]() |
623d44cabe | ||
![]() |
0d479ca00b | ||
![]() |
8bc49ef437 | ||
![]() |
f83fcec786 | ||
![]() |
93690ce40d | ||
![]() |
f82c5f2f27 | ||
![]() |
a83c1c3899 | ||
![]() |
91d6aed109 | ||
![]() |
db8f8fe51d | ||
![]() |
4596004b17 | ||
![]() |
d5540906cb | ||
![]() |
90796a979d | ||
![]() |
2190a87772 | ||
![]() |
c5953b83f8 | ||
![]() |
24bc60abf0 | ||
![]() |
31eee6b009 | ||
![]() |
c5da565a8f | ||
![]() |
947cd712e1 | ||
![]() |
edc208f96b | ||
![]() |
1fb0296ee7 | ||
![]() |
6488d3df87 | ||
![]() |
56189d78e0 | ||
![]() |
bff18127b8 | ||
![]() |
363206e0ba | ||
![]() |
fd3e378501 | ||
![]() |
4ba2fe4c9d | ||
![]() |
2c499626ad | ||
![]() |
2b581a03c3 | ||
![]() |
450c15210a | ||
![]() |
65fed8cc93 | ||
![]() |
4b64771ea2 | ||
![]() |
f39977a6ff | ||
![]() |
933b535caa | ||
![]() |
8abc5d2f20 | ||
![]() |
d8783cd994 | ||
![]() |
d5d087feb5 | ||
![]() |
6ba3399df7 | ||
![]() |
65124b3aa8 | ||
![]() |
98597f4726 | ||
![]() |
e7981f0d8e | ||
![]() |
cf654427c3 | ||
![]() |
ff2f628282 |
@@ -5,3 +5,99 @@ dotnet_diagnostic.CA1848.severity = none
|
||||
|
||||
# CA2254: 模板应为静态表达式
|
||||
dotnet_diagnostic.CA2254.severity = suggestion
|
||||
|
||||
[*.cs]
|
||||
#### 命名样式 ####
|
||||
|
||||
# 命名规则
|
||||
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
|
||||
|
||||
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
|
||||
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
|
||||
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
|
||||
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
|
||||
|
||||
# 符号规范
|
||||
|
||||
dotnet_naming_symbols.interface.applicable_kinds = interface
|
||||
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.interface.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
|
||||
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.types.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
|
||||
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.non_field_members.required_modifiers =
|
||||
|
||||
# 命名样式
|
||||
|
||||
dotnet_naming_style.begins_with_i.required_prefix = I
|
||||
dotnet_naming_style.begins_with_i.required_suffix =
|
||||
dotnet_naming_style.begins_with_i.word_separator =
|
||||
dotnet_naming_style.begins_with_i.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.pascal_case.required_prefix =
|
||||
dotnet_naming_style.pascal_case.required_suffix =
|
||||
dotnet_naming_style.pascal_case.word_separator =
|
||||
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.pascal_case.required_prefix =
|
||||
dotnet_naming_style.pascal_case.required_suffix =
|
||||
dotnet_naming_style.pascal_case.word_separator =
|
||||
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||
|
||||
[*.vb]
|
||||
#### 命名样式 ####
|
||||
|
||||
# 命名规则
|
||||
|
||||
dotnet_naming_rule.interface_should_be_以_i_开始.severity = suggestion
|
||||
dotnet_naming_rule.interface_should_be_以_i_开始.symbols = interface
|
||||
dotnet_naming_rule.interface_should_be_以_i_开始.style = 以_i_开始
|
||||
|
||||
dotnet_naming_rule.类型_should_be_帕斯卡拼写法.severity = suggestion
|
||||
dotnet_naming_rule.类型_should_be_帕斯卡拼写法.symbols = 类型
|
||||
dotnet_naming_rule.类型_should_be_帕斯卡拼写法.style = 帕斯卡拼写法
|
||||
|
||||
dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.severity = suggestion
|
||||
dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.symbols = 非字段成员
|
||||
dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.style = 帕斯卡拼写法
|
||||
|
||||
# 符号规范
|
||||
|
||||
dotnet_naming_symbols.interface.applicable_kinds = interface
|
||||
dotnet_naming_symbols.interface.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected
|
||||
dotnet_naming_symbols.interface.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.类型.applicable_kinds = class, struct, interface, enum
|
||||
dotnet_naming_symbols.类型.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected
|
||||
dotnet_naming_symbols.类型.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.非字段成员.applicable_kinds = property, event, method
|
||||
dotnet_naming_symbols.非字段成员.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected
|
||||
dotnet_naming_symbols.非字段成员.required_modifiers =
|
||||
|
||||
# 命名样式
|
||||
|
||||
dotnet_naming_style.以_i_开始.required_prefix = I
|
||||
dotnet_naming_style.以_i_开始.required_suffix =
|
||||
dotnet_naming_style.以_i_开始.word_separator =
|
||||
dotnet_naming_style.以_i_开始.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.帕斯卡拼写法.required_prefix =
|
||||
dotnet_naming_style.帕斯卡拼写法.required_suffix =
|
||||
dotnet_naming_style.帕斯卡拼写法.word_separator =
|
||||
dotnet_naming_style.帕斯卡拼写法.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.帕斯卡拼写法.required_prefix =
|
||||
dotnet_naming_style.帕斯卡拼写法.required_suffix =
|
||||
dotnet_naming_style.帕斯卡拼写法.word_separator =
|
||||
dotnet_naming_style.帕斯卡拼写法.capitalization = pascal_case
|
||||
|
@@ -1,8 +1,7 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>3.0.0.0</Version>
|
||||
<Version>3.0.0.28</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
<Copyright>© 2023-present Diego</Copyright>
|
||||
|
@@ -13,3 +13,4 @@
|
||||
global using System;
|
||||
|
||||
global using ThingsGateway.Components;
|
||||
|
||||
|
@@ -32,7 +32,6 @@ internal class Program
|
||||
AppDomain.CurrentDomain.UnhandledException += (sender, error) =>
|
||||
{
|
||||
};
|
||||
|
||||
app.Run();
|
||||
}
|
||||
}
|
@@ -2,6 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -28,5 +29,18 @@
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="wwwroot\favicon.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot\favicon.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot\index.html">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
</Project>
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
@@ -12,6 +12,8 @@
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
using ThingsGateway.Components;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
|
||||
/// <summary>
|
||||
@@ -69,7 +71,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
|
||||
_periodicTimer?.Dispose();
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void LogOut(ThingsGateway.Foundation.LogLevel logLevel, object source, string message, Exception exception)
|
||||
public void LogOut(ThingsGateway.Foundation.Core.LogLevel logLevel, object source, string message, Exception exception)
|
||||
{
|
||||
Messages.Add(((LogLevel)logLevel,
|
||||
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - {message} {exception}"));
|
||||
@@ -99,7 +101,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
|
||||
catch (Exception ex)
|
||||
{
|
||||
Messages.Add((LogLevel.Error,
|
||||
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 错误:{ex.Message}"));
|
||||
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 错误:{ex}"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -124,7 +126,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
|
||||
catch (Exception ex)
|
||||
{
|
||||
Messages.Add((LogLevel.Error,
|
||||
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 写入前失败:{ex.Message}"));
|
||||
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 写入前失败:{ex}"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
@using BlazorComponent;
|
||||
@using Microsoft.AspNetCore.Components.Web;
|
||||
@using Microsoft.JSInterop;
|
||||
@using ThingsGateway.Foundation;
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
@inherits DriverDebugUIBase
|
||||
|
@@ -49,7 +49,7 @@ public partial class DriverDebugUIPage : DriverDebugUIBase
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + ex.Message));
|
||||
Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + ex));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@
|
||||
@using Microsoft.AspNetCore.Components.Web;
|
||||
@using System.IO.Ports;
|
||||
@using System.Collections.Concurrent;
|
||||
@using ThingsGateway.Foundation;
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using Masa.Blazor
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
<div class="mb-4">通道配置</div>
|
||||
|
@@ -15,7 +15,7 @@
|
||||
@using Microsoft.AspNetCore.Components.Web;
|
||||
@using System.IO.Ports;
|
||||
@using System.Collections.Concurrent;
|
||||
@using ThingsGateway.Foundation;
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using Masa.Blazor
|
||||
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
@@ -26,10 +26,10 @@
|
||||
<MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@port />
|
||||
|
||||
<MButton Class="ma-1" OnClick=@Connect Color="primary">
|
||||
连接
|
||||
启动
|
||||
</MButton>
|
||||
<MButton Class="ma-1" OnClick=@DisConnect Color="red">
|
||||
断开
|
||||
停止
|
||||
</MButton>
|
||||
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
@using Microsoft.AspNetCore.Components.Web;
|
||||
@using System.IO.Ports;
|
||||
@using System.Collections.Concurrent;
|
||||
@using ThingsGateway.Foundation;
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using Masa.Blazor
|
||||
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
|
@@ -15,5 +15,7 @@ global using System.Threading;
|
||||
global using System.Threading.Tasks;
|
||||
|
||||
global using ThingsGateway.Components;
|
||||
global using ThingsGateway.Foundation.Core;
|
||||
global using ThingsGateway.Foundation.Serial;
|
||||
global using ThingsGateway.Foundation.Sockets;
|
||||
|
||||
|
@@ -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
|
||||
|
||||
@@ -26,7 +26,7 @@ public partial class MainLayout
|
||||
[
|
||||
{
|
||||
"Href": "/index",
|
||||
"Title": "<EFBFBD><EFBFBD>ҳ"
|
||||
"Title": "首页"
|
||||
},
|
||||
{
|
||||
"Title": "Modbus",
|
||||
@@ -124,6 +124,15 @@ public partial class MainLayout
|
||||
"Title": "OPCUAClient"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Mqtt",
|
||||
"Children": [
|
||||
{
|
||||
"Href": "/MqttClient",
|
||||
"Title": "MqttClient"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -135,6 +144,15 @@ public partial class MainLayout
|
||||
var dataStringPro =
|
||||
"""
|
||||
[
|
||||
{
|
||||
"Title": "Melsec",
|
||||
"Children": [
|
||||
{
|
||||
"Href": "/QnA3E_Binary",
|
||||
"Title": "QnA3E_Binary"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "ABCIP",
|
||||
"Children": [
|
||||
@@ -189,19 +207,40 @@ public partial class MainLayout
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "GasCustom",
|
||||
"Title": "HZW_QTJC_01",
|
||||
"Children": [
|
||||
{
|
||||
"Href": "/GasCustomSerial",
|
||||
"Title": "GasCustomSerial"
|
||||
"Href": "/HZW_QTJC_01Serial",
|
||||
"Title": "HZW_QTJC_01Serial"
|
||||
},
|
||||
{
|
||||
"Href": "/GasCustomSerialOverTcp",
|
||||
"Title": "GasCustomSerialOverTcp"
|
||||
"Href": "/HZW_QTJC_01SerialOverTcp",
|
||||
"Title": "HZW_QTJC_01SerialOverTcp"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
"Title": "LQTCP",
|
||||
"Children": [
|
||||
{
|
||||
"Href": "/LQTCP",
|
||||
"Title": "LQTCP"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "KELID2008",
|
||||
"Children": [
|
||||
{
|
||||
"Href": "/KELID2008",
|
||||
"Title": "KELID2008"
|
||||
},
|
||||
{
|
||||
"Href": "/KELID2008OverTcp",
|
||||
"Title": "KELID2008OverTcp"
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
|
@@ -1,10 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro'">
|
||||
<DefineConstants>Pro</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro'">
|
||||
|
||||
<ItemGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro' AND '$(Configuration)' == 'Debug'">
|
||||
|
||||
<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.Melsec\Page\QnA3E_BinaryDebugPage.razor.cs" Link="Pages\Melsec\QnA3E_BinaryDebugPage.razor.cs" />
|
||||
<Content Include="..\..\PluginPro\ThingsGateway.Plugin.Melsec\Page\QnA3E_BinaryDebugPage.razor" Link="Pages\Melsec\QnA3E_BinaryDebugPage.razor" />
|
||||
<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.Melsec\ThingsGateway.Foundation.Adapter.Melsec.csproj" />
|
||||
|
||||
|
||||
<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.AllenBradleyCip\Page\AllenBradleyCipTcpDebugPage.razor.cs" Link="Pages\ABCIP\AllenBradleyCipTcpDebugPage.razor.cs" />
|
||||
<Content Include="..\..\PluginPro\ThingsGateway.Plugin.AllenBradleyCip\Page\AllenBradleyCipTcpDebugPage.razor" Link="Pages\ABCIP\AllenBradleyCipTcpDebugPage.razor" />
|
||||
<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.AllenBradleyCip\ThingsGateway.Foundation.Adapter.AllenBradleyCip.csproj" />
|
||||
@@ -31,25 +40,51 @@
|
||||
<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.Vigor\ThingsGateway.Foundation.Adapter.Vigor.csproj" />
|
||||
|
||||
|
||||
<Compile Include="..\..\PluginProGasCustom\ThingsGateway.Plugin.GasCustom\Page\GasCustomSerialDebugPage.razor.cs" Link="Pages\GasCustom\GasCustomSerialDebugPage.razor.cs" />
|
||||
<Compile Include="..\..\PluginProGasCustom\ThingsGateway.Plugin.GasCustom\Page\GasCustomSerialOverTcpDebugPage.razor.cs" Link="Pages\GasCustom\GasCustomSerialOverTcpDebugPage.razor.cs" />
|
||||
<Content Include="..\..\PluginProGasCustom\ThingsGateway.Plugin.GasCustom\Page\GasCustomSerialDebugPage.razor" Link="Pages\GasCustom\GasCustomSerialDebugPage.razor" />
|
||||
<Content Include="..\..\PluginProGasCustom\ThingsGateway.Plugin.GasCustom\Page\GasCustomSerialOverTcpDebugPage.razor" Link="GasCustom\Vigor\GasCustomSerialOverTcpDebugPage.razor" />
|
||||
<ProjectReference Include="..\..\PluginProGasCustom\ThingsGateway.Foundation.Adapter.GasCustom\ThingsGateway.Foundation.Adapter.GasCustom.csproj" />
|
||||
<Compile Include="..\..\PluginProAF2021\ThingsGateway.Plugin.HZW_QTJC_01\Page\HZW_QTJC_01SerialDebugPage.razor.cs" Link="Pages\HZW_QTJC_01\HZW_QTJC_01SerialDebugPage.razor.cs" />
|
||||
<Compile Include="..\..\PluginProAF2021\ThingsGateway.Plugin.HZW_QTJC_01\Page\HZW_QTJC_01SerialOverTcpDebugPage.razor.cs" Link="Pages\HZW_QTJC_01\HZW_QTJC_01SerialOverTcpDebugPage.razor.cs" />
|
||||
<Content Include="..\..\PluginProAF2021\ThingsGateway.Plugin.HZW_QTJC_01\Page\HZW_QTJC_01SerialDebugPage.razor" Link="Pages\HZW_QTJC_01\HZW_QTJC_01SerialDebugPage.razor" />
|
||||
<Content Include="..\..\PluginProAF2021\ThingsGateway.Plugin.HZW_QTJC_01\Page\HZW_QTJC_01SerialOverTcpDebugPage.razor" Link="Pages\HZW_QTJC_01\HZW_QTJC_01SerialOverTcpDebugPage.razor" />
|
||||
<ProjectReference Include="..\..\PluginProAF2021\ThingsGateway.Foundation.Adapter.HZW_QTJC_01\ThingsGateway.Foundation.Adapter.HZW_QTJC_01.csproj" />
|
||||
|
||||
|
||||
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro' ">
|
||||
<Compile Include="..\..\PluginProAF2021\ThingsGateway.Plugin.LQTCP\Page\LQTCPDebugPage.razor.cs" Link="Pages\LQTCP\LQTCPDebugPage.razor.cs" />
|
||||
<Content Include="..\..\PluginProAF2021\ThingsGateway.Plugin.LQTCP\Page\LQTCPDebugPage.razor" Link="Pages\LQTCP\LQTCPDebugPage.razor" />
|
||||
<ProjectReference Include="..\..\PluginProAF2021\ThingsGateway.Foundation.Adapter.LQTCP\ThingsGateway.Foundation.Adapter.LQTCP.csproj" />
|
||||
|
||||
|
||||
<Compile Include="..\..\PluginProAF2021\ThingsGateway.Plugin.KELID2008\Page\KELID2008DebugPage.razor.cs" Link="Pages\KELID2008\KELID2008DebugPage.razor.cs" />
|
||||
<Compile Include="..\..\PluginProAF2021\ThingsGateway.Plugin.KELID2008\Page\KELID2008OverTcpDebugPage.razor.cs" Link="Pages\KELID2008\KELID2008OverTcpDebugPage.razor.cs" />
|
||||
<Content Include="..\..\PluginProAF2021\ThingsGateway.Plugin.KELID2008\Page\KELID2008DebugPage.razor" Link="Pages\KELID2008\KELID2008DebugPage.razor" />
|
||||
<Content Include="..\..\PluginProAF2021\ThingsGateway.Plugin.KELID2008\Page\KELID2008OverTcpDebugPage.razor" Link="Pages\KELID2008\KELID2008OverTcpDebugPage.razor" />
|
||||
<ProjectReference Include="..\..\PluginProAF2021\ThingsGateway.Foundation.Adapter.KELID2008\ThingsGateway.Foundation.Adapter.KELID2008.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\MqttRpcNameVaueWithId.cs" Link="Pages\Mqtt\MqttRpcNameVaueWithId.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientDebugPage.razor.cs" Link="Pages\Mqtt\MqttClientDebugPage.razor.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientPage.razor.cs" Link="Pages\Mqtt\MqttClientPage.razor.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\RpcClass\MqttRpcClient.cs" Link="Pages\Mqtt\MqttRpcClient.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\RpcClass\MqttRpcClientExtensions.cs" Link="Pages\Mqtt\MqttRpcClientExtensions.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\RpcClass\MqttRpcTopicPair.cs" Link="Pages\Mqtt\MqttRpcTopicPair.cs" />
|
||||
<Compile Include="..\..\Web\ThingsGateway.Gateway.Application\Workers\ManageGateway\MqttLoggerExtensions.cs" Link="Pages\Mqtt\MqttLoggerExtensions.cs" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientDebugPage.razor" Link="Pages\Mqtt\MqttClientDebugPage.razor" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientPage.razor" Link="Pages\Mqtt\MqttClientPage.razor" />
|
||||
<PackageReference Include="MQTTnet" Version="4.3.1.873" />
|
||||
|
||||
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007DebugPage.razor.cs" Link="Pages\DLT645\DLT645_2007DebugPage.razor.cs" />
|
||||
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007DebugPage.razor" Link="Pages\DLT645\DLT645_2007DebugPage.razor" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007OverTcpDebugPage.razor.cs" Link="Pages\DLT645\DLT645_2007OverTcpDebugPage.razor.cs" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007OverTcpDebugPage.razor" Link="Pages\DLT645\DLT645_2007OverTcpDebugPage.razor" />
|
||||
|
||||
|
||||
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusRtuDebugPage.razor.cs" Link="Pages\Modbus\ModbusRtuDebugPage.razor.cs" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusRtuDebugPage.razor" Link="Pages\Modbus\ModbusRtuDebugPage.razor" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusRtuOverTcpDebugPage.razor.cs" Link="Pages\Modbus\ModbusRtuOverTcpDebugPage.razor.cs" />
|
||||
@@ -101,21 +136,24 @@
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<!--<PackageReference Include="ThingsGateway.Foundation.Adapter.DLT645" Version="*" />
|
||||
<PackageReference Include="ThingsGateway.Foundation.Adapter.Modbus" Version="*" />
|
||||
<PackageReference Include="ThingsGateway.Foundation.Adapter.OPCDA" Version="*" />
|
||||
<PackageReference Include="ThingsGateway.Foundation.Adapter.OPCUA" Version="*" />
|
||||
<PackageReference Include="ThingsGateway.Foundation.Adapter.Siemens" Version="*" />-->
|
||||
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.DLT645\ThingsGateway.Foundation.Adapter.DLT645.csproj" />
|
||||
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.Modbus\ThingsGateway.Foundation.Adapter.Modbus.csproj" />
|
||||
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.OPCDA\ThingsGateway.Foundation.Adapter.OPCDA.csproj" />
|
||||
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.OPCUA\ThingsGateway.Foundation.Adapter.OPCUA.csproj" />
|
||||
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.Siemens\ThingsGateway.Foundation.Adapter.Siemens.csproj" />
|
||||
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Web\ThingsGateway.Components\ThingsGateway.Components.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="wwwroot\**">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
|
||||
</Project>
|
||||
|
@@ -19,7 +19,7 @@
|
||||
@using BlazorComponent
|
||||
@using Masa.Blazor
|
||||
@using Masa.Blazor.Presets
|
||||
@using ThingsGateway.Foundation;
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using ThingsGateway.Components;
|
||||
@using ThingsGateway.Core;
|
||||
@using System.Net.Http.Json
|
||||
|
@@ -0,0 +1,16 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
global using System;
|
||||
|
||||
global using System.Windows.Forms;
|
||||
|
78
framework/Demo/ThingsGateway.Foundation.Demo.Winform/MainFrom.Designer.cs
generated
Normal file
@@ -0,0 +1,78 @@
|
||||
#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.Drawing;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo.Winform
|
||||
{
|
||||
partial class MainFrom
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainFrom));
|
||||
blazorWebView1 = new Microsoft.AspNetCore.Components.WebView.WindowsForms.BlazorWebView();
|
||||
SuspendLayout();
|
||||
//
|
||||
// blazorWebView1
|
||||
//
|
||||
blazorWebView1.Dock = DockStyle.Fill;
|
||||
blazorWebView1.Location = new Point(0, 0);
|
||||
blazorWebView1.Margin = new Padding(4);
|
||||
blazorWebView1.Name = "blazorWebView1";
|
||||
blazorWebView1.Size = new Size(1029, 529);
|
||||
blazorWebView1.TabIndex = 0;
|
||||
blazorWebView1.Text = "blazorWebView1";
|
||||
//
|
||||
// MainFrom
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(9F, 20F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(1029, 529);
|
||||
Controls.Add(blazorWebView1);
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
Margin = new Padding(4);
|
||||
Name = "MainFrom";
|
||||
Text = "Form1";
|
||||
FormClosed += MainFrom_FormClosed;
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Microsoft.AspNetCore.Components.WebView.WindowsForms.BlazorWebView blazorWebView1;
|
||||
}
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <20>˴<EFBFBD><CBB4><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><C8A8><EFBFBD><EFBFBD>Ϊȫ<CEAA>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ǣ<EFBFBD><C7A3><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <20>˴<EFBFBD><CBB4><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><C8A8><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4>룩<EFBFBD><EBA3A9><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><DFB1><EFBFBD>Diego<67><6F><EFBFBD><EFBFBD>
|
||||
// Դ<><D4B4><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>Э<EFBFBD><D0AD><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD>ֿ<EFBFBD><D6BF>Ŀ<EFBFBD>ԴЭ<D4B4>鼰<EFBFBD><E9BCB0><EFBFBD><EFBFBD>Э<EFBFBD><D0AD>
|
||||
// GiteeԴ<65><D4B4><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<62><D4B4><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<><CAB9><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<51><C8BA>605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Microsoft.AspNetCore.Components.WebView.WindowsForms;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using ThingsGateway.Components;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo.Winform
|
||||
{
|
||||
public partial class MainFrom : Form
|
||||
{
|
||||
public MainFrom()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var services = new ServiceCollection();
|
||||
services.AddWindowsFormsBlazorWebView();
|
||||
services.ThingsGatewayComponentsConfigureServices();
|
||||
|
||||
blazorWebView1.HostPage = "wwwroot/index.html";
|
||||
blazorWebView1.Services = services.BuildServiceProvider();
|
||||
this.Text = "ThingsGateway.Foundation.Demo";
|
||||
blazorWebView1.RootComponents.Add<ThingsGateway.Foundation.Demo.App>("#app");
|
||||
}
|
||||
|
||||
private void MainFrom_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
Application.Exit();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,197 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAwo82AMKPNgvCjzYkwo82JsKPNifCjzYqwo82IcKPNgLCjzYAAAAAAAAA
|
||||
AAAAAAAAAAAAAMKPNgDCjzYBwo82HsKPNknCjzZewo82QcKPNhLCjzYAwo82AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCjzYAwo82S8KPNtPCjzbiwo8258KPNuDCjzatwo82EsKP
|
||||
NgAAAAAAAAAAAAAAAADCjzYAwo82BsKPNmvCjzbbwo826MKPNtvCjzbhwo82vcKPNmDCjzYywo82AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMKPNgDCjzYPwo82O8KPNs7Cjzb/wo82iMKP
|
||||
Nh7CjzYCwo82AAAAAAAAAAAAwo82AMKPNgDCjzZnwo8298KPNsLCjzY6wo82GsKPNjTCjzbJwo82/8KP
|
||||
NpTCjzYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMKPNgDCjzYIwo82vsKP
|
||||
Nv/CjzZowo82AAAAAAAAAAAAAAAAAAAAAADCjzYAwo82JMKPNtnCjzbxwo82QcKPNgDCjzYAwo82AMKP
|
||||
NpHCjzb/wo82lsKPNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwo82AMKP
|
||||
NgjCjza9wo82/8KPNmjCjzYAAAAAAAAAAAAAAAAAwo82AMKPNgDCjzZ2wo82/8KPNrnCjzYKwo82AAAA
|
||||
AADCjzYAwo82jcKPNv/CjzaWwo82AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AADCjzYAwo82CMKPNr3Cjzb/wo82aMKPNgAAAAAAAAAAAAAAAADCjzYAwo82CcKPNrrCjzb/wo82fcKP
|
||||
NgDCjzYAAAAAAMKPNgDCjzaLwo82/8KPNpbCjzYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAMKPNgDCjzYIwo82vMKPNv/CjzZpwo82AAAAAAAAAAAAAAAAAMKPNgDCjzYfwo8238KP
|
||||
Nv3CjzZRwo82AMKPNgDCjzYBwo82B8KPNpnCjzb/wo82psKPNgrCjzYAwo82AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAwo82AMKPNgjCjza8wo82/8KPNmnCjzYAAAAAAAAAAAAAAAAAwo82AMKP
|
||||
NjbCjzbxwo829sKPNj7CjzYAwo82AMKPNiPCjzaywo827cKPNv/Cjzbywo82qMKPNhPCjzYAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCjzYAwo82CMKPNrvCjzb/wo82acKPNgAAAAAAAAAAAAAA
|
||||
AADCjzYAwo82P8KPNvfCjzbzwo82OcKPNgDCjzYAwo82D8KPNlnCjzZiwo82X8KPNmDCjzZRwo82CcKP
|
||||
NgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMKPNgDCjzYHwo82usKPNv/CjzZpwo82AAAA
|
||||
AAAAAAAAAAAAAMKPNgDCjzY+wo829sKPNvTCjzY8wo82AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwo82AMKPNgfCjza6wo82/8KP
|
||||
NmnCjzYAAAAAAAAAAAAAAAAAwo82AMKPNirCjzbpwo82+MKPNkDCjzYAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCjzYAwo82B8KP
|
||||
NrnCjzb/wo82acKPNgAAAAAAAAAAAAAAAADCjzYAwo82FcKPNtLCjzb/wo82VsKPNgAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwo82AMKPNgLCjzYTwo82BMKP
|
||||
NgDCjzYHwo82t8KPNv/CjzZpwo82AMKPNgDCjzYMwo82E8KPNgDCjzYCwo82n8KPNv/CjzaEwo82AMKP
|
||||
NgAAAAAAwo82AMKPNgDCjzZPwo82XcKPNgLCjzYAAAAAAAAAAAAAAAAAAAAAAAAAAADCjzYAwo82F8KP
|
||||
NrTCjzY6wo82AMKPNgbCjza0wo82/8KPNmnCjzYAwo82AMKPNnPCjzaawo82A8KPNgDCjzZOwo82+MKP
|
||||
NsbCjzYRwo82AAAAAADCjzYAwo82DcKPNsLCjzagwo82AMKPNgAAAAAAAAAAAAAAAAAAAAAAAAAAAMKP
|
||||
NgDCjzYPwo82ysKPNpPCjzYBwo82BcKPNrHCjzb/wo82acKPNgDCjzYUwo82zMKPNpPCjzYAwo82AMKP
|
||||
NgrCjzanwo82/MKPNmnCjzYAwo82AMKPNgDCjzZRwo8298KPNnbCjzYAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAwo82AMKPNgDCjzaawo827cKPNmHCjzYswo82vMKPNv/CjzaEwo82K8KPNoDCjzb5wo82ZMKP
|
||||
NgAAAAAAwo82AMKPNi7CjzbWwo825sKPNlnCjzYdwo82SMKPNtTCjzb9wo82UsKPNgAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAwo82AMKPNmHCjzb3wo828cKPNt/Cjzbuwo8298KPNurCjzbjwo829MKP
|
||||
NurCjzY6wo82AAAAAADCjzYAwo82AMKPNjfCjza8wo826cKPNtvCjzbewo82ycKPNs7CjzYvwo82AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCjzYAwo82EsKPNj3CjzZAwo82QcKPNkDCjzY/wo82QMKP
|
||||
NkDCjzY/wo82OMKPNgrCjzYAAAAAAAAAAADCjzYAwo82AMKPNg/CjzY5wo82SsKPNjDCjzYOwo82G8KP
|
||||
NgXCjzYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////////////////wH4H/8B8Af/AfAH/4f
|
||||
hx/+H4cf/h8PH/4fDAf+HwwH/h8MB/4fD//+Hw///h8P/+IZD4/iGIcP4BGHH+ABwB/wAeAf8AHwH///
|
||||
//////////////////////////////////8=
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
@@ -0,0 +1,19 @@
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo.Winform
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
// To customize application configuration such as set high DPI settings or default font,
|
||||
// see https://aka.ms/applicationconfiguration.
|
||||
ApplicationConfiguration.Initialize();
|
||||
Application.Run(new MainFrom());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
||||
<TargetFrameworks>net7.0-windows</TargetFrameworks>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="favicon.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="favicon.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.WindowsForms" Version="7.0.96" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ThingsGateway.Foundation.Demo.Rcl\ThingsGateway.Foundation.Demo.Rcl.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="wwwroot\favicon.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot\favicon.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot\index.html">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
</Project>
|
BIN
framework/Demo/ThingsGateway.Foundation.Demo.Winform/favicon.ico
Normal file
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 10 KiB |
@@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
||||
<title>ThingsGateway.Foundation.Demo</title>
|
||||
<base href="/" />
|
||||
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
|
||||
|
||||
<link href="_content/Masa.Blazor/css/masa-blazor.min.css" rel="stylesheet" />
|
||||
<link href="_content/ThingsGateway.Components/css/materialdesign/v7.1.96/css/materialdesignicons.min.css" rel="stylesheet">
|
||||
<link href="_content/ThingsGateway.Components/css/material/icons.css" rel="stylesheet">
|
||||
<link href="_content/ThingsGateway.Components/css/fontawesome/v6.4.0/css/all.min.css" rel="stylesheet">
|
||||
<link href="_content/ThingsGateway.Components/style/custom.css" rel="stylesheet">
|
||||
<link href="_content/ThingsGateway.Components/prism/prism-material-dark-for-masa.css" rel="stylesheet">
|
||||
<link href="_content/ThingsGateway.Components/prism/prism-line-highlight.min.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
<div id="blazor-error-ui">
|
||||
<span>
|
||||
<environment include="Staging,Production">
|
||||
An error has occurred. This application may no longer respond until reloaded.
|
||||
</environment>
|
||||
<environment include="Development">
|
||||
An unhandled exception has occurred. See browser dev tools for details.
|
||||
</environment>
|
||||
</span>
|
||||
<a href="" class="reload">Reload</a>
|
||||
<a class="dismiss">🗙</a>
|
||||
</div>
|
||||
|
||||
<script src="_framework/blazor.webview.js" autostart="true"></script>
|
||||
<script src="_content/ThingsGateway.Components/prism/prism.min.js"></script>
|
||||
<script src="_content/BlazorComponent/js/blazor-component.js"></script>
|
||||
</body>
|
||||
</html>
|
@@ -1,9 +1,12 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>3.0.0.0</Version>
|
||||
<Version>3.0.0.28</Version>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<TargetFrameworks>net45;netstandard2.0;net6.0;net7.0</TargetFrameworks>
|
||||
<Description>
|
||||
ThingsGateway.Foundation是工业设备通讯类库,归属于ThingsGateway边缘网关项目,说明文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
</Description>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
<Copyright>© 2023-present Diego</Copyright>
|
||||
@@ -16,7 +19,6 @@
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://diego2098.gitee.io/thingsgateway-docs/</PackageProjectUrl>
|
||||
<PackageTags>ThingsGateway;Diego;dotNET China;Blazor;设备采集;边缘网关</PackageTags>
|
||||
@@ -42,5 +44,10 @@
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<DebugSymbols>True</DebugSymbols>
|
||||
<DebugType>Embedded</DebugType>
|
||||
<EmbedAllSources>True</EmbedAllSources>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
@@ -10,7 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
@@ -36,12 +35,7 @@ public class DataInfo
|
||||
}
|
||||
internal static class DLT645Helper
|
||||
{
|
||||
internal static byte[] BytesAdd(this byte[] bytes, int value)
|
||||
{
|
||||
for (int index = 0; index < bytes.Length; ++index)
|
||||
bytes[index] = (byte)(bytes[index] + value);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
internal static string Get2007ErrorMessage(byte buffer)
|
||||
{
|
||||
|
@@ -10,7 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
@@ -445,7 +444,7 @@ public class DLT645_2007 : ReadWriteDevicesSerialSessionBase
|
||||
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
string str = $"04000C{(level + 1):D2}";
|
||||
string str = $"04000C{level + 1:D2}";
|
||||
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WritePassword,
|
||||
str.ByHexStringToBytes().Reverse().ToArray()
|
||||
|
@@ -92,15 +92,15 @@ public class DLT645_2007Address : DeviceAddressBase
|
||||
StringBuilder stringGeter = new();
|
||||
if (Station.Length > 0)
|
||||
{
|
||||
stringGeter.Append("s=" + Station.Reverse().ToArray().ToHexString() + ";");
|
||||
stringGeter.Append($"s={Station.Reverse().ToArray().ToHexString()};");
|
||||
}
|
||||
if (DataId.Length > 0)
|
||||
{
|
||||
stringGeter.Append(DataId.Reverse().ToArray().ToHexString() + ";");
|
||||
stringGeter.Append($"{DataId.Reverse().ToArray().ToHexString()};");
|
||||
}
|
||||
if (!Reverse)
|
||||
{
|
||||
stringGeter.Append("s=" + Reverse.ToString() + ";");
|
||||
stringGeter.Append($"s={Reverse.ToString()};");
|
||||
}
|
||||
return stringGeter.ToString();
|
||||
}
|
||||
|
@@ -134,7 +134,7 @@ public class DLT645_2007DataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter
|
||||
|
||||
if ((response[headCodeIndex + 8] != send[sendHeadCodeIndex + 8] + 0x80))//控制码不符合时,返回错误
|
||||
{
|
||||
request.Message = "返回控制码:" + $"0x{response[headCodeIndex + 8]:X2},请求控制码:" + $"0x{send[sendHeadCodeIndex + 8]:X2},不符合规则";
|
||||
request.Message = $"返回控制码:0x{response[headCodeIndex + 8]:X2},请求控制码:0x{send[sendHeadCodeIndex + 8]:X2},不符合规则";
|
||||
request.ErrorCode = 999;
|
||||
return FilterResult.Success;
|
||||
}
|
||||
@@ -146,7 +146,7 @@ public class DLT645_2007DataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter
|
||||
{
|
||||
byte byte1 = (byte)(response[headCodeIndex + 10] - 0x33);
|
||||
var error = DLT645Helper.Get2007ErrorMessage(byte1);
|
||||
request.Message = "异常控制码:" + $"0x{response[headCodeIndex + 8]:X2},错误信息:{error}";
|
||||
request.Message = $"异常控制码:0x{response[headCodeIndex + 8]:X2},错误信息:{error}";
|
||||
request.ErrorCode = 999;
|
||||
return FilterResult.Success;
|
||||
}
|
||||
|
@@ -20,15 +20,12 @@ public class DLT645_2007Message : MessageBase, IMessage
|
||||
public override int HeadBytesLength => -1;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CheckHeadBytes(byte[] head)
|
||||
public override bool CheckHeadBytes(byte[] heads)
|
||||
{
|
||||
BodyLength = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void SendBytesThen()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -10,7 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
@@ -10,8 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
|
||||
internal static class PackHelper
|
||||
|
@@ -11,9 +11,11 @@
|
||||
#endregion
|
||||
|
||||
global using System;
|
||||
global using System.Collections.Generic;
|
||||
global using System.Linq;
|
||||
global using System.Threading;
|
||||
global using System.Threading.Tasks;
|
||||
|
||||
global using ThingsGateway.Foundation.Core;
|
||||
global using ThingsGateway.Foundation.Serial;
|
||||
global using ThingsGateway.Foundation.Sockets;
|
||||
|
@@ -1,442 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>ThingsGateway.Foundation.Adapter.DLT645</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DataInfo">
|
||||
<summary>
|
||||
解析参数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DataInfo.ByteLength">
|
||||
<summary>
|
||||
解析长度
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DataInfo.Digtal">
|
||||
<summary>
|
||||
小数位
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DataInfo.IsSigned">
|
||||
<summary>
|
||||
有符号解析
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645Helper.GetDataInfos(System.Byte[])">
|
||||
<summary>
|
||||
获取返回的解析信息
|
||||
</summary>
|
||||
<param name="buffer"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645Helper.GetDLT645_2007Command(System.String,System.Int32,System.Byte,System.String,System.Byte[],System.String[])">
|
||||
<summary>
|
||||
获取DLT645报文
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007">
|
||||
<summary>
|
||||
DLT645_2007
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.#ctor(ThingsGateway.Foundation.Serial.SerialSession)">
|
||||
<summary>
|
||||
DLT645_2007
|
||||
</summary>
|
||||
<param name="serialSession"></param>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.EnableFEHead">
|
||||
<summary>
|
||||
增加FE FE FE FE的报文头部
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.OperCode">
|
||||
<summary>
|
||||
写入需操作员代码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.Password">
|
||||
<summary>
|
||||
写入密码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.Station">
|
||||
<summary>
|
||||
通讯地址BCD码,一般应该是12个字符
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.GetAddressDescription">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.SetDataAdapter">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.String,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.UInt32,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Byte,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Double,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Single,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Int64,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.UInt64,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.UInt16,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Int16,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Int32,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.BroadcastTime(System.DateTime,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
广播校时
|
||||
</summary>
|
||||
<param name="dateTime"></param>
|
||||
<param name="cancellationToken"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.FreezeAsync(System.DateTime,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
冻结
|
||||
</summary>
|
||||
<param name="dateTime"></param>
|
||||
<param name="cancellationToken"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.ReadDeviceStationAsync(System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
读取通信地址
|
||||
</summary>
|
||||
<param name="cancellationToken"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteBaudRateAsync(System.Int32,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
修改波特率
|
||||
</summary>
|
||||
<param name="baudRate"></param>
|
||||
<param name="cancellationToken"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteDeviceStationAsync(System.String,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
更新通信地址
|
||||
</summary>
|
||||
<param name="station"></param>
|
||||
<param name="cancellationToken"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WritePasswordAsync(System.Byte,System.String,System.String,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
修改密码
|
||||
</summary>
|
||||
<param name="level"></param>
|
||||
<param name="oldPassword"></param>
|
||||
<param name="newPassword"></param>
|
||||
<param name="cancellationToken"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.ControlCode">
|
||||
<summary>
|
||||
控制码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.Read">
|
||||
<summary>
|
||||
读数据
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.ReadSub">
|
||||
<summary>
|
||||
读后续数据
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.ReadStation">
|
||||
<summary>
|
||||
读站号
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.Write">
|
||||
<summary>
|
||||
写数据
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.WriteStation">
|
||||
<summary>
|
||||
写站号
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.BroadcastTime">
|
||||
<summary>
|
||||
广播校时
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.Freeze">
|
||||
<summary>
|
||||
冻结
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.WriteBaudRate">
|
||||
<summary>
|
||||
更新波特率
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.WritePassword">
|
||||
<summary>
|
||||
更新密码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address">
|
||||
<summary>
|
||||
DLT645_2007Address
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.#ctor">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.#ctor(System.String,System.UInt16)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.#ctor(System.String,System.Byte[])">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.DataId">
|
||||
<summary>
|
||||
数据标识
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.Reverse">
|
||||
<summary>
|
||||
反转解析
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.Station">
|
||||
<summary>
|
||||
站号信息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.Parse(System.String,System.Int32)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.ParseFrom(System.String,System.Int32)">
|
||||
<summary>
|
||||
解析地址
|
||||
</summary>
|
||||
<param name="address"></param>
|
||||
<param name="length"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.ToString">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter">
|
||||
<summary>
|
||||
DLT645_2007
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.#ctor(ThingsGateway.Foundation.EndianType)">
|
||||
<summary>
|
||||
DLT645_2007
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.ToDouble(System.Byte[],System.Int32)">
|
||||
<summary>
|
||||
DLT645协议转换double
|
||||
</summary>
|
||||
<param name="buffer">带数据项标识</param>
|
||||
<param name="offset"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.ToString(System.Byte[])">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.ToString(System.Byte[],System.Int32,System.Int32)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter">
|
||||
<summary>
|
||||
DLT645_2007DataHandleAdapter
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.EnableFEHead">
|
||||
<summary>
|
||||
增加FE FE FE FE的报文头部
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.PackCommand(System.Byte[])">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.GetInstance">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.UnpackResponse(ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message,System.Byte[],System.Byte[],System.Byte[])">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp">
|
||||
<summary>
|
||||
DLT645_2007
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.#ctor(ThingsGateway.Foundation.TcpClient)">
|
||||
<summary>
|
||||
DLT645_2007
|
||||
</summary>
|
||||
<param name="tcpClient"></param>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.EnableFEHead">
|
||||
<summary>
|
||||
增加FE FE FE FE的报文头部
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.OperCode">
|
||||
<summary>
|
||||
写入需操作员代码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.Password">
|
||||
<summary>
|
||||
写入密码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.Station">
|
||||
<summary>
|
||||
通讯地址BCD码,一般应该是12个字符
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.GetAddressDescription">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.SetDataAdapter">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.String,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.UInt32,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Byte,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Double,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Single,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Int64,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.UInt64,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.UInt16,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Int16,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Int32,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.BroadcastTime(System.DateTime,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
广播校时
|
||||
</summary>
|
||||
<param name="dateTime"></param>
|
||||
<param name="cancellationToken"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.FreezeAsync(System.DateTime,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
冻结
|
||||
</summary>
|
||||
<param name="dateTime"></param>
|
||||
<param name="cancellationToken"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.ReadDeviceStationAsync(System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
读取通信地址
|
||||
</summary>
|
||||
<param name="cancellationToken"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteBaudRateAsync(System.Int32,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
修改波特率
|
||||
</summary>
|
||||
<param name="baudRate"></param>
|
||||
<param name="cancellationToken"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteDeviceStationAsync(System.String,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
更新通信地址
|
||||
</summary>
|
||||
<param name="station"></param>
|
||||
<param name="cancellationToken"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WritePasswordAsync(System.Byte,System.String,System.String,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
修改密码
|
||||
</summary>
|
||||
<param name="level"></param>
|
||||
<param name="oldPassword"></param>
|
||||
<param name="newPassword"></param>
|
||||
<param name="cancellationToken"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message.HeadBytesLength">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message.CheckHeadBytes(System.Byte[])">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message.SendBytesThen">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
@@ -11,9 +11,11 @@
|
||||
#endregion
|
||||
|
||||
global using System;
|
||||
global using System.Collections.Generic;
|
||||
global using System.Linq;
|
||||
global using System.Threading;
|
||||
global using System.Threading.Tasks;
|
||||
|
||||
global using ThingsGateway.Foundation.Core;
|
||||
global using ThingsGateway.Foundation.Serial;
|
||||
global using ThingsGateway.Foundation.Sockets;
|
||||
|
@@ -147,15 +147,15 @@ public class ModbusAddress : DeviceAddressBase
|
||||
StringBuilder stringGeter = new();
|
||||
if (Station > 0)
|
||||
{
|
||||
stringGeter.Append("s=" + Station.ToString() + ";");
|
||||
stringGeter.Append($"s={Station.ToString()};");
|
||||
}
|
||||
if (WriteFunction > 0)
|
||||
{
|
||||
stringGeter.Append("w=" + WriteFunction.ToString() + ";");
|
||||
stringGeter.Append($"w={WriteFunction.ToString()};");
|
||||
}
|
||||
if (!string.IsNullOrEmpty(SocketId))
|
||||
{
|
||||
stringGeter.Append("id=" + SocketId + ";");
|
||||
stringGeter.Append($"id={SocketId};");
|
||||
}
|
||||
stringGeter.Append(GetFunctionString(ReadFunction) + (AddressStart + 1).ToString());
|
||||
return stringGeter.ToString();
|
||||
|
@@ -91,9 +91,17 @@ internal class ModbusHelper
|
||||
|
||||
if (response[1] >= 0x80)//错误码
|
||||
return new OperResult<byte[], FilterResult>(GetDescriptionByErrorCode(response[2])) { Content2 = FilterResult.Success };
|
||||
if ((response.Length < response[2] + 3))
|
||||
return new OperResult<byte[], FilterResult>("数据长度不足" + response.ToHexString()) { Content2 = FilterResult.Cache };
|
||||
if (response[1] <= 0x05)
|
||||
{
|
||||
if ((response.Length < response[2] + 3))
|
||||
return new OperResult<byte[], FilterResult>("数据长度不足" + response.ToHexString()) { Content2 = FilterResult.Cache };
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((response.Length < 6))
|
||||
return new OperResult<byte[], FilterResult>("数据长度不足" + response.ToHexString()) { Content2 = FilterResult.Cache };
|
||||
|
||||
}
|
||||
|
||||
if (send.Length == 0)
|
||||
{
|
||||
@@ -109,7 +117,7 @@ internal class ModbusHelper
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[], FilterResult>(ex.Message) { Content2 = FilterResult.Success };
|
||||
return new OperResult<byte[], FilterResult>(ex) { Content2 = FilterResult.Success };
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
@@ -126,15 +134,20 @@ internal class ModbusHelper
|
||||
|
||||
if (response[1] >= 0x80)//错误码
|
||||
return new OperResult<byte[], FilterResult>(GetDescriptionByErrorCode(response[2])) { Content2 = FilterResult.Success };
|
||||
if ((response.Length < response[2] + 5))
|
||||
return new OperResult<byte[], FilterResult>("数据长度不足" + response.ToHexString()) { Content2 = FilterResult.Cache };
|
||||
if (response[1] <= 0x05)
|
||||
{
|
||||
if ((response.Length < response[2] + 5))
|
||||
return new OperResult<byte[], FilterResult>("数据长度不足" + response.ToHexString()) { Content2 = FilterResult.Cache };
|
||||
|
||||
if (response[2] == 0)
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((response.Length < 8))
|
||||
return new OperResult<byte[], FilterResult>("数据长度不足" + response.ToHexString()) { Content2 = FilterResult.Cache };
|
||||
|
||||
}
|
||||
|
||||
|
||||
var data = response.SelectMiddle(0, response[2] != 0 ? response[2] + 5 : 8);
|
||||
if (crcCheck && !EasyCRC16.CheckCRC16(data))
|
||||
return new OperResult<byte[], FilterResult>("Crc校验失败" + DataTransUtil.ByteToHexString(data, ' ')) { Content2 = FilterResult.Success };
|
||||
@@ -152,7 +165,7 @@ internal class ModbusHelper
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex.Message);
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
@@ -172,7 +185,7 @@ internal class ModbusHelper
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex.Message);
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +207,7 @@ internal class ModbusHelper
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex.Message);
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
@@ -231,7 +244,7 @@ internal class ModbusHelper
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex.Message);
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,7 +296,7 @@ internal class ModbusHelper
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex.Message);
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10,7 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
|
@@ -10,6 +10,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
|
||||
/// <summary>
|
||||
@@ -41,20 +43,43 @@ public class ModbusRtuDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<M
|
||||
/// <inheritdoc/>
|
||||
protected override FilterResult UnpackResponse(ModbusRtuMessage request, byte[] send, byte[] body, byte[] response)
|
||||
{
|
||||
//理想状态检测
|
||||
var result = ModbusHelper.GetModbusRtuData(send, response, Crc16CheckEnable);
|
||||
if (result.IsSuccess)
|
||||
//链路干扰时需剔除前缀中的多于字节,初步按站号+功能码找寻初始字节
|
||||
if (send?.Length > 0)
|
||||
{
|
||||
request.ErrorCode = result.ErrorCode;
|
||||
request.Message = result.Message;
|
||||
request.Content = result.Content;
|
||||
int index = -1;
|
||||
for (int i = 0; i < response.Length - 1; i++)
|
||||
{
|
||||
if (response[i] == send[0] && (response[i + 1] == send[1] || response[i + 1] == (send[1] + 0x80)))
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index >= 0)
|
||||
{
|
||||
response = response.RemoveBegin(index);
|
||||
}
|
||||
|
||||
//理想状态检测
|
||||
var result = ModbusHelper.GetModbusRtuData(send, response, Crc16CheckEnable);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
request.ErrorCode = result.ErrorCode;
|
||||
request.Message = result.Message;
|
||||
request.Content = result.Content;
|
||||
}
|
||||
else
|
||||
{
|
||||
request.ErrorCode = result.ErrorCode;
|
||||
request.Message = result.Message;
|
||||
}
|
||||
return result.Content2;
|
||||
}
|
||||
else
|
||||
{
|
||||
request.ErrorCode = result.ErrorCode;
|
||||
request.Message = result.Message;
|
||||
return FilterResult.Success;
|
||||
}
|
||||
return result.Content2;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -20,15 +20,12 @@ public class ModbusRtuMessage : MessageBase, IMessage
|
||||
public override int HeadBytesLength => -1;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CheckHeadBytes(byte[] head)
|
||||
public override bool CheckHeadBytes(byte[] heads)
|
||||
{
|
||||
BodyLength = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void SendBytesThen()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -10,7 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
|
||||
|
@@ -10,7 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Bool;
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
@@ -25,7 +24,7 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
|
||||
/// <summary>
|
||||
/// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
|
||||
/// </summary>
|
||||
public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SerialSession, OperResult> WriteData;
|
||||
public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SerialSession, Task<OperResult>> WriteData;
|
||||
|
||||
/// <summary>
|
||||
/// 继电器
|
||||
@@ -102,62 +101,76 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack);
|
||||
|
||||
}
|
||||
|
||||
EasyLock easyLock = new();
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
easyLock.Wait();
|
||||
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
return new OperResult<byte[]>("地址错误");
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
Init(mAddress);
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
{
|
||||
return new OperResult<byte[]>("地址错误");
|
||||
}
|
||||
Init(mAddress);
|
||||
|
||||
}
|
||||
|
||||
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
|
||||
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
|
||||
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
|
||||
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
|
||||
int len = mAddress.ReadFunction == 2 || mAddress.ReadFunction == 1 ? length : length * RegisterByteLength;
|
||||
switch (mAddress.ReadFunction)
|
||||
{
|
||||
case 1:
|
||||
byte[] bytes0 = new byte[len];
|
||||
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer01ByteBlock.Read(bytes0);
|
||||
return OperResult.CreateSuccessResult(bytes0);
|
||||
case 2:
|
||||
byte[] bytes1 = new byte[len];
|
||||
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer02ByteBlock.Read(bytes1);
|
||||
return OperResult.CreateSuccessResult(bytes1);
|
||||
case 3:
|
||||
|
||||
byte[] bytes3 = new byte[len];
|
||||
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer03ByteBlock.Read(bytes3);
|
||||
return OperResult.CreateSuccessResult(bytes3);
|
||||
case 4:
|
||||
byte[] bytes4 = new byte[len];
|
||||
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer04ByteBlock.Read(bytes4);
|
||||
return OperResult.CreateSuccessResult(bytes4);
|
||||
}
|
||||
return new OperResult<byte[]>("功能码错误");
|
||||
}
|
||||
|
||||
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
|
||||
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
|
||||
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
|
||||
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
|
||||
int len = mAddress.ReadFunction == 2 || mAddress.ReadFunction == 1 ? length : length * RegisterByteLength;
|
||||
switch (mAddress.ReadFunction)
|
||||
finally
|
||||
{
|
||||
case 1:
|
||||
byte[] bytes0 = new byte[len];
|
||||
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer01ByteBlock.Read(bytes0);
|
||||
return OperResult.CreateSuccessResult(bytes0);
|
||||
case 2:
|
||||
byte[] bytes1 = new byte[len];
|
||||
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer02ByteBlock.Read(bytes1);
|
||||
return OperResult.CreateSuccessResult(bytes1);
|
||||
case 3:
|
||||
|
||||
byte[] bytes3 = new byte[len];
|
||||
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer03ByteBlock.Read(bytes3);
|
||||
return OperResult.CreateSuccessResult(bytes3);
|
||||
case 4:
|
||||
byte[] bytes4 = new byte[len];
|
||||
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer04ByteBlock.Read(bytes4);
|
||||
return OperResult.CreateSuccessResult(bytes4);
|
||||
easyLock.Release();
|
||||
}
|
||||
return new OperResult<byte[]>("功能码错误");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -174,87 +187,108 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
|
||||
SerialSession.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult(ex);
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
easyLock.Wait();
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
return new OperResult("地址错误");
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
Init(mAddress);
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult(ex);
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
{
|
||||
return new OperResult("地址错误");
|
||||
}
|
||||
Init(mAddress);
|
||||
}
|
||||
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
|
||||
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
|
||||
switch (mAddress.ReadFunction)
|
||||
{
|
||||
case 3:
|
||||
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer03ByteBlock.Write(value);
|
||||
return OperResult.CreateSuccessResult();
|
||||
case 4:
|
||||
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer04ByteBlock.Write(value);
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
return new OperResult("功能码错误");
|
||||
|
||||
}
|
||||
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
|
||||
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
|
||||
switch (mAddress.ReadFunction)
|
||||
finally
|
||||
{
|
||||
case 3:
|
||||
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer03ByteBlock.Write(value);
|
||||
return OperResult.CreateSuccessResult();
|
||||
case 4:
|
||||
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer04ByteBlock.Write(value);
|
||||
return OperResult.CreateSuccessResult();
|
||||
|
||||
easyLock.Release();
|
||||
}
|
||||
return new OperResult("功能码错误");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (new OperResult(ex));
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
easyLock.Wait();
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
return (new OperResult("地址错误"));
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
Init(mAddress);
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (new OperResult(ex));
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
{
|
||||
return (new OperResult("地址错误"));
|
||||
}
|
||||
Init(mAddress);
|
||||
|
||||
}
|
||||
|
||||
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
|
||||
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
|
||||
switch (mAddress.ReadFunction)
|
||||
{
|
||||
case 1:
|
||||
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer01ByteBlock.Write(value.BoolArrayToByte());
|
||||
return (OperResult.CreateSuccessResult());
|
||||
case 2:
|
||||
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer02ByteBlock.Write(value.BoolArrayToByte());
|
||||
return (OperResult.CreateSuccessResult());
|
||||
}
|
||||
return new OperResult("功能码错误");
|
||||
|
||||
}
|
||||
|
||||
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
|
||||
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
|
||||
switch (mAddress.ReadFunction)
|
||||
finally
|
||||
{
|
||||
case 1:
|
||||
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer01ByteBlock.Write(value.BoolArrayToByte());
|
||||
return (OperResult.CreateSuccessResult());
|
||||
case 2:
|
||||
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer02ByteBlock.Write(value.BoolArrayToByte());
|
||||
return (OperResult.CreateSuccessResult());
|
||||
|
||||
easyLock.Release();
|
||||
}
|
||||
return new OperResult("功能码错误");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -268,12 +302,13 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
|
||||
{
|
||||
return Task.FromResult(Write(address, value));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Received(ByteBlock byteBlock, IRequestInfo requestInfo)
|
||||
protected override async Task Received(SerialSession client, ReceivedDataEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
var requestInfo = e.RequestInfo;
|
||||
//接收外部报文
|
||||
if (requestInfo is ModbusSerialServerMessage modbusServerMessage)
|
||||
{
|
||||
@@ -313,7 +348,7 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
|
||||
if (WriteData != null)
|
||||
{
|
||||
// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
|
||||
if ((WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess)
|
||||
if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess)
|
||||
{
|
||||
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length));
|
||||
if (result.IsSuccess)
|
||||
@@ -350,7 +385,7 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
|
||||
if (WriteData != null)
|
||||
{
|
||||
|
||||
if ((WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess)
|
||||
if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess)
|
||||
{
|
||||
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData);
|
||||
if (result.IsSuccess)
|
||||
@@ -409,13 +444,9 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
|
||||
|
||||
private void Init(ModbusAddress mAddress)
|
||||
{
|
||||
if (ModbusServer01ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
|
||||
ModbusServer01ByteBlocks[mAddress.Station].SetLength(1024 * 128);
|
||||
if (ModbusServer02ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
|
||||
ModbusServer02ByteBlocks[mAddress.Station].SetLength(1024 * 128);
|
||||
if (ModbusServer03ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
|
||||
ModbusServer03ByteBlocks[mAddress.Station].SetLength(1024 * 128);
|
||||
if (ModbusServer04ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
|
||||
ModbusServer04ByteBlocks[mAddress.Station].SetLength(1024 * 128);
|
||||
ModbusServer01ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
|
||||
ModbusServer02ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
|
||||
ModbusServer03ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
|
||||
ModbusServer04ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
|
||||
}
|
||||
}
|
||||
|
@@ -57,7 +57,7 @@ public class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesTcpDataHandle
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex.Message);
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -30,14 +30,11 @@ public class ModbusSerialServerMessage : MessageBase, IMessage
|
||||
public override int HeadBytesLength => -1;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CheckHeadBytes(byte[] head)
|
||||
public override bool CheckHeadBytes(byte[] heads)
|
||||
{
|
||||
BodyLength = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void SendBytesThen()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
@@ -10,7 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
|
@@ -23,10 +23,10 @@ public class ModbusTcpMessage : MessageBase, IMessage
|
||||
/// </summary>
|
||||
public bool IsCheckMessageId { get; set; } = false;
|
||||
/// <inheritdoc/>
|
||||
public override bool CheckHeadBytes(byte[] head)
|
||||
public override bool CheckHeadBytes(byte[] heads)
|
||||
{
|
||||
if (head == null || head.Length <= 0) return false;
|
||||
HeadBytes = head;
|
||||
if (heads == null || heads.Length <= 0) return false;
|
||||
HeadBytes = heads;
|
||||
|
||||
int num = (HeadBytes[4] * 256) + HeadBytes[5];
|
||||
BodyLength = num;
|
||||
|
@@ -10,7 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
@@ -85,15 +84,6 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
protected override void Connecting(SocketClient client, ConnectingEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.IP + ":" + client.Port + "正在连接");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter(object socketClient = null)
|
||||
@@ -196,7 +186,7 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
var item = commandResult.Content;
|
||||
if (FrameTime != 0)
|
||||
Thread.Sleep(FrameTime);
|
||||
var WaitingClientEx = client.GetWaitingClientEx(new() { BreakTrigger = true });
|
||||
var WaitingClientEx = client.CreateWaitingClient(new() { });
|
||||
var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
@@ -223,7 +213,7 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
|
||||
var item = commandResult.Content;
|
||||
await Task.Delay(FrameTime, cancellationToken);
|
||||
var WaitingClientEx = client.GetWaitingClientEx(new() { BreakTrigger = true });
|
||||
var WaitingClientEx = client.CreateWaitingClient(new() { });
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Bool;
|
||||
@@ -26,7 +25,7 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
|
||||
/// <summary>
|
||||
/// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
|
||||
/// </summary>
|
||||
public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SocketClient, OperResult> WriteData;
|
||||
public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SocketClient, Task<OperResult>> WriteData;
|
||||
|
||||
/// <summary>
|
||||
/// 继电器
|
||||
@@ -105,62 +104,75 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack);
|
||||
|
||||
}
|
||||
|
||||
EasyLock easyLock = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
easyLock.Wait();
|
||||
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
return new OperResult<byte[]>("地址错误");
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
Init(mAddress);
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
{
|
||||
return new OperResult<byte[]>("地址错误");
|
||||
}
|
||||
Init(mAddress);
|
||||
|
||||
}
|
||||
|
||||
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
|
||||
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
|
||||
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
|
||||
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
|
||||
int len = mAddress.ReadFunction == 2 || mAddress.ReadFunction == 1 ? length : length * RegisterByteLength;
|
||||
switch (mAddress.ReadFunction)
|
||||
{
|
||||
case 1:
|
||||
byte[] bytes0 = new byte[len];
|
||||
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer01ByteBlock.Read(bytes0);
|
||||
return OperResult.CreateSuccessResult(bytes0);
|
||||
case 2:
|
||||
byte[] bytes1 = new byte[len];
|
||||
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer02ByteBlock.Read(bytes1);
|
||||
return OperResult.CreateSuccessResult(bytes1);
|
||||
case 3:
|
||||
|
||||
byte[] bytes3 = new byte[len];
|
||||
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer03ByteBlock.Read(bytes3);
|
||||
return OperResult.CreateSuccessResult(bytes3);
|
||||
case 4:
|
||||
byte[] bytes4 = new byte[len];
|
||||
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer04ByteBlock.Read(bytes4);
|
||||
return OperResult.CreateSuccessResult(bytes4);
|
||||
}
|
||||
return new OperResult<byte[]>("功能码错误");
|
||||
}
|
||||
|
||||
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
|
||||
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
|
||||
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
|
||||
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
|
||||
int len = mAddress.ReadFunction == 2 || mAddress.ReadFunction == 1 ? length : length * RegisterByteLength;
|
||||
switch (mAddress.ReadFunction)
|
||||
finally
|
||||
{
|
||||
case 1:
|
||||
byte[] bytes0 = new byte[len];
|
||||
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer01ByteBlock.Read(bytes0);
|
||||
return OperResult.CreateSuccessResult(bytes0);
|
||||
case 2:
|
||||
byte[] bytes1 = new byte[len];
|
||||
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer02ByteBlock.Read(bytes1);
|
||||
return OperResult.CreateSuccessResult(bytes1);
|
||||
case 3:
|
||||
|
||||
byte[] bytes3 = new byte[len];
|
||||
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer03ByteBlock.Read(bytes3);
|
||||
return OperResult.CreateSuccessResult(bytes3);
|
||||
case 4:
|
||||
byte[] bytes4 = new byte[len];
|
||||
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer04ByteBlock.Read(bytes4);
|
||||
return OperResult.CreateSuccessResult(bytes4);
|
||||
easyLock.Release();
|
||||
}
|
||||
return new OperResult<byte[]>("功能码错误");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -194,84 +206,104 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult(ex);
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
easyLock.Wait();
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
return new OperResult("地址错误");
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
Init(mAddress);
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult(ex);
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
{
|
||||
return new OperResult("地址错误");
|
||||
}
|
||||
Init(mAddress);
|
||||
}
|
||||
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
|
||||
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
|
||||
switch (mAddress.ReadFunction)
|
||||
{
|
||||
case 3:
|
||||
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer03ByteBlock.Write(value);
|
||||
return OperResult.CreateSuccessResult();
|
||||
case 4:
|
||||
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer04ByteBlock.Write(value);
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
return new OperResult("功能码错误");
|
||||
|
||||
}
|
||||
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
|
||||
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
|
||||
switch (mAddress.ReadFunction)
|
||||
finally
|
||||
{
|
||||
case 3:
|
||||
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer03ByteBlock.Write(value);
|
||||
return OperResult.CreateSuccessResult();
|
||||
case 4:
|
||||
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
|
||||
ModbusServer04ByteBlock.Write(value);
|
||||
return OperResult.CreateSuccessResult();
|
||||
|
||||
easyLock.Release();
|
||||
}
|
||||
return new OperResult("功能码错误");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (new OperResult(ex));
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
easyLock.Wait();
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
return (new OperResult("地址错误"));
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
Init(mAddress);
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (new OperResult(ex));
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
{
|
||||
return (new OperResult("地址错误"));
|
||||
}
|
||||
Init(mAddress);
|
||||
|
||||
}
|
||||
|
||||
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
|
||||
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
|
||||
switch (mAddress.ReadFunction)
|
||||
{
|
||||
case 1:
|
||||
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer01ByteBlock.Write(value.BoolArrayToByte());
|
||||
return (OperResult.CreateSuccessResult());
|
||||
case 2:
|
||||
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer02ByteBlock.Write(value.BoolArrayToByte());
|
||||
return (OperResult.CreateSuccessResult());
|
||||
}
|
||||
return new OperResult("功能码错误");
|
||||
|
||||
}
|
||||
|
||||
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
|
||||
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
|
||||
switch (mAddress.ReadFunction)
|
||||
finally
|
||||
{
|
||||
case 1:
|
||||
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer01ByteBlock.Write(value.BoolArrayToByte());
|
||||
return (OperResult.CreateSuccessResult());
|
||||
case 2:
|
||||
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
|
||||
ModbusServer02ByteBlock.Write(value.BoolArrayToByte());
|
||||
return (OperResult.CreateSuccessResult());
|
||||
|
||||
easyLock.Release();
|
||||
}
|
||||
return new OperResult("功能码错误");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -285,12 +317,13 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
|
||||
{
|
||||
return Task.FromResult(Write(address, value));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Received(SocketClient client, IRequestInfo requestInfo)
|
||||
protected override async Task Received(SocketClient client, ReceivedDataEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
var requestInfo = e.RequestInfo;
|
||||
//接收外部报文
|
||||
if (requestInfo is ModbusTcpServerMessage modbusServerMessage)
|
||||
{
|
||||
@@ -331,7 +364,7 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
|
||||
if (WriteData != null)
|
||||
{
|
||||
// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
|
||||
if ((WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess)
|
||||
if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess)
|
||||
{
|
||||
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length));
|
||||
if (result.IsSuccess)
|
||||
@@ -368,7 +401,7 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
|
||||
if (WriteData != null)
|
||||
{
|
||||
|
||||
if ((WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess)
|
||||
if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess)
|
||||
{
|
||||
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData);
|
||||
if (result.IsSuccess)
|
||||
@@ -429,13 +462,9 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
|
||||
|
||||
private void Init(ModbusAddress mAddress)
|
||||
{
|
||||
if (ModbusServer01ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
|
||||
ModbusServer01ByteBlocks[mAddress.Station].SetLength(1024 * 128);
|
||||
if (ModbusServer02ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
|
||||
ModbusServer02ByteBlocks[mAddress.Station].SetLength(1024 * 128);
|
||||
if (ModbusServer03ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
|
||||
ModbusServer03ByteBlocks[mAddress.Station].SetLength(1024 * 128);
|
||||
if (ModbusServer04ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
|
||||
ModbusServer04ByteBlocks[mAddress.Station].SetLength(1024 * 128);
|
||||
ModbusServer01ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
|
||||
ModbusServer02ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
|
||||
ModbusServer03ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
|
||||
ModbusServer04ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
|
||||
}
|
||||
}
|
||||
|
@@ -57,7 +57,7 @@ public class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesTcpDataHandleAda
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex.Message);
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -29,10 +29,10 @@ namespace ThingsGateway.Foundation.Adapter.Modbus
|
||||
/// <inheritdoc/>
|
||||
public override int HeadBytesLength => 6;
|
||||
/// <inheritdoc/>
|
||||
public override bool CheckHeadBytes(byte[] head)
|
||||
public override bool CheckHeadBytes(byte[] heads)
|
||||
{
|
||||
if (head == null || head.Length != 6) return false;
|
||||
HeadBytes = head;
|
||||
if (heads == null || heads.Length != 6) return false;
|
||||
HeadBytes = heads;
|
||||
|
||||
int num = (HeadBytes[4] * 256) + HeadBytes[5];
|
||||
BodyLength = num;
|
||||
|
@@ -10,7 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
|
@@ -10,8 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
using ThingsGateway.Foundation.Extension.String;
|
||||
|
||||
|
@@ -406,7 +406,7 @@
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.Received(ThingsGateway.Foundation.Sockets.SocketClient,ThingsGateway.Foundation.IRequestInfo)">
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.Received(ThingsGateway.Foundation.Sockets.SocketClient,ThingsGateway.Foundation.Core.IRequestInfo)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusServerDataHandleAdapter">
|
||||
@@ -598,7 +598,7 @@
|
||||
PackHelper
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.PackHelper.ModbusLoadSourceRead``2(ThingsGateway.Foundation.IReadWrite,System.Collections.Generic.List{``1},System.Int32)">
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.PackHelper.ModbusLoadSourceRead``2(ThingsGateway.Foundation.Core.IReadWrite,System.Collections.Generic.List{``1},System.Int32)">
|
||||
<summary>
|
||||
打包变量,添加到<see href="deviceVariableSourceReads"></see>
|
||||
</summary>
|
||||
|
@@ -176,7 +176,7 @@ internal class OpcServer : IDisposable
|
||||
{
|
||||
status = (OPCSERVERSTATUS)o;
|
||||
serverStatus = new();
|
||||
serverStatus.Version = status.wMajorVersion.ToString() + "." + status.wMinorVersion.ToString() + "." + status.wBuildNumber.ToString();
|
||||
serverStatus.Version = $"{status.wMajorVersion.ToString()}.{status.wMinorVersion.ToString()}.{status.wBuildNumber.ToString()}";
|
||||
serverStatus.ServerState = status.dwServerState;
|
||||
serverStatus.StartTime = Comn.Convert.FileTimeToDateTime(status.ftStartTime);
|
||||
serverStatus.CurrentTime = Comn.Convert.FileTimeToDateTime(status.ftCurrentTime);
|
||||
|
@@ -1,3 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
|
||||
</Project>
|
||||
|
@@ -1,579 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>ThingsGateway.Foundation.Adapter.OPCDA</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.CollectionExtensions.RemoveWhere``1(System.Collections.Generic.ICollection{``0},System.Func{``0,System.Boolean})">
|
||||
<summary>
|
||||
移除符合条件的元素
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="this"></param>
|
||||
<param name="where"></param>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.LOCALE_SYSTEM_DEFAULT">
|
||||
<summary>
|
||||
The WIN32 system default locale.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.LOCALE_USER_DEFAULT">
|
||||
<summary>
|
||||
The WIN32 user default locale.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.CreateInstance(System.Guid,System.String)">
|
||||
<summary>
|
||||
创建一个COM服务器的实例。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.GetSystemMessage(System.Int32)">
|
||||
<summary>
|
||||
指定错误消息文本检索系统。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.InitializeSecurity">
|
||||
<summary>
|
||||
初始化COM安全。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.ReadClasses(ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCEnumGUID)">
|
||||
<summary>
|
||||
从枚举器读取guid。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.ReadClasses(ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumGUID)">
|
||||
<summary>
|
||||
从枚举器读取guid。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.RealseComServer(System.Object)">
|
||||
<summary>
|
||||
释放 COM 对象
|
||||
</summary>
|
||||
<param name="m_server"></param>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.OPCDA.Comn.Convert.FILETIME_BaseTime">
|
||||
<summary>
|
||||
windows的filetime是从1601-1-1 00:00:00开始的,datetime是从1-1-1 00:00:00开始的
|
||||
datetime和filetime的滴答单位都是100ns(100纳秒,千万分之一秒),所以转换时只需要考虑开始时间即可
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.OnDataChangedHandler">
|
||||
<summary>
|
||||
值变化
|
||||
</summary>
|
||||
<param name="opcItems"></param>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.OnReadCompletedHandler">
|
||||
<summary>
|
||||
读取
|
||||
</summary>
|
||||
<param name="opcItems"></param>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.OnWriteCompletedHandler">
|
||||
<summary>
|
||||
写入
|
||||
</summary>
|
||||
<param name="opcItems"></param>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.ItemReadResult">
|
||||
<summary>
|
||||
返回结果
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ItemReadResult.Name">
|
||||
<summary>
|
||||
ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ItemReadResult.Quality">
|
||||
<summary>
|
||||
Quality
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ItemReadResult.TimeStamp">
|
||||
<summary>
|
||||
TimeStamp
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ItemReadResult.Value">
|
||||
<summary>
|
||||
Value
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcGroup.InitIoInterfaces(System.Object)">
|
||||
<summary>
|
||||
建立连接
|
||||
</summary>
|
||||
<param name="handle"></param>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcGroup.ReadAsync">
|
||||
<summary>
|
||||
组读取
|
||||
</summary>
|
||||
<exception cref="T:System.Runtime.InteropServices.ExternalException"></exception>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem">
|
||||
<summary>
|
||||
OpcItem
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.#ctor(System.String)">
|
||||
<summary>
|
||||
OpcItem
|
||||
</summary>
|
||||
<param name="itemId"></param>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.AccessPath">
|
||||
<summary>
|
||||
AccessPath
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.Blob">
|
||||
<summary>
|
||||
Blob
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.BlobSize">
|
||||
<summary>
|
||||
BlobSize
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.ClientHandle">
|
||||
<summary>
|
||||
ClientHandle
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.IsActive">
|
||||
<summary>
|
||||
active(1) or not(0)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.ItemID">
|
||||
<summary>
|
||||
数据项在opc server的完全名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.Quality">
|
||||
<summary>
|
||||
Quality
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.RunTimeDataType">
|
||||
<summary>
|
||||
RunTimeDataType
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.ServerHandle">
|
||||
<summary>
|
||||
ServerHandle
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.TimeStamp">
|
||||
<summary>
|
||||
TimeStamp
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.Value">
|
||||
<summary>
|
||||
Value
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcServer.AddGroup(System.String,System.Boolean,System.Int32,System.Single)">
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcServer.Browse(System.String)">
|
||||
<summary>
|
||||
获取节点
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcServer.GetServerStatus">
|
||||
<summary>
|
||||
服务器状态
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus">
|
||||
<summary>
|
||||
ServerStatus
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.CurrentTime">
|
||||
<summary>
|
||||
CurrentTime
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.LastUpdateTime">
|
||||
<summary>
|
||||
LastUpdateTime
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.ServerState">
|
||||
<summary>
|
||||
ServerState
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.StartTime">
|
||||
<summary>
|
||||
StartTime
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.VendorInfo">
|
||||
<summary>
|
||||
VendorInfo
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.Version">
|
||||
<summary>
|
||||
Version
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Discovery.OpcDiscovery">
|
||||
<summary>
|
||||
OpcDiscovery
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Discovery.OpcDiscovery.GetOpcServer(System.String,System.String)">
|
||||
<summary>
|
||||
GetOpcServer
|
||||
</summary>
|
||||
<param name="serverName"></param>
|
||||
<param name="host"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IConnectionPoint">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IConnectionPointContainer">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumConnectionPoints">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumConnections">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumGUID">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumString">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumUnknown">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCCommon">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCEnumGUID">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCServerList">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCServerList2">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCShutdown">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.CONNECTDATA">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCBROWSEDIRECTION">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCBROWSEFILTER">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCBROWSETYPE">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCDATASOURCE">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCENUMSCOPE">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCEUTYPE">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCNAMESPACETYPE">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCSERVERSTATE">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.CATID_OPCDAServer10">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.CATID_OPCDAServer20">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.CATID_OPCDAServer30">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.CATID_XMLDAServer10">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumOPCItemAttributes">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCAsyncIO">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCAsyncIO2">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCAsyncIO3">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCBrowse">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCBrowseServerAddressSpace">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCDataCallback">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCGroupStateMgt">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCGroupStateMgt2">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCItemDeadbandMgt">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCItemIO">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCItemMgt">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCItemProperties">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCItemSamplingMgt">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCPublicGroupStateMgt">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCServer">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCServerPublicGroups">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCSyncIO">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCSyncIO2">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCBROWSEELEMENT">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCGROUPHEADER">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCGROUPHEADERWRITE">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMATTRIBUTES">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMDEF">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMHEADER1">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMHEADER2">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMHEADERWRITE">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMPROPERTIES">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMPROPERTY">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMRESULT">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMSTATE">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMVQT">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCSERVERSTATUS">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.Constants">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.Qualities">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.Properties">
|
||||
<exclude />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.DataChangedEventHandler">
|
||||
<summary>
|
||||
订阅变化项
|
||||
</summary>
|
||||
<param name="values"></param>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient">
|
||||
<summary>
|
||||
OPCDAClient
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.ItemDicts">
|
||||
<summary>
|
||||
当前保存的需订阅列表
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.#ctor(ThingsGateway.Foundation.ILog)">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
<param name="logger"></param>
|
||||
</member>
|
||||
<member name="E:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.DataChangedHandler">
|
||||
<summary>
|
||||
数据变化事件
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.IsConnected">
|
||||
<summary>
|
||||
是否连接成功
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.OPCNode">
|
||||
<summary>
|
||||
当前配置
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.AddItems(System.Collections.Generic.Dictionary{System.String,System.Collections.Generic.List{ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem}})">
|
||||
<summary>
|
||||
添加节点,需要在连接成功后执行
|
||||
</summary>
|
||||
<param name="items">组名称/变量节点,注意每次添加的组名称不能相同</param>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.AddItemsWithSave(System.Collections.Generic.List{System.String})">
|
||||
<summary>
|
||||
设置节点并保存,每次重连会自动添加节点
|
||||
</summary>
|
||||
<param name="items"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.Connect">
|
||||
<summary>
|
||||
连接服务器
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.Disconnect">
|
||||
<summary>
|
||||
断开连接
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.GetBrowseElements(System.String)">
|
||||
<summary>
|
||||
浏览节点
|
||||
</summary>
|
||||
<param name="itemId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.GetServerStatus">
|
||||
<summary>
|
||||
获取服务状态
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.Init(ThingsGateway.Foundation.Adapter.OPCDA.OPCNode)">
|
||||
<summary>
|
||||
初始化设置
|
||||
</summary>
|
||||
<param name="node"></param>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.ReadItemsWithGroup(System.String)">
|
||||
<summary>
|
||||
按OPC组读取组内变量,结果会在订阅事件中返回
|
||||
</summary>
|
||||
<param name="groupName">组名称,值为null时读取全部组</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.RemoveItems(System.Collections.Generic.List{System.String})">
|
||||
<summary>
|
||||
移除节点
|
||||
</summary>
|
||||
<param name="items"></param>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.ToString">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.WriteItem(System.Collections.Generic.Dictionary{System.String,Newtonsoft.Json.Linq.JToken})">
|
||||
<summary>
|
||||
批量写入值
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.Dispose(System.Boolean)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode">
|
||||
<summary>
|
||||
OPCDA连接配置项
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.ActiveSubscribe">
|
||||
<summary>
|
||||
是否订阅
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.CheckRate">
|
||||
<summary>
|
||||
内部检测重连间隔/min
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.DeadBand">
|
||||
<summary>
|
||||
死区
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.GroupSize">
|
||||
<summary>
|
||||
分组大小
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.OPCIP">
|
||||
<summary>
|
||||
OPCIP
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.OPCName">
|
||||
<summary>
|
||||
OPCNAME
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.UpdateRate">
|
||||
<summary>
|
||||
订阅间隔
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.ToString">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
@@ -1,4 +1,4 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
@@ -70,6 +70,11 @@ public class OPCNode
|
||||
/// </summary>
|
||||
[Description("安全策略")]
|
||||
public bool IsUseSecurity { get; set; } = false;
|
||||
/// <summary>
|
||||
/// 加载服务端数据类型
|
||||
/// </summary>
|
||||
[Description("加载服务端数据类型")]
|
||||
public bool LoadType { get; set; } = true;
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
@@ -17,22 +17,23 @@ using Opc.Ua.Client;
|
||||
using Opc.Ua.Client.ComplexTypes;
|
||||
using Opc.Ua.Configuration;
|
||||
|
||||
|
||||
//修改自https://github.com/dathlin/OpcUaHelper 与OPC基金会net库
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.OPCUA;
|
||||
|
||||
/// <summary>
|
||||
/// 订阅委托
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public delegate void DataChangedEventHandler((VariableNode variableNode, DataValue dataValue, JToken jToken) value);
|
||||
|
||||
/// <summary>
|
||||
/// OPCUAClient
|
||||
/// </summary>
|
||||
public class OPCUAClient : IDisposable
|
||||
{
|
||||
|
||||
#region 属性,变量等
|
||||
|
||||
/// <summary>
|
||||
/// 当前配置
|
||||
/// </summary>
|
||||
@@ -46,32 +47,37 @@ public class OPCUAClient : IDisposable
|
||||
/// <summary>
|
||||
/// 当前保存的变量名称列表
|
||||
/// </summary>
|
||||
public List<string> Variables = new();
|
||||
|
||||
private readonly Action<byte, object, string, Exception> _logAction;
|
||||
public List<List<string>> Variables = new();
|
||||
|
||||
/// <summary>
|
||||
/// 当前的变量名称/OPC变量节点
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, VariableNode> _variableDicts = new();
|
||||
|
||||
private readonly object checkLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// 当前的订阅组,组名称/组
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, Subscription> dic_subscriptions = new();
|
||||
|
||||
private readonly ApplicationInstance m_application = new();
|
||||
|
||||
private readonly ApplicationConfiguration m_configuration;
|
||||
private SessionReconnectHandler m_reConnectHandler;
|
||||
private EventHandler m_ReconnectComplete;
|
||||
private EventHandler m_ReconnectStarting;
|
||||
private EventHandler<KeepAliveEventArgs> m_KeepAliveComplete;
|
||||
private EventHandler<bool> m_ConnectComplete;
|
||||
private EventHandler<OpcUaStatusEventArgs> m_OpcStatusChange;
|
||||
|
||||
private ISession m_session;
|
||||
|
||||
/// <summary>
|
||||
/// 默认的构造函数,实例化一个新的OPC UA类
|
||||
/// </summary>
|
||||
public OPCUAClient(Action<byte, object, string, Exception> log)
|
||||
public OPCUAClient()
|
||||
{
|
||||
_logAction = log;
|
||||
var certificateValidator = new CertificateValidator();
|
||||
certificateValidator.CertificateValidation += CertificateValidation;
|
||||
|
||||
@@ -90,7 +96,6 @@ public class OPCUAClient : IDisposable
|
||||
MaxMessageQueueSize = 1000000,
|
||||
MaxNotificationQueueSize = 1000000,
|
||||
MaxPublishRequestCount = 10000000,
|
||||
|
||||
},
|
||||
|
||||
SecurityConfiguration = new SecurityConfiguration
|
||||
@@ -133,8 +138,6 @@ public class OPCUAClient : IDisposable
|
||||
StoreType = CertificateStoreType.Directory,
|
||||
StorePath = AppContext.BaseDirectory + @"OPCUAClientCertificate\pki\trustedUser",
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
|
||||
TransportQuotas = new TransportQuotas
|
||||
@@ -160,8 +163,6 @@ public class OPCUAClient : IDisposable
|
||||
|
||||
m_configuration.Validate(ApplicationType.Client);
|
||||
m_application.ApplicationConfiguration = m_configuration;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -188,6 +189,52 @@ public class OPCUAClient : IDisposable
|
||||
/// SessionReconnectHandler
|
||||
/// </summary>
|
||||
public SessionReconnectHandler ReConnectHandler => m_reConnectHandler;
|
||||
|
||||
/// <summary>
|
||||
/// Raised when a good keep alive from the server arrives.
|
||||
/// </summary>
|
||||
public event EventHandler<KeepAliveEventArgs> KeepAliveComplete
|
||||
{
|
||||
add { m_KeepAliveComplete += value; }
|
||||
remove { m_KeepAliveComplete -= value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised when a reconnect operation starts.
|
||||
/// </summary>
|
||||
public event EventHandler ReconnectStarting
|
||||
{
|
||||
add { m_ReconnectStarting += value; }
|
||||
remove { m_ReconnectStarting -= value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised when a reconnect operation completes.
|
||||
/// </summary>
|
||||
public event EventHandler ReconnectComplete
|
||||
{
|
||||
add { m_ReconnectComplete += value; }
|
||||
remove { m_ReconnectComplete -= value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised after successfully connecting to or disconnecing from a server.
|
||||
/// </summary>
|
||||
public event EventHandler<bool> ConnectComplete
|
||||
{
|
||||
add { m_ConnectComplete += value; }
|
||||
remove { m_ConnectComplete -= value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised after the client status change
|
||||
/// </summary>
|
||||
public event EventHandler<OpcUaStatusEventArgs> OpcStatusChange
|
||||
{
|
||||
add { m_OpcStatusChange += value; }
|
||||
remove { m_OpcStatusChange -= value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前活动会话。
|
||||
/// </summary>
|
||||
@@ -200,7 +247,7 @@ public class OPCUAClient : IDisposable
|
||||
/// <summary>
|
||||
/// 新增订阅,需要指定订阅组名称,订阅的tag名数组
|
||||
/// </summary>
|
||||
public async Task AddSubscriptionAsync(string subscriptionName, string[] items)
|
||||
public async Task AddSubscriptionAsync(string subscriptionName, string[] items, bool loadType = true)
|
||||
{
|
||||
Subscription m_subscription = new(m_session.DefaultSubscription)
|
||||
{
|
||||
@@ -213,14 +260,14 @@ public class OPCUAClient : IDisposable
|
||||
DisplayName = subscriptionName
|
||||
};
|
||||
List<MonitoredItem> monitoredItems = new();
|
||||
var variableNodes = loadType ? await ReadNodesAsync(items) : null;
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
var variableNode = await ReadNodeAsync(items[i], false);
|
||||
var item = new MonitoredItem
|
||||
{
|
||||
StartNodeId = variableNode.NodeId,
|
||||
StartNodeId = loadType ? variableNodes[i].NodeId : items[i],
|
||||
AttributeId = Attributes.Value,
|
||||
DisplayName = items[i],
|
||||
Filter = OPCNode.DeadBand == 0 ? null : new DataChangeFilter() { DeadbandValue = OPCNode.DeadBand, DeadbandType = (int)DeadbandType.Absolute, Trigger = DataChangeTrigger.StatusValue },
|
||||
@@ -231,7 +278,7 @@ public class OPCUAClient : IDisposable
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logAction?.Invoke(3, this, $"初始化{items[i]}变量订阅失败", ex);
|
||||
UpdateStatus(3, DateTime.Now, $"初始化{items[i]}变量订阅失败,错误原因:{ex}");
|
||||
}
|
||||
}
|
||||
m_subscription.AddItems(monitoredItems);
|
||||
@@ -247,9 +294,9 @@ public class OPCUAClient : IDisposable
|
||||
var isError = m_subscription.MonitoredItems.Any(a => a.Status.Error != null && StatusCode.IsBad(a.Status.Error.StatusCode));
|
||||
if (isError)
|
||||
{
|
||||
_logAction?.Invoke(3, this, $"创建以下变量订阅失败:{Environment.NewLine}{m_subscription.MonitoredItems.Where(
|
||||
UpdateStatus(3, DateTime.Now, $"创建以下变量订阅失败:{Environment.NewLine}{m_subscription.MonitoredItems.Where(
|
||||
a => a.Status.Error != null && StatusCode.IsBad(a.Status.Error.StatusCode))
|
||||
.Select(a => a.StartNodeId.ToString() + ":" + a.Status.Error.ToString()).ToJsonString()}", null);
|
||||
.Select(a => $"{a.StartNodeId.ToString()}:{a.Status.Error.ToString()}").ToJsonString()}");
|
||||
}
|
||||
|
||||
lock (dic_subscriptions)
|
||||
@@ -281,7 +328,6 @@ public class OPCUAClient : IDisposable
|
||||
item.Value.Delete(true);
|
||||
m_session.RemoveSubscription(item.Value);
|
||||
try { item.Value.Dispose(); } catch { }
|
||||
|
||||
}
|
||||
dic_subscriptions.Clear();
|
||||
}
|
||||
@@ -304,39 +350,40 @@ public class OPCUAClient : IDisposable
|
||||
dic_subscriptions.RemoveWhere(a => a.Key == subscriptionName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private async void Callback(MonitoredItem monitoreditem, MonitoredItemNotificationEventArgs monitoredItemNotificationEventArgs)
|
||||
private void Callback(MonitoredItem monitoreditem, MonitoredItemNotificationEventArgs monitoredItemNotificationEventArgs)
|
||||
{
|
||||
try
|
||||
{
|
||||
var variableNode = await ReadNodeAsync(monitoreditem.StartNodeId.ToString(), false);
|
||||
foreach (var value in monitoreditem.DequeueValues())
|
||||
if (m_session != null)
|
||||
{
|
||||
if (value.Value != null)
|
||||
var variableNode = ReadNode(monitoreditem.StartNodeId.ToString(), false);
|
||||
foreach (var value in monitoreditem.DequeueValues())
|
||||
{
|
||||
var data = JsonUtils.Encode(m_session.MessageContext, TypeInfo.GetBuiltInType(variableNode.DataType, m_session.SystemContext.TypeTable), value.Value);
|
||||
if (data == null && value.Value != null)
|
||||
if (value.Value != null)
|
||||
{
|
||||
_logAction?.Invoke(3, this, $"{monitoreditem.StartNodeId}转换出错,原始值String为{value.Value}", null);
|
||||
var data1 = JsonUtils.Encode(m_session.MessageContext, TypeInfo.GetBuiltInType(variableNode.DataType, m_session.SystemContext.TypeTable), value.Value);
|
||||
var data = JsonUtils.Encode(m_session.MessageContext, TypeInfo.GetBuiltInType(variableNode.DataType, m_session.SystemContext.TypeTable), value.Value);
|
||||
if (data == null && value.Value != null)
|
||||
{
|
||||
UpdateStatus(3, DateTime.Now, $"{monitoreditem.StartNodeId}转换出错,原始值String为{value.Value}");
|
||||
var data1 = JsonUtils.Encode(m_session.MessageContext, TypeInfo.GetBuiltInType(variableNode.DataType, m_session.SystemContext.TypeTable), value.Value);
|
||||
}
|
||||
DataChangedHandler?.Invoke((variableNode, value, data));
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = JValue.CreateNull();
|
||||
DataChangedHandler?.Invoke((variableNode, value, data));
|
||||
}
|
||||
DataChangedHandler?.Invoke((variableNode, value, data));
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = JValue.CreateNull();
|
||||
DataChangedHandler?.Invoke((variableNode, value, data));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logAction?.Invoke(3, this, $"{monitoreditem.StartNodeId}订阅处理错误", ex);
|
||||
UpdateStatus(3, DateTime.Now, $"{monitoreditem.StartNodeId}订阅处理错误,错误原因:" + ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -462,17 +509,16 @@ public class OPCUAClient : IDisposable
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 连接
|
||||
|
||||
private ComplexTypeSystem typeSystem;
|
||||
|
||||
/// <summary>
|
||||
/// 连接到服务器
|
||||
/// </summary>
|
||||
public async Task ConnectAsync()
|
||||
public async Task ConnectAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await ConnectAsync(OPCNode.OPCUrl);
|
||||
_logAction?.Invoke(1, this, $"连接成功", null);
|
||||
await ConnectAsync(OPCNode.OPCUrl, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -484,15 +530,15 @@ public class OPCUAClient : IDisposable
|
||||
// disconnect any existing session.
|
||||
if (m_session != null)
|
||||
{
|
||||
_logAction?.Invoke(1, this, $"主动断开连接", null);
|
||||
m_session = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new session.
|
||||
/// </summary>
|
||||
/// <returns>The new session object.</returns>
|
||||
private async Task<ISession> ConnectAsync(string serverUrl)
|
||||
private async Task<ISession> ConnectAsync(string serverUrl, CancellationToken cancellationToken)
|
||||
{
|
||||
PrivateDisconnect();
|
||||
|
||||
@@ -501,6 +547,7 @@ public class OPCUAClient : IDisposable
|
||||
throw new ArgumentNullException("未初始化配置");
|
||||
}
|
||||
var useSecurity = OPCNode?.IsUseSecurity ?? true;
|
||||
|
||||
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(m_configuration, serverUrl, useSecurity, 10000);
|
||||
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
|
||||
ConfiguredEndpoint endpoint = new(null, endpointDescription, endpointConfiguration);
|
||||
@@ -516,28 +563,41 @@ public class OPCUAClient : IDisposable
|
||||
//创建本地证书
|
||||
await m_application.CheckApplicationInstanceCertificate(true, 0, 1200);
|
||||
m_session = await Opc.Ua.Client.Session.Create(
|
||||
m_configuration,
|
||||
endpoint,
|
||||
false,
|
||||
OPCNode.CheckDomain,
|
||||
(string.IsNullOrEmpty(OPCUAName)) ? m_configuration.ApplicationName : OPCUAName,
|
||||
60000,
|
||||
userIdentity,
|
||||
Array.Empty<string>());
|
||||
|
||||
m_configuration,
|
||||
endpoint,
|
||||
false,
|
||||
OPCNode.CheckDomain,
|
||||
(string.IsNullOrEmpty(OPCUAName)) ? m_configuration.ApplicationName : OPCUAName,
|
||||
60000,
|
||||
userIdentity,
|
||||
Array.Empty<string>(), cancellationToken
|
||||
).ConfigureAwait(false);
|
||||
typeSystem = new ComplexTypeSystem(m_session);
|
||||
|
||||
m_session.KeepAliveInterval = OPCNode.KeepAliveInterval == 0 ? 60000 : OPCNode.KeepAliveInterval;
|
||||
m_session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive);
|
||||
|
||||
// raise an event.
|
||||
DoConnectComplete(true);
|
||||
|
||||
UpdateStatus(2, DateTime.UtcNow, "Connected");
|
||||
|
||||
//如果是订阅模式,连接时添加订阅组
|
||||
if (OPCNode.ActiveSubscribe)
|
||||
await AddSubscriptionAsync(Guid.NewGuid().ToString(), Variables.ToArray());
|
||||
{
|
||||
foreach (var item in Variables)
|
||||
{
|
||||
await AddSubscriptionAsync(Guid.NewGuid().ToString(), item.ToArray(), OPCNode.LoadType);
|
||||
}
|
||||
}
|
||||
return m_session;
|
||||
}
|
||||
|
||||
private void PrivateDisconnect()
|
||||
{
|
||||
bool state = m_session?.Connected == true;
|
||||
|
||||
|
||||
if (m_reConnectHandler != null)
|
||||
{
|
||||
try { m_reConnectHandler.Dispose(); } catch { }
|
||||
@@ -549,8 +609,14 @@ public class OPCUAClient : IDisposable
|
||||
m_session.Close(10000);
|
||||
}
|
||||
|
||||
if (state)
|
||||
{
|
||||
UpdateStatus(2, DateTime.UtcNow, "Disconnected");
|
||||
DoConnectComplete(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 读取/写入
|
||||
@@ -593,7 +659,6 @@ public class OPCUAClient : IDisposable
|
||||
valuesToWrite.Add(valueToWrite);
|
||||
}
|
||||
|
||||
|
||||
var result = await m_session.WriteAsync(
|
||||
requestHeader: null,
|
||||
nodesToWrite: valuesToWrite, cancellationToken);
|
||||
@@ -601,7 +666,6 @@ public class OPCUAClient : IDisposable
|
||||
ClientBase.ValidateResponse(result.Results, valuesToWrite);
|
||||
ClientBase.ValidateDiagnosticInfos(result.DiagnosticInfos, valuesToWrite);
|
||||
|
||||
|
||||
var keys = writeInfoLists.Keys.ToList();
|
||||
for (int i = 0; i < keys.Count; i++)
|
||||
{
|
||||
@@ -624,7 +688,6 @@ public class OPCUAClient : IDisposable
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -680,15 +743,61 @@ public class OPCUAClient : IDisposable
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
NodeId nodeToRead = new(nodeIdStr);
|
||||
var node = (VariableNode)await m_session.ReadNodeAsync(nodeToRead, cancellationToken);
|
||||
await typeSystem.LoadType(node.DataType, true, true);
|
||||
var node = (VariableNode)await m_session.ReadNodeAsync(nodeToRead, NodeClass.Variable, false, cancellationToken);
|
||||
if (OPCNode.LoadType)
|
||||
await typeSystem.LoadType(node.DataType).ConfigureAwait(false);
|
||||
_variableDicts.AddOrUpdate(nodeIdStr, node);
|
||||
return node;
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 从服务器或缓存读取节点
|
||||
/// </summary>
|
||||
private VariableNode ReadNode(string nodeIdStr, bool isOnlyServer = true)
|
||||
{
|
||||
if (!isOnlyServer)
|
||||
{
|
||||
if (_variableDicts.TryGetValue(nodeIdStr, out var value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
NodeId nodeToRead = new(nodeIdStr);
|
||||
var node = (VariableNode)m_session.ReadNode(nodeToRead, NodeClass.Variable, false);
|
||||
_variableDicts.AddOrUpdate(nodeIdStr, node);
|
||||
return node;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从服务器读取节点
|
||||
/// </summary>
|
||||
private async Task<List<Node>> ReadNodesAsync(string[] nodeIdStrs, CancellationToken cancellationToken = default)
|
||||
{
|
||||
List<NodeId> nodeIds = new List<NodeId>();
|
||||
foreach (var item in nodeIdStrs)
|
||||
{
|
||||
NodeId nodeToRead = new(item);
|
||||
nodeIds.Add(nodeToRead);
|
||||
}
|
||||
(IList<Node>, IList<ServiceResult>) nodes = await m_session.ReadNodesAsync(nodeIds, NodeClass.Variable, false, cancellationToken);
|
||||
for (int i = 0; i < nodes.Item1.Count; i++)
|
||||
{
|
||||
if (StatusCode.IsGood(nodes.Item2[i].StatusCode))
|
||||
{
|
||||
var node = ((VariableNode)nodes.Item1[i]);
|
||||
await typeSystem.LoadType(node.DataType).ConfigureAwait(false);
|
||||
_variableDicts.AddOrUpdate(nodeIdStrs[i], node);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateStatus(3, DateTime.Now, $"获取服务器节点信息失败{nodes.Item2[i]}");
|
||||
}
|
||||
}
|
||||
return nodes.Item1.ToList();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 特性
|
||||
|
||||
@@ -754,7 +863,6 @@ public class OPCUAClient : IDisposable
|
||||
ResultMask = (uint)BrowseResultMask.All
|
||||
};
|
||||
nodesToBrowse.Add(nodeToBrowse);
|
||||
|
||||
}
|
||||
|
||||
return await ReadNoteAttributeAsync(nodesToBrowse, nodesToRead, cancellationToken);
|
||||
@@ -917,11 +1025,9 @@ public class OPCUAClient : IDisposable
|
||||
|
||||
return nodeAttribute.ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -940,7 +1046,6 @@ public class OPCUAClient : IDisposable
|
||||
throw new Exception(string.Format("验证证书失败,错误代码:{0}: {1}", eventArgs.Error.Code, eventArgs.Error.AdditionalInfo));
|
||||
}
|
||||
|
||||
|
||||
private async Task<Dictionary<string, List<OPCNodeAttribute>>> ReadNoteAttributeAsync(BrowseDescriptionCollection nodesToBrowse, ReadValueIdCollection nodesToRead, CancellationToken cancellationToken)
|
||||
{
|
||||
int startOfProperties = nodesToRead.Count;
|
||||
@@ -1017,7 +1122,6 @@ public class OPCUAClient : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (nodeAttributes.ContainsKey(nodeToRead.NodeId.ToString()))
|
||||
{
|
||||
nodeAttributes[nodeToRead.NodeId.ToString()].Add(item);
|
||||
@@ -1035,21 +1139,47 @@ public class OPCUAClient : IDisposable
|
||||
/// </summary>
|
||||
private void Server_ReconnectComplete(object sender, EventArgs e)
|
||||
{
|
||||
if (!Object.ReferenceEquals(sender, m_reConnectHandler))
|
||||
try
|
||||
{
|
||||
return;
|
||||
if (!Object.ReferenceEquals(sender, m_reConnectHandler))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_session = m_reConnectHandler.Session;
|
||||
m_reConnectHandler.Dispose();
|
||||
m_reConnectHandler = null;
|
||||
|
||||
// raise any additional notifications.
|
||||
m_ReconnectComplete?.Invoke(this, e);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
m_session = m_reConnectHandler.Session;
|
||||
m_reConnectHandler = null;
|
||||
|
||||
/// <summary>
|
||||
/// Report the client status
|
||||
/// </summary>
|
||||
/// <param name="logLevel">Whether the status represents an error. </param>
|
||||
/// <param name="time">The time associated with the status.</param>
|
||||
/// <param name="status">The status message.</param>
|
||||
/// <param name="args">Arguments used to format the status message.</param>
|
||||
private void UpdateStatus(int logLevel, DateTime time, string status, params object[] args)
|
||||
{
|
||||
m_OpcStatusChange?.Invoke(this, new OpcUaStatusEventArgs()
|
||||
{
|
||||
LogLevel = logLevel,
|
||||
Time = time.ToLocalTime(),
|
||||
Text = String.Format(status, args),
|
||||
});
|
||||
}
|
||||
|
||||
private void Session_KeepAlive(ISession session, KeepAliveEventArgs e)
|
||||
{
|
||||
lock (checkLock)
|
||||
{
|
||||
|
||||
if (!Object.ReferenceEquals(session, m_session))
|
||||
{
|
||||
return;
|
||||
@@ -1057,22 +1187,39 @@ public class OPCUAClient : IDisposable
|
||||
|
||||
if (ServiceResult.IsBad(e.Status))
|
||||
{
|
||||
_logAction?.Invoke(3, this, $"心跳检测错误:{e.Status}", null);
|
||||
if (m_session.KeepAliveInterval <= 0)
|
||||
{
|
||||
UpdateStatus(3, e.CurrentTime, "Communication Error ({0})", e.Status);
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateStatus(3, e.CurrentTime, "Reconnecting in {0}s", m_session.KeepAliveInterval / 1000);
|
||||
|
||||
if (m_reConnectHandler == null)
|
||||
{
|
||||
m_ReconnectStarting?.Invoke(this, e);
|
||||
|
||||
m_reConnectHandler = new SessionReconnectHandler();
|
||||
m_reConnectHandler.BeginReconnect(m_session, m_session.KeepAliveInterval, Server_ReconnectComplete);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// update status.
|
||||
UpdateStatus(0, e.CurrentTime, "Session_KeepAlive Connected [{0}]", session.Endpoint.EndpointUrl);
|
||||
|
||||
// raise any additional notifications.
|
||||
m_KeepAliveComplete?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Raises the connect complete event on the main GUI thread.
|
||||
/// </summary>
|
||||
private void DoConnectComplete(bool state)
|
||||
{
|
||||
m_ConnectComplete?.Invoke(this, state);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
@@ -13,6 +13,33 @@
|
||||
using Opc.Ua;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.OPCUA;
|
||||
|
||||
/// <summary>
|
||||
/// OPC UA的状态更新消息
|
||||
/// </summary>
|
||||
public class OpcUaStatusEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 日志等级,<br></br>
|
||||
/// 更为详细的步骤型日志输出 Trace = 0,<br></br>
|
||||
/// 调试信息日志Debug = 1,<br></br>
|
||||
/// 消息类日志输出 Info = 2,<br></br>
|
||||
/// 警告类日志输出 Warning = 3,<br></br>
|
||||
/// 错误类日志输出 Error = 4,<br></br>
|
||||
/// 不可控中断类日输出Critical = 5,
|
||||
/// </summary>
|
||||
public int LogLevel { get; set; }
|
||||
/// <summary>
|
||||
/// 时间
|
||||
/// </summary>
|
||||
public DateTime Time { get; set; }
|
||||
/// <summary>
|
||||
/// 文本
|
||||
/// </summary>
|
||||
public string Text { get; set; }
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取属性过程中用于描述的
|
||||
/// </summary>
|
||||
@@ -22,6 +49,7 @@ public class OPCNodeAttribute
|
||||
/// 属性的名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作结果状态描述
|
||||
/// </summary>
|
||||
@@ -31,10 +59,9 @@ public class OPCNodeAttribute
|
||||
/// 属性的类型描述
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 属性的值,如果读取错误,返回文本描述
|
||||
/// </summary>
|
||||
public object Value { get; set; }
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -7,9 +7,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client" Version="1.4.372.56" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client.ComplexTypes" Version="1.4.372.56" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client" Version="1.4.372.76" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client.ComplexTypes" Version="1.4.372.76" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
||||
|
@@ -1,468 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>ThingsGateway.Foundation.Adapter.OPCUA</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.CollectionExtensions.RemoveWhere``1(System.Collections.Generic.ICollection{``0},System.Func{``0,System.Boolean})">
|
||||
<summary>
|
||||
移除符合条件的元素
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="this"></param>
|
||||
<param name="where"></param>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.CollectionExtensions.SelectAsync``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Threading.Tasks.Task{``1}})">
|
||||
<summary>
|
||||
异步Select
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<typeparam name="TResult"></typeparam>
|
||||
<param name="source"></param>
|
||||
<param name="selector"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils">
|
||||
<summary>
|
||||
辅助类
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.Browse(Opc.Ua.Client.ISession,Opc.Ua.BrowseDescriptionCollection,System.Boolean)">
|
||||
<summary>
|
||||
Browses the address space and returns the references found.
|
||||
</summary>
|
||||
<param name="session">The session.</param>
|
||||
<param name="nodesToBrowse">The set of browse operations to perform.</param>
|
||||
<param name="throwOnError">if set to <c>true</c> a exception will be thrown on an error.</param>
|
||||
<returns>
|
||||
The references found. Null if an error occurred.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.PrepareBrowseNext(Opc.Ua.BrowseResultCollection)">
|
||||
<summary>
|
||||
Create the continuation point collection from the browse result
|
||||
collection for the BrowseNext service.
|
||||
</summary>
|
||||
<param name="browseResultCollection">The browse result collection to use.</param>
|
||||
<returns>The collection of continuation points for the BrowseNext service.</returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.BrowseAsync(Opc.Ua.Client.ISession,Opc.Ua.BrowseDescriptionCollection,System.Boolean,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
浏览地址空间
|
||||
</summary>
|
||||
<param name="session"></param>
|
||||
<param name="nodesToBrowse"></param>
|
||||
<param name="throwOnError"></param>
|
||||
<param name="cancellationToken"></param>
|
||||
<returns></returns>
|
||||
<exception cref="T:Opc.Ua.ServiceResultException"></exception>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.BrowseAsync(Opc.Ua.Client.ISession,Opc.Ua.BrowseDescription,System.Boolean,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
浏览地址空间
|
||||
</summary>
|
||||
<param name="session"></param>
|
||||
<param name="nodeToBrowse"></param>
|
||||
<param name="throwOnError"></param>
|
||||
<param name="cancellationToken"></param>
|
||||
<returns></returns>
|
||||
<exception cref="T:Opc.Ua.ServiceResultException"></exception>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.BrowseSuperTypesAsync(Opc.Ua.Client.ISession,Opc.Ua.NodeId,System.Boolean)">
|
||||
<summary>
|
||||
浏览地址空间并返回指定类型的所有节点
|
||||
</summary>
|
||||
<param name="session"></param>
|
||||
<param name="typeId"></param>
|
||||
<param name="throwOnError"></param>
|
||||
<returns></returns>
|
||||
<exception cref="T:Opc.Ua.ServiceResultException"></exception>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.CollectFieldsForInstanceAsync(Opc.Ua.Client.ISession,Opc.Ua.NodeId,Opc.Ua.SimpleAttributeOperandCollection,System.Collections.Generic.List{Opc.Ua.NodeId})">
|
||||
<summary>
|
||||
Collects the fields for the instance.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.CollectFieldsForType(Opc.Ua.Client.ISession,Opc.Ua.NodeId,Opc.Ua.SimpleAttributeOperandCollection,System.Collections.Generic.List{Opc.Ua.NodeId})">
|
||||
<summary>
|
||||
Collects the fields for the type.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.ConstructEventAsync(Opc.Ua.Client.ISession,Opc.Ua.Client.MonitoredItem,Opc.Ua.EventFieldList,System.Collections.Generic.Dictionary{Opc.Ua.NodeId,System.Type},System.Collections.Generic.Dictionary{Opc.Ua.NodeId,Opc.Ua.NodeId})">
|
||||
<summary>
|
||||
Constructs an event object from a notification.
|
||||
</summary>
|
||||
<param name="session">The session.</param>
|
||||
<param name="monitoredItem">The monitored item that produced the notification.</param>
|
||||
<param name="notification">The notification.</param>
|
||||
<param name="knownEventTypes">The known event types.</param>
|
||||
<param name="eventTypeMappings">Mapping between event types and known event types.</param>
|
||||
<returns>
|
||||
The event object. Null if the notification is not a valid event type.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.DiscoverServers(Opc.Ua.ApplicationConfiguration)">
|
||||
<summary>
|
||||
Discovers the servers on the local machine.
|
||||
</summary>
|
||||
<param name="configuration">The configuration.</param>
|
||||
<returns>A list of server urls.</returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.FindEventType(Opc.Ua.Client.MonitoredItem,Opc.Ua.EventFieldList)">
|
||||
<summary>
|
||||
Finds the type of the event for the notification.
|
||||
</summary>
|
||||
<param name="monitoredItem">The monitored item.</param>
|
||||
<param name="notification">The notification.</param>
|
||||
<returns>The NodeId of the EventType.</returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.GetAttributeDisplayText(Opc.Ua.Client.ISession,System.UInt32,Opc.Ua.Variant)">
|
||||
<summary>
|
||||
指定的属性的显示文本。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.SelectEndpoint(System.String,System.Boolean)">
|
||||
<summary>
|
||||
Finds the endpoint that best matches the current settings.
|
||||
</summary>
|
||||
<param name="discoveryUrl">The discovery URL.</param>
|
||||
<param name="useSecurity">if set to <c>true</c> select an endpoint that uses security.</param>
|
||||
<returns>The best available endpoint.</returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.TranslateBrowsePaths(Opc.Ua.Client.ISession,Opc.Ua.NodeId,Opc.Ua.NamespaceTable,System.Threading.CancellationToken,System.String[])">
|
||||
<summary>
|
||||
返回一组相对路径的节点id
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.CollectFieldsAsync(Opc.Ua.Client.ISession,Opc.Ua.NodeId,Opc.Ua.QualifiedNameCollection,Opc.Ua.SimpleAttributeOperandCollection,System.Collections.Generic.List{Opc.Ua.NodeId},System.Collections.Generic.Dictionary{Opc.Ua.NodeId,Opc.Ua.QualifiedNameCollection})">
|
||||
<summary>
|
||||
Collects the fields for the instance node.
|
||||
</summary>
|
||||
<param name="session">The session.</param>
|
||||
<param name="nodeId">The node id.</param>
|
||||
<param name="parentPath">The parent path.</param>
|
||||
<param name="fields">The event fields.</param>
|
||||
<param name="fieldNodeIds">The node id for the declaration of the field.</param>
|
||||
<param name="foundNodes">The table of found nodes.</param>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.ContainsPath(Opc.Ua.SimpleAttributeOperandCollection,Opc.Ua.QualifiedNameCollection)">
|
||||
<summary>
|
||||
判断指定的select子句包含的浏览路径。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.GetAccessLevelDisplayText(System.Byte)">
|
||||
<summary>
|
||||
访问级别属性的显示文本。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.GetEventNotifierDisplayText(System.Byte)">
|
||||
<summary>
|
||||
事件通知属性的显示文本
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils">
|
||||
<summary>
|
||||
扩展方法
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.Decode(Opc.Ua.IServiceMessageContext,Opc.Ua.NodeId,Opc.Ua.BuiltInType,System.Int32,Newtonsoft.Json.Linq.JToken)">
|
||||
<summary>
|
||||
解析获取DataValue
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.DecoderObject(Opc.Ua.IServiceMessageContext,Opc.Ua.NodeId,Opc.Ua.BuiltInType,System.Int32,Newtonsoft.Json.Linq.JToken)">
|
||||
<summary>
|
||||
解析获取object
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.DecodeRawData(Opc.Ua.JsonDecoder,Opc.Ua.BuiltInType,System.Int32,System.String)">
|
||||
<summary>
|
||||
DecodeRawData
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.Encode(Opc.Ua.IServiceMessageContext,Opc.Ua.BuiltInType,System.Object)">
|
||||
<summary>
|
||||
OPCUAValue解析为Jtoken
|
||||
</summary>
|
||||
<param name="Context"></param>
|
||||
<param name="type"></param>
|
||||
<param name="value"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.CreateEncoder(Opc.Ua.IServiceMessageContext,System.IO.Stream,System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
|
||||
<summary>
|
||||
CreateEncoder
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.CalculateActualValueRank(Newtonsoft.Json.Linq.JToken)">
|
||||
<summary>
|
||||
维度
|
||||
</summary>
|
||||
<param name="jToken"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode">
|
||||
<summary>
|
||||
OPCUAClient配置项
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.OPCUrl">
|
||||
<summary>
|
||||
OPCUrl
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.UserName">
|
||||
<summary>
|
||||
登录账号
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.Password">
|
||||
<summary>
|
||||
登录密码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.CheckDomain">
|
||||
<summary>
|
||||
检查域
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.UpdateRate">
|
||||
<summary>
|
||||
更新间隔
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.ActiveSubscribe">
|
||||
<summary>
|
||||
是否订阅
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.GroupSize">
|
||||
<summary>
|
||||
分组大小
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.DeadBand">
|
||||
<summary>
|
||||
死区
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.KeepAliveInterval">
|
||||
<summary>
|
||||
KeepAliveInterval/ms
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.IsUseSecurity">
|
||||
<summary>
|
||||
安全策略
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.ToString">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCUA.DataChangedEventHandler">
|
||||
<summary>
|
||||
订阅委托
|
||||
</summary>
|
||||
<param name="value"></param>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient">
|
||||
<summary>
|
||||
OPCUAClient
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.OPCNode">
|
||||
<summary>
|
||||
当前配置
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ProductUri">
|
||||
<summary>
|
||||
ProductUri
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Variables">
|
||||
<summary>
|
||||
当前保存的变量名称列表
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient._variableDicts">
|
||||
<summary>
|
||||
当前的变量名称/OPC变量节点
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.dic_subscriptions">
|
||||
<summary>
|
||||
当前的订阅组,组名称/组
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReConnectHandler">
|
||||
<summary>
|
||||
SessionReconnectHandler
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.#ctor(ThingsGateway.Foundation.ILog)">
|
||||
<summary>
|
||||
默认的构造函数,实例化一个新的OPC UA类
|
||||
</summary>
|
||||
</member>
|
||||
<member name="E:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.DataChangedHandler">
|
||||
<summary>
|
||||
订阅
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.AppConfig">
|
||||
<summary>
|
||||
配置信息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Connected">
|
||||
<summary>
|
||||
连接状态
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.OPCUAName">
|
||||
<summary>
|
||||
OPCUAClient
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Session">
|
||||
<summary>
|
||||
当前活动会话。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.AddSubscriptionAsync(System.String,System.String[])">
|
||||
<summary>
|
||||
新增订阅,需要指定订阅组名称,订阅的tag名数组
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.RemoveAllSubscription">
|
||||
<summary>
|
||||
移除所有的订阅消息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.RemoveSubscription(System.String)">
|
||||
<summary>
|
||||
移除订阅消息
|
||||
</summary>
|
||||
<param name="subscriptionName">组名称</param>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.BrowseNodeReferenceAsync(System.String)">
|
||||
<summary>
|
||||
浏览一个节点的引用
|
||||
</summary>
|
||||
<param name="tag">节点值</param>
|
||||
<returns>引用节点描述</returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.CallMethodByNodeId(System.String,System.String,System.Object[])">
|
||||
<summary>
|
||||
调用服务器的方法
|
||||
</summary>
|
||||
<param name="tagParent">方法的父节点tag</param>
|
||||
<param name="tag">方法的节点tag</param>
|
||||
<param name="args">传递的参数</param>
|
||||
<returns>输出的结果值</returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadHistoryRawDataValues(System.String,System.DateTime,System.DateTime,System.UInt32,System.Boolean,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
读取历史数据
|
||||
</summary>
|
||||
<param name="tag">节点的索引</param>
|
||||
<param name="start">开始时间</param>
|
||||
<param name="end">结束时间</param>
|
||||
<param name="count">读取的个数</param>
|
||||
<param name="containBound">是否包含边界</param>
|
||||
<param name="cancellationToken">cancellationToken</param>
|
||||
<returns>读取的数据列表</returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ConnectAsync">
|
||||
<summary>
|
||||
连接到服务器
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Disconnect">
|
||||
<summary>
|
||||
断开连接。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ConnectAsync(System.String)">
|
||||
<summary>
|
||||
Creates a new session.
|
||||
</summary>
|
||||
<returns>The new session object.</returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadJTokenValueAsync(System.String[],System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
从服务器读取值
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.WriteNodeAsync(System.Collections.Generic.Dictionary{System.String,Newtonsoft.Json.Linq.JToken},System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
异步写opc标签
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadJTokenValueAsync(Opc.Ua.NodeId[],System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
从服务器读取值
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadNodeAsync(System.String,System.Boolean,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
从服务器或缓存读取节点
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadNoteAttributeAsync(System.String,System.UInt32,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
读取一个节点的所有属性
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadNoteAttributeAsync(System.Collections.Generic.List{System.String},System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
读取节点的所有属性
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadNoteAttributes(System.String)">
|
||||
<summary>
|
||||
读取一个节点的所有属性
|
||||
</summary>
|
||||
<param name="tag">节点信息</param>
|
||||
<returns>节点的特性值</returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Dispose(System.Boolean)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Server_ReconnectComplete(System.Object,System.EventArgs)">
|
||||
<summary>
|
||||
连接处理器连接事件处理完成。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.OPCUA.OPCNodeAttribute">
|
||||
<summary>
|
||||
读取属性过程中用于描述的
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNodeAttribute.Name">
|
||||
<summary>
|
||||
属性的名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNodeAttribute.StatusCode">
|
||||
<summary>
|
||||
操作结果状态描述
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNodeAttribute.Type">
|
||||
<summary>
|
||||
属性的类型描述
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNodeAttribute.Value">
|
||||
<summary>
|
||||
属性的值,如果读取错误,返回文本描述
|
||||
</summary>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
@@ -11,8 +11,10 @@
|
||||
#endregion
|
||||
|
||||
global using System;
|
||||
global using System.Collections.Generic;
|
||||
global using System.Linq;
|
||||
global using System.Threading;
|
||||
global using System.Threading.Tasks;
|
||||
|
||||
global using ThingsGateway.Foundation.Core;
|
||||
global using ThingsGateway.Foundation.Sockets;
|
||||
|
@@ -10,7 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using ThingsGateway.Foundation.Extension.String;
|
||||
using ThingsGateway.Foundation.Extension;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Siemens;
|
||||
/// <summary>
|
||||
@@ -54,7 +54,10 @@ public class SiemensAddress : DeviceAddressBase
|
||||
/// DB块数据信息
|
||||
/// </summary>
|
||||
public ushort DbBlock { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// IsWString,默认是true,如果不是WString,需要填写W=false;
|
||||
/// </summary>
|
||||
public bool IsWString { get; set; } = true;
|
||||
/// <summary>
|
||||
/// 获取起始地址
|
||||
/// </summary>
|
||||
@@ -103,127 +106,132 @@ public class SiemensAddress : DeviceAddressBase
|
||||
public static SiemensAddress ParseFrom(string address)
|
||||
{
|
||||
SiemensAddress s7AddressData = new();
|
||||
|
||||
address = address.ToUpper();
|
||||
address = address.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
|
||||
string[] strArr = address.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
for (int index = 0; index < strArr.Length; ++index)
|
||||
{
|
||||
if (strArr[index].StartsWith("W="))
|
||||
{
|
||||
s7AddressData.IsWString = strArr[index].Substring(2).ToBoolean(true);
|
||||
}
|
||||
else if (!strArr[index].Contains("="))
|
||||
{
|
||||
|
||||
s7AddressData.DbBlock = 0;
|
||||
if (address.StartsWith("AI"))
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.AI;
|
||||
if (address.StartsWith("AIX") || address.StartsWith("AIB") || address.StartsWith("AIW") || address.StartsWith("AID"))
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(address.Substring(3)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address.Substring(3));
|
||||
}
|
||||
else
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(address.Substring(2)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address.Substring(2));
|
||||
}
|
||||
}
|
||||
else if (address.StartsWith("AQ"))
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.AQ;
|
||||
if (address.StartsWith("AQX") || address.StartsWith("AQB") || address.StartsWith("AQW") || address.StartsWith("AQD"))
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(address.Substring(3)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address.Substring(3));
|
||||
}
|
||||
else
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(address.Substring(2)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address.Substring(2));
|
||||
}
|
||||
}
|
||||
else if (address[0] == 'I')
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.PE;
|
||||
if (address.StartsWith("IX") || address.StartsWith("IB") || address.StartsWith("IW") || address.StartsWith("ID"))
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(address.Substring(2)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address.Substring(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(address.Substring(1)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address.Substring(1));
|
||||
}
|
||||
}
|
||||
else if (address[0] == 'Q')
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.PA;
|
||||
if (address.StartsWith("QX") || address.StartsWith("QB") || address.StartsWith("QW") || address.StartsWith("QD"))
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(address.Substring(2)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address.Substring(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(address.Substring(1)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address.Substring(1));
|
||||
}
|
||||
}
|
||||
else if (address[0] == 'M')
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.MK;
|
||||
if (address.StartsWith("MX") || address.StartsWith("MB") || address.StartsWith("MW") || address.StartsWith("MD"))
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(address.Substring(2)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address.Substring(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(address.Substring(1)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address.Substring(1));
|
||||
}
|
||||
}
|
||||
else if (address[0] == 'D' || address.Substring(0, 2) == "DB")
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.DB;
|
||||
string[] strArray = address.Split('.');
|
||||
s7AddressData.DbBlock = address[1] != 'B' ? Convert.ToUInt16(strArray[0].Substring(1)) : Convert.ToUInt16(strArray[0].Substring(2));
|
||||
string address1 = address.Substring(address.IndexOf('.') + 1);
|
||||
if (address1.StartsWith("DBX") || address1.StartsWith("DBB") || address1.StartsWith("DBW") || address1.StartsWith("DBD"))
|
||||
{
|
||||
address1 = address1.Substring(3);
|
||||
}
|
||||
s7AddressData.DbBlock = 0;
|
||||
|
||||
s7AddressData.Address = GetAddressStart(address1).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address1);
|
||||
}
|
||||
else if (address[0] == 'T')
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.TM;
|
||||
s7AddressData.Address = GetAddressStart(address.Substring(1), true).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address.Substring(1));
|
||||
}
|
||||
else if (address[0] == 'C')
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.CT;
|
||||
s7AddressData.Address = GetAddressStart(address.Substring(1), true).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address.Substring(1));
|
||||
}
|
||||
else if (address[0] == 'V')
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.DB;
|
||||
s7AddressData.DbBlock = 1;
|
||||
if (address.StartsWith("VB") || address.StartsWith("VW") || address.StartsWith("VD") || address.StartsWith("VX"))
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(address.Substring(2)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address.Substring(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(address.Substring(1)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address.Substring(1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("解析错误,无相关变量类型");
|
||||
}
|
||||
if (strArr[index].StartsWith("AI"))
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.AI;
|
||||
if (strArr[index].StartsWith("AIX") || strArr[index].StartsWith("AIB") || strArr[index].StartsWith("AIW") || strArr[index].StartsWith("AID"))
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(strArr[index].Substring(3)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(strArr[index].Substring(3));
|
||||
}
|
||||
else
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(strArr[index].Substring(2)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(strArr[index].Substring(2));
|
||||
}
|
||||
}
|
||||
else if (strArr[index].StartsWith("AQ"))
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.AQ;
|
||||
if (strArr[index].StartsWith("AQX") || strArr[index].StartsWith("AQB") || strArr[index].StartsWith("AQW") || strArr[index].StartsWith("AQD"))
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(strArr[index].Substring(3)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(strArr[index].Substring(3));
|
||||
}
|
||||
else
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(strArr[index].Substring(2)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(strArr[index].Substring(2));
|
||||
}
|
||||
}
|
||||
else if (strArr[index][0] == 'I')
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.PE;
|
||||
if (strArr[index].StartsWith("IX") || strArr[index].StartsWith("IB") || strArr[index].StartsWith("IW") || strArr[index].StartsWith("ID"))
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(strArr[index].Substring(2)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(strArr[index].Substring(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(strArr[index].Substring(1)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(strArr[index].Substring(1));
|
||||
}
|
||||
}
|
||||
else if (strArr[index][0] == 'Q')
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.PA;
|
||||
if (strArr[index].StartsWith("QX") || strArr[index].StartsWith("QB") || strArr[index].StartsWith("QW") || strArr[index].StartsWith("QD"))
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(strArr[index].Substring(2)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(strArr[index].Substring(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(strArr[index].Substring(1)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(strArr[index].Substring(1));
|
||||
}
|
||||
}
|
||||
else if (strArr[index][0] == 'M')
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.MK;
|
||||
if (strArr[index].StartsWith("MX") || strArr[index].StartsWith("MB") || strArr[index].StartsWith("MW") || strArr[index].StartsWith("MD"))
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(strArr[index].Substring(2)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(strArr[index].Substring(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(strArr[index].Substring(1)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(strArr[index].Substring(1));
|
||||
}
|
||||
}
|
||||
else if (strArr[index][0] == 'D' || strArr[index].Substring(0, 2) == "DB")
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.DB;
|
||||
string[] strArray = strArr[index].Split('.');
|
||||
s7AddressData.DbBlock = strArray[index][1] != 'B' ? Convert.ToUInt16(strArray[0].Substring(1)) : Convert.ToUInt16(strArray[0].Substring(2));
|
||||
string address1 = strArr[index].Substring(strArr[index].IndexOf('.') + 1);
|
||||
if (address1.StartsWith("DBX") || address1.StartsWith("DBB") || address1.StartsWith("DBW") || address1.StartsWith("DBD"))
|
||||
{
|
||||
address1 = address1.Substring(3);
|
||||
}
|
||||
|
||||
s7AddressData.Address = GetAddressStart(address1).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(address1);
|
||||
}
|
||||
else if (strArr[index][0] == 'T')
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.TM;
|
||||
s7AddressData.Address = GetAddressStart(strArr[index].Substring(1), true).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(strArr[index].Substring(1));
|
||||
}
|
||||
else if (strArr[index][0] == 'C')
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.CT;
|
||||
s7AddressData.Address = GetAddressStart(strArr[index].Substring(1), true).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(strArr[index].Substring(1));
|
||||
}
|
||||
else if (strArr[index][0] == 'V')
|
||||
{
|
||||
s7AddressData.DataCode = (byte)S7Area.DB;
|
||||
s7AddressData.DbBlock = 1;
|
||||
if (strArr[index].StartsWith("VB") || strArr[index].StartsWith("VW") || strArr[index].StartsWith("VD") || strArr[index].StartsWith("VX"))
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(strArr[index].Substring(2)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(strArr[index].Substring(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
s7AddressData.Address = GetAddressStart(strArr[index].Substring(1)).ToString();
|
||||
s7AddressData.BitCode = GetBitCode(strArr[index].Substring(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return s7AddressData;
|
||||
}
|
||||
|
||||
@@ -242,44 +250,44 @@ public class SiemensAddress : DeviceAddressBase
|
||||
{
|
||||
if (DataCode == (byte)S7Area.TM)
|
||||
{
|
||||
return "T" + Address.ToString();
|
||||
return $"T{Address.ToString()}{(IsWString ? ";W=true;" : ";W=false;")}";
|
||||
}
|
||||
if (DataCode == (byte)S7Area.CT)
|
||||
{
|
||||
return "C" + Address.ToString();
|
||||
return $"C{Address.ToString()}{(IsWString ? ";W=true;" : ";W=false;")}";
|
||||
}
|
||||
|
||||
if (DataCode == (byte)S7Area.AI)
|
||||
{
|
||||
return "AI" + GetStringAddress(AddressStart);
|
||||
return $"AI{GetStringAddress(AddressStart)}{(IsWString ? ";W=true;" : ";W=false;")}";
|
||||
}
|
||||
|
||||
if (DataCode == (byte)S7Area.AQ)
|
||||
{
|
||||
return "AQ" + GetStringAddress(AddressStart);
|
||||
return $"AQ{GetStringAddress(AddressStart)}{(IsWString ? ";W=true;" : ";W=false;")}";
|
||||
}
|
||||
|
||||
if (DataCode == (byte)S7Area.PE)
|
||||
{
|
||||
return "I" + GetStringAddress(AddressStart);
|
||||
return $"I{GetStringAddress(AddressStart)}{(IsWString ? ";W=true;" : ";W=false;")}";
|
||||
}
|
||||
|
||||
if (DataCode == (byte)S7Area.PA)
|
||||
{
|
||||
return "Q" + GetStringAddress(AddressStart);
|
||||
return $"Q{GetStringAddress(AddressStart)}{(IsWString ? ";W=true;" : ";W=false;")}";
|
||||
}
|
||||
|
||||
if (DataCode == (byte)S7Area.MK)
|
||||
{
|
||||
return "M" + GetStringAddress(AddressStart);
|
||||
return $"M{GetStringAddress(AddressStart)}{(IsWString ? ";W=true;" : ";W=false;")}";
|
||||
}
|
||||
|
||||
return DataCode == (byte)S7Area.DB ? "DB" + DbBlock.ToString() + "." + GetStringAddress(AddressStart) : Address.ToString();
|
||||
return DataCode == (byte)S7Area.DB ? $"DB{DbBlock.ToString()}.{GetStringAddress(AddressStart)}{(IsWString ? ";W=true;" : ";W=false;")}" : Address.ToString() + (IsWString ? ";W=true;" : ";W=false;");
|
||||
}
|
||||
|
||||
private static string GetStringAddress(int addressStart)
|
||||
{
|
||||
return addressStart % 8 == 0 ? (addressStart / 8).ToString() : string.Format("{0}.{1}", addressStart / 8, addressStart % 8);
|
||||
return addressStart % 8 == 0 ? (addressStart / 8).ToString() : $"{addressStart / 8}.{addressStart % 8}";
|
||||
}
|
||||
|
||||
}
|
@@ -10,8 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Siemens;
|
||||
|
||||
/// <summary>
|
||||
|
@@ -10,8 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Siemens;
|
||||
|
||||
internal static class PackHelper
|
||||
@@ -28,8 +26,7 @@ internal static class PackHelper
|
||||
|
||||
IThingsGatewayBitConverter transformParameter = ByteTransformUtil.GetTransByAddress(ref address, byteConverter);
|
||||
item.ThingsGatewayBitConverter = transformParameter;
|
||||
item.VariableAddress = address;//需要使用过滤后的地址
|
||||
|
||||
//item.VariableAddress = address;//需要使用过滤后的地址
|
||||
item.Index = siemensS7Net.GetBitOffset(item.VariableAddress);
|
||||
}
|
||||
//按读取间隔分组
|
||||
@@ -38,43 +35,55 @@ internal static class PackHelper
|
||||
{
|
||||
Dictionary<SiemensAddress, T2> map = item.ToDictionary(it =>
|
||||
{
|
||||
|
||||
var lastLen = it.DataTypeEnum.GetByteLength();
|
||||
if (lastLen <= 0)
|
||||
{
|
||||
switch (it.DataTypeEnum)
|
||||
{
|
||||
case DataTypeEnum.String:
|
||||
if (it.ThingsGatewayBitConverter.Length == null)
|
||||
{
|
||||
throw new("数据类型为字符串时,必须指定字符串长度,才能进行打包");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (siemensS7Net.CurrentPlc == SiemensEnum.S200Smart)
|
||||
{
|
||||
//字符串在S200Smart中,第一个字节不属于实际内容
|
||||
it.Index += 1;
|
||||
//it.ThingsGatewayBitConverter.StringLength -= 1;
|
||||
lastLen = it.ThingsGatewayBitConverter.Length.Value + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//字符串在S7中,前两个字节不属于实际内容
|
||||
it.Index += 2;
|
||||
//it.ThingsGatewayBitConverter.StringLength -= 2;
|
||||
lastLen = it.ThingsGatewayBitConverter.Length.Value + 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lastLen = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
var s7Address = SiemensAddress.ParseFrom(it.VariableAddress);
|
||||
var lastLen = it.DataTypeEnum.GetByteLength();
|
||||
if (lastLen <= 0)
|
||||
{
|
||||
switch (it.DataTypeEnum)
|
||||
{
|
||||
case DataTypeEnum.String:
|
||||
if (it.ThingsGatewayBitConverter.Length == null)
|
||||
{
|
||||
throw new("数据类型为字符串时,必须指定字符串长度,才能进行打包");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (siemensS7Net.CurrentPlc == SiemensEnum.S200Smart)
|
||||
{
|
||||
if (s7Address.IsWString)
|
||||
{
|
||||
//字符串在S200Smart中,第一个字节不属于实际内容
|
||||
it.Index += 1;
|
||||
lastLen = it.ThingsGatewayBitConverter.Length.Value + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastLen = it.ThingsGatewayBitConverter.Length.Value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s7Address.IsWString)
|
||||
{
|
||||
//字符串在S7中,前两个字节不属于实际内容
|
||||
it.Index += 2;
|
||||
lastLen = it.ThingsGatewayBitConverter.Length.Value + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastLen = it.ThingsGatewayBitConverter.Length.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lastLen = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((s7Address.DataCode == (byte)S7WordLength.Counter || s7Address.DataCode == (byte)S7WordLength.Timer) && lastLen == 1)
|
||||
{
|
||||
lastLen = 2;
|
||||
|
@@ -36,11 +36,42 @@ internal partial class SiemensHelper
|
||||
// return OperResult.CreateSuccessResult<byte[]>(numArray);
|
||||
//}
|
||||
|
||||
internal static OperResult<byte[]> AnalysisReadByte(byte[] sends, byte[] content)
|
||||
internal static OperResult<byte[], FilterResult> AnalysisReadByte(byte[] sends, byte[] content)
|
||||
{
|
||||
int length = 0;
|
||||
int itemLen = (sends.Length - 19) / 12;
|
||||
|
||||
//添加错误代码校验
|
||||
if (content[17] + content[18] > 0)
|
||||
{
|
||||
return new($"PLC返回错误,错误类型{content[17].ToString("X2")}错误代码:{content[18].ToString("X2")}")
|
||||
{
|
||||
Content2 = FilterResult.Success
|
||||
};
|
||||
}
|
||||
if (content.Length < 21)
|
||||
{
|
||||
return new($"长度不足")
|
||||
{
|
||||
Content2 = FilterResult.Cache
|
||||
};
|
||||
}
|
||||
if (content.Length < 25 + content[20])
|
||||
{
|
||||
return new($"长度不足")
|
||||
{
|
||||
Content2 = FilterResult.Cache
|
||||
};
|
||||
}
|
||||
//添加返回代码校验
|
||||
if (content[21] != 0xff)
|
||||
{
|
||||
return new($"PLC返回错误,返回代码{content[21].ToString("X2")}")
|
||||
{
|
||||
Content2 = FilterResult.Success
|
||||
};
|
||||
}
|
||||
|
||||
for (int index = 0; index < itemLen; index++)
|
||||
{
|
||||
if (sends[22 + (index * 12)] >= (byte)S7WordLength.Word)
|
||||
@@ -53,9 +84,9 @@ internal partial class SiemensHelper
|
||||
}
|
||||
}
|
||||
|
||||
if (content.Length < 21 || content[20] != itemLen)
|
||||
if (content[20] != itemLen)
|
||||
{
|
||||
return new OperResult<byte[]>("数据块长度校验失败");
|
||||
return new("数据块长度校验失败");
|
||||
}
|
||||
|
||||
byte[] dataArray = new byte[length];
|
||||
@@ -105,29 +136,39 @@ internal partial class SiemensHelper
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>((int)content[index2] + GetCpuError(content[index2]));
|
||||
return new((int)content[index2] + GetCpuError(content[index2]))
|
||||
{
|
||||
Content2 = FilterResult.Success
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return OperResult.CreateSuccessResult(dataArray);
|
||||
return OperResult.CreateSuccessResult(dataArray, FilterResult.Success);
|
||||
|
||||
}
|
||||
|
||||
internal static OperResult<byte[]> AnalysisWrite(byte[] content)
|
||||
internal static OperResult<byte[], FilterResult> AnalysisWrite(byte[] content)
|
||||
{
|
||||
if (content.Length < 22)
|
||||
{
|
||||
return new OperResult<byte[]>() { Message = "未知错误" };
|
||||
return new()
|
||||
{
|
||||
Message = "长度不足",
|
||||
Content2 = FilterResult.Success
|
||||
};
|
||||
}
|
||||
|
||||
byte err = content[21];
|
||||
if (err != byte.MaxValue)
|
||||
{
|
||||
return new OperResult<byte[]>((int)content[21] + GetCpuError(content[21]));
|
||||
return new($"错误代码:{(int)content[21]}描述:{GetCpuError(content[21])}")
|
||||
{
|
||||
Content2 = FilterResult.Success
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateSuccessResult(content);
|
||||
return OperResult.CreateSuccessResult(content, FilterResult.Success);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -10,7 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
@@ -68,7 +67,6 @@ namespace ThingsGateway.Foundation.Adapter.Siemens
|
||||
break;
|
||||
|
||||
}
|
||||
tcpClient.Connected += Connected;
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
@@ -125,34 +123,7 @@ namespace ThingsGateway.Foundation.Adapter.Siemens
|
||||
#region 设置
|
||||
|
||||
/// <summary>
|
||||
/// 远程TSAP,需重新连接
|
||||
/// </summary>
|
||||
public int DestTSAP
|
||||
{
|
||||
get
|
||||
{
|
||||
return
|
||||
_currentPlc == SiemensEnum.S200 || _currentPlc == SiemensEnum.S200Smart ?
|
||||
(ISO_CR[17] * 256) + ISO_CR[18] :
|
||||
(ISO_CR[20] * 256) + ISO_CR[21];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_currentPlc == SiemensEnum.S200 || _currentPlc == SiemensEnum.S200Smart)
|
||||
{
|
||||
ISO_CR[17] = BitConverter.GetBytes(value)[1];
|
||||
ISO_CR[18] = BitConverter.GetBytes(value)[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
ISO_CR[20] = BitConverter.GetBytes(value)[1];
|
||||
ISO_CR[21] = BitConverter.GetBytes(value)[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 本地TSAP,需重新连接
|
||||
/// 本地TSAP
|
||||
/// </summary>
|
||||
public int LocalTSAP
|
||||
{
|
||||
@@ -294,8 +265,8 @@ namespace ThingsGateway.Foundation.Adapter.Siemens
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter(object socketClient = null)
|
||||
{
|
||||
SiemensS7PLCDataHandleAdapter DataHandleAdapter = new();
|
||||
TcpClient.SetDataHandlingAdapter(DataHandleAdapter);
|
||||
SiemensS7PLCDataHandleAdapter dataHandleAdapter = new();
|
||||
TcpClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
|
||||
|
||||
@@ -477,17 +448,20 @@ namespace ThingsGateway.Foundation.Adapter.Siemens
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void Connected(ITcpClient client, ConnectedEventArgs e)
|
||||
/// <inheritdoc/>
|
||||
protected override async Task Connected(ITcpClient client, ConnectedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result1 = SendThenResponse(ISO_CR);
|
||||
NormalDataHandlingAdapter dataHandleAdapter = new();
|
||||
TcpClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
var result1 = await SendThenResponseAsync(ISO_CR);
|
||||
if (!result1.IsSuccess)
|
||||
{
|
||||
Logger?.Warning($"{client.IP} : {client.Port}:ISO_TP握手失败-{result1.Message}");
|
||||
return;
|
||||
}
|
||||
var result2 = SendThenResponse(S7_PN);
|
||||
var result2 = await SendThenResponseAsync(S7_PN);
|
||||
if (!result2.IsSuccess)
|
||||
{
|
||||
Logger?.Warning($"{client.IP} : {client.Port}:PDU初始化失败-{result2.Message}");
|
||||
@@ -500,7 +474,11 @@ namespace ThingsGateway.Foundation.Adapter.Siemens
|
||||
{
|
||||
Logger.Exception(ex);
|
||||
}
|
||||
|
||||
finally
|
||||
{
|
||||
SetDataAdapter();
|
||||
}
|
||||
await base.Connected(client, e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -35,10 +35,10 @@ public class SiemensS7PLCDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapte
|
||||
/// <inheritdoc/>
|
||||
protected override FilterResult UnpackResponse(SiemensMessage request, byte[] send, byte[] body, byte[] response)
|
||||
{
|
||||
var result = new OperResult<byte[]>();
|
||||
var result = new OperResult<byte[], FilterResult>();
|
||||
if (response[2] * 256 + response[3] == 7)
|
||||
{
|
||||
result = new OperResult<byte[]>() { Content = response };
|
||||
result = new() { Content = response, Content2 = FilterResult.Success };
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -56,6 +56,6 @@ public class SiemensS7PLCDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapte
|
||||
request.ErrorCode = result.ErrorCode;
|
||||
request.Message = result.Message;
|
||||
request.Content = result.Content;
|
||||
return FilterResult.Success;
|
||||
return result.Content2;
|
||||
}
|
||||
}
|
||||
|
@@ -10,8 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Siemens;
|
||||
|
@@ -0,0 +1,15 @@
|
||||
0x00 Reserved 未定义,预留
|
||||
|
||||
0x01 Hardware error 硬件错误
|
||||
|
||||
0x03 Accessing the object not allowed 对象不允许访问
|
||||
|
||||
0x05 Invalid address 无效地址,所需的地址超出此PLC的极限
|
||||
|
||||
0x06 Data type not supported 数据类型不支持
|
||||
|
||||
0x07 Data type inconsistent 日期类型不一致
|
||||
|
||||
0x0a Object does not exist 对象不存在
|
||||
|
||||
0xff Success 成功
|
@@ -0,0 +1,825 @@
|
||||
附录一:错误码具体含义
|
||||
|
||||
0x0000
|
||||
|
||||
没有错误
|
||||
|
||||
0x0110
|
||||
|
||||
块号无效
|
||||
|
||||
0x0111
|
||||
|
||||
请求长度无效
|
||||
|
||||
0x0112
|
||||
|
||||
参数无效
|
||||
|
||||
0x0113
|
||||
|
||||
块类型无效
|
||||
|
||||
0x0114
|
||||
|
||||
找不到块
|
||||
|
||||
0x0115
|
||||
|
||||
块已存在
|
||||
|
||||
0x0116
|
||||
|
||||
块被写保护
|
||||
|
||||
0x0117
|
||||
|
||||
块/操作系统更新太大
|
||||
|
||||
0x0118
|
||||
|
||||
块号无效
|
||||
|
||||
0x0119
|
||||
|
||||
输入的密码不正确
|
||||
|
||||
0x011A
|
||||
|
||||
PG资源错误
|
||||
|
||||
0x011B
|
||||
|
||||
PLC资源错误
|
||||
|
||||
0x011C
|
||||
|
||||
协议错误
|
||||
|
||||
0x011D
|
||||
|
||||
块太多(与模块相关的限制)
|
||||
|
||||
0x011E
|
||||
|
||||
不再与数据库建立连接,或者S7DOS句柄无效
|
||||
|
||||
0x011F
|
||||
|
||||
结果缓冲区太小
|
||||
|
||||
0x0120
|
||||
|
||||
块结束列表
|
||||
|
||||
0x0140
|
||||
|
||||
可用内存不足
|
||||
|
||||
0x0141
|
||||
|
||||
由于缺少资源,无法处理作业
|
||||
|
||||
0x8001
|
||||
|
||||
当块处于当前状态时,无法执行请求的服务
|
||||
|
||||
0x8003
|
||||
|
||||
S7协议错误:传输块时发生错误
|
||||
|
||||
0x8100
|
||||
|
||||
应用程序,一般错误:远程模块未知的服务
|
||||
|
||||
0x8104
|
||||
|
||||
未在模块上实现此服务或报告了帧错误
|
||||
|
||||
0x8204
|
||||
|
||||
对象的类型规范不一致
|
||||
|
||||
0x8205
|
||||
|
||||
复制的块已存在且未链接
|
||||
|
||||
0x8301
|
||||
|
||||
模块上的内存空间或工作内存不足,或者指定的存储介质不可访问
|
||||
|
||||
0x8302
|
||||
|
||||
可用资源太少或处理器资源不可用
|
||||
|
||||
0x8304
|
||||
|
||||
无法进一步并行上传。存在资源瓶颈
|
||||
|
||||
0x8305
|
||||
|
||||
功能不可用
|
||||
|
||||
0x8306
|
||||
|
||||
工作内存不足(用于复制,链接,加载AWP)
|
||||
|
||||
0x8307
|
||||
|
||||
保持性工作记忆不够(用于复制,链接,加载AWP)
|
||||
|
||||
0x8401
|
||||
|
||||
S7协议错误:无效的服务序列(例如,加载或上载块)
|
||||
|
||||
0x8402
|
||||
|
||||
由于寻址对象的状态,服务无法执行
|
||||
|
||||
0x8404
|
||||
|
||||
S7协议:无法执行该功能
|
||||
|
||||
0x8405
|
||||
|
||||
远程块处于DISABLE状态(CFB)。该功能无法执行
|
||||
|
||||
0x8500
|
||||
|
||||
S7协议错误:帧错误
|
||||
|
||||
0x8503
|
||||
|
||||
来自模块的警报:服务过早取消
|
||||
|
||||
0x8701
|
||||
|
||||
寻址通信伙伴上的对象时出错(例如,区域长度错误)
|
||||
|
||||
0x8702
|
||||
|
||||
模块不支持所请求的服务
|
||||
|
||||
0x8703
|
||||
|
||||
拒绝访问对象
|
||||
|
||||
0x8704
|
||||
|
||||
访问错误:对象已损坏
|
||||
|
||||
0xD001
|
||||
|
||||
协议错误:非法的作业号
|
||||
|
||||
0xD002
|
||||
|
||||
参数错误:非法的作业变体
|
||||
|
||||
0xD003
|
||||
|
||||
参数错误:模块不支持调试功能
|
||||
|
||||
0xD004
|
||||
|
||||
参数错误:作业状态非法
|
||||
|
||||
0xD005
|
||||
|
||||
参数错误:作业终止非法
|
||||
|
||||
0xD006
|
||||
|
||||
参数错误:非法链路断开ID
|
||||
|
||||
0xD007
|
||||
|
||||
参数错误:缓冲区元素数量非法
|
||||
|
||||
0xD008
|
||||
|
||||
参数错误:扫描速率非法
|
||||
|
||||
0xD009
|
||||
|
||||
参数错误:执行次数非法
|
||||
|
||||
0xD00A
|
||||
|
||||
参数错误:非法触发事件
|
||||
|
||||
0xD00B
|
||||
|
||||
参数错误:非法触发条件
|
||||
|
||||
0xD011
|
||||
|
||||
调用环境路径中的参数错误:块不存在
|
||||
|
||||
0xD012
|
||||
|
||||
参数错误:块中的地址错误
|
||||
|
||||
0xD014
|
||||
|
||||
参数错误:正在删除/覆盖块
|
||||
|
||||
0xD015
|
||||
|
||||
参数错误:标签地址非法
|
||||
|
||||
0xD016
|
||||
|
||||
参数错误:由于用户程序错误,无法测试作业
|
||||
|
||||
0xD017
|
||||
|
||||
参数错误:非法触发号
|
||||
|
||||
0xD025
|
||||
|
||||
参数错误:路径无效
|
||||
|
||||
0xD026
|
||||
|
||||
参数错误:非法访问类型
|
||||
|
||||
0xD027
|
||||
|
||||
参数错误:不允许此数据块数
|
||||
|
||||
0xD031
|
||||
|
||||
内部协议错误
|
||||
|
||||
0xD032
|
||||
|
||||
参数错误:结果缓冲区长度错误
|
||||
|
||||
0xD033
|
||||
|
||||
协议错误:作业长度错误
|
||||
|
||||
0xD03F
|
||||
|
||||
编码错误:参数部分出错(例如,保留字节不等于0)
|
||||
|
||||
0xD041
|
||||
|
||||
数据错误:非法状态列表ID
|
||||
|
||||
0xD042
|
||||
|
||||
数据错误:标签地址非法
|
||||
|
||||
0xD043
|
||||
|
||||
数据错误:找不到引用的作业,检查作业数据
|
||||
|
||||
0xD044
|
||||
|
||||
数据错误:标签值非法,检查作业数据
|
||||
|
||||
0xD045
|
||||
|
||||
数据错误:HOLD中不允许退出ODIS控制
|
||||
|
||||
0xD046
|
||||
|
||||
数据错误:运行时测量期间非法测量阶段
|
||||
|
||||
0xD047
|
||||
|
||||
数据错误:“读取作业列表”中的非法层次结构
|
||||
|
||||
0xD048
|
||||
|
||||
数据错误:“删除作业”中的非法删除ID
|
||||
|
||||
0xD049
|
||||
|
||||
“替换作业”中的替换ID无效
|
||||
|
||||
0xD04A
|
||||
|
||||
执行'程序状态'时出错
|
||||
|
||||
0xD05F
|
||||
|
||||
编码错误:数据部分出错(例如,保留字节不等于0,...)
|
||||
|
||||
0xD061
|
||||
|
||||
资源错误:没有作业的内存空间
|
||||
|
||||
0xD062
|
||||
|
||||
资源错误:作业列表已满
|
||||
|
||||
0xD063
|
||||
|
||||
资源错误:触发事件占用
|
||||
|
||||
0xD064
|
||||
|
||||
资源错误:没有足够的内存空间用于一个结果缓冲区元素
|
||||
|
||||
0xD065
|
||||
|
||||
资源错误:没有足够的内存空间用于多个结果缓冲区元素
|
||||
|
||||
0xD066
|
||||
|
||||
资源错误:可用于运行时测量的计时器被另一个作业占用
|
||||
|
||||
0xD067
|
||||
|
||||
资源错误:“修改标记”作业过多(特别是多处理器操作)
|
||||
|
||||
0xD081
|
||||
|
||||
当前模式下不允许使用的功能
|
||||
|
||||
0xD082
|
||||
|
||||
模式错误:无法退出HOLD模式
|
||||
|
||||
0xD0A1
|
||||
|
||||
当前保护级别不允许使用的功能
|
||||
|
||||
0xD0A2
|
||||
|
||||
目前无法运行,因为正在运行的函数会修改内存
|
||||
|
||||
0xD0A3
|
||||
|
||||
I / O上活动的“修改标记”作业太多(特别是多处理器操作)
|
||||
|
||||
0xD0A4
|
||||
|
||||
'强制'已经建立
|
||||
|
||||
0xD0A5
|
||||
|
||||
找不到引用的作业
|
||||
|
||||
0xD0A6
|
||||
|
||||
无法禁用/启用作业
|
||||
|
||||
0xD0A7
|
||||
|
||||
无法删除作业,例如因为当前正在读取作业
|
||||
|
||||
0xD0A8
|
||||
|
||||
无法替换作业,例如因为当前正在读取或删除作业
|
||||
|
||||
0xD0A9
|
||||
|
||||
无法读取作业,例如因为当前正在删除作业
|
||||
|
||||
0xD0AA
|
||||
|
||||
处理操作超出时间限制
|
||||
|
||||
0xD0AB
|
||||
|
||||
进程操作中的作业参数无效
|
||||
|
||||
0xD0AC
|
||||
|
||||
进程操作中的作业数据无效
|
||||
|
||||
0xD0AD
|
||||
|
||||
已设置操作模式
|
||||
|
||||
0xD0AE
|
||||
|
||||
作业是通过不同的连接设置的,只能通过此连接进行处理
|
||||
|
||||
0xD0C1
|
||||
|
||||
访问标签时至少检测到一个错误
|
||||
|
||||
0xD0C2
|
||||
|
||||
切换到STOP / HOLD模式
|
||||
|
||||
0xD0C3
|
||||
|
||||
访问标记时至少检测到一个错误。模式更改为STOP / HOLD
|
||||
|
||||
0xD0C4
|
||||
|
||||
运行时测量期间超时
|
||||
|
||||
0xD0C5
|
||||
|
||||
块堆栈的显示不一致,因为块被删除/重新加载
|
||||
|
||||
0xD0C6
|
||||
|
||||
作业已被删除,因为它所引用的作业已被删除
|
||||
|
||||
0xD0C7
|
||||
|
||||
由于退出了STOP模式,因此作业被自动删除
|
||||
|
||||
0xD0C8
|
||||
|
||||
由于测试作业和正在运行的程序之间不一致,“块状态”中止
|
||||
|
||||
0xD0C9
|
||||
|
||||
通过复位OB90退出状态区域
|
||||
|
||||
0xD0CA
|
||||
|
||||
通过在退出前重置OB90并访问错误读取标签退出状态范围
|
||||
|
||||
0xD0CB
|
||||
|
||||
外设输出的输出禁用再次激活
|
||||
|
||||
0xD0CC
|
||||
|
||||
调试功能的数据量受时间限制
|
||||
|
||||
0xD201
|
||||
|
||||
块名称中的语法错误
|
||||
|
||||
0xD202
|
||||
|
||||
函数参数中的语法错误
|
||||
|
||||
0xD205
|
||||
|
||||
RAM中已存在链接块:无法进行条件复制
|
||||
|
||||
0xD206
|
||||
|
||||
EPROM中已存在链接块:无法进行条件复制
|
||||
|
||||
0xD208
|
||||
|
||||
超出模块的最大复制(未链接)块数
|
||||
|
||||
0xD209
|
||||
|
||||
(至少)模块上找不到给定块之一
|
||||
|
||||
0xD20A
|
||||
|
||||
超出了可以与一个作业链接的最大块数
|
||||
|
||||
0xD20B
|
||||
|
||||
超出了一个作业可以删除的最大块数
|
||||
|
||||
0xD20C
|
||||
|
||||
OB无法复制,因为关联的优先级不存在
|
||||
|
||||
0xD20D
|
||||
|
||||
SDB无法解释(例如,未知数)
|
||||
|
||||
0xD20E
|
||||
|
||||
没有(进一步)阻止可用
|
||||
|
||||
0xD20F
|
||||
|
||||
超出模块特定的最大块大小
|
||||
|
||||
0xD210
|
||||
|
||||
块号无效
|
||||
|
||||
0xD212
|
||||
|
||||
标头属性不正确(与运行时相关)
|
||||
|
||||
0xD213
|
||||
|
||||
SDB太多。请注意对正在使用的模块的限制
|
||||
|
||||
0xD216
|
||||
|
||||
无效的用户程序 - 重置模块
|
||||
|
||||
0xD217
|
||||
|
||||
不允许在模块属性中指定的保护级别
|
||||
|
||||
0xD218
|
||||
|
||||
属性不正确(主动/被动)
|
||||
|
||||
0xD219
|
||||
|
||||
块长度不正确(例如,第一部分或整个块的长度不正确)
|
||||
|
||||
0xD21A
|
||||
|
||||
本地数据长度不正确或写保护错误
|
||||
|
||||
0xD21B
|
||||
|
||||
模块无法压缩或压缩早期中断
|
||||
|
||||
0xD21D
|
||||
|
||||
传输的动态项目数据量是非法的
|
||||
|
||||
0xD21E
|
||||
|
||||
无法为模块(例如FM,CP)分配参数。系统数据无法链接
|
||||
|
||||
0xD220
|
||||
|
||||
编程语言无效。请注意对正在使用的模块的限制
|
||||
|
||||
0xD221
|
||||
|
||||
连接或路由的系统数据无效
|
||||
|
||||
0xD222
|
||||
|
||||
全局数据定义的系统数据包含无效参数
|
||||
|
||||
0xD223
|
||||
|
||||
通信功能块的实例数据块错误或超出最大背景数据块数
|
||||
|
||||
0xD224
|
||||
|
||||
SCAN系统数据块包含无效参数
|
||||
|
||||
0xD225
|
||||
|
||||
DP系统数据块包含无效参数
|
||||
|
||||
0xD226
|
||||
|
||||
块中发生结构错误
|
||||
|
||||
0xD230
|
||||
|
||||
块中发生结构错误
|
||||
|
||||
0xD231
|
||||
|
||||
至少有一个已加载的OB无法复制,因为关联的优先级不存在
|
||||
|
||||
0xD232
|
||||
|
||||
加载块的至少一个块编号是非法的
|
||||
|
||||
0xD234
|
||||
|
||||
块在指定的内存介质或作业中存在两次
|
||||
|
||||
0xD235
|
||||
|
||||
该块包含不正确的校验和
|
||||
|
||||
0xD236
|
||||
|
||||
该块不包含校验和
|
||||
|
||||
0xD237
|
||||
|
||||
您将要加载块两次,即CPU上已存在具有相同时间戳的块
|
||||
|
||||
0xD238
|
||||
|
||||
指定的块中至少有一个不是DB
|
||||
|
||||
0xD239
|
||||
|
||||
至少有一个指定的DB在装载存储器中不可用作链接变量
|
||||
|
||||
0xD23A
|
||||
|
||||
至少有一个指定的DB与复制和链接的变体有很大不同
|
||||
|
||||
0xD240
|
||||
|
||||
违反了协调规则
|
||||
|
||||
0xD241
|
||||
|
||||
当前保护级别不允许该功能
|
||||
|
||||
0xD242
|
||||
|
||||
处理F块时的保护冲突
|
||||
|
||||
0xD250
|
||||
|
||||
更新和模块ID或版本不匹配
|
||||
|
||||
0xD251
|
||||
|
||||
操作系统组件序列不正确
|
||||
|
||||
0xD252
|
||||
|
||||
校验和错误
|
||||
|
||||
0xD253
|
||||
|
||||
没有可用的可执行加载程序; 只能使用存储卡进行更新
|
||||
|
||||
0xD254
|
||||
|
||||
操作系统中的存储错误
|
||||
|
||||
0xD280
|
||||
|
||||
在S7-300 CPU中编译块时出错
|
||||
|
||||
0xD2A1
|
||||
|
||||
块上的另一个块功能或触发器处于活动状态
|
||||
|
||||
0xD2A2
|
||||
|
||||
块上的触发器处于活动状态。首先完成调试功能
|
||||
|
||||
0xD2A3
|
||||
|
||||
块未激活(链接),块被占用或块当前被标记为删除
|
||||
|
||||
0xD2A4
|
||||
|
||||
该块已被另一个块函数处理
|
||||
|
||||
0xD2A6
|
||||
|
||||
无法同时保存和更改用户程序
|
||||
|
||||
0xD2A7
|
||||
|
||||
块具有“未链接”属性或未处理
|
||||
|
||||
0xD2A8
|
||||
|
||||
激活的调试功能阻止将参数分配给CPU
|
||||
|
||||
0xD2A9
|
||||
|
||||
正在为CPU分配新参数
|
||||
|
||||
0xD2AA
|
||||
|
||||
当前正在为模块分配新参数
|
||||
|
||||
0xD2AB
|
||||
|
||||
当前正在更改动态配置限制
|
||||
|
||||
0xD2AC
|
||||
|
||||
正在运行的激活或取消激活分配(SFC 12)暂时阻止R-KiR过程
|
||||
|
||||
0xD2B0
|
||||
|
||||
在RUN(CiR)中配置时发生错误
|
||||
|
||||
0xD2C0
|
||||
|
||||
已超出最大工艺对象数
|
||||
|
||||
0xD2C1
|
||||
|
||||
模块上已存在相同的技术数据块
|
||||
|
||||
0xD2C2
|
||||
|
||||
无法下载用户程序或下载硬件配置
|
||||
|
||||
0xD401
|
||||
|
||||
信息功能不可用
|
||||
|
||||
0xD402
|
||||
|
||||
信息功能不可用
|
||||
|
||||
0xD403
|
||||
|
||||
服务已登录/注销(诊断/ PMC)
|
||||
|
||||
0xD404
|
||||
|
||||
达到的最大节点数。不再需要登录诊断/ PMC
|
||||
|
||||
0xD405
|
||||
|
||||
不支持服务或函数参数中的语法错误
|
||||
|
||||
0xD406
|
||||
|
||||
当前不可用的必需信息
|
||||
|
||||
0xD407
|
||||
|
||||
发生诊断错误
|
||||
|
||||
0xD408
|
||||
|
||||
更新已中止
|
||||
|
||||
0xD409
|
||||
|
||||
DP总线错误
|
||||
|
||||
0xD601
|
||||
|
||||
函数参数中的语法错误
|
||||
|
||||
0xD602
|
||||
|
||||
输入的密码不正确
|
||||
|
||||
0xD603
|
||||
|
||||
连接已合法化
|
||||
|
||||
0xD604
|
||||
|
||||
已启用连接
|
||||
|
||||
0xD605
|
||||
|
||||
由于密码不存在,因此无法进行合法化
|
||||
|
||||
0xD801
|
||||
|
||||
至少有一个标记地址无效
|
||||
|
||||
0xD802
|
||||
|
||||
指定的作业不存在
|
||||
|
||||
0xD803
|
||||
|
||||
非法的工作状态
|
||||
|
||||
0xD804
|
||||
|
||||
非法循环时间(非法时基或多个)
|
||||
|
||||
0xD805
|
||||
|
||||
不能再设置循环读取作业
|
||||
|
||||
0xD806
|
||||
|
||||
引用的作业处于无法执行请求的功能的状态
|
||||
|
||||
0xD807
|
||||
|
||||
功能因过载而中止,这意味着执行读取周期所需的时间比设置的扫描周期时间长
|
||||
|
||||
0xDC01
|
||||
|
||||
日期和/或时间无效
|
||||
|
||||
0xE201
|
||||
|
||||
CPU已经是主设备
|
||||
|
||||
0xE202
|
||||
|
||||
由于闪存模块中的用户程序不同,无法进行连接和更新
|
||||
|
||||
0xE203
|
||||
|
||||
由于固件不同,无法连接和更新
|
||||
|
||||
0xE204
|
||||
|
||||
由于内存配置不同,无法连接和更新
|
||||
|
||||
0xE205
|
||||
|
||||
由于同步错误导致连接/更新中止
|
||||
|
||||
0xE206
|
||||
|
||||
由于协调违规而拒绝连接/更新
|
||||
|
||||
0xEF01
|
||||
|
||||
S7协议错误:ID2错误; 工作中只允许00H
|
||||
|
||||
0xEF02
|
||||
|
||||
S7协议错误:ID2错误; 资源集不存在
|
@@ -1,336 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>ThingsGateway.Foundation.Adapter.Siemens</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.S7Area">
|
||||
<summary>
|
||||
区域
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.PE">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.PA">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.MK">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.DB">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.CT">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.TM">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.AI">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.AQ">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress">
|
||||
<summary>
|
||||
西门子PLC地址数据信息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.BitCode">
|
||||
<summary>
|
||||
bit位偏移
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.DataCode">
|
||||
<summary>
|
||||
数据块代码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.DbBlock">
|
||||
<summary>
|
||||
DB块数据信息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.GetAddressStart(System.String,System.Boolean)">
|
||||
<summary>
|
||||
获取起始地址
|
||||
</summary>
|
||||
<param name="address"></param>
|
||||
<param name="isCounterOrTimer"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.GetBitCode(System.String)">
|
||||
<summary>
|
||||
获取bit
|
||||
</summary>
|
||||
<param name="address"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.ParseFrom(System.String)">
|
||||
<summary>
|
||||
解析地址
|
||||
</summary>
|
||||
<param name="address"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.ParseFrom(System.String,System.Int32)">
|
||||
<summary>
|
||||
解析地址
|
||||
</summary>
|
||||
<param name="address"></param>
|
||||
<param name="length"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.Parse(System.String,System.Int32)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.ToString">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.DateTime">
|
||||
<summary>
|
||||
https://github.com/S7NetPlus/s7netplus/blob/develop/S7.Net/Types/DateTime.cs
|
||||
Contains the methods to convert between <see cref="T:System.DateTime"/> and S7 representation of datetime values.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.DateTime.SpecMaximumDateTime">
|
||||
<summary>
|
||||
The maximum <see cref="T:System.DateTime"/> value supported by the specification.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.DateTime.SpecMinimumDateTime">
|
||||
<summary>
|
||||
The minimum <see cref="T:System.DateTime"/> value supported by the specification.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.DateTime.FromByteArray(System.Byte[])">
|
||||
<summary>
|
||||
Parses a <see cref="T:System.DateTime"/> value from bytes.
|
||||
</summary>
|
||||
<param name="bytes">Input bytes read from PLC.</param>
|
||||
<returns>A <see cref="T:System.DateTime"/> object representing the value read from PLC.</returns>
|
||||
<exception cref="T:System.ArgumentOutOfRangeException">Thrown when the length of
|
||||
<paramref name="bytes"/> is not 8 or any value in <paramref name="bytes"/>
|
||||
is outside the valid range of values.</exception>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.DateTime.ToArray(System.Byte[])">
|
||||
<summary>
|
||||
Parses an array of <see cref="T:System.DateTime"/> values from bytes.
|
||||
</summary>
|
||||
<param name="bytes">Input bytes read from PLC.</param>
|
||||
<returns>An array of <see cref="T:System.DateTime"/> objects representing the values read from PLC.</returns>
|
||||
<exception cref="T:System.ArgumentOutOfRangeException">Thrown when the length of
|
||||
<paramref name="bytes"/> is not a multiple of 8 or any value in
|
||||
<paramref name="bytes"/> is outside the valid range of values.</exception>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.DateTime.ToByteArray(System.DateTime)">
|
||||
<summary>
|
||||
Converts a <see cref="T:System.DateTime"/> value to a byte array.
|
||||
</summary>
|
||||
<param name="dateTime">The DateTime value to convert.</param>
|
||||
<returns>A byte array containing the S7 date time representation of <paramref name="dateTime"/>.</returns>
|
||||
<exception cref="T:System.ArgumentOutOfRangeException">Thrown when the value of
|
||||
<paramref name="dateTime"/> is before <see cref="P:SpecMinimumDateTime"/>
|
||||
or after <see cref="P:SpecMaximumDateTime"/>.</exception>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.DateTime.ToByteArray(System.DateTime[])">
|
||||
<summary>
|
||||
Converts an array of <see cref="T:System.DateTime"/> values to a byte array.
|
||||
</summary>
|
||||
<param name="dateTimes">The DateTime values to convert.</param>
|
||||
<returns>A byte array containing the S7 date time representations of <paramref name="dateTimes"/>.</returns>
|
||||
<exception cref="T:System.ArgumentOutOfRangeException">Thrown when any value of
|
||||
<paramref name="dateTimes"/> is before <see cref="P:SpecMinimumDateTime"/>
|
||||
or after <see cref="P:SpecMaximumDateTime"/>.</exception>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensHelper.S7_MULRW_HEADER">
|
||||
<summary>
|
||||
S7连读写请求头(包含ISO头和COTP头)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Bit">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Byte">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Char">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Word">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Int">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.DWord">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.DInt">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Real">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Counter">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Timer">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.SiemensMessage">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensMessage.HeadBytesLength">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensMessage.CheckHeadBytes(System.Byte[])">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S200">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S200Smart">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S300">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S400">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S1200">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S1500">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC">
|
||||
<summary>
|
||||
相关命令含义源自网络资料/Shrap7/s7netplus
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.#ctor(ThingsGateway.Foundation.TcpClient,ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum)">
|
||||
<summary>
|
||||
传入PLC类型,程序内会改变相应PLC类型的S7协议LocalTSAP, RemoteTSAP等
|
||||
</summary>
|
||||
<param name="tcpClient"></param>
|
||||
<param name="siemensPLCEnum"></param>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.CurrentPlc">
|
||||
<summary>
|
||||
当前PLC类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.GetAddressDescription">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.GetBitOffset(System.String)">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
<param name="address"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.DestTSAP">
|
||||
<summary>
|
||||
远程TSAP,需重新连接
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.LocalTSAP">
|
||||
<summary>
|
||||
本地TSAP,需重新连接
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.PDULength">
|
||||
<summary>
|
||||
PDULength
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.Rack">
|
||||
<summary>
|
||||
机架号,需重新连接
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.Slot">
|
||||
<summary>
|
||||
槽号,需重新连接
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.ReadDateAsync(System.String,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
读取日期
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.ReadDateTimeAsync(System.String,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
读取时间
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.ReadStringAsync(System.String,System.Text.Encoding,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
读取变长字符串
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.SetDataAdapter">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.WriteAsync(System.String,System.String,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.WriteDateAsync(System.String,System.DateTime,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
写入日期
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.WriteDateTimeAsync(System.String,System.DateTime,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
写入时间
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLCDataHandleAdapter">
|
||||
<summary>
|
||||
SiemensS7PLCDataHandleAdapter
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLCDataHandleAdapter.PackCommand(System.Byte[])">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLCDataHandleAdapter.GetInstance">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLCDataHandleAdapter.UnpackResponse(ThingsGateway.Foundation.Adapter.Siemens.SiemensMessage,System.Byte[],System.Byte[],System.Byte[])">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
@@ -10,7 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 设备地址数据的信息,对每个协议都建立其变量地址的表示类
|
||||
|
@@ -10,7 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 打包读取变量
|
||||
|
@@ -10,7 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
/// <summary>
|
||||
/// 打包读取变量
|
||||
/// </summary>
|
||||
|
@@ -10,7 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 设备读写接口
|
||||
|
@@ -15,7 +15,7 @@ using System.Text;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.String;
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 读写扩展方法
|
||||
|
@@ -10,7 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// TCP读写设备
|
||||
@@ -24,8 +24,8 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
|
||||
public ReadWriteDevicesSerialSessionBase(SerialSession serialSession)
|
||||
{
|
||||
SerialSession = serialSession;
|
||||
WaitingClientEx = SerialSession.GetWaitingClientEx(new() { BreakTrigger = true });
|
||||
SerialSession.Received += Received;
|
||||
WaitingClientEx = SerialSession.CreateWaitingClient(new() { });
|
||||
SerialSession.Received -= Received;
|
||||
SerialSession.Connecting -= Connecting;
|
||||
SerialSession.Connected -= Connected;
|
||||
SerialSession.Disconnecting -= Disconnecting;
|
||||
@@ -34,26 +34,21 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
|
||||
SerialSession.Connected += Connected;
|
||||
SerialSession.Disconnecting += Disconnecting;
|
||||
SerialSession.Disconnected += Disconnected;
|
||||
SerialSession.Received += Received;
|
||||
Logger = SerialSession.Logger;
|
||||
}
|
||||
/// <summary>
|
||||
/// 接收解析
|
||||
/// </summary>
|
||||
protected virtual void Received(ByteBlock byteBlock, IRequestInfo requestInfo)
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Task Received(SerialSession client, ReceivedDataEventArgs e)
|
||||
{
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
private void Received(SerialSession client, ByteBlock byteBlock, IRequestInfo requestInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
Received(byteBlock, requestInfo);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Exception(this, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 串口管理对象
|
||||
@@ -86,11 +81,12 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
|
||||
/// <inheritdoc/>
|
||||
public override void Dispose()
|
||||
{
|
||||
Disconnect();
|
||||
SerialSession.Received -= Received;
|
||||
SerialSession.Connecting -= Connecting;
|
||||
SerialSession.Connected -= Connected;
|
||||
SerialSession.Disconnecting -= Disconnecting;
|
||||
SerialSession.Disconnected -= Disconnected;
|
||||
Disconnect();
|
||||
if (CascadeDisposal)
|
||||
SerialSession.SafeDispose();
|
||||
}
|
||||
@@ -100,8 +96,8 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
|
||||
{
|
||||
try
|
||||
{
|
||||
waitingOptions ??= new WaitingOptions { BreakTrigger = true, ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
|
||||
ResponsedData result = SerialSession.GetWaitingClientEx(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
|
||||
waitingOptions ??= new WaitingOptions { };
|
||||
ResponsedData result = SerialSession.CreateWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
|
||||
return OperResult.CreateSuccessResult(result.Data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -115,8 +111,8 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
|
||||
{
|
||||
try
|
||||
{
|
||||
waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
|
||||
ResponsedData result = await SerialSession.GetWaitingClientEx(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
|
||||
waitingOptions ??= new WaitingOptions { };
|
||||
ResponsedData result = await SerialSession.CreateWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
|
||||
return OperResult.CreateSuccessResult(result.Data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -130,24 +126,34 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
|
||||
{
|
||||
return SerialSession.SerialProperty.ToString();
|
||||
}
|
||||
private void Connected(ISerialSession client, ConnectedEventArgs e)
|
||||
/// <summary>
|
||||
/// Connected
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Task Connected(ISerialSession client, ConnectedEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.SerialProperty.ToString() + "连接成功");
|
||||
SetDataAdapter();
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private void Connecting(ISerialSession client, SerialConnectingEventArgs e)
|
||||
private Task Connecting(ISerialSession client, SerialConnectingEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.SerialProperty.ToString() + "正在连接");
|
||||
SetDataAdapter();
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private void Disconnected(ISerialSessionBase client, DisconnectEventArgs e)
|
||||
private Task Disconnected(ISerialSessionBase client, DisconnectEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.SerialProperty.ToString() + "断开连接-" + e.Message);
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private void Disconnecting(ISerialSessionBase client, DisconnectEventArgs e)
|
||||
private Task Disconnecting(ISerialSessionBase client, DisconnectEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.SerialProperty.ToString() + "正在主动断开连接-" + e.Message);
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
}
|
@@ -12,7 +12,7 @@
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// TCP读写设备
|
||||
@@ -23,7 +23,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
|
||||
public ReadWriteDevicesTcpClientBase(TcpClient tcpClient)
|
||||
{
|
||||
TcpClient = tcpClient;
|
||||
WaitingClientEx = TcpClient.GetWaitingClientEx(new() { BreakTrigger = true });
|
||||
WaitingClientEx = TcpClient.CreateWaitingClient(new() { });
|
||||
TcpClient.Connecting -= Connecting;
|
||||
TcpClient.Connected -= Connected;
|
||||
TcpClient.Disconnecting -= Disconnecting;
|
||||
@@ -59,7 +59,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
|
||||
/// <inheritdoc/>
|
||||
public override Task ConnectAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return TcpClient.ConnectAsync(ConnectTimeOut);
|
||||
return TcpClient.ConnectAsync(ConnectTimeOut, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -72,11 +72,11 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
|
||||
/// <inheritdoc/>
|
||||
public override void Dispose()
|
||||
{
|
||||
Disconnect();
|
||||
TcpClient.Connecting -= Connecting;
|
||||
TcpClient.Connected -= Connected;
|
||||
TcpClient.Disconnecting -= Disconnecting;
|
||||
TcpClient.Disconnected -= Disconnected;
|
||||
Disconnect();
|
||||
if (CascadeDisposal)
|
||||
TcpClient.SafeDispose();
|
||||
}
|
||||
@@ -86,8 +86,8 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
|
||||
{
|
||||
try
|
||||
{
|
||||
waitingOptions ??= new WaitingOptions { BreakTrigger = true, ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
|
||||
ResponsedData result = TcpClient.GetWaitingClientEx(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
|
||||
waitingOptions ??= new WaitingOptions { };
|
||||
ResponsedData result = TcpClient.CreateWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
|
||||
return OperResult.CreateSuccessResult(result.Data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -101,8 +101,8 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
|
||||
{
|
||||
try
|
||||
{
|
||||
waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
|
||||
ResponsedData result = await TcpClient.GetWaitingClientEx(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
|
||||
waitingOptions ??= new WaitingOptions { };
|
||||
ResponsedData result = await TcpClient.CreateWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
|
||||
return OperResult.CreateSuccessResult(result.Data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -116,24 +116,34 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
|
||||
{
|
||||
return TcpClient.RemoteIPHost.ToString();
|
||||
}
|
||||
private void Connected(ITcpClient client, ConnectedEventArgs e)
|
||||
/// <summary>
|
||||
/// Connected
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Task Connected(ITcpClient client, ConnectedEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.RemoteIPHost.ToString() + "连接成功");
|
||||
SetDataAdapter();
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private void Connecting(ITcpClient client, ConnectingEventArgs e)
|
||||
private Task Connecting(ITcpClient client, ConnectingEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.RemoteIPHost.ToString() + "正在连接");
|
||||
SetDataAdapter();
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private void Disconnected(ITcpClientBase client, DisconnectEventArgs e)
|
||||
private Task Disconnected(ITcpClientBase client, DisconnectEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.IP + ":" + client.Port + "断开连接-" + e.Message);
|
||||
Logger?.Debug($"{client.IP}:{client.Port}断开连接-{e.Message}");
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private void Disconnecting(ITcpClientBase client, DisconnectEventArgs e)
|
||||
private Task Disconnecting(ITcpClientBase client, DisconnectEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.IP + ":" + client.Port + "正在主动断开连接-" + e.Message);
|
||||
Logger?.Debug($"{client.IP}:{client.Port}正在主动断开连接-{e.Message}");
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
}
|
@@ -12,7 +12,7 @@
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 服务设备
|
||||
@@ -23,9 +23,14 @@ public abstract class ReadWriteDevicesTcpServerBase : ReadWriteDevicesBase
|
||||
public ReadWriteDevicesTcpServerBase(TcpService tcpService)
|
||||
{
|
||||
TcpService = tcpService;
|
||||
TcpService.Received -= Received;
|
||||
TcpService.Connecting -= Connecting;
|
||||
TcpService.Connected -= Connected;
|
||||
TcpService.Disconnecting -= Disconnecting;
|
||||
TcpService.Disconnected -= Disconnected;
|
||||
TcpService.Received += Received;
|
||||
TcpService.Connecting += Connecting;
|
||||
TcpService.Connected += Connected;
|
||||
TcpService.Received += Received;
|
||||
TcpService.Disconnecting += Disconnecting;
|
||||
TcpService.Disconnected += Disconnected;
|
||||
Logger = TcpService.Logger;
|
||||
@@ -50,7 +55,8 @@ public abstract class ReadWriteDevicesTcpServerBase : ReadWriteDevicesBase
|
||||
/// <inheritdoc/>
|
||||
public override Task ConnectAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.Run(() => TcpService.Start());
|
||||
Connect(cancellationToken);
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -63,65 +69,63 @@ public abstract class ReadWriteDevicesTcpServerBase : ReadWriteDevicesBase
|
||||
/// <inheritdoc/>
|
||||
public override void Dispose()
|
||||
{
|
||||
Disconnect();
|
||||
TcpService.Received -= Received;
|
||||
TcpService.Connecting -= Connecting;
|
||||
TcpService.Connected -= Connected;
|
||||
TcpService.Disconnecting -= Disconnecting;
|
||||
TcpService.Disconnected -= Disconnected;
|
||||
Disconnect();
|
||||
if (CascadeDisposal)
|
||||
TcpService.SafeDispose();
|
||||
}
|
||||
/// <summary>
|
||||
/// 接收解析
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Task Received(SocketClient client, ReceivedDataEventArgs e)
|
||||
{
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return TcpService.ServerName;
|
||||
}
|
||||
/// <summary>
|
||||
/// 接收解析
|
||||
/// </summary>
|
||||
protected virtual void Received(SocketClient client, IRequestInfo requestInfo)
|
||||
{
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void Connected(SocketClient client, ConnectedEventArgs e)
|
||||
protected virtual Task Connected(SocketClient client, ConnectedEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.IP + ":" + client.Port + "连接成功");
|
||||
Logger?.Debug($"{client.IP}:{client.Port}连接成功");
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected virtual void Connecting(SocketClient client, ConnectingEventArgs e)
|
||||
protected virtual Task Connecting(SocketClient client, ConnectingEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.IP + ":" + client.Port + "正在连接");
|
||||
Logger?.Debug($"{client.IP}:{client.Port}正在连接");
|
||||
SetDataAdapter(client);
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected virtual void Disconnected(ITcpClientBase client, DisconnectEventArgs e)
|
||||
protected virtual Task Disconnected(ITcpClientBase client, DisconnectEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.IP + ":" + client.Port + "断开连接-" + e.Message);
|
||||
Logger?.Debug($"{client.IP}:{client.Port}断开连接-{e.Message}");
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected virtual void Disconnecting(ITcpClientBase client, DisconnectEventArgs e)
|
||||
protected virtual Task Disconnecting(ITcpClientBase client, DisconnectEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.IP + ":" + client.Port + "正在主动断开连接-" + e.Message);
|
||||
Logger?.Debug($"{client.IP}:{client.Port}正在主动断开连接-{e.Message}");
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private void Received(SocketClient client, ByteBlock byteBlock, IRequestInfo requestInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
Received(client, requestInfo);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Exception(this, ex);
|
||||
}
|
||||
}
|
||||
}
|
@@ -10,7 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// UDP读写设备
|
||||
@@ -22,7 +22,7 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase
|
||||
{
|
||||
UdpSession = udpSession;
|
||||
SetDataAdapter();
|
||||
WaitingClientEx = UdpSession.GetWaitingClientEx(new() { BreakTrigger = true });
|
||||
WaitingClientEx = UdpSession.CreateWaitingClient(new() { });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -64,8 +64,8 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase
|
||||
{
|
||||
try
|
||||
{
|
||||
waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
|
||||
ResponsedData result = UdpSession.GetWaitingClientEx(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
|
||||
waitingOptions ??= new WaitingOptions { };
|
||||
ResponsedData result = UdpSession.CreateWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
|
||||
return OperResult.CreateSuccessResult(result.Data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -79,8 +79,8 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase
|
||||
{
|
||||
try
|
||||
{
|
||||
waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
|
||||
ResponsedData result = await UdpSession.GetWaitingClientEx(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
|
||||
waitingOptions ??= new WaitingOptions { };
|
||||
ResponsedData result = await UdpSession.CreateWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
|
||||
return OperResult.CreateSuccessResult(result.Data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@@ -12,7 +12,7 @@
|
||||
|
||||
using System.Collections;
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 线程安全的LinkedList
|
||||
|
@@ -10,7 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// HSL摘录,用于CRC16验证的类
|
||||
|
@@ -10,7 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 自增
|
||||
|
@@ -10,7 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// EasyLock,使用轻量级SemaphoreSlim锁,只允许一个并发量,并记录并发信息
|
||||
@@ -20,6 +20,12 @@ public sealed class EasyLock
|
||||
private static long lockWaitCount;
|
||||
private readonly SemaphoreSlim m_waiterLock = new SemaphoreSlim(1);
|
||||
/// <inheritdoc/>
|
||||
public EasyLock(bool initialState = true)
|
||||
{
|
||||
if (!initialState)
|
||||
m_waiterLock.Wait();
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
~EasyLock()
|
||||
{
|
||||
m_waiterLock.SafeDispose();
|
||||
@@ -45,39 +51,41 @@ public sealed class EasyLock
|
||||
/// <summary>
|
||||
/// 进入锁
|
||||
/// </summary>
|
||||
public void Wait()
|
||||
public void Wait(CancellationToken cancellationToken = default)
|
||||
{
|
||||
Interlocked.Increment(ref lockWaitCount);
|
||||
m_waiterLock.Wait();
|
||||
m_waiterLock.Wait(cancellationToken);
|
||||
Interlocked.Decrement(ref lockWaitCount);
|
||||
}
|
||||
/// <summary>
|
||||
/// 进入锁
|
||||
/// </summary>
|
||||
public void Wait(TimeSpan timeSpan, CancellationToken cancellationToken)
|
||||
public bool Wait(TimeSpan timeSpan, CancellationToken cancellationToken)
|
||||
{
|
||||
Interlocked.Increment(ref lockWaitCount);
|
||||
m_waiterLock.Wait(timeSpan, cancellationToken);
|
||||
var data = m_waiterLock.Wait(timeSpan, cancellationToken);
|
||||
Interlocked.Decrement(ref lockWaitCount);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 进入锁
|
||||
/// </summary>
|
||||
public async Task WaitAsync()
|
||||
public async Task WaitAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
Interlocked.Increment(ref lockWaitCount);
|
||||
await m_waiterLock.WaitAsync();
|
||||
await m_waiterLock.WaitAsync(cancellationToken);
|
||||
Interlocked.Decrement(ref lockWaitCount);
|
||||
}
|
||||
/// <summary>
|
||||
/// 进入锁
|
||||
/// </summary>
|
||||
public async Task WaitAsync(TimeSpan timeSpan, CancellationToken cancellationToken)
|
||||
public async Task<bool> WaitAsync(TimeSpan timeSpan, CancellationToken cancellationToken)
|
||||
{
|
||||
Interlocked.Increment(ref lockWaitCount);
|
||||
await m_waiterLock.WaitAsync(timeSpan, cancellationToken);
|
||||
var data = await m_waiterLock.WaitAsync(timeSpan, cancellationToken);
|
||||
Interlocked.Decrement(ref lockWaitCount);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
@@ -10,7 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// TimerTick
|
||||
|
@@ -10,7 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 常量
|
||||
|
@@ -10,15 +10,21 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// TCP/Serial适配器基类
|
||||
/// </summary>
|
||||
public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDataHandlingAdapter<TRequest> where TRequest : class, IMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// 报文输出时采用字符串还是HexString
|
||||
/// </summary>
|
||||
public virtual bool IsHexData { get; set; } = true;
|
||||
/// <inheritdoc cref="ReadWriteDevicesTcpDataHandleAdapter{TRequest}"/>
|
||||
public ReadWriteDevicesTcpDataHandleAdapter()
|
||||
{
|
||||
@@ -46,7 +52,7 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
|
||||
{
|
||||
//获取全部内容
|
||||
var allBytes = byteBlock.ToArray(0, byteBlock.Len);
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 接收:{allBytes.ToHexString(' ')}");
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 接收:{(IsHexData ? allBytes.ToHexString(' ') : Encoding.UTF8.GetString(allBytes))}");
|
||||
//缓存/不缓存解析一样,因为游标已经归0
|
||||
{
|
||||
request = Request;
|
||||
@@ -131,7 +137,7 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
|
||||
/// <summary>
|
||||
/// 发送方法,会重新建立<see cref="Request"/>
|
||||
/// </summary>
|
||||
protected void GoSend(byte[] item)
|
||||
protected virtual void GoSend(byte[] item)
|
||||
{
|
||||
byte[] bytes;
|
||||
if (IsSendPackCommand)
|
||||
@@ -141,7 +147,22 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
|
||||
Request = GetInstance();
|
||||
Request.SendBytes = bytes;
|
||||
GoSend(bytes, 0, bytes.Length);
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{Request.SendBytes.ToHexString(' ')}");
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{(IsHexData ? Request.SendBytes.ToHexString(' ') : Encoding.UTF8.GetString(Request.SendBytes))}");
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送方法,会重新建立<see cref="Request"/>
|
||||
/// </summary>
|
||||
protected virtual async Task GoSendAsync(byte[] item)
|
||||
{
|
||||
byte[] bytes;
|
||||
if (IsSendPackCommand)
|
||||
bytes = PackCommand(item);
|
||||
else
|
||||
bytes = item;
|
||||
Request = GetInstance();
|
||||
Request.SendBytes = bytes;
|
||||
await GoSendAsync(bytes, 0, bytes.Length);
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{(IsHexData ? Request.SendBytes.ToHexString(' ') : Encoding.UTF8.GetString(Request.SendBytes))}");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -150,6 +171,12 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
|
||||
GoSend(buffer);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Task PreviewSendAsync(byte[] buffer, int offset, int length)
|
||||
{
|
||||
return GoSendAsync(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 报文拆包
|
||||
/// </summary>
|
||||
@@ -159,6 +186,13 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return Owner.ToString();
|
||||
if (Owner is SocketClient client)
|
||||
{
|
||||
return client.GetIPPort();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Owner.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@@ -11,16 +11,24 @@
|
||||
#endregion
|
||||
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// UDP适配器基类
|
||||
/// </summary>
|
||||
public abstract class ReadWriteDevicesUdpDataHandleAdapter<TRequest> : UdpDataHandlingAdapter where TRequest : class, IMessage
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 报文输出时采用字符串还是HexString
|
||||
/// </summary>
|
||||
public virtual bool IsHexData { get; set; } = true;
|
||||
|
||||
/// <inheritdoc cref="ReadWriteDevicesUdpDataHandleAdapter{TRequest}"/>
|
||||
public ReadWriteDevicesUdpDataHandleAdapter()
|
||||
{
|
||||
@@ -68,13 +76,13 @@ public abstract class ReadWriteDevicesUdpDataHandleAdapter<TRequest> : UdpDataHa
|
||||
Request = GetInstance();
|
||||
Request.SendBytes = bytes;
|
||||
GoSend(endPoint, bytes, 0, bytes.Length);
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{Request.SendBytes.ToHexString(' ')}");
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{(IsHexData ? Request.SendBytes.ToHexString(' ') : Encoding.UTF8.GetString(Request.SendBytes))}");
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
protected override void PreviewReceived(EndPoint remoteEndPoint, ByteBlock byteBlock)
|
||||
{
|
||||
var allBytes = byteBlock.ToArray(0, byteBlock.Len);
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 接收:{allBytes.ToHexString(' ')}");
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 接收:{(IsHexData ? allBytes.ToHexString(' ') : Encoding.UTF8.GetString(allBytes))}");
|
||||
|
||||
if (Request?.SendBytes == null)
|
||||
{
|
||||
@@ -128,11 +136,6 @@ public abstract class ReadWriteDevicesUdpDataHandleAdapter<TRequest> : UdpDataHa
|
||||
{
|
||||
throw new System.NotImplementedException();//因为设置了不支持拼接发送,所以该方法可以不实现。
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
protected override void PreviewSend(IRequestInfo requestInfo)
|
||||
{
|
||||
throw new System.NotImplementedException();//因为设置了不支持,所以该方法可以不实现。
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Reset()
|
||||
|
@@ -10,7 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 数据类型
|
||||
|
@@ -10,13 +10,48 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static class ByteExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取异或校验
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="left"></param>
|
||||
/// <param name="right"></param>
|
||||
/// <returns></returns>
|
||||
public static byte[] GetAsciiXOR(this byte[] data, int left, int right)
|
||||
{
|
||||
int tmp = data[left];
|
||||
for (int i = left + 1; i < data.Length - right; i++)
|
||||
{
|
||||
tmp = (tmp ^ data[i]);
|
||||
}
|
||||
|
||||
byte[] fcs = new byte[2];
|
||||
fcs[0] = Encoding.ASCII.GetBytes(((byte)tmp).ToString("X2"))[0];
|
||||
fcs[1] = Encoding.ASCII.GetBytes(((byte)tmp).ToString("X2"))[1];
|
||||
return fcs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数组内容分别相加某个数字
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static byte[] BytesAdd(this byte[] bytes, int value)
|
||||
{
|
||||
for (int index = 0; index < bytes.Length; ++index)
|
||||
bytes[index] = (byte)(bytes[index] + value);
|
||||
return bytes;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取byte数据类型的第offset位,是否为True<br />
|
||||
/// </summary>
|
||||
|
@@ -12,7 +12,7 @@
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 对象拓展
|
||||
|
@@ -10,7 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
@@ -178,6 +178,10 @@ public static class GenericExtensions
|
||||
/// <inheritdoc cref="DataTransUtil.SpliceArray" />
|
||||
public static T[] SpliceArray<T>(this T[] value, params T[][] arrays)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
value = new T[0];
|
||||
}
|
||||
List<T[]> objArrayList = new(arrays.Length + 1)
|
||||
{
|
||||
value
|
||||
|