我将为半导体可靠性测试机上位机系统提供更详细的模块化实现,重点包括监控界面、日志界面、流程配置界面的具体代码,以及多设备管理、历史数据查询、云端部署和深度学习模型的设计与实现
我将为半导体可靠性测试机上位机系统提供更详细的模块化实现,重点包括监控界面、日志界面、流程配置界面的具体代码,以及多设备管理、历史数据查询、云端部署和深度学习模型的设计与实现。本文将基于 .NET Core 8.0、WPF、MVVM 模式、Prism 框架、LiveCharts2、Entity Framework Core、Serilog 等技术栈,结合异步编程和高性能优化,确保代码可落地且易扩展。由于内容较多,我将分模块展开,并提供具体代码示例和实现细节。
一、监控界面(MonitorView)实现
1.1 功能描述
监控界面用于实时显示硬件状态,包括:
-
温箱:温度、湿度、运行状态。
-
通道:电压、电流、温度等参数。
-
辅控板:蜂鸣器、PLC、接触器等状态。
-
老化板:工位数据、热阻等。
-
电源:输出电压、电流、开关状态。 支持动态刷新、异常告警、仪表盘和表格展示。
1.2 MonitorView.xaml
xaml
<UserControl x:Class="ReliabilityTestSystem.UI.Modules.MonitorModule.Views.MonitorView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
xmlns:prism="http://prismlibrary.com/">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- 硬件选择 -->
<StackPanel Orientation="Horizontal" Margin="5">
<ComboBox ItemsSource="{Binding HardwareTypes}"
SelectedItem="{Binding SelectedHardwareType}"
Width="150" Margin="5"/>
<Button Content="刷新" Command="{Binding RefreshCommand}" Margin="5"/>
<Button Content="帮助" Command="{Binding ShowHelpCommand}" Margin="5"
ToolTip="查看监控界面操作指南"/>
</StackPanel>
<!-- 硬件状态展示 -->
<TabControl Grid.Row="1" ItemsSource="{Binding HardwareGroups}">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- 数据表格 -->
<DataGrid ItemsSource="{Binding Devices}"
AutoGenerateColumns="False"
Margin="5">
<DataGrid.Columns>
<DataGridTextColumn Header="设备ID" Binding="{Binding Id}"/>
<DataGridTextColumn Header="名称" Binding="{Binding Name}"/>
<DataGridTextColumn Header="状态" Binding="{Binding Status}"/>
<DataGridTextColumn Header="参数" Binding="{Binding Parameters}"/>
</DataGrid.Columns>
</DataGrid>
<!-- 仪表盘 -->
<StackPanel Grid.Column="1" Margin="5">
<lc:GaugeChart Total="100"
Value="{Binding SelectedDevice.Temperature}"
LabelFormatter="{Binding LabelFormatter}"
Height="150" Width="150"
Margin="5"/>
<TextBlock Text="{Binding SelectedDevice.Name}"
FontWeight="Bold" Margin="5"/>
</StackPanel>
</Grid>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
</UserControl>
1.3 MonitorViewModel.cs
csharp
using LiveChartsCore;
using LiveChartsCore.SkiaSharpView;
using Prism.Commands;
using Prism.Mvvm;
using ReliabilityTestSystem.Core.Models;
using ReliabilityTestSystem.Core.Services;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;
namespace ReliabilityTestSystem.UI.Modules.MonitorModule.ViewModels
{
public class MonitorViewModel : BindableBase
{
private readonly IHardwareService _hardwareService;
private ObservableCollection<string> _hardwareTypes;
private string _selectedHardwareType;
private ObservableCollection<HardwareGroup> _hardwareGroups;
private Timer _refreshTimer;
private Func<double, string> _labelFormatter = value => $"{value:F1} °C";
public MonitorViewModel(IHardwareService hardwareService)
{
_hardwareService = hardwareService;
RefreshCommand = new DelegateCommand(async () => await RefreshAsync());
ShowHelpCommand = new DelegateCommand(ShowHelp);
HardwareTypes = new ObservableCollection<string> { "温箱", "通道", "辅控板", "老化板", "电源" };
SelectedHardwareType = HardwareTypes.First();
HardwareGroups = new ObservableCollection<HardwareGroup>();
// 设置定时刷新(每秒)
_refreshTimer = new Timer(1000);
_refreshTimer.Elapsed += async (s, e) => await RefreshAsync();
_refreshTimer.Start();
Task.Run(() => InitializeAsync());
}
public ObservableCollection<string> HardwareTypes
{
get => _hardwareTypes;
set => SetProperty(ref _hardwareTypes, value);
}
public string SelectedHardwareType
{
get => _selectedHardwareType;
set
{
SetProperty(ref _selectedHardwareType, value);
Task.Run(() => await LoadHardwareGroupsAsync());
}
}
public ObservableCollection<HardwareGroup> HardwareGroups
{
get => _hardwareGroups;
set => SetProperty(ref _hardwareGroups, value);
}
public DelegateCommand RefreshCommand { get; private set; }
public DelegateCommand ShowHelpCommand { get; private set; }
public Func<double, string> LabelFormatter => _labelFormatter;
private async Task InitializeAsync()
{
await LoadHardwareGroupsAsync();
}
private async Task LoadHardwareGroupsAsync()
{
var devices = await _hardwareService.GetDevicesByTypeAsync(SelectedHardwareType);
var groups = devices.GroupBy(d => d.Category)
.Select(g => new HardwareGroup
{
Name = g.Key,
Devices = new ObservableCollection<Device>(g.ToList()),
SelectedDevice = g.FirstOrDefault()
});
HardwareGroups.Clear();
foreach (var group of groups)
{
HardwareGroups.Add(group);
}
}
private async Task RefreshAsync()
{
await LoadHardwareGroupsAsync();
}
private void ShowHelp()
{
Application.Current.Dispatcher.Invoke(() => MessageBox.Show(
"监控界面操作指南:选择硬件类型,查看设备状态,点击刷新更新数据。"));
}
}
public class HardwareGroup : BindableBase
{
private Device _selectedDevice;
public string Name { get; set; }
public ObservableCollection<Device> Devices { get; set; }
public Device SelectedDevice
{
get => _selectedDevice;
set => SetProperty(ref _selectedDevice, value);
}
}
}
1.4 IHardwareService.cs
硬件服务接口,用于获取设备状态(具体实现依赖硬件驱动层)。
csharp
namespace ReliabilityTestSystem.Core.Services
{
public interface IHardwareService
{
Task<IEnumerable<Device>> GetDevicesByTypeAsync(string type);
}
public class Device
{
public string Id { get; set; }
public string Name { get; set; }
public string Status { get; set; }
public string Parameters { get; set; }
public string Category { get; set; }
public double Temperature { get; set; }
}
}
二、日志界面(LogView)实现
2.1 功能描述
日志界面展示系统和实验的日志流,支持:
-
实时日志流显示。
-
日志过滤(按时间、级别、节点)。
-
日志订阅与导出。
-
使用 Serilog 记录日志,确保高性能。
2.2 LogView.xaml
xaml
<UserControl x:Class="ReliabilityTestSystem.UI.Modules.LogModule.Views.LogView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- 过滤器 -->
<StackPanel Orientation="Horizontal" Margin="5">
<ComboBox ItemsSource="{Binding LogLevels}"
SelectedItem="{Binding SelectedLogLevel}"
Width="100" Margin="5"/>
<TextBox Text="{Binding FilterText}" Width="200" Margin="5"/>
<Button Content="导出" Command="{Binding ExportLogsCommand}" Margin="5"/>
<Button Content="帮助" Command="{Binding ShowHelpCommand}" Margin="5"
ToolTip="查看日志界面操作指南"/>
</StackPanel>
<!-- 日志列表 -->
<DataGrid Grid.Row="1" ItemsSource="{Binding Logs}"
AutoGenerateColumns="False" Margin="5">
<DataGrid.Columns>
<DataGridTextColumn Header="时间" Binding="{Binding Timestamp, StringFormat={}{0:yyyy-MM-dd HH:mm:ss}}"/>
<DataGridTextColumn Header="级别" Binding="{Binding Level}"/>
<DataGridTextColumn Header="消息" Binding="{Binding Message}" Width="*"/>
<DataGridTextColumn Header="节点" Binding="{Binding Source}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</UserControl>
2.3 LogViewModel.cs
csharp
using Prism.Commands;
using Prism.Mvvm;
using ReliabilityTestSystem.Core.Services;
using Serilog;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace ReliabilityTestSystem.UI.Modules.LogModule.ViewModels
{
public class LogViewModel : BindableBase
{
private readonly ILogService _logService;
private ObservableCollection<LogEntry> _logs;
private ObservableCollection<string> _logLevels;
private string _selectedLogLevel;
private string _filterText;
public LogViewModel(ILogService logService)
{
_logService = logService;
Logs = new ObservableCollection<LogEntry>();
LogLevels = new ObservableCollection<string> { "All", "Information", "Warning", "Error" };
SelectedLogLevel = LogLevels.First();
ExportLogsCommand = new DelegateCommand(ExportLogs);
ShowHelpCommand = new DelegateCommand(ShowHelp);
// 订阅日志更新
_logService.LogReceived += (s, e) => Application.Current.Dispatcher.Invoke(() => AddLog(e));
Task.Run(() => LoadLogsAsync());
}
public ObservableCollection<LogEntry> Logs
{
get => _logs;
set => SetProperty(ref _logs, value);
}
public ObservableCollection<string> LogLevels
{
get => _logLevels;
set => SetProperty(ref _logLevels, value);
}
public string SelectedLogLevel
{
get => _selectedLogLevel;
set
{
SetProperty(ref _selectedLogLevel, value);
FilterLogs();
}
}
public string FilterText
{
get => _filterText;
set
{
SetProperty(ref _filterText, value);
FilterLogs();
}
}
public DelegateCommand ExportLogsCommand { get; private set; }
public DelegateCommand ShowHelpCommand { get; private set; }
private async Task LoadLogsAsync()
{
var logs = await _logService.GetRecentLogsAsync(1000);
Application.Current.Dispatcher.Invoke(() =>
{
foreach (var log in logs)
{
Logs.Add(log);
}
});
}
private void AddLog(LogEntry log)
{
if (Logs.Count > 1000) Logs.RemoveAt(0); // 限制日志数量
Logs.Add(log);
}
private void FilterLogs()
{
var filtered = _logService.GetRecentLogsAsync(1000).Result
.Where(l => (SelectedLogLevel == "All" || l.Level == SelectedLogLevel) &&
(string.IsNullOrEmpty(FilterText) || l.Message.Contains(FilterText, StringComparison.OrdinalIgnoreCase)));
Application.Current.Dispatcher.Invoke(() =>
{
Logs.Clear();
foreach (var log in filtered)
{
Logs.Add(log);
}
});
}
private void ExportLogs()
{
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), $"logs_{DateTime.Now:yyyyMMdd_HHmmss}.csv");
using (var writer = new StreamWriter(path))
{
writer.WriteLine("Timestamp,Level,Message,Source");
foreach (var log in Logs)
{
writer.WriteLine($"\"{log.Timestamp}\",\"{log.Level}\",\"{log.Message}\",\"{log.Source}\"");
}
}
MessageBox.Show($"日志已导出到 {path}");
}
private void ShowHelp()
{
MessageBox.Show("日志界面操作指南:选择日志级别或输入关键字过滤,点击导出保存日志。");
}
}
public class LogEntry
{
public DateTime Timestamp { get; set; }
public string Level { get; set; }
public string Message { get; set; }
public string Source { get; set; }
}
}
2.4 ILogService.cs
日志服务接口,基于 Serilog。
csharp
namespace ReliabilityTestSystem.Core.Services
{
public interface ILogService
{
event EventHandler<LogEntry> LogReceived;
Task<IEnumerable<LogEntry>> GetRecentLogsAsync(int maxCount);
}
}
三、流程配置界面(ConfigView)深入实现
3.1 功能描述
流程配置界面支持动态设置实验流程(如升温、升压、延时),包括:
-
添加、删除、编辑测试步骤。
-
支持复杂流程(条件分支、循环)。
-
保存配置到数据库或文件。
-
提供预览和验证功能。
3.2 ConfigView.xaml
xaml
<UserControl x:Class="ReliabilityTestSystem.UI.Modules.ConfigModule.Views.ConfigView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- 步骤编辑 -->
<StackPanel Orientation="Horizontal" Margin="5">
<ComboBox ItemsSource="{Binding StepTypes}"
SelectedItem="{Binding SelectedStepType}"
Width="150" Margin="5"/>
<TextBox Text="{Binding StepParameter}" Width="200" Margin="5"/>
<Button Content="添加步骤" Command="{Binding AddStepCommand}" Margin="5"/>
<Button Content="帮助" Command="{Binding ShowHelpCommand}" Margin="5"
ToolTip="查看流程配置操作指南"/>
</StackPanel>
<!-- 步骤列表 -->
<ListBox Grid.Row="1" ItemsSource="{Binding TestSteps}" Margin="5">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Description}"/>
<Button Grid.Column="1" Content="删除"
Command="{Binding DataContext.DeleteStepCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"
CommandParameter="{Binding}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!-- 操作按钮 -->
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="5">
<Button Content="预览" Command="{Binding PreviewCommand}" Margin="5"/>
<Button Content="保存" Command="{Binding SaveConfigCommand}" Margin="5"/>
</StackPanel>
</Grid>
</UserControl>
3.3 ConfigViewModel.cs
csharp
using Prism.Commands;
using Prism.Mvvm;
using ReliabilityTestSystem.Core.Models;
using ReliabilityTestSystem.Core.Services;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
namespace ReliabilityTestSystem.UI.Modules.ConfigModule.ViewModels
{
public class ConfigViewModel : BindableBase
{
private readonly IConfigService _configService;
private ObservableCollection<TestStep> _testSteps;
private ObservableCollection<string> _stepTypes;
private string _selectedStepType;
private string _stepParameter;
public ConfigViewModel(IConfigService configService)
{
_configService = configService;
TestSteps = new ObservableCollection<TestStep>();
StepTypes = new ObservableCollection<string> { "升温", "升压", "延时", "循环", "条件" };
SelectedStepType = StepTypes.First();
AddStepCommand = new DelegateCommand(AddStep);
DeleteStepCommand = new DelegateCommand<TestStep>(DeleteStep);
PreviewCommand = new DelegateCommand(Preview);
SaveConfigCommand = new DelegateCommand(async () => await SaveConfigAsync());
ShowHelpCommand = new DelegateCommand(ShowHelp);
}
public ObservableCollection<TestStep> TestSteps
{
get => _testSteps;
set => SetProperty(ref _testSteps, value);
}
public ObservableCollection<string> StepTypes
{
get => _stepTypes;
set => SetProperty(ref _stepTypes, value);
}
public string SelectedStepType
{
get => _selectedStepType;
set => SetProperty(ref _selectedStepType, value);
}
public string StepParameter
{
get => _stepParameter;
set => SetProperty(ref _stepParameter, value);
}
public DelegateCommand AddStepCommand { get; private set; }
public DelegateCommand<TestStep> DeleteStepCommand { get; private set; }
public DelegateCommand PreviewCommand { get; private set; }
public DelegateCommand SaveConfigCommand { get; private set; }
public DelegateCommand ShowHelpCommand { get; private set; }
private void AddStep()
{
if (!string.IsNullOrEmpty(SelectedStepType) && !string.IsNullOrEmpty(StepParameter))
{
var step = new TestStep
{
StepType = SelectedStepType,
Parameter = StepParameter,
Description = $"{SelectedStepType}: {StepParameter}"
};
TestSteps.Add(step);
StepParameter = string.Empty;
}
}
private void DeleteStep(TestStep step)
{
TestSteps.Remove(step);
}
private void Preview()
{
var preview = string.Join("\n", TestSteps.Select(s => s.Description));
MessageBox.Show($"流程预览:\n{preview}");
}
private async Task SaveConfigAsync()
{
await _configService.SaveTestConfigAsync(TestSteps.ToList());
MessageBox.Show("配置已保存");
}
private void ShowHelp()
{
MessageBox.Show("流程配置操作指南:选择步骤类型,输入参数,添加或删除步骤,预览后保存。");
}
}
}
3.4 IConfigService.cs
配置服务接口。
csharp
namespace ReliabilityTestSystem.Core.Services
{
public interface IConfigService
{
Task SaveTestConfigAsync(IList<TestStep> steps);
}
public class TestStep
{
public string StepType { get; set; }
public string Parameter { get; set; }
public string Description { get; set; }
}
}
四、多设备管理实现
4.1 功能描述
支持动态发现和管理 200+ 设备,通过设备注册服务实现:
-
自动扫描硬件(COM、TCP/IP 等协议)。
-
动态加载驱动(反射或依赖注入)。
-
设备状态实时更新。
4.2 IDeviceRegistry.cs
设备注册服务接口。
csharp
namespace ReliabilityTestSystem.Core.Services
{
public interface IDeviceRegistry
{
Task DiscoverDevicesAsync();
IEnumerable<IDeviceDriver> GetRegisteredDevices();
event EventHandler<DeviceDiscoveredEventArgs> DeviceDiscovered;
}
public interface IDeviceDriver
{
string Id { get; }
string Name { get; }
Task InitializeAsync();
Task<object> ReadDataAsync();
Task SetParameterAsync(string parameter, object value);
}
public class DeviceDiscoveredEventArgs : EventArgs
{
public IDeviceDriver Device { get; set; }
}
}
4.3 DeviceRegistry.cs
设备注册服务实现(使用反射加载驱动)。
csharp
using System.Reflection;
namespace ReliabilityTestSystem.Core.Services
{
public class DeviceRegistry : IDeviceRegistry
{
private readonly List<IDeviceDriver> _devices = new List<IDeviceDriver>();
public event EventHandler<DeviceDiscoveredEventArgs> DeviceDiscovered;
public async Task DiscoverDevicesAsync()
{
// 扫描驱动程序集
var driverTypes = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => typeof(IDeviceDriver).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
foreach (var type in driverTypes)
{
var driver = (IDeviceDriver)Activator.CreateInstance(type);
await driver.InitializeAsync();
_devices.Add(driver);
DeviceDiscovered?.Invoke(this, new DeviceDiscoveredEventArgs { Device = driver });
}
}
public IEnumerable<IDeviceDriver> GetRegisteredDevices() => _devices;
}
}
4.4 示例驱动:PowerSupplyDriver.cs
电源驱动示例。
csharp
namespace ReliabilityTestSystem.Core.Drivers
{
public class PowerSupplyDriver : IDeviceDriver
{
public string Id => Guid.NewGuid().ToString();
public string Name => "特牛电源";
public async Task InitializeAsync()
{
// 模拟初始化
await Task.Delay(100);
}
public async Task<object> ReadDataAsync()
{
// 模拟读取电压和电流
return new { Voltage = 5.0, Current = 1.2 };
}
public async Task SetParameterAsync(string parameter, object value)
{
// 模拟设置参数
await Task.Delay(50);
}
}
}
4.5 集成到 MonitorViewModel
csharp
public MonitorViewModel(IHardwareService hardwareService, IDeviceRegistry deviceRegistry)
{
_hardwareService = hardwareService;
_deviceRegistry = deviceRegistry;
deviceRegistry.DeviceDiscovered += (s, e) => RefreshAsync();
Task.Run(() => deviceRegistry.DiscoverDevicesAsync());
}
五、历史数据查询实现
5.1 功能描述
历史数据查询界面支持:
-
按时间范围、通道、实验类型查询。
-
分页显示结果(EF Core)。
-
导出 CSV 或查看曲线。
5.2 HistoryQueryView.xaml
xaml
<UserControl x:Class="ReliabilityTestSystem.UI.Modules.HistoryModule.Views.HistoryQueryView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- 查询条件 -->
<StackPanel Orientation="Horizontal" Margin="5">
<DatePicker SelectedDate="{Binding StartDate}" Margin="5"/>
<DatePicker SelectedDate="{Binding EndDate}" Margin="5"/>
<ComboBox ItemsSource="{Binding Channels}"
SelectedItem="{Binding SelectedChannel}"
Width="150" Margin="5"/>
<Button Content="查询" Command="{Binding QueryCommand}" Margin="5"/>
<Button Content="帮助" Command="{Binding ShowHelpCommand}" Margin="5"/>
</StackPanel>
<!-- 查询结果 -->
<DataGrid Grid.Row="1" ItemsSource="{Binding QueryResults}"
AutoGenerateColumns="True" Margin="5"/>
<!-- 分页 -->
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="5">
<Button Content="上一页" Command="{Binding PreviousPageCommand}" Margin="5"/>
<TextBlock Text="{Binding CurrentPage}" Margin="5"/>
<Button Content="下一页" Command="{Binding NextPageCommand}" Margin="5"/>
<Button Content="导出" Command="{Binding ExportResultsCommand}" Margin="5"/>
</StackPanel>
</Grid>
</UserControl>
5.3 HistoryQueryViewModel.cs
csharp
using Microsoft.EntityFrameworkCore;
using Prism.Commands;
using Prism.Mvvm;
using ReliabilityTestSystem.Core.Data;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
namespace ReliabilityTestSystem.UI.Modules.HistoryModule.ViewModels
{
public class HistoryQueryViewModel : BindableBase
{
private readonly AppDbContext _dbContext;
private ObservableCollection<object> _queryResults;
private ObservableCollection<string> _channels;
private string _selectedChannel;
private DateTime? _startDate;
private DateTime? _endDate;
private int _currentPage = 1;
private readonly int _pageSize = 100;
public HistoryQueryViewModel(AppDbContext dbContext)
{
_dbContext = dbContext;
QueryResults = new ObservableCollection<object>();
Channels = new ObservableCollection<string> { "通道1", "通道2" }; // 模拟
SelectedChannel = Channels.First();
QueryCommand = new DelegateCommand(async () => await QueryAsync());
PreviousPageCommand = new DelegateCommand(async () => await ChangePageAsync(-1));
NextPageCommand = new DelegateCommand(async () => await ChangePageAsync(1));
ExportResultsCommand = new DelegateCommand(ExportResults);
ShowHelpCommand = new DelegateCommand(ShowHelp);
}
public ObservableCollection<object> QueryResults
{
get => _queryResults;
set => SetProperty(ref _queryResults, value);
}
public ObservableCollection<string> Channels
{
get => _channels;
set => SetProperty(ref _channels, value);
}
public string SelectedChannel
{
get => _selectedChannel;
set => SetProperty(ref _selectedChannel, value);
}
public DateTime? StartDate
{
get => _startDate;
set => SetProperty(ref _startDate, value);
}
public DateTime? EndDate
{
get => _endDate;
set => SetProperty(ref _endDate, value);
}
public int CurrentPage
{
get => _currentPage;
set => SetProperty(ref _currentPage, value);
}
public DelegateCommand QueryCommand { get; private set; }
public DelegateCommand PreviousPageCommand { get; private set; }
public DelegateCommand NextPageCommand { get; private set; }
public DelegateCommand ExportResultsCommand { get; private set; }
public DelegateCommand ShowHelpCommand { get; private set; }
private async Task QueryAsync()
{
var query = _dbContext.TestData.AsQueryable();
if (!string.IsNullOrEmpty(SelectedChannel))
query = query.Where(d => d.Channel == SelectedChannel);
if (StartDate.HasValue)
query = query.Where(d => d.Timestamp >= StartDate.Value);
if (EndDate.HasValue)
query = query.Where(d => d.Timestamp <= EndDate.Value);
var results = await query
.OrderBy(d => d.Timestamp)
.Skip((CurrentPage - 1) * _pageSize)
.Take(_pageSize)
.Select(d => new { d.Timestamp, d.Channel, d.Temperature, d.Voltage })
.ToListAsync();
QueryResults.Clear();
foreach (var result in results)
{
QueryResults.Add(result);
}
}
private async Task ChangePageAsync(int delta)
{
CurrentPage = Math.Max(1, CurrentPage + delta);
await QueryAsync();
}
private void ExportResults()
{
// 类似 LogViewModel 的导出逻辑
}
private void ShowHelp()
{
MessageBox.Show("历史查询操作指南:选择时间范围和通道,点击查询显示结果。");
}
}
}
5.4 AppDbContext.cs
EF Core 数据库上下文。
csharp
using Microsoft.EntityFrameworkCore;
namespace ReliabilityTestSystem.Core.Data
{
public class AppDbContext : DbContext
{
public DbSet<TestData> TestData { get; set; }
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
}
public class TestData
{
public int Id { get; set; }
public DateTime Timestamp { get; set; }
public string Channel { get; set; }
public double Temperature { get; set; }
public double Voltage { get; set; }
}
}
六、云端部署与 SignalR 实现
6.1 功能描述
支持将实时数据同步到云端,使用 SignalR 实现:
-
实时推送设备状态和实验数据。
-
支持 Web 端或移动端查看。
6.2 SignalR 服务端
创建一个 ASP.NET Core 项目(ReliabilityTestSystem.Web)。
Startup.cs
csharp
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.SignalR;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<DataHub>("/dataHub");
});
}
}
DataHub.cs
csharp
using Microsoft.AspNetCore.SignalR;
namespace ReliabilityTestSystem.Web.Hubs
{
public class DataHub : Hub
{
public async Task SendData(string channel, object data)
{
await Clients.All.SendAsync("ReceiveData", channel, data);
}
}
}
6.3 WPF 客户端集成 SignalR
安装 SignalR 客户端包:
bash
dotnet add package Microsoft.AspNetCore.SignalR.Client
SignalRService.cs
csharp
using Microsoft.AspNetCore.SignalR.Client;
using System.Threading.Tasks;
namespace ReliabilityTestSystem.Core.Services
{
public class SignalRService
{
private readonly HubConnection _connection;
public SignalRService()
{
_connection = new HubConnectionBuilder()
.WithUrl("https://yourserver/dataHub")
.Build();
}
public async Task StartAsync()
{
await _connection.StartAsync();
}
public async Task SendDataAsync(string channel, object data)
{
await _connection.InvokeAsync("SendData", channel, data);
}
}
}
在 ChannelDetailViewModel 中推送数据
csharp
public class ChannelDetailViewModel : BindableBase, INavigationAware
{
private readonly SignalRService _signalRService;
public ChannelDetailViewModel(SignalRService signalRService)
{
_signalRService = signalRService;
Task.Run(() => _signalRService.StartAsync());
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
var time = DateTime.Now.Ticks;
var temperature = 25 + Math.Sin(time / 10000000.0) * 2;
var voltage = 5 + Math.Cos(time / 10000000.0) * 0.2;
Application.Current.Dispatcher.Invoke(() =>
{
// 更新本地 UI
((ObservableCollection<double>)Series[0].Values).Add(temperature);
((ObservableCollection<double>)Series[1].Values).Add(voltage);
ChannelData.Add(new { Time = DateTime.Now, Temperature = temperature, Voltage = voltage });
// 推送至云端
_signalRService.SendDataAsync(Channel.Name, new { Time = DateTime.Now, Temperature = temperature, Voltage = voltage });
});
}
}
七、深度学习模型集成(ML.NET)
7.1 功能描述
使用 ML.NET 预测老化板寿命,基于历史数据(温度、电压、电流等)训练模型。
7.2 安装 ML.NET
bash
dotnet add package Microsoft.ML
7.3 数据模型
csharp
public class AgingBoardData
{
public float Temperature { get; set; }
public float Voltage { get; set; }
public float Current { get; set; }
public float Lifetime { get; set; } // 目标:寿命(小时)
}
public class LifetimePrediction
{
[ColumnName("Score")]
public float Lifetime { get; set; }
}
7.4 训练模型
csharp
using Microsoft.ML;
using Microsoft.ML.Data;
namespace ReliabilityTestSystem.Core.ML
{
public class LifetimePredictor
{
private readonly MLContext _mlContext = new MLContext();
private ITransformer _model;
public void TrainModel(IEnumerable<AgingBoardData> data)
{
var dataView = _mlContext.Data.LoadFromEnumerable(data);
var pipeline = _mlContext.Transforms.Concatenate("Features", nameof(AgingBoardData.Temperature), nameof(AgingBoardData.Voltage), nameof(AgingBoardData.Current))
.Append(_mlContext.Regression.Trainers.FastTree(labelColumnName: nameof(AgingBoardData.Lifetime)));
_model = pipeline.Fit(dataView);
}
public float Predict(AgingBoardData input)
{
var predictionEngine = _mlContext.Model.CreatePredictionEngine<AgingBoardData, LifetimePrediction>(_model);
return predictionEngine.Predict(input).Lifetime;
}
}
}
7.5 在 MonitorViewModel 中使用
csharp
public MonitorViewModel(IHardwareService hardwareService, LifetimePredictor predictor)
{
_hardwareService = hardwareService;
_predictor = predictor;
// 训练模型(假设有历史数据)
var trainingData = new List<AgingBoardData>
{
new AgingBoardData { Temperature = 25, Voltage = 5, Current = 1.2, Lifetime = 1000 },
new AgingBoardData { Temperature = 30, Voltage = 5.5, Current = 1.5, Lifetime = 800 }
};
_predictor.TrainModel(trainingData);
}
private async Task RefreshAsync()
{
var devices = await _hardwareService.GetDevicesByTypeAsync(SelectedHardwareType);
foreach (var device in devices.Where(d => d.Category == "老化板"))
{
var prediction = _predictor.Predict(new AgingBoardData
{
Temperature = (float)device.Temperature,
Voltage = 5.0f, // 模拟
Current = 1.2f
});
device.Parameters += $", 预测寿命: {prediction:F1} 小时";
}
// 更新 UI
}
八、总结与后续扩展
8.1 本篇总结
-
监控界面:实现了设备状态实时显示、仪表盘和表格。
-
日志界面:支持实时日志流、过滤和导出。
-
流程配置:动态设置实验步骤,包含预览和保存。
-
多设备管理:通过反射动态发现和管理 200+ 设备。
-
历史数据查询:使用 EF Core 实现分页查询。
-
云端部署:集成 SignalR 实现实时数据推送。
-
深度学习:使用 ML.NET 预测老化板寿命。
8.2 后续扩展
-
分布式架构:支持多上位机协同,基于 gRPC 或 RabbitMQ。
-
边缘计算:在设备端预处理数据,减少上位机负载。
-
高级可视化:集成 3D 模型展示烘箱结构。
-
自动化测试:为每个模块编写单元测试和 UI 测试。
8.3 下一步
请告诉我您希望深入的模块或功能,例如:
-
具体实验(如 HTRB、HTGB)的 TestController 实现。
-
硬件驱动层的完整代码(COM、TCP/IP 协议)。
-
更多 ML.NET 模型(异常检测、热阻预测)。
-
云端 Web 端可视化界面设计。
您需要哪部分的详细代码或设计?
更多推荐
所有评论(0)