mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-11-03 00:53:59 +08:00
build: 10.9.67
feat: 报警恢复增加延时功能 refactor: 移除通讯任务时,设置设备、变量离线状态 fix: 罗克韦尔PLC通讯超时错误
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BootstrapBlazor.TableExport" Version="9.2.6" />
|
||||
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
|
||||
<PackageReference Include="BootstrapBlazor" Version="9.8.1" />
|
||||
<PackageReference Include="BootstrapBlazor" Version="9.8.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BootstrapBlazor.FontAwesome" Version="9.0.2" />
|
||||
<PackageReference Include="BootstrapBlazor.FontAwesome" Version="9.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<PluginVersion>10.9.66</PluginVersion>
|
||||
<ProPluginVersion>10.9.66</ProPluginVersion>
|
||||
<DefaultVersion>10.9.66</DefaultVersion>
|
||||
<AuthenticationVersion>2.9.24</AuthenticationVersion>
|
||||
<PluginVersion>10.9.67</PluginVersion>
|
||||
<ProPluginVersion>10.9.67</ProPluginVersion>
|
||||
<DefaultVersion>10.9.67</DefaultVersion>
|
||||
<AuthenticationVersion>2.9.27</AuthenticationVersion>
|
||||
<SourceGeneratorVersion>10.9.24</SourceGeneratorVersion>
|
||||
<NET8Version>8.0.18</NET8Version>
|
||||
<NET9Version>9.0.7</NET9Version>
|
||||
|
||||
@@ -238,7 +238,7 @@ public abstract class TcpCustomDataHandlingAdapter<TRequest> : SingleStreamDataH
|
||||
// 如果缓存的数据长度超过设定的最大包大小,则抛出异常。
|
||||
if (this.m_tempByteBlock.Length > this.MaxPackageSize)
|
||||
{
|
||||
throw new Exception("缓存的数据长度大于设定值的情况下未收到解析信号");
|
||||
throw new Exception($"The parsed signal was not received when the cached data length {m_tempByteBlock.Length} exceeds the set value {MaxPackageSize}");
|
||||
}
|
||||
|
||||
// 将字节块指针移到末尾。
|
||||
@@ -306,7 +306,7 @@ public abstract class TcpCustomDataHandlingAdapter<TRequest> : SingleStreamDataH
|
||||
|
||||
if (this.m_tempByteBlock.Length > this.MaxPackageSize)
|
||||
{
|
||||
this.OnError(default, "缓存的数据长度大于设定值的情况下未收到解析信号", true, true);
|
||||
this.OnError(default, $"The parsed signal was not received when the cached data length {m_tempByteBlock.Length} exceeds the set value {MaxPackageSize}", true, true);
|
||||
}
|
||||
}
|
||||
if (this.UpdateCacheTimeWhenRev)
|
||||
|
||||
@@ -18,7 +18,7 @@ public enum EventTypeEnum
|
||||
/// <summary>
|
||||
/// 准备报警
|
||||
/// </summary>
|
||||
Prepare,
|
||||
PrepareAlarm,
|
||||
|
||||
/// <summary>
|
||||
/// 报警产生
|
||||
@@ -34,4 +34,9 @@ public enum EventTypeEnum
|
||||
/// 报警恢复
|
||||
/// </summary>
|
||||
Finish,
|
||||
|
||||
/// <summary>
|
||||
/// 准备恢复
|
||||
/// </summary>
|
||||
PrepareFinish,
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@ namespace ThingsGateway.Gateway.Application;
|
||||
/// </summary>
|
||||
public partial class VariableRuntime : Variable, IVariable, IDisposable
|
||||
{
|
||||
private DateTime? prepareEventTime;
|
||||
private DateTime? prepareAlarmEventTime;
|
||||
private DateTime? prepareFinishEventTime;
|
||||
private EventTypeEnum? eventType;
|
||||
|
||||
private AlarmTypeEnum? alarmType { get; set; }
|
||||
|
||||
@@ -55,7 +55,12 @@ public partial class VariableRuntime : Variable, IVariable, IDisposable
|
||||
/// 事件时间
|
||||
/// </summary>
|
||||
[AutoGenerateColumn(Ignore = true)]
|
||||
internal DateTime? PrepareEventTime { get => prepareEventTime; set => prepareEventTime = value; }
|
||||
internal DateTime? PrepareAlarmEventTime { get => prepareAlarmEventTime; set => prepareAlarmEventTime = value; }
|
||||
/// <summary>
|
||||
/// 事件时间
|
||||
/// </summary>
|
||||
[AutoGenerateColumn(Ignore = true)]
|
||||
internal DateTime? PrepareFinishEventTime { get => prepareFinishEventTime; set => prepareFinishEventTime = value; }
|
||||
|
||||
/// <summary>
|
||||
/// 变化时间
|
||||
|
||||
@@ -284,16 +284,16 @@ internal sealed class AlarmTask : IDisposable
|
||||
//添加报警延时策略
|
||||
if (delay > 0)
|
||||
{
|
||||
if (item.EventType != EventTypeEnum.Alarm && item.EventType != EventTypeEnum.Prepare)
|
||||
if (item.EventType != EventTypeEnum.Alarm && item.EventType != EventTypeEnum.PrepareAlarm)
|
||||
{
|
||||
item.EventType = EventTypeEnum.Prepare;//准备报警
|
||||
item.PrepareEventTime = now;
|
||||
item.EventType = EventTypeEnum.PrepareAlarm;//准备报警
|
||||
item.PrepareAlarmEventTime = now;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item.EventType == EventTypeEnum.Prepare)
|
||||
if (item.EventType == EventTypeEnum.PrepareAlarm)
|
||||
{
|
||||
if ((now - item.PrepareEventTime!.Value).TotalSeconds > delay)
|
||||
if ((now - item.PrepareAlarmEventTime!.Value).TotalMilliseconds > delay)
|
||||
{
|
||||
//超过延时时间,触发报警
|
||||
item.EventType = EventTypeEnum.Alarm;
|
||||
@@ -304,7 +304,7 @@ internal sealed class AlarmTask : IDisposable
|
||||
item.AlarmCode = item.Value.ToString();
|
||||
item.RecoveryCode = string.Empty;
|
||||
item.AlarmText = text;
|
||||
item.PrepareEventTime = null;
|
||||
item.PrepareAlarmEventTime = null;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
@@ -312,9 +312,9 @@ internal sealed class AlarmTask : IDisposable
|
||||
else if (item.EventType == EventTypeEnum.Alarm && item.AlarmType != alarmEnum)
|
||||
{
|
||||
//报警类型改变,重新计时
|
||||
if (item.PrepareEventTime == null)
|
||||
item.PrepareEventTime = now;
|
||||
if ((now - item.PrepareEventTime!.Value).TotalSeconds > delay)
|
||||
if (item.PrepareAlarmEventTime == null)
|
||||
item.PrepareAlarmEventTime = now;
|
||||
if ((now - item.PrepareAlarmEventTime!.Value).TotalMilliseconds > delay)
|
||||
{
|
||||
//超过延时时间,触发报警
|
||||
item.EventType = EventTypeEnum.Alarm;
|
||||
@@ -325,7 +325,7 @@ internal sealed class AlarmTask : IDisposable
|
||||
item.AlarmCode = item.Value.ToString();
|
||||
item.RecoveryCode = string.Empty;
|
||||
item.AlarmText = text;
|
||||
item.PrepareEventTime = null;
|
||||
item.PrepareAlarmEventTime = null;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
@@ -346,24 +346,64 @@ internal sealed class AlarmTask : IDisposable
|
||||
item.AlarmCode = item.Value.ToString();
|
||||
item.RecoveryCode = string.Empty;
|
||||
item.AlarmText = text;
|
||||
item.PrepareAlarmEventTime = null;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else if (eventEnum == EventTypeEnum.Finish)
|
||||
{
|
||||
// 如果是需恢复报警事件
|
||||
// 获取旧的报警信息
|
||||
if (GlobalData.RealAlarmIdVariables.TryGetValue(item.Id, out var oldAlarm))
|
||||
var now = DateTime.Now;
|
||||
//添加报警延时策略
|
||||
if (delay > 0)
|
||||
{
|
||||
item.AlarmType = oldAlarm.AlarmType;
|
||||
item.EventType = eventEnum;
|
||||
item.AlarmLimit = oldAlarm.AlarmLimit;
|
||||
item.AlarmCode = oldAlarm.AlarmCode;
|
||||
item.RecoveryCode = item.Value.ToString();
|
||||
item.AlarmText = oldAlarm.AlarmText;
|
||||
item.EventTime = DateTime.Now;
|
||||
if (item.EventType != EventTypeEnum.Finish && item.EventType != EventTypeEnum.PrepareFinish)
|
||||
{
|
||||
item.EventType = EventTypeEnum.PrepareFinish;//准备报警
|
||||
item.PrepareFinishEventTime = now;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item.EventType == EventTypeEnum.PrepareFinish)
|
||||
{
|
||||
if ((now - item.PrepareFinishEventTime!.Value).TotalMilliseconds > delay)
|
||||
{
|
||||
if (GlobalData.RealAlarmIdVariables.TryGetValue(item.Id, out var oldAlarm))
|
||||
{
|
||||
item.AlarmType = oldAlarm.AlarmType;
|
||||
item.EventType = eventEnum;
|
||||
item.AlarmLimit = oldAlarm.AlarmLimit;
|
||||
item.AlarmCode = oldAlarm.AlarmCode;
|
||||
item.RecoveryCode = item.Value.ToString();
|
||||
item.AlarmText = oldAlarm.AlarmText;
|
||||
item.EventTime = DateTime.Now;
|
||||
item.PrepareFinishEventTime = null;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果是需恢复报警事件
|
||||
// 获取旧的报警信息
|
||||
if (GlobalData.RealAlarmIdVariables.TryGetValue(item.Id, out var oldAlarm))
|
||||
{
|
||||
item.AlarmType = oldAlarm.AlarmType;
|
||||
item.EventType = eventEnum;
|
||||
item.AlarmLimit = oldAlarm.AlarmLimit;
|
||||
item.AlarmCode = oldAlarm.AlarmCode;
|
||||
item.RecoveryCode = item.Value.ToString();
|
||||
item.AlarmText = oldAlarm.AlarmText;
|
||||
item.EventTime = DateTime.Now;
|
||||
item.PrepareFinishEventTime = null;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// 触发报警变化事件
|
||||
@@ -333,6 +333,8 @@ internal sealed class DeviceThreadManage : IAsyncDisposable, IDeviceThreadManage
|
||||
}
|
||||
}
|
||||
|
||||
driver.IdVariableRuntimes.ForEach(a => a.Value.SetErrorMessage(null));
|
||||
|
||||
CancellationTokenSources.TryAdd(driver.DeviceId, cts);
|
||||
|
||||
_ = Task.Factory.StartNew((state) => DriverStart(state, token), driver, token);
|
||||
@@ -395,17 +397,21 @@ internal sealed class DeviceThreadManage : IAsyncDisposable, IDeviceThreadManage
|
||||
// 查找具有指定设备ID的驱动程序对象
|
||||
if (Drivers.TryRemove(deviceId, out var driver))
|
||||
{
|
||||
driver.CurrentDevice.SetDeviceStatus(now, false, "Communication connection has been removed");
|
||||
if (IsCollectChannel == true)
|
||||
{
|
||||
foreach (var a in driver.IdVariableRuntimes)
|
||||
{
|
||||
a.Value.SetValue(a.Value.Value, now, false);
|
||||
a.Value.SetErrorMessage("Communication connection has been removed");
|
||||
if (a.Value.SaveValue && !a.Value.DynamicVariable)
|
||||
{
|
||||
saveVariableRuntimes.Add(a.Value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 取消驱动程序的操作
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
<TableColumn Field="@context.BindUrl" FieldExpression=@(() => context.BindUrl) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||
<TableColumn Field="@context.MaxClientCount" FieldExpression=@(() => context.MaxClientCount) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||
<TableColumn Field="@context.MaxConcurrentCount" FieldExpression=@(() => context.MaxConcurrentCount) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||
<TableColumn Field="@context.DtuIdHex" FieldExpression=@(() => context.DtuIdHex) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||
<TableColumn Field="@context.HeartbeatHex" FieldExpression=@(() => context.HeartbeatHex) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||
|
||||
<TableColumn @bind-Field="@context.Id" Filterable=true Sortable=true Visible="false" DefaultSort=true DefaultSortOrder="SortOrder.Asc" />
|
||||
|
||||
|
||||
Reference in New Issue
Block a user