Files
petwash/PetWashControl/ViewModels/MainViewModel.cs
2026-02-27 11:20:42 +08:00

870 lines
30 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using PetWashControl.Models;
using PetWashControl.Services;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Windows;
namespace PetWashControl.ViewModels;
public partial class WashStep : ObservableObject
{
[ObservableProperty]
private string _name = "";
[ObservableProperty]
private string _status = "等待中";
[ObservableProperty]
private bool _isActive;
}
public partial class MainViewModel : ObservableObject
{
private readonly ApiService _apiService;
private readonly MqttClientService _mqttService;
private readonly ModbusService _modbusService;
private readonly ConfigurationService _config;
private readonly LogService _logger;
public event Action<string>? ViewChanged;
[ObservableProperty]
private ObservableCollection<Package> _packages = new();
[ObservableProperty]
private Package? _selectedPackage;
[ObservableProperty]
private Order? _currentOrder;
[ObservableProperty]
private string _statusMessage = "系统就绪";
[ObservableProperty]
private bool _isDoorOpen;
[ObservableProperty]
private bool _isWashing;
[ObservableProperty]
private bool _isConnected;
[ObservableProperty]
private bool _isModbusConnected;
[ObservableProperty]
private string _currentView = "Idle";
private string _previousView = "Idle"; // 保存进入设置前的视图
[ObservableProperty]
private int _washProgress;
[ObservableProperty]
private string _currentStep = "";
[ObservableProperty]
private string _remainingTime = "00:00";
[ObservableProperty]
private ObservableCollection<WashStep> _washSteps = new();
[ObservableProperty]
private double _waterTemperature = 40.0;
[ObservableProperty]
private double _roomTemperature = 25.0;
[ObservableProperty]
private string _currentCarouselImage = "/Images/dog.png";
[ObservableProperty]
private string _deviceNumber = "设备编号: PW-001";
[ObservableProperty]
private string _currentDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
[ObservableProperty]
private string _currentDayOfWeek = DateTime.Now.ToString("dddd", new System.Globalization.CultureInfo("zh-CN"));
[ObservableProperty]
private bool _isInstructionDialogOpen;
[ObservableProperty]
private bool _isCustomerServiceDialogOpen;
[ObservableProperty]
private int _firstSprayWaterTime = 2;
[ObservableProperty]
private int _afterShampoo1SprayTime = 2;
[ObservableProperty]
private int _afterShampoo2SprayTime = 2;
[ObservableProperty]
private int _afterShampoo3SprayTime = 2;
[ObservableProperty]
private int _sprayShampoo1Time = 1;
[ObservableProperty]
private int _sprayShampoo2Time = 1;
[ObservableProperty]
private int _sprayShampoo3Time = 1;
[ObservableProperty]
private int _coldAirTime = 2;
[ObservableProperty]
private int _hotAirTime = 5;
[ObservableProperty]
private int _uvSterilizationTime = 3;
[ObservableProperty]
private int _shampoo1Level = 80;
[ObservableProperty]
private int _shampoo2Level = 75;
[ObservableProperty]
private int _shampoo3Level = 70;
private readonly System.Timers.Timer _carouselTimer;
private readonly System.Timers.Timer _clockTimer;
private readonly string[] _carouselImages = { "/Images/dog.png", "/Images/dog1.png", "/Images/dog2.png" };
private int _currentImageIndex = 0;
public MainViewModel()
{
_config = new ConfigurationService();
_logger = new LogService();
_apiService = new ApiService(_config);
_mqttService = new MqttClientService(_config);
_modbusService = new ModbusService(_config, _logger);
_mqttService.MessageReceived += OnMqttMessageReceived;
_modbusService.ConnectionStatusChanged += OnModbusConnectionStatusChanged;
// 从配置加载时间参数
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;
// 初始化洗护步骤
InitializeWashSteps();
// 初始化图片轮播定时器每5秒切换
_carouselTimer = new System.Timers.Timer(5000);
_carouselTimer.Elapsed += (s, e) =>
{
Application.Current.Dispatcher.Invoke(() =>
{
_currentImageIndex = (_currentImageIndex + 1) % _carouselImages.Length;
CurrentCarouselImage = _carouselImages[_currentImageIndex];
});
};
_carouselTimer.Start();
// 初始化时钟定时器(每秒更新)
_clockTimer = new System.Timers.Timer(1000);
_clockTimer.Elapsed += (s, e) =>
{
Application.Current.Dispatcher.Invoke(() =>
{
var now = DateTime.Now;
CurrentDateTime = now.ToString("yyyy-MM-dd HH:mm:ss");
CurrentDayOfWeek = now.ToString("dddd", new System.Globalization.CultureInfo("zh-CN"));
});
};
_clockTimer.Start();
}
private void InitializeWashSteps()
{
WashSteps.Add(new WashStep { Name = "第一次冲水", Status = "等待中" });
WashSteps.Add(new WashStep { Name = "沐浴露喷洒", Status = "等待中" });
WashSteps.Add(new WashStep { Name = "第二次冲水", Status = "等待中" });
WashSteps.Add(new WashStep { Name = "香波喷洒", Status = "等待中" });
WashSteps.Add(new WashStep { Name = "第三次冲水", Status = "等待中" });
WashSteps.Add(new WashStep { Name = "护理液喷洒", Status = "等待中" });
WashSteps.Add(new WashStep { Name = "第四次冲水", Status = "等待中" });
WashSteps.Add(new WashStep { Name = "热风吹毛", Status = "等待中" });
WashSteps.Add(new WashStep { Name = "冷热风混合", Status = "等待中" });
WashSteps.Add(new WashStep { Name = "紫外线杀菌", Status = "等待中" });
}
public async Task InitializeAsync()
{
try
{
_logger.LogInfo("开始初始化系统...");
// 连接 Modbus TCP 设备
_logger.LogInfo($"正在连接 Modbus TCP 设备: {_config.ModbusIpAddress}:{_config.ModbusPort}");
var modbusConnected = await _modbusService.ConnectAsync();
IsModbusConnected = modbusConnected;
if (modbusConnected)
{
_logger.LogInfo("Modbus TCP 设备连接成功");
}
else
{
_logger.LogWarning("Modbus TCP 设备连接失败,系统将继续运行但设备控制功能可能不可用");
}
// 连接 MQTT
await _mqttService.ConnectAsync();
IsConnected = _mqttService.IsConnected;
_logger.LogInfo("MQTT连接成功");
await LoadPackagesAsync();
if (IsModbusConnected)
{
StatusMessage = "系统就绪,设备已连接";
}
else
{
StatusMessage = "系统就绪,设备未连接";
}
_logger.LogInfo("系统初始化完成");
}
catch (Exception ex)
{
_logger.LogError("初始化失败", ex);
StatusMessage = $"初始化失败: {ex.Message}";
MessageBox.Show($"系统初始化失败,请检查后端服务和设备连接。\n\n错误: {ex.Message}",
"错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
[RelayCommand]
private async Task LoadPackagesAsync()
{
try
{
_logger.LogInfo("加载套餐列表...");
var packages = await _apiService.GetPackagesAsync();
Packages.Clear();
foreach (var package in packages)
{
Packages.Add(package);
}
_logger.LogInfo($"成功加载 {packages.Count} 个套餐");
}
catch (Exception ex)
{
_logger.LogError("加载套餐失败", ex);
StatusMessage = $"加载套餐失败: {ex.Message}";
}
}
[RelayCommand]
private void ShowPayment()
{
CurrentView = "Payment";
ViewChanged?.Invoke("Payment");
StatusMessage = "请选择套餐";
_logger.LogInfo("切换到支付界面");
}
[RelayCommand]
private void ShowSettings()
{
// 保存当前视图状态
_previousView = CurrentView;
CurrentView = "Settings";
ViewChanged?.Invoke("Settings");
StatusMessage = "系统设置";
_logger.LogInfo($"切换到设置界面,之前的视图: {_previousView}");
}
[RelayCommand]
private void ShowInstruction()
{
IsInstructionDialogOpen = true;
_logger.LogInfo("显示使用说明");
}
[RelayCommand]
private void CloseInstruction()
{
IsInstructionDialogOpen = false;
_logger.LogInfo("关闭使用说明");
}
[RelayCommand]
private void ShowCustomerService()
{
IsCustomerServiceDialogOpen = true;
_logger.LogInfo("显示联系客服");
}
[RelayCommand]
private void CloseCustomerService()
{
IsCustomerServiceDialogOpen = false;
_logger.LogInfo("关闭联系客服");
}
[RelayCommand]
private void SaveSettings()
{
try
{
// 更新配置
_config.FirstSprayWaterTime = FirstSprayWaterTime;
_config.AfterShampoo1SprayTime = AfterShampoo1SprayTime;
_config.AfterShampoo2SprayTime = AfterShampoo2SprayTime;
_config.AfterShampoo3SprayTime = AfterShampoo3SprayTime;
_config.SprayShampoo1Time = SprayShampoo1Time;
_config.SprayShampoo2Time = SprayShampoo2Time;
_config.SprayShampoo3Time = SprayShampoo3Time;
_config.ColdAirTime = ColdAirTime;
_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");
MessageBox.Show("系统参数保存成功!", "成功", MessageBoxButton.OK, MessageBoxImage.Information);
}
catch (Exception ex)
{
_logger.LogError("保存系统参数失败", ex);
MessageBox.Show($"保存失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
// 参数调整命令
[RelayCommand]
private void IncreaseFirstSprayWater() => FirstSprayWaterTime = Math.Min(FirstSprayWaterTime + 1, 60);
[RelayCommand]
private void DecreaseFirstSprayWater() => FirstSprayWaterTime = Math.Max(FirstSprayWaterTime - 1, 0);
[RelayCommand]
private void IncreaseSprayShampoo1() => SprayShampoo1Time = Math.Min(SprayShampoo1Time + 1, 60);
[RelayCommand]
private void DecreaseSprayShampoo1() => SprayShampoo1Time = Math.Max(SprayShampoo1Time - 1, 0);
[RelayCommand]
private void IncreaseAfterShampoo1Spray() => AfterShampoo1SprayTime = Math.Min(AfterShampoo1SprayTime + 1, 60);
[RelayCommand]
private void DecreaseAfterShampoo1Spray() => AfterShampoo1SprayTime = Math.Max(AfterShampoo1SprayTime - 1, 0);
[RelayCommand]
private void IncreaseSprayShampoo2() => SprayShampoo2Time = Math.Min(SprayShampoo2Time + 1, 60);
[RelayCommand]
private void DecreaseSprayShampoo2() => SprayShampoo2Time = Math.Max(SprayShampoo2Time - 1, 0);
[RelayCommand]
private void IncreaseAfterShampoo2Spray() => AfterShampoo2SprayTime = Math.Min(AfterShampoo2SprayTime + 1, 60);
[RelayCommand]
private void DecreaseAfterShampoo2Spray() => AfterShampoo2SprayTime = Math.Max(AfterShampoo2SprayTime - 1, 0);
[RelayCommand]
private void IncreaseSprayShampoo3() => SprayShampoo3Time = Math.Min(SprayShampoo3Time + 1, 60);
[RelayCommand]
private void DecreaseSprayShampoo3() => SprayShampoo3Time = Math.Max(SprayShampoo3Time - 1, 0);
[RelayCommand]
private void IncreaseAfterShampoo3Spray() => AfterShampoo3SprayTime = Math.Min(AfterShampoo3SprayTime + 1, 60);
[RelayCommand]
private void DecreaseAfterShampoo3Spray() => AfterShampoo3SprayTime = Math.Max(AfterShampoo3SprayTime - 1, 0);
[RelayCommand]
private void IncreaseColdAir() => ColdAirTime = Math.Min(ColdAirTime + 1, 60);
[RelayCommand]
private void DecreaseColdAir() => ColdAirTime = Math.Max(ColdAirTime - 1, 0);
[RelayCommand]
private void IncreaseHotAir() => HotAirTime = Math.Min(HotAirTime + 1, 60);
[RelayCommand]
private void DecreaseHotAir() => HotAirTime = Math.Max(HotAirTime - 1, 0);
[RelayCommand]
private void IncreaseUvSterilization() => UvSterilizationTime = Math.Min(UvSterilizationTime + 1, 60);
[RelayCommand]
private void DecreaseUvSterilization() => UvSterilizationTime = Math.Max(UvSterilizationTime - 1, 0);
[RelayCommand]
private void BackToIdle()
{
// 如果从设置页面返回,且之前不是待机界面,则返回到之前的视图
if (CurrentView == "Settings" && _previousView != "Idle" && _previousView != "Settings")
{
CurrentView = _previousView;
ViewChanged?.Invoke(_previousView);
// 根据返回的视图设置相应的状态消息
switch (_previousView)
{
case "Washing":
StatusMessage = "洗护进行中...";
_logger.LogInfo("从设置返回到洗护界面");
break;
case "Payment":
StatusMessage = "请选择套餐";
_logger.LogInfo("从设置返回到支付界面");
break;
case "QRCode":
StatusMessage = $"请扫码支付 ¥{SelectedPackage?.Price}";
_logger.LogInfo("从设置返回到二维码支付界面");
break;
default:
StatusMessage = "系统就绪,请点击开始";
_logger.LogInfo("从设置返回到待机界面");
break;
}
// 重置之前的视图状态
_previousView = "Idle";
return;
}
// 默认返回到待机界面
CurrentView = "Idle";
ViewChanged?.Invoke("Idle");
StatusMessage = "系统就绪,请点击开始";
SelectedPackage = null;
CurrentOrder = null;
IsDoorOpen = false;
// 重置洗护步骤状态
foreach (var step in WashSteps)
{
step.Status = "等待中";
step.IsActive = false;
}
_previousView = "Idle";
_logger.LogInfo("返回待机界面");
}
[RelayCommand]
private async Task SelectPackage(Package package)
{
if (package == null) return;
SelectedPackage = package;
_logger.LogInfo($"选择套餐: {package.Name}");
try
{
// 创建订单
CurrentOrder = await _apiService.CreateOrderAsync(package.Id);
StatusMessage = $"订单创建成功,请扫码支付 ¥{package.Price}";
_logger.LogInfo($"订单创建成功订单ID: {CurrentOrder?.Id}");
// 切换到二维码支付界面
CurrentView = "QRCode";
ViewChanged?.Invoke("QRCode");
}
catch (Exception ex)
{
_logger.LogError("创建订单失败", ex);
StatusMessage = $"创建订单失败: {ex.Message}";
MessageBox.Show($"创建订单失败\n\n{ex.Message}", "错误",
MessageBoxButton.OK, MessageBoxImage.Error);
}
}
[RelayCommand]
private void CancelPayment()
{
_logger.LogInfo("取消支付");
CurrentOrder = null;
SelectedPackage = null;
CurrentView = "Payment";
ViewChanged?.Invoke("Payment");
StatusMessage = "已取消支付,请重新选择套餐";
}
[RelayCommand]
private async Task CreateOrderAsync()
{
if (SelectedPackage == null)
{
MessageBox.Show("请先选择套餐", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
try
{
_logger.LogInfo($"创建订单套餐ID: {SelectedPackage.Id}");
CurrentOrder = await _apiService.CreateOrderAsync(SelectedPackage.Id);
StatusMessage = $"订单创建成功,订单号: {CurrentOrder?.Id},请支付 ¥{SelectedPackage.Price}";
_logger.LogInfo($"订单创建成功订单ID: {CurrentOrder?.Id}");
}
catch (Exception ex)
{
_logger.LogError("创建订单失败", ex);
StatusMessage = $"创建订单失败: {ex.Message}";
MessageBox.Show($"创建订单失败\n\n{ex.Message}", "错误",
MessageBoxButton.OK, MessageBoxImage.Error);
}
}
[RelayCommand]
private async Task SimulatePaymentAsync()
{
if (CurrentOrder == null)
{
MessageBox.Show("请先创建订单", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
try
{
_logger.LogInfo($"模拟支付订单ID: {CurrentOrder.Id}");
// 模拟支付处理延迟
StatusMessage = "正在处理支付...";
await Task.Delay(1500);
// 确认支付
CurrentOrder = await _apiService.ConfirmPaymentAsync(CurrentOrder.Id);
StatusMessage = "支付成功!设备门已打开,请将宠物放入";
IsDoorOpen = true;
_logger.LogInfo("支付成功,门已打开");
// 显示支付成功提示
MessageBox.Show("支付成功!\n\n设备门已自动打开\n请将宠物放入设备后关闭门开始洗护",
"支付成功", MessageBoxButton.OK, MessageBoxImage.Information);
// 返回待机界面,显示关门按钮
CurrentView = "Idle";
ViewChanged?.Invoke("Idle");
}
catch (Exception ex)
{
_logger.LogError("支付失败", ex);
StatusMessage = $"支付失败: {ex.Message}";
MessageBox.Show($"支付失败\n\n{ex.Message}", "错误",
MessageBoxButton.OK, MessageBoxImage.Error);
}
}
[RelayCommand]
private async Task CloseDoorAsync()
{
if (CurrentOrder == null || !IsDoorOpen)
{
MessageBox.Show("门未打开", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
try
{
_logger.LogInfo($"关门订单ID: {CurrentOrder.Id}");
// 通过MQTT发送关门状态
await _mqttService.PublishAsync("device/status", new
{
status = "door_closed",
orderId = CurrentOrder.Id,
timestamp = DateTime.Now
});
// 更新订单状态
CurrentOrder = await _apiService.UpdateOrderStatusAsync(CurrentOrder.Id, OrderStatus.DoorClosed);
IsDoorOpen = false;
StatusMessage = "门已关闭,清洗即将开始...";
_logger.LogInfo("门已关闭,等待清洗开始");
// 切换到洗护界面
CurrentView = "Washing";
ViewChanged?.Invoke("Washing");
IsWashing = true;
CurrentStep = "第一次冲水";
WashProgress = 0;
// 开始模拟洗护流程
_ = SimulateWashingProcessAsync();
}
catch (Exception ex)
{
_logger.LogError("关门失败", ex);
StatusMessage = $"关门失败: {ex.Message}";
MessageBox.Show($"关门失败\n\n{ex.Message}", "错误",
MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private async Task SimulateWashingProcessAsync()
{
try
{
// 将分钟转换为秒
var steps = new[]
{
("第一次冲水", FirstSprayWaterTime * 60),
("沐浴露喷洒", SprayShampoo1Time * 60),
("第二次冲水", AfterShampoo1SprayTime * 60),
("香波喷洒", SprayShampoo2Time * 60),
("第三次冲水", AfterShampoo2SprayTime * 60),
("护理液喷洒", SprayShampoo3Time * 60),
("第四次冲水", AfterShampoo3SprayTime * 60),
("热风吹毛", HotAirTime * 60),
("冷热风混合", ColdAirTime * 60),
("紫外线杀菌", UvSterilizationTime * 60)
};
int totalDuration = steps.Sum(s => s.Item2);
int elapsed = 0;
for (int stepIndex = 0; stepIndex < steps.Length; stepIndex++)
{
var (stepName, duration) = steps[stepIndex];
CurrentStep = stepName;
_logger.LogInfo($"开始步骤: {stepName}, 时长: {duration / 60}分钟");
// 更新步骤状态
Application.Current.Dispatcher.Invoke(() =>
{
// 标记之前的步骤为已完成
for (int i = 0; i < stepIndex; i++)
{
WashSteps[i].Status = "已完成";
WashSteps[i].IsActive = false;
}
// 标记当前步骤为进行中
WashSteps[stepIndex].Status = "进行中";
WashSteps[stepIndex].IsActive = true;
// 标记后续步骤为等待中
for (int i = stepIndex + 1; i < WashSteps.Count; i++)
{
WashSteps[i].Status = "等待中";
WashSteps[i].IsActive = false;
}
});
for (int i = 0; i <= duration; i++)
{
if (!IsWashing) return; // 如果被停止,退出
elapsed++;
WashProgress = (int)((double)elapsed / totalDuration * 100);
int remaining = totalDuration - elapsed;
int minutes = remaining / 60;
int seconds = remaining % 60;
RemainingTime = $"{minutes:D2}:{seconds:D2}";
// 模拟温度变化
UpdateTemperatures(stepName, i, duration);
await Task.Delay(100); // 加速模拟实际应为1000ms
}
}
// 标记所有步骤为已完成
Application.Current.Dispatcher.Invoke(() =>
{
foreach (var step in WashSteps)
{
step.Status = "已完成";
step.IsActive = false;
}
});
// 洗护完成
await CompleteWashingAsync();
}
catch (Exception ex)
{
_logger.LogError("洗护流程失败", ex);
StatusMessage = $"洗护流程失败: {ex.Message}";
}
}
private async Task CompleteWashingAsync()
{
if (CurrentOrder == null) return;
try
{
_logger.LogInfo($"清洗完成订单ID: {CurrentOrder.Id}");
// 发送清洗完成状态
await _mqttService.PublishAsync("device/status", new
{
status = "completed",
orderId = CurrentOrder.Id,
timestamp = DateTime.Now
});
CurrentOrder = await _apiService.UpdateOrderStatusAsync(CurrentOrder.Id, OrderStatus.Completed);
IsWashing = false;
IsDoorOpen = true;
StatusMessage = "清洗完成!请取出宠物";
MessageBox.Show("清洗完成!\n\n感谢使用无人自动洗宠机", "完成",
MessageBoxButton.OK, MessageBoxImage.Information);
_logger.LogInfo("订单流程完成");
// 返回待机界面
CurrentOrder = null;
SelectedPackage = null;
BackToIdle();
}
catch (Exception ex)
{
_logger.LogError("完成流程失败", ex);
StatusMessage = $"完成流程失败: {ex.Message}";
}
}
private void OnMqttMessageReceived(string topic, string payload)
{
Application.Current.Dispatcher.Invoke(() =>
{
try
{
_logger.LogInfo($"收到MQTT消息 - Topic: {topic}, Payload: {payload}");
var message = JsonSerializer.Deserialize<JsonElement>(payload);
if (topic == "device/command")
{
var command = message.GetProperty("command").GetString();
if (command == "open_door")
{
IsDoorOpen = true;
StatusMessage = "设备门已打开,请将宠物放入后点击关门";
_logger.LogInfo("收到开门指令");
}
else if (command == "start_wash")
{
IsWashing = true;
var duration = message.GetProperty("durationMinutes").GetInt32();
StatusMessage = $"清洗已开始,预计 {duration} 分钟完成";
_logger.LogInfo($"收到开始清洗指令,时长: {duration}分钟");
}
}
else if (topic == "device/status")
{
var status = message.GetProperty("status").GetString();
StatusMessage = $"设备状态: {status}";
_logger.LogInfo($"设备状态更新: {status}");
}
}
catch (Exception ex)
{
_logger.LogError("处理MQTT消息失败", ex);
StatusMessage = $"处理消息失败: {ex.Message}";
}
});
}
private void OnModbusConnectionStatusChanged(bool isConnected)
{
Application.Current.Dispatcher.Invoke(() =>
{
IsModbusConnected = isConnected;
if (isConnected)
{
_logger.LogInfo("Modbus TCP 设备已连接");
if (StatusMessage.Contains("设备未连接"))
{
StatusMessage = "系统就绪,设备已连接";
}
}
else
{
_logger.LogWarning("Modbus TCP 设备连接断开");
if (!StatusMessage.Contains("失败") && !StatusMessage.Contains("错误"))
{
StatusMessage = "警告:设备连接断开";
}
}
});
}
private void UpdateTemperatures(string stepName, int currentTime, int totalTime)
{
// 根据不同步骤模拟温度变化
var random = new Random();
double progress = (double)currentTime / totalTime;
switch (stepName)
{
case "第一次冲水":
case "第二次冲水":
case "第三次冲水":
case "第四次冲水":
// 冲水阶段水温在38-42度之间波动
WaterTemperature = 40.0 + (random.NextDouble() - 0.5) * 4;
RoomTemperature = 25.0 + (random.NextDouble() - 0.5) * 2;
break;
case "沐浴露喷洒":
case "香波喷洒":
case "护理液喷洒":
// 喷洒阶段:水温略低
WaterTemperature = 38.0 + (random.NextDouble() - 0.5) * 2;
RoomTemperature = 25.0 + (random.NextDouble() - 0.5) * 2;
break;
case "热风吹毛":
// 热风阶段:水温降低,室温升高
WaterTemperature = 35.0 - progress * 10 + (random.NextDouble() - 0.5) * 2;
RoomTemperature = 25.0 + progress * 8 + (random.NextDouble() - 0.5) * 2;
break;
case "冷热风混合":
// 混合风阶段:温度逐渐降低
WaterTemperature = 25.0 + (random.NextDouble() - 0.5) * 2;
RoomTemperature = 30.0 - progress * 5 + (random.NextDouble() - 0.5) * 2;
break;
case "紫外线杀菌":
// 紫外线杀菌阶段:温度稳定
WaterTemperature = 25.0 + (random.NextDouble() - 0.5) * 1;
RoomTemperature = 26.0 + (random.NextDouble() - 0.5) * 1;
break;
default:
// 默认温度
WaterTemperature = 40.0 + (random.NextDouble() - 0.5) * 2;
RoomTemperature = 25.0 + (random.NextDouble() - 0.5) * 2;
break;
}
// 确保温度在合理范围内
WaterTemperature = Math.Max(20, Math.Min(45, WaterTemperature));
RoomTemperature = Math.Max(20, Math.Min(35, RoomTemperature));
}
}