using OperationControl.Models; using System.Collections.ObjectModel; using System.ComponentModel; using System.Windows.Threading; using static AgroBase.Models.Enums; using Application = System.Windows.Application; namespace OperationControl.ViewModels.Views.Operacao { public class OperacaoBottomViewModel : INotifyPropertyChanged { private AlertaModel _toastAlerta; private AlertaModel _alertaSelecionado; private readonly DispatcherTimer _toastTimer; public OperacaoBottomViewModel() { AlertasAtivos = new ObservableCollection(); _toastTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(5) }; _toastTimer.Tick += (s, e) => { _toastTimer.Stop(); ToastAlerta = null; }; } public ObservableCollection AlertasAtivos { get; } public AlertaModel ToastAlerta { get => _toastAlerta; set { if (_toastAlerta != value) { _toastAlerta = value; OnPropertyChanged(nameof(ToastAlerta)); } } } public AlertaModel AlertaSelecionado { get => _alertaSelecionado; set { if (_alertaSelecionado != value) { _alertaSelecionado = value; OnPropertyChanged(nameof(AlertaSelecionado)); } } } public event PropertyChangedEventHandler PropertyChanged; public event Action AlertaSelecionadoChanged; public void SelecionarAlerta(AlertaModel alerta) { if (alerta == null) return; AlertaSelecionado = alerta; AlertaSelecionadoChanged?.Invoke(alerta); } public void AdicionarAlerta(string roverId, T_Code modulo, SeveridadeAlerta severidade, string mensagem, string modId = null) { if (!Application.Current.Dispatcher.CheckAccess()) { Application.Current.Dispatcher.BeginInvoke(new Action(() => AdicionarAlerta(roverId, modulo, severidade, mensagem, modId))); return; } var existente = AlertasAtivos.FirstOrDefault(x => x.Rover_ID == roverId && x.Modulo == modulo && x.Mod_ID == modId); if (existente == null) { var alerta = new AlertaModel { Rover_ID = roverId, Modulo = modulo, Mod_ID = modId, Severidade = severidade, Mensagem = mensagem, Timestamp = DateTime.Now }; AlertasAtivos.Insert(0, alerta); MostrarToast(alerta); } else { existente.Mensagem = mensagem; existente.Severidade = severidade; existente.Timestamp = DateTime.Now; // caso o model nao implemente INotifyPropertyChanged, // forçamos um refresh simples: RecarregarAlerta(existente); } OnPropertyChanged(nameof(AlertasAtivos)); } public void RemoverAlerta(string roverId, T_Code modulo, SeveridadeAlerta? severidade = null, string modId = null) { if (!Application.Current.Dispatcher.CheckAccess()) { Application.Current.Dispatcher.BeginInvoke(new Action(() => RemoverAlerta(roverId, modulo, severidade, modId))); return; } var alerta = AlertasAtivos.FirstOrDefault(x => x.Rover_ID == roverId && x.Modulo == modulo && x.Mod_ID == modId && (severidade != null ? x.Severidade == severidade : true)); if (alerta != null) { AlertasAtivos.Remove(alerta); if (ReferenceEquals(ToastAlerta, alerta)) ToastAlerta = null; if (ReferenceEquals(AlertaSelecionado, alerta)) AlertaSelecionado = null; } OnPropertyChanged(nameof(AlertasAtivos)); } public void MostrarToast(AlertaModel alerta) { ToastAlerta = alerta; _toastTimer.Stop(); _toastTimer.Start(); } public void LimparToast() { _toastTimer.Stop(); ToastAlerta = null; } public void DefinirAlertas(params AlertaModel[] alertas) { if (!Application.Current.Dispatcher.CheckAccess()) { Application.Current.Dispatcher.BeginInvoke(new Action(() => DefinirAlertas(alertas))); return; } AlertasAtivos.Clear(); if (alertas != null) { foreach (var alerta in alertas) AlertasAtivos.Add(alerta); } OnPropertyChanged(nameof(AlertasAtivos)); } private void RecarregarAlerta(AlertaModel alerta) { var idx = AlertasAtivos.IndexOf(alerta); if (idx >= 0) { AlertasAtivos.RemoveAt(idx); AlertasAtivos.Insert(idx, alerta); } } private void OnPropertyChanged(string nome) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome)); } public void AtualizarListaAlertasRoverSelecionado(string rover_id) { var rover = VariaveisControleOperacao.RoversNaRede.FirstOrDefault(x => x.RoverId == rover_id); if (rover == null) return; var dados_leitura = rover?.DadosLeitura; if (dados_leitura?.ModulosSaude == null) return; SeveridadeAlerta DeParaStatus(StatusModulo status, bool mandatorio) { switch (status) { case StatusModulo.Operante: return SeveridadeAlerta.Info; case StatusModulo.Alerta: return SeveridadeAlerta.Warning; case StatusModulo.Falha: return mandatorio ? SeveridadeAlerta.Critical : SeveridadeAlerta.Error; case StatusModulo.Conectado: return mandatorio ? SeveridadeAlerta.Warning : SeveridadeAlerta.Info; case StatusModulo.Desconectado: return mandatorio ? SeveridadeAlerta.Critical : SeveridadeAlerta.Error; default: return SeveridadeAlerta.Info; } } foreach (var mod in dados_leitura.ModulosSaude) { if (mod.saude_individual.Any()) { foreach (var ind in mod.saude_individual) { if (ind.status != StatusModulo.Operante) { AdicionarAlerta(rover.RoverId, mod.modulo, DeParaStatus(ind.status, ind.em_uso), string.Join(", ", ind.motivos), modId: ind.label); } else { RemoverAlerta(rover.RoverId, mod.modulo, modId: ind.label); } } } else { if (mod.status != StatusModulo.Operante) { AdicionarAlerta(rover.RoverId, mod.modulo, DeParaStatus(mod.status, rover.ModulosMandatorios?.Any(x => x.Dispositivo == mod.modulo && x.Mandatorio) ?? false), string.Join(", ", mod.motivos)); } else { RemoverAlerta(rover.RoverId, mod.modulo); } } } } } }