迁移4.0
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -363,4 +363,5 @@ MigrationBackup/
|
||||
FodyWeavers.xsd
|
||||
|
||||
|
||||
/framework/*Pro*
|
||||
/framework/*pro*
|
||||
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
[*.cs]
|
||||
|
||||
# CA1848: 使用 LoggerMessage 委托
|
||||
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
|
||||
3
framework/.gitignore
vendored
3
framework/.gitignore
vendored
@@ -360,5 +360,4 @@ MigrationBackup/
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
FodyWeavers.xsd
|
||||
@@ -1,6 +1,7 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>3.0.1.0</Version>
|
||||
<TargetFrameworks>net6.0;net8.0;</TargetFrameworks>
|
||||
<Version>4.0.0.0</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
|
||||
@@ -23,6 +23,8 @@ internal class Program
|
||||
|
||||
var appBuilder = PhotinoBlazorAppBuilder.CreateDefault(args);
|
||||
|
||||
Serve.RunNative();
|
||||
|
||||
appBuilder.RootComponents.Add<App>("#app");
|
||||
|
||||
appBuilder.Services.ThingsGatewayComponentsConfigureServices();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
<TargetFrameworks>net6.0;net8.0;</TargetFrameworks>
|
||||
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
using ThingsGateway.Components;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
|
||||
/// <summary>
|
||||
@@ -34,12 +32,17 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
|
||||
this.SafeDispose();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 变量地址
|
||||
/// </summary>
|
||||
public virtual string Address { get; set; } = "40001";
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
[Inject]
|
||||
public InitTimezone InitTimezone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 长度
|
||||
/// </summary>
|
||||
@@ -58,13 +61,6 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
|
||||
/// 数据类型
|
||||
/// </summary>
|
||||
protected virtual DataTypeEnum DataTypeEnum { get; set; } = DataTypeEnum.Int16;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
[Inject]
|
||||
public InitTimezone InitTimezone { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<MRow Class="my-1" Justify="JustifyTypes.Start" Align="AlignTypes.Start" NoGutters>
|
||||
<MTextField Class="mx-1 my-1" Style="max-width:200px" Label="读取长度" Dense Outlined HideDetails="@("auto")" @bind-Value=@Length />
|
||||
<MSelect Class="mx-1 my-1" Style="max-width:200px" @bind-Value="DataTypeEnum" Outlined Label="数据类型"
|
||||
Items=@(typeof(DataTypeEnum).GetEnumListWithOutSugar())
|
||||
Items=@(typeof(DataTypeEnum).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(DataTypeEnum)u.Value)
|
||||
@@ -87,9 +87,9 @@
|
||||
@foreach (var item in DeviceVariableRunTimes)
|
||||
{
|
||||
<MRow Dense Align="AlignTypes.Center">
|
||||
<MTextField Class="ma-1" Outlined Style="min-width:100px" Label=@(item.DescriptionWithOutSugar(x => x.VariableAddress)) Dense HideDetails="@("auto")" @bind-Value=@item.VariableAddress></MTextField>
|
||||
<MSelect Class="mx-1 my-1" Style="max-width:120px" @bind-Value="item.DataTypeEnum" Outlined Label=@(item.DescriptionWithOutSugar(x => x.DataTypeEnum))
|
||||
Items=@(typeof(DataTypeEnum).GetEnumListWithOutSugar())
|
||||
<MTextField Class="ma-1" Outlined Style="min-width:100px" Label=@(item.Description(x => x.Address)) Dense HideDetails="@("auto")" @bind-Value=@item.Address></MTextField>
|
||||
<MSelect Class="mx-1 my-1" Style="max-width:120px" @bind-Value="item.DataTypeEnum" Outlined Label=@(item.Description(x => x.DataTypeEnum))
|
||||
Items=@(typeof(DataTypeEnum).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(DataTypeEnum)u.Value)
|
||||
@@ -97,7 +97,7 @@
|
||||
Dense>
|
||||
</MSelect>
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(item.DescriptionWithOutSugar(x => x.IntervalTime)) Dense HideDetails="@("auto")" @bind-Value=@item.IntervalTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(item.Description(x => x.IntervalTime)) Dense HideDetails="@("auto")" @bind-Value=@item.IntervalTime></MTextField>
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=实时值 Readonly ClearIcon="" Dense HideDetails="@("auto")" Value=item.Value?.ToJsonString()></MTextField>
|
||||
|
||||
|
||||
@@ -30,16 +30,66 @@ public partial class DriverDebugUIPage : DriverDebugUIBase
|
||||
/// MaxPack
|
||||
/// </summary>
|
||||
public int MaxPack = 100;
|
||||
private StringNumber _selected = 0;
|
||||
|
||||
/// <inheritdoc/>
|
||||
~DriverDebugUIPage()
|
||||
{
|
||||
this.SafeDispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自定义模板
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment CodeContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义模板
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment OtherContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public override IReadWrite Plc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义模板
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment ReadWriteContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sections
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public List<(string Code, string Language)> Sections { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// ShowDefaultOtherContent
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool ShowDefaultOtherContent { get; set; } = true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Dispose()
|
||||
{
|
||||
Plc?.SafeDispose();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MulReadAsync
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task MulReadAsync()
|
||||
{
|
||||
var deviceVariableSourceReads = Plc.LoadSourceRead<DeviceVariableSourceRead, DeviceVariableRunTime>(DeviceVariableRunTimes, MaxPack);
|
||||
var deviceVariableSourceReads = Plc.LoadSourceRead<DeviceVariableSourceRead, DeviceVariableRunTime>(DeviceVariableRunTimes, MaxPack, 1000);
|
||||
foreach (var item in deviceVariableSourceReads)
|
||||
{
|
||||
var result = await Plc.ReadAsync(item.VariableAddress, item.Length);
|
||||
var result = await Plc.ReadAsync(item.Address, item.Length);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
try
|
||||
@@ -57,20 +107,14 @@ public partial class DriverDebugUIPage : DriverDebugUIBase
|
||||
Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
}
|
||||
}
|
||||
|
||||
private StringNumber _selected = 0;
|
||||
/// <summary>
|
||||
/// Sections
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public List<(string Code, string Language)> Sections { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// ShowDefaultOtherContent
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool ShowDefaultOtherContent { get; set; } = true;
|
||||
|
||||
/// <param name="firstRender"></param>
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
base.OnAfterRender(firstRender);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnInitialized()
|
||||
@@ -80,25 +124,25 @@ public partial class DriverDebugUIPage : DriverDebugUIBase
|
||||
new DeviceVariableRunTime()
|
||||
{
|
||||
DataTypeEnum=DataTypeEnum.Int16,
|
||||
VariableAddress="40001",
|
||||
Address="40001",
|
||||
IntervalTime=1000,
|
||||
},
|
||||
new DeviceVariableRunTime()
|
||||
{
|
||||
DataTypeEnum=DataTypeEnum.Int16,
|
||||
VariableAddress="40011",
|
||||
Address="40011",
|
||||
IntervalTime=1000,
|
||||
},
|
||||
new DeviceVariableRunTime()
|
||||
{
|
||||
DataTypeEnum=DataTypeEnum.Int16,
|
||||
VariableAddress="40031",
|
||||
Address="40031",
|
||||
IntervalTime=1000,
|
||||
},
|
||||
new DeviceVariableRunTime()
|
||||
{
|
||||
DataTypeEnum=DataTypeEnum.Int16,
|
||||
VariableAddress="40101",
|
||||
Address="40101",
|
||||
IntervalTime=1000,
|
||||
},
|
||||
};
|
||||
@@ -110,7 +154,7 @@ public partial class DriverDebugUIPage : DriverDebugUIBase
|
||||
/// <inheritdoc/>
|
||||
public TimerTick TimerTick { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public string VariableAddress { get; set; }
|
||||
public string Address { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public int Length { get; set; }
|
||||
/// <inheritdoc/>
|
||||
@@ -124,7 +168,7 @@ public partial class DriverDebugUIPage : DriverDebugUIBase
|
||||
public int IntervalTime { get; set; }
|
||||
/// <inheritdoc/>
|
||||
[Description("变量地址")]
|
||||
public string VariableAddress { get; set; }
|
||||
public string Address { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public int Index { get; set; }
|
||||
/// <inheritdoc/>
|
||||
@@ -151,25 +195,25 @@ public partial class DriverDebugUIPage : DriverDebugUIBase
|
||||
new DeviceVariableRunTime()
|
||||
{
|
||||
DataTypeEnum=DataTypeEnum.Int16,
|
||||
VariableAddress="40001",
|
||||
Address="40001",
|
||||
IntervalTime=1000,
|
||||
},
|
||||
new DeviceVariableRunTime()
|
||||
{
|
||||
DataTypeEnum=DataTypeEnum.Int16,
|
||||
VariableAddress="40011",
|
||||
Address="40011",
|
||||
IntervalTime=1000,
|
||||
},
|
||||
new DeviceVariableRunTime()
|
||||
{
|
||||
DataTypeEnum=DataTypeEnum.Int16,
|
||||
VariableAddress="40031",
|
||||
Address="40031",
|
||||
IntervalTime=1000,
|
||||
},
|
||||
new DeviceVariableRunTime()
|
||||
{
|
||||
DataTypeEnum=DataTypeEnum.Int16,
|
||||
VariableAddress="40101",
|
||||
Address="40101",
|
||||
IntervalTime=1000,
|
||||
},
|
||||
};
|
||||
@@ -178,7 +222,7 @@ public partial class DriverDebugUIPage : DriverDebugUIBase
|
||||
var deviceVariableSourceReads = Plc.LoadSourceRead<DeviceVariableSourceRead, DeviceVariableRunTime>(DeviceVariableRunTimes, MaxPack);
|
||||
foreach (var item in deviceVariableSourceReads)
|
||||
{
|
||||
var result = await Plc.ReadAsync(item.VariableAddress, item.Length);
|
||||
var result = await Plc.ReadAsync(item.Address, item.Length);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
item.DeviceVariableRunTimes.PraseStructContent(result.Content);
|
||||
@@ -191,46 +235,4 @@ public partial class DriverDebugUIPage : DriverDebugUIBase
|
||||
""", "csharp"));
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自定义模板
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment ReadWriteContent { get; set; }
|
||||
/// <summary>
|
||||
/// 自定义模板
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment OtherContent { get; set; }
|
||||
/// <summary>
|
||||
/// 自定义模板
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment CodeContent { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
~DriverDebugUIPage()
|
||||
{
|
||||
this.SafeDispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public override IReadWrite Plc { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Dispose()
|
||||
{
|
||||
Plc?.SafeDispose();
|
||||
base.Dispose();
|
||||
}
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="firstRender"></param>
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
base.OnAfterRender(firstRender);
|
||||
}
|
||||
}
|
||||
@@ -15,22 +15,22 @@
|
||||
@using Microsoft.AspNetCore.Components.Web;
|
||||
@using System.IO.Ports;
|
||||
@using Masa.Blazor
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">通道配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(serialProperty.DescriptionWithOutSugar(x => x.PortName)) Dense HideDetails="@("auto")" @bind-Value=@serialProperty.PortName />
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(serialProperty.DescriptionWithOutSugar(x => x.BaudRate)) Dense HideDetails="@("auto")" @bind-Value=@serialProperty.BaudRate />
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(serialProperty.DescriptionWithOutSugar(x => x.DataBits)) Dense HideDetails="@("auto")" @bind-Value=@serialProperty.DataBits />
|
||||
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="serialProperty.Parity" Label="@(serialProperty.DescriptionWithOutSugar(x => x.Parity))"
|
||||
Items=@(typeof(Parity).GetEnumListWithOutSugar())
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialProperty.Description(x => x.PortName)) Dense HideDetails="@("auto")" @bind-Value=@_serialProperty.PortName />
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialProperty.Description(x => x.BaudRate)) Dense HideDetails="@("auto")" @bind-Value=@_serialProperty.BaudRate />
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialProperty.Description(x => x.DataBits)) Dense HideDetails="@("auto")" @bind-Value=@_serialProperty.DataBits />
|
||||
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialProperty.Parity" Label="@(_serialProperty.Description(x => x.Parity))"
|
||||
Items=@(typeof(Parity).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(Parity)u.Value)
|
||||
HideDetails=@("auto") Height="30"
|
||||
Dense>
|
||||
</MSelect>
|
||||
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="serialProperty.StopBits" Label="@(serialProperty.DescriptionWithOutSugar(x => x.StopBits))"
|
||||
Items=@(typeof(StopBits).GetEnumListWithOutSugar())
|
||||
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialProperty.StopBits" Label="@(_serialProperty.Description(x => x.StopBits))"
|
||||
Items=@(typeof(StopBits).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(StopBits)u.Value)
|
||||
|
||||
@@ -20,11 +20,17 @@ public partial class SerialSessionPage : IDisposable
|
||||
/// </summary>
|
||||
public Action<LogLevel, object, string, Exception> LogAction;
|
||||
|
||||
private TouchSocketConfig config;
|
||||
private readonly SerialProperty _serialProperty = new();
|
||||
private TouchSocketConfig _config;
|
||||
private SerialSession _serialSession { get; set; } = new();
|
||||
|
||||
private readonly SerialProperty serialProperty = new();
|
||||
|
||||
private SerialSession SerialSession { get; set; } = new();
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_serialSession.SafeDispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象
|
||||
@@ -32,20 +38,49 @@ public partial class SerialSessionPage : IDisposable
|
||||
/// <returns></returns>
|
||||
public SerialSession GetSerialSession()
|
||||
{
|
||||
config ??= new TouchSocketConfig();
|
||||
_config ??= new TouchSocketConfig();
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
config.SetSerialProperty(serialProperty);
|
||||
_config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
_config.SetSerialProperty(_serialProperty);
|
||||
//载入配置
|
||||
SerialSession.Setup(config);
|
||||
return SerialSession;
|
||||
_serialSession.Setup(_config);
|
||||
return _serialSession;
|
||||
}
|
||||
internal void StateHasChangedAsync()
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="firstRender"></param>
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
_config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
_serialSession.Setup(_config);
|
||||
}
|
||||
base.OnAfterRender(firstRender);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_config ??= new TouchSocketConfig();
|
||||
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
private async Task ConnectAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
SerialSession.Close();
|
||||
_serialSession.Close();
|
||||
await GetSerialSession().ConnectAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -58,49 +93,12 @@ public partial class SerialSessionPage : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
SerialSession.Close();
|
||||
_serialSession.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAction?.Invoke(LogLevel.Error, null, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
config ??= new TouchSocketConfig();
|
||||
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="firstRender"></param>
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
SerialSession.Setup(config);
|
||||
}
|
||||
base.OnAfterRender(firstRender);
|
||||
}
|
||||
|
||||
private void LogOut(LogLevel logLevel, object source, string message, Exception exception) => LogAction?.Invoke(logLevel, source, message, exception);
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
SerialSession.SafeDispose();
|
||||
}
|
||||
internal void StateHasChangedAsync()
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
@@ -17,12 +17,12 @@
|
||||
@using System.Collections.Concurrent;
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using Masa.Blazor
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">通道配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
|
||||
<MTextField Class="ma-1" Style="max-width:100px" Label="IP地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@IP />
|
||||
<MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@Port />
|
||||
<MTextField Class="ma-1" Style="max-width:100px" Label="IP地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@_ip />
|
||||
<MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@_port />
|
||||
|
||||
<MButton Class="ma-1" OnClick=@ConnectAsync Color="primary">
|
||||
连接
|
||||
|
||||
@@ -20,23 +20,77 @@ public partial class TcpClientPage : IDisposable
|
||||
/// </summary>
|
||||
public Action<LogLevel, object, string, Exception> LogAction;
|
||||
|
||||
private TouchSocketConfig config;
|
||||
private TouchSocketConfig _config;
|
||||
/// <summary>
|
||||
/// IP
|
||||
/// </summary>
|
||||
private string IP = "127.0.0.1";
|
||||
private string _ip = "127.0.0.1";
|
||||
/// <summary>
|
||||
/// Port
|
||||
/// </summary>
|
||||
public int Port { get; set; } = 502;
|
||||
public int _port { get; set; } = 502;
|
||||
|
||||
private TcpClient TcpClient { get; set; } = new();
|
||||
private TcpClient _tcpClient { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_tcpClient.SafeDispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TcpClient GetTcpClient()
|
||||
{
|
||||
_config ??= new TouchSocketConfig();
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
_config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
_config.SetRemoteIPHost(new IPHost(_ip + ":" + _port));
|
||||
//载入配置
|
||||
_tcpClient.Setup(_config);
|
||||
return _tcpClient;
|
||||
}
|
||||
|
||||
internal void StateHasChangedAsync()
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="firstRender"></param>
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
_config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
_config.SetRemoteIPHost(new IPHost(_ip + ":" + _port));
|
||||
_tcpClient.Setup(_config);
|
||||
}
|
||||
base.OnAfterRender(firstRender);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_config ??= new TouchSocketConfig();
|
||||
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
private async Task ConnectAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
TcpClient.Close();
|
||||
_tcpClient.Close();
|
||||
await GetTcpClient().ConnectAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -50,7 +104,7 @@ public partial class TcpClientPage : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
TcpClient.Close();
|
||||
_tcpClient.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -58,59 +112,5 @@ public partial class TcpClientPage : IDisposable
|
||||
LogAction?.Invoke(LogLevel.Error, null, null, ex);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TcpClient GetTcpClient()
|
||||
{
|
||||
config ??= new TouchSocketConfig();
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
config.SetRemoteIPHost(new IPHost(IP + ":" + Port));
|
||||
//载入配置
|
||||
TcpClient.Setup(config);
|
||||
return TcpClient;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
config ??= new TouchSocketConfig();
|
||||
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="firstRender"></param>
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
config.SetRemoteIPHost(new IPHost(IP + ":" + Port));
|
||||
TcpClient.Setup(config);
|
||||
}
|
||||
base.OnAfterRender(firstRender);
|
||||
}
|
||||
|
||||
private void LogOut(LogLevel logLevel, object source, string message, Exception exception) => LogAction?.Invoke(logLevel, source, message, exception);
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
TcpClient.SafeDispose();
|
||||
}
|
||||
|
||||
internal void StateHasChangedAsync()
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
@@ -18,12 +18,12 @@
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using Masa.Blazor
|
||||
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">通道配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
|
||||
<MTextField Class="ma-1" Style="max-width:100px" Label="IP地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@ip />
|
||||
<MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@port />
|
||||
<MTextField Class="ma-1" Style="max-width:100px" Label="IP地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@_ip />
|
||||
<MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@_port />
|
||||
|
||||
<MButton Class="ma-1" OnClick=@Connect Color="primary">
|
||||
启动
|
||||
|
||||
@@ -20,19 +20,73 @@ public partial class TcpServerPage : IDisposable
|
||||
/// </summary>
|
||||
public Action<LogLevel, object, string, Exception> LogAction;
|
||||
|
||||
private TouchSocketConfig config;
|
||||
private TouchSocketConfig _config;
|
||||
|
||||
private string ip = "127.0.0.1";
|
||||
private string _ip = "127.0.0.1";
|
||||
|
||||
private int port = 502;
|
||||
private int _port = 502;
|
||||
|
||||
private TcpService TcpServer { get; set; } = new();
|
||||
private TcpService _tcpServer { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_tcpServer.SafeDispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TcpService GetTcpServer()
|
||||
{
|
||||
_config ??= new TouchSocketConfig();
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
_config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
_config.SetListenIPHosts(new IPHost[] { new IPHost(_ip + ":" + _port) });
|
||||
//载入配置
|
||||
_tcpServer.Setup(_config);
|
||||
return _tcpServer;
|
||||
}
|
||||
|
||||
internal void StateHasChangedAsync()
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="firstRender"></param>
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
_config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
_config.SetListenIPHosts(new IPHost[] { new IPHost(_ip + ":" + _port) });
|
||||
_tcpServer.Setup(_config);
|
||||
}
|
||||
base.OnAfterRender(firstRender);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_config ??= new TouchSocketConfig();
|
||||
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
private void Connect()
|
||||
{
|
||||
try
|
||||
{
|
||||
TcpServer.Stop();
|
||||
_tcpServer.Stop();
|
||||
GetTcpServer().Start();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -46,63 +100,12 @@ public partial class TcpServerPage : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
TcpServer.Stop();
|
||||
_tcpServer.Stop();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAction?.Invoke(LogLevel.Error, null, null, ex);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TcpService GetTcpServer()
|
||||
{
|
||||
config ??= new TouchSocketConfig();
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
config.SetListenIPHosts(new IPHost[] { new IPHost(ip + ":" + port) });
|
||||
//载入配置
|
||||
TcpServer.Setup(config);
|
||||
return TcpServer;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
config ??= new TouchSocketConfig();
|
||||
|
||||
base.OnInitialized();
|
||||
}
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="firstRender"></param>
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
config.SetListenIPHosts(new IPHost[] { new IPHost(ip + ":" + port) });
|
||||
TcpServer.Setup(config);
|
||||
}
|
||||
base.OnAfterRender(firstRender);
|
||||
}
|
||||
|
||||
private void LogOut(LogLevel logLevel, object source, string message, Exception exception) => LogAction?.Invoke(logLevel, source, message, exception);
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
TcpServer.SafeDispose();
|
||||
}
|
||||
internal void StateHasChangedAsync()
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
@@ -18,12 +18,12 @@
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using Masa.Blazor
|
||||
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">通道配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
|
||||
<MTextField Class="ma-1" Style="max-width:100px" Label="IP地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@IP />
|
||||
<MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@Port />
|
||||
<MTextField Class="ma-1" Style="max-width:100px" Label="IP地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@_ip />
|
||||
<MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@_port />
|
||||
|
||||
<MButton Class="ma-1" OnClick=Connect Color="primary">
|
||||
连接
|
||||
|
||||
@@ -15,28 +15,85 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
/// <inheritdoc/>
|
||||
public partial class UdpSessionPage : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// IP
|
||||
/// </summary>
|
||||
public string _ip = "127.0.0.1";
|
||||
|
||||
/// <summary>
|
||||
/// Port
|
||||
/// </summary>
|
||||
public int _port = 502;
|
||||
|
||||
/// <summary>
|
||||
/// 日志输出
|
||||
/// </summary>
|
||||
public Action<LogLevel, object, string, Exception> LogAction;
|
||||
|
||||
private TouchSocketConfig config;
|
||||
/// <summary>
|
||||
/// IP
|
||||
/// </summary>
|
||||
public string IP = "127.0.0.1";
|
||||
/// <summary>
|
||||
/// Port
|
||||
/// </summary>
|
||||
public int Port = 502;
|
||||
private TouchSocketConfig _config;
|
||||
private UdpSession _udpSession { get; set; } = new();
|
||||
|
||||
private UdpSession UdpSession { get; set; } = new();
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_udpSession.SafeDispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public UdpSession GetUdpSession()
|
||||
{
|
||||
_config ??= new TouchSocketConfig();
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
_config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
_config.SetRemoteIPHost(new IPHost(_ip + ":" + _port));
|
||||
_config.SetBindIPHost(new IPHost(0));
|
||||
//载入配置
|
||||
_udpSession.Setup(_config);
|
||||
return _udpSession;
|
||||
}
|
||||
|
||||
internal void StateHasChangedAsync()
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="firstRender"></param>
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
_config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
_config.SetRemoteIPHost(new IPHost(_ip + ":" + _port));
|
||||
_config.SetBindIPHost(new IPHost(0));
|
||||
_udpSession.Setup(_config);
|
||||
}
|
||||
base.OnAfterRender(firstRender);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_config ??= new TouchSocketConfig();
|
||||
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
private void Connect()
|
||||
{
|
||||
try
|
||||
{
|
||||
UdpSession.Stop();
|
||||
_udpSession.Stop();
|
||||
GetUdpSession().Start();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -49,7 +106,7 @@ public partial class UdpSessionPage : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
UdpSession.Stop();
|
||||
_udpSession.Stop();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -57,57 +114,5 @@ public partial class UdpSessionPage : IDisposable
|
||||
LogAction?.Invoke(LogLevel.Error, null, null, ex);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public UdpSession GetUdpSession()
|
||||
{
|
||||
config ??= new TouchSocketConfig();
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
config.SetRemoteIPHost(new IPHost(IP + ":" + Port));
|
||||
config.SetBindIPHost(new IPHost(0));
|
||||
//载入配置
|
||||
UdpSession.Setup(config);
|
||||
return UdpSession;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
config ??= new TouchSocketConfig();
|
||||
|
||||
base.OnInitialized();
|
||||
}
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="firstRender"></param>
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
config.SetRemoteIPHost(new IPHost(IP + ":" + Port));
|
||||
config.SetBindIPHost(new IPHost(0));
|
||||
UdpSession.Setup(config);
|
||||
}
|
||||
base.OnAfterRender(firstRender);
|
||||
}
|
||||
private void LogOut(LogLevel logLevel, object source, string message, Exception exception) => LogAction?.Invoke(logLevel, source, message, exception);
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
UdpSession.SafeDispose();
|
||||
}
|
||||
internal void StateHasChangedAsync()
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
@@ -19,10 +19,10 @@ public class DeviceVariableRunTime : IDeviceVariableRunTime
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[Description("读取间隔")]
|
||||
public int IntervalTime { get; set; }
|
||||
public int? IntervalTime { get; set; }
|
||||
/// <inheritdoc/>
|
||||
[Description("变量地址")]
|
||||
public string VariableAddress { get; set; }
|
||||
public string Address { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public int Index { get; set; }
|
||||
/// <inheritdoc/>
|
||||
@@ -33,10 +33,16 @@ public class DeviceVariableRunTime : IDeviceVariableRunTime
|
||||
/// <inheritdoc/>
|
||||
[Description("实时值")]
|
||||
public object Value { get; set; }
|
||||
|
||||
public bool IsOnline { get; set; }
|
||||
|
||||
public string LastErrorMessage { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public OperResult SetValue(object value, DateTime dateTime = default, bool isOnline = true)
|
||||
public OperResult SetValue(object value, DateTime dateTime = default, string lastErrorMessage = null)
|
||||
{
|
||||
Value = value;
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public class DeviceVariableSourceRead : IDeviceVariableSourceRead<IDeviceVariableRunTime>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public TimerTick TimerTick { get; set; }
|
||||
public TimerTick IntervalTimeTick { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public string VariableAddress { get; set; }
|
||||
public string Address { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public int Length { get; set; }
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -19,28 +19,28 @@
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<SerialSessionPage @ref=SerialSessionPage></SerialSessionPage>
|
||||
<SerialSessionPage @ref=_serialSessionPage></SerialSessionPage>
|
||||
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
@if (_plc != null)
|
||||
{
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
|
||||
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.OperCode)) Dense HideDetails="@("auto")" @bind-Value=@_plc.OperCode></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.Password)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Password></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.OperCode)) Dense HideDetails="@("auto")" @bind-Value=@_plc.OperCode></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.Password)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Password></MTextField>
|
||||
|
||||
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.DescriptionWithOutSugar(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumListWithOutSugar())
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.Description(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(DataFormat)u.Value)
|
||||
@@ -48,14 +48,14 @@
|
||||
Dense>
|
||||
</MSelect>
|
||||
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.DescriptionWithOutSugar(x => x.EnableFEHead)) Dense HideDetails="@("auto")" @bind-Value=@_plc.EnableFEHead></MCheckbox>
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.EnableFEHead)) Dense HideDetails="@("auto")" @bind-Value=@_plc.EnableFEHead></MCheckbox>
|
||||
|
||||
}
|
||||
</MRow>
|
||||
</MCard>
|
||||
|
||||
|
||||
<DriverDebugUIPage @ref=driverDebugUIPage Sections="_sections" ShowDefaultOtherContent=false>
|
||||
<DriverDebugUIPage @ref=_driverDebugUIPage Sections="_sections" ShowDefaultOtherContent=false>
|
||||
<OtherContent>
|
||||
<MSubheader>
|
||||
广播校时
|
||||
@@ -162,11 +162,11 @@
|
||||
var result = await _plc.WritePasswordAsync(level, oldPassword, newPassword);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
}
|
||||
else
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,11 +177,11 @@
|
||||
var result = await _plc.WriteDeviceStationAsync(station);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
}
|
||||
else
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,11 +191,11 @@
|
||||
var result = await _plc.WriteBaudRateAsync(baudRate);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
}
|
||||
else
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,11 +204,11 @@
|
||||
var result = await _plc.ReadDeviceStationAsync();
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Content));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Content));
|
||||
}
|
||||
else
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
}
|
||||
}
|
||||
private DateTime dateTime;
|
||||
@@ -19,11 +19,9 @@ public partial class DLT645_2007DebugPage
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
public SerialSessionPage SerialSessionPage;
|
||||
private DriverDebugUIPage driverDebugUIPage;
|
||||
|
||||
private SerialSessionPage _serialSessionPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
private ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007 _plc;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
@@ -71,14 +69,14 @@ public partial class DLT645_2007DebugPage
|
||||
""", "csharp"));
|
||||
|
||||
|
||||
if (SerialSessionPage != null)
|
||||
SerialSessionPage.LogAction = driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007(SerialSessionPage.GetSerialSession());
|
||||
driverDebugUIPage.Plc = _plc;
|
||||
if (_serialSessionPage != null)
|
||||
_serialSessionPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007(_serialSessionPage.GetSerialSession());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
|
||||
//初始化
|
||||
driverDebugUIPage.Address = "02010100";
|
||||
driverDebugUIPage.DeviceVariableRunTimes.ForEach(a => a.VariableAddress = "02010100");
|
||||
_driverDebugUIPage.Address = "02010100";
|
||||
_driverDebugUIPage.DeviceVariableRunTimes.ForEach(a => a.Address = "02010100");
|
||||
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
@@ -18,26 +18,26 @@
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<TcpClientPage @ref=TcpClientPage></TcpClientPage>
|
||||
<TcpClientPage @ref=_tcpClientPage></TcpClientPage>
|
||||
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
@if (_plc != null)
|
||||
{
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.OperCode)) Dense HideDetails="@("auto")" @bind-Value=@_plc.OperCode></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.Password)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Password></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.OperCode)) Dense HideDetails="@("auto")" @bind-Value=@_plc.OperCode></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.Password)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Password></MTextField>
|
||||
|
||||
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.DescriptionWithOutSugar(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumListWithOutSugar())
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.Description(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(DataFormat)u.Value)
|
||||
@@ -45,14 +45,14 @@
|
||||
Dense>
|
||||
</MSelect>
|
||||
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.DescriptionWithOutSugar(x => x.EnableFEHead)) Dense HideDetails="@("auto")" @bind-Value=@_plc.EnableFEHead></MCheckbox>
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.EnableFEHead)) Dense HideDetails="@("auto")" @bind-Value=@_plc.EnableFEHead></MCheckbox>
|
||||
|
||||
}
|
||||
</MRow>
|
||||
</MCard>
|
||||
|
||||
|
||||
<DriverDebugUIPage @ref=driverDebugUIPage Sections="_sections" ShowDefaultOtherContent=false>
|
||||
<DriverDebugUIPage @ref=_driverDebugUIPage Sections="_sections" ShowDefaultOtherContent=false>
|
||||
<OtherContent>
|
||||
<MSubheader>
|
||||
广播校时
|
||||
@@ -159,11 +159,11 @@
|
||||
var result = await _plc.WritePasswordAsync(level, oldPassword, newPassword);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
}
|
||||
else
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,11 +174,11 @@
|
||||
var result = await _plc.WriteDeviceStationAsync(station);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
}
|
||||
else
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,11 +188,11 @@
|
||||
var result = await _plc.WriteBaudRateAsync(baudRate);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
}
|
||||
else
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,11 +201,11 @@
|
||||
var result = await _plc.ReadDeviceStationAsync();
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Content));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Content));
|
||||
}
|
||||
else
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(_driverDebugUIPage.InitTimezone.TimezoneOffset) + " - " + result.Message));
|
||||
}
|
||||
}
|
||||
private DateTime dateTime;
|
||||
@@ -19,8 +19,8 @@ public partial class DLT645_2007OverTcpDebugPage
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
public TcpClientPage TcpClientPage;
|
||||
private DriverDebugUIPage driverDebugUIPage;
|
||||
private TcpClientPage _tcpClientPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
private ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp _plc;
|
||||
|
||||
@@ -66,16 +66,16 @@ public partial class DLT645_2007OverTcpDebugPage
|
||||
|
||||
""", "csharp"));
|
||||
|
||||
if (TcpClientPage != null)
|
||||
TcpClientPage.LogAction = driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp(TcpClientPage.GetTcpClient());
|
||||
driverDebugUIPage.Plc = _plc;
|
||||
if (_tcpClientPage != null)
|
||||
_tcpClientPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp(_tcpClientPage.GetTcpClient());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
|
||||
//初始化
|
||||
driverDebugUIPage.Address = "02010100";
|
||||
driverDebugUIPage.DeviceVariableRunTimes.ForEach(a => a.VariableAddress = "02010100");
|
||||
TcpClientPage.Port = 5000;
|
||||
TcpClientPage.StateHasChangedAsync();
|
||||
_driverDebugUIPage.Address = "02010100";
|
||||
_driverDebugUIPage.DeviceVariableRunTimes.ForEach(a => a.Address = "02010100");
|
||||
_tcpClientPage._port = 5000;
|
||||
_tcpClientPage.StateHasChangedAsync();
|
||||
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
@@ -0,0 +1,56 @@
|
||||
@*
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
*@
|
||||
|
||||
@page "/ModbusRtu"
|
||||
|
||||
@using BlazorComponent;
|
||||
@using Microsoft.AspNetCore.Components.Web;
|
||||
@using Microsoft.JSInterop;
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<SerialSessionPage @ref=_serialSessionPage></SerialSessionPage>
|
||||
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
@if (_plc != null)
|
||||
{
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.Description(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(DataFormat)u.Value)
|
||||
HideDetails=@("auto") Height="30"
|
||||
Dense>
|
||||
</MSelect>
|
||||
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.Crc16CheckEnable)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Crc16CheckEnable></MCheckbox>
|
||||
|
||||
}
|
||||
</MRow>
|
||||
</MCard>
|
||||
|
||||
|
||||
<DriverDebugUIPage @ref=_driverDebugUIPage Sections="_sections">
|
||||
|
||||
</DriverDebugUIPage>
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
|
||||
|
||||
@@ -19,11 +21,11 @@ public partial class ModbusRtuDebugPage
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
public SerialSessionPage SerialSessionPage;
|
||||
private DriverDebugUIPage driverDebugUIPage;
|
||||
private SerialSessionPage _serialSessionPage;
|
||||
private readonly List<(string Code, string Language)> _sections = new();
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu _plc;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
@@ -70,10 +72,10 @@ public partial class ModbusRtuDebugPage
|
||||
""", "csharp"));
|
||||
|
||||
|
||||
if (SerialSessionPage != null)
|
||||
SerialSessionPage.LogAction = driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu(SerialSessionPage.GetSerialSession());
|
||||
driverDebugUIPage.Plc = _plc;
|
||||
if (_serialSessionPage != null)
|
||||
_serialSessionPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu(_serialSessionPage.GetSerialSession());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
}
|
||||
@@ -18,22 +18,22 @@
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<TcpClientPage @ref=TcpClientPage></TcpClientPage>
|
||||
<TcpClientPage @ref=_tcpClientPage></TcpClientPage>
|
||||
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
@if (_plc != null)
|
||||
{
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.DescriptionWithOutSugar(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumListWithOutSugar())
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.Description(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(DataFormat)u.Value)
|
||||
@@ -41,19 +41,16 @@
|
||||
Dense>
|
||||
</MSelect>
|
||||
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.DescriptionWithOutSugar(x => x.Crc16CheckEnable)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Crc16CheckEnable></MCheckbox>
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.Crc16CheckEnable)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Crc16CheckEnable></MCheckbox>
|
||||
|
||||
}
|
||||
</MRow>
|
||||
</MCard>
|
||||
|
||||
|
||||
<DriverDebugUIPage @ref=driverDebugUIPage Sections="_sections">
|
||||
<DriverDebugUIPage @ref=_driverDebugUIPage Sections="_sections">
|
||||
|
||||
</DriverDebugUIPage>
|
||||
|
||||
|
||||
@code {
|
||||
private readonly List<(string Code, string Language)> _sections = new();
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
|
||||
|
||||
@@ -19,10 +21,11 @@ public partial class ModbusRtuOverTcpDebugPage
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
public TcpClientPage TcpClientPage;
|
||||
private DriverDebugUIPage driverDebugUIPage;
|
||||
private TcpClientPage _tcpClientPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp _plc;
|
||||
private readonly List<(string Code, string Language)> _sections = new();
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
@@ -67,10 +70,10 @@ public partial class ModbusRtuOverTcpDebugPage
|
||||
|
||||
""", "csharp"));
|
||||
|
||||
if (TcpClientPage != null)
|
||||
TcpClientPage.LogAction = driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp(TcpClientPage.GetTcpClient());
|
||||
driverDebugUIPage.Plc = _plc;
|
||||
if (_tcpClientPage != null)
|
||||
_tcpClientPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp(_tcpClientPage.GetTcpClient());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
}
|
||||
@@ -18,22 +18,22 @@
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<UdpSessionPage @ref=UdpSessionPage></UdpSessionPage>
|
||||
<UdpSessionPage @ref=_udpSessionPage></UdpSessionPage>
|
||||
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
@if (_plc != null)
|
||||
{
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.DescriptionWithOutSugar(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumListWithOutSugar())
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.Description(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(DataFormat)u.Value)
|
||||
@@ -41,14 +41,14 @@
|
||||
Dense>
|
||||
</MSelect>
|
||||
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.DescriptionWithOutSugar(x => x.Crc16CheckEnable)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Crc16CheckEnable></MCheckbox>
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.Crc16CheckEnable)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Crc16CheckEnable></MCheckbox>
|
||||
|
||||
}
|
||||
</MRow>
|
||||
</MCard>
|
||||
|
||||
|
||||
<DriverDebugUIPage @ref=driverDebugUIPage Sections="_sections">
|
||||
<DriverDebugUIPage @ref=_driverDebugUIPage Sections="_sections">
|
||||
|
||||
</DriverDebugUIPage>
|
||||
|
||||
@@ -19,8 +19,8 @@ public partial class ModbusRtuOverUdpDebugPage
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
public UdpSessionPage UdpSessionPage;
|
||||
private DriverDebugUIPage driverDebugUIPage;
|
||||
private UdpSessionPage _udpSessionPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp _plc;
|
||||
|
||||
@@ -66,10 +66,10 @@ public partial class ModbusRtuOverUdpDebugPage
|
||||
|
||||
""", "csharp"));
|
||||
|
||||
if (UdpSessionPage != null)
|
||||
UdpSessionPage.LogAction = driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp(UdpSessionPage.GetUdpSession());
|
||||
driverDebugUIPage.Plc = _plc;
|
||||
if (_udpSessionPage != null)
|
||||
_udpSessionPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp(_udpSessionPage.GetUdpSession());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
}
|
||||
@@ -19,22 +19,22 @@
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<SerialSessionPage @ref=SerialSessionPage></SerialSessionPage>
|
||||
<SerialSessionPage @ref=_serialSessionPage></SerialSessionPage>
|
||||
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
@if (_plc != null)
|
||||
{
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.DescriptionWithOutSugar(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumListWithOutSugar())
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.Description(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(DataFormat)u.Value)
|
||||
@@ -42,14 +42,14 @@
|
||||
Dense>
|
||||
</MSelect>
|
||||
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.DescriptionWithOutSugar(x => x.MulStation)) Dense HideDetails="@("auto")" @bind-Value=@_plc.MulStation></MCheckbox>
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.MulStation)) Dense HideDetails="@("auto")" @bind-Value=@_plc.MulStation></MCheckbox>
|
||||
|
||||
}
|
||||
</MRow>
|
||||
</MCard>
|
||||
|
||||
|
||||
<DriverDebugUIPage @ref=driverDebugUIPage Sections="_sections">
|
||||
<DriverDebugUIPage @ref=_driverDebugUIPage Sections="_sections">
|
||||
|
||||
</DriverDebugUIPage>
|
||||
|
||||
@@ -19,8 +19,8 @@ public partial class ModbusSerialServerDebugPage
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
public SerialSessionPage SerialSessionPage;
|
||||
private DriverDebugUIPage driverDebugUIPage;
|
||||
private SerialSessionPage _serialSessionPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusSerialServer _plc;
|
||||
|
||||
@@ -70,10 +70,10 @@ public partial class ModbusSerialServerDebugPage
|
||||
""", "csharp"));
|
||||
|
||||
|
||||
if (SerialSessionPage != null)
|
||||
SerialSessionPage.LogAction = driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusSerialServer(SerialSessionPage.GetSerialSession());
|
||||
driverDebugUIPage.Plc = _plc;
|
||||
if (_serialSessionPage != null)
|
||||
_serialSessionPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusSerialServer(_serialSessionPage.GetSerialSession());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
}
|
||||
@@ -18,22 +18,22 @@
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<TcpClientPage @ref=TcpClientPage></TcpClientPage>
|
||||
<TcpClientPage @ref=_tcpClientPage></TcpClientPage>
|
||||
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
@if (_plc != null)
|
||||
{
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.DescriptionWithOutSugar(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumListWithOutSugar())
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.Description(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(DataFormat)u.Value)
|
||||
@@ -41,14 +41,14 @@
|
||||
Dense>
|
||||
</MSelect>
|
||||
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.DescriptionWithOutSugar(x => x.IsCheckMessageId)) Dense HideDetails="@("auto")" @bind-Value=@_plc.IsCheckMessageId></MCheckbox>
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.IsCheckMessageId)) Dense HideDetails="@("auto")" @bind-Value=@_plc.IsCheckMessageId></MCheckbox>
|
||||
|
||||
}
|
||||
</MRow>
|
||||
</MCard>
|
||||
|
||||
|
||||
<DriverDebugUIPage @ref=driverDebugUIPage Sections="_sections">
|
||||
<DriverDebugUIPage @ref=_driverDebugUIPage Sections="_sections">
|
||||
|
||||
</DriverDebugUIPage>
|
||||
|
||||
@@ -16,14 +16,14 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
/// <inheritdoc/>
|
||||
public partial class ModbusTcpDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
private TcpClientPage TcpClientPage;
|
||||
private DriverDebugUIPage driverDebugUIPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp _plc;
|
||||
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
private TcpClientPage _tcpClientPage;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
@@ -67,10 +67,10 @@ public partial class ModbusTcpDebugPage
|
||||
|
||||
""", "csharp"));
|
||||
|
||||
if (TcpClientPage != null)
|
||||
TcpClientPage.LogAction = driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp(TcpClientPage.GetTcpClient());
|
||||
driverDebugUIPage.Plc = _plc;
|
||||
if (_tcpClientPage != null)
|
||||
_tcpClientPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp(_tcpClientPage.GetTcpClient());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
}
|
||||
@@ -18,21 +18,21 @@
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<TcpServerPage @ref=TcpServerPage></TcpServerPage>
|
||||
<TcpServerPage @ref=_tcpServerPage></TcpServerPage>
|
||||
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
@if (_plc != null)
|
||||
{
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.DescriptionWithOutSugar(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumListWithOutSugar())
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.Description(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(DataFormat)u.Value)
|
||||
@@ -40,14 +40,14 @@
|
||||
Dense>
|
||||
</MSelect>
|
||||
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.DescriptionWithOutSugar(x => x.IsCheckMessageId)) Dense HideDetails="@("auto")" @bind-Value=@_plc.IsCheckMessageId></MCheckbox>
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.IsCheckMessageId)) Dense HideDetails="@("auto")" @bind-Value=@_plc.IsCheckMessageId></MCheckbox>
|
||||
|
||||
}
|
||||
</MRow>
|
||||
</MCard>
|
||||
|
||||
|
||||
<DriverDebugUIPage @ref=driverDebugUIPage Sections="_sections">
|
||||
<DriverDebugUIPage @ref=_driverDebugUIPage Sections="_sections">
|
||||
|
||||
</DriverDebugUIPage>
|
||||
|
||||
@@ -20,8 +20,8 @@ public partial class ModbusTcpDtuDebugPage
|
||||
/// <summary>
|
||||
/// TcpServerPage
|
||||
/// </summary>
|
||||
public TcpServerPage TcpServerPage;
|
||||
private DriverDebugUIPage driverDebugUIPage;
|
||||
private TcpServerPage _tcpServerPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpDtu _plc;
|
||||
|
||||
@@ -68,10 +68,10 @@ public partial class ModbusTcpDtuDebugPage
|
||||
|
||||
""", "csharp"));
|
||||
|
||||
if (TcpServerPage != null)
|
||||
TcpServerPage.LogAction = driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpDtu(TcpServerPage.GetTcpServer());
|
||||
driverDebugUIPage.Plc = _plc;
|
||||
if (_tcpServerPage != null)
|
||||
_tcpServerPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpDtu(_tcpServerPage.GetTcpServer());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
}
|
||||
@@ -18,21 +18,21 @@
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<TcpServerPage @ref=TcpServerPage></TcpServerPage>
|
||||
<TcpServerPage @ref=_tcpServerPage></TcpServerPage>
|
||||
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
@if (_plc != null)
|
||||
{
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.DescriptionWithOutSugar(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumListWithOutSugar())
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.Description(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(DataFormat)u.Value)
|
||||
@@ -40,14 +40,14 @@
|
||||
Dense>
|
||||
</MSelect>
|
||||
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.DescriptionWithOutSugar(x => x.MulStation)) Dense HideDetails="@("auto")" @bind-Value=@_plc.MulStation></MCheckbox>
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.MulStation)) Dense HideDetails="@("auto")" @bind-Value=@_plc.MulStation></MCheckbox>
|
||||
|
||||
}
|
||||
</MRow>
|
||||
</MCard>
|
||||
|
||||
|
||||
<DriverDebugUIPage @ref=driverDebugUIPage Sections="_sections">
|
||||
<DriverDebugUIPage @ref=_driverDebugUIPage Sections="_sections">
|
||||
|
||||
</DriverDebugUIPage>
|
||||
|
||||
@@ -20,8 +20,8 @@ public partial class ModbusTcpServerDebugPage
|
||||
/// <summary>
|
||||
/// TcpServerPage
|
||||
/// </summary>
|
||||
public TcpServerPage TcpServerPage;
|
||||
private DriverDebugUIPage driverDebugUIPage;
|
||||
private TcpServerPage _tcpServerPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpServer _plc;
|
||||
|
||||
@@ -68,10 +68,10 @@ public partial class ModbusTcpServerDebugPage
|
||||
|
||||
""", "csharp"));
|
||||
|
||||
if (TcpServerPage != null)
|
||||
TcpServerPage.LogAction = driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpServer(TcpServerPage.GetTcpServer());
|
||||
driverDebugUIPage.Plc = _plc;
|
||||
if (_tcpServerPage != null)
|
||||
_tcpServerPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpServer(_tcpServerPage.GetTcpServer());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
}
|
||||
@@ -18,22 +18,22 @@
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<UdpSessionPage @ref=UdpSessionPage></UdpSessionPage>
|
||||
<UdpSessionPage @ref=_udpSessionPage></UdpSessionPage>
|
||||
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
@if (_plc != null)
|
||||
{
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.DescriptionWithOutSugar(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.Station)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.DescriptionWithOutSugar(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumListWithOutSugar())
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.Description(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(DataFormat)u.Value)
|
||||
@@ -41,14 +41,14 @@
|
||||
Dense>
|
||||
</MSelect>
|
||||
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.DescriptionWithOutSugar(x => x.IsCheckMessageId)) Dense HideDetails="@("auto")" @bind-Value=@_plc.IsCheckMessageId></MCheckbox>
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.IsCheckMessageId)) Dense HideDetails="@("auto")" @bind-Value=@_plc.IsCheckMessageId></MCheckbox>
|
||||
|
||||
}
|
||||
</MRow>
|
||||
</MCard>
|
||||
|
||||
|
||||
<DriverDebugUIPage @ref=driverDebugUIPage Sections="_sections">
|
||||
<DriverDebugUIPage @ref=_driverDebugUIPage Sections="_sections">
|
||||
|
||||
</DriverDebugUIPage>
|
||||
|
||||
@@ -19,8 +19,8 @@ public partial class ModbusUdpDebugPage
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
public UdpSessionPage UdpSessionPage;
|
||||
private DriverDebugUIPage driverDebugUIPage;
|
||||
private UdpSessionPage _udpSessionPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp _plc;
|
||||
|
||||
@@ -66,10 +66,10 @@ public partial class ModbusUdpDebugPage
|
||||
|
||||
""", "csharp"));
|
||||
|
||||
if (UdpSessionPage != null)
|
||||
UdpSessionPage.LogAction = driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp(UdpSessionPage.GetUdpSession());
|
||||
driverDebugUIPage.Plc = _plc;
|
||||
if (_udpSessionPage != null)
|
||||
_udpSessionPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp(_udpSessionPage.GetUdpSession());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
@using Microsoft.AspNetCore.Components.Web;
|
||||
@using Masa.Blazor.Presets;
|
||||
@using Microsoft.JSInterop;
|
||||
@inherits BaseComponentBase
|
||||
|
||||
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@@ -33,11 +34,11 @@
|
||||
|
||||
|
||||
|
||||
<DriverDebugUIPage @ref=driverDebugUIPage Sections="_sections" ShowDefaultOtherContent=false>
|
||||
<DriverDebugUIPage @ref=_driverDebugUIPage Sections="_sections" ShowDefaultOtherContent=false>
|
||||
<ReadWriteContent>
|
||||
<div class="my-1 py-1">
|
||||
|
||||
<MTextarea Class="mx-1 my-1" Label="变量地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@driverDebugUIPage.Address />
|
||||
<MTextarea Class="mx-1 my-1" Label="变量地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@_driverDebugUIPage.Address />
|
||||
|
||||
<MButton Class="mx-1 my-1" Color="primary" OnClick="Add">
|
||||
添加
|
||||
@@ -49,7 +50,7 @@
|
||||
组读取
|
||||
</MButton>
|
||||
|
||||
<MTextarea Class="mx-1 mt-3 my-1" Label="值" Dense Outlined HideDetails="@("auto")" @bind-Value=@driverDebugUIPage.WriteValue />
|
||||
<MTextarea Class="mx-1 mt-3 my-1" Label="值" Dense Outlined HideDetails="@("auto")" @bind-Value=@_driverDebugUIPage.WriteValue />
|
||||
<MButton Class="mx-1 my-1" Color="primary" OnClick="WriteAsync">
|
||||
写入
|
||||
</MButton>
|
||||
@@ -15,6 +15,7 @@ using BlazorComponent;
|
||||
using Masa.Blazor;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
@@ -32,18 +33,15 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class OPCDAClientDebugPage : IDisposable
|
||||
{
|
||||
private ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient _plc;
|
||||
private DriverDebugUIPage driverDebugUIPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
bool IsShowImportVariableList;
|
||||
private OPCDAClientPage opcDAClientPage;
|
||||
private OPCDAImportVariable ImportVariable { get; set; }
|
||||
[Inject]
|
||||
private InitTimezone InitTimezone { get; set; }
|
||||
|
||||
[Inject]
|
||||
IPopupService PopupService { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
public override void Dispose()
|
||||
{
|
||||
_plc.SafeDispose();
|
||||
opcDAClientPage.SafeDispose();
|
||||
@@ -62,14 +60,14 @@ public partial class OPCDAClientDebugPage : IDisposable
|
||||
{
|
||||
if (opcDAClientPage != null)
|
||||
{
|
||||
opcDAClientPage.LogAction = driverDebugUIPage.LogOut;
|
||||
opcDAClientPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
opcDAClientPage.ValueAction = ValueOut;
|
||||
|
||||
}
|
||||
_plc = opcDAClientPage.OPC;
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
driverDebugUIPage.Sections.Clear();
|
||||
_driverDebugUIPage.Sections.Clear();
|
||||
}
|
||||
|
||||
base.OnAfterRender(firstRender);
|
||||
@@ -78,7 +76,7 @@ public partial class OPCDAClientDebugPage : IDisposable
|
||||
private void Add()
|
||||
{
|
||||
var tags = new Dictionary<string, List<OpcItem>>();
|
||||
var tag = new OpcItem(driverDebugUIPage.Address);
|
||||
var tag = new OpcItem(_driverDebugUIPage.Address);
|
||||
tags.Add(Guid.NewGuid().ToString(), new List<OpcItem>() { tag });
|
||||
try
|
||||
{
|
||||
@@ -86,7 +84,7 @@ public partial class OPCDAClientDebugPage : IDisposable
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, $"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - {ex}"));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, $"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - {ex}"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,8 +105,8 @@ public partial class OPCDAClientDebugPage : IDisposable
|
||||
await PopupService.EnqueueSnackbarAsync("无可用变量", AlertTypes.Warning);
|
||||
return;
|
||||
}
|
||||
await Furion.App.GetService<CollectDeviceService>().AddAsync(data?.Item1);
|
||||
await Furion.App.GetService<VariableService>().AddBatchAsync(data?.Item2);
|
||||
await _serviceScope.ServiceProvider.GetService<CollectDeviceService>().AddAsync(data?.Item1);
|
||||
await _serviceScope.ServiceProvider.GetService<VariableService>().AddBatchAsync(data?.Item2);
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
}
|
||||
@@ -153,7 +151,7 @@ public partial class OPCDAClientDebugPage : IDisposable
|
||||
/// <returns></returns>
|
||||
public async Task DownDeviceExportAsync(CollectDevice data)
|
||||
{
|
||||
using var memoryStream = await Furion.App.GetService<CollectDeviceService>().ExportFileAsync(new List<CollectDevice>() { data });
|
||||
using var memoryStream = await _serviceScope.ServiceProvider.GetService<CollectDeviceService>().ExportFileAsync(new List<CollectDevice>() { data });
|
||||
using var streamRef = new DotNetStreamReference(stream: memoryStream);
|
||||
JSObjectReference ??= await JSRuntime.LoadModuleAsync("js/downloadFileFromStream");
|
||||
await JSObjectReference.InvokeVoidAsync("downloadFileFromStream", $"设备导出{DateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx", streamRef);
|
||||
@@ -165,7 +163,7 @@ public partial class OPCDAClientDebugPage : IDisposable
|
||||
/// <returns></returns>
|
||||
public async Task DownDeviceVariableExportAsync(List<DeviceVariable> data, string devName)
|
||||
{
|
||||
using var memoryStream = await Furion.App.GetService<VariableService>().ExportFileAsync(data, devName);
|
||||
using var memoryStream = await _serviceScope.ServiceProvider.GetService<VariableService>().ExportFileAsync(data, devName);
|
||||
using var streamRef = new DotNetStreamReference(stream: memoryStream);
|
||||
JSObjectReference ??= await JSRuntime.LoadModuleAsync("js/downloadFileFromStream");
|
||||
await JSObjectReference.InvokeVoidAsync("downloadFileFromStream", $"变量导出{DateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx", streamRef);
|
||||
@@ -173,7 +171,7 @@ public partial class OPCDAClientDebugPage : IDisposable
|
||||
|
||||
#endif
|
||||
|
||||
private Task ReadAsync()
|
||||
private async Task ReadAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -182,55 +180,55 @@ public partial class OPCDAClientDebugPage : IDisposable
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, $"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - {ex}"));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, $"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - {ex}"));
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
private void Remove()
|
||||
{
|
||||
_plc.RemoveItems(new List<string>() { driverDebugUIPage.Address });
|
||||
_plc.RemoveItems(new List<string>() { _driverDebugUIPage.Address });
|
||||
}
|
||||
|
||||
private void ValueOut(List<ItemReadResult> values)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Debug, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + values.ToJsonString()));
|
||||
if (driverDebugUIPage.Messages.Count > 2500)
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Debug, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + values.ToJsonString()));
|
||||
if (_driverDebugUIPage.Messages.Count > 2500)
|
||||
{
|
||||
driverDebugUIPage.Messages.Clear();
|
||||
_driverDebugUIPage.Messages.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private Task WriteAsync()
|
||||
private async Task WriteAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
JToken tagValue = driverDebugUIPage.WriteValue.GetJTokenFromObj();
|
||||
JToken tagValue = _driverDebugUIPage.WriteValue.GetJTokenFromObj();
|
||||
var obj = tagValue.GetObjFromJToken();
|
||||
|
||||
var data = _plc.WriteItem(
|
||||
new()
|
||||
{
|
||||
{driverDebugUIPage.Address, obj}
|
||||
{_driverDebugUIPage.Address, obj}
|
||||
}
|
||||
);
|
||||
if (data.Count > 0)
|
||||
{
|
||||
foreach (var item in data)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + item.ToJsonString()));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + item.ToJsonString()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - 写入成功"));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - 写入成功"));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Error, $"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 写入失败:{ex}"));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Error, $"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 写入失败:{ex}"));
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -16,17 +16,21 @@
|
||||
@using System.IO.Ports;
|
||||
@using System.Collections.Concurrent;
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using ThingsGateway.Foundation.Adapter.OPCDA;
|
||||
@using Masa.Blazor
|
||||
@implements IDisposable
|
||||
<MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%">
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">设备配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
<MTextField Class="ma-1" Label=IP Dense Outlined HideDetails="@("auto")" @bind-Value=@IP />
|
||||
<MTextField Class="ma-1" Label=端口 Dense Outlined HideDetails="@("auto")" @bind-Value=@Port />
|
||||
<MTextField Class="ma-1" Label=@node.Description(a=>a.GroupSize) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.GroupSize />
|
||||
<MTextField Class="ma-1" Label=@node.Description(a=>a.UpdateRate) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.UpdateRate />
|
||||
|
||||
<MTextField Class="ma-1" Label=ID Dense Outlined HideDetails="@("auto")" @bind-Value=@ConnectId />
|
||||
<MTextField Class="ma-1" Label=用户 Dense Outlined HideDetails="@("auto")" @bind-Value=@UserName />
|
||||
<MTextField Class="ma-1" Label=密码 Dense Outlined HideDetails="@("auto")" @bind-Value=@Password />
|
||||
<MTextField Class="ma-1" Label=@node.Description(a=>a.DeadBand) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.DeadBand />
|
||||
<MTextField Class="ma-1" Label=@node.Description(a=>a.CheckRate) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.CheckRate />
|
||||
<MTextField Class="ma-1" Label=@node.Description(a=>a.OPCIP) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.OPCIP />
|
||||
<MTextField Class="ma-1" Label=@node.Description(a=>a.OPCName) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.OPCName />
|
||||
|
||||
<MCheckbox Class="ma-1" Label=@node.Description(a=>a.ActiveSubscribe) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.ActiveSubscribe />
|
||||
|
||||
<MButton Class="ma-1" OnClick=@Connect Color="primary">
|
||||
连接
|
||||
@@ -19,7 +19,7 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
/// <summary>
|
||||
/// OPC
|
||||
/// </summary>
|
||||
public partial class OPCDAClientPage
|
||||
public partial class OPCDAClientPage : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 日志输出
|
||||
@@ -36,7 +36,7 @@ public partial class OPCDAClientPage
|
||||
/// </summary>
|
||||
public Action<List<ItemReadResult>> ValueAction;
|
||||
|
||||
private readonly OPCNode node = new();
|
||||
private readonly OPCDANode node = new();
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
@@ -14,6 +14,7 @@
|
||||
@using BlazorComponent;
|
||||
@using Microsoft.AspNetCore.Components.Web;
|
||||
@using System.Reflection;
|
||||
@inherits BaseComponentBase
|
||||
|
||||
@using ThingsGateway.Foundation.Adapter.OPCDA;
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@@ -17,7 +17,6 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
using ThingsGateway.Foundation.Adapter.OPCDA.Rcw;
|
||||
using ThingsGateway.Foundation.Extension;
|
||||
#if Plugin
|
||||
using ThingsGateway.Plugin.OPCDA;
|
||||
#endif
|
||||
@@ -98,7 +97,7 @@ public partial class OPCDAImportVariable
|
||||
return new DeviceVariable()
|
||||
{
|
||||
Name = a.Name + "-" + id,
|
||||
VariableAddress = a.ItemName,
|
||||
Address = a.ItemName,
|
||||
DeviceId = device.Id,
|
||||
Id = id,
|
||||
ProtectTypeEnum = level,
|
||||
@@ -118,7 +117,7 @@ public partial class OPCDAImportVariable
|
||||
Enable = true,
|
||||
IsLogOut = true,
|
||||
DevicePropertys = new(),
|
||||
PluginId = Furion.App.GetService<DriverPluginService>().GetIdByName(nameof(ThingsGateway.Plugin.OPCDA.OPCDAClient)).ToLong(),
|
||||
PluginName = "ThingsGateway.Plugin.OPCDA.OPCDAClient",
|
||||
};
|
||||
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.OPCName), Value = PLC.OPCNode.OPCName, Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.OPCName)).GetCustomAttribute<DevicePropertyAttribute>().Description });
|
||||
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.OPCIP), Value = PLC.OPCNode.OPCIP, Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.OPCIP)).GetCustomAttribute<DevicePropertyAttribute>().Description });
|
||||
@@ -204,13 +203,13 @@ public partial class OPCDAImportVariable
|
||||
|
||||
}
|
||||
|
||||
private Task PopulateBranchAsync(OPCDATagModel model)
|
||||
private async Task PopulateBranchAsync(OPCDATagModel model)
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
var sourceId = model.Tag.ItemName;
|
||||
model.Nodes = PopulateBranch(sourceId);
|
||||
});
|
||||
await Task.Run(() =>
|
||||
{
|
||||
var sourceId = model.Tag.ItemName;
|
||||
model.Nodes = PopulateBranch(sourceId);
|
||||
});
|
||||
}
|
||||
internal class OPCDATagModel
|
||||
{
|
||||
@@ -19,6 +19,7 @@
|
||||
@using Microsoft.AspNetCore.Components.Web;
|
||||
@using Masa.Blazor.Presets;
|
||||
@using Microsoft.JSInterop;
|
||||
@inherits BaseComponentBase
|
||||
|
||||
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@@ -32,11 +33,11 @@
|
||||
|
||||
|
||||
|
||||
<DriverDebugUIPage @ref=driverDebugUIPage Sections="_sections" ShowDefaultOtherContent=false>
|
||||
<DriverDebugUIPage @ref=_driverDebugUIPage Sections="_sections" ShowDefaultOtherContent=false>
|
||||
<ReadWriteContent>
|
||||
<div class="my-1 py-1">
|
||||
|
||||
<MTextarea Class="mx-1 my-1" Label="变量地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@driverDebugUIPage.Address />
|
||||
<MTextarea Class="mx-1 my-1" Label="变量地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@_driverDebugUIPage.Address />
|
||||
|
||||
<MButton Class="mx-1 my-1" Color="primary" OnClick="Add">
|
||||
添加
|
||||
@@ -48,7 +49,7 @@
|
||||
组读取
|
||||
</MButton>
|
||||
|
||||
<MTextarea Class="mx-1 mt-3 my-1" Label="值" Dense Outlined HideDetails="@("auto")" @bind-Value=@driverDebugUIPage.WriteValue />
|
||||
<MTextarea Class="mx-1 mt-3 my-1" Label="值" Dense Outlined HideDetails="@("auto")" @bind-Value=@_driverDebugUIPage.WriteValue />
|
||||
<MButton Class="mx-1 my-1" Color="primary" OnClick="WriteAsync">
|
||||
写入
|
||||
</MButton>
|
||||
@@ -15,6 +15,7 @@ using BlazorComponent;
|
||||
using Masa.Blazor;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
@@ -30,23 +31,21 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class OPCUAClientDebugPage
|
||||
{
|
||||
private ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient _plc;
|
||||
private DriverDebugUIPage driverDebugUIPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
bool IsShowImportVariableList;
|
||||
private OPCUAClientPage opcUAClientPage;
|
||||
private OPCUAImportVariable ImportVariable { get; set; }
|
||||
[Inject]
|
||||
private InitTimezone InitTimezone { get; set; }
|
||||
|
||||
[Inject]
|
||||
IPopupService PopupService { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
public override void Dispose()
|
||||
{
|
||||
_plc.SafeDispose();
|
||||
opcUAClientPage.SafeDispose();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -62,13 +61,13 @@ public partial class OPCUAClientDebugPage
|
||||
{
|
||||
if (opcUAClientPage != null)
|
||||
{
|
||||
opcUAClientPage.LogAction = driverDebugUIPage.LogOut;
|
||||
opcUAClientPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = opcUAClientPage.OPC;
|
||||
_plc.DataChangedHandler += Plc_DataChangedHandler;
|
||||
}
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
driverDebugUIPage.Sections.Clear();
|
||||
_driverDebugUIPage.Sections.Clear();
|
||||
|
||||
}
|
||||
|
||||
@@ -77,10 +76,10 @@ public partial class OPCUAClientDebugPage
|
||||
private async Task Add()
|
||||
{
|
||||
if (_plc.Connected)
|
||||
await _plc.AddSubscriptionAsync(Guid.NewGuid().ToString(), new[] { driverDebugUIPage.Address });
|
||||
await _plc.AddSubscriptionAsync(Guid.NewGuid().ToString(), new[] { _driverDebugUIPage.Address });
|
||||
else
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Debug, $"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 未连接"));
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Debug, $"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 未连接"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,8 +96,8 @@ public partial class OPCUAClientDebugPage
|
||||
await PopupService.EnqueueSnackbarAsync("无可用变量", AlertTypes.Warning);
|
||||
return;
|
||||
}
|
||||
await Furion.App.GetService<CollectDeviceService>().AddAsync(data.Item1);
|
||||
await Furion.App.GetService<VariableService>().AddBatchAsync(data.Item2);
|
||||
await _serviceScope.ServiceProvider.GetService<CollectDeviceService>().AddAsync(data.Item1);
|
||||
await _serviceScope.ServiceProvider.GetService<VariableService>().AddBatchAsync(data.Item2);
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
finally
|
||||
@@ -142,7 +141,7 @@ public partial class OPCUAClientDebugPage
|
||||
/// <returns></returns>
|
||||
public async Task DownDeviceExportAsync(CollectDevice data)
|
||||
{
|
||||
using var memoryStream = await Furion.App.GetService<CollectDeviceService>().ExportFileAsync(new List<CollectDevice>() { data });
|
||||
using var memoryStream = await _serviceScope.ServiceProvider.GetService<CollectDeviceService>().ExportFileAsync(new List<CollectDevice>() { data });
|
||||
using var streamRef = new DotNetStreamReference(stream: memoryStream);
|
||||
JSObjectReference ??= await JSRuntime.LoadModuleAsync("js/downloadFileFromStream");
|
||||
await JSObjectReference.InvokeVoidAsync("downloadFileFromStream", $"设备导出{DateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx", streamRef);
|
||||
@@ -154,7 +153,7 @@ public partial class OPCUAClientDebugPage
|
||||
/// <returns></returns>
|
||||
public async Task DownDeviceVariableExportAsync(List<DeviceVariable> data, string devName)
|
||||
{
|
||||
using var memoryStream = await Furion.App.GetService<VariableService>().ExportFileAsync(data, devName);
|
||||
using var memoryStream = await _serviceScope.ServiceProvider.GetService<VariableService>().ExportFileAsync(data, devName);
|
||||
using var streamRef = new DotNetStreamReference(stream: memoryStream);
|
||||
JSObjectReference ??= await JSRuntime.LoadModuleAsync("js/downloadFileFromStream");
|
||||
await JSObjectReference.InvokeVoidAsync("downloadFileFromStream", $"变量导出{DateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx", streamRef);
|
||||
@@ -164,11 +163,11 @@ public partial class OPCUAClientDebugPage
|
||||
|
||||
private void Plc_DataChangedHandler((VariableNode variableNode, DataValue dataValue, Newtonsoft.Json.Linq.JToken jToken) item)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Debug,
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Debug,
|
||||
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - {item.variableNode.NodeId}:{item.jToken}"));
|
||||
if (driverDebugUIPage.Messages.Count > 2500)
|
||||
if (_driverDebugUIPage.Messages.Count > 2500)
|
||||
{
|
||||
driverDebugUIPage.Messages.Clear();
|
||||
_driverDebugUIPage.Messages.Clear();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -178,20 +177,20 @@ public partial class OPCUAClientDebugPage
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await _plc.ReadJTokenValueAsync(new string[] { driverDebugUIPage.Address });
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Debug,
|
||||
var data = await _plc.ReadJTokenValueAsync(new string[] { _driverDebugUIPage.Address });
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Debug,
|
||||
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - {data[0].Item1}:{data[0].Item3}"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning,
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning,
|
||||
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - {ex}"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning,
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning,
|
||||
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 未连接"));
|
||||
}
|
||||
}
|
||||
@@ -201,7 +200,7 @@ public partial class OPCUAClientDebugPage
|
||||
_plc.RemoveSubscription("");
|
||||
else
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning,
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning,
|
||||
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 未连接"));
|
||||
}
|
||||
}
|
||||
@@ -215,25 +214,25 @@ public partial class OPCUAClientDebugPage
|
||||
var data = await _plc.WriteNodeAsync(
|
||||
new()
|
||||
{
|
||||
{ driverDebugUIPage.Address, JToken.Parse(driverDebugUIPage.WriteValue)}
|
||||
{ _driverDebugUIPage.Address, JToken.Parse(_driverDebugUIPage.WriteValue)}
|
||||
}
|
||||
);
|
||||
|
||||
foreach (var item in data)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((item.Value.Item1 ? Microsoft.Extensions.Logging.LogLevel.Warning : Microsoft.Extensions.Logging.LogLevel.Information,
|
||||
_driverDebugUIPage.Messages.Add((item.Value.Item1 ? Microsoft.Extensions.Logging.LogLevel.Warning : Microsoft.Extensions.Logging.LogLevel.Information,
|
||||
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - {item.Value.Item2}"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning,
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning,
|
||||
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 未连接"));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Error,
|
||||
_driverDebugUIPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Error,
|
||||
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - {ex}"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
@*
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
*@
|
||||
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
@using BlazorComponent;
|
||||
@using Microsoft.AspNetCore.Components.Web;
|
||||
@using System.IO.Ports;
|
||||
@using System.Collections.Concurrent;
|
||||
@using Opc.Ua.Client;
|
||||
@using Opc.Ua;
|
||||
@using System.Linq;
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using ThingsGateway.Foundation.Adapter.OPCUA;
|
||||
@using Masa.Blazor
|
||||
@implements IDisposable
|
||||
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">设备配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
<MTextField Class="ma-1" Label=@node.Description(a=>a.GroupSize) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.GroupSize />
|
||||
<MTextField Class="ma-1" Label=@node.Description(a=>a.UpdateRate) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.UpdateRate />
|
||||
|
||||
<MTextField Class="ma-1" Label=@node.Description(a=>a.DeadBand) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.DeadBand />
|
||||
<MTextField Class="ma-1" Label=@node.Description(a=>a.KeepAliveInterval) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.KeepAliveInterval />
|
||||
|
||||
<MTextField Class="ma-1" Label=@node.Description(a=>a.OPCUrl) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.OPCUrl />
|
||||
<MTextField Class="ma-1" Label=@node.Description(a=>a.UserName) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.UserName />
|
||||
<MTextField Class="ma-1" Label=@node.Description(a=>a.Password) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.Password />
|
||||
|
||||
<MCheckbox Class="ma-1" Label=@node.Description(a=>a.ActiveSubscribe) Dense HideDetails="@("auto")" @bind-Value=@node.ActiveSubscribe />
|
||||
<MCheckbox Class="ma-1" Label=@node.Description(a=>a.IsUseSecurity) Dense HideDetails="@("auto")" @bind-Value=@node.IsUseSecurity />
|
||||
<MCheckbox Class="ma-1" Label=@node.Description(a=>a.CheckDomain) Dense HideDetails="@("auto")" @bind-Value=@node.CheckDomain />
|
||||
<MCheckbox Class="ma-1" Label=@node.Description(a=>a.LoadType) Dense HideDetails="@("auto")" @bind-Value=@node.LoadType />
|
||||
|
||||
<MButton Class="ma-1" OnClick=@ConnectAsync Color="primary">
|
||||
连接
|
||||
</MButton>
|
||||
|
||||
<MButton Class="ma-1" OnClick=@DisConnect Color="red">
|
||||
断开
|
||||
</MButton>
|
||||
</MRow>
|
||||
|
||||
|
||||
|
||||
</MCard>
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
/// <summary>
|
||||
/// OPCUAClientPage
|
||||
/// </summary>
|
||||
public partial class OPCUAClientPage
|
||||
public partial class OPCUAClientPage : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 日志输出
|
||||
@@ -28,7 +28,7 @@ public partial class OPCUAClientPage
|
||||
/// </summary>
|
||||
public ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient OPC;
|
||||
|
||||
private readonly OPCNode node = new();
|
||||
private readonly OPCUANode node = new();
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -11,6 +11,7 @@
|
||||
*@
|
||||
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
@inherits BaseComponentBase
|
||||
|
||||
@using BlazorComponent;
|
||||
@using Microsoft.AspNetCore.Components.Web;
|
||||
@@ -19,7 +19,6 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
using ThingsGateway.Foundation.Adapter.OPCUA;
|
||||
using ThingsGateway.Foundation.Extension;
|
||||
|
||||
#if Plugin
|
||||
using ThingsGateway.Plugin.OPCUA;
|
||||
@@ -116,7 +115,7 @@ public partial class OPCUAImportVariable
|
||||
return new DeviceVariable()
|
||||
{
|
||||
Name = a.DisplayName.Text + "-" + id,
|
||||
VariableAddress = a.NodeId.ToString(),
|
||||
Address = a.NodeId.ToString(),
|
||||
DeviceId = device.Id,
|
||||
DataTypeEnum = dataTypeEnum,
|
||||
Id = id,
|
||||
@@ -145,7 +144,7 @@ public partial class OPCUAImportVariable
|
||||
Enable = true,
|
||||
IsLogOut = true,
|
||||
DevicePropertys = new(),
|
||||
PluginId = Furion.App.GetService<DriverPluginService>().GetIdByName(nameof(ThingsGateway.Plugin.OPCUA.OPCUAClient)).ToLong(),
|
||||
PluginName = "ThingsGateway.Plugin.OPCUA.OPCUAClient",
|
||||
};
|
||||
|
||||
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCUAClientProperty.OPCURL), Value = PLC.OPCNode.OPCUrl, Description = typeof(OPCUAClientProperty).GetProperty(nameof(OPCUAClientProperty.OPCURL)).GetCustomAttribute<DevicePropertyAttribute>().Description });
|
||||
@@ -289,9 +288,9 @@ public partial class OPCUAImportVariable
|
||||
return nodes;
|
||||
}
|
||||
|
||||
private Task<TResult[]> SelectAsync<T, TResult>(IEnumerable<T> source, Func<T, Task<TResult>> selector)
|
||||
private async Task<TResult[]> SelectAsync<T, TResult>(IEnumerable<T> source, Func<T, Task<TResult>> selector)
|
||||
{
|
||||
return Task.WhenAll(source.Select(selector));
|
||||
return await Task.WhenAll(source.Select(selector));
|
||||
}
|
||||
internal class OPCUATagModel
|
||||
{
|
||||
@@ -0,0 +1,75 @@
|
||||
@*
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
*@
|
||||
|
||||
@page "/Siemens"
|
||||
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
@using BlazorComponent;
|
||||
@using Microsoft.AspNetCore.Components.Web;
|
||||
@using Microsoft.JSInterop;
|
||||
|
||||
@using ThingsGateway.Foundation.Adapter.Siemens;
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using ThingsGateway.Foundation.Extension;
|
||||
@using ThingsGateway.Foundation.Serial;
|
||||
|
||||
@using Masa.Blazor
|
||||
|
||||
|
||||
<TcpClientPage @ref=_tcpClientPage></TcpClientPage>
|
||||
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
@if (_plc != null)
|
||||
{
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.FrameTime)) Dense HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.CacheTimeout)) Dense HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.TimeOut)) Dense HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.Slot)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Slot></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(_plc.Description(x => x.Rack)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Rack></MTextField>
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.SiemensEnum" Label="@(_plc.Description(x => x.SiemensEnum))"
|
||||
Items=@(typeof(SiemensEnum).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(SiemensEnum)u.Value)
|
||||
HideDetails=@("auto") Height="30"
|
||||
Dense>
|
||||
</MSelect>
|
||||
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px" @bind-Value="_plc.DataFormat" Label="@(_plc.Description(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
ItemValue=@(u =>(DataFormat)u.Value)
|
||||
HideDetails=@("auto") Height="30"
|
||||
Dense>
|
||||
</MSelect>
|
||||
|
||||
}
|
||||
</MRow>
|
||||
</MCard>
|
||||
|
||||
|
||||
<DriverDebugUIPage @ref=_driverDebugUIPage Sections="_sections">
|
||||
|
||||
</DriverDebugUIPage>
|
||||
|
||||
|
||||
@code {
|
||||
private readonly List<(string Code, string Language)> _sections = new();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,22 +10,20 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using ThingsGateway.Foundation.Adapter.Siemens;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public partial class S7_200DebugPage
|
||||
public partial class SiemensDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
private TcpClientPage TcpClientPage;
|
||||
private DriverDebugUIPage driverDebugUIPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
private ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC _plc;
|
||||
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
private TcpClientPage _tcpClientPage;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
@@ -69,17 +67,17 @@ public partial class S7_200DebugPage
|
||||
|
||||
""", "csharp"));
|
||||
|
||||
if (TcpClientPage != null)
|
||||
TcpClientPage.LogAction = driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC(TcpClientPage.GetTcpClient(), SiemensEnum.S200);
|
||||
driverDebugUIPage.Plc = _plc;
|
||||
if (_tcpClientPage != null)
|
||||
_tcpClientPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC(_tcpClientPage.GetTcpClient());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
|
||||
//初始化
|
||||
driverDebugUIPage.Address = "M100";
|
||||
_driverDebugUIPage.Address = "M100";
|
||||
int index = 0;
|
||||
driverDebugUIPage.DeviceVariableRunTimes.ForEach(a => a.VariableAddress = "M" + (100 + index++));
|
||||
TcpClientPage.Port = 102;
|
||||
TcpClientPage.StateHasChangedAsync();
|
||||
_driverDebugUIPage.DeviceVariableRunTimes.ForEach(a => a.Address = "M" + (100 + index++));
|
||||
_tcpClientPage._port = 102;
|
||||
_tcpClientPage.StateHasChangedAsync();
|
||||
|
||||
|
||||
//载入配置
|
||||
@@ -24,7 +24,7 @@
|
||||
<Logo CONFIG_COPYRIGHT=@CONFIG_COPYRIGHT CONFIG_TITLE=@CONFIG_TITLE HeightInt=@(IsMobile?BlazorResourceConst.AppBarHeight:BlazorResourceConst.AppBarHeight+BlazorResourceConst.PageTabsHeight) />
|
||||
<AppList ClassString="overflow-y-auto" Routable
|
||||
StyleString=@($"height: calc(100vh - {BlazorResourceConst.AppBarHeight+BlazorResourceConst.PageTabsHeight}px);")
|
||||
Items="Navs" />
|
||||
Items="_navs" />
|
||||
</MNavigationDrawer>
|
||||
|
||||
<MAppBar Color="barcolor" Style=@($"{(!(IsMobile||_drawerOpen!=true)? "left:200px;":"")}") Elevation="1" App Flat ClippedRight Dense ElevateOnScroll
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
<MMain Style=@($"{(!(IsMobile||_drawerOpen!=true)? "padding-left:200px;":"")}")>
|
||||
<div class="full-width">
|
||||
<PageTabs @ref="_pageTabs" PageTabItems="pageTabItems" />
|
||||
<PageTabs @ref="_pageTabs" PageTabItems="_pageTabItems" />
|
||||
</div>
|
||||
<MDivider Center></MDivider>
|
||||
<MCard Flat Class="overflow-y-auto overflow-x-hidden ma-auto pa-0 rounded-0" Style=@($"height: calc(100vh - {BlazorResourceConst.AppBarHeight+BlazorResourceConst.PageTabsHeight+BlazorResourceConst.FooterHeight}px);")>
|
||||
|
||||
@@ -17,8 +17,9 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class MainLayout
|
||||
{
|
||||
|
||||
private List<NavItem> Navs { get; set; } = new();
|
||||
private List<PageTabItem> pageTabItems { get; set; } = new();
|
||||
private List<NavItem> _navs { get; set; } = new();
|
||||
private List<PageTabItem> _pageTabItems { get; set; } = new();
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
var dataString =
|
||||
@@ -69,28 +70,8 @@ public partial class MainLayout
|
||||
"Title": "Siemens",
|
||||
"Children": [
|
||||
{
|
||||
"Href": "/S7_1500",
|
||||
"Title": "S7_1500"
|
||||
},
|
||||
{
|
||||
"Href": "/S7_1200",
|
||||
"Title": "S7_1200"
|
||||
},
|
||||
{
|
||||
"Href": "/S7_200",
|
||||
"Title": "S7_200"
|
||||
},
|
||||
{
|
||||
"Href": "/S7_200SMART",
|
||||
"Title": "S7_200SMART"
|
||||
},
|
||||
{
|
||||
"Href": "/S7_300",
|
||||
"Title": "S7_400"
|
||||
},
|
||||
{
|
||||
"Href": "/S7_400",
|
||||
"Title": "S7_400"
|
||||
"Href": "/Siemens",
|
||||
"Title": "Siemens"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -138,7 +119,7 @@ public partial class MainLayout
|
||||
|
||||
|
||||
""";
|
||||
Navs = dataString.FromJsonString<List<NavItem>>();
|
||||
_navs = dataString.FromJsonString<List<NavItem>>();
|
||||
|
||||
#if Pro
|
||||
var dataStringPro =
|
||||
@@ -247,7 +228,7 @@ public partial class MainLayout
|
||||
""";
|
||||
Navs.AddRange(dataStringPro.FromJsonString<List<NavItem>>());
|
||||
#endif
|
||||
pageTabItems = Navs.PasePageTabItem();
|
||||
_pageTabItems = _navs.PasePageTabItem();
|
||||
base.OnInitialized();
|
||||
}
|
||||
}
|
||||
@@ -1,159 +1,14 @@
|
||||
<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' 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" />
|
||||
|
||||
<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.Omron\Page\OmronFinsTcpDebugPage.razor.cs" Link="Pages\OmronFins\OmronFinsTcpDebugPage.razor.cs" />
|
||||
<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.Omron\Page\OmronFinsUdpDebugPage.razor.cs" Link="Pages\OmronFins\OmronFinsUdpDebugPage.razor.cs" />
|
||||
<Content Include="..\..\PluginPro\ThingsGateway.Plugin.Omron\Page\OmronFinsTcpDebugPage.razor" Link="Pages\OmronFins\OmronFinsTcpDebugPage.razor" />
|
||||
<Content Include="..\..\PluginPro\ThingsGateway.Plugin.Omron\Page\OmronFinsUdpDebugPage.razor" Link="Pages\OmronFins\OmronFinsUdpDebugPage.razor" />
|
||||
<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.Omron\ThingsGateway.Foundation.Adapter.Omron.csproj" />
|
||||
|
||||
<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.Secs\Page\SecsHsmsTcpDebugPage.razor.cs" Link="Pages\Secs\SecsHsmsTcpDebugPage.razor.cs" />
|
||||
<Content Include="..\..\PluginPro\ThingsGateway.Plugin.Secs\Page\SecsHsmsTcpDebugPage.razor" Link="Pages\Secs\SecsHsmsTcpDebugPage.razor" />
|
||||
<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.Secs\ThingsGateway.Foundation.Adapter.Secs.csproj" />
|
||||
|
||||
|
||||
<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.TS550\Page\TS550DebugPage.razor.cs" Link="Pages\TS550\TS550DebugPage.razor.cs" />
|
||||
<Content Include="..\..\PluginPro\ThingsGateway.Plugin.TS550\Page\TS550DebugPage.razor" Link="Pages\TS550\TS550DebugPage.razor" />
|
||||
<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.TS550\ThingsGateway.Foundation.Adapter.TS550.csproj" />
|
||||
|
||||
<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.Vigor\Page\VigorSerialDebugPage.razor.cs" Link="Pages\Vigor\VigorSerialDebugPage.razor.cs" />
|
||||
<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.Vigor\Page\VigorSerialOverTcpDebugPage.razor.cs" Link="Pages\Vigor\VigorSerialOverTcpDebugPage.razor.cs" />
|
||||
<Content Include="..\..\PluginPro\ThingsGateway.Plugin.Vigor\Page\VigorSerialDebugPage.razor" Link="Pages\Vigor\VigorSerialDebugPage.razor" />
|
||||
<Content Include="..\..\PluginPro\ThingsGateway.Plugin.Vigor\Page\VigorSerialOverTcpDebugPage.razor" Link="Pages\Vigor\VigorSerialOverTcpDebugPage.razor" />
|
||||
<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.Vigor\ThingsGateway.Foundation.Adapter.Vigor.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" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusRtuOverTcpDebugPage.razor" Link="Pages\Modbus\ModbusRtuOverTcpDebugPage.razor" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusRtuOverUdpDebugPage.razor.cs" Link="Pages\Modbus\ModbusRtuOverUdpDebugPage.razor.cs" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusRtuOverUdpDebugPage.razor" Link="Pages\Modbus\ModbusRtuOverUdpDebugPage.razor" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusSerialServerDebugPage.razor.cs" Link="Pages\Modbus\ModbusSerialServerDebugPage.razor.cs" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusSerialServerDebugPage.razor" Link="Pages\Modbus\ModbusSerialServerDebugPage.razor" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusTcpDebugPage.razor.cs" Link="Pages\Modbus\ModbusTcpDebugPage.razor.cs" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusTcpDebugPage.razor" Link="Pages\Modbus\ModbusTcpDebugPage.razor" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusTcpDtuDebugPage.razor.cs" Link="Pages\Modbus\ModbusTcpDtuDebugPage.razor.cs" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusTcpDtuDebugPage.razor" Link="Pages\Modbus\ModbusTcpDtuDebugPage.razor" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusTcpServerDebugPage.razor.cs" Link="Pages\Modbus\ModbusTcpServerDebugPage.razor.cs" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusTcpServerDebugPage.razor" Link="Pages\Modbus\ModbusTcpServerDebugPage.razor" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusUdpDebugPage.razor.cs" Link="Pages\Modbus\ModbusUdpDebugPage.razor.cs" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusUdpDebugPage.razor" Link="Pages\Modbus\ModbusUdpDebugPage.razor" />
|
||||
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.OPCDA\Page\OPCDAClientDebugPage.razor.cs" Link="Pages\OPCDA\OPCDAClientDebugPage.razor.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.OPCDA\Page\OPCDAClientPage.razor.cs" Link="Pages\OPCDA\OPCDAClientPage.razor.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.OPCDA\Page\OPCDAImportVariable.razor.cs" Link="Pages\OPCDA\OPCDAImportVariable.razor.cs" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.OPCDA\Page\OPCDAClientDebugPage.razor" Link="Pages\OPCDA\OPCDAClientDebugPage.razor" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.OPCDA\Page\OPCDAClientPage.razor" Link="Pages\OPCDA\OPCDAClientPage.razor" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.OPCDA\Page\OPCDAImportVariable.razor" Link="Pages\OPCDA\OPCDAImportVariable.razor" />
|
||||
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.OPCUA\Page\OPCUAClientDebugPage.razor" Link="Pages\OPCUA\OPCUAClientDebugPage.razor" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.OPCUA\Page\OPCUAClientPage.razor" Link="Pages\OPCUA\OPCUAClientPage.razor" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.OPCUA\Page\OPCUAImportVariable.razor" Link="Pages\OPCUA\OPCUAImportVariable.razor" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.OPCUA\Page\OPCUAClientDebugPage.razor.cs" Link="Pages\OPCUA\OPCUAClientDebugPage.razor.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.OPCUA\Page\OPCUAClientPage.razor.cs" Link="Pages\OPCUA\OPCUAClientPage.razor.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.OPCUA\Page\OPCUAImportVariable.razor.cs" Link="Pages\OPCUA\OPCUAImportVariable.razor.cs" />
|
||||
|
||||
|
||||
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_1200DebugPage.razor" Link="Pages\Siemens\S7_1200DebugPage.razor" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_1500DebugPage.razor" Link="Pages\Siemens\S7_1500DebugPage.razor" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_200DebugPage.razor" Link="Pages\Siemens\S7_200DebugPage.razor" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_200SMARTDebugPage.razor" Link="Pages\Siemens\S7_200SMARTDebugPage.razor" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_300DebugPage.razor" Link="Pages\Siemens\S7_300DebugPage.razor" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_400DebugPage.razor" Link="Pages\Siemens\S7_400DebugPage.razor" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_1200DebugPage.razor.cs" Link="Pages\Siemens\S7_1200DebugPage.razor.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_1500DebugPage.razor.cs" Link="Pages\Siemens\S7_1500DebugPage.razor.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_200DebugPage.razor.cs" Link="Pages\Siemens\S7_200DebugPage.razor.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_200SMARTDebugPage.razor.cs" Link="Pages\Siemens\S7_200SMARTDebugPage.razor.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_300DebugPage.razor.cs" Link="Pages\Siemens\S7_300DebugPage.razor.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_400DebugPage.razor.cs" Link="Pages\Siemens\S7_400DebugPage.razor.cs" />
|
||||
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<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="..\..\admin\ThingsGateway.Components\ThingsGateway.Components.csproj" />
|
||||
<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.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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace ThingsGateway.Foundation.Demo.Winform
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
blazorWebView1.Dispose();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
@@ -68,6 +69,7 @@ namespace ThingsGateway.Foundation.Demo.Winform
|
||||
Text = "Form1";
|
||||
FormClosed += MainFrom_FormClosed;
|
||||
ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
using Microsoft.AspNetCore.Components.WebView.WindowsForms;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ThingsGateway.Components;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo.Winform
|
||||
@@ -23,9 +26,14 @@ namespace ThingsGateway.Foundation.Demo.Winform
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var services = new ServiceCollection();
|
||||
services.AddWindowsFormsBlazorWebView();
|
||||
services.ThingsGatewayComponentsConfigureServices();
|
||||
IServiceCollection services = null;
|
||||
|
||||
Serve.RunNative(a =>
|
||||
{
|
||||
services = a;
|
||||
services.AddWindowsFormsBlazorWebView();
|
||||
services.ThingsGatewayComponentsConfigureServices();
|
||||
});
|
||||
|
||||
blazorWebView1.HostPage = "wwwroot/index.html";
|
||||
blazorWebView1.Services = services.BuildServiceProvider();
|
||||
@@ -35,7 +43,14 @@ namespace ThingsGateway.Foundation.Demo.Winform
|
||||
|
||||
private void MainFrom_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
Application.Exit();
|
||||
|
||||
Task.Run(() => { MessageBox.Show("释放资源中,稍候自动退出程序..."); });
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(3000);
|
||||
Process.GetCurrentProcess().Kill();
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,43 +3,45 @@
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
||||
<TargetFrameworks>net7.0-windows</TargetFrameworks>
|
||||
<TargetFrameworks>net6.0-windows;net8.0-windows</TargetFrameworks>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="favicon.ico" />
|
||||
<None Remove="favicon.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="favicon.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Include="favicon.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net6.0-windows'">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.WindowsForms" Version="6.0.553" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net8.0-windows'">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.WindowsForms" Version="8.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.WindowsForms" Version="7.0.100" />
|
||||
<ProjectReference Include="..\ThingsGateway.Foundation.Demo.Rcl\ThingsGateway.Foundation.Demo.Rcl.csproj" />
|
||||
</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>
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>3.0.1.0</Version>
|
||||
<Version>4.0.0.0</Version>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<TargetFrameworks>net45;netstandard2.0;net6.0;net7.0</TargetFrameworks>
|
||||
<TargetFrameworks>net45;netstandard2.0;net6.0;net8.0;</TargetFrameworks>
|
||||
<Description>
|
||||
ThingsGateway.Foundation是工业设备通讯类库,归属于ThingsGateway边缘网关项目,说明文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
</Description>
|
||||
@@ -25,8 +25,8 @@
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<DelaySign>False</DelaySign>
|
||||
<SatelliteResourceLanguages>zh-Hans</SatelliteResourceLanguages>
|
||||
<PackageOutputPath>../../nupkgs</PackageOutputPath>
|
||||
<AssemblyOriginatorKeyFile>../../../snks/ThingsGateway.snk</AssemblyOriginatorKeyFile>
|
||||
<PackageOutputPath>..\..\nupkgs</PackageOutputPath>
|
||||
<AssemblyOriginatorKeyFile>..\..\..\snks/ThingsGateway.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
Binary file not shown.
@@ -15,7 +15,7 @@ namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
/// <summary>
|
||||
/// 控制码
|
||||
/// </summary>
|
||||
public enum ControlCode : byte
|
||||
internal enum ControlCode : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 读数据
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
/// <summary>
|
||||
/// 解析参数
|
||||
/// </summary>
|
||||
public class DataInfo
|
||||
internal class DataInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 解析长度
|
||||
|
||||
@@ -12,13 +12,11 @@
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
/// <summary>
|
||||
/// DLT645_2007
|
||||
/// </summary>
|
||||
public class DLT645_2007 : ReadWriteDevicesSerialSessionBase
|
||||
public class DLT645_2007 : ReadWriteDevicesSerialSessionBase, IDLT645_2007
|
||||
{
|
||||
/// <summary>
|
||||
/// DLT645_2007
|
||||
@@ -30,102 +28,35 @@ public class DLT645_2007 : ReadWriteDevicesSerialSessionBase
|
||||
RegisterByteLength = 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 增加FE FE FE FE的报文头部
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[Description("前导符报文头")]
|
||||
public bool EnableFEHead { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入需操作员代码
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[Description("操作员代码")]
|
||||
public string OperCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入密码
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[Description("写入密码")]
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通讯地址BCD码,一般应该是12个字符
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[Description("通讯地址")]
|
||||
public string Station { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription()
|
||||
{
|
||||
|
||||
var str = """
|
||||
查看附带文档或者相关资料,下面列举一下常见的数据标识地址
|
||||
|
||||
地址 说明
|
||||
-----------------------------------------
|
||||
02010100 A相电压
|
||||
02020100 A相电流
|
||||
02030000 瞬时总有功功率
|
||||
00000000 (当前)组合有功总电能
|
||||
00010000 (当前)正向有功总电能
|
||||
|
||||
""";
|
||||
return base.GetAddressDescription() + Environment.NewLine + str;
|
||||
return base.GetAddressDescription() + Environment.NewLine + DLT645_2007Util.GetAddressDescription();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack)
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime)
|
||||
{
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack);
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Read, Station);
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = WaitingClientEx.SendThenResponse(commandResult.Content, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Read, Station);
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter(object socketClient = null)
|
||||
public override void SetDataAdapter(ISocketClient socketClient = default)
|
||||
{
|
||||
var dataHandleAdapter = new DLT645_2007DataHandleAdapter
|
||||
{
|
||||
@@ -133,39 +64,41 @@ public class DLT645_2007 : ReadWriteDevicesSerialSessionBase
|
||||
};
|
||||
SerialSession.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return DLT645_2007Util.Read(this, address, length, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return DLT645_2007Util.ReadAsync(this, address, length, cancellationToken);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, string value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
Password ??= string.Empty;
|
||||
OperCode ??= string.Empty;
|
||||
if (Password.Length < 8)
|
||||
Password = Password.PadLeft(8, '0');
|
||||
if (OperCode.Length < 8)
|
||||
OperCode = OperCode.PadLeft(8, '0');
|
||||
var data = DataTransUtil.SpliceArray(Password.ByHexStringToBytes(), OperCode.ByHexStringToBytes());
|
||||
string[] strArray = value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Write, Station, data, strArray);
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = WaitingClientEx.SendThenResponse(commandResult.Content, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
return DLT645_2007Util.Write(this, address, value, cancellationToken);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, string value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
return DLT645_2007Util.WriteAsync(this, address, value, cancellationToken);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default) => Write(address, value.ToString(), cancellationToken);
|
||||
|
||||
@@ -173,39 +106,7 @@ public class DLT645_2007 : ReadWriteDevicesSerialSessionBase
|
||||
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default) => Write(address, value.ToString(), cancellationToken);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult> WriteAsync(string address, string value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
Password ??= string.Empty;
|
||||
OperCode ??= string.Empty;
|
||||
if (Password.Length < 8)
|
||||
Password = Password.PadLeft(8, '0');
|
||||
if (OperCode.Length < 8)
|
||||
OperCode = OperCode.PadLeft(8, '0');
|
||||
var data = DataTransUtil.SpliceArray(Password.ByHexStringToBytes(), OperCode.ByHexStringToBytes());
|
||||
string[] strArray = value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Write, Station, data, strArray);
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, uint value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
/// <inheritdoc/>
|
||||
@@ -224,256 +125,54 @@ public class DLT645_2007 : ReadWriteDevicesSerialSessionBase
|
||||
public override Task<OperResult> WriteAsync(string address, int value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||
|
||||
|
||||
#region 其他方法
|
||||
|
||||
/// <summary>
|
||||
/// 广播校时
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="DLT645_2007Util.BroadcastTime(IDLT645_2007,DateTime, CancellationToken)"/>
|
||||
public OperResult BroadcastTime(DateTime dateTime, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
string str = $"{dateTime.Second:D2}{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}{dateTime.Year % 100:D2}";
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.BroadcastTime, str.ByHexStringToBytes().ToArray(), "999999999999".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
SerialSession.Send(commandResult.Content);
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
return DLT645_2007Util.BroadcastTime(this, dateTime, cancellationToken);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 冻结
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="DLT645_2007Util.FreezeAsync(IDLT645_2007,DateTime, CancellationToken)"/>
|
||||
public async Task<OperResult> FreezeAsync(DateTime dateTime, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
string str = $"{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}";
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.Freeze, str.ByHexStringToBytes().ToArray(), Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
return await DLT645_2007Util.FreezeAsync(this, dateTime, cancellationToken);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 读取通信地址
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="DLT645_2007Util.ReadDeviceStationAsync(IDLT645_2007, CancellationToken)"/>
|
||||
public async Task<OperResult<string>> ReadDeviceStationAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.ReadStation, null, "AAAAAAAAAAAA".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
var buffer = result1.Content.SelectMiddle(0, 6).BytesAdd(-0x33);
|
||||
return OperResult.CreateSuccessResult(buffer.Reverse().ToArray().ToHexString());
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
return await DLT645_2007Util.ReadDeviceStationAsync(this, cancellationToken);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 修改波特率
|
||||
/// </summary>
|
||||
/// <param name="baudRate"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="DLT645_2007Util.WriteBaudRateAsync(IDLT645_2007, int, CancellationToken)"/>
|
||||
public async Task<OperResult> WriteBaudRateAsync(int baudRate, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
byte baudRateByte;
|
||||
switch (baudRate)
|
||||
{
|
||||
case 600: baudRateByte = 0x02; break;
|
||||
case 1200: baudRateByte = 0x04; break;
|
||||
case 2400: baudRateByte = 0x08; break;
|
||||
case 4800: baudRateByte = 0x10; break;
|
||||
case 9600: baudRateByte = 0x20; break;
|
||||
case 19200: baudRateByte = 0x40; break;
|
||||
default: return new OperResult<string>($"不支持此波特率:{baudRate}");
|
||||
}
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteBaudRate, new byte[] { baudRateByte }, Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
return await DLT645_2007Util.WriteBaudRateAsync(this, baudRate, cancellationToken);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新通信地址
|
||||
/// </summary>
|
||||
/// <param name="station"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="DLT645_2007Util.WriteDeviceStationAsync(IDLT645_2007, string, CancellationToken)"/>
|
||||
public async Task<OperResult> WriteDeviceStationAsync(string station, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteStation, station.ByHexStringToBytes().Reverse().ToArray(), "AAAAAAAAAAAA".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
return await DLT645_2007Util.WriteDeviceStationAsync(this, station, cancellationToken);
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改密码
|
||||
/// </summary>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="oldPassword"></param>
|
||||
/// <param name="newPassword"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
/// <inheritdoc cref="DLT645_2007Util.WritePasswordAsync(IDLT645_2007, byte,string,string, CancellationToken)"/>
|
||||
public async Task<OperResult> WritePasswordAsync(byte level, string oldPassword, string newPassword, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
string str = $"04000C{level + 1:D2}";
|
||||
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WritePassword,
|
||||
str.ByHexStringToBytes().Reverse().ToArray()
|
||||
.SpliceArray(oldPassword.ByHexStringToBytes().Reverse().ToArray())
|
||||
.SpliceArray(newPassword.ByHexStringToBytes().Reverse().ToArray())
|
||||
, Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
return await DLT645_2007Util.WritePasswordAsync(this, level, oldPassword, newPassword, cancellationToken);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public class DLT645_2007Address : DeviceAddressBase
|
||||
/// <returns></returns>
|
||||
public static DLT645_2007Address ParseFrom(string address)
|
||||
{
|
||||
DLT645_2007Address dLT645_2007Address = new();
|
||||
DLT645_2007Address dlt645_2007Address = new();
|
||||
byte[] array;
|
||||
array = new byte[0];
|
||||
if (address.IndexOf(';') < 0)
|
||||
@@ -59,7 +59,7 @@ public class DLT645_2007Address : DeviceAddressBase
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] strArray = address.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] strArray = address.SplitStringBySemicolon();
|
||||
|
||||
for (int index = 0; index < strArray.Length; ++index)
|
||||
{
|
||||
@@ -69,11 +69,11 @@ public class DLT645_2007Address : DeviceAddressBase
|
||||
if (station.IsNullOrEmpty()) station = string.Empty;
|
||||
if (station.Length < 12)
|
||||
station = station.PadLeft(12, '0');
|
||||
dLT645_2007Address.Station = station.ByHexStringToBytes().Reverse().ToArray();
|
||||
dlt645_2007Address.Station = station.ByHexStringToBytes().Reverse().ToArray();
|
||||
}
|
||||
else if (strArray[index].Contains("r="))
|
||||
{
|
||||
dLT645_2007Address.Reverse = strArray[index].Substring(2).GetBoolValue();
|
||||
dlt645_2007Address.Reverse = strArray[index].Substring(2).ToBool(false);
|
||||
}
|
||||
else if (!strArray[index].Contains("="))
|
||||
{
|
||||
@@ -81,8 +81,8 @@ public class DLT645_2007Address : DeviceAddressBase
|
||||
}
|
||||
}
|
||||
}
|
||||
dLT645_2007Address.DataId = array;
|
||||
return dLT645_2007Address;
|
||||
dlt645_2007Address.DataId = array;
|
||||
return dlt645_2007Address;
|
||||
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ public class DLT645_2007Address : DeviceAddressBase
|
||||
}
|
||||
if (!Reverse)
|
||||
{
|
||||
stringGeter.Append($"s={Reverse.ToString()};");
|
||||
stringGeter.Append($"s={Reverse};");
|
||||
}
|
||||
return stringGeter.ToString();
|
||||
}
|
||||
|
||||
@@ -26,7 +26,41 @@ public class DLT645_2007BitConverter : ThingsGatewayBitConverter
|
||||
public DLT645_2007BitConverter(EndianType endianType) : base(endianType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override short ToInt16(byte[] buffer, int offset)
|
||||
{
|
||||
return Convert.ToInt16(this.ToString(buffer, offset, buffer.Length));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override ushort ToUInt16(byte[] buffer, int offset)
|
||||
{
|
||||
return Convert.ToUInt16(this.ToString(buffer, offset, buffer.Length));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override float ToSingle(byte[] buffer, int offset)
|
||||
{
|
||||
return Convert.ToSingle(this.ToString(buffer, offset, buffer.Length));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override long ToInt64(byte[] buffer, int offset)
|
||||
{
|
||||
return Convert.ToInt64(this.ToString(buffer, offset, buffer.Length));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override int ToInt32(byte[] buffer, int offset)
|
||||
{
|
||||
return Convert.ToInt32(this.ToString(buffer, offset, buffer.Length));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override uint ToUInt32(byte[] buffer, int offset)
|
||||
{
|
||||
return Convert.ToUInt32(this.ToString(buffer, offset, buffer.Length));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override ulong ToUInt64(byte[] buffer, int offset)
|
||||
{
|
||||
return Convert.ToUInt64(this.ToString(buffer, offset, buffer.Length));
|
||||
}
|
||||
/// <summary>
|
||||
/// DLT645协议转换double
|
||||
/// </summary>
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
/// <summary>
|
||||
/// DLT645_2007DataHandleAdapter
|
||||
/// </summary>
|
||||
public class DLT645_2007DataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<DLT645_2007Message>
|
||||
internal class DLT645_2007DataHandleAdapter : ReadWriteDevicesSingleStreamDataHandleAdapter<DLT645_2007Message>
|
||||
{
|
||||
/// <summary>
|
||||
/// 增加FE FE FE FE的报文头部
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class DLT645_2007Message : MessageBase, IMessage
|
||||
internal class DLT645_2007Message : MessageBase, IMessage
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override int HeadBytesLength => -1;
|
||||
|
||||
@@ -12,13 +12,11 @@
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
/// <summary>
|
||||
/// DLT645_2007
|
||||
/// </summary>
|
||||
public class DLT645_2007OverTcp : ReadWriteDevicesTcpClientBase
|
||||
public class DLT645_2007OverTcp : ReadWriteDevicesTcpClientBase, IDLT645_2007
|
||||
{
|
||||
/// <summary>
|
||||
/// DLT645_2007
|
||||
@@ -30,102 +28,35 @@ public class DLT645_2007OverTcp : ReadWriteDevicesTcpClientBase
|
||||
RegisterByteLength = 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 增加FE FE FE FE的报文头部
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[Description("前导符报文头")]
|
||||
public bool EnableFEHead { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入需操作员代码
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[Description("操作员代码")]
|
||||
public string OperCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入密码
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[Description("写入密码")]
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通讯地址BCD码,一般应该是12个字符
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[Description("通讯地址")]
|
||||
public string Station { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription()
|
||||
{
|
||||
|
||||
var str = """
|
||||
查看附带文档或者相关资料,下面列举一下常见的数据标识地址
|
||||
|
||||
地址 说明
|
||||
-----------------------------------------
|
||||
02010100 A相电压
|
||||
02020100 A相电流
|
||||
02030000 瞬时总有功功率
|
||||
00000000 (当前)组合有功总电能
|
||||
00010000 (当前)正向有功总电能
|
||||
|
||||
""";
|
||||
return base.GetAddressDescription() + Environment.NewLine + str;
|
||||
return base.GetAddressDescription() + Environment.NewLine + DLT645_2007Util.GetAddressDescription();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack)
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime)
|
||||
{
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack);
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Read, Station);
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = WaitingClientEx.SendThenResponse(commandResult.Content, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Read, Station);
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter(object socketClient = null)
|
||||
public override void SetDataAdapter(ISocketClient socketClient = default)
|
||||
{
|
||||
var dataHandleAdapter = new DLT645_2007DataHandleAdapter
|
||||
{
|
||||
@@ -133,39 +64,41 @@ public class DLT645_2007OverTcp : ReadWriteDevicesTcpClientBase
|
||||
};
|
||||
TcpClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return DLT645_2007Util.Read(this, address, length, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return DLT645_2007Util.ReadAsync(this, address, length, cancellationToken);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, string value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
Password ??= string.Empty;
|
||||
OperCode ??= string.Empty;
|
||||
if (Password.Length < 8)
|
||||
Password = Password.PadLeft(8, '0');
|
||||
if (OperCode.Length < 8)
|
||||
OperCode = OperCode.PadLeft(8, '0');
|
||||
var data = DataTransUtil.SpliceArray(Password.ByHexStringToBytes(), OperCode.ByHexStringToBytes());
|
||||
string[] strArray = value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Write, Station, data, strArray);
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = WaitingClientEx.SendThenResponse(commandResult.Content, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
return DLT645_2007Util.Write(this, address, value, cancellationToken);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, string value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
return DLT645_2007Util.WriteAsync(this, address, value, cancellationToken);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default) => Write(address, value.ToString(), cancellationToken);
|
||||
|
||||
@@ -173,39 +106,7 @@ public class DLT645_2007OverTcp : ReadWriteDevicesTcpClientBase
|
||||
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default) => Write(address, value.ToString(), cancellationToken);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult> WriteAsync(string address, string value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
Password ??= string.Empty;
|
||||
OperCode ??= string.Empty;
|
||||
if (Password.Length < 8)
|
||||
Password = Password.PadLeft(8, '0');
|
||||
if (OperCode.Length < 8)
|
||||
OperCode = OperCode.PadLeft(8, '0');
|
||||
var data = DataTransUtil.SpliceArray(Password.ByHexStringToBytes(), OperCode.ByHexStringToBytes());
|
||||
string[] strArray = value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Write, Station, data, strArray);
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, uint value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
/// <inheritdoc/>
|
||||
@@ -224,257 +125,56 @@ public class DLT645_2007OverTcp : ReadWriteDevicesTcpClientBase
|
||||
public override Task<OperResult> WriteAsync(string address, int value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||
|
||||
|
||||
#region 其他方法
|
||||
|
||||
/// <summary>
|
||||
/// 广播校时
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="DLT645_2007Util.BroadcastTime(IDLT645_2007,DateTime, CancellationToken)"/>
|
||||
public OperResult BroadcastTime(DateTime dateTime, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
string str = $"{dateTime.Second:D2}{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}{dateTime.Year % 100:D2}";
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.BroadcastTime, str.ByHexStringToBytes().Reverse().ToArray(), "999999999999".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
TcpClient.Send(commandResult.Content);
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
return DLT645_2007Util.BroadcastTime(this, dateTime, cancellationToken);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 冻结
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="DLT645_2007Util.FreezeAsync(IDLT645_2007,DateTime, CancellationToken)"/>
|
||||
public async Task<OperResult> FreezeAsync(DateTime dateTime, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
string str = $"{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}";
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.Freeze, str.ByHexStringToBytes().Reverse().ToArray(), Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
return await DLT645_2007Util.FreezeAsync(this, dateTime, cancellationToken);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 读取通信地址
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="DLT645_2007Util.ReadDeviceStationAsync(IDLT645_2007, CancellationToken)"/>
|
||||
public async Task<OperResult<string>> ReadDeviceStationAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.ReadStation, null, "AAAAAAAAAAAA".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
var buffer = result1.Content.SelectMiddle(0, 6).BytesAdd(-0x33);
|
||||
return OperResult.CreateSuccessResult(buffer.Reverse().ToArray().ToHexString());
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
return await DLT645_2007Util.ReadDeviceStationAsync(this, cancellationToken);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 修改波特率
|
||||
/// </summary>
|
||||
/// <param name="baudRate"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="DLT645_2007Util.WriteBaudRateAsync(IDLT645_2007, int, CancellationToken)"/>
|
||||
public async Task<OperResult> WriteBaudRateAsync(int baudRate, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
byte baudRateByte;
|
||||
switch (baudRate)
|
||||
{
|
||||
case 600: baudRateByte = 0x02; break;
|
||||
case 1200: baudRateByte = 0x04; break;
|
||||
case 2400: baudRateByte = 0x08; break;
|
||||
case 4800: baudRateByte = 0x10; break;
|
||||
case 9600: baudRateByte = 0x20; break;
|
||||
case 19200: baudRateByte = 0x40; break;
|
||||
default: return new OperResult<string>($"不支持此波特率:{baudRate}");
|
||||
}
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteBaudRate, new byte[] { baudRateByte }, Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
return await DLT645_2007Util.WriteBaudRateAsync(this, baudRate, cancellationToken);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新通信地址
|
||||
/// </summary>
|
||||
/// <param name="station"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="DLT645_2007Util.WriteDeviceStationAsync(IDLT645_2007, string, CancellationToken)"/>
|
||||
public async Task<OperResult> WriteDeviceStationAsync(string station, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteStation, station.ByHexStringToBytes().Reverse().ToArray(), "AAAAAAAAAAAA".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
return await DLT645_2007Util.WriteDeviceStationAsync(this, station, cancellationToken);
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改密码
|
||||
/// </summary>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="oldPassword"></param>
|
||||
/// <param name="newPassword"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
/// <inheritdoc cref="DLT645_2007Util.WritePasswordAsync(IDLT645_2007, byte,string,string, CancellationToken)"/>
|
||||
public async Task<OperResult> WritePasswordAsync(byte level, string oldPassword, string newPassword, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
string str = $"04000C{level:D2}";
|
||||
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WritePassword,
|
||||
str.ByHexStringToBytes().Reverse().ToArray()
|
||||
.SpliceArray(oldPassword.ByHexStringToBytes().Reverse().ToArray())
|
||||
.SpliceArray(newPassword.ByHexStringToBytes().Reverse().ToArray())
|
||||
, Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
return await DLT645_2007Util.WritePasswordAsync(this, level, oldPassword, newPassword, cancellationToken);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
#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 ThingsGateway.Foundation.Extension.Generic;
|
||||
using ThingsGateway.Foundation.Extension.String;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
/// <summary>
|
||||
/// DLT645_2007
|
||||
/// </summary>
|
||||
internal static class DLT645_2007Util
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public static string GetAddressDescription()
|
||||
{
|
||||
var str = """
|
||||
查看附带文档或者相关资料,下面列举一下常见的数据标识地址
|
||||
|
||||
地址 说明
|
||||
-----------------------------------------
|
||||
02010100 A相电压
|
||||
02020100 A相电流
|
||||
02030000 瞬时总有功功率
|
||||
00000000 (当前)组合有功总电能
|
||||
00010000 (当前)正向有功总电能
|
||||
|
||||
""";
|
||||
return Environment.NewLine + str;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static OperResult<byte[]> Read(IDLT645_2007 dlt645_2007, string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
dlt645_2007.Connect(cancellationToken);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Read, dlt645_2007.Station);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return dlt645_2007.SendThenReturn<DLT645_2007Message>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static async Task<OperResult<byte[]>> ReadAsync(IDLT645_2007 dlt645_2007, string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await dlt645_2007.ConnectAsync(cancellationToken);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Read, dlt645_2007.Station);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await dlt645_2007.SendThenReturnAsync<DLT645_2007Message>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static OperResult Write(IDLT645_2007 dlt645_2007, string address, string value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
dlt645_2007.Connect(cancellationToken);
|
||||
dlt645_2007.Password ??= string.Empty;
|
||||
dlt645_2007.OperCode ??= string.Empty;
|
||||
if (dlt645_2007.Password.Length < 8)
|
||||
dlt645_2007.Password = dlt645_2007.Password.PadLeft(8, '0');
|
||||
if (dlt645_2007.OperCode.Length < 8)
|
||||
dlt645_2007.OperCode = dlt645_2007.OperCode.PadLeft(8, '0');
|
||||
|
||||
var data = DataTransUtil.SpliceArray(dlt645_2007.Password.ByHexStringToBytes(), dlt645_2007.OperCode.ByHexStringToBytes());
|
||||
string[] strArray = value.SplitStringBySemicolon();
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Write, dlt645_2007.Station, data, strArray);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return dlt645_2007.SendThenReturn<DLT645_2007Message>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static async Task<OperResult> WriteAsync(IDLT645_2007 dlt645_2007, string address, string value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
await dlt645_2007.ConnectAsync(cancellationToken);
|
||||
dlt645_2007.Password ??= string.Empty;
|
||||
dlt645_2007.OperCode ??= string.Empty;
|
||||
if (dlt645_2007.Password.Length < 8)
|
||||
dlt645_2007.Password = dlt645_2007.Password.PadLeft(8, '0');
|
||||
if (dlt645_2007.OperCode.Length < 8)
|
||||
dlt645_2007.OperCode = dlt645_2007.OperCode.PadLeft(8, '0');
|
||||
var data = DataTransUtil.SpliceArray(dlt645_2007.Password.ByHexStringToBytes(), dlt645_2007.OperCode.ByHexStringToBytes());
|
||||
string[] strArray = value.SplitStringBySemicolon();
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Write, dlt645_2007.Station, data, strArray);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await dlt645_2007.SendThenReturnAsync<DLT645_2007Message>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#region 其他方法
|
||||
|
||||
/// <summary>
|
||||
/// 广播校时
|
||||
/// </summary>
|
||||
/// <param name="dlt645_2007">链路</param>
|
||||
/// <param name="dateTime">时间</param>
|
||||
/// <param name="cancellationToken">取消令箭</param>
|
||||
/// <returns></returns>
|
||||
public static OperResult BroadcastTime(IDLT645_2007 dlt645_2007, DateTime dateTime, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
dlt645_2007.Connect(cancellationToken);
|
||||
string str = $"{dateTime.Second:D2}{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}{dateTime.Year % 100:D2}";
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.BroadcastTime, str.ByHexStringToBytes().ToArray(), "999999999999".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
dlt645_2007.Send(commandResult.Content);
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 冻结
|
||||
/// </summary>
|
||||
/// <param name="dlt645_2007">链路</param>
|
||||
/// <param name="dateTime">时间</param>
|
||||
/// <param name="cancellationToken">取消令箭</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<OperResult> FreezeAsync(IDLT645_2007 dlt645_2007, DateTime dateTime, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await dlt645_2007.ConnectAsync(cancellationToken);
|
||||
string str = $"{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}";
|
||||
if (dlt645_2007.Station.IsNullOrEmpty()) dlt645_2007.Station = string.Empty;
|
||||
if (dlt645_2007.Station.Length < 12) dlt645_2007.Station = dlt645_2007.Station.PadLeft(12, '0');
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.Freeze, str.ByHexStringToBytes().ToArray(), dlt645_2007.Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await dlt645_2007.SendThenReturnAsync<DLT645_2007Message>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取通信地址
|
||||
/// </summary>
|
||||
/// <param name="dlt645_2007">链路</param>
|
||||
/// <param name="cancellationToken">取消令箭</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<OperResult<string>> ReadDeviceStationAsync(IDLT645_2007 dlt645_2007, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await dlt645_2007.ConnectAsync(cancellationToken);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.ReadStation, null, "AAAAAAAAAAAA".ByHexStringToBytes());
|
||||
if (!commandResult.IsSuccess) return new(commandResult);
|
||||
var result = await dlt645_2007.SendThenReturnAsync<DLT645_2007Message>(commandResult.Content, cancellationToken);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
var buffer = result.Content.SelectMiddle(0, 6).BytesAdd(-0x33);
|
||||
return OperResult.CreateSuccessResult(buffer.Reverse().ToArray().ToHexString());
|
||||
}
|
||||
else
|
||||
{
|
||||
return new(result);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 修改波特率
|
||||
/// </summary>
|
||||
/// <param name="dlt645_2007">链路</param>
|
||||
/// <param name="baudRate">波特率</param>
|
||||
/// <param name="cancellationToken">取消令箭</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<OperResult> WriteBaudRateAsync(IDLT645_2007 dlt645_2007, int baudRate, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await dlt645_2007.ConnectAsync(cancellationToken);
|
||||
byte baudRateByte;
|
||||
switch (baudRate)
|
||||
{
|
||||
case 600: baudRateByte = 0x02; break;
|
||||
case 1200: baudRateByte = 0x04; break;
|
||||
case 2400: baudRateByte = 0x08; break;
|
||||
case 4800: baudRateByte = 0x10; break;
|
||||
case 9600: baudRateByte = 0x20; break;
|
||||
case 19200: baudRateByte = 0x40; break;
|
||||
default: return new OperResult<string>($"不支持此波特率:{baudRate}");
|
||||
}
|
||||
if (dlt645_2007.Station.IsNullOrEmpty()) dlt645_2007.Station = string.Empty;
|
||||
if (dlt645_2007.Station.Length < 12) dlt645_2007.Station = dlt645_2007.Station.PadLeft(12, '0');
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteBaudRate, new byte[] { baudRateByte }, dlt645_2007.Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await dlt645_2007.SendThenReturnAsync<DLT645_2007Message>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新通信地址
|
||||
/// </summary>
|
||||
/// <param name="dlt645_2007">链路</param>
|
||||
/// <param name="station">站号</param>
|
||||
/// <param name="cancellationToken">取消令箭</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<OperResult> WriteDeviceStationAsync(IDLT645_2007 dlt645_2007, string station, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await dlt645_2007.ConnectAsync(cancellationToken);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteStation, station.ByHexStringToBytes().Reverse().ToArray(), "AAAAAAAAAAAA".ByHexStringToBytes());
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await dlt645_2007.SendThenReturnAsync<DLT645_2007Message>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改密码
|
||||
/// </summary>
|
||||
/// <param name="dlt645_2007">链路</param>
|
||||
/// <param name="level">密码等级,0-8</param>
|
||||
/// <param name="oldPassword">旧密码</param>
|
||||
/// <param name="newPassword">新密码</param>
|
||||
/// <param name="cancellationToken">取消令箭</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<OperResult> WritePasswordAsync(IDLT645_2007 dlt645_2007, byte level, string oldPassword, string newPassword, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await dlt645_2007.ConnectAsync(cancellationToken);
|
||||
|
||||
if (dlt645_2007.Station.IsNullOrEmpty()) dlt645_2007.Station = string.Empty;
|
||||
if (dlt645_2007.Station.Length < 12) dlt645_2007.Station = dlt645_2007.Station.PadLeft(12, '0');
|
||||
string str = $"04000C{level + 1:D2}";
|
||||
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WritePassword,
|
||||
str.ByHexStringToBytes().Reverse().ToArray()
|
||||
.SpliceArray(oldPassword.ByHexStringToBytes().Reverse().ToArray())
|
||||
.SpliceArray(newPassword.ByHexStringToBytes().Reverse().ToArray())
|
||||
, dlt645_2007.Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await dlt645_2007.SendThenReturnAsync<DLT645_2007Message>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
@@ -10,32 +10,28 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Core
|
||||
namespace ThingsGateway.Foundation.Adapter.DLT645
|
||||
{
|
||||
/// <summary>
|
||||
/// 全局分页查询输入参数
|
||||
/// DLT645_2007
|
||||
/// </summary>
|
||||
public interface IBasePageInput
|
||||
public interface IDLT645_2007 : IReadWrite
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前页码
|
||||
/// 增加FE FE FE FE的报文头部
|
||||
/// </summary>
|
||||
int Current { get; set; }
|
||||
bool EnableFEHead { get; set; }
|
||||
/// <summary>
|
||||
/// 关键字
|
||||
/// 操作员代码
|
||||
/// </summary>
|
||||
string SearchKey { get; set; }
|
||||
string OperCode { get; set; }
|
||||
/// <summary>
|
||||
/// 每页条数
|
||||
/// 写入密码
|
||||
/// </summary>
|
||||
int Size { get; set; }
|
||||
string Password { get; set; }
|
||||
/// <summary>
|
||||
/// 排序方式,true为desc,false为asc
|
||||
/// 通讯地址BCD码,一般应该是12个字符
|
||||
/// </summary>
|
||||
List<bool> SortDesc { get; set; }
|
||||
/// <summary>
|
||||
/// 排序字段
|
||||
/// </summary>
|
||||
List<string> SortField { get; set; }
|
||||
string Station { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -14,25 +14,34 @@ namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
|
||||
internal static class PackHelper
|
||||
{
|
||||
public static List<T> LoadSourceRead<T, T2>(IReadWrite device, List<T2> deviceVariables, int maxPack) where T : IDeviceVariableSourceRead<IDeviceVariableRunTime>, new() where T2 : IDeviceVariableRunTime, new()
|
||||
/// <summary>
|
||||
/// 打包变量,添加到<see href="deviceVariableSourceReads"></see>
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
/// <param name="deviceVariables"></param>
|
||||
/// <param name="maxPack">最大打包长度</param>
|
||||
/// <param name="defaultIntervalTime">默认间隔时间</param>
|
||||
/// <returns></returns>
|
||||
public static List<T> LoadSourceRead<T, T2>(IReadWrite device, List<T2> deviceVariables, int maxPack, int defaultIntervalTime) where T : IDeviceVariableSourceRead<IDeviceVariableRunTime>, new() where T2 : IDeviceVariableRunTime, new()
|
||||
{
|
||||
var byteConverter = device.ThingsGatewayBitConverter;
|
||||
var result = new List<T>();
|
||||
//需要先剔除额外信息,比如dataformat等
|
||||
foreach (var item in deviceVariables)
|
||||
{
|
||||
var address = item.VariableAddress;
|
||||
var address = item.Address;
|
||||
|
||||
IThingsGatewayBitConverter transformParameter = ByteTransformUtil.GetTransByAddress(ref address, byteConverter);
|
||||
item.ThingsGatewayBitConverter = transformParameter;
|
||||
//item.VariableAddress = address;
|
||||
item.Index = device.GetBitOffset(item.VariableAddress);
|
||||
//item.Address = address;
|
||||
item.Index = device.GetBitOffset(item.Address);
|
||||
|
||||
result.Add(new()
|
||||
{
|
||||
DeviceVariableRunTimes = new() { item },
|
||||
VariableAddress = address,
|
||||
Address = address,
|
||||
Length = 1,
|
||||
IntervalTimeTick = new(item.IntervalTime ?? defaultIntervalTime)
|
||||
});
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -44,13 +44,13 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription()
|
||||
{
|
||||
return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription();
|
||||
return $"{base.GetAddressDescription()}{Environment.NewLine}{ModbusHelper.GetAddressDescription()}";
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack)
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime)
|
||||
{
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack);
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -61,7 +61,8 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
Connect(cancellationToken);
|
||||
var mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station);
|
||||
return SendThenReturn(mAddress.SocketId, commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn(mAddress.SocketId, commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -77,7 +78,8 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
await ConnectAsync(cancellationToken);
|
||||
var mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station);
|
||||
return await SendThenReturnAsync(mAddress.SocketId, commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync(mAddress.SocketId, commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -86,16 +88,16 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter(object socketClient = null)
|
||||
public override void SetDataAdapter(ISocketClient socketClient = default)
|
||||
{
|
||||
if (socketClient is SocketClient client)
|
||||
if (socketClient != default)
|
||||
{
|
||||
ModbusTcpDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
IsCheckMessageId = IsCheckMessageId,
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
};
|
||||
client.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
socketClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -119,7 +121,8 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
Connect(cancellationToken);
|
||||
var mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station);
|
||||
return SendThenReturn(mAddress.SocketId, commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn(mAddress.SocketId, commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -135,7 +138,8 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
Connect(cancellationToken);
|
||||
var mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station);
|
||||
return SendThenReturn(mAddress.SocketId, commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn(mAddress.SocketId, commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -151,7 +155,8 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
await ConnectAsync(cancellationToken);
|
||||
var mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station);
|
||||
return await SendThenReturnAsync(mAddress.SocketId, commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync(mAddress.SocketId, commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -167,7 +172,8 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
await ConnectAsync(cancellationToken);
|
||||
var mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station);
|
||||
return await SendThenReturnAsync(mAddress.SocketId, commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync(mAddress.SocketId, commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -175,64 +181,42 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
}
|
||||
}
|
||||
|
||||
private OperResult<byte[]> SendThenReturn(string id, OperResult<byte[]> commandResult, CancellationToken cancellationToken)
|
||||
private OperResult<byte[]> SendThenReturn(string id, byte[] command, CancellationToken cancellationToken)
|
||||
{
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
if (TcpService.TryGetSocketClient($"ID={id}", out var client))
|
||||
{
|
||||
SetDataAdapter(client);
|
||||
|
||||
var item = commandResult.Content;
|
||||
if (FrameTime != 0)
|
||||
Thread.Sleep(FrameTime);
|
||||
var WaitingClientEx = client.CreateWaitingClient(new() { });
|
||||
var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>("客户端未连接");
|
||||
}
|
||||
if (TcpService.TryGetSocketClient($"ID={id}", out var client))
|
||||
{
|
||||
SetDataAdapter(client);
|
||||
return SendThenReturn<ModbusTcpMessage>(command, cancellationToken, client);
|
||||
}
|
||||
else
|
||||
{
|
||||
return commandResult;
|
||||
return new OperResult<byte[]>("客户端未连接");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private async Task<OperResult<byte[]>> SendThenReturnAsync(string id, OperResult<byte[]> commandResult, CancellationToken cancellationToken)
|
||||
private async Task<OperResult<byte[]>> SendThenReturnAsync(string id, byte[] command, CancellationToken cancellationToken)
|
||||
{
|
||||
if (commandResult.IsSuccess)
|
||||
if (TcpService.TryGetSocketClient($"ID={id}", out var client))
|
||||
{
|
||||
if (TcpService.TryGetSocketClient($"ID={id}", out var client))
|
||||
SetDataAdapter(client);
|
||||
return await SendThenReturnAsync<ModbusTcpMessage>(command, cancellationToken, client);
|
||||
}
|
||||
else if (TcpService.SocketClients.Count == 1)
|
||||
{
|
||||
var client1 = TcpService.SocketClients.GetClients().FirstOrDefault();
|
||||
if (client1 != null)
|
||||
{
|
||||
SetDataAdapter(client);
|
||||
|
||||
var item = commandResult.Content;
|
||||
await Task.Delay(FrameTime, cancellationToken);
|
||||
var WaitingClientEx = client.CreateWaitingClient(new() { });
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>("客户端未连接");
|
||||
SetDataAdapter(client1);
|
||||
return await SendThenReturnAsync<ModbusTcpMessage>(command, cancellationToken, client1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return commandResult;
|
||||
}
|
||||
|
||||
|
||||
return new OperResult<byte[]>("客户端未连接");
|
||||
}
|
||||
|
||||
internal class ModbusTcpDtuPlugin : PluginBase, ITcpReceivingPlugin
|
||||
{
|
||||
public Task OnTcpReceiving(ITcpClientBase client, ByteBlockEventArgs e)
|
||||
public async Task OnTcpReceiving(ITcpClientBase client, ByteBlockEventArgs e)
|
||||
{
|
||||
if (client is ISocketClient socket)
|
||||
{
|
||||
@@ -243,7 +227,7 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
socket.ResetId(id);
|
||||
}
|
||||
}
|
||||
return e.InvokeNext();//如果本插件无法处理当前数据,请将数据转至下一个插件。
|
||||
await e.InvokeNext();//如果本插件无法处理当前数据,请将数据转至下一个插件。
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Foundation.Extension;
|
||||
using ThingsGateway.Foundation.Extension.String;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
@@ -54,7 +53,7 @@ public class ModbusAddress : DeviceAddressBase
|
||||
/// <summary>
|
||||
/// BitIndex
|
||||
/// </summary>
|
||||
public int BitIndex => (int)(Address.SplitDot().LastOrDefault().ToInt());
|
||||
public int BitIndex => (int)(Address.SplitStringByDelimiter().LastOrDefault().ToInt());
|
||||
|
||||
/// <summary>
|
||||
/// 读取功能码
|
||||
@@ -88,7 +87,7 @@ public class ModbusAddress : DeviceAddressBase
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] strArray = address.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] strArray = address.SplitStringBySemicolon();
|
||||
for (int index = 0; index < strArray.Length; ++index)
|
||||
{
|
||||
if (strArray[index].ToUpper().StartsWith("S="))
|
||||
|
||||
@@ -24,7 +24,7 @@ internal class ModbusHelper
|
||||
/// </summary>
|
||||
internal static byte[] AddCrc(byte[] command)
|
||||
{
|
||||
return EasyCRC16.CRC16(command);
|
||||
return CRC16Utils.CRC16(command);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -149,7 +149,7 @@ internal class ModbusHelper
|
||||
|
||||
|
||||
var data = response.SelectMiddle(0, response[2] != 0 ? response[2] + 5 : 8);
|
||||
if (crcCheck && !EasyCRC16.CheckCRC16(data))
|
||||
if (crcCheck && !CRC16Utils.CheckCRC16(data))
|
||||
return new OperResult<byte[], FilterResult>("Crc校验失败" + DataTransUtil.ByteToHexString(data, ' ')) { Content2 = FilterResult.Success };
|
||||
return GetModbusData(send, data.RemoveLast(2));
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// </summary>
|
||||
public class ModbusRtu : ReadWriteDevicesSerialSessionBase
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// ModbusRtu
|
||||
/// </summary>
|
||||
@@ -45,26 +44,24 @@ public class ModbusRtu : ReadWriteDevicesSerialSessionBase
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription()
|
||||
{
|
||||
return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription();
|
||||
return $"{base.GetAddressDescription()}{Environment.NewLine}{ModbusHelper.GetAddressDescription()}";
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack)
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime)
|
||||
{
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack);
|
||||
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station);
|
||||
return SendThenReturn(commandResult, cancellationToken);
|
||||
|
||||
return ModbusHelper.GetReadModbusCommand(address, length, Station).Then(a => SendThenReturn<ModbusRtuMessage>(a, cancellationToken));
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -79,7 +76,8 @@ public class ModbusRtu : ReadWriteDevicesSerialSessionBase
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station);
|
||||
return await SendThenReturnAsync(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -88,7 +86,7 @@ public class ModbusRtu : ReadWriteDevicesSerialSessionBase
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter(object socketClient = null)
|
||||
public override void SetDataAdapter(ISocketClient socketClient = default)
|
||||
{
|
||||
ModbusRtuDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
@@ -105,7 +103,8 @@ public class ModbusRtu : ReadWriteDevicesSerialSessionBase
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station);
|
||||
return SendThenReturn(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -120,7 +119,8 @@ public class ModbusRtu : ReadWriteDevicesSerialSessionBase
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station);
|
||||
return SendThenReturn(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -135,7 +135,8 @@ public class ModbusRtu : ReadWriteDevicesSerialSessionBase
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station);
|
||||
return await SendThenReturnAsync(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -150,7 +151,8 @@ public class ModbusRtu : ReadWriteDevicesSerialSessionBase
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station);
|
||||
return await SendThenReturnAsync(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -158,34 +160,5 @@ public class ModbusRtu : ReadWriteDevicesSerialSessionBase
|
||||
}
|
||||
}
|
||||
|
||||
private OperResult<byte[]> SendThenReturn(OperResult<byte[]> commandResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var item = commandResult.Content;
|
||||
if (FrameTime != 0)
|
||||
Thread.Sleep(FrameTime);
|
||||
var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>(commandResult.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<OperResult<byte[]>> SendThenReturnAsync(OperResult<byte[]> commandResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var item = commandResult.Content;
|
||||
await Task.Delay(FrameTime, cancellationToken);
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>(commandResult.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// Rtu适配器
|
||||
/// </summary>
|
||||
public class ModbusRtuDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<ModbusRtuMessage>
|
||||
internal class ModbusRtuDataHandleAdapter : ReadWriteDevicesSingleStreamDataHandleAdapter<ModbusRtuMessage>
|
||||
{
|
||||
/// <summary>
|
||||
/// 检测CRC
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class ModbusRtuMessage : MessageBase, IMessage
|
||||
internal class ModbusRtuMessage : MessageBase, IMessage
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override int HeadBytesLength => -1;
|
||||
|
||||
@@ -40,7 +40,7 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription()
|
||||
{
|
||||
return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription();
|
||||
return $"{base.GetAddressDescription()}{Environment.NewLine}{ModbusHelper.GetAddressDescription()}";
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,8 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station);
|
||||
return SendThenReturn(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -66,7 +67,8 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station);
|
||||
return await SendThenReturnAsync(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -75,14 +77,13 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack)
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime)
|
||||
{
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack);
|
||||
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter(object socketClient = null)
|
||||
public override void SetDataAdapter(ISocketClient socketClient = default)
|
||||
{
|
||||
ModbusRtuDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
@@ -99,7 +100,8 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station);
|
||||
return SendThenReturn(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -114,7 +116,8 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station);
|
||||
return SendThenReturn(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -129,7 +132,8 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station);
|
||||
return await SendThenReturnAsync(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -144,7 +148,8 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station);
|
||||
return await SendThenReturnAsync(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -152,34 +157,4 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase
|
||||
}
|
||||
}
|
||||
|
||||
private OperResult<byte[]> SendThenReturn(OperResult<byte[]> commandResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var item = commandResult.Content;
|
||||
if (FrameTime != 0)
|
||||
Thread.Sleep(FrameTime);
|
||||
var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>(commandResult.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<OperResult<byte[]>> SendThenReturnAsync(OperResult<byte[]> commandResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var item = commandResult.Content;
|
||||
await Task.Delay(FrameTime, cancellationToken);
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>(commandResult.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription()
|
||||
{
|
||||
return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription();
|
||||
return $"{base.GetAddressDescription()}{Environment.NewLine}{ModbusHelper.GetAddressDescription()}";
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
|
||||
@@ -47,7 +47,8 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station);
|
||||
return SendThenReturn(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -62,7 +63,8 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station);
|
||||
return await SendThenReturnAsync(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -71,7 +73,7 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter(object socketClient = null)
|
||||
public override void SetDataAdapter(ISocketClient socketClient = default)
|
||||
{
|
||||
ModbusRtuOverUdpDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
@@ -85,10 +87,9 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack)
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime)
|
||||
{
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack);
|
||||
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -98,7 +99,8 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station);
|
||||
return SendThenReturn(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -113,7 +115,8 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station);
|
||||
return SendThenReturn(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -128,7 +131,8 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station);
|
||||
return await SendThenReturnAsync(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -143,7 +147,8 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station);
|
||||
return await SendThenReturnAsync(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -151,34 +156,5 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase
|
||||
}
|
||||
}
|
||||
|
||||
private OperResult<byte[]> SendThenReturn(OperResult<byte[]> commandResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var item = commandResult.Content;
|
||||
if (FrameTime != 0)
|
||||
Thread.Sleep(FrameTime);
|
||||
var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>(commandResult.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<OperResult<byte[]>> SendThenReturnAsync(OperResult<byte[]> commandResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var item = commandResult.Content;
|
||||
await Task.Delay(FrameTime, cancellationToken);
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>(commandResult.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class ModbusRtuOverUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter<ModbusRtuMessage>
|
||||
internal class ModbusRtuOverUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter<ModbusRtuMessage>
|
||||
{
|
||||
/// <summary>
|
||||
/// 检测CRC
|
||||
|
||||
@@ -1,452 +0,0 @@
|
||||
#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.Collections.Concurrent;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Bool;
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
|
||||
/// </summary>
|
||||
public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SerialSession, Task<OperResult>> WriteData;
|
||||
|
||||
/// <summary>
|
||||
/// 继电器
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<byte, ByteBlock> ModbusServer01ByteBlocks = new();
|
||||
|
||||
/// <summary>
|
||||
/// 开关输入
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<byte, ByteBlock> ModbusServer02ByteBlocks = new();
|
||||
|
||||
/// <summary>
|
||||
/// 输入寄存器
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<byte, ByteBlock> ModbusServer03ByteBlocks = new();
|
||||
|
||||
/// <summary>
|
||||
/// 保持寄存器
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<byte, ByteBlock> ModbusServer04ByteBlocks = new();
|
||||
/// <inheritdoc/>
|
||||
public ModbusSerialServer(SerialSession serialSession) : base(serialSession)
|
||||
{
|
||||
ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big);
|
||||
RegisterByteLength = 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 多站点
|
||||
/// </summary>
|
||||
public bool MulStation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认站点
|
||||
/// </summary>
|
||||
public byte Station { get; set; } = 1;
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Dispose()
|
||||
{
|
||||
foreach (var item in ModbusServer01ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
foreach (var item in ModbusServer02ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
foreach (var item in ModbusServer03ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
foreach (var item in ModbusServer04ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
ModbusServer01ByteBlocks.Clear();
|
||||
ModbusServer02ByteBlocks.Clear();
|
||||
ModbusServer03ByteBlocks.Clear();
|
||||
ModbusServer04ByteBlocks.Clear();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription()
|
||||
{
|
||||
return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack)
|
||||
{
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack);
|
||||
|
||||
}
|
||||
|
||||
EasyLock easyLock = new();
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
easyLock.Wait();
|
||||
|
||||
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)
|
||||
{
|
||||
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[]>("功能码错误");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
easyLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(Read(address, length));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter(object socketClient)
|
||||
{
|
||||
ModbusSerialServerDataHandleAdapter dataHandleAdapter = new();
|
||||
dataHandleAdapter.CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout);
|
||||
SerialSession.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
easyLock.Wait();
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
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("功能码错误");
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
easyLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
easyLock.Wait();
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
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("功能码错误");
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
easyLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(Write(address, value));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(Write(address, value));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task Received(SerialSession client, ReceivedDataEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var requestInfo = e.RequestInfo;
|
||||
//接收外部报文
|
||||
if (requestInfo is ModbusSerialServerMessage modbusServerMessage)
|
||||
{
|
||||
if (modbusServerMessage.CurModbusAddress == null)
|
||||
{
|
||||
return;//无法解析直接返回
|
||||
}
|
||||
if (!modbusServerMessage.IsSuccess)
|
||||
{
|
||||
return;//无法解析直接返回
|
||||
}
|
||||
|
||||
if (modbusServerMessage.CurModbusAddress.WriteFunction == 0)//读取
|
||||
{
|
||||
var data = Read(modbusServerMessage.CurModbusAddress.ToString(), modbusServerMessage.Length);
|
||||
if (data.IsSuccess)
|
||||
{
|
||||
var coreData = data.Content;
|
||||
if (modbusServerMessage.CurModbusAddress.ReadFunction == 1 || modbusServerMessage.CurModbusAddress.ReadFunction == 2)
|
||||
{
|
||||
coreData = data.Content.Select(m => m > 0).ToArray().BoolArrayToByte().SelectMiddle(0, (int)Math.Ceiling(modbusServerMessage.Length / 8.0));
|
||||
}
|
||||
var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 2).SpliceArray(new byte[] { (byte)coreData.Length }, coreData);
|
||||
SerialSession.Send(sendData);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(SerialSession, modbusServerMessage);//返回错误码
|
||||
}
|
||||
}
|
||||
else//写入
|
||||
{
|
||||
var coreData = modbusServerMessage.Content;
|
||||
if (modbusServerMessage.CurModbusAddress.ReadFunction == 1 || modbusServerMessage.CurModbusAddress.ReadFunction == 2)
|
||||
{
|
||||
//写入继电器
|
||||
if (WriteData != null)
|
||||
{
|
||||
// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
|
||||
if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess)
|
||||
{
|
||||
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length));
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
WriteSuccess03(SerialSession, modbusServerMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(SerialSession, modbusServerMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(SerialSession, modbusServerMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//写入内存区
|
||||
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length));
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
WriteSuccess03(SerialSession, modbusServerMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(SerialSession, modbusServerMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//写入寄存器
|
||||
if (WriteData != null)
|
||||
{
|
||||
|
||||
if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess)
|
||||
{
|
||||
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
WriteSuccess03(SerialSession, modbusServerMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(SerialSession, modbusServerMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(SerialSession, modbusServerMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
WriteSuccess03(SerialSession, modbusServerMessage);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(SerialSession, modbusServerMessage);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, ToString());
|
||||
}
|
||||
//返回错误码
|
||||
static void WriteError(SerialSession SerialSession, ModbusSerialServerMessage modbusServerMessage)
|
||||
{
|
||||
var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 2)
|
||||
.SpliceArray(new byte[] { (byte)1 });//01 lllegal function
|
||||
sendData[1] = (byte)(sendData[1] + 128);
|
||||
SerialSession.Send(sendData);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteSuccess03(SerialSession SerialSession, ModbusSerialServerMessage modbusServerMessage)
|
||||
{
|
||||
var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 6);
|
||||
SerialSession.Send(sendData);
|
||||
}
|
||||
|
||||
private void Init(ModbusAddress mAddress)
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -37,13 +37,13 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription()
|
||||
{
|
||||
return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription();
|
||||
return $"{base.GetAddressDescription()}{Environment.NewLine}{ModbusHelper.GetAddressDescription()}";
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack)
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime)
|
||||
{
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack);
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -53,8 +53,8 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station);
|
||||
var data = SendThenReturn(commandResult, cancellationToken);
|
||||
return data;
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn<ModbusTcpMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -70,8 +70,8 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase
|
||||
await ConnectAsync(cancellationToken);
|
||||
|
||||
var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station);
|
||||
var data = await SendThenReturnAsync(commandResult, cancellationToken);
|
||||
return data;
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync<ModbusTcpMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -81,7 +81,7 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter(object socketClient = null)
|
||||
public override void SetDataAdapter(ISocketClient socketClient = default)
|
||||
{
|
||||
ModbusTcpDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
@@ -98,7 +98,8 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station);
|
||||
return SendThenReturn(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn<ModbusTcpMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -113,7 +114,8 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station);
|
||||
return SendThenReturn(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn<ModbusTcpMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -128,7 +130,8 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station);
|
||||
return await SendThenReturnAsync(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync<ModbusTcpMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -143,7 +146,8 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station);
|
||||
return await SendThenReturnAsync(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync<ModbusTcpMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -151,34 +155,4 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase
|
||||
}
|
||||
}
|
||||
|
||||
private OperResult<byte[]> SendThenReturn(OperResult<byte[]> commandResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var item = commandResult.Content;
|
||||
if (FrameTime != 0)
|
||||
Thread.Sleep(FrameTime);
|
||||
var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>(commandResult.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<OperResult<byte[]>> SendThenReturnAsync(OperResult<byte[]> commandResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var item = commandResult.Content;
|
||||
await Task.Delay(FrameTime, cancellationToken);
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>(commandResult.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// ModbusTcpDataHandleAdapter
|
||||
/// </summary>
|
||||
public class ModbusTcpDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<ModbusTcpMessage>
|
||||
internal class ModbusTcpDataHandleAdapter : ReadWriteDevicesSingleStreamDataHandleAdapter<ModbusTcpMessage>
|
||||
{
|
||||
private readonly EasyIncrementCount easyIncrementCount = new(ushort.MaxValue);
|
||||
private readonly IncrementCount easyIncrementCount = new(ushort.MaxValue);
|
||||
|
||||
/// <summary>
|
||||
/// 检测事务标识符
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class ModbusTcpMessage : MessageBase, IMessage
|
||||
internal class ModbusTcpMessage : MessageBase, IMessage
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override int HeadBytesLength => 6;
|
||||
@@ -29,6 +29,7 @@ public class ModbusTcpMessage : MessageBase, IMessage
|
||||
HeadBytes = heads;
|
||||
|
||||
int num = (HeadBytes[4] * 256) + HeadBytes[5];
|
||||
if (num > 0xff + 3) return false;
|
||||
BodyLength = num;
|
||||
|
||||
if (!IsCheckMessageId)
|
||||
|
||||
@@ -1,470 +0,0 @@
|
||||
#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.Collections.Concurrent;
|
||||
using System.ComponentModel;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Bool;
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
|
||||
/// </summary>
|
||||
public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SocketClient, Task<OperResult>> WriteData;
|
||||
|
||||
/// <summary>
|
||||
/// 继电器
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<byte, ByteBlock> ModbusServer01ByteBlocks = new();
|
||||
|
||||
/// <summary>
|
||||
/// 开关输入
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<byte, ByteBlock> ModbusServer02ByteBlocks = new();
|
||||
|
||||
/// <summary>
|
||||
/// 输入寄存器
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<byte, ByteBlock> ModbusServer03ByteBlocks = new();
|
||||
|
||||
/// <summary>
|
||||
/// 保持寄存器
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<byte, ByteBlock> ModbusServer04ByteBlocks = new();
|
||||
/// <inheritdoc/>
|
||||
public ModbusTcpServer(TcpService tcpService) : base(tcpService)
|
||||
{
|
||||
ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big);
|
||||
RegisterByteLength = 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 多站点
|
||||
/// </summary>
|
||||
[Description("多站点")]
|
||||
public bool MulStation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认站点
|
||||
/// </summary>
|
||||
[Description("默认站点")]
|
||||
public byte Station { get; set; } = 1;
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Dispose()
|
||||
{
|
||||
foreach (var item in ModbusServer01ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
foreach (var item in ModbusServer02ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
foreach (var item in ModbusServer03ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
foreach (var item in ModbusServer04ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
ModbusServer01ByteBlocks.Clear();
|
||||
ModbusServer02ByteBlocks.Clear();
|
||||
ModbusServer03ByteBlocks.Clear();
|
||||
ModbusServer04ByteBlocks.Clear();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription()
|
||||
{
|
||||
return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack)
|
||||
{
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack);
|
||||
|
||||
}
|
||||
|
||||
EasyLock easyLock = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
easyLock.Wait();
|
||||
|
||||
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)
|
||||
{
|
||||
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[]>("功能码错误");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
easyLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(Read(address, length));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter(object socketClient)
|
||||
{
|
||||
if (socketClient is SocketClient client)
|
||||
{
|
||||
ModbusTcpServerDataHandleAdapter dataHandleAdapter = new();
|
||||
dataHandleAdapter.CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout);
|
||||
client.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var item in TcpService.GetClients())
|
||||
{
|
||||
ModbusTcpDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
};
|
||||
item.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
easyLock.Wait();
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
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("功能码错误");
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
easyLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
easyLock.Wait();
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
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("功能码错误");
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
easyLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(Write(address, value));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(Write(address, value));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task Received(SocketClient client, ReceivedDataEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var requestInfo = e.RequestInfo;
|
||||
//接收外部报文
|
||||
if (requestInfo is ModbusTcpServerMessage modbusServerMessage)
|
||||
{
|
||||
if (modbusServerMessage.CurModbusAddress == null)
|
||||
{
|
||||
return;//无法解析直接返回
|
||||
}
|
||||
if (!modbusServerMessage.IsSuccess)
|
||||
{
|
||||
return;//无法解析直接返回
|
||||
}
|
||||
|
||||
if (modbusServerMessage.CurModbusAddress.WriteFunction == 0)//读取
|
||||
{
|
||||
var data = Read(modbusServerMessage.CurModbusAddress.ToString(), modbusServerMessage.Length);
|
||||
if (data.IsSuccess)
|
||||
{
|
||||
var coreData = data.Content;
|
||||
if (modbusServerMessage.CurModbusAddress.ReadFunction == 1 || modbusServerMessage.CurModbusAddress.ReadFunction == 2)
|
||||
{
|
||||
coreData = data.Content.Select(m => m > 0).ToArray().BoolArrayToByte().SelectMiddle(0, (int)Math.Ceiling(modbusServerMessage.Length / 8.0));
|
||||
}
|
||||
var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 8).SpliceArray(new byte[] { (byte)coreData.Length }, coreData);
|
||||
sendData[5] = (byte)(sendData.Length - 6);
|
||||
client.Send(sendData);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(client, modbusServerMessage);//返回错误码
|
||||
}
|
||||
}
|
||||
else//写入
|
||||
{
|
||||
var coreData = modbusServerMessage.Content;
|
||||
if (modbusServerMessage.CurModbusAddress.ReadFunction == 1 || modbusServerMessage.CurModbusAddress.ReadFunction == 2)
|
||||
{
|
||||
//写入继电器
|
||||
if (WriteData != null)
|
||||
{
|
||||
// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
|
||||
if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess)
|
||||
{
|
||||
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length));
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
WriteSuccess03(client, modbusServerMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(client, modbusServerMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(client, modbusServerMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//写入内存区
|
||||
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length));
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
WriteSuccess03(client, modbusServerMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(client, modbusServerMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//写入寄存器
|
||||
if (WriteData != null)
|
||||
{
|
||||
|
||||
if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess)
|
||||
{
|
||||
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
WriteSuccess03(client, modbusServerMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(client, modbusServerMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(client, modbusServerMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
WriteSuccess03(client, modbusServerMessage);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(client, modbusServerMessage);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, ToString());
|
||||
}
|
||||
//返回错误码
|
||||
static void WriteError(SocketClient client, ModbusTcpServerMessage modbusServerMessage)
|
||||
{
|
||||
var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 8)
|
||||
.SpliceArray(new byte[] { (byte)1 });//01 lllegal function
|
||||
sendData[5] = (byte)(sendData.Length - 6);
|
||||
sendData[7] = (byte)(sendData[7] + 128);
|
||||
client.Send(sendData);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteSuccess03(SocketClient client, ModbusTcpServerMessage modbusServerMessage)
|
||||
{
|
||||
var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 12);
|
||||
sendData[5] = (byte)(sendData.Length - 6);
|
||||
client.Send(sendData);
|
||||
}
|
||||
|
||||
private void Init(ModbusAddress mAddress)
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -39,16 +39,15 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack)
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime)
|
||||
{
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack);
|
||||
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription()
|
||||
{
|
||||
return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription();
|
||||
return $"{base.GetAddressDescription()}{Environment.NewLine}{ModbusHelper.GetAddressDescription()}";
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
|
||||
@@ -57,7 +56,8 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station);
|
||||
return SendThenReturn(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn<ModbusTcpMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -72,7 +72,8 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station);
|
||||
return await SendThenReturnAsync(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync<ModbusTcpMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -81,7 +82,7 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter(object socketClient = null)
|
||||
public override void SetDataAdapter(ISocketClient socketClient = default)
|
||||
{
|
||||
ModbusUdpDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
@@ -101,7 +102,8 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station);
|
||||
return SendThenReturn(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn<ModbusTcpMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -116,7 +118,8 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase
|
||||
{
|
||||
Connect(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station);
|
||||
return SendThenReturn(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return SendThenReturn<ModbusTcpMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -131,7 +134,8 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station);
|
||||
return await SendThenReturnAsync(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync<ModbusTcpMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -146,7 +150,8 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase
|
||||
{
|
||||
await ConnectAsync(cancellationToken);
|
||||
var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station);
|
||||
return await SendThenReturnAsync(commandResult, cancellationToken);
|
||||
if (!commandResult.IsSuccess) return commandResult;
|
||||
return await SendThenReturnAsync<ModbusTcpMessage>(commandResult.Content, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -154,34 +159,5 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase
|
||||
}
|
||||
}
|
||||
|
||||
private OperResult<byte[]> SendThenReturn(OperResult<byte[]> commandResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var item = commandResult.Content;
|
||||
if (FrameTime != 0)
|
||||
Thread.Sleep(FrameTime);
|
||||
var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>(commandResult.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<OperResult<byte[]>> SendThenReturnAsync(OperResult<byte[]> commandResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var item = commandResult.Content;
|
||||
await Task.Delay(FrameTime, cancellationToken);
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>(commandResult.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class ModbusUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter<ModbusTcpMessage>
|
||||
internal class ModbusUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter<ModbusTcpMessage>
|
||||
{
|
||||
private readonly EasyIncrementCount easyIncrementCount = new(ushort.MaxValue);
|
||||
private readonly IncrementCount easyIncrementCount = new(ushort.MaxValue);
|
||||
|
||||
/// <summary>
|
||||
/// 检测事务标识符
|
||||
|
||||
@@ -26,8 +26,9 @@ public class PackHelper
|
||||
/// <param name="device"></param>
|
||||
/// <param name="deviceVariables"></param>
|
||||
/// <param name="maxPack">最大打包长度</param>
|
||||
/// <param name="defaultIntervalTime">默认间隔时间</param>
|
||||
/// <returns></returns>
|
||||
public static List<T> LoadSourceRead<T, T2>(IReadWrite device, List<T2> deviceVariables, int maxPack) where T : IDeviceVariableSourceRead<IDeviceVariableRunTime>, new() where T2 : IDeviceVariableRunTime, new()
|
||||
public static List<T> LoadSourceRead<T, T2>(IReadWrite device, List<T2> deviceVariables, int maxPack, int defaultIntervalTime) where T : IDeviceVariableSourceRead<IDeviceVariableRunTime>, new() where T2 : IDeviceVariableRunTime, new()
|
||||
{
|
||||
if (deviceVariables == null)
|
||||
throw new ArgumentNullException(nameof(deviceVariables));
|
||||
@@ -37,13 +38,13 @@ public class PackHelper
|
||||
//需要先剔除额外信息,比如dataformat等
|
||||
foreach (var item in deviceVariables)
|
||||
{
|
||||
var address = item.VariableAddress;
|
||||
var address = item.Address;
|
||||
IThingsGatewayBitConverter transformParameter = ByteTransformUtil.GetTransByAddress(ref address, byteConverter);
|
||||
item.ThingsGatewayBitConverter = transformParameter;
|
||||
//item.VariableAddress = address;
|
||||
item.Index = device.GetBitOffset(item.VariableAddress);
|
||||
//item.Address = address;
|
||||
item.Index = device.GetBitOffset(item.Address);
|
||||
}
|
||||
var deviceVariableRunTimeGroups = deviceVariables.GroupBy(it => it.IntervalTime);
|
||||
var deviceVariableRunTimeGroups = deviceVariables.GroupBy(it => it.IntervalTime ?? defaultIntervalTime);
|
||||
foreach (var group in deviceVariableRunTimeGroups)
|
||||
{
|
||||
Dictionary<ModbusAddress, T2> map = group.ToDictionary(it =>
|
||||
@@ -66,10 +67,10 @@ public class PackHelper
|
||||
lastLen *= it.ThingsGatewayBitConverter.Length.Value;
|
||||
}
|
||||
|
||||
var address = it.VariableAddress;
|
||||
var address = it.Address;
|
||||
if (address.IndexOf('.') > 0)
|
||||
{
|
||||
var addressSplits = address.SplitDot();
|
||||
var addressSplits = address.SplitStringByDelimiter();
|
||||
address = addressSplits.RemoveLast(1).ArrayToString(".");
|
||||
}
|
||||
var result = ModbusAddress.ParseFrom(address);
|
||||
@@ -133,9 +134,9 @@ public class PackHelper
|
||||
|
||||
T sourceRead = new()
|
||||
{
|
||||
TimerTick = new TimerTick(intervalTime),
|
||||
IntervalTimeTick = new TimerTick(intervalTime),
|
||||
//这里只需要根据地址排序的第一个地址,作为实际打包报文中的起始地址
|
||||
VariableAddress = startAddress.ToString(),
|
||||
Address = startAddress.ToString(),
|
||||
Length = sourceLen
|
||||
};
|
||||
foreach (var item in tempAddressEnd)
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
internal interface IModbusServer : IReadWrite
|
||||
{
|
||||
/// <summary>
|
||||
/// 读写锁
|
||||
/// </summary>
|
||||
public EasyLock EasyLock { get; }
|
||||
/// <summary>
|
||||
/// 多站点
|
||||
/// </summary>
|
||||
bool MulStation { get; set; }
|
||||
/// <summary>
|
||||
/// 默认站点
|
||||
/// </summary>
|
||||
byte Station { get; set; }
|
||||
/// <summary>
|
||||
/// 是否Rtu报文
|
||||
/// </summary>
|
||||
bool IsRtu { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 继电器
|
||||
/// </summary>
|
||||
internal ConcurrentDictionary<byte, ByteBlock> ModbusServer01ByteBlocks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开关输入
|
||||
/// </summary>
|
||||
internal ConcurrentDictionary<byte, ByteBlock> ModbusServer02ByteBlocks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 输入寄存器
|
||||
/// </summary>
|
||||
internal ConcurrentDictionary<byte, ByteBlock> ModbusServer03ByteBlocks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 保持寄存器
|
||||
/// </summary>
|
||||
internal ConcurrentDictionary<byte, ByteBlock> ModbusServer04ByteBlocks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
/// <param name="mAddress"></param>
|
||||
public void Init(ModbusAddress mAddress);
|
||||
/// <summary>
|
||||
/// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
|
||||
/// </summary>
|
||||
public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, ISenderClient, Task<OperResult>> OnWriteData { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -10,20 +10,20 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Plugin.Mqtt;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class IotSharpClientVariableProperty : VariablePropertyBase
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus
|
||||
{
|
||||
/// <summary>
|
||||
/// 启用
|
||||
/// ModbusServerMessage
|
||||
/// </summary>
|
||||
[VariableProperty("启用", "")]
|
||||
public bool Enable { get; set; } = true;
|
||||
/// <summary>
|
||||
/// 允许写入
|
||||
/// </summary>
|
||||
[VariableProperty("允许写入", "")]
|
||||
public bool VariableRpcEnable { get; set; } = true;
|
||||
}
|
||||
internal interface IModbusServerMessage : IMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// 读写长度
|
||||
/// </summary>
|
||||
int Length { get; set; }
|
||||
/// <summary>
|
||||
/// 当前关联的地址
|
||||
/// </summary>
|
||||
ModbusAddress ModbusAddress { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
#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.Collections.Concurrent;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase, IModbusServer
|
||||
{
|
||||
/// <summary>
|
||||
/// 读写锁
|
||||
/// </summary>
|
||||
public EasyLock EasyLock { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
|
||||
/// </summary>
|
||||
public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, ISenderClient, Task<OperResult>> OnWriteData { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<byte, ByteBlock> ModbusServer01ByteBlocks { get; set; } = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<byte, ByteBlock> ModbusServer02ByteBlocks { get; set; } = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<byte, ByteBlock> ModbusServer03ByteBlocks { get; set; } = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConcurrentDictionary<byte, ByteBlock> ModbusServer04ByteBlocks { get; set; } = new();
|
||||
/// <inheritdoc/>
|
||||
public ModbusSerialServer(SerialSession serialSession) : base(serialSession)
|
||||
{
|
||||
ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big);
|
||||
RegisterByteLength = 2;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool MulStation { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte Station { get; set; } = 1;
|
||||
/// <inheritdoc/>
|
||||
public bool IsRtu => true;
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Dispose()
|
||||
{
|
||||
foreach (var item in ModbusServer01ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
foreach (var item in ModbusServer02ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
foreach (var item in ModbusServer03ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
foreach (var item in ModbusServer04ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
ModbusServer01ByteBlocks.Clear();
|
||||
ModbusServer02ByteBlocks.Clear();
|
||||
ModbusServer03ByteBlocks.Clear();
|
||||
ModbusServer04ByteBlocks.Clear();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription()
|
||||
{
|
||||
return $"{base.GetAddressDescription()}{Environment.NewLine}{ModbusHelper.GetAddressDescription()}";
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime)
|
||||
{
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
return ModbusServerHelpers.Read(this, address, length);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(Read(address, length));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter(ISocketClient socketClient = default)
|
||||
{
|
||||
ModbusSerialServerDataHandleAdapter dataHandleAdapter = new();
|
||||
dataHandleAdapter.CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout);
|
||||
SerialSession.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
return ModbusServerHelpers.Write(this, address, value);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
return ModbusServerHelpers.Write(this, address, value);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(Write(address, value));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(Write(address, value));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task Received(SerialSession client, ReceivedDataEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ModbusServerHelpers.Received(this, client, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Init(ModbusAddress mAddress)
|
||||
{
|
||||
ModbusServer01ByteBlocks.GetOrAdd(mAddress.Station, a =>
|
||||
{
|
||||
var data = new ByteBlock(ushort.MaxValue * 2);
|
||||
data.SetLength(ushort.MaxValue * 2);
|
||||
return data;
|
||||
});
|
||||
ModbusServer02ByteBlocks.GetOrAdd(mAddress.Station, a =>
|
||||
{
|
||||
var data = new ByteBlock(ushort.MaxValue * 2);
|
||||
data.SetLength(ushort.MaxValue * 2);
|
||||
return data;
|
||||
});
|
||||
ModbusServer03ByteBlocks.GetOrAdd(mAddress.Station, a =>
|
||||
{
|
||||
var data = new ByteBlock(ushort.MaxValue * 2);
|
||||
data.SetLength(ushort.MaxValue * 2);
|
||||
return data;
|
||||
});
|
||||
ModbusServer04ByteBlocks.GetOrAdd(mAddress.Station, a =>
|
||||
{
|
||||
var data = new ByteBlock(ushort.MaxValue * 2);
|
||||
data.SetLength(ushort.MaxValue * 2);
|
||||
return data;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ using ThingsGateway.Foundation.Extension.Generic;
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<ModbusSerialServerMessage>
|
||||
internal class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesSingleStreamDataHandleAdapter<ModbusSerialServerMessage>
|
||||
{
|
||||
private readonly ThingsGatewayBitConverter ThingsGatewayBitConverter = new(EndianType.Big);
|
||||
|
||||
@@ -34,7 +34,7 @@ public class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesTcpDataHandle
|
||||
/// </summary>
|
||||
/// <param name="response">返回数据</param>
|
||||
/// <returns></returns>
|
||||
internal OperResult<byte[]> GetModbusData(byte[] response)
|
||||
internal OperResult<byte[], FilterResult> GetModbusData(byte[] response)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -42,22 +42,30 @@ public class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesTcpDataHandle
|
||||
if (func == 1 || func == 2 || func == 3 || func == 4 || func == 5 || func == 6)
|
||||
{
|
||||
if (response.Length == 6)
|
||||
return OperResult.CreateSuccessResult(response);
|
||||
return OperResult.CreateSuccessResult(response, FilterResult.Success);
|
||||
}
|
||||
else if (func == 15 || func == 16)
|
||||
{
|
||||
var length = ThingsGatewayBitConverter.ToByte(response, 6);
|
||||
if (response.Length == 7 + length)
|
||||
{
|
||||
return OperResult.CreateSuccessResult(response);
|
||||
return OperResult.CreateSuccessResult(response, FilterResult.Success);
|
||||
}
|
||||
if (response.Length > 7 + length)
|
||||
{
|
||||
return new() { Content2 = FilterResult.Success, Message = $"数据长度{response.Length}错误" };
|
||||
}
|
||||
else
|
||||
{
|
||||
return new() { Content2 = FilterResult.Cache, Message = $"数据长度{response.Length}错误" };
|
||||
}
|
||||
}
|
||||
|
||||
return new OperResult<byte[]>() { Message = $"数据长度{response.Length}错误" };
|
||||
return new() { Content2 = FilterResult.Success, Message = $"数据长度{response.Length}错误" };
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
return new(ex) { Content2 = FilterResult.Success };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +96,7 @@ public class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesTcpDataHandle
|
||||
{
|
||||
if (function > 6)
|
||||
{
|
||||
request.CurModbusAddress = new ModbusAddress()
|
||||
request.ModbusAddress = new ModbusAddress()
|
||||
{
|
||||
Station = station,
|
||||
Address = addressStart.ToString(),
|
||||
@@ -100,7 +108,7 @@ public class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesTcpDataHandle
|
||||
}
|
||||
else
|
||||
{
|
||||
request.CurModbusAddress = new ModbusAddress()
|
||||
request.ModbusAddress = new ModbusAddress()
|
||||
{
|
||||
Station = station,
|
||||
Address = addressStart.ToString(),
|
||||
@@ -113,7 +121,7 @@ public class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesTcpDataHandle
|
||||
}
|
||||
else
|
||||
{
|
||||
request.CurModbusAddress = new ModbusAddress()
|
||||
request.ModbusAddress = new ModbusAddress()
|
||||
{
|
||||
Station = station,
|
||||
Address = addressStart.ToString(),
|
||||
@@ -129,7 +137,7 @@ public class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesTcpDataHandle
|
||||
{
|
||||
request.ErrorCode = result.ErrorCode;
|
||||
request.Message = result.Message;
|
||||
return FilterResult.Cache;
|
||||
return result.Content2;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -15,15 +15,11 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class ModbusSerialServerMessage : MessageBase, IMessage
|
||||
internal class ModbusSerialServerMessage : MessageBase, IMessage, IModbusServerMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前关联的地址
|
||||
/// </summary>
|
||||
public ModbusAddress CurModbusAddress { get; set; }
|
||||
/// <summary>
|
||||
/// 当前读写的数据长度
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
public ModbusAddress ModbusAddress { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public int Length { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -0,0 +1,356 @@
|
||||
#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 ThingsGateway.Foundation.Adapter.Modbus;
|
||||
using ThingsGateway.Foundation.Extension.Bool;
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
internal static class ModbusServerHelpers
|
||||
{
|
||||
|
||||
internal static OperResult<byte[]> Read(IModbusServer modbusServer, string address, int length)
|
||||
{
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, modbusServer.Station);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
if (modbusServer.MulStation)
|
||||
{
|
||||
modbusServer.Init(mAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (modbusServer.Station != mAddress.Station)
|
||||
{
|
||||
return new OperResult<byte[]>("地址错误");
|
||||
}
|
||||
modbusServer.Init(mAddress);
|
||||
}
|
||||
try
|
||||
{
|
||||
modbusServer.EasyLock.Wait();
|
||||
|
||||
var ModbusServer01ByteBlock = modbusServer.ModbusServer01ByteBlocks[mAddress.Station];
|
||||
var ModbusServer02ByteBlock = modbusServer.ModbusServer02ByteBlocks[mAddress.Station];
|
||||
var ModbusServer03ByteBlock = modbusServer.ModbusServer03ByteBlocks[mAddress.Station];
|
||||
var ModbusServer04ByteBlock = modbusServer.ModbusServer04ByteBlocks[mAddress.Station];
|
||||
int len = mAddress.ReadFunction == 2 || mAddress.ReadFunction == 1 ? length : length * modbusServer.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 * modbusServer.RegisterByteLength;
|
||||
ModbusServer03ByteBlock.Read(bytes3);
|
||||
return OperResult.CreateSuccessResult(bytes3);
|
||||
case 4:
|
||||
byte[] bytes4 = new byte[len];
|
||||
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * modbusServer.RegisterByteLength;
|
||||
ModbusServer04ByteBlock.Read(bytes4);
|
||||
return OperResult.CreateSuccessResult(bytes4);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
modbusServer.EasyLock.Release();
|
||||
}
|
||||
return new OperResult<byte[]>("功能码错误");
|
||||
}
|
||||
|
||||
|
||||
internal static OperResult Write(IModbusServer modbusServer, string address, byte[] value)
|
||||
{
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, modbusServer.Station);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult(ex);
|
||||
}
|
||||
if (modbusServer.MulStation)
|
||||
{
|
||||
modbusServer.Init(mAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (modbusServer.Station != mAddress.Station)
|
||||
{
|
||||
return new OperResult("地址错误");
|
||||
}
|
||||
modbusServer.Init(mAddress);
|
||||
}
|
||||
try
|
||||
{
|
||||
modbusServer.EasyLock.Wait();
|
||||
var ModbusServer03ByteBlock = modbusServer.ModbusServer03ByteBlocks[mAddress.Station];
|
||||
var ModbusServer04ByteBlock = modbusServer.ModbusServer04ByteBlocks[mAddress.Station];
|
||||
switch (mAddress.ReadFunction)
|
||||
{
|
||||
case 3:
|
||||
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * modbusServer.RegisterByteLength;
|
||||
ModbusServer03ByteBlock.Write(value);
|
||||
return OperResult.CreateSuccessResult();
|
||||
case 4:
|
||||
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * modbusServer.RegisterByteLength;
|
||||
ModbusServer04ByteBlock.Write(value);
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
}
|
||||
finally { modbusServer.EasyLock.Release(); }
|
||||
return new OperResult("功能码错误");
|
||||
}
|
||||
|
||||
|
||||
internal static OperResult Write(IModbusServer modbusServer, string address, bool[] value)
|
||||
{
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, modbusServer.Station);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (new OperResult(ex));
|
||||
}
|
||||
if (modbusServer.MulStation)
|
||||
{
|
||||
modbusServer.Init(mAddress);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (modbusServer.Station != mAddress.Station)
|
||||
{
|
||||
return (new OperResult("地址错误"));
|
||||
}
|
||||
modbusServer.Init(mAddress);
|
||||
|
||||
}
|
||||
try
|
||||
{
|
||||
modbusServer.EasyLock.Wait();
|
||||
var ModbusServer01ByteBlock = modbusServer.ModbusServer01ByteBlocks[mAddress.Station];
|
||||
var ModbusServer02ByteBlock = modbusServer.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());
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
modbusServer.EasyLock.Release();
|
||||
}
|
||||
|
||||
return new OperResult("功能码错误");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
internal static async Task Received(IModbusServer modbusServer, ISenderClient client, ReceivedDataEventArgs e)
|
||||
{
|
||||
var requestInfo = e.RequestInfo;
|
||||
//接收外部报文
|
||||
if (requestInfo is IModbusServerMessage modbusServerMessage)
|
||||
{
|
||||
if (modbusServerMessage.ModbusAddress == null)
|
||||
{
|
||||
return;//无法解析直接返回
|
||||
}
|
||||
if (!modbusServerMessage.IsSuccess)
|
||||
{
|
||||
return;//无法解析直接返回
|
||||
}
|
||||
|
||||
if (modbusServerMessage.ModbusAddress.WriteFunction == 0)//读取
|
||||
{
|
||||
var data = modbusServer.Read(modbusServerMessage.ModbusAddress.ToString(), modbusServerMessage.Length);
|
||||
if (data.IsSuccess)
|
||||
{
|
||||
var coreData = data.Content;
|
||||
if (modbusServerMessage.ModbusAddress.ReadFunction == 1 || modbusServerMessage.ModbusAddress.ReadFunction == 2)
|
||||
{
|
||||
coreData = data.Content.Select(m => m > 0).ToArray().BoolArrayToByte().SelectMiddle(0, (int)Math.Ceiling(modbusServerMessage.Length / 8.0));
|
||||
}
|
||||
//rtu返回头
|
||||
if (modbusServer.IsRtu)
|
||||
{
|
||||
var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 2).SpliceArray(new byte[] { (byte)coreData.Length }, coreData);
|
||||
client.Send(sendData);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 8).SpliceArray(new byte[] { (byte)coreData.Length }, coreData);
|
||||
sendData[5] = (byte)(sendData.Length - 6);
|
||||
client.Send(sendData);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(modbusServer.IsRtu, client, modbusServerMessage);//返回错误码
|
||||
}
|
||||
}
|
||||
else//写入
|
||||
{
|
||||
var coreData = modbusServerMessage.Content;
|
||||
if (modbusServerMessage.ModbusAddress.ReadFunction == 1 || modbusServerMessage.ModbusAddress.ReadFunction == 2)
|
||||
{
|
||||
//写入继电器
|
||||
if (modbusServer.OnWriteData != null)
|
||||
{
|
||||
// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
|
||||
if ((await modbusServer.OnWriteData(modbusServerMessage.ModbusAddress, modbusServerMessage.Content, modbusServer.ThingsGatewayBitConverter, client)).IsSuccess)
|
||||
{
|
||||
WriteSuccess(modbusServer.IsRtu, client, modbusServerMessage);
|
||||
//var result = modbusServer.Write(modbusServerMessage.ModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length));
|
||||
//if (result.IsSuccess)
|
||||
//{
|
||||
// WriteSuccess(modbusServer, modbusServerMessage);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// WriteError(modbusServer, modbusServerMessage);
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(modbusServer.IsRtu, client, modbusServerMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//写入内存区
|
||||
var result = modbusServer.Write(modbusServerMessage.ModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length));
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
WriteSuccess(modbusServer.IsRtu, client, modbusServerMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(modbusServer.IsRtu, client, modbusServerMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//写入寄存器
|
||||
if (modbusServer.OnWriteData != null)
|
||||
{
|
||||
|
||||
if ((await modbusServer.OnWriteData(modbusServerMessage.ModbusAddress, modbusServerMessage.Content, modbusServer.ThingsGatewayBitConverter, client)).IsSuccess)
|
||||
{
|
||||
WriteSuccess(modbusServer.IsRtu, client, modbusServerMessage);
|
||||
//var result = modbusServer.Write(modbusServerMessage.ModbusAddress.ToString(), coreData);
|
||||
//if (result.IsSuccess)
|
||||
//{
|
||||
// WriteSuccess(modbusServer, modbusServerMessage);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// WriteError(modbusServer, modbusServerMessage);
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(modbusServer.IsRtu, client, modbusServerMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = modbusServer.Write(modbusServerMessage.ModbusAddress.ToString(), coreData);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
WriteSuccess(modbusServer.IsRtu, client, modbusServerMessage);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(modbusServer.IsRtu, client, modbusServerMessage);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 返回错误码
|
||||
/// </summary>
|
||||
static void WriteError(bool isRtu, ISenderClient client, IModbusServerMessage modbusServerMessage)
|
||||
{
|
||||
if (isRtu)
|
||||
{
|
||||
var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 2)
|
||||
.SpliceArray(new byte[] { (byte)1 });//01 lllegal function
|
||||
sendData[1] = (byte)(sendData[1] + 128);
|
||||
client.Send(sendData);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 8)
|
||||
.SpliceArray(new byte[] { (byte)1 });//01 lllegal function
|
||||
sendData[5] = (byte)(sendData.Length - 6);
|
||||
sendData[7] = (byte)(sendData[7] + 128);
|
||||
client.Send(sendData);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 返回成功
|
||||
/// </summary>
|
||||
internal static void WriteSuccess(bool isRtu, ISenderClient client, IModbusServerMessage modbusServerMessage)
|
||||
{
|
||||
if (isRtu)
|
||||
{
|
||||
var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 6);
|
||||
client.Send(sendData);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 12);
|
||||
sendData[5] = (byte)(sendData.Length - 6);
|
||||
client.Send(sendData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
#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.Collections.Concurrent;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class ModbusTcpServer : ReadWriteDevicesTcpServerBase, IModbusServer
|
||||
{
|
||||
/// <summary>
|
||||
/// 读写锁
|
||||
/// </summary>
|
||||
public EasyLock EasyLock { get; } = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ModbusTcpServer(TcpService tcpService) : base(tcpService)
|
||||
{
|
||||
ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big);
|
||||
RegisterByteLength = 2;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsRtu => false;
|
||||
|
||||
/// <summary>
|
||||
/// 继电器
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<byte, ByteBlock> ModbusServer01ByteBlocks { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 开关输入
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<byte, ByteBlock> ModbusServer02ByteBlocks { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 输入寄存器
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<byte, ByteBlock> ModbusServer03ByteBlocks { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 保持寄存器
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<byte, ByteBlock> ModbusServer04ByteBlocks { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 多站点
|
||||
/// </summary>
|
||||
[Description("多站点")]
|
||||
public bool MulStation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
|
||||
/// </summary>
|
||||
public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, ISenderClient, Task<OperResult>> OnWriteData { get; set; }
|
||||
/// <summary>
|
||||
/// 默认站点
|
||||
/// </summary>
|
||||
[Description("默认站点")]
|
||||
public byte Station { get; set; } = 1;
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Dispose()
|
||||
{
|
||||
foreach (var item in ModbusServer01ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
foreach (var item in ModbusServer02ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
foreach (var item in ModbusServer03ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
foreach (var item in ModbusServer04ByteBlocks)
|
||||
{
|
||||
item.Value.SafeDispose();
|
||||
}
|
||||
ModbusServer01ByteBlocks.Clear();
|
||||
ModbusServer02ByteBlocks.Clear();
|
||||
ModbusServer03ByteBlocks.Clear();
|
||||
ModbusServer04ByteBlocks.Clear();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription()
|
||||
{
|
||||
return $"{base.GetAddressDescription()}{Environment.NewLine}{ModbusHelper.GetAddressDescription()}";
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Init(ModbusAddress mAddress)
|
||||
{
|
||||
ModbusServer01ByteBlocks.GetOrAdd(mAddress.Station, a =>
|
||||
{
|
||||
var data = new ByteBlock(ushort.MaxValue * 2);
|
||||
data.SetLength(ushort.MaxValue * 2);
|
||||
return data;
|
||||
});
|
||||
ModbusServer02ByteBlocks.GetOrAdd(mAddress.Station, a =>
|
||||
{
|
||||
var data = new ByteBlock(ushort.MaxValue * 2);
|
||||
data.SetLength(ushort.MaxValue * 2);
|
||||
return data;
|
||||
});
|
||||
ModbusServer03ByteBlocks.GetOrAdd(mAddress.Station, a =>
|
||||
{
|
||||
var data = new ByteBlock(ushort.MaxValue * 2);
|
||||
data.SetLength(ushort.MaxValue * 2);
|
||||
return data;
|
||||
});
|
||||
ModbusServer04ByteBlocks.GetOrAdd(mAddress.Station, a =>
|
||||
{
|
||||
var data = new ByteBlock(ushort.MaxValue * 2);
|
||||
data.SetLength(ushort.MaxValue * 2);
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime)
|
||||
{
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return ModbusServerHelpers.Read(this, address, length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(Read(address, length));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter(ISocketClient socketClient = default)
|
||||
{
|
||||
if (socketClient != default)
|
||||
{
|
||||
ModbusTcpServerDataHandleAdapter dataHandleAdapter = new();
|
||||
dataHandleAdapter.CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout);
|
||||
socketClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var item in TcpService.GetClients())
|
||||
{
|
||||
ModbusTcpDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
};
|
||||
item.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return ModbusServerHelpers.Write(this, address, value);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return ModbusServerHelpers.Write(this, address, value);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(Write(address, value));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(Write(address, value));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
protected override async Task Received(SocketClient client, ReceivedDataEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ModbusServerHelpers.Received(this, client, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ using ThingsGateway.Foundation.Extension.Generic;
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<ModbusTcpServerMessage>
|
||||
internal class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesSingleStreamDataHandleAdapter<ModbusTcpServerMessage>
|
||||
{
|
||||
private readonly ThingsGatewayBitConverter ThingsGatewayBitConverter = new(EndianType.Big);
|
||||
|
||||
@@ -34,7 +34,7 @@ public class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesTcpDataHandleAda
|
||||
/// </summary>
|
||||
/// <param name="response">返回数据</param>
|
||||
/// <returns></returns>
|
||||
internal OperResult<byte[]> GetModbusData(byte[] response)
|
||||
internal OperResult<byte[], FilterResult> GetModbusData(byte[] response)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -42,22 +42,30 @@ public class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesTcpDataHandleAda
|
||||
if (func == 1 || func == 2 || func == 3 || func == 4 || func == 5 || func == 6)
|
||||
{
|
||||
if (response.Length == 6)
|
||||
return OperResult.CreateSuccessResult(response);
|
||||
return OperResult.CreateSuccessResult(response, FilterResult.Success);
|
||||
}
|
||||
else if (func == 15 || func == 16)
|
||||
{
|
||||
var length = ThingsGatewayBitConverter.ToByte(response, 6);
|
||||
if (response.Length == 7 + length)
|
||||
{
|
||||
return OperResult.CreateSuccessResult(response);
|
||||
return OperResult.CreateSuccessResult(response, FilterResult.Success);
|
||||
}
|
||||
if (response.Length > 7 + length)
|
||||
{
|
||||
return new() { Content2 = FilterResult.Success, Message = $"数据长度{response.Length}错误" };
|
||||
}
|
||||
else
|
||||
{
|
||||
return new() { Content2 = FilterResult.Cache, Message = $"数据长度{response.Length}错误" };
|
||||
}
|
||||
}
|
||||
|
||||
return new OperResult<byte[]>() { Message = $"数据长度{response.Length}错误" };
|
||||
return new() { Content2 = FilterResult.Success, Message = $"数据长度{response.Length}错误" };
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
return new(ex) { Content2 = FilterResult.Success };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +93,7 @@ public class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesTcpDataHandleAda
|
||||
{
|
||||
if (function > 6)
|
||||
{
|
||||
request.CurModbusAddress = new ModbusAddress()
|
||||
request.ModbusAddress = new ModbusAddress()
|
||||
{
|
||||
Station = station,
|
||||
Address = addressStart.ToString(),
|
||||
@@ -97,7 +105,7 @@ public class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesTcpDataHandleAda
|
||||
}
|
||||
else
|
||||
{
|
||||
request.CurModbusAddress = new ModbusAddress()
|
||||
request.ModbusAddress = new ModbusAddress()
|
||||
{
|
||||
Station = station,
|
||||
Address = addressStart.ToString(),
|
||||
@@ -110,7 +118,7 @@ public class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesTcpDataHandleAda
|
||||
}
|
||||
else
|
||||
{
|
||||
request.CurModbusAddress = new ModbusAddress()
|
||||
request.ModbusAddress = new ModbusAddress()
|
||||
{
|
||||
Station = station,
|
||||
Address = addressStart.ToString(),
|
||||
@@ -126,7 +134,7 @@ public class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesTcpDataHandleAda
|
||||
{
|
||||
request.ErrorCode = result.ErrorCode;
|
||||
request.Message = result.Message;
|
||||
return FilterResult.Cache;
|
||||
return result.Content2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,12 @@ namespace ThingsGateway.Foundation.Adapter.Modbus
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class ModbusTcpServerMessage : MessageBase, IMessage
|
||||
internal class ModbusTcpServerMessage : MessageBase, IMessage, IModbusServerMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前关联的地址
|
||||
/// </summary>
|
||||
public ModbusAddress CurModbusAddress { get; set; }
|
||||
public ModbusAddress ModbusAddress { get; set; }
|
||||
/// <summary>
|
||||
/// 当前读写的数据长度
|
||||
/// </summary>
|
||||
@@ -19,7 +19,7 @@ namespace ThingsGateway.Foundation.Adapter.OPCDA.Discovery;
|
||||
/// <summary>
|
||||
/// OpcDiscovery
|
||||
/// </summary>
|
||||
public class OpcDiscovery
|
||||
internal class OpcDiscovery
|
||||
{
|
||||
private static readonly Guid CATID_OPC_DA10 = new("63D5F430-CFE4-11d1-B2C8-0060083BA1FB");
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ public class OPCDAClient : IDisposable
|
||||
/// <summary>
|
||||
/// 当前配置
|
||||
/// </summary>
|
||||
public OPCNode OPCNode { get; private set; }
|
||||
public OPCDANode OPCNode { get; private set; }
|
||||
private List<OpcGroup> Groups => m_server.OpcGroups;
|
||||
|
||||
/// <summary>
|
||||
@@ -198,7 +198,7 @@ public class OPCDAClient : IDisposable
|
||||
/// 初始化设置
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
public void Init(OPCNode node)
|
||||
public void Init(OPCDANode node)
|
||||
{
|
||||
if (node != null)
|
||||
OPCNode = node;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user