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

337 lines
12 KiB
C#
Raw Normal View History

using OperationControl.Models;
2026-03-20 02:03:07 +00:00
using OperationControl.ViewModels.Views.Operacao.Monitoramento;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Threading;
using static AgroBase.Models.Enums;
namespace OperationControl.ViewModels.Views.Operacao
{
public class OperacaoBottomViewModel : INotifyPropertyChanged
{
2026-03-20 02:03:07 +00:00
private HistoricoViewModel? historicoVm => Variaveis.Dock?._vm?._viewOperacaoCenter?.Historico?._vm;
public ObservableCollection<AlertaModel> AlertasAtivos { get; } = new();
private AlertaModel _toastAlerta;
public AlertaModel ToastAlerta
{
get => _toastAlerta;
set
{
if (_toastAlerta == value) return;
_toastAlerta = value;
OnPropertyChanged(nameof(ToastAlerta));
}
}
private readonly DispatcherTimer _toastTimer;
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
// EVENTO PARA O PAI TRATAR A NAVEGAÇÃO
public event Action<AlertaModel> SolicitarAbrirDiagnostico;
public OperacaoBottomViewModel()
{
_toastTimer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(6)
};
_toastTimer.Tick += (s, e) =>
{
_toastTimer.Stop();
ToastAlerta = null;
};
}
public void SelecionarAlerta(AlertaModel alerta)
{
if (alerta == null) return;
SolicitarAbrirDiagnostico?.Invoke(alerta);
}
public void LimparToast()
{
_toastTimer.Stop();
ToastAlerta = null;
}
public void MostrarToast(AlertaModel alerta)
{
ToastAlerta = alerta;
_toastTimer.Stop();
_toastTimer.Start();
}
public void AdicionarAlerta(string roverId, AgroBase.Models.Enums.T_Code modulo, SeveridadeAlerta severidade, string mensagem, string? modId = null)
{
App.Current.Dispatcher.BeginInvoke(new Action(() =>
{
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,
CriadoEm = DateTime.Now
};
AlertasAtivos.Add(alerta);
MostrarToast(alerta);
2026-03-20 02:03:07 +00:00
historicoVm?.RegistrarHistoricoAlerta("INICIO", alerta);
}
else
{
2026-03-20 02:03:07 +00:00
bool mudouMensagem = existente.Mensagem != mensagem;
bool mudouSeveridade = existente.Severidade != severidade;
existente.Mensagem = mensagem;
existente.Severidade = severidade;
2026-03-20 02:03:07 +00:00
if (mudouMensagem || mudouSeveridade)
{
historicoVm?.RegistrarHistoricoAlerta("MUDANCA", existente);
}
}
}));
}
public void RemoverAlerta(string roverId, AgroBase.Models.Enums.T_Code modulo, SeveridadeAlerta? severidade = null, string? modId = null)
{
App.Current.Dispatcher.BeginInvoke(new Action(() =>
{
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)
2026-03-20 02:03:07 +00:00
{
historicoVm?.RegistrarHistoricoAlerta("FIM", alerta);
AlertasAtivos.Remove(alerta);
2026-03-20 02:03:07 +00:00
}
}));
}
public void ClicarNoAlerta(AlertaModel alerta)
{
if (alerta == null) return;
SelecionarAlerta(alerta);
}
public void ClicarNoToast()
{
var alerta = ToastAlerta;
if (alerta == null) return;
LimparToast();
SelecionarAlerta(alerta);
}
2026-03-12 01:00:21 +00:00
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;
}
}
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;
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);
}
}
}
}
2026-03-12 01:00:21 +00:00
public void AtualizarListaAlertasTodosRovers()
{
App.Current.Dispatcher.BeginInvoke(new Action(() =>
{
string GerarChave(string roverId, T_Code modulo, string? modId) => $"{roverId}|{modulo}|{modId ?? ""}";
var agora = DateTime.Now;
// 1) Gera os alertas que DEVERIAM existir neste momento
2026-03-12 01:00:21 +00:00
var alertasEsperados = new List<AlertaModel>();
foreach (var rover in VariaveisControleOperacao.RoversNaRede)
{
var dadosLeitura = rover?.DadosLeitura;
if (dadosLeitura?.ModulosSaude == null)
continue;
foreach (var mod in dadosLeitura.ModulosSaude)
{
if (mod.saude_individual != null && mod.saude_individual.Any())
{
foreach (var ind in mod.saude_individual)
{
if (ind.status == StatusModulo.Operante)
continue;
bool mandatorio = ind.em_uso;
if (mandatorio)
2026-03-12 01:00:21 +00:00
{
alertasEsperados.Add(new AlertaModel
{
Rover_ID = rover.RoverId,
Modulo = mod.modulo,
Mod_ID = ind.label,
Severidade = DeParaStatus(ind.status, mandatorio),
Mensagem = string.Join(", ", ind.motivos ?? new List<string>())
// NÃO define Timestamp aqui ainda
});
}
2026-03-12 01:00:21 +00:00
}
}
else
{
if (mod.status == StatusModulo.Operante)
continue;
bool mandatorio = rover.ModulosMandatorios?.Any(x =>
x.Dispositivo == mod.modulo && x.Utilizar) ?? false;
2026-03-12 01:00:21 +00:00
if (mandatorio)
2026-03-12 01:00:21 +00:00
{
alertasEsperados.Add(new AlertaModel
{
Rover_ID = rover.RoverId,
Modulo = mod.modulo,
Mod_ID = null,
Severidade = DeParaStatus(mod.status, mandatorio),
Mensagem = string.Join(", ", mod.motivos ?? new List<string>() { "Motivo desconhecido" })
// NÃO define Timestamp aqui ainda
});
}
2026-03-12 01:00:21 +00:00
}
}
}
var mapaEsperado = alertasEsperados.ToDictionary(
x => GerarChave(x.Rover_ID, x.Modulo, x.Mod_ID),
x => x);
var mapaAtual = AlertasAtivos.ToDictionary(
x => GerarChave(x.Rover_ID, x.Modulo, x.Mod_ID),
x => x);
// 2) Remove os alertas que não existem mais
var chavesParaRemover = mapaAtual.Keys
.Where(chave => !mapaEsperado.ContainsKey(chave))
.ToList();
2026-03-12 01:00:21 +00:00
foreach (var chave in chavesParaRemover)
2026-03-12 01:00:21 +00:00
{
var alertaRemover = mapaAtual[chave];
2026-03-12 01:00:21 +00:00
2026-03-20 02:03:07 +00:00
historicoVm?.RegistrarHistoricoAlerta("FIM", alertaRemover);
AlertasAtivos.Remove(alertaRemover);
if (ToastAlerta == alertaRemover)
LimparToast();
2026-03-12 01:00:21 +00:00
}
// 3) Adiciona novos ou atualiza os existentes
foreach (var kv in mapaEsperado)
2026-03-12 01:00:21 +00:00
{
var chave = kv.Key;
var esperado = kv.Value;
2026-03-12 01:00:21 +00:00
if (!mapaAtual.TryGetValue(chave, out var existente))
2026-03-12 01:00:21 +00:00
{
// Novo alerta
esperado.CriadoEm = agora;
2026-03-12 01:00:21 +00:00
AlertasAtivos.Add(esperado);
MostrarToast(esperado);
2026-03-20 02:03:07 +00:00
historicoVm?.RegistrarHistoricoAlerta("INICIO", esperado);
2026-03-12 01:00:21 +00:00
}
else
{
// Alerta já existia -> mantém Timestamp original
2026-03-12 01:00:21 +00:00
bool mudou =
existente.Mensagem != esperado.Mensagem ||
existente.Severidade != esperado.Severidade;
if (mudou)
{
existente.Mensagem = esperado.Mensagem;
existente.Severidade = esperado.Severidade;
existente.AtualizadoEm = agora;
2026-03-12 01:00:21 +00:00
MostrarToast(existente);
2026-03-20 02:03:07 +00:00
historicoVm?.RegistrarHistoricoAlerta("MUDANCA", existente);
2026-03-12 01:00:21 +00:00
}
}
}
var ordenado = AlertasAtivos.OrderByDescending(x => x.AtualizadoEm ?? x.CriadoEm).ToList();
AlertasAtivos.Clear();
foreach (var a in ordenado)
{
AlertasAtivos.Add(a);
}
2026-03-12 01:00:21 +00:00
}));
}
}
}