diff --git a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/App.axaml.cs b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/App.axaml.cs
index 6fcaf5b..5a591f7 100644
--- a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/App.axaml.cs
+++ b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/App.axaml.cs
@@ -5,12 +5,17 @@ using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml;
using Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModels;
using Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Views;
+using Serilog;
+using System;
using System.Linq;
+using System.Threading.Tasks;
namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance
{
public partial class App : Application
{
+ private static bool exceptionHandlersRegistered;
+
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
@@ -18,6 +23,8 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance
public override void OnFrameworkInitializationCompleted()
{
+ RegisterExceptionHandlers();
+
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow
@@ -28,5 +35,33 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance
base.OnFrameworkInitializationCompleted();
}
+
+ private static void RegisterExceptionHandlers()
+ {
+ if (exceptionHandlersRegistered)
+ {
+ return;
+ }
+
+ AppDomain.CurrentDomain.UnhandledException += (_, args) =>
+ {
+ if (args.ExceptionObject is Exception exception)
+ {
+ Log.Fatal(exception, "捕获到 AppDomain 未处理异常,IsTerminating={IsTerminating}", args.IsTerminating);
+ }
+ else
+ {
+ Log.Fatal("捕获到 AppDomain 未处理异常:{ExceptionObject}", args.ExceptionObject);
+ }
+ };
+
+ TaskScheduler.UnobservedTaskException += (_, args) =>
+ {
+ Log.Error(args.Exception, "捕获到未观察的后台任务异常");
+ args.SetObserved();
+ };
+
+ exceptionHandlersRegistered = true;
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Footwear Test methodsfor wholeshoe Slipresistanceperformance.csproj b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Footwear Test methodsfor wholeshoe Slipresistanceperformance.csproj
index 802a661..b79c0d4 100644
--- a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Footwear Test methodsfor wholeshoe Slipresistanceperformance.csproj
+++ b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Footwear Test methodsfor wholeshoe Slipresistanceperformance.csproj
@@ -25,6 +25,8 @@
+
+
diff --git a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Models/AdcZeroCalibration.cs b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Models/AdcZeroCalibration.cs
new file mode 100644
index 0000000..71ed377
--- /dev/null
+++ b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Models/AdcZeroCalibration.cs
@@ -0,0 +1,7 @@
+namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Models
+{
+ public sealed record AdcZeroCalibration(
+ int NormalPressureZero,
+ int FrictionZero1,
+ int FrictionZero2);
+}
diff --git a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Models/PlcDeviceParameters.cs b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Models/PlcDeviceParameters.cs
new file mode 100644
index 0000000..a19f3a8
--- /dev/null
+++ b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Models/PlcDeviceParameters.cs
@@ -0,0 +1,7 @@
+namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Models
+{
+ public sealed record PlcDeviceParameters(
+ double ManualSpeed,
+ double ManualDisplacement,
+ double TestSpeed);
+}
diff --git a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Program.cs b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Program.cs
index aa9dd7f..104b674 100644
--- a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Program.cs
+++ b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Program.cs
@@ -1,18 +1,35 @@
-using Avalonia;
+using Avalonia;
+using Serilog;
using System;
+using System.IO;
namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance
{
internal sealed class Program
{
- // Initialization code. Don't use any Avalonia, third-party APIs or any
- // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
- // yet and stuff might break.
[STAThread]
- public static void Main(string[] args) => BuildAvaloniaApp()
- .StartWithClassicDesktopLifetime(args);
+ public static int Main(string[] args)
+ {
+ ConfigureLogging();
+
+ try
+ {
+ Log.Information("鞋类整鞋防滑性能试验程序启动");
+ BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ Log.Fatal(ex, "程序发生致命异常并退出");
+ return 1;
+ }
+ finally
+ {
+ Log.Information("鞋类整鞋防滑性能试验程序退出");
+ Log.CloseAndFlush();
+ }
+ }
- // Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure()
.UsePlatformDetect()
@@ -21,5 +38,27 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance
#endif
.WithInterFont()
.LogToTrace();
+
+ private static void ConfigureLogging()
+ {
+ var logDirectory = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+ "FootwearSlipResistance",
+ "Logs");
+ Directory.CreateDirectory(logDirectory);
+
+ Log.Logger = new LoggerConfiguration()
+ .MinimumLevel.Debug()
+ .WriteTo.File(
+ Path.Combine(logDirectory, "app-.log"),
+ rollingInterval: RollingInterval.Day,
+ retainedFileCountLimit: 30,
+ fileSizeLimitBytes: 20 * 1024 * 1024,
+ rollOnFileSizeLimit: true,
+ shared: true,
+ flushToDiskInterval: TimeSpan.FromSeconds(1),
+ outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
+ .CreateLogger();
+ }
}
}
diff --git a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Services/SlipExcelExportService.cs b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Services/SlipExcelExportService.cs
index c3793bc..c548523 100644
--- a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Services/SlipExcelExportService.cs
+++ b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Services/SlipExcelExportService.cs
@@ -2,6 +2,7 @@ using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Models;
+using Serilog;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -28,6 +29,13 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Services
: report.TestNumber);
var path = Path.Combine(directory, $"{safeNumber}_防滑性能测试报告.xlsx");
+ Log.Information(
+ "开始导出防滑性能 Excel:TestNumber={TestNumber}, ResultCount={ResultCount}, PointCount={PointCount}, Path={Path}",
+ report.TestNumber,
+ report.Results.Count,
+ report.Points.Count,
+ path);
+
using var document = SpreadsheetDocument.Create(path, SpreadsheetDocumentType.Workbook);
var workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
@@ -38,6 +46,7 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Services
AddDataSheet(workbookPart, sheets, 3, report.Points);
workbookPart.Workbook.Save();
+ Log.Information("防滑性能 Excel 导出完成:Path={Path}", path);
return path;
}
diff --git a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Services/SlipResistanceDeviceService.cs b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Services/SlipResistanceDeviceService.cs
index 3e0df88..5bc891f 100644
--- a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Services/SlipResistanceDeviceService.cs
+++ b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Services/SlipResistanceDeviceService.cs
@@ -1,6 +1,7 @@
using Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Models;
using NModbus;
using NModbus.IO;
+using Serilog;
using System;
using System.Globalization;
using System.IO.Ports;
@@ -37,10 +38,16 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Services
private IModbusSerialMaster? adcMaster;
private DeviceSettings settings = new("0.00", "0.00", "0.30", "0", "0.00", "0", "0.00", "0", "0.00", "COM7", "COM8", 115200);
private SlipDeviceSnapshot snapshot = SlipDeviceSnapshot.Offline();
+ private DateTime lastAdcErrorLoggedAt = DateTime.MinValue;
+ private DateTime lastPlcErrorLoggedAt = DateTime.MinValue;
private double verticalLoadN;
private double horizontalFrictionN;
private double displacementMm;
+ private int pressureRawValue;
+ private int frictionRawValue1;
+ private int frictionRawValue2;
+ private bool hasAdcRawValues;
private bool isTestRunning;
private bool isResetting;
private bool isConnected;
@@ -64,6 +71,13 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Services
try
{
+ Log.Information(
+ "启动防滑测试设备连接:PLC={PlcPort}, ADC={AdcPort}, BaudRate={BaudRate}, SlaveId={SlaveId}",
+ settings.PlcPortName,
+ settings.AdcPortName,
+ settings.BaudRate,
+ SlaveId);
+
plcPort = CreatePort(settings.PlcPortName, settings.BaudRate);
adcPort = CreatePort(settings.AdcPortName, settings.BaudRate);
plcPort.Open();
@@ -79,9 +93,16 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Services
SetConnected(true, string.Empty);
adcTask = Task.Run(() => PollAdc(token), token);
plcTask = Task.Run(() => PollPlc(token), token);
+ Log.Information("防滑测试设备连接成功,ADC/PLC 轮询已启动");
}
catch (Exception ex)
{
+ Log.Error(
+ ex,
+ "防滑测试设备连接失败:PLC={PlcPort}, ADC={AdcPort}, BaudRate={BaudRate}",
+ settings.PlcPortName,
+ settings.AdcPortName,
+ settings.BaudRate);
SetConnected(false, ex.Message);
Stop();
}
@@ -90,6 +111,14 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Services
public void UpdateSettings(DeviceSettings deviceSettings)
{
settings = deviceSettings;
+ Log.Debug(
+ "设备设置已更新:PLC={PlcPort}, ADC={AdcPort}, BaudRate={BaudRate}, TestSpeed={TestSpeed}, ManualSpeed={ManualSpeed}, ManualDisplacement={ManualDisplacement}",
+ settings.PlcPortName,
+ settings.AdcPortName,
+ settings.BaudRate,
+ settings.TestSpeed,
+ settings.ManualSpeed,
+ settings.ManualDisplacement);
}
public Task PulseStartTestAsync() => PulseCoilAsync(StartTestCoil);
@@ -120,8 +149,50 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Services
public Task WriteManualDisplacementAsync(double value) => WriteFloatRegisterAsync(ManualDisplacementRegister, value);
+ public Task ReadDeviceParametersAsync() =>
+ Task.Run(() =>
+ {
+ var master = plcMaster ?? throw new InvalidOperationException("PLC 未连接");
+ var manualSpeedWords = master.ReadHoldingRegisters(SlaveId, ManualSpeedRegister, 2);
+ var manualDisplacementWords = master.ReadHoldingRegisters(SlaveId, ManualDisplacementRegister, 2);
+ var testSpeedWords = master.ReadHoldingRegisters(SlaveId, TestSpeedRegister, 2);
+ var parameters = new PlcDeviceParameters(
+ UshortToFloat(manualSpeedWords[1], manualSpeedWords[0]),
+ UshortToFloat(manualDisplacementWords[1], manualDisplacementWords[0]),
+ UshortToFloat(testSpeedWords[1], testSpeedWords[0]));
+
+ Log.Information(
+ "读取 PLC 参数完成:D{ManualSpeedRegister}={ManualSpeed:F3}, D{ManualDisplacementRegister}={ManualDisplacement:F3}, D{TestSpeedRegister}={TestSpeed:F3}",
+ ManualSpeedRegister,
+ parameters.ManualSpeed,
+ ManualDisplacementRegister,
+ parameters.ManualDisplacement,
+ TestSpeedRegister,
+ parameters.TestSpeed);
+ return parameters;
+ });
+
+ public AdcZeroCalibration CaptureCurrentAdcZero()
+ {
+ lock (sync)
+ {
+ if (!hasAdcRawValues)
+ {
+ throw new InvalidOperationException("ADC 尚未读取到有效原始数据");
+ }
+
+ Log.Information(
+ "采集 ADC 零点:NormalPressureZero={NormalPressureZero}, FrictionZero1={FrictionZero1}, FrictionZero2={FrictionZero2}",
+ pressureRawValue,
+ frictionRawValue1,
+ frictionRawValue2);
+ return new AdcZeroCalibration(pressureRawValue, frictionRawValue1, frictionRawValue2);
+ }
+ }
+
public void Stop()
{
+ Log.Information("停止防滑测试设备连接与轮询");
cancellationTokenSource?.Cancel();
try
@@ -209,6 +280,10 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Services
lock (sync)
{
+ pressureRawValue = pressureRaw;
+ frictionRawValue1 = friction1Raw;
+ frictionRawValue2 = friction2Raw;
+ hasAdcRawValues = true;
verticalLoadN = pressure;
horizontalFrictionN = friction;
lastError = string.Empty;
@@ -220,6 +295,7 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Services
}
catch (Exception ex)
{
+ LogPollingError("ADC", ex, ref lastAdcErrorLoggedAt);
SetConnected(false, ex.Message);
Thread.Sleep(250);
}
@@ -255,6 +331,7 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Services
}
catch (Exception ex)
{
+ LogPollingError("PLC", ex, ref lastPlcErrorLoggedAt);
SetConnected(false, ex.Message);
Thread.Sleep(250);
}
@@ -263,6 +340,7 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Services
private async Task PulseCoilAsync(ushort coil)
{
+ Log.Information("发送 PLC 脉冲线圈:M{Coil}", coil);
await WriteCoilAsync(coil, true);
await Task.Delay(80);
await WriteCoilAsync(coil, false);
@@ -274,6 +352,7 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Services
var master = plcMaster ?? throw new InvalidOperationException("PLC 未连接");
var current = master.ReadCoils(SlaveId, coil, 1)[0];
master.WriteSingleCoil(SlaveId, coil, !current);
+ Log.Information("切换 PLC 线圈:M{Coil}, Before={Before}, After={After}", coil, current, !current);
});
private Task WriteCoilAsync(ushort coil, bool value) =>
@@ -281,6 +360,7 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Services
{
var master = plcMaster ?? throw new InvalidOperationException("PLC 未连接");
master.WriteSingleCoil(SlaveId, coil, value);
+ Log.Debug("写入 PLC 线圈:M{Coil}={Value}", coil, value);
});
private Task WriteFloatRegisterAsync(ushort register, double value) =>
@@ -288,8 +368,27 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.Services
{
var master = plcMaster ?? throw new InvalidOperationException("PLC 未连接");
master.WriteMultipleRegisters(SlaveId, register, SplitFloatToUShortArray((float)value));
+ Log.Information("写入 PLC 浮点寄存器:D{Register}={Value:F3}", register, value);
});
+ private void LogPollingError(string source, Exception exception, ref DateTime lastLoggedAt)
+ {
+ var now = DateTime.UtcNow;
+ if (now - lastLoggedAt < TimeSpan.FromSeconds(5))
+ {
+ return;
+ }
+
+ lastLoggedAt = now;
+ Log.Error(
+ exception,
+ "{Source} 轮询失败:PLC={PlcPort}, ADC={AdcPort}, BaudRate={BaudRate}",
+ source,
+ settings.PlcPortName,
+ settings.AdcPortName,
+ settings.BaudRate);
+ }
+
private void SetConnected(bool connected, string error)
{
lock (sync)
diff --git a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/ViewModels/MainWindowViewModel.cs b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/ViewModels/MainWindowViewModel.cs
index 5bc6674..aeb3188 100644
--- a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/ViewModels/MainWindowViewModel.cs
+++ b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/ViewModels/MainWindowViewModel.cs
@@ -7,6 +7,7 @@ using LiveChartsCore;
using LiveChartsCore.Defaults;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Painting;
+using Serilog;
using SkiaSharp;
using System;
using System.Collections.Generic;
@@ -215,6 +216,7 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModel
public MainWindowViewModel()
{
+ Log.Information("初始化主页面 ViewModel");
Series =
[
CreateLineSeries("垂直压力(N)", verticalLoadPoints, "#DC2626", 0, 0.65),
@@ -226,6 +228,7 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModel
LoadDeviceSettings();
UpdateTargetLoad();
deviceService.Start(CurrentSettings());
+ _ = LoadPlcParametersAsync();
refreshTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(33) };
refreshTimer.Tick += (_, _) => RefreshFromDevice();
@@ -263,6 +266,7 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModel
var points = currentRun.Count > 0 ? currentRun.ToList() : lastCompletedRun;
if (points.Count == 0)
{
+ Log.Warning("请求导出 Excel 时没有可导出的实时采样数据:TestNumber={TestNumber}", TestNumber);
CurrentStatus = "没有可导出的实时采样数据,请先完成一次测试";
return;
}
@@ -292,6 +296,7 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModel
}
catch (Exception ex)
{
+ Log.Error(ex, "Excel 导出失败:TestNumber={TestNumber}, PointCount={PointCount}", TestNumber, points.Count);
CurrentStatus = $"Excel 导出失败:{ex.Message}";
}
}
@@ -336,6 +341,41 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModel
deviceService.UpdateSettings(CurrentSettings());
}
+ [RelayCommand]
+ private void CalibrateNormalPressureZero()
+ {
+ try
+ {
+ var zero = deviceService.CaptureCurrentAdcZero();
+ NormalPressureZero = zero.NormalPressureZero.ToString(CultureInfo.InvariantCulture);
+ SaveAndApplySettings();
+ CurrentStatus = "正压力零点已按当前 ADC 原始值采集";
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "正压力零点采集失败");
+ CurrentStatus = $"正压力零点采集失败:{ex.Message}";
+ }
+ }
+
+ [RelayCommand]
+ private void CalibrateFrictionZero()
+ {
+ try
+ {
+ var zero = deviceService.CaptureCurrentAdcZero();
+ FrictionZero1 = zero.FrictionZero1.ToString(CultureInfo.InvariantCulture);
+ FrictionZero2 = zero.FrictionZero2.ToString(CultureInfo.InvariantCulture);
+ SaveAndApplySettings();
+ CurrentStatus = "摩擦零点已按当前 ADC 原始值采集";
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "摩擦零点采集失败");
+ CurrentStatus = $"摩擦零点采集失败:{ex.Message}";
+ }
+ }
+
partial void OnUploadProgressChanged(int value) => OnPropertyChanged(nameof(UploadProgressText));
partial void OnManualSpeedChanged(string value)
@@ -434,6 +474,7 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModel
runStopwatch.Restart();
UploadProgress = 0;
CurrentStatus = "测试运行:按标准采集垂直载荷、摩擦力、位移与摩擦系数";
+ Log.Information("测试开始:TestNumber={TestNumber}, TargetLoad={TargetLoad}, TestSpeed={TestSpeed}", TestNumber, TargetLoadText, TestSpeedText);
}
private void RecordPoint(SlipDeviceSnapshot device)
@@ -466,6 +507,7 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModel
runStopwatch.Stop();
if (currentRun.Count < 3)
{
+ Log.Warning("测试停止但采样点不足:TestNumber={TestNumber}, PointCount={PointCount}", TestNumber, currentRun.Count);
CurrentStatus = "测试已停止,但有效采样点不足,未生成结果";
return;
}
@@ -503,6 +545,13 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModel
CurrentStatus = verdict == "有效"
? "测试完成:已按标准生成静/动摩擦系数"
: "测试完成:最近三次结果差异超过 10%,建议重新测试";
+ Log.Information(
+ "测试完成:TestNumber={TestNumber}, PointCount={PointCount}, StaticCoefficient={StaticCoefficient:F3}, DynamicCoefficient={DynamicCoefficient:F3}, Verdict={Verdict}",
+ TestNumber,
+ currentRun.Count,
+ staticCoefficientValue,
+ dynamicCoefficientValue,
+ verdict);
}
private bool NeedsRetest(double staticCoefficientValue, double dynamicCoefficientValue)
@@ -571,6 +620,7 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModel
}
catch (Exception ex)
{
+ Log.Error(ex, "设备指令失败:{SuccessMessage}", successMessage);
CurrentStatus = $"设备指令失败:{ex.Message}";
}
}
@@ -591,6 +641,25 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModel
deviceService.UpdateSettings(CurrentSettings());
}
+ private async Task LoadPlcParametersAsync()
+ {
+ try
+ {
+ var parameters = await deviceService.ReadDeviceParametersAsync();
+ isLoadingDeviceSettings = true;
+ ManualSpeed = parameters.ManualSpeed.ToString("F2", CultureInfo.InvariantCulture);
+ ManualDisplacement = parameters.ManualDisplacement.ToString("F2", CultureInfo.InvariantCulture);
+ TestSpeed = parameters.TestSpeed.ToString("F2", CultureInfo.InvariantCulture);
+ isLoadingDeviceSettings = false;
+ SaveAndApplySettings();
+ }
+ catch (Exception ex)
+ {
+ isLoadingDeviceSettings = false;
+ Log.Warning(ex, "启动时读取 PLC 参数失败,将使用本地保存的设备设置");
+ }
+ }
+
private void LoadDeviceSettings()
{
if (!File.Exists(DeviceSettingsPath))
@@ -621,8 +690,9 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModel
AdcPortName = settings.AdcPortName ?? AdcPortName;
BaudRate = settings.BaudRate > 0 ? settings.BaudRate : BaudRate;
}
- catch
+ catch (Exception ex)
{
+ Log.Warning(ex, "读取设备设置失败:Path={Path}", DeviceSettingsPath);
}
finally
{
@@ -643,8 +713,9 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModel
var json = JsonSerializer.Serialize(CurrentSettings(), new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(DeviceSettingsPath, json);
}
- catch
+ catch (Exception ex)
{
+ Log.Warning(ex, "保存设备设置失败:Path={Path}", DeviceSettingsPath);
}
}
diff --git a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Views/MainWindow.axaml b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Views/MainWindow.axaml
index 5eed7ba..56203c1 100644
--- a/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Views/MainWindow.axaml
+++ b/Footwear Test methodsfor wholeshoe Slipresistanceperformance/Views/MainWindow.axaml
@@ -328,7 +328,7 @@
-
+
@@ -432,12 +432,14 @@
+
+