|
@@ -9,9 +9,8 @@ namespace YZWater.Core.ViewModels;
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// 主工艺视图 ViewModel(接入真实 PLC 数据)
|
|
/// 主工艺视图 ViewModel(接入真实 PLC 数据)
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
-public partial class ViewAViewModel : ObservableObject, IDisposable
|
|
|
|
|
|
|
+public partial class ViewAViewModel : TranslatableViewModelBase
|
|
|
{
|
|
{
|
|
|
- private readonly LanguageService _lang = LanguageService.Instance;
|
|
|
|
|
private readonly SynchronizationContext? _uiContext = SynchronizationContext.Current;
|
|
private readonly SynchronizationContext? _uiContext = SynchronizationContext.Current;
|
|
|
private DateTime _startTime = DateTime.Now;
|
|
private DateTime _startTime = DateTime.Now;
|
|
|
private System.Timers.Timer? _clockTimer;
|
|
private System.Timers.Timer? _clockTimer;
|
|
@@ -109,52 +108,52 @@ public partial class ViewAViewModel : ObservableObject, IDisposable
|
|
|
[ObservableProperty] private DateTime _currentTime = DateTime.Now;
|
|
[ObservableProperty] private DateTime _currentTime = DateTime.Now;
|
|
|
|
|
|
|
|
// ═══════════════════════════════════════════════
|
|
// ═══════════════════════════════════════════════
|
|
|
- // 翻译文字
|
|
|
|
|
|
|
+ // 翻译属性(getter-only,通过基类 T() 获取翻译)
|
|
|
// ═══════════════════════════════════════════════
|
|
// ═══════════════════════════════════════════════
|
|
|
- [ObservableProperty] private string _titleText;
|
|
|
|
|
- [ObservableProperty] private string _subtitleText;
|
|
|
|
|
- [ObservableProperty] private string _plcStatusText;
|
|
|
|
|
- [ObservableProperty] private string _connectText;
|
|
|
|
|
- [ObservableProperty] private string _disconnectText;
|
|
|
|
|
- [ObservableProperty] private string _refreshText;
|
|
|
|
|
- [ObservableProperty] private string _tank1Text;
|
|
|
|
|
- [ObservableProperty] private string _tank2Text;
|
|
|
|
|
- [ObservableProperty] private string _tank3Text;
|
|
|
|
|
- [ObservableProperty] private string _tank4Text;
|
|
|
|
|
- [ObservableProperty] private string _pump1Text;
|
|
|
|
|
- [ObservableProperty] private string _pump2Text;
|
|
|
|
|
- [ObservableProperty] private string _pump3Text;
|
|
|
|
|
- [ObservableProperty] private string _pump4Text;
|
|
|
|
|
- [ObservableProperty] private string _pump5Text;
|
|
|
|
|
- [ObservableProperty] private string _fan1Text;
|
|
|
|
|
- [ObservableProperty] private string _fan2Text;
|
|
|
|
|
- [ObservableProperty] private string _valve1Text;
|
|
|
|
|
- [ObservableProperty] private string _valve2Text;
|
|
|
|
|
- [ObservableProperty] private string _valve3Text;
|
|
|
|
|
- [ObservableProperty] private string _valve4Text;
|
|
|
|
|
- [ObservableProperty] private string _modeText;
|
|
|
|
|
- [ObservableProperty] private string _realtimeText;
|
|
|
|
|
- [ObservableProperty] private string _inflowText;
|
|
|
|
|
- [ObservableProperty] private string _outflowText;
|
|
|
|
|
- [ObservableProperty] private string _deltaText;
|
|
|
|
|
- [ObservableProperty] private string _statisticsText;
|
|
|
|
|
- [ObservableProperty] private string _runtimeText;
|
|
|
|
|
- [ObservableProperty] private string _devicesText;
|
|
|
|
|
- [ObservableProperty] private string _alarmText;
|
|
|
|
|
- [ObservableProperty] private string _efficiencyText;
|
|
|
|
|
- [ObservableProperty] private string _quickOpsText;
|
|
|
|
|
- [ObservableProperty] private string _startAllText;
|
|
|
|
|
- [ObservableProperty] private string _stopAllText;
|
|
|
|
|
- [ObservableProperty] private string _ackAlarmText;
|
|
|
|
|
- [ObservableProperty] private string _exportText;
|
|
|
|
|
- [ObservableProperty] private string _flowMetersText;
|
|
|
|
|
- [ObservableProperty] private string _deviceStatusText;
|
|
|
|
|
- [ObservableProperty] private string _processFlowText;
|
|
|
|
|
- [ObservableProperty] private string _pump1TitleText;
|
|
|
|
|
- [ObservableProperty] private string _pump2TitleText;
|
|
|
|
|
- [ObservableProperty] private string _refluxPumpText;
|
|
|
|
|
- [ObservableProperty] private string _fan1TitleText;
|
|
|
|
|
- [ObservableProperty] private string _fan2TitleText;
|
|
|
|
|
|
|
+ public string TitleText => T("AppName");
|
|
|
|
|
+ public string SubtitleText => T("ProcessFlow");
|
|
|
|
|
+ public string PlcStatusText => T("PlcConnected");
|
|
|
|
|
+ public string ConnectText => T("Connect");
|
|
|
|
|
+ public string DisconnectText => T("Disconnect");
|
|
|
|
|
+ public string RefreshText => T("Refresh");
|
|
|
|
|
+ public string Tank1Text => T("TankInlet");
|
|
|
|
|
+ public string Tank2Text => T("TankBio");
|
|
|
|
|
+ public string Tank3Text => T("TankSediment");
|
|
|
|
|
+ public string Tank4Text => T("TankOutlet");
|
|
|
|
|
+ public string Pump1Text => T("Pump1");
|
|
|
|
|
+ public string Pump2Text => T("Pump2");
|
|
|
|
|
+ public string Pump3Text => T("Pump3");
|
|
|
|
|
+ public string Pump4Text => T("Pump4");
|
|
|
|
|
+ public string Pump5Text => T("Pump5");
|
|
|
|
|
+ public string Fan1Text => T("Fan1");
|
|
|
|
|
+ public string Fan2Text => T("Fan2");
|
|
|
|
|
+ public string Valve1Text => T("ValveInlet");
|
|
|
|
|
+ public string Valve2Text => T("ValveAeration");
|
|
|
|
|
+ public string Valve3Text => T("ValveReflux");
|
|
|
|
|
+ public string Valve4Text => T("ValveOutlet");
|
|
|
|
|
+ public string ModeText => T("Mode");
|
|
|
|
|
+ public string RealtimeText => T("Realtime");
|
|
|
|
|
+ public string InflowText => T("Inflow");
|
|
|
|
|
+ public string OutflowText => T("Outflow");
|
|
|
|
|
+ public string DeltaText => T("Delta");
|
|
|
|
|
+ public string StatisticsText => T("Statistics");
|
|
|
|
|
+ public string RuntimeText => T("Runtime");
|
|
|
|
|
+ public string DevicesText => T("Devices");
|
|
|
|
|
+ public string AlarmText => T("Alarm");
|
|
|
|
|
+ public string EfficiencyText => T("Efficiency");
|
|
|
|
|
+ public string QuickOpsText => T("QuickOps");
|
|
|
|
|
+ public string StartAllText => T("StartAll");
|
|
|
|
|
+ public string StopAllText => T("StopAll");
|
|
|
|
|
+ public string AckAlarmText => T("AckAlarm");
|
|
|
|
|
+ public string ExportText => T("Export");
|
|
|
|
|
+ public string FlowMetersText => T("FlowMeters");
|
|
|
|
|
+ public string DeviceStatusText => T("DeviceStatus");
|
|
|
|
|
+ public string ProcessFlowText => T("ProcessFlow");
|
|
|
|
|
+ public string Pump1TitleText => T("Pump1Title");
|
|
|
|
|
+ public string Pump2TitleText => T("Pump2Title");
|
|
|
|
|
+ public string RefluxPumpText => T("RefluxPump");
|
|
|
|
|
+ public string Fan1TitleText => T("Fan1Title");
|
|
|
|
|
+ public string Fan2TitleText => T("Fan2Title");
|
|
|
|
|
|
|
|
[ObservableProperty]
|
|
[ObservableProperty]
|
|
|
[NotifyPropertyChangedFor(nameof(Is2DView))]
|
|
[NotifyPropertyChangedFor(nameof(Is2DView))]
|
|
@@ -164,8 +163,53 @@ public partial class ViewAViewModel : ObservableObject, IDisposable
|
|
|
|
|
|
|
|
public ViewAViewModel()
|
|
public ViewAViewModel()
|
|
|
{
|
|
{
|
|
|
- UpdateTexts();
|
|
|
|
|
- _lang.LanguageChanged += OnLanguageChanged;
|
|
|
|
|
|
|
+ // 注册翻译映射
|
|
|
|
|
+ RegisterTranslation(nameof(TitleText), "AppName");
|
|
|
|
|
+ RegisterTranslation(nameof(SubtitleText), "ProcessFlow");
|
|
|
|
|
+ RegisterTranslation(nameof(PlcStatusText), "PlcConnected");
|
|
|
|
|
+ RegisterTranslation(nameof(ConnectText), "Connect");
|
|
|
|
|
+ RegisterTranslation(nameof(DisconnectText), "Disconnect");
|
|
|
|
|
+ RegisterTranslation(nameof(RefreshText), "Refresh");
|
|
|
|
|
+ RegisterTranslation(nameof(Tank1Text), "TankInlet");
|
|
|
|
|
+ RegisterTranslation(nameof(Tank2Text), "TankBio");
|
|
|
|
|
+ RegisterTranslation(nameof(Tank3Text), "TankSediment");
|
|
|
|
|
+ RegisterTranslation(nameof(Tank4Text), "TankOutlet");
|
|
|
|
|
+ RegisterTranslation(nameof(Pump1Text), "Pump1");
|
|
|
|
|
+ RegisterTranslation(nameof(Pump2Text), "Pump2");
|
|
|
|
|
+ RegisterTranslation(nameof(Pump3Text), "Pump3");
|
|
|
|
|
+ RegisterTranslation(nameof(Pump4Text), "Pump4");
|
|
|
|
|
+ RegisterTranslation(nameof(Pump5Text), "Pump5");
|
|
|
|
|
+ RegisterTranslation(nameof(Fan1Text), "Fan1");
|
|
|
|
|
+ RegisterTranslation(nameof(Fan2Text), "Fan2");
|
|
|
|
|
+ RegisterTranslation(nameof(Valve1Text), "ValveInlet");
|
|
|
|
|
+ RegisterTranslation(nameof(Valve2Text), "ValveAeration");
|
|
|
|
|
+ RegisterTranslation(nameof(Valve3Text), "ValveReflux");
|
|
|
|
|
+ RegisterTranslation(nameof(Valve4Text), "ValveOutlet");
|
|
|
|
|
+ RegisterTranslation(nameof(ModeText), "Mode");
|
|
|
|
|
+ RegisterTranslation(nameof(RealtimeText), "Realtime");
|
|
|
|
|
+ RegisterTranslation(nameof(InflowText), "Inflow");
|
|
|
|
|
+ RegisterTranslation(nameof(OutflowText), "Outflow");
|
|
|
|
|
+ RegisterTranslation(nameof(DeltaText), "Delta");
|
|
|
|
|
+ RegisterTranslation(nameof(StatisticsText), "Statistics");
|
|
|
|
|
+ RegisterTranslation(nameof(RuntimeText), "Runtime");
|
|
|
|
|
+ RegisterTranslation(nameof(DevicesText), "Devices");
|
|
|
|
|
+ RegisterTranslation(nameof(AlarmText), "Alarm");
|
|
|
|
|
+ RegisterTranslation(nameof(EfficiencyText), "Efficiency");
|
|
|
|
|
+ RegisterTranslation(nameof(QuickOpsText), "QuickOps");
|
|
|
|
|
+ RegisterTranslation(nameof(StartAllText), "StartAll");
|
|
|
|
|
+ RegisterTranslation(nameof(StopAllText), "StopAll");
|
|
|
|
|
+ RegisterTranslation(nameof(AckAlarmText), "AckAlarm");
|
|
|
|
|
+ RegisterTranslation(nameof(ExportText), "Export");
|
|
|
|
|
+ RegisterTranslation(nameof(FlowMetersText), "FlowMeters");
|
|
|
|
|
+ RegisterTranslation(nameof(DeviceStatusText), "DeviceStatus");
|
|
|
|
|
+ RegisterTranslation(nameof(ProcessFlowText), "ProcessFlow");
|
|
|
|
|
+ RegisterTranslation(nameof(Pump1TitleText), "Pump1Title");
|
|
|
|
|
+ RegisterTranslation(nameof(Pump2TitleText), "Pump2Title");
|
|
|
|
|
+ RegisterTranslation(nameof(RefluxPumpText), "RefluxPump");
|
|
|
|
|
+ RegisterTranslation(nameof(Fan1TitleText), "Fan1Title");
|
|
|
|
|
+ RegisterTranslation(nameof(Fan2TitleText), "Fan2Title");
|
|
|
|
|
+
|
|
|
|
|
+ SubscribeLanguageChanged();
|
|
|
|
|
|
|
|
// 订阅 PLC 轮询数据
|
|
// 订阅 PLC 轮询数据
|
|
|
PlcPollingService.Instance.DataUpdated += OnDataUpdated;
|
|
PlcPollingService.Instance.DataUpdated += OnDataUpdated;
|
|
@@ -178,7 +222,13 @@ public partial class ViewAViewModel : ObservableObject, IDisposable
|
|
|
StartClockTimer();
|
|
StartClockTimer();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private void OnLanguageChanged() => RunOnUi(UpdateTexts);
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// 语言变更时需要在 UI 线程刷新(ViewA 有 SynchronizationContext 需求)
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ protected override void OnLanguageChanged()
|
|
|
|
|
+ {
|
|
|
|
|
+ RunOnUi(RefreshTranslations);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
private void RunOnUi(Action action)
|
|
private void RunOnUi(Action action)
|
|
|
{
|
|
{
|
|
@@ -193,54 +243,6 @@ public partial class ViewAViewModel : ObservableObject, IDisposable
|
|
|
action();
|
|
action();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private void UpdateTexts()
|
|
|
|
|
- {
|
|
|
|
|
- TitleText = _lang.Get("AppName");
|
|
|
|
|
- SubtitleText = _lang.Get("ProcessFlow");
|
|
|
|
|
- PlcStatusText = _lang.Get("PlcConnected");
|
|
|
|
|
- ConnectText = _lang.Get("Connect");
|
|
|
|
|
- DisconnectText = _lang.Get("Disconnect");
|
|
|
|
|
- RefreshText = _lang.Get("Refresh");
|
|
|
|
|
- Tank1Text = _lang.Get("TankInlet");
|
|
|
|
|
- Tank2Text = _lang.Get("TankBio");
|
|
|
|
|
- Tank3Text = _lang.Get("TankSediment");
|
|
|
|
|
- Tank4Text = _lang.Get("TankOutlet");
|
|
|
|
|
- Pump1Text = _lang.Get("Pump1");
|
|
|
|
|
- Pump2Text = _lang.Get("Pump2");
|
|
|
|
|
- Pump3Text = _lang.Get("Pump3");
|
|
|
|
|
- Pump4Text = _lang.Get("Pump4");
|
|
|
|
|
- Pump5Text = _lang.Get("Pump5");
|
|
|
|
|
- Fan1Text = _lang.Get("Fan1");
|
|
|
|
|
- Fan2Text = _lang.Get("Fan2");
|
|
|
|
|
- Valve1Text = _lang.Get("ValveInlet");
|
|
|
|
|
- Valve2Text = _lang.Get("ValveAeration");
|
|
|
|
|
- Valve3Text = _lang.Get("ValveReflux");
|
|
|
|
|
- Valve4Text = _lang.Get("ValveOutlet");
|
|
|
|
|
- ModeText = _lang.Get("Mode");
|
|
|
|
|
- RealtimeText = _lang.Get("Realtime");
|
|
|
|
|
- InflowText = _lang.Get("Inflow");
|
|
|
|
|
- OutflowText = _lang.Get("Outflow");
|
|
|
|
|
- DeltaText = _lang.Get("Delta");
|
|
|
|
|
- StatisticsText = _lang.Get("Statistics");
|
|
|
|
|
- RuntimeText = _lang.Get("Runtime");
|
|
|
|
|
- DevicesText = _lang.Get("Devices");
|
|
|
|
|
- AlarmText = _lang.Get("Alarm");
|
|
|
|
|
- EfficiencyText = _lang.Get("Efficiency");
|
|
|
|
|
- QuickOpsText = _lang.Get("QuickOps");
|
|
|
|
|
- StartAllText = _lang.Get("StartAll");
|
|
|
|
|
- StopAllText = _lang.Get("StopAll");
|
|
|
|
|
- AckAlarmText = _lang.Get("AckAlarm");
|
|
|
|
|
- ExportText = _lang.Get("Export");
|
|
|
|
|
- FlowMetersText = _lang.Get("FlowMeters");
|
|
|
|
|
- DeviceStatusText = _lang.Get("DeviceStatus");
|
|
|
|
|
- ProcessFlowText = _lang.Get("ProcessFlow");
|
|
|
|
|
- Pump1TitleText = _lang.Get("Pump1Title");
|
|
|
|
|
- Pump2TitleText = _lang.Get("Pump2Title");
|
|
|
|
|
- RefluxPumpText = _lang.Get("RefluxPump");
|
|
|
|
|
- Fan1TitleText = _lang.Get("Fan1Title");
|
|
|
|
|
- Fan2TitleText = _lang.Get("Fan2Title");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
private void StartClockTimer()
|
|
private void StartClockTimer()
|
|
|
{
|
|
{
|
|
|
_clockTimer = new System.Timers.Timer(1000);
|
|
_clockTimer = new System.Timers.Timer(1000);
|
|
@@ -336,8 +338,8 @@ public partial class ViewAViewModel : ObservableObject, IDisposable
|
|
|
: 0;
|
|
: 0;
|
|
|
UpdateIfChanged(ref _efficiency, (float)efficiency);
|
|
UpdateIfChanged(ref _efficiency, (float)efficiency);
|
|
|
|
|
|
|
|
- // 检查报警
|
|
|
|
|
- CheckAlarms(data);
|
|
|
|
|
|
|
+ // 报警由 AlarmService 统一检测,通过 AlarmStateChanged 事件更新
|
|
|
|
|
+ UpdateAlarmStateFromService();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -353,12 +355,18 @@ public partial class ViewAViewModel : ObservableObject, IDisposable
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
private void OnAlarmStateChanged()
|
|
private void OnAlarmStateChanged()
|
|
|
{
|
|
{
|
|
|
- RunOnUi(() =>
|
|
|
|
|
- {
|
|
|
|
|
- HasAlarm = AlarmService.Instance.HasActiveAlarm;
|
|
|
|
|
- AlarmMessage = AlarmService.Instance.ActiveAlarmMessage;
|
|
|
|
|
- AlarmCount = AlarmService.Instance.ActiveAlarmCount;
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ RunOnUi(UpdateAlarmStateFromService);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// 从 AlarmService 读取报警状态(避免重复检测逻辑)
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ private void UpdateAlarmStateFromService()
|
|
|
|
|
+ {
|
|
|
|
|
+ var alarmService = AlarmService.Instance;
|
|
|
|
|
+ HasAlarm = alarmService.HasActiveAlarm;
|
|
|
|
|
+ AlarmMessage = alarmService.ActiveAlarmMessage;
|
|
|
|
|
+ AlarmCount = alarmService.ActiveAlarmCount;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private static PlcDataModel CreateSnapshot(PlcDataModel data) => new()
|
|
private static PlcDataModel CreateSnapshot(PlcDataModel data) => new()
|
|
@@ -404,24 +412,25 @@ public partial class ViewAViewModel : ObservableObject, IDisposable
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
private void UpdateDeviceStatuses(PlcDataModel data)
|
|
private void UpdateDeviceStatuses(PlcDataModel data)
|
|
|
{
|
|
{
|
|
|
|
|
+ // 使用 ThemeColors 常量替代硬编码颜色
|
|
|
// 仅在状态变化时更新(避免不必要的字符串分配和通知)
|
|
// 仅在状态变化时更新(避免不必要的字符串分配和通知)
|
|
|
- UpdateIfChanged(ref _pump1StatusColor, data.Pump1Running ? "#00897B" : (data.Pump1Fault ? "#EF4444" : "#4B5563"));
|
|
|
|
|
- UpdateIfChanged(ref _pump2StatusColor, data.Pump2Running ? "#00897B" : (data.Pump2Fault ? "#EF4444" : "#4B5563"));
|
|
|
|
|
- UpdateIfChanged(ref _pump3StatusColor, data.Pump3Running ? "#00897B" : (data.Pump3Fault ? "#EF4444" : "#4B5563"));
|
|
|
|
|
- UpdateIfChanged(ref _pump4StatusColor, data.Pump4Running ? "#00897B" : (data.Pump4Fault ? "#EF4444" : "#4B5563"));
|
|
|
|
|
- UpdateIfChanged(ref _pump5StatusColor, data.Pump5Running ? "#00897B" : (data.Pump5Fault ? "#EF4444" : "#4B5563"));
|
|
|
|
|
-
|
|
|
|
|
- UpdateIfChanged(ref _fan1StatusColor, data.Fan1Running ? "#00897B" : (data.Fan1Fault ? "#EF4444" : "#4B5563"));
|
|
|
|
|
- UpdateIfChanged(ref _fan2StatusColor, data.Fan2Running ? "#00897B" : (data.Fan2Fault ? "#EF4444" : "#4B5563"));
|
|
|
|
|
-
|
|
|
|
|
- UpdateIfChanged(ref _valve1StatusColor, data.Valve1Position > 50 ? "#00897B" :
|
|
|
|
|
- data.Valve1Position < 50 ? "#F59E0B" : "#4B5563");
|
|
|
|
|
- UpdateIfChanged(ref _valve2StatusColor, data.Valve2Position > 50 ? "#00897B" :
|
|
|
|
|
- data.Valve2Position < 50 ? "#F59E0B" : "#4B5563");
|
|
|
|
|
- UpdateIfChanged(ref _valve3StatusColor, data.Valve3Position > 50 ? "#00897B" :
|
|
|
|
|
- data.Valve3Position < 50 ? "#F59E0B" : "#4B5563");
|
|
|
|
|
- UpdateIfChanged(ref _valve4StatusColor, data.Valve4Position > 50 ? "#00897B" :
|
|
|
|
|
- data.Valve4Position < 50 ? "#F59E0B" : "#4B5563");
|
|
|
|
|
|
|
+ UpdateIfChanged(ref _pump1StatusColor, data.Pump1Running ? ThemeColors.Success : (data.Pump1Fault ? ThemeColors.Danger : ThemeColors.TextDisabled));
|
|
|
|
|
+ UpdateIfChanged(ref _pump2StatusColor, data.Pump2Running ? ThemeColors.Success : (data.Pump2Fault ? ThemeColors.Danger : ThemeColors.TextDisabled));
|
|
|
|
|
+ UpdateIfChanged(ref _pump3StatusColor, data.Pump3Running ? ThemeColors.Success : (data.Pump3Fault ? ThemeColors.Danger : ThemeColors.TextDisabled));
|
|
|
|
|
+ UpdateIfChanged(ref _pump4StatusColor, data.Pump4Running ? ThemeColors.Success : (data.Pump4Fault ? ThemeColors.Danger : ThemeColors.TextDisabled));
|
|
|
|
|
+ UpdateIfChanged(ref _pump5StatusColor, data.Pump5Running ? ThemeColors.Success : (data.Pump5Fault ? ThemeColors.Danger : ThemeColors.TextDisabled));
|
|
|
|
|
+
|
|
|
|
|
+ UpdateIfChanged(ref _fan1StatusColor, data.Fan1Running ? ThemeColors.Success : (data.Fan1Fault ? ThemeColors.Danger : ThemeColors.TextDisabled));
|
|
|
|
|
+ UpdateIfChanged(ref _fan2StatusColor, data.Fan2Running ? ThemeColors.Success : (data.Fan2Fault ? ThemeColors.Danger : ThemeColors.TextDisabled));
|
|
|
|
|
+
|
|
|
|
|
+ UpdateIfChanged(ref _valve1StatusColor, data.Valve1Position > 50 ? ThemeColors.Success :
|
|
|
|
|
+ data.Valve1Position < 50 ? ThemeColors.Warning : ThemeColors.TextDisabled);
|
|
|
|
|
+ UpdateIfChanged(ref _valve2StatusColor, data.Valve2Position > 50 ? ThemeColors.Success :
|
|
|
|
|
+ data.Valve2Position < 50 ? ThemeColors.Warning : ThemeColors.TextDisabled);
|
|
|
|
|
+ UpdateIfChanged(ref _valve3StatusColor, data.Valve3Position > 50 ? ThemeColors.Success :
|
|
|
|
|
+ data.Valve3Position < 50 ? ThemeColors.Warning : ThemeColors.TextDisabled);
|
|
|
|
|
+ UpdateIfChanged(ref _valve4StatusColor, data.Valve4Position > 50 ? ThemeColors.Success :
|
|
|
|
|
+ data.Valve4Position < 50 ? ThemeColors.Warning : ThemeColors.TextDisabled);
|
|
|
|
|
|
|
|
UpdateIfChanged(ref _pump1Status, data.Pump1Running ? $"RUNNING {data.Pump1Freq:F0}Hz" : (data.Pump1Fault ? "FAULT" : "STOPPED"));
|
|
UpdateIfChanged(ref _pump1Status, data.Pump1Running ? $"RUNNING {data.Pump1Freq:F0}Hz" : (data.Pump1Fault ? "FAULT" : "STOPPED"));
|
|
|
UpdateIfChanged(ref _pump2Status, data.Pump2Running ? $"RUNNING {data.Pump2Freq:F0}Hz" : (data.Pump2Fault ? "FAULT" : "STOPPED"));
|
|
UpdateIfChanged(ref _pump2Status, data.Pump2Running ? $"RUNNING {data.Pump2Freq:F0}Hz" : (data.Pump2Fault ? "FAULT" : "STOPPED"));
|
|
@@ -433,42 +442,6 @@ public partial class ViewAViewModel : ObservableObject, IDisposable
|
|
|
UpdateIfChanged(ref _fan2Status, data.Fan2Running ? "RUNNING" : (data.Fan2Fault ? "FAULT" : "STOPPED"));
|
|
UpdateIfChanged(ref _fan2Status, data.Fan2Running ? "RUNNING" : (data.Fan2Fault ? "FAULT" : "STOPPED"));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /// <summary>
|
|
|
|
|
- /// 检查报警(从 PlcPollingService 数据)
|
|
|
|
|
- /// </summary>
|
|
|
|
|
- private void CheckAlarms(PlcDataModel data)
|
|
|
|
|
- {
|
|
|
|
|
- var config = ConfigService.GetConfig();
|
|
|
|
|
- if (config == null) return;
|
|
|
|
|
-
|
|
|
|
|
- HasAlarm = false;
|
|
|
|
|
- AlarmMessage = string.Empty;
|
|
|
|
|
- AlarmCount = 0;
|
|
|
|
|
-
|
|
|
|
|
- if (data.Tank1Level > config.LevelHighAlarm || data.Tank1Level < config.LevelLowAlarm)
|
|
|
|
|
- {
|
|
|
|
|
- HasAlarm = true;
|
|
|
|
|
- AlarmCount++;
|
|
|
|
|
- }
|
|
|
|
|
- if (data.Tank2Level > config.LevelHighAlarm || data.Tank2Level < config.LevelLowAlarm)
|
|
|
|
|
- {
|
|
|
|
|
- HasAlarm = true;
|
|
|
|
|
- AlarmCount++;
|
|
|
|
|
- }
|
|
|
|
|
- if (data.InflowRate > config.FlowHighAlarm)
|
|
|
|
|
- {
|
|
|
|
|
- HasAlarm = true;
|
|
|
|
|
- AlarmCount++;
|
|
|
|
|
- }
|
|
|
|
|
- if (data.HasAnyFault)
|
|
|
|
|
- {
|
|
|
|
|
- HasAlarm = true;
|
|
|
|
|
- AlarmCount++;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- RunningDeviceCount = data.RunningPumpCount + data.RunningFanCount;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
// ═══════════════════════════════════════════════
|
|
// ═══════════════════════════════════════════════
|
|
|
// PLC 控制命令
|
|
// PLC 控制命令
|
|
|
// ═══════════════════════════════════════════════
|
|
// ═══════════════════════════════════════════════
|
|
@@ -579,7 +552,7 @@ public partial class ViewAViewModel : ObservableObject, IDisposable
|
|
|
await AlarmService.Instance.AcknowledgeAllAsync();
|
|
await AlarmService.Instance.AcknowledgeAllAsync();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public void Dispose()
|
|
|
|
|
|
|
+ public new void Dispose()
|
|
|
{
|
|
{
|
|
|
if (_disposed) return;
|
|
if (_disposed) return;
|
|
|
_disposed = true;
|
|
_disposed = true;
|
|
@@ -588,10 +561,11 @@ public partial class ViewAViewModel : ObservableObject, IDisposable
|
|
|
_clockTimer?.Dispose();
|
|
_clockTimer?.Dispose();
|
|
|
_clockTimer = null;
|
|
_clockTimer = null;
|
|
|
|
|
|
|
|
- _lang.LanguageChanged -= OnLanguageChanged;
|
|
|
|
|
PlcPollingService.Instance.DataUpdated -= OnDataUpdated;
|
|
PlcPollingService.Instance.DataUpdated -= OnDataUpdated;
|
|
|
PlcPollingService.Instance.ConnectionStateChanged -= OnConnectionStateChanged;
|
|
PlcPollingService.Instance.ConnectionStateChanged -= OnConnectionStateChanged;
|
|
|
AlarmService.Instance.AlarmStateChanged -= OnAlarmStateChanged;
|
|
AlarmService.Instance.AlarmStateChanged -= OnAlarmStateChanged;
|
|
|
|
|
+
|
|
|
|
|
+ base.Dispose();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|