This commit is contained in:
@@ -11,6 +11,20 @@
|
||||
public double PressureFactor { get; set; } = 1.0;
|
||||
public double WetFlowFactor { get; set; } = 1.0;
|
||||
public double DryFlowFactor { get; set; } = 1.0;
|
||||
|
||||
|
||||
|
||||
public ushort PressureRegisterStation1 { get; set; }
|
||||
public ushort PressureRegisterStation2 { get; set; }
|
||||
public ushort PressureRegisterStation3 { get; set; }
|
||||
public ushort PressureModeRegister { get; set; }
|
||||
public ushort PressCoil { get; set; }
|
||||
public ushort StartCoil { get; set; }
|
||||
public ushort EnableCoil { get; set; }
|
||||
public ushort StopCoil { get; set; }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +33,13 @@
|
||||
|
||||
public interface IPlcService
|
||||
{
|
||||
Task<float> ReadPressureAsync();
|
||||
Task<float> ReadPressureAsync(int stationId); // 按工位读取压力
|
||||
Task<float> ReadWetFlowAsync();
|
||||
Task<float> ReadDryFlowAsync();
|
||||
Task WriteCoilAsync(ushort coilAddress, bool value); // 写线圈
|
||||
Task WriteRegisterAsync(ushort registerAddress, ushort value); // 写寄存器
|
||||
|
||||
Task<bool> ReadCoilAsync(ushort coilAddress); // 新增:读取线圈状态
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,8 @@
|
||||
new TestLiquid { Name = "水", SurfaceTension = 72.0 },
|
||||
new TestLiquid { Name = "石油馏分", SurfaceTension = 30.0 },
|
||||
new TestLiquid { Name = "乙醇", SurfaceTension = 22.3 },
|
||||
new TestLiquid { Name = "液态石蜡", SurfaceTension = 34.7 }
|
||||
new TestLiquid { Name = "液态石蜡", SurfaceTension = 34.7 },
|
||||
new TestLiquid { Name = "BSD16", SurfaceTension = 16.0 } // 新增
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -56,6 +56,41 @@ namespace MembranePoreTester.Communication
|
||||
public async Task<float> ReadDryFlowAsync() =>
|
||||
await ReadFloatAsync(_config.DryFlowRegister) * (float)_config.DryFlowFactor;
|
||||
|
||||
|
||||
public async Task WriteCoilAsync(ushort coilAddress, bool value)
|
||||
{
|
||||
await EnsureConnectedAsync();
|
||||
await _master.WriteSingleCoilAsync(_config.SlaveId, coilAddress, value);
|
||||
}
|
||||
|
||||
public async Task WriteRegisterAsync(ushort registerAddress, ushort value)
|
||||
{
|
||||
await EnsureConnectedAsync();
|
||||
await _master.WriteSingleRegisterAsync(_config.SlaveId, registerAddress, value);
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> ReadCoilAsync(ushort coilAddress)
|
||||
{
|
||||
await EnsureConnectedAsync();
|
||||
bool[] result = await _master.ReadCoilsAsync(_config.SlaveId, coilAddress, 1);
|
||||
return result[0];
|
||||
}
|
||||
|
||||
// 新增读取压力(根据工位)
|
||||
public async Task<float> ReadPressureAsync(int stationId)
|
||||
{
|
||||
ushort startAddress = stationId switch
|
||||
{
|
||||
1 => _config.PressureRegisterStation1,
|
||||
2 => _config.PressureRegisterStation2,
|
||||
3 => _config.PressureRegisterStation3,
|
||||
_ => throw new ArgumentException("Invalid station")
|
||||
};
|
||||
return await ReadFloatAsync(startAddress);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_master?.Dispose();
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace MembranePoreTester.ViewModels
|
||||
{
|
||||
try
|
||||
{
|
||||
float rawPressure = await _plcService.ReadPressureAsync();
|
||||
float rawPressure = await _plcService.ReadPressureAsync(StationId);
|
||||
Record.BubblePointPressure = rawPressure * _plcConfig.PressureFactor;
|
||||
OnPropertyChanged(nameof(Record.BubblePointPressure));
|
||||
}
|
||||
@@ -127,6 +127,13 @@ namespace MembranePoreTester.ViewModels
|
||||
ReportGenerator.GenerateBubblePointReport(Record);
|
||||
}
|
||||
|
||||
public void UpdateBubblePointPressure(double pressure)
|
||||
{
|
||||
Record.BubblePointPressure = pressure;
|
||||
OnPropertyChanged(nameof(Record.BubblePointPressure));
|
||||
OnPropertyChanged(nameof(MaxPoreSize)); // 最大孔径依赖于压力
|
||||
}
|
||||
|
||||
|
||||
|
||||
private int _stationId;
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using MembranePoreTester.Communication;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel; // 用于 PropertyChanged
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace MembranePoreTester.ViewModels
|
||||
{
|
||||
@@ -6,24 +11,137 @@ namespace MembranePoreTester.ViewModels
|
||||
{
|
||||
public ObservableCollection<StationItem> Stations { get; } = new();
|
||||
|
||||
public class StationItem : ViewModelBase
|
||||
{
|
||||
private readonly IPlcService _plcService;
|
||||
private readonly PlcConfiguration _plcConfig;
|
||||
private bool _isPressing;
|
||||
private string _pressButtonText = "加压";
|
||||
private string _highLowPressure = "低压";
|
||||
private bool _enableStatus; // M21 状态
|
||||
|
||||
public string Name { get; set; }
|
||||
public BubblePointViewModel BubblePointVM { get; set; }
|
||||
public PoreDistributionViewModel PoreDistributionVM { get; set; }
|
||||
public int StationId { get; set; }
|
||||
|
||||
public string HighLowPressure
|
||||
{
|
||||
get => _highLowPressure;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _highLowPressure, value))
|
||||
{
|
||||
// 当选择变化时,写入 PLC 压力模式寄存器
|
||||
Task.Run(async () => await WritePressureModeAsync(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string PressButtonText
|
||||
{
|
||||
get => _pressButtonText;
|
||||
set => SetProperty(ref _pressButtonText, value);
|
||||
}
|
||||
|
||||
// 使能状态(只读)
|
||||
public bool EnableStatus
|
||||
{
|
||||
get => _enableStatus;
|
||||
private set => SetProperty(ref _enableStatus, value);
|
||||
}
|
||||
// 使能状态显示文本
|
||||
public string EnableStatusText => EnableStatus ? "运行中" : "未启动";
|
||||
|
||||
// 使能状态显示颜色(绿色表示运行中,灰色表示未启动)
|
||||
public string EnableStatusColor => EnableStatus ? "Green" : "Gray";
|
||||
|
||||
// 定时器,用于轮询 M21 状态
|
||||
private System.Windows.Threading.DispatcherTimer _timer;
|
||||
|
||||
public ICommand PressCommand { get; }
|
||||
//public ICommand BurstCommand { get; }
|
||||
public ICommand StartCommand { get; }
|
||||
public ICommand StopCommand { get; }
|
||||
public ICommand EnableCommand { get; } // 备用,但可以使用复选框直接绑定
|
||||
|
||||
public StationItem()
|
||||
{
|
||||
_plcService = App.PlcService;
|
||||
_plcConfig = App.PlcConfig;
|
||||
|
||||
PressCommand = new RelayCommand(async () => await TogglePressAsync());
|
||||
//BurstCommand = new RelayCommand(async () => await ReadBurstPressureAsync());
|
||||
StartCommand = new RelayCommand(async () => await WriteCoilAsync(_plcConfig.StartCoil, true));
|
||||
StopCommand = new RelayCommand(async () => await WriteCoilAsync(_plcConfig.StopCoil, true));
|
||||
// 启动定时器,每秒读取一次 M21 状态
|
||||
_timer = new System.Windows.Threading.DispatcherTimer();
|
||||
_timer.Interval = TimeSpan.FromSeconds(1);
|
||||
_timer.Tick += async (s, e) => await ReadEnableStatusAsync();
|
||||
_timer.Start();
|
||||
}
|
||||
|
||||
private async Task TogglePressAsync()
|
||||
{
|
||||
_isPressing = !_isPressing;
|
||||
await WriteCoilAsync(_plcConfig.PressCoil, _isPressing);
|
||||
PressButtonText = _isPressing ? "停止加压" : "加压";
|
||||
}
|
||||
|
||||
|
||||
private async Task ReadEnableStatusAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
bool status = await _plcService.ReadCoilAsync(_plcConfig.EnableCoil); // 读取 M21
|
||||
EnableStatus = status;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 读取出错时保持原状态或显示错误
|
||||
System.Diagnostics.Debug.WriteLine($"读取使能状态失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task WriteCoilAsync(ushort coil, bool value)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _plcService.WriteCoilAsync(coil, value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"写线圈失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task WritePressureModeAsync(string mode)
|
||||
{
|
||||
ushort val = mode == "高压" ? (ushort)1 : (ushort)0;
|
||||
try
|
||||
{
|
||||
await _plcService.WriteRegisterAsync(_plcConfig.PressureModeRegister, val);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"写压力模式失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
for (int i = 1; i <= 3; i++)
|
||||
{
|
||||
Stations.Add(new StationItem
|
||||
var station = new StationItem
|
||||
{
|
||||
Name = $"工位 {i}",
|
||||
BubblePointVM = new BubblePointViewModel { StationId = i },
|
||||
PoreDistributionVM = new PoreDistributionViewModel { StationId = i }
|
||||
});
|
||||
PoreDistributionVM = new PoreDistributionViewModel { StationId = i },
|
||||
StationId = i
|
||||
};
|
||||
Stations.Add(station);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class StationItem
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public BubblePointViewModel BubblePointVM { get; set; }
|
||||
public PoreDistributionViewModel PoreDistributionVM { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,7 @@ namespace MembranePoreTester.ViewModels
|
||||
try
|
||||
{
|
||||
// 始终读取压力
|
||||
float rawPressure = await _plcService.ReadPressureAsync();
|
||||
float rawPressure = await _plcService.ReadPressureAsync(StationId);
|
||||
double pressure = rawPressure * _plcConfig.PressureFactor;
|
||||
|
||||
if (SelectedDataPoint != null)
|
||||
|
||||
97
ViewModels/StationViewModel.cs
Normal file
97
ViewModels/StationViewModel.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using System.Windows.Input;
|
||||
using MembranePoreTester.Communication;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace MembranePoreTester.ViewModels
|
||||
{
|
||||
public class StationViewModel : ViewModelBase
|
||||
{
|
||||
private readonly IPlcService _plcService;
|
||||
private readonly PlcConfiguration _plcConfig;
|
||||
private bool _isPressing;
|
||||
private string _pressButtonText = "加压";
|
||||
private string _highLowPressure = "低压";
|
||||
private bool _enableChecked;
|
||||
|
||||
public int StationId { get; set; }
|
||||
|
||||
public BubblePointViewModel BubblePointVM { get; } = new();
|
||||
public PoreDistributionViewModel PoreDistributionVM { get; } = new();
|
||||
|
||||
public string HighLowPressure
|
||||
{
|
||||
get => _highLowPressure;
|
||||
set => SetProperty(ref _highLowPressure, value);
|
||||
}
|
||||
|
||||
public string PressButtonText
|
||||
{
|
||||
get => _pressButtonText;
|
||||
set => SetProperty(ref _pressButtonText, value);
|
||||
}
|
||||
|
||||
public bool EnableChecked
|
||||
{
|
||||
get => _enableChecked;
|
||||
set => SetProperty(ref _enableChecked, value);
|
||||
}
|
||||
|
||||
public ICommand PressCommand { get; }
|
||||
public ICommand BurstCommand { get; }
|
||||
public ICommand StartCommand { get; }
|
||||
public ICommand StopCommand { get; }
|
||||
public ICommand EnableCommand { get; } // 用于使能复选框
|
||||
|
||||
public StationViewModel()
|
||||
{
|
||||
_plcService = App.PlcService;
|
||||
_plcConfig = App.PlcConfig;
|
||||
BubblePointVM.StationId = StationId;
|
||||
PoreDistributionVM.StationId = StationId;
|
||||
// 初始化按钮文字
|
||||
_pressButtonText = "加压"; // 直接设置字段,避免触发属性通知循环
|
||||
PressButtonText = "加压"; // 或者通过属性设置
|
||||
System.Diagnostics.Debug.WriteLine($"工位{StationId} PressButtonText初始值: {PressButtonText}");
|
||||
PressCommand = new RelayCommand(async () => await TogglePressAsync());
|
||||
BurstCommand = new RelayCommand(async () => await ReadBurstPressureAsync());
|
||||
StartCommand = new RelayCommand(async () => await WriteCoilAsync(_plcConfig.StartCoil, true));
|
||||
StopCommand = new RelayCommand(async () => await WriteCoilAsync(_plcConfig.StopCoil, true));
|
||||
// 使能复选框点击时写入对应线圈
|
||||
EnableCommand = new RelayCommand(async () => await WriteCoilAsync(_plcConfig.EnableCoil, EnableChecked));
|
||||
}
|
||||
|
||||
private async Task TogglePressAsync()
|
||||
{
|
||||
_isPressing = !_isPressing;
|
||||
await WriteCoilAsync(_plcConfig.PressCoil, _isPressing);
|
||||
PressButtonText = _isPressing ? "停止加压" : "加压";
|
||||
}
|
||||
|
||||
private async Task ReadBurstPressureAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
float pressure = await ((ModbusTcpPlcService)_plcService).ReadPressureAsync(StationId);
|
||||
BubblePointVM.UpdateBubblePointPressure(pressure * _plcConfig.PressureFactor);
|
||||
MessageBox.Show($"涨破压力: {pressure} {BubblePointVM.Record.PressureUnit}", "提示");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"读取压力失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task WriteCoilAsync(ushort coil, bool value)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ((ModbusTcpPlcService)_plcService).WriteCoilAsync(coil, value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"写线圈失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,8 +54,8 @@
|
||||
<Label Content="表面张力(mN/m):"/>
|
||||
<TextBox Text="{Binding CustomSurfaceTension}" Width="100" Margin="5"/>
|
||||
</StackPanel>
|
||||
<Label Content="生产厂家:" Margin="5"/>
|
||||
<TextBox Text="{Binding Record.LiquidManufacturer}" Margin="5"/>
|
||||
<!--<Label Content="生产厂家:" Margin="5"/>
|
||||
<TextBox Text="{Binding Record.LiquidManufacturer}" Margin="5"/>-->
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBox Text="{Binding Record.BubblePointPressure}" Width="150" Margin="5"/>
|
||||
|
||||
<Button Content="读取PLC" Command="{Binding ReadPlcCommand}" Padding="10,5" Margin="5"/>
|
||||
<Button Content="涨破" Command="{Binding ReadPlcCommand}" Padding="10,5" Margin="5"/>
|
||||
<ComboBox ItemsSource="{Binding PressureUnits}" SelectedItem="{Binding Record.PressureUnit}" Width="80" Margin="5"/>
|
||||
<Button Content="计算最大孔径" Command="{Binding CalculateCommand}" Padding="10,5" Margin="5"/>
|
||||
</StackPanel>
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
<Window.DataContext>
|
||||
<viewModels:MainViewModel />
|
||||
</Window.DataContext>
|
||||
|
||||
|
||||
<DockPanel LastChildFill="True">
|
||||
<DockPanel>
|
||||
<!-- 全局历史记录按钮 -->
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="5">
|
||||
<Button Content="历史记录" Click="OpenHistory_Click" Padding="10,5" Margin="5"/>
|
||||
</StackPanel>
|
||||
|
||||
<TabControl ItemsSource="{Binding Stations}">
|
||||
<!-- 工位选项卡 -->
|
||||
<TabControl x:Name="stationTabControl" ItemsSource="{Binding Stations}">
|
||||
<TabControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Name}"/>
|
||||
@@ -24,42 +24,43 @@
|
||||
</TabControl.ItemTemplate>
|
||||
<TabControl.ContentTemplate>
|
||||
<DataTemplate>
|
||||
<!-- 每个工位内部再嵌套一个TabControl切换测试类型 -->
|
||||
<TabControl>
|
||||
<TabItem Header="泡点法测试最大孔径">
|
||||
<local:BubblePointView DataContext="{Binding BubblePointVM}"/>
|
||||
</TabItem>
|
||||
<TabItem Header="孔分布测试">
|
||||
<local:PoreDistributionView DataContext="{Binding PoreDistributionVM}"/>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
<DockPanel>
|
||||
<!-- 工位控制栏 -->
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="5">
|
||||
<ComboBox SelectedItem="{Binding HighLowPressure}" Width="80" Margin="5">
|
||||
<ComboBoxItem IsSelected="True">低压</ComboBoxItem>
|
||||
<ComboBoxItem>高压</ComboBoxItem>
|
||||
</ComboBox>
|
||||
<Button Content="启动" Command="{Binding StartCommand}" Width="80" Margin="5"/>
|
||||
<Button Content="停止" Command="{Binding StopCommand}" Width="80" Margin="5"/>
|
||||
|
||||
|
||||
<Button Content="{Binding PressButtonText}" Command="{Binding PressCommand}" Width="80" Margin="5"/>
|
||||
<!--<Button Content="涨破" Command="{Binding BurstCommand}" Width="80" Margin="5"/>-->
|
||||
|
||||
<!--<CheckBox Content="使能" IsChecked="{Binding EnableChecked}" Margin="5"/>-->
|
||||
<!-- 原来的复选框 -->
|
||||
<!-- <CheckBox Content="使能" IsChecked="{Binding EnableChecked}" Margin="5"/> -->
|
||||
|
||||
<!-- 替换为状态指示灯 -->
|
||||
<StackPanel Orientation="Horizontal" Margin="5">
|
||||
<Ellipse Width="12" Height="12" Fill="{Binding EnableStatusColor}" Margin="2"/>
|
||||
<TextBlock Text="{Binding EnableStatusText}" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 测试类型选项卡 -->
|
||||
<TabControl>
|
||||
<TabItem Header="泡点法测试最大孔径">
|
||||
<local:BubblePointView DataContext="{Binding BubblePointVM}"/>
|
||||
</TabItem>
|
||||
<TabItem Header="孔分布测试">
|
||||
<local:PoreDistributionView DataContext="{Binding PoreDistributionVM}"/>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</DockPanel>
|
||||
</DataTemplate>
|
||||
</TabControl.ContentTemplate>
|
||||
</TabControl>
|
||||
</DockPanel>
|
||||
</Window>
|
||||
|
||||
|
||||
|
||||
|
||||
<!--<Window x:Class="MembranePoreTester.Views.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:MembranePoreTester.Views"
|
||||
Title="膜孔径测试系统 (GB/T 32361-2015)"
|
||||
Width="1024" Height="768"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<TabControl>
|
||||
<TabItem Header="泡点法测试最大孔径">
|
||||
<local:BubblePointView/>
|
||||
|
||||
</TabItem>
|
||||
<TabItem Header="孔分布测试">
|
||||
<local:PoreDistributionView/>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</Window>-->
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -35,8 +35,9 @@ namespace MembranePoreTester.Views
|
||||
var mainVM = DataContext as MainViewModel;
|
||||
if (mainVM == null) return;
|
||||
|
||||
// 获取当前选中的工位(可选)
|
||||
int currentStation = 1; // 可获取当前Tab索引+1
|
||||
// 获取当前选中的工位索引(假设选项卡控件是 TabControl,名称为 stationTabControl)
|
||||
// 需要在 XAML 中为 TabControl 设置 x:Name="stationTabControl"
|
||||
int currentStation = stationTabControl.SelectedIndex + 1; // 假设索引从0开始
|
||||
var historyWin = new HistoryWindow { SelectedStation = currentStation };
|
||||
historyWin.ShowDialog();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
{
|
||||
"PlcSettings": {
|
||||
"IpAddress": "192.168.1.100",
|
||||
"IpAddress": "192.168.1.10",
|
||||
"Port": 502,
|
||||
"SlaveId": 1,
|
||||
"PressureRegister": 0,
|
||||
"PressureRegisterStation1": 6,
|
||||
"PressureRegisterStation2": 8,
|
||||
"PressureRegisterStation3": 10,
|
||||
"PressureModeRegister": 200, // 高压/低压选择寄存器(0=低压,1=高压)
|
||||
"PressCoil": 100, // 加压线圈(M100)
|
||||
"StartCoil": 20, // 启动线圈(M20)
|
||||
"EnableCoil": 21, // 使能线圈(M21)
|
||||
"StopCoil": 7, // 停止线圈(M7)
|
||||
"PressureFactor": 1.0,
|
||||
"WetFlowRegister": 2,
|
||||
"DryFlowRegister": 4,
|
||||
"PressureFactor": 1.0,
|
||||
"WetFlowFactor": 1.0,
|
||||
"DryFlowFactor": 1.0
|
||||
}
|
||||
|
||||
BIN
分离膜孔径测试仪.gxw
Normal file
BIN
分离膜孔径测试仪.gxw
Normal file
Binary file not shown.
@@ -16,6 +16,7 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.3" />
|
||||
<PackageReference Include="NModbus4.NetCore" Version="4.0.0" />
|
||||
<PackageReference Include="SunnyUI" Version="3.9.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user