diff --git a/PetWashControl/ViewModels/MainViewModel.cs b/PetWashControl/ViewModels/MainViewModel.cs
index 7460070..7b2fa56 100644
--- a/PetWashControl/ViewModels/MainViewModel.cs
+++ b/PetWashControl/ViewModels/MainViewModel.cs
@@ -136,6 +136,7 @@ public partial class MainViewModel : ObservableObject
private readonly System.Timers.Timer _carouselTimer;
private readonly System.Timers.Timer _clockTimer;
+ private readonly System.Timers.Timer _liquidLevelTimer;
private readonly string[] _carouselImages = { "/Images/dog.png", "/Images/dog1.png", "/Images/dog2.png" };
private int _currentImageIndex = 0;
@@ -189,6 +190,24 @@ public partial class MainViewModel : ObservableObject
});
};
_clockTimer.Start();
+
+ // 初始化液位监测定时器(每30秒更新一次)
+ _liquidLevelTimer = new System.Timers.Timer(30000);
+ _liquidLevelTimer.Elapsed += async (s, e) =>
+ {
+ if (IsModbusConnected)
+ {
+ try
+ {
+ await LoadLiquidLevelsAsync();
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError("定时更新液位失败", ex);
+ }
+ }
+ };
+ _liquidLevelTimer.Start();
}
private void InitializeWashSteps()
@@ -219,10 +238,14 @@ public partial class MainViewModel : ObservableObject
if (modbusConnected)
{
_logger.LogInfo("Modbus TCP 设备连接成功");
+
+ // 从设备读取初始配置参数
+ await LoadDeviceParametersAsync();
}
else
{
- _logger.LogWarning("Modbus TCP 设备连接失败,系统将继续运行但设备控制功能可能不可用");
+ _logger.LogWarning("Modbus TCP 设备连接失败,使用默认配置");
+ LoadDefaultParameters();
}
// 连接 MQTT
@@ -252,6 +275,94 @@ public partial class MainViewModel : ObservableObject
}
}
+ ///
+ /// 从 Modbus 设备读取系统参数
+ ///
+ private async Task LoadDeviceParametersAsync()
+ {
+ try
+ {
+ _logger.LogInfo("正在从设备读取系统参数...");
+
+ // 读取时间参数(D404-D424,共11个寄存器)
+ var timeParams = await _modbusService.ReadHoldingRegistersAsync(404, 11);
+
+ FirstSprayWaterTime = timeParams[0]; // D404 首次喷水时间
+ AfterShampoo1SprayTime = timeParams[1]; // D406 沐浴1后喷水时间
+ AfterShampoo2SprayTime = timeParams[2]; // D408 沐浴2后喷水时间
+ AfterShampoo3SprayTime = timeParams[3]; // D410 沐浴3后喷水时间
+ // D412 清洗笼子喷水(暂不使用)
+ SprayShampoo1Time = timeParams[5]; // D414 喷沐浴露1时间
+ SprayShampoo2Time = timeParams[6]; // D416 喷沐浴露2时间
+ SprayShampoo3Time = timeParams[7]; // D418 喷沐浴露3时间
+ HotAirTime = timeParams[8]; // D420 吹热风时间
+ ColdAirTime = timeParams[9]; // D422 吹冷风时间
+ UvSterilizationTime = timeParams[10]; // D424 紫外线杀菌时间
+
+ _logger.LogInfo($"时间参数读取成功 - 首次喷水:{FirstSprayWaterTime}min, 沐浴1后:{AfterShampoo1SprayTime}min, " +
+ $"沐浴2后:{AfterShampoo2SprayTime}min, 沐浴3后:{AfterShampoo3SprayTime}min, " +
+ $"喷沐浴露1:{SprayShampoo1Time}min, 喷沐浴露2:{SprayShampoo2Time}min, 喷沐浴露3:{SprayShampoo3Time}min, " +
+ $"热风:{HotAirTime}min, 冷风:{ColdAirTime}min, 紫外线:{UvSterilizationTime}min");
+
+ // 读取液位参数
+ await LoadLiquidLevelsAsync();
+
+ StatusMessage = "设备参数加载成功";
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError("读取设备参数失败,使用默认配置", ex);
+ LoadDefaultParameters();
+ StatusMessage = "设备参数读取失败,使用默认配置";
+ }
+ }
+
+ ///
+ /// 读取液位传感器数据
+ ///
+ private async Task LoadLiquidLevelsAsync()
+ {
+ try
+ {
+ // 读取1号液位 (D1280)
+ var level1 = await _modbusService.ReadHoldingRegistersAsync(1280, 1);
+ Shampoo1Level = level1[0];
+
+ // 读取2号液位 (D1330)
+ var level2 = await _modbusService.ReadHoldingRegistersAsync(1330, 1);
+ Shampoo2Level = level2[0];
+
+ // 读取3号液位 (D1380)
+ var level3 = await _modbusService.ReadHoldingRegistersAsync(1380, 1);
+ Shampoo3Level = level3[0];
+
+ _logger.LogInfo($"液位读取成功 - 1号:{Shampoo1Level}%, 2号:{Shampoo2Level}%, 3号:{Shampoo3Level}%");
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError("读取液位失败", ex);
+ }
+ }
+
+ ///
+ /// 加载默认参数
+ ///
+ private void LoadDefaultParameters()
+ {
+ FirstSprayWaterTime = _config.FirstSprayWaterTime;
+ AfterShampoo1SprayTime = _config.AfterShampoo1SprayTime;
+ AfterShampoo2SprayTime = _config.AfterShampoo2SprayTime;
+ AfterShampoo3SprayTime = _config.AfterShampoo3SprayTime;
+ SprayShampoo1Time = _config.SprayShampoo1Time;
+ SprayShampoo2Time = _config.SprayShampoo2Time;
+ SprayShampoo3Time = _config.SprayShampoo3Time;
+ ColdAirTime = _config.ColdAirTime;
+ HotAirTime = _config.HotAirTime;
+ UvSterilizationTime = _config.UvSterilizationTime;
+
+ _logger.LogInfo("已加载默认参数配置");
+ }
+
[RelayCommand]
private async Task LoadPackagesAsync()
{
@@ -323,11 +434,13 @@ public partial class MainViewModel : ObservableObject
}
[RelayCommand]
- private void SaveSettings()
+ private async Task SaveSettingsAsync()
{
try
{
- // 更新配置
+ StatusMessage = "正在保存参数...";
+
+ // 更新本地配置
_config.FirstSprayWaterTime = FirstSprayWaterTime;
_config.AfterShampoo1SprayTime = AfterShampoo1SprayTime;
_config.AfterShampoo2SprayTime = AfterShampoo2SprayTime;
@@ -339,17 +452,68 @@ public partial class MainViewModel : ObservableObject
_config.HotAirTime = HotAirTime;
_config.UvSterilizationTime = UvSterilizationTime;
- _logger.LogInfo($"系统参数已保存 - 首次喷水:{FirstSprayWaterTime}min, 沐浴1后喷水:{AfterShampoo1SprayTime}min, 沐浴2后喷水:{AfterShampoo2SprayTime}min, 沐浴3后喷水:{AfterShampoo3SprayTime}min, 喷沐浴露1:{SprayShampoo1Time}min, 喷沐浴露2:{SprayShampoo2Time}min, 喷沐浴露3:{SprayShampoo3Time}min, 冷风:{ColdAirTime}min, 热风:{HotAirTime}min, 紫外线杀菌:{UvSterilizationTime}min");
+ _logger.LogInfo($"本地参数已更新 - 首次喷水:{FirstSprayWaterTime}min, 沐浴1后:{AfterShampoo1SprayTime}min, " +
+ $"沐浴2后:{AfterShampoo2SprayTime}min, 沐浴3后:{AfterShampoo3SprayTime}min, " +
+ $"喷沐浴露1:{SprayShampoo1Time}min, 喷沐浴露2:{SprayShampoo2Time}min, 喷沐浴露3:{SprayShampoo3Time}min, " +
+ $"冷风:{ColdAirTime}min, 热风:{HotAirTime}min, 紫外线:{UvSterilizationTime}min");
- MessageBox.Show("系统参数保存成功!", "成功", MessageBoxButton.OK, MessageBoxImage.Information);
+ // 如果 Modbus 已连接,写入设备
+ if (IsModbusConnected)
+ {
+ await SaveParametersToDeviceAsync();
+ MessageBox.Show("系统参数已保存到设备!", "成功", MessageBoxButton.OK, MessageBoxImage.Information);
+ StatusMessage = "参数保存成功";
+ }
+ else
+ {
+ MessageBox.Show("系统参数已保存到本地配置!\n\n注意:设备未连接,参数未写入设备。",
+ "保存成功", MessageBoxButton.OK, MessageBoxImage.Warning);
+ StatusMessage = "参数已保存(仅本地)";
+ }
}
catch (Exception ex)
{
_logger.LogError("保存系统参数失败", ex);
+ StatusMessage = "参数保存失败";
MessageBox.Show($"保存失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
+ ///
+ /// 将参数保存到 Modbus 设备
+ ///
+ private async Task SaveParametersToDeviceAsync()
+ {
+ try
+ {
+ _logger.LogInfo("正在将参数写入设备...");
+
+ // 准备时间参数数据(D404-D424,共11个寄存器)
+ ushort[] timeParams = new ushort[11];
+ timeParams[0] = (ushort)FirstSprayWaterTime; // D404 首次喷水时间
+ timeParams[1] = (ushort)AfterShampoo1SprayTime; // D406 沐浴1后喷水时间
+ timeParams[2] = (ushort)AfterShampoo2SprayTime; // D408 沐浴2后喷水时间
+ timeParams[3] = (ushort)AfterShampoo3SprayTime; // D410 沐浴3后喷水时间
+ timeParams[4] = 0; // D412 清洗笼子喷水(保留)
+ timeParams[5] = (ushort)SprayShampoo1Time; // D414 喷沐浴露1时间
+ timeParams[6] = (ushort)SprayShampoo2Time; // D416 喷沐浴露2时间
+ timeParams[7] = (ushort)SprayShampoo3Time; // D418 喷沐浴露3时间
+ timeParams[8] = (ushort)HotAirTime; // D420 吹热风时间
+ timeParams[9] = (ushort)ColdAirTime; // D422 吹冷风时间
+ timeParams[10] = (ushort)UvSterilizationTime; // D424 紫外线杀菌时间
+
+ // 写入设备
+ await _modbusService.WriteMultipleRegistersAsync(404, timeParams);
+
+ _logger.LogInfo("参数已成功写入设备");
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError("写入设备参数失败", ex);
+ throw new Exception($"写入设备失败: {ex.Message}", ex);
+ }
+ }
+
// 参数调整命令
[RelayCommand]
private void IncreaseFirstSprayWater() => FirstSprayWaterTime = Math.Min(FirstSprayWaterTime + 1, 60);