agrobot_base/AgroBase/OperationControl/ViewModels/Views/Operacao/OperacaoBottomViewModel.cs

249 lines
8.1 KiB
C#

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<AlertaModel>();
_toastTimer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(5)
};
_toastTimer.Tick += (s, e) =>
{
_toastTimer.Stop();
ToastAlerta = null;
};
}
public ObservableCollection<AlertaModel> 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<AlertaModel> 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);
}
}
}
}
}
}