迁移4.0

This commit is contained in:
Kimdiego2098
2023-11-18 22:43:36 +08:00
parent bfe2465658
commit a17a15e5d7
1099 changed files with 20012 additions and 31589 deletions

3
.gitignore vendored
View File

@@ -363,4 +363,5 @@ MigrationBackup/
FodyWeavers.xsd
/framework/*Pro*
/framework/*pro*

View File

@@ -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

View File

@@ -360,5 +360,4 @@ MigrationBackup/
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
FodyWeavers.xsd

View File

@@ -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>

View File

@@ -23,6 +23,8 @@ internal class Program
var appBuilder = PhotinoBlazorAppBuilder.CreateDefault(args);
Serve.RunNative();
appBuilder.RootComponents.Add<App>("#app");
appBuilder.Services.ThingsGatewayComponentsConfigureServices();

View File

@@ -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>

View File

@@ -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()
{

View File

@@ -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>

View File

@@ -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);
}
}

View File

@@ -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)

View File

@@ -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();
}
}

View File

@@ -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">
连接

View File

@@ -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();
}
}

View File

@@ -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">
启动

View File

@@ -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();
}
}

View File

@@ -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">
连接

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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/>

View File

@@ -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;

View File

@@ -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();

View File

@@ -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;

View File

@@ -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();

View File

@@ -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>

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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>

View File

@@ -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();
}

View File

@@ -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>

View File

@@ -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();
}

View File

@@ -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>

View File

@@ -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();
}

View File

@@ -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>

View File

@@ -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();
}

View File

@@ -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>

View File

@@ -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();
}

View File

@@ -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>

View File

@@ -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();
}

View File

@@ -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>

View File

@@ -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;
}
}

View File

@@ -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">
连接

View File

@@ -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/>

View File

@@ -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;

View File

@@ -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
{

View File

@@ -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>

View File

@@ -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}"));
}
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -11,6 +11,7 @@
*@
@namespace ThingsGateway.Foundation.Demo
@inherits BaseComponentBase
@using BlazorComponent;
@using Microsoft.AspNetCore.Components.Web;

View File

@@ -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
{

View File

@@ -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();
}

View File

@@ -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();
//载入配置

View File

@@ -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);")>

View File

@@ -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();
}
}

View File

@@ -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>

View File

@@ -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

View File

@@ -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();
});
}
}
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -15,7 +15,7 @@ namespace ThingsGateway.Foundation.Adapter.DLT645;
/// <summary>
/// 控制码
/// </summary>
public enum ControlCode : byte
internal enum ControlCode : byte
{
/// <summary>
/// 读数据

View File

@@ -18,7 +18,7 @@ namespace ThingsGateway.Foundation.Adapter.DLT645;
/// <summary>
/// 解析参数
/// </summary>
public class DataInfo
internal class DataInfo
{
/// <summary>
/// 解析长度

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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>

View File

@@ -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的报文头部

View File

@@ -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;

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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为descfalse为asc
/// 通讯地址BCD码一般应该是12个字符
/// </summary>
List<bool> SortDesc { get; set; }
/// <summary>
/// 排序字段
/// </summary>
List<string> SortField { get; set; }
string Station { get; set; }
}
}

View File

@@ -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;

View File

@@ -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();//如果本插件无法处理当前数据,请将数据转至下一个插件。
}
}
}

View File

@@ -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="))

View File

@@ -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));
}

View File

@@ -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);
}
}
}

View File

@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
/// <summary>
/// Rtu适配器
/// </summary>
public class ModbusRtuDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<ModbusRtuMessage>
internal class ModbusRtuDataHandleAdapter : ReadWriteDevicesSingleStreamDataHandleAdapter<ModbusRtuMessage>
{
/// <summary>
/// 检测CRC

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -15,7 +15,7 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
/// <summary>
/// <inheritdoc/>
/// </summary>
public class ModbusRtuOverUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter<ModbusRtuMessage>
internal class ModbusRtuOverUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter<ModbusRtuMessage>
{
/// <summary>
/// 检测CRC

View File

@@ -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));
}
}

View File

@@ -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);
}
}
}

View File

@@ -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>
/// 检测事务标识符

View File

@@ -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)

View File

@@ -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));
}
}

View File

@@ -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);
}
}
}

View File

@@ -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>
/// 检测事务标识符

View File

@@ -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)

View File

@@ -0,0 +1,68 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using 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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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;
});
}
}

View File

@@ -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

View File

@@ -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/>

View File

@@ -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);
}
}
}

View File

@@ -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());
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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>

View File

@@ -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");

View File

@@ -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