Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4aa000cf0 | ||
|
|
01aa6ca066 |
@@ -62,7 +62,7 @@ public class SugarAopService : ISugarAopService
|
||||
if (ex.Parameters == null) return;
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
DbContext.WriteLog($"{config.ConfigId}库操作异常");
|
||||
DbContext.WriteErrorLogWithSql(UtilMethods.GetNativeSql(ex.Sql, (SugarParameter[])ex.Parameters));
|
||||
DbContext.WriteErrorLogWithSql(UtilMethods.GetNativeSql(ex.Sql, (IReadOnlyList<SugarParameter>)ex.Parameters));
|
||||
NewLife.Log.XTrace.WriteException(ex);
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<PluginVersion>10.9.64</PluginVersion>
|
||||
<ProPluginVersion>10.9.64</ProPluginVersion>
|
||||
<DefaultVersion>10.9.64</DefaultVersion>
|
||||
<PluginVersion>10.9.66</PluginVersion>
|
||||
<ProPluginVersion>10.9.66</ProPluginVersion>
|
||||
<DefaultVersion>10.9.66</DefaultVersion>
|
||||
<AuthenticationVersion>2.9.24</AuthenticationVersion>
|
||||
<SourceGeneratorVersion>10.9.24</SourceGeneratorVersion>
|
||||
<NET8Version>8.0.18</NET8Version>
|
||||
|
||||
@@ -18,46 +18,71 @@
|
||||
<EditTemplate Context="value">
|
||||
<div class="col-12 col-sm-6 col-md-4">
|
||||
<Select SkipValidate="true" @bind-Value="@value.ChannelType" OnSelectedItemChanged=@((a)=>
|
||||
{
|
||||
return InvokeAsync(StateHasChanged);
|
||||
}) />
|
||||
{
|
||||
return InvokeAsync(StateHasChanged);
|
||||
}) />
|
||||
</div>
|
||||
</EditTemplate>
|
||||
|
||||
</EditorItem>
|
||||
</EditorItem>
|
||||
|
||||
<EditorItem @bind-Field="@context.RemoteUrl" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpClient&&context.ChannelType!=ChannelTypeEnum.UdpSession) />
|
||||
<EditorItem @bind-Field="@context.BindUrl" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpClient&&context.ChannelType!=ChannelTypeEnum.UdpSession&&context.ChannelType!=ChannelTypeEnum.TcpService) />
|
||||
<EditorItem @bind-Field="@context.RemoteUrl" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpClient && context.ChannelType != ChannelTypeEnum.UdpSession) />
|
||||
<EditorItem @bind-Field="@context.BindUrl" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpClient && context.ChannelType != ChannelTypeEnum.UdpSession && context.ChannelType != ChannelTypeEnum.TcpService) />
|
||||
|
||||
<EditorItem @bind-Field="@context.PortName" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.BaudRate" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.DataBits" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.Parity" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.StopBits" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.DtrEnable" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.RtsEnable" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.StreamAsync" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.PortName" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.BaudRate" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.DataBits" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.Parity" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.StopBits" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.DtrEnable" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.RtsEnable" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.StreamAsync" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
|
||||
|
||||
<EditorItem @bind-Field="@context.CacheTimeout" Ignore=@(context.ChannelType==ChannelTypeEnum.UdpSession||context.ChannelType==ChannelTypeEnum.Other) />
|
||||
<EditorItem @bind-Field="@context.ConnectTimeout" Ignore=@(context.ChannelType==ChannelTypeEnum.UdpSession||context.ChannelType==ChannelTypeEnum.TcpService||context.ChannelType==ChannelTypeEnum.Other) />
|
||||
<EditorItem @bind-Field="@context.MaxConcurrentCount" Ignore=@(context.ChannelType==ChannelTypeEnum.Other) />
|
||||
<EditorItem @bind-Field="@context.CacheTimeout" Ignore=@(context.ChannelType == ChannelTypeEnum.UdpSession || context.ChannelType == ChannelTypeEnum.Other) />
|
||||
<EditorItem @bind-Field="@context.ConnectTimeout" Ignore=@(context.ChannelType == ChannelTypeEnum.UdpSession || context.ChannelType == ChannelTypeEnum.TcpService || context.ChannelType == ChannelTypeEnum.Other) />
|
||||
<EditorItem @bind-Field="@context.MaxConcurrentCount" Ignore=@(context.ChannelType == ChannelTypeEnum.Other) />
|
||||
|
||||
<EditorItem @bind-Field="@context.MaxClientCount" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpService) />
|
||||
<EditorItem @bind-Field="@context.CheckClearTime" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpService) />
|
||||
<EditorItem @bind-Field="@context.Heartbeat" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpService&&context.ChannelType!=ChannelTypeEnum.TcpClient&&context.ChannelType!=ChannelTypeEnum.UdpSession) />
|
||||
<EditorItem @bind-Field="@context.HeartbeatTime" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpClient&&context.ChannelType!=ChannelTypeEnum.UdpSession) />
|
||||
<EditorItem @bind-Field="@context.DtuId" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpClient&&context.ChannelType!=ChannelTypeEnum.UdpSession) />
|
||||
<EditorItem @bind-Field="@context.DtuSeviceType" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpService&&context.ChannelType!=ChannelTypeEnum.UdpSession) />
|
||||
<EditorItem @bind-Field="@context.MaxClientCount" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpService) />
|
||||
<EditorItem @bind-Field="@context.CheckClearTime" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpService) />
|
||||
|
||||
</FieldItems>
|
||||
<Buttons>
|
||||
<Button IsAsync class="mx-2" Color=Color.Primary OnClick="ConnectClick">@Localizer["Connect"]</Button>
|
||||
<Button IsAsync class="mx-2" Color=Color.Warning OnClick="DisconnectClick">@Localizer["Disconnect"]</Button>
|
||||
</Buttons>
|
||||
</EditorFormObject>
|
||||
|
||||
</ValidateForm>
|
||||
<EditorItem @bind-Field="@context.Heartbeat" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpService && context.ChannelType != ChannelTypeEnum.TcpClient && context.ChannelType != ChannelTypeEnum.UdpSession)>
|
||||
<EditTemplate Context="value">
|
||||
<div class="col-12 col-sm-6 col-md-4">
|
||||
<BootstrapInput @bind-Value=value.Heartbeat ShowLabel="true" class="me-2"></BootstrapInput>
|
||||
<Checkbox @bind-Value=value.HeartbeatHex ShowAfterLabel DisplayText="hex"></Checkbox>
|
||||
</div>
|
||||
</EditTemplate>
|
||||
</EditorItem>
|
||||
|
||||
</BodyTemplate>
|
||||
</Card>
|
||||
|
||||
<EditorItem @bind-Field="@context.HeartbeatTime" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpClient && context.ChannelType != ChannelTypeEnum.UdpSession) />
|
||||
<EditorItem @bind-Field="@context.DtuId" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpClient && context.ChannelType != ChannelTypeEnum.UdpSession)>
|
||||
|
||||
|
||||
<EditTemplate Context="value">
|
||||
<div class="col-12 col-sm-6 col-md-4">
|
||||
<BootstrapInput @bind-Value=value.DtuId ShowLabel="true" class="me-2"></BootstrapInput>
|
||||
<Checkbox @bind-Value=value.DtuIdHex ShowAfterLabel DisplayText="hex"></Checkbox>
|
||||
</div>
|
||||
</EditTemplate>
|
||||
|
||||
</EditorItem>
|
||||
|
||||
<EditorItem @bind-Field="@context.DtuIdHex" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpService) />
|
||||
|
||||
|
||||
<EditorItem @bind-Field="@context.DtuSeviceType" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpService && context.ChannelType != ChannelTypeEnum.UdpSession) />
|
||||
|
||||
</FieldItems>
|
||||
<Buttons>
|
||||
<Button IsAsync class="mx-2" Color=Color.Primary OnClick="ConnectClick">@Localizer["Connect"]</Button>
|
||||
<Button IsAsync class="mx-2" Color=Color.Warning OnClick="DisconnectClick">@Localizer["Disconnect"]</Button>
|
||||
</Buttons>
|
||||
</EditorFormObject>
|
||||
|
||||
</ValidateForm>
|
||||
|
||||
</BodyTemplate>
|
||||
</Card>
|
||||
|
||||
@@ -72,6 +72,8 @@
|
||||
"DtuId": "DtuId",
|
||||
"DtuSeviceType": "DtuSeviceType",
|
||||
"Heartbeat": "Heartbeat",
|
||||
"DtuIdHex": "DtuIdHex",
|
||||
"HeartbeatHex": "HeartbeatHex",
|
||||
"HeartbeatTime": "HeartbeatTime",
|
||||
"MaxClientCount": "MaxClientCount",
|
||||
"MaxConcurrentCount": "MaxConcurrentCount",
|
||||
|
||||
@@ -69,9 +69,11 @@
|
||||
"ConnectTimeout": "连接超时",
|
||||
"DataBits": "数据位",
|
||||
"DtrEnable": "Dtr",
|
||||
"DtuId": "Dtu终端注册包(utf-8)",
|
||||
"DtuId": "Dtu终端注册包",
|
||||
"DtuSeviceType": "DTU服务类型",
|
||||
"Heartbeat": "心跳内容(utf8)",
|
||||
"Heartbeat": "心跳内容",
|
||||
"DtuIdHex": "Dtu终端注册包是否Hex",
|
||||
"HeartbeatHex": "心跳内容是否Hex",
|
||||
"HeartbeatTime": "心跳间隔",
|
||||
"MaxClientCount": "最大连接数",
|
||||
"MaxConcurrentCount": "最大并发数",
|
||||
|
||||
@@ -94,10 +94,12 @@ namespace ThingsGateway.Foundation
|
||||
public virtual int MaxClientCount { get; set; }
|
||||
public virtual int CheckClearTime { get; set; }
|
||||
public virtual string Heartbeat { get; set; }
|
||||
public virtual bool HeartbeatHex { get; set; }
|
||||
|
||||
#region dtu终端
|
||||
public virtual int HeartbeatTime { get; set; }
|
||||
public virtual string DtuId { get; set; }
|
||||
public virtual bool DtuIdHex { get; set; }
|
||||
#endregion
|
||||
public virtual DtuSeviceType DtuSeviceType { get; set; }
|
||||
|
||||
|
||||
@@ -54,20 +54,29 @@ public static class ChannelOptionsExtensions
|
||||
/// <returns></returns>
|
||||
internal static async Task OnChannelEvent(this IClientChannel clientChannel, ChannelEventHandler funcs)
|
||||
{
|
||||
clientChannel.ThrowIfNull(nameof(IClientChannel));
|
||||
funcs.ThrowIfNull(nameof(ChannelEventHandler));
|
||||
|
||||
if (funcs.Count > 0)
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < funcs.Count; i++)
|
||||
|
||||
clientChannel.ThrowIfNull(nameof(IClientChannel));
|
||||
funcs.ThrowIfNull(nameof(ChannelEventHandler));
|
||||
|
||||
if (funcs.Count > 0)
|
||||
{
|
||||
var func = funcs[i];
|
||||
var handled = await func.Invoke(clientChannel, i == funcs.Count - 1).ConfigureAwait(false);
|
||||
if (handled)
|
||||
for (int i = 0; i < funcs.Count; i++)
|
||||
{
|
||||
break;
|
||||
var func = funcs[i];
|
||||
var handled = await func.Invoke(clientChannel, i == funcs.Count - 1).ConfigureAwait(false);
|
||||
if (handled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
clientChannel.Logger?.LogWarning(ex, "fail ChannelEvent");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,10 +111,13 @@ public interface IChannelOptions
|
||||
int CheckClearTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 心跳检测(utf8)
|
||||
/// 心跳检测
|
||||
/// </summary>
|
||||
string Heartbeat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 心跳检测是否hex
|
||||
/// </summary>
|
||||
bool HeartbeatHex { get; set; }
|
||||
#region dtu终端
|
||||
/// <summary>
|
||||
/// 心跳时间
|
||||
@@ -122,10 +125,13 @@ public interface IChannelOptions
|
||||
public int HeartbeatTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认Dtu注册包(utf-8)
|
||||
/// 默认Dtu注册包
|
||||
/// </summary>
|
||||
public string DtuId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认Dtu注册包是否hex
|
||||
/// </summary>
|
||||
bool DtuIdHex { get; set; }
|
||||
#endregion
|
||||
|
||||
public DtuSeviceType DtuSeviceType { get; set; }
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.String;
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -28,13 +30,34 @@ public class DtuPlugin : PluginBase, ITcpReceivingPlugin
|
||||
set
|
||||
{
|
||||
_heartbeat = value;
|
||||
if (!_heartbeat.IsNullOrEmpty())
|
||||
HeartbeatByte = new ArraySegment<byte>(Encoding.UTF8.GetBytes(value));
|
||||
if (!heartbeatHex)
|
||||
HeartbeatByte = new ArraySegment<byte>(Encoding.UTF8.GetBytes(_heartbeat ?? string.Empty));
|
||||
else
|
||||
HeartbeatByte = new ArraySegment<byte>(_heartbeat?.HexStringToBytes() ?? Array.Empty<byte>());
|
||||
}
|
||||
}
|
||||
private string _heartbeat;
|
||||
private ArraySegment<byte> HeartbeatByte = new();
|
||||
|
||||
|
||||
private bool heartbeatHex;
|
||||
public bool HeartbeatHex
|
||||
{
|
||||
get
|
||||
{
|
||||
return heartbeatHex;
|
||||
}
|
||||
set
|
||||
{
|
||||
heartbeatHex = value;
|
||||
if (!heartbeatHex)
|
||||
HeartbeatByte = new ArraySegment<byte>(Encoding.UTF8.GetBytes(_heartbeat ?? string.Empty));
|
||||
else
|
||||
HeartbeatByte = new ArraySegment<byte>(_heartbeat?.HexStringToBytes() ?? Array.Empty<byte>());
|
||||
}
|
||||
}
|
||||
public bool DtuIdHex { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task OnTcpReceiving(ITcpSession client, ByteBlockEventArgs e)
|
||||
{
|
||||
@@ -43,7 +66,7 @@ public class DtuPlugin : PluginBase, ITcpReceivingPlugin
|
||||
{
|
||||
if (!socket.Id.StartsWith("ID="))
|
||||
{
|
||||
var id = $"ID={e.ByteBlock}";
|
||||
var id = DtuIdHex ? $"ID={e.ByteBlock.Span.ToHexString()}" : $"ID={e.ByteBlock.ToString(0, e.ByteBlock.Length)}";
|
||||
if (tcpServiceChannel.TryGetClient(id, out var oldClient))
|
||||
{
|
||||
try
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.String;
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
|
||||
[PluginOption(Singleton = true)]
|
||||
@@ -24,7 +26,10 @@ internal sealed class HeartbeatAndReceivePlugin : PluginBase, ITcpConnectedPlugi
|
||||
set
|
||||
{
|
||||
_dtuId = value;
|
||||
DtuIdByte = new ArraySegment<byte>(Encoding.UTF8.GetBytes(value));
|
||||
if (!dtuIdHex)
|
||||
DtuIdByte = new ArraySegment<byte>(Encoding.UTF8.GetBytes(_dtuId ?? string.Empty));
|
||||
else
|
||||
DtuIdByte = new ArraySegment<byte>(_dtuId?.HexStringToBytes() ?? Array.Empty<byte>());
|
||||
}
|
||||
}
|
||||
private string _dtuId;
|
||||
@@ -42,15 +47,64 @@ internal sealed class HeartbeatAndReceivePlugin : PluginBase, ITcpConnectedPlugi
|
||||
set
|
||||
{
|
||||
_heartbeat = value;
|
||||
if (!_heartbeat.IsNullOrEmpty())
|
||||
{
|
||||
HeartbeatByte = new ArraySegment<byte>(Encoding.UTF8.GetBytes(value));
|
||||
}
|
||||
if (!heartbeatHex)
|
||||
HeartbeatByte = new ArraySegment<byte>(Encoding.UTF8.GetBytes(_heartbeat ?? string.Empty));
|
||||
else
|
||||
HeartbeatByte = new ArraySegment<byte>(_heartbeat?.HexStringToBytes() ?? Array.Empty<byte>());
|
||||
}
|
||||
}
|
||||
private string _heartbeat;
|
||||
private ArraySegment<byte> HeartbeatByte;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private bool heartbeatHex;
|
||||
public bool HeartbeatHex
|
||||
{
|
||||
get
|
||||
{
|
||||
return heartbeatHex;
|
||||
}
|
||||
set
|
||||
{
|
||||
heartbeatHex = value;
|
||||
if (!heartbeatHex)
|
||||
{
|
||||
HeartbeatByte = new ArraySegment<byte>(Encoding.UTF8.GetBytes(_heartbeat ?? string.Empty));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
HeartbeatByte = new ArraySegment<byte>(_heartbeat?.HexStringToBytes() ?? Array.Empty<byte>());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
private bool dtuIdHex;
|
||||
public bool DtuIdHex
|
||||
{
|
||||
get
|
||||
{
|
||||
return dtuIdHex;
|
||||
}
|
||||
set
|
||||
{
|
||||
dtuIdHex = value;
|
||||
if (!dtuIdHex)
|
||||
{
|
||||
DtuIdByte = new ArraySegment<byte>(Encoding.UTF8.GetBytes(_dtuId ?? string.Empty));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
DtuIdByte = new ArraySegment<byte>(_dtuId?.HexStringToBytes() ?? Array.Empty<byte>());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
private Task Task;
|
||||
private bool SendHeartbeat;
|
||||
public int HeartbeatTime { get; set; } = 3000;
|
||||
|
||||
@@ -25,6 +25,8 @@ public static class PluginUtil
|
||||
action += a =>
|
||||
{
|
||||
var plugin = a.Add<HeartbeatAndReceivePlugin>();
|
||||
plugin.HeartbeatHex = channelOptions.HeartbeatHex;
|
||||
plugin.DtuIdHex = channelOptions.DtuIdHex;
|
||||
plugin.Heartbeat = channelOptions.Heartbeat;
|
||||
plugin.DtuId = channelOptions.DtuId;
|
||||
plugin.HeartbeatTime = channelOptions.HeartbeatTime;
|
||||
@@ -52,7 +54,9 @@ public static class PluginUtil
|
||||
action += a =>
|
||||
{
|
||||
var plugin = a.Add<DtuPlugin>();
|
||||
plugin.HeartbeatHex = channelOptions.HeartbeatHex;
|
||||
plugin.Heartbeat = channelOptions.Heartbeat;
|
||||
plugin.DtuIdHex = channelOptions.DtuIdHex;
|
||||
};
|
||||
}
|
||||
return action;
|
||||
|
||||
@@ -142,7 +142,20 @@ public static partial class DeviceExtension
|
||||
return new();
|
||||
|
||||
case WaitDataStatus.Canceled: return new(new OperationCanceledException());
|
||||
case WaitDataStatus.Overtime: return waitDataAsync.WaitResult == null ? new(new TimeoutException()) : new(waitDataAsync.WaitResult);
|
||||
case WaitDataStatus.Overtime:
|
||||
{
|
||||
if (waitDataAsync.WaitResult != null)
|
||||
{
|
||||
waitDataAsync.WaitResult.Exception = new TimeoutException();
|
||||
if (waitDataAsync.WaitResult.IsSuccess) waitDataAsync.WaitResult.OperCode = 999;
|
||||
if (waitDataAsync.WaitResult.ErrorMessage.IsNullOrEmpty()) waitDataAsync.WaitResult.ErrorMessage = "Timeout";
|
||||
return new(waitDataAsync.WaitResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new(new TimeoutException());
|
||||
}
|
||||
}
|
||||
case WaitDataStatus.Disposed:
|
||||
case WaitDataStatus.Default:
|
||||
default:
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
"DtuSeviceType": "DtuSeviceType",
|
||||
"Heartbeat": "Heartbeat",
|
||||
"HeartbeatTime": "HeartbeatTime",
|
||||
"DtuIdHex": "DtuIdHex",
|
||||
"HeartbeatHex": "HeartbeatHex",
|
||||
"MaxClientCount": "MaxClientCount",
|
||||
"MaxConcurrentCount": "MaxConcurrentCount",
|
||||
"Name": "Name",
|
||||
@@ -73,7 +75,7 @@
|
||||
"Timeout": "Timeout"
|
||||
},
|
||||
"ThingsGateway.Foundation.DtuServiceDeviceBase": {
|
||||
"DtuId": "DtuId(UTF8)"
|
||||
"DtuId": "DtuId"
|
||||
},
|
||||
"ThingsGateway.Foundation.VariableClass": {
|
||||
"RegisterAddress": "RegisterAddress"
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
"ConnectTimeout": "连接超时",
|
||||
"DataBits": "数据位",
|
||||
"DtrEnable": "Dtr",
|
||||
"DtuId": "Dtu终端注册包(utf-8)",
|
||||
"DtuId": "Dtu终端注册包",
|
||||
"DtuSeviceType": "DTU服务类型",
|
||||
"Heartbeat": "心跳内容(utf8)",
|
||||
"Heartbeat": "心跳内容",
|
||||
"DtuIdHex": "Dtu终端注册包是否Hex",
|
||||
"HeartbeatHex": "心跳内容是否Hex",
|
||||
"HeartbeatTime": "心跳间隔",
|
||||
"MaxClientCount": "最大连接数",
|
||||
"MaxConcurrentCount": "最大并发数",
|
||||
@@ -73,7 +75,7 @@
|
||||
"Timeout": "读写超时"
|
||||
},
|
||||
"ThingsGateway.Foundation.DtuServiceDeviceBase": {
|
||||
"DtuId": "Dtu注册包(UTF8)"
|
||||
"DtuId": "Dtu注册包"
|
||||
},
|
||||
"ThingsGateway.Foundation.VariableClass": {
|
||||
"RegisterAddress": "寄存器地址"
|
||||
|
||||
@@ -177,6 +177,10 @@ public class Channel : ChannelOptionsBase, IPrimaryIdEntity, IBaseDataEntity, IB
|
||||
[AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
|
||||
public override string Heartbeat { get; set; }
|
||||
|
||||
[SugarColumn(ColumnDescription = "心跳内容是否Hex", IsNullable = true)]
|
||||
[AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
|
||||
public override bool HeartbeatHex { get; set; }
|
||||
|
||||
#region dtu终端
|
||||
|
||||
[SugarColumn(ColumnDescription = "心跳间隔", IsNullable = true)]
|
||||
@@ -187,6 +191,9 @@ public class Channel : ChannelOptionsBase, IPrimaryIdEntity, IBaseDataEntity, IB
|
||||
[AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
|
||||
public override string DtuId { get; set; }
|
||||
|
||||
[SugarColumn(ColumnDescription = "DtuId是否Hex", IsNullable = true)]
|
||||
[AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
|
||||
public override bool DtuIdHex { get; set; }
|
||||
#endregion
|
||||
|
||||
[SugarColumn(ColumnDescription = "Dtu类型", IsNullable = true)]
|
||||
|
||||
@@ -242,6 +242,8 @@
|
||||
"ExportChannel": "Export Channel",
|
||||
"Heartbeat": "Heartbeat",
|
||||
"HeartbeatTime": "HeartbeatTime",
|
||||
"DtuIdHex": "DtuIdHex",
|
||||
"HeartbeatHex": "HeartbeatHex",
|
||||
"ImportChannel": "Import Channel",
|
||||
"ImportNullError": "Unable to recognize",
|
||||
"LogEnable": "LogEnable",
|
||||
@@ -274,10 +276,10 @@
|
||||
},
|
||||
|
||||
"ThingsGateway.Gateway.Application.CollectFoundationDtuPackPropertyBase": {
|
||||
"DtuId": "DtuId(UTF8)"
|
||||
"DtuId": "DtuId"
|
||||
},
|
||||
"ThingsGateway.Gateway.Application.CollectFoundationDtuPropertyBase": {
|
||||
"DtuId": "DtuId(UTF8)"
|
||||
"DtuId": "DtuId"
|
||||
},
|
||||
"ThingsGateway.Gateway.Application.CollectFoundationPackPropertyBase": {
|
||||
"MaxPack": "MaxPack"
|
||||
|
||||
@@ -235,11 +235,13 @@
|
||||
"DeleteChannel": "删除通道",
|
||||
"Disconnect": "断开",
|
||||
"DtrEnable": "Dtr",
|
||||
"DtuId": "Dtu终端注册包(utf-8)",
|
||||
"DtuId": "Dtu终端注册包",
|
||||
"DtuSeviceType": "DTU服务类型",
|
||||
"Enable": "启用",
|
||||
"ExportChannel": "导出通道",
|
||||
"Heartbeat": "心跳内容(utf8)",
|
||||
"Heartbeat": "心跳内容",
|
||||
"DtuIdHex": "Dtu终端注册包是否Hex",
|
||||
"HeartbeatHex": "心跳内容是否Hex",
|
||||
"HeartbeatTime": "心跳间隔",
|
||||
"ImportChannel": "导入通道",
|
||||
"ImportNullError": "无法识别",
|
||||
@@ -273,10 +275,10 @@
|
||||
},
|
||||
|
||||
"ThingsGateway.Gateway.Application.CollectFoundationDtuPackPropertyBase": {
|
||||
"DtuId": "Dtu注册包(UTF8)"
|
||||
"DtuId": "Dtu注册包"
|
||||
},
|
||||
"ThingsGateway.Gateway.Application.CollectFoundationDtuPropertyBase": {
|
||||
"DtuId": "Dtu注册包(UTF8)"
|
||||
"DtuId": "Dtu注册包"
|
||||
},
|
||||
"ThingsGateway.Gateway.Application.CollectFoundationPackPropertyBase": {
|
||||
"MaxPack": "最大打包长度"
|
||||
|
||||
@@ -33,102 +33,125 @@
|
||||
RenderFragment renderFragment =>
|
||||
@<EditorForm class="p-2" AutoGenerateAllItem="false" RowType=RowType.Inline ItemsPerRow=2 LabelWidth=200 Model="Model">
|
||||
|
||||
<FieldItems>
|
||||
<EditorItem TValue="string" TModel="Channel" @bind-Field="@context.Name">
|
||||
<EditTemplate Context="value">
|
||||
<div class="col-12">
|
||||
<h6>@GatewayLocalizer["BasicInformation"]</h6>
|
||||
</div>
|
||||
</EditTemplate>
|
||||
</EditorItem>
|
||||
<FieldItems>
|
||||
<EditorItem TValue="string" TModel="Channel" @bind-Field="@context.Name">
|
||||
<EditTemplate Context="value">
|
||||
<div class="col-12">
|
||||
<h6>@GatewayLocalizer["BasicInformation"]</h6>
|
||||
</div>
|
||||
</EditTemplate>
|
||||
</EditorItem>
|
||||
|
||||
<EditorItem @bind-Field="@context.Name" Readonly=BatchEditEnable />
|
||||
<EditorItem @bind-Field="@context.Name" Readonly=BatchEditEnable />
|
||||
|
||||
|
||||
<EditorItem @bind-Field="@context.PluginName">
|
||||
<EditTemplate Context="value">
|
||||
<div class="col-12 col-md-6">
|
||||
<Select @bind-Value="@value.PluginName"
|
||||
Items="@PluginNames" IsDisabled=BatchEditEnable
|
||||
ShowSearch="true">
|
||||
<ItemTemplate Context="name">
|
||||
@if (PluginDcit.TryGetValue(name.Value, out var pluginOutput))
|
||||
{
|
||||
if (pluginOutput.EducationPlugin)
|
||||
{
|
||||
<div class="d-flex">
|
||||
<span>@name.Text</span>
|
||||
<div style="flex-grow: 1;"></div>
|
||||
<Tag Color="Color.Primary">PRO</Tag>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
<EditorItem @bind-Field="@context.PluginName">
|
||||
<EditTemplate Context="value">
|
||||
<div class="col-12 col-md-6">
|
||||
<Select @bind-Value="@value.PluginName"
|
||||
Items="@PluginNames" IsDisabled=BatchEditEnable
|
||||
ShowSearch="true">
|
||||
<ItemTemplate Context="name">
|
||||
@if (PluginDcit.TryGetValue(name.Value, out var pluginOutput))
|
||||
{
|
||||
if (pluginOutput.EducationPlugin)
|
||||
{
|
||||
<div class="d-flex">
|
||||
<span>@name.Text</span>
|
||||
<div style="flex-grow: 1;"></div>
|
||||
<Tag Color="Color.Primary">PRO</Tag>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>@name.Text</span>
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>@name.Value</span>
|
||||
}
|
||||
</ItemTemplate>
|
||||
</Select>
|
||||
</div>
|
||||
</EditTemplate>
|
||||
</EditorItem>
|
||||
</ItemTemplate>
|
||||
</Select>
|
||||
</div>
|
||||
</EditTemplate>
|
||||
</EditorItem>
|
||||
|
||||
<EditorItem @bind-Field="@context.Enable" />
|
||||
<EditorItem @bind-Field="@context.LogLevel" />
|
||||
<EditorItem @bind-Field="@context.Enable" />
|
||||
<EditorItem @bind-Field="@context.LogLevel" />
|
||||
|
||||
<EditorItem TValue="string" TModel="Channel" @bind-Field="@context.Name">
|
||||
<EditTemplate Context="value">
|
||||
<div class="col-12">
|
||||
<h6>@GatewayLocalizer["Connection"]</h6>
|
||||
</div>
|
||||
</EditTemplate>
|
||||
</EditorItem>
|
||||
<EditorItem TValue="string" TModel="Channel" @bind-Field="@context.Name">
|
||||
<EditTemplate Context="value">
|
||||
<div class="col-12">
|
||||
<h6>@GatewayLocalizer["Connection"]</h6>
|
||||
</div>
|
||||
</EditTemplate>
|
||||
</EditorItem>
|
||||
|
||||
<EditorItem @bind-Field="@context.ChannelType">
|
||||
<EditorItem @bind-Field="@context.ChannelType">
|
||||
|
||||
<EditTemplate Context="value">
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<Select SkipValidate="true" @bind-Value="@value.ChannelType" OnSelectedItemChanged=@((a)=>
|
||||
{
|
||||
return InvokeAsync(StateHasChanged);
|
||||
}) />
|
||||
</div>
|
||||
</EditTemplate>
|
||||
<EditTemplate Context="value">
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<Select SkipValidate="true" @bind-Value="@value.ChannelType" OnSelectedItemChanged=@((a)=>
|
||||
{
|
||||
return InvokeAsync(StateHasChanged);
|
||||
}) />
|
||||
</div>
|
||||
</EditTemplate>
|
||||
|
||||
</EditorItem>
|
||||
</EditorItem>
|
||||
|
||||
|
||||
<EditorItem @bind-Field="@context.RemoteUrl" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpClient&&context.ChannelType!=ChannelTypeEnum.UdpSession) />
|
||||
<EditorItem @bind-Field="@context.BindUrl" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpClient&&context.ChannelType!=ChannelTypeEnum.UdpSession&&context.ChannelType!=ChannelTypeEnum.TcpService) />
|
||||
<EditorItem @bind-Field="@context.RemoteUrl" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpClient && context.ChannelType != ChannelTypeEnum.UdpSession) />
|
||||
<EditorItem @bind-Field="@context.BindUrl" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpClient && context.ChannelType != ChannelTypeEnum.UdpSession && context.ChannelType != ChannelTypeEnum.TcpService) />
|
||||
|
||||
<EditorItem @bind-Field="@context.PortName" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.BaudRate" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.DataBits" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.Parity" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.StopBits" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.DtrEnable" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.RtsEnable" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.StreamAsync" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.PortName" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.BaudRate" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.DataBits" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.Parity" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.StopBits" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.DtrEnable" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.RtsEnable" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.StreamAsync" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
|
||||
|
||||
<EditorItem @bind-Field="@context.CacheTimeout" Ignore=@(context.ChannelType==ChannelTypeEnum.UdpSession||context.ChannelType==ChannelTypeEnum.Other) />
|
||||
<EditorItem @bind-Field="@context.ConnectTimeout" Ignore=@(context.ChannelType==ChannelTypeEnum.UdpSession||context.ChannelType==ChannelTypeEnum.TcpService||context.ChannelType==ChannelTypeEnum.Other) />
|
||||
<EditorItem @bind-Field="@context.MaxConcurrentCount" Ignore=@(context.ChannelType==ChannelTypeEnum.Other) />
|
||||
<EditorItem @bind-Field="@context.CacheTimeout" Ignore=@(context.ChannelType == ChannelTypeEnum.UdpSession || context.ChannelType == ChannelTypeEnum.Other) />
|
||||
<EditorItem @bind-Field="@context.ConnectTimeout" Ignore=@(context.ChannelType == ChannelTypeEnum.UdpSession || context.ChannelType == ChannelTypeEnum.TcpService || context.ChannelType == ChannelTypeEnum.Other) />
|
||||
<EditorItem @bind-Field="@context.MaxConcurrentCount" Ignore=@(context.ChannelType == ChannelTypeEnum.Other) />
|
||||
|
||||
|
||||
<EditorItem @bind-Field="@context.MaxClientCount" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpService) />
|
||||
<EditorItem @bind-Field="@context.CheckClearTime" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpService) />
|
||||
<EditorItem @bind-Field="@context.Heartbeat" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpService&&context.ChannelType!=ChannelTypeEnum.TcpClient&&context.ChannelType!=ChannelTypeEnum.UdpSession) />
|
||||
<EditorItem @bind-Field="@context.HeartbeatTime" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpClient&&context.ChannelType!=ChannelTypeEnum.UdpSession) />
|
||||
<EditorItem @bind-Field="@context.DtuId" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpClient&&context.ChannelType!=ChannelTypeEnum.UdpSession) />
|
||||
<EditorItem @bind-Field="@context.DtuSeviceType" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpService&&context.ChannelType!=ChannelTypeEnum.UdpSession) />
|
||||
<EditorItem @bind-Field="@context.MaxClientCount" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpService) />
|
||||
<EditorItem @bind-Field="@context.CheckClearTime" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpService) />
|
||||
|
||||
</FieldItems>
|
||||
<EditorItem @bind-Field="@context.Heartbeat" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpService && context.ChannelType != ChannelTypeEnum.TcpClient && context.ChannelType != ChannelTypeEnum.UdpSession)>
|
||||
<EditTemplate Context="value">
|
||||
<div class="col-12 col-md-6">
|
||||
<BootstrapInput @bind-Value=value.Heartbeat ShowLabel="true" class="me-2"></BootstrapInput>
|
||||
<Checkbox @bind-Value=value.HeartbeatHex ShowAfterLabel DisplayText="hex"></Checkbox>
|
||||
</div>
|
||||
</EditTemplate>
|
||||
</EditorItem>
|
||||
|
||||
</EditorForm>;
|
||||
|
||||
<EditorItem @bind-Field="@context.HeartbeatTime" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpClient && context.ChannelType != ChannelTypeEnum.UdpSession) />
|
||||
<EditorItem @bind-Field="@context.DtuId" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpClient && context.ChannelType != ChannelTypeEnum.UdpSession)>
|
||||
|
||||
|
||||
<EditTemplate Context="value">
|
||||
<div class="col-12 col-md-6">
|
||||
<BootstrapInput @bind-Value=value.DtuId ShowLabel="true" class="me-2"></BootstrapInput>
|
||||
<Checkbox @bind-Value=value.DtuIdHex ShowAfterLabel DisplayText="hex"></Checkbox>
|
||||
</div>
|
||||
</EditTemplate>
|
||||
|
||||
</EditorItem>
|
||||
|
||||
<EditorItem @bind-Field="@context.DtuIdHex" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpService) />
|
||||
|
||||
<EditorItem @bind-Field="@context.DtuSeviceType" Ignore=@(context.ChannelType != ChannelTypeEnum.TcpService && context.ChannelType != ChannelTypeEnum.UdpSession) />
|
||||
|
||||
</FieldItems>
|
||||
|
||||
</EditorForm>;
|
||||
|
||||
}
|
||||
@@ -138,9 +138,8 @@ public partial class VariableEditComponent
|
||||
AddressDynamicComponent = new BootstrapDynamicComponent(AddressUIType, new Dictionary<string, object?>
|
||||
{
|
||||
[nameof(IAddressUIBase.Model)] = Model.RegisterAddress,
|
||||
|
||||
[nameof(IAddressUIBase.ModelChanged)] =
|
||||
(string address) => Model.RegisterAddress = address
|
||||
(Action<string>)(address => Model.RegisterAddress = address)
|
||||
});
|
||||
}
|
||||
else
|
||||
|
||||
@@ -59,7 +59,7 @@ public partial class ModbusMaster : ComponentBase, IDisposable
|
||||
|
||||
op.Component = BootstrapDynamicComponent.CreateComponent<ModbusAddressComponent>(new Dictionary<string, object?>
|
||||
{
|
||||
{nameof(ModbusAddressComponent.ModelChanged), (string a) => DeviceComponent?.SetRegisterAddress(a)},
|
||||
{nameof(ModbusAddressComponent.ModelChanged), (Action<string>)(a => DeviceComponent?.SetRegisterAddress(a))},
|
||||
{nameof(ModbusAddressComponent.Model),address },
|
||||
});
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ public partial class ModbusSlave : ComponentBase, IDisposable
|
||||
|
||||
op.Component = BootstrapDynamicComponent.CreateComponent<ModbusAddressComponent>(new Dictionary<string, object?>
|
||||
{
|
||||
{nameof(ModbusAddressComponent.ModelChanged), (string a) => DeviceComponent?.SetRegisterAddress(a)},
|
||||
{nameof(ModbusAddressComponent.ModelChanged), (Action<string>)(a => DeviceComponent?.SetRegisterAddress(a))},
|
||||
{nameof(ModbusAddressComponent.Model),address },
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user