将PollLevelType类型改为int类型

This commit is contained in:
2025-09-05 19:59:21 +08:00
parent 8b86f079e5
commit 6e123b47cc
16 changed files with 88 additions and 146 deletions

View File

@@ -16,7 +16,7 @@ public class VariableDto
public VariableTableDto? VariableTable { get; set; }
public List<VariableMqttAliasDto>? MqttAliases { get; set; }
public SignalType SignalType { get; set; }
public PollLevelType PollLevel { get; set; }
public int PollLevel { get; set; }
public bool IsActive { get; set; }
public int VariableTableId { get; set; }
public string OpcUaNodeId { get; set; }

View File

@@ -1,36 +0,0 @@
using System.ComponentModel;
namespace DMS.Core.Enums
{
public enum PollLevelType
{
[Description("10毫秒")]
TenMilliseconds = 10,
[Description("100毫秒")]
HundredMilliseconds = 100,
[Description("500毫秒")]
FiveHundredMilliseconds = 500,
[Description("1秒钟")]
OneSecond = 1000,
[Description("5秒钟")]
FiveSeconds = 5000,
[Description("10秒钟")]
TenSeconds = 10000,
[Description("20秒钟")]
TwentySeconds = 20000,
[Description("30秒钟")]
ThirtySeconds = 30000,
[Description("1分钟")]
OneMinute = 60000,
[Description("3分钟")]
ThreeMinutes = 180000,
[Description("5分钟")]
FiveMinutes = 300000,
[Description("10分钟")]
TenMinutes = 600000,
[Description("30分钟")]
ThirtyMinutes = 1800000,
[Description("1小时")]
OneHour = 3600000
}
}

View File

@@ -37,7 +37,7 @@ public class Variable
/// <summary>
/// 变量的轮询级别,决定了其读取频率。
/// </summary>
public PollLevelType PollLevel { get; set; }
public int PollLevel { get; set; }
/// <summary>
/// 指示此变量是否处于激活状态。

View File

@@ -147,7 +147,7 @@ namespace DMS.Infrastructure.UnitTests
.RuleFor(v => v.Name, f => f.Commerce.ProductName())
.RuleFor(v => v.S7Address, f => $"DB1.DBD{f.Random.Int(0, 1000)}")
.RuleFor(v => v.SignalType, f => f.PickRandom<SignalType>())
.RuleFor(v => v.PollLevel, f => f.PickRandom<PollLevelType>())
.RuleFor(v => v.PollLevel, f => f.Random.Int(10, 1800000))
.RuleFor(v => v.IsActive, f => f.Random.Bool())
.RuleFor(v => v.IsHistoryEnabled, f => f.Random.Bool())
.RuleFor(v => v.HistoryDeadband, f => f.Random.Double(0.0, 1.0))

View File

@@ -35,8 +35,7 @@ public class DbVariable
/// <summary>
/// 变量的轮询级别,决定数据采集频率。
/// </summary>
[SugarColumn(ColumnDataType="varchar(20)",SqlParameterDbType=typeof(EnumToStringConvert))]
public PollLevelType PollLevel { get; set; }
public int PollLevel { get; set; }
/// <summary>
/// 指示此变量是否处于激活状态。

View File

@@ -263,7 +263,7 @@ public static class ExcelHelper
variable.OpcUaNodeId = "";
variable.Protocol = ProtocolType.S7;
variable.PollLevel = PollLevelType.ThirtySeconds;
variable.PollLevel = 30000; // ThirtySeconds
variableDatas.Add(variable);
}

View File

@@ -260,7 +260,7 @@ public class ExcelService : IExcelService
variable.OpcUaNodeId = "";
variable.Protocol = ProtocolType.S7;
variable.PollLevel = PollLevelType.ThirtySeconds;
variable.PollLevel = 30000; // ThirtySeconds
variableDatas.Add(variable);
}

View File

@@ -52,25 +52,22 @@ public class OpcUaBackgroundService : BackgroundService
private readonly int _opcUaSubscriptionSamplingIntervalMs = 1000;
// 模拟 PollingIntervals实际应用中可能从配置或数据库加载
private static readonly Dictionary<PollLevelType, TimeSpan> PollingIntervals
= new Dictionary<PollLevelType, TimeSpan>
private static readonly Dictionary<int, TimeSpan> PollingIntervals
= new Dictionary<int, TimeSpan>
{
{ PollLevelType.TenMilliseconds, TimeSpan.FromMilliseconds((int)PollLevelType.TenMilliseconds) },
{ PollLevelType.HundredMilliseconds, TimeSpan.FromMilliseconds((int)PollLevelType.HundredMilliseconds) },
{
PollLevelType.FiveHundredMilliseconds,
TimeSpan.FromMilliseconds((int)PollLevelType.FiveHundredMilliseconds)
},
{ PollLevelType.OneSecond, TimeSpan.FromMilliseconds((int)PollLevelType.OneSecond) },
{ PollLevelType.FiveSeconds, TimeSpan.FromMilliseconds((int)PollLevelType.FiveSeconds) },
{ PollLevelType.TenSeconds, TimeSpan.FromMilliseconds((int)PollLevelType.TenSeconds) },
{ PollLevelType.TwentySeconds, TimeSpan.FromMilliseconds((int)PollLevelType.TwentySeconds) },
{ PollLevelType.ThirtySeconds, TimeSpan.FromMilliseconds((int)PollLevelType.ThirtySeconds) },
{ PollLevelType.OneMinute, TimeSpan.FromMilliseconds((int)PollLevelType.OneMinute) },
{ PollLevelType.ThreeMinutes, TimeSpan.FromMilliseconds((int)PollLevelType.ThreeMinutes) },
{ PollLevelType.FiveMinutes, TimeSpan.FromMilliseconds((int)PollLevelType.FiveMinutes) },
{ PollLevelType.TenMinutes, TimeSpan.FromMilliseconds((int)PollLevelType.TenMinutes) },
{ PollLevelType.ThirtyMinutes, TimeSpan.FromMilliseconds((int)PollLevelType.ThirtyMinutes) }
{ 10, TimeSpan.FromMilliseconds(10) }, // TenMilliseconds
{ 100, TimeSpan.FromMilliseconds(100) }, // HundredMilliseconds
{ 500, TimeSpan.FromMilliseconds(500) }, // FiveHundredMilliseconds
{ 1000, TimeSpan.FromMilliseconds(1000) }, // OneSecond
{ 5000, TimeSpan.FromMilliseconds(5000) }, // FiveSeconds
{ 10000, TimeSpan.FromMilliseconds(10000) }, // TenSeconds
{ 20000, TimeSpan.FromMilliseconds(20000) }, // TwentySeconds
{ 30000, TimeSpan.FromMilliseconds(30000) }, // ThirtySeconds
{ 60000, TimeSpan.FromMilliseconds(60000) }, // OneMinute
{ 180000, TimeSpan.FromMilliseconds(180000) }, // ThreeMinutes
{ 300000, TimeSpan.FromMilliseconds(300000) }, // FiveMinutes
{ 600000, TimeSpan.FromMilliseconds(600000) }, // TenMinutes
{ 1800000, TimeSpan.FromMilliseconds(1800000) } // ThirtyMinutes
};
public OpcUaBackgroundService(IDataCenterService dataCenterService,IDataProcessingService dataProcessingService, ILogger<OpcUaBackgroundService> logger)
@@ -283,12 +280,12 @@ public class OpcUaBackgroundService : BackgroundService
var variableGroup = opcUaVariables.GroupBy(variable => variable.PollLevel);
foreach (var vGroup in variableGroup)
{
var pollLevelType = vGroup.Key;
var pollLevel = vGroup.Key;
var opcUaNodes
= vGroup.Select(variableDto => new OpcUaNode() { NodeId = variableDto.OpcUaNodeId })
.ToList();
PollingIntervals.TryGetValue(pollLevelType, out var pollLevel);
PollingIntervals.TryGetValue(pollLevel, out var interval);
opcUaService.SubscribeToNode(opcUaNodes,HandleDataChanged,10000,1000);
}
}

View File

@@ -223,7 +223,7 @@ namespace DMS.Infrastructure.Services
// 为每个PollLevel组设置单独的订阅
foreach (var group in variablesByPollLevel)
{
PollLevelType pollLevel = group.Key;
int pollLevel = group.Key;
var variables = group.Value;
_logger.LogInformation("为设备 {DeviceName} 设置PollLevel {PollLevel} 的订阅,变量数: {VariableCount}",
@@ -253,23 +253,23 @@ namespace DMS.Infrastructure.Services
/// <summary>
/// 根据PollLevel获取发布间隔毫秒
/// </summary>
private int GetPublishingIntervalFromPollLevel(PollLevelType pollLevel)
private int GetPublishingIntervalFromPollLevel(int pollLevel)
{
// 根据PollLevelType枚举值映射到发布间隔
// 根据轮询级别值映射到发布间隔
return pollLevel switch
{
PollLevelType.HundredMilliseconds => 100, // TenMilliseconds -> 100ms发布间隔
PollLevelType.FiveHundredMilliseconds => 500, // HundredMilliseconds -> 500ms发布间隔
PollLevelType.OneSecond => 1000, // FiveHundredMilliseconds -> 1000ms发布间隔
PollLevelType.FiveSeconds => 5000, // OneSecond -> 2000ms发布间隔
PollLevelType.TenSeconds => 10000, // TenSeconds -> 10000ms发布间隔
PollLevelType.TwentySeconds => 20000, // TwentySeconds -> 20000ms发布间隔
PollLevelType.ThirtySeconds => 30000, // ThirtySeconds -> 30000ms发布间隔
PollLevelType.OneMinute => 60000, // OneMinute -> 60000ms发布间隔
PollLevelType.FiveMinutes => 300000, // ThreeMinutes -> 120000ms发布间隔
PollLevelType.TenMinutes => 600000, // FiveMinutes -> 180000ms发布间隔
PollLevelType.ThirtyMinutes => 1800000, // TenMinutes -> 300000ms发布间隔
PollLevelType.OneHour => 3600000, // ThirtyMinutes -> 600000ms发布间隔
100 => 100, // HundredMilliseconds -> 100ms发布间隔
500 => 500, // FiveHundredMilliseconds -> 500ms发布间隔
1000 => 1000, // OneSecond -> 1000ms发布间隔
5000 => 5000, // FiveSeconds -> 5000ms发布间隔
10000 => 10000, // TenSeconds -> 10000ms发布间隔
20000 => 20000, // TwentySeconds -> 20000ms发布间隔
30000 => 30000, // ThirtySeconds -> 30000ms发布间隔
60000 => 60000, // OneMinute -> 60000ms发布间隔
300000 => 300000, // FiveMinutes -> 300000ms发布间隔
600000 => 600000, // TenMinutes -> 600000ms发布间隔
1800000 => 1800000, // ThirtyMinutes -> 1800000ms发布间隔
3600000 => 3600000, // OneHour -> 3600000ms发布间隔
_ => _options.SubscriptionPublishingIntervalMs // 默认值
};
}

View File

@@ -30,24 +30,24 @@ public class OptimizedS7BackgroundService : BackgroundService
private readonly int _s7PollOnceSleepTimeMs = 50;
// 存储每个设备的变量按轮询级别分组
private readonly ConcurrentDictionary<int, Dictionary<PollLevelType, List<VariableDto>>> _variablesByPollLevel = new();
private readonly ConcurrentDictionary<int, Dictionary<int, List<VariableDto>>> _variablesByPollLevel = new();
// 模拟 PollingIntervals实际应用中可能从配置或数据库加载
private static readonly Dictionary<PollLevelType, TimeSpan> PollingIntervals = new Dictionary<PollLevelType, TimeSpan>
private static readonly Dictionary<int, TimeSpan> PollingIntervals = new Dictionary<int, TimeSpan>
{
{ PollLevelType.TenMilliseconds, TimeSpan.FromMilliseconds((int)PollLevelType.TenMilliseconds) },
{ PollLevelType.HundredMilliseconds, TimeSpan.FromMilliseconds((int)PollLevelType.HundredMilliseconds) },
{ PollLevelType.FiveHundredMilliseconds, TimeSpan.FromMilliseconds((int)PollLevelType.FiveHundredMilliseconds) },
{ PollLevelType.OneSecond, TimeSpan.FromMilliseconds((int)PollLevelType.OneSecond) },
{ PollLevelType.FiveSeconds, TimeSpan.FromMilliseconds((int)PollLevelType.FiveSeconds) },
{ PollLevelType.TenSeconds, TimeSpan.FromMilliseconds((int)PollLevelType.TenSeconds) },
{ PollLevelType.TwentySeconds, TimeSpan.FromMilliseconds((int)PollLevelType.TwentySeconds) },
{ PollLevelType.ThirtySeconds, TimeSpan.FromMilliseconds((int)PollLevelType.ThirtySeconds) },
{ PollLevelType.OneMinute, TimeSpan.FromMilliseconds((int)PollLevelType.OneMinute) },
{ PollLevelType.ThreeMinutes, TimeSpan.FromMilliseconds((int)PollLevelType.ThreeMinutes) },
{ PollLevelType.FiveMinutes, TimeSpan.FromMilliseconds((int)PollLevelType.FiveMinutes) },
{ PollLevelType.TenMinutes, TimeSpan.FromMilliseconds((int)PollLevelType.TenMinutes) },
{ PollLevelType.ThirtyMinutes, TimeSpan.FromMilliseconds((int)PollLevelType.ThirtyMinutes) }
{ 10, TimeSpan.FromMilliseconds(10) }, // TenMilliseconds
{ 100, TimeSpan.FromMilliseconds(100) }, // HundredMilliseconds
{ 500, TimeSpan.FromMilliseconds(500) }, // FiveHundredMilliseconds
{ 1000, TimeSpan.FromMilliseconds(1000) }, // OneSecond
{ 5000, TimeSpan.FromMilliseconds(5000) }, // FiveSeconds
{ 10000, TimeSpan.FromMilliseconds(10000) }, // TenSeconds
{ 20000, TimeSpan.FromMilliseconds(20000) }, // TwentySeconds
{ 30000, TimeSpan.FromMilliseconds(30000) }, // ThirtySeconds
{ 60000, TimeSpan.FromMilliseconds(60000) }, // OneMinute
{ 180000, TimeSpan.FromMilliseconds(180000) }, // ThreeMinutes
{ 300000, TimeSpan.FromMilliseconds(300000) }, // FiveMinutes
{ 600000, TimeSpan.FromMilliseconds(600000) }, // TenMinutes
{ 1800000, TimeSpan.FromMilliseconds(1800000) } // ThirtyMinutes
};
/// <summary>
@@ -223,7 +223,7 @@ public class OptimizedS7BackgroundService : BackgroundService
/// <summary>
/// 检查是否应该轮询变量
/// </summary>
private bool ShouldPollVariables(List<VariableDto> variables, PollLevelType pollLevel)
private bool ShouldPollVariables(List<VariableDto> variables, int pollLevel)
{
if (!PollingIntervals.TryGetValue(pollLevel, out var interval))
return false;

View File

@@ -26,8 +26,8 @@ namespace DMS.Infrastructure.Services
private readonly ILogger<S7DeviceAgent> _logger;
private Plc _plc;
private bool _isConnected;
private readonly Dictionary<PollLevelType, List<Variable>> _variablesByPollLevel;
private readonly Dictionary<PollLevelType, DateTime> _lastPollTimes;
private readonly Dictionary<int, List<Variable>> _variablesByPollLevel;
private readonly Dictionary<int, DateTime> _lastPollTimes;
public S7DeviceAgent(Device device, IChannelBus channelBus, IMessenger messenger, ILogger<S7DeviceAgent> logger)
{
@@ -36,8 +36,8 @@ namespace DMS.Infrastructure.Services
_messenger = messenger ?? throw new ArgumentNullException(nameof(messenger));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_variablesByPollLevel = new Dictionary<PollLevelType, List<Variable>>();
_lastPollTimes = new Dictionary<PollLevelType, DateTime>();
_variablesByPollLevel = new Dictionary<int, List<Variable>>();
_lastPollTimes = new Dictionary<int, DateTime>();
InitializePlc();
}
@@ -175,7 +175,7 @@ namespace DMS.Infrastructure.Services
}
}
private bool ShouldPoll(PollLevelType pollLevel)
private bool ShouldPoll(int pollLevel)
{
// 获取轮询间隔
var interval = GetPollingInterval(pollLevel);
@@ -189,28 +189,28 @@ namespace DMS.Infrastructure.Services
return true;
}
private TimeSpan GetPollingInterval(PollLevelType pollLevel)
private TimeSpan GetPollingInterval(int pollLevel)
{
return pollLevel switch
{
PollLevelType.TenMilliseconds => TimeSpan.FromMilliseconds(10),
PollLevelType.HundredMilliseconds => TimeSpan.FromMilliseconds(100),
PollLevelType.FiveHundredMilliseconds => TimeSpan.FromMilliseconds(500),
PollLevelType.OneSecond => TimeSpan.FromMilliseconds(1000),
PollLevelType.FiveSeconds => TimeSpan.FromMilliseconds(5000),
PollLevelType.TenSeconds => TimeSpan.FromMilliseconds(10000),
PollLevelType.TwentySeconds => TimeSpan.FromMilliseconds(20000),
PollLevelType.ThirtySeconds => TimeSpan.FromMilliseconds(30000),
PollLevelType.OneMinute => TimeSpan.FromMinutes(1),
PollLevelType.ThreeMinutes => TimeSpan.FromMinutes(3),
PollLevelType.FiveMinutes => TimeSpan.FromMinutes(5),
PollLevelType.TenMinutes => TimeSpan.FromMinutes(10),
PollLevelType.ThirtyMinutes => TimeSpan.FromMinutes(30),
10 => TimeSpan.FromMilliseconds(10), // TenMilliseconds
100 => TimeSpan.FromMilliseconds(100), // HundredMilliseconds
500 => TimeSpan.FromMilliseconds(500), // FiveHundredMilliseconds
1000 => TimeSpan.FromMilliseconds(1000), // OneSecond
5000 => TimeSpan.FromMilliseconds(5000), // FiveSeconds
10000 => TimeSpan.FromMilliseconds(10000), // TenSeconds
20000 => TimeSpan.FromMilliseconds(20000), // TwentySeconds
30000 => TimeSpan.FromMilliseconds(30000), // ThirtySeconds
60000 => TimeSpan.FromMilliseconds(60000), // OneMinute
180000 => TimeSpan.FromMilliseconds(180000), // ThreeMinutes
300000 => TimeSpan.FromMilliseconds(300000), // FiveMinutes
600000 => TimeSpan.FromMilliseconds(600000), // TenMinutes
1800000 => TimeSpan.FromMilliseconds(1800000), // ThirtyMinutes
_ => TimeSpan.FromMilliseconds(1000)
};
}
private async Task PollVariablesByLevelAsync(List<Variable> variables, PollLevelType pollLevel)
private async Task PollVariablesByLevelAsync(List<Variable> variables, int pollLevel)
{
// 批量读取变量
var dataItems = new List<DataItem>();

View File

@@ -3,20 +3,19 @@ using System.Collections.Generic;
using System.Linq;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using DMS.Core.Enums;
namespace DMS.WPF.ViewModels.Dialogs
{
public partial class PollLevelDialogViewModel : DialogViewModelBase<PollLevelType?>
public partial class PollLevelDialogViewModel : DialogViewModelBase<int?>
{
[ObservableProperty]
private PollLevelType _selectedPollLevelType;
private int _selectedPollLevelType;
public List<PollLevelType> PollLevelTypes { get; }
public List<int> PollLevelTypes { get; }
public PollLevelDialogViewModel(PollLevelType currentPollLevelType)
public PollLevelDialogViewModel(int currentPollLevelType)
{
PollLevelTypes = Enum.GetValues(typeof(PollLevelType)).Cast<PollLevelType>().ToList();
PollLevelTypes = new List<int> { 10, 100, 500, 1000, 5000, 10000, 20000, 30000, 60000, 180000, 300000, 600000, 1800000, 3600000 };
SelectedPollLevelType = currentPollLevelType;
Title = "修改轮询频率";
PrimaryButText = "确定";

View File

@@ -73,7 +73,7 @@ public partial class VariableItemViewModel : ObservableObject
/// 用于决定数据采集的频率(如:高、中、低)。
/// </summary>
[ObservableProperty]
private PollLevelType _pollLevel=PollLevelType.ThirtySeconds;
private int _pollLevel = 30000; // ThirtySeconds
/// <summary>
/// 获取或设置一个值,该值指示此变量是否被激活。

View File

@@ -24,7 +24,7 @@
SelectedItem="{Binding SelectedPollLevelType}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource EnumDescriptionConverter}}" />
<TextBlock Text="{Binding}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

View File

@@ -24,7 +24,6 @@
<valueConverts:EnumToStringConverter x:Key="EnumToStringConverter" />
<ex:EnumBindingSource x:Key="ProtocolType" EnumType="{x:Type en:ProtocolType}" />
<ex:EnumBindingSource x:Key="SignalType" EnumType="{x:Type enums:SignalType}" />
<ex:EnumBindingSource x:Key="PollLevelType" EnumType="{x:Type enums:PollLevelType}" />
<ex:EnumBindingSource x:Key="CSharpDataType" EnumType="{x:Type enums:DataType}" />
</ui:ContentDialog.Resources>
@@ -145,19 +144,15 @@
</ComboBox.ItemTemplate>
</hc:ComboBox>
<hc:ComboBox
<hc:TextBox
Grid.Row="2"
Grid.Column="0"
Margin="0,15,0,0"
hc:InfoElement.Title="轮询级别:"
ItemsSource="{Binding Source={StaticResource PollLevelType}}"
SelectedItem="{Binding Variable.PollLevel, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource EnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</hc:ComboBox>
Text="{Binding PollLevel}"
>
</hc:TextBox>
<hc:ComboBox
Grid.Row="2"

View File

@@ -22,7 +22,6 @@
<ex:BindingProxy x:Key="proxy" Data="{Binding}" />
<ex:EnumBindingSource x:Key="signalType" EnumType="{x:Type enums:SignalType}" />
<valueConverts:EnumDescriptionConverter x:Key="EnumDescriptionConverter" />
<ex:EnumBindingSource x:Key="pollLevelType" EnumType="{x:Type enums:PollLevelType}" />
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<!-- 标签字体的样式 -->
@@ -269,23 +268,12 @@
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="轮询频率" SortMemberPath="PollLevelType">
<DataGridTemplateColumn Header="轮询频率" SortMemberPath="PollLevel">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding PollLevel, Converter={StaticResource EnumDescriptionConverter}}" />
<TextBlock Text="{Binding PollLevel}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Source={StaticResource pollLevelType}}" SelectedItem="{Binding PollLevel}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource EnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn