agrobot_base/AgroBase/AgroBase/Forms/IHM/frmDiagnosticos.cs

953 lines
35 KiB
C#

using AgroBase.Forms.IHM.Controls;
using AgroBase.Models;
using AgroBase.Models.Operacoes;
using AgroBase.Models.Operadores;
using AgroBase.Services;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using static AgroBase.Models.Enums;
namespace AgroBase.Forms.IHM
{
public partial class frmDiagnosticos : Form, ITelaNavegavel
{
public class DiagnosticoGraficoSerieViewModel
{
private string _label;
public string Label
{
get => _label;
set => _label = value;
}
private string _unidade;
public string Unidade
{
get => _unidade;
set => _unidade = value;
}
public ObservableCollection<double> Valores { get; } = new ObservableCollection<double>();
}
public ObservableCollection<DiagnosticoGraficoSerieViewModel> SeriesGrafico { get; } = new ObservableCollection<DiagnosticoGraficoSerieViewModel>();
public ObservableCollection<string> LabelsGrafico { get; } = new ObservableCollection<string>();
private string _ultimoIdGrafico = "";
private enum AbaDiagnostico
{
Condicoes,
Acompanhamento,
Opcoes,
Logs
}
private AbaDiagnostico _abaAtual = AbaDiagnostico.Acompanhamento;
private HmiBufferedListView _lstCondicoes;
private HmiBufferedListView _lstLogs;
private Chart _graficoAcompanhamento;
private FlowLayoutPanel _pnlOpcoes;
private Label _lblSemOpcoes;
private OperacaoModel op => Variaveis.OperacaoEmAndamento;
public event EventHandler VoltarSolicitado;
private readonly List<HmiModuleBadge> _badges = new List<HmiModuleBadge>();
private HmiModuleBadge _badgeSelecionada => _badges.FirstOrDefault(x => x.Selecionado);
public frmDiagnosticos()
{
InitializeComponent();
ConfigurarConteudoAbas();
OrganizarCamadasMapa();
ConfigurarEstadoInicial();
VincularEventos();
ExibirAba(AbaDiagnostico.Acompanhamento, "Acompanhamento e histórico em tempo real");
}
private void ConfigurarEstadoInicial()
{
tabCondicoes.Selected = false;
tabAcompanhamento.Selected = true;
tabOpcoes.Selected = false;
tabLogs.Selected = false;
RegistrarBadges();
}
private void RegistrarBadges()
{
foreach (var badge in pnlMapa.Controls.OfType<HmiModuleBadge>())
{
_badges.Add(badge);
}
}
private void VincularEventos()
{
btnVoltar.Click += btnVoltar_Click;
btnSalvarModulo.Click += BtnSalvarModulo_Click;
tabCondicoes.Click += delegate
{
ExibirAba(AbaDiagnostico.Condicoes, "Condições operacionais do módulo");
};
tabAcompanhamento.Click += delegate
{
ExibirAba(AbaDiagnostico.Acompanhamento, "Acompanhamento e histórico em tempo real");
};
tabOpcoes.Click += delegate
{
ExibirAba(AbaDiagnostico.Opcoes, "Ações locais disponíveis para o módulo");
};
tabLogs.Click += delegate
{
ExibirAba(AbaDiagnostico.Logs, "Logs recentes do módulo");
};
chkEmUso.CheckedChanged += delegate
{
if (_badgeSelecionada == null)
return;
_badgeSelecionada.EmUso = chkEmUso.Checked;
};
chkMandatorio.CheckedChanged += delegate
{
if (_badgeSelecionada == null)
return;
_badgeSelecionada.Mandatorio = chkMandatorio.Checked;
};
foreach (HmiModuleBadge badge in _badges)
badge.Click += Badge_Click;
}
private void OrganizarCamadasMapa()
{
picRover.SendToBack();
lblMapaTitulo.BringToFront();
pnlImpedimentoMapa.BringToFront();
pnlLegenda.BringToFront();
foreach (Control controle in pnlMapa.Controls)
{
HmiModuleBadge badge = controle as HmiModuleBadge;
if (badge != null)
badge.BringToFront();
}
}
private void ConfigurarConteudoAbas()
{
detailBodyLayout.SuspendLayout();
detailBodyLayout.Controls.Clear();
detailBodyLayout.RowCount = 1;
detailBodyLayout.ColumnCount = 1;
detailBodyLayout.RowStyles.Clear();
detailBodyLayout.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
detailBodyLayout.ColumnStyles.Clear();
detailBodyLayout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
_lstCondicoes = CriarListaDiagnostico();
_lstCondicoes.Name = "lstCondicoes";
_lstLogs = CriarListaDiagnostico();
_lstLogs.Name = "lstLogs";
_graficoAcompanhamento = CriarGraficoAcompanhamento();
_pnlOpcoes = new FlowLayoutPanel();
_pnlOpcoes.Name = "pnlOpcoes";
_pnlOpcoes.Dock = DockStyle.Fill;
_pnlOpcoes.BackColor = Color.Transparent;
_pnlOpcoes.FlowDirection = FlowDirection.TopDown;
_pnlOpcoes.WrapContents = false;
_pnlOpcoes.AutoScroll = true;
_pnlOpcoes.Padding = new Padding(4);
_lblSemOpcoes = new Label();
_lblSemOpcoes.AutoSize = false;
_lblSemOpcoes.Size = new Size(320, 45);
_lblSemOpcoes.Font = new Font("Segoe UI", 8F);
_lblSemOpcoes.ForeColor = HmiTheme.TextMuted;
_lblSemOpcoes.TextAlign = ContentAlignment.MiddleCenter;
_lblSemOpcoes.Text = "Nenhuma opção local disponível para este módulo.";
_pnlOpcoes.Controls.Add(_lblSemOpcoes);
/*
* Todos ocupam a mesma célula.
* Apenas um ficará visível por vez.
*/
detailBodyLayout.Controls.Add(_lstCondicoes, 0, 0);
detailBodyLayout.Controls.Add(_graficoAcompanhamento, 0, 0);
detailBodyLayout.Controls.Add(_pnlOpcoes, 0, 0);
detailBodyLayout.Controls.Add(_lstLogs, 0, 0);
detailBodyLayout.ResumeLayout(true);
}
private HmiBufferedListView CriarListaDiagnostico()
{
HmiBufferedListView lista = new HmiBufferedListView();
lista.Dock = DockStyle.Fill;
lista.View = View.Details;
lista.FullRowSelect = true;
lista.GridLines = false;
lista.HeaderStyle = ColumnHeaderStyle.None;
lista.MultiSelect = false;
lista.HideSelection = false;
lista.BackColor = Color.FromArgb(20, 25, 29);
lista.ForeColor = HmiTheme.Text;
lista.BorderStyle = BorderStyle.FixedSingle;
lista.Font = new Font("Segoe UI", 7.8F);
lista.Columns.Add("Descrição", 320, HorizontalAlignment.Left);
lista.Resize += delegate
{
if (lista.Columns.Count > 0)
{
lista.Columns[0].Width = Math.Max(50, lista.ClientSize.Width - 4);
}
};
return lista;
}
private Chart CriarGraficoAcompanhamento()
{
Chart chart = new Chart();
chart.Name = "graficoAcompanhamento";
chart.Dock = DockStyle.Fill;
chart.BackColor = Color.FromArgb(20, 25, 29);
chart.BorderlineWidth = 0;
ChartArea area = new ChartArea("Principal");
area.BackColor = Color.FromArgb(20, 25, 29);
area.AxisX.LabelStyle.ForeColor = HmiTheme.TextMuted;
area.AxisY.LabelStyle.ForeColor = HmiTheme.TextMuted;
area.AxisX.LineColor = HmiTheme.Border;
area.AxisY.LineColor = HmiTheme.Border;
area.AxisX.MajorGrid.LineColor = Color.FromArgb(38, 46, 52);
area.AxisY.MajorGrid.LineColor = Color.FromArgb(38, 46, 52);
area.AxisX.LabelStyle.Font = new Font("Segoe UI", 6.5F);
area.AxisY.LabelStyle.Font = new Font("Segoe UI", 6.5F);
area.AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
area.AxisX.IsMarginVisible = false;
chart.ChartAreas.Add(area);
Legend legenda = new Legend("Legenda");
legenda.Docking = Docking.Top;
legenda.Alignment = StringAlignment.Center;
legenda.BackColor = Color.Transparent;
legenda.ForeColor = HmiTheme.Text;
legenda.Font = new Font("Segoe UI", 6.5F);
chart.Legends.Add(legenda);
return chart;
}
public void AtualizarDadosTela()
{
string impedimento = op?.Sensoriamento?.Operacao?.ErroOperacaoLiberada ?? "Nenhum";
impedimento = impedimento.Replace("\n\n", "; ");
lblImpedimentoMapa.Text = $"Impedimento: {impedimento}";
foreach (var badge in _badges)
{
AtualizarStatusBadge(badge);
}
AtualizarDadosModSelecionado();
}
private void AtualizarStatusBadge(HmiModuleBadge badge)
{
if (op?.Parametros?.ModulosMandatorios == null)
return;
StatusModulo status = StatusModulo.Desconectado;
bool mandatorio = false;
bool em_uso = false;
OperacaoModulosMandatoriosModel mod = op?.Parametros?.ModulosMandatorios?.FirstOrDefault(x => x.Dispositivo == badge.ModuleCode);
var mods_saude = op?.Sensoriamento?.OperadorSaude?.ModulosSaude;
var _saude = mods_saude?.FirstOrDefault(x => x.modulo == badge.ModuleCode);
if (_saude != null)
{
if (badge.ModuleSubCode == S_Code.sVZO)
{
status = _saude.status;
mandatorio = mod?.Mandatorio ?? false;
em_uso = mod?.Utilizar ?? false;
}
else
{
var _ind = _saude.saude_individual?.FirstOrDefault(x => x.id == badge.ModuleID);
if (_ind != null)
{
status = _ind.status;
}
(bool mandatorio, bool emUso) modInd;
if (mod != null && mod.ComponentesEmUso != null && mod.ComponentesEmUso.TryGetValue(badge.ModuleID, out modInd))
{
mandatorio = modInd.mandatorio;
em_uso = modInd.emUso;
}
}
}
badge.State = status;
if (!badge.Equals(_badgeSelecionada))
{
badge.Mandatorio = mandatorio;
badge.EmUso = em_uso;
}
}
private void AtualizarDadosModSelecionado()
{
if (_badgeSelecionada == null)
return;
var badge = _badgeSelecionada;
var parametros = op?.Parametros;
var sensoriamento = op?.Sensoriamento;
var mods_saude = sensoriamento?.OperadorSaude?.ModulosSaude;
bool badge_principal = badge.ModuleSubCode == S_Code.sVZO && !SerialService.DispositivosMultiplos.Contains(badge.ModuleCode);
StatusModulo status = badge.State;
bool mandatorio = badge.Mandatorio;
bool em_uso = badge.EmUso;
List<string> motivos = new List<string>();
List<ManagerWorkerMessageResponseModulosPendentesSaudeCondicoesModel> condicoes = new List<ManagerWorkerMessageResponseModulosPendentesSaudeCondicoesModel>();
double saude = 0.0;
bool iniciado = ObterIniciado(badge, parametros);
double can = CalcularLatenciaCan(badge.ModuleCode, sensoriamento, badge.ModuleID);
double latencia = 0.0;
var _saude = mods_saude?.FirstOrDefault(x => x.modulo == badge.ModuleCode);
if (_saude != null)
{
if (badge_principal)
{
saude = _saude.saude;
motivos.AddRange(_saude.motivos);
condicoes.AddRange(_saude.condicoes_operacionais);
}
else
{
var _ind = _saude.saude_individual?.FirstOrDefault(x => x.label == badge.ModuleID);
if (_ind != null)
{
saude = _ind.saude;
motivos.AddRange(_ind.motivos);
condicoes.AddRange(_ind.condicoes_operacionais);
}
}
}
string impedimento = motivos.Any() ? string.Join(", ", motivos) : "Nenhum";
lblImpedimentoModulo.Text = $"Impedimento: {impedimento}";
lblModulo.Text = $"Módulo: {badge.ModuleCode}";
lblID.Text = $"ID: {badge.ModuleID}";
lblSCode.Text = $"SCode: {badge.ModuleSubCode}";
lblStatus.Text = $"Status: {status}";
lblSaude.Text = $"Saúde: {saude:F0}%";
lblIniciado.Text = $"Iniciado: " + (iniciado ? "SIM" : "NÃO");
lblCan.Text = $"CAN: {can:F0} ms";
lblLatencia.Text = $"Latência: {latencia:F0} ms";
chkMandatorio.Checked = mandatorio;
chkEmUso.Checked = em_uso;
badge.CondicoesOperacionais.Clear();
foreach (var cond in condicoes)
badge.CondicoesOperacionais.Add($"{cond.descricao} (Valor: {cond.valor}, Severidade: {cond.severidade:0}%)");
badge.Logs.Clear();
var logs = parametros?.DadosLeitura?.Logs?.Where(x => x.Dispositivo == badge.ModuleCode);
if (!badge_principal)
logs = logs?.Where(x => x.ID == badge.ModuleID);
else
logs = logs?.Where(x => x.ID == null);
if (logs != null)
{
foreach (var log in logs)
badge.Logs.Add($"{log.Momento:HH:mm:ss.fff} - {log.Mensagem}");
}
AtualizarGraficoModuloSelecionado(parametros);
AtualizarConteudoAbaAtual();
}
private double CalcularLatenciaCan(T_Code modulo, OperacaoSensoriamentoConjuntoModel dados, string mod_id = null)
{
DateTime ucr = DateTime.MinValue;
if (modulo == T_Code.Bat)
ucr = dados?.Bateria?.Momento ?? DateTime.MinValue;
else if (modulo == T_Code.Sen)
ucr = dados?.Sensoriamento?.UltimoComandoRespondido ?? DateTime.MinValue;
else if (modulo == T_Code.Atu)
ucr = dados?.Atuador?.UltimoComandoRespondido ?? DateTime.MinValue;
else if (modulo == T_Code.Mov)
ucr = dados?.Movimentacao?.Modulos?.FirstOrDefault(x => x.Modulo_ID == mod_id)?.UltimoComandoRespondido ?? DateTime.MinValue;
else if (modulo == T_Code.Dir)
ucr = dados?.Direcional?.Modulos?.FirstOrDefault(x => x.Modulo_ID == mod_id)?.UltimoComandoRespondido ?? DateTime.MinValue;
else
ucr = dados?.Momento ?? DateTime.MinValue;
DateTime momento = dados?.Momento ?? DateTime.MinValue;
double canLatencia = (ucr - momento).TotalMilliseconds;
return canLatencia;
}
private bool ObterIniciado(HmiModuleBadge badge, OperacaoParametrosModel dados)
{
var rover = dados?.DadosLeitura;
if (rover == null)
return false;
switch (badge.ModuleCode)
{
case T_Code.Mov:
return rover.Movimentacao?.Modulos?.FirstOrDefault(x => x.Modulo_ID == badge.ModuleID)?.Inicializado ?? false;
case T_Code.Dir:
return rover.Direcional?.Modulos?.FirstOrDefault(x => x.Modulo_ID == badge.ModuleID)?.Inicializado ?? false;
case T_Code.Atu:
if (string.IsNullOrWhiteSpace(badge.ModuleID))
return rover.Atuador?.Iniciado ?? false;
switch (badge.ModuleSubCode)
{
case S_Code.sBIC:
return rover.Atuador?.Bicos?.FirstOrDefault(x => x.ID == badge.ModuleID)?.Inicializado ?? false;
case S_Code.sBMB:
return rover.Atuador?.Bombas?.FirstOrDefault(x => x.ID == badge.ModuleID)?.Inicializado ?? false;
//case S_Code.sSRV:
// return rover.Atuador?.Servos?.FirstOrDefault(x => x.ID == item.LabelModulo)?.Inicializado ?? false;
default:
return rover.Atuador?.Sensores?.FirstOrDefault(x => x.ID == badge.ModuleID && x.Componente == badge.ModuleSubCode)?.Inicializado ?? false;
}
case T_Code.Sen:
if (string.IsNullOrWhiteSpace(badge.ModuleID))
return rover.Sensoriamento?.Iniciado ?? false;
switch (badge.ModuleSubCode)
{
case S_Code.sLED:
return rover.Sensoriamento?.Sinaleiros?.FirstOrDefault(x => x.ID == badge.ModuleID)?.Inicializado ?? false;
case S_Code.sRLE:
return rover.Sensoriamento?.Reles?.FirstOrDefault(x => x.ID == badge.ModuleID)?.Inicializado ?? false;
case S_Code.sSRV:
return rover.Sensoriamento?.Servos?.FirstOrDefault(x => x.ID == badge.ModuleID)?.Inicializado ?? false;
default:
return rover.Sensoriamento?.Sensores?.FirstOrDefault(x => x.ID == badge.ModuleID && x.Componente == badge.ModuleSubCode)?.Inicializado ?? false;
}
case T_Code.Imu:
return rover.Imu?.Iniciado ?? false;
case T_Code.Npc:
case T_Code.Ipb:
return dados.Alive;
case T_Code.Can:
return rover.DispositivosMapeados?.Any(x => x.Dispositivo == T_Code.Can) ?? false;
case T_Code.Cam:
case T_Code.Snr:
case T_Code.Lvx:
case T_Code.Gps:
return rover.DispositivosMapeados?.FirstOrDefault(x => x.Dispositivo == badge.ModuleCode)?.Saude > 0;
case T_Code.Bat:
return rover.Bateria?.Iniciado ?? false;
case T_Code.Trj:
return rover.Trajetoria?.QtdPontos > 0;
default:
return false;
}
}
private void BtnSalvarModulo_Click(object sender, EventArgs e)
{
if (_badgeSelecionada == null)
return;
if (op?.Parametros?.ModulosMandatorios == null)
return;
OperacaoModulosMandatoriosModel mod = op?.Parametros?.ModulosMandatorios?.FirstOrDefault(x => x.Dispositivo == _badgeSelecionada.ModuleCode);
if (mod == null)
{
mod = new OperacaoModulosMandatoriosModel()
{
Dispositivo = _badgeSelecionada.ModuleCode,
Utilizar = false,
Mandatorio = false,
Conectado = false,
ComponentesEmUso = new Dictionary<string, (bool, bool)>()
};
op.Parametros.ModulosMandatorios.Add(mod);
}
mod.Mandatorio = _badgeSelecionada.Mandatorio;
mod.Utilizar = _badgeSelecionada.EmUso;
}
private void btnVoltar_Click(object sender, EventArgs e)
{
if (VoltarSolicitado != null)
VoltarSolicitado(this, EventArgs.Empty);
}
private void Badge_Click(object sender, EventArgs e)
{
HmiModuleBadge selecionado = sender as HmiModuleBadge;
if (selecionado == null)
return;
foreach (HmiModuleBadge badge in _badges)
{
badge.Selecionado = false;
}
selecionado.Selecionado = true;
LimparHistoricoGrafico();
AtualizarStatusBadge(selecionado);
AtualizarDadosModSelecionado();
AtualizarConteudoAbaAtual();
}
private void ExibirAba(AbaDiagnostico aba, string descricao)
{
_abaAtual = aba;
tabCondicoes.Selected = aba == AbaDiagnostico.Condicoes;
tabAcompanhamento.Selected = aba == AbaDiagnostico.Acompanhamento;
tabOpcoes.Selected = aba == AbaDiagnostico.Opcoes;
tabLogs.Selected = aba == AbaDiagnostico.Logs;
_lstCondicoes.Visible = aba == AbaDiagnostico.Condicoes;
_graficoAcompanhamento.Visible = aba == AbaDiagnostico.Acompanhamento;
_pnlOpcoes.Visible = aba == AbaDiagnostico.Opcoes;
_lstLogs.Visible = aba == AbaDiagnostico.Logs;
lblConteudoAba.Text = descricao;
switch (aba)
{
case AbaDiagnostico.Condicoes:
_lstCondicoes.BringToFront();
break;
case AbaDiagnostico.Acompanhamento:
_graficoAcompanhamento.BringToFront();
break;
case AbaDiagnostico.Opcoes:
_pnlOpcoes.BringToFront();
break;
case AbaDiagnostico.Logs:
_lstLogs.BringToFront();
break;
}
AtualizarConteudoAbaAtual();
}
private void AtualizarConteudoAbaAtual()
{
if (_badgeSelecionada == null)
{
LimparConteudoDiagnostico();
return;
}
switch (_abaAtual)
{
case AbaDiagnostico.Condicoes:
AtualizarListaCondicoes();
break;
case AbaDiagnostico.Acompanhamento:
AtualizarVisualGrafico();
break;
case AbaDiagnostico.Opcoes:
//AtualizarOpcoesModulo();
break;
case AbaDiagnostico.Logs:
AtualizarListaLogs();
break;
}
}
private void LimparConteudoDiagnostico()
{
if (_lstCondicoes != null)
_lstCondicoes.Items.Clear();
if (_lstLogs != null)
_lstLogs.Items.Clear();
if (_graficoAcompanhamento != null)
_graficoAcompanhamento.Series.Clear();
}
private void LimparHistoricoGrafico()
{
SeriesGrafico.Clear();
LabelsGrafico.Clear();
_ultimoIdGrafico = string.Empty;
if (_graficoAcompanhamento != null)
_graficoAcompanhamento.Series.Clear();
}
private void AtualizarListaCondicoes()
{
List<string> itens = new List<string>();
if (_badgeSelecionada == null || _badgeSelecionada.CondicoesOperacionais == null || _badgeSelecionada.CondicoesOperacionais.Count == 0)
{
itens.Add("Nenhuma condição operacional registrada.");
}
else
{
itens.AddRange(_badgeSelecionada.CondicoesOperacionais);
}
_lstCondicoes.SincronizarLista(itens);
}
private void AtualizarListaLogs()
{
List<string> itens = new List<string>();
if (_badgeSelecionada == null || _badgeSelecionada.Logs == null || _badgeSelecionada.Logs.Count == 0)
{
itens.Add("Nenhum log recente para este módulo.");
}
else
{
int inicio = Math.Max(0, _badgeSelecionada.Logs.Count - 100);
for (int i = inicio; i < _badgeSelecionada.Logs.Count; i++)
{
itens.Add(_badgeSelecionada.Logs[i]);
}
}
bool estavaNoFinal = _lstLogs.EstaNoFinalDaLista();
_lstLogs.SincronizarLista(itens);
if (estavaNoFinal && _lstLogs.Items.Count > 0)
{
_lstLogs.EnsureVisible(_lstLogs.Items.Count - 1);
}
}
private void AtualizarVisualGrafico()
{
if (_graficoAcompanhamento == null)
return;
_graficoAcompanhamento.SuspendLayout();
try
{
_graficoAcompanhamento.Series.Clear();
if (SeriesGrafico.Count == 0)
return;
foreach (DiagnosticoGraficoSerieViewModel item in SeriesGrafico)
{
Series serie = new Series(item.Label);
serie.ChartType = SeriesChartType.Line;
serie.ChartArea = "Principal";
serie.Legend = "Legenda";
serie.BorderWidth = 2;
serie.IsVisibleInLegend = true;
serie.LegendText = string.IsNullOrWhiteSpace(item.Unidade) ? item.Label : item.Label + " (" + item.Unidade + ")";
serie.XValueType = ChartValueType.String;
int quantidade = Math.Min(item.Valores.Count, LabelsGrafico.Count);
int inicioValores = item.Valores.Count - quantidade;
int inicioLabels = LabelsGrafico.Count - quantidade;
for (int i = 0; i < quantidade; i++)
{
string label = LabelsGrafico[inicioLabels + i];
double valor = item.Valores[inicioValores + i];
serie.Points.AddXY(label, valor);
}
_graficoAcompanhamento.Series.Add(serie);
}
_graficoAcompanhamento.Invalidate();
}
finally
{
_graficoAcompanhamento.ResumeLayout();
}
}
private void AtualizarGraficoModuloSelecionado(OperacaoParametrosModel parametros)
{
string idAtual = string.Empty;
if (_badgeSelecionada != null)
{
idAtual = _badgeSelecionada.ModuleCode + "|" + _badgeSelecionada.ModuleSubCode + "|" + (_badgeSelecionada.ModuleID ?? string.Empty);
}
if (_ultimoIdGrafico != idAtual)
{
SeriesGrafico.Clear();
LabelsGrafico.Clear();
_ultimoIdGrafico = idAtual;
}
if (_badgeSelecionada == null || parametros?.DadosLeitura == null)
return;
var rover = parametros?.DadosLeitura;
HmiModuleBadge item = _badgeSelecionada;
if (rover == null)
return;
rover.Atualizar();
DateTime? momento = rover.Momento;
if (momento.HasValue)
{
LabelsGrafico.Add(momento.Value.ToString("HH:mm:ss"));
while (LabelsGrafico.Count > 60)
LabelsGrafico.RemoveAt(0);
}
void AddOrAppendSerie(string label, string unidade, double? valor)
{
if (!valor.HasValue)
return;
var serie = SeriesGrafico.FirstOrDefault(x => x.Label == label && x.Unidade == unidade);
if (serie == null)
{
serie = new DiagnosticoGraficoSerieViewModel
{
Label = label,
Unidade = unidade
};
SeriesGrafico.Add(serie);
}
serie.Valores.Add(valor.Value);
while (serie.Valores.Count > 60)
serie.Valores.RemoveAt(0);
}
switch (item.ModuleCode)
{
case T_Code.Sen:
switch (item.ModuleSubCode)
{
case S_Code.sCOR:
var barramento = rover.Bateria?.Barramentos?.FirstOrDefault(x => x.ID == item.ModuleID);
AddOrAppendSerie("Corrente", "mA", barramento?.Corrente);
AddOrAppendSerie("Tensão", "V", barramento?.Tensao);
AddOrAppendSerie("Potência", "mW", barramento?.Potencia);
AddOrAppendSerie("Energia", "J", barramento?.Energia);
AddOrAppendSerie("Temperatura", "°C", barramento?.Temperatura);
break;
case S_Code.sNTC:
var ntc = rover.Sensoriamento?.Sensores?
.FirstOrDefault(x => x.ID == item.ModuleID && x.Componente == item.ModuleSubCode)?
.Valores?[0];
AddOrAppendSerie("Temperatura", "°C", ntc);
break;
case S_Code.sRLE:
var rele = rover.Sensoriamento?.Reles?.FirstOrDefault(x => x.ID == item.ModuleID);
AddOrAppendSerie("Comando", "", rele?.ComandoEstado == true ? 1 : 0);
AddOrAppendSerie("Leitura", "", rele?.LeituraEstado == true ? 1 : 0);
break;
case S_Code.sSRV:
var servoSen = rover.Sensoriamento?.Servos?.FirstOrDefault(x => x.ID == item.ModuleID);
AddOrAppendSerie("Comando", "°", servoSen?.ComandoAngulo);
AddOrAppendSerie("Leitura", "°", servoSen?.LeituraAngulo);
break;
}
break;
case T_Code.Atu:
switch (item.ModuleSubCode)
{
case S_Code.sBIC:
var bico = rover.Atuador?.Bicos?.FirstOrDefault(x => x.ID == item.ModuleID);
AddOrAppendSerie("Cmd", "", bico?.ComandoEstado ?? false ? 100 : 0);
AddOrAppendSerie("Vazão", "mL/s", bico?.VazaoInstantaneaMLs);
break;
case S_Code.sBMB:
var bomba = rover.Atuador?.Bombas?.FirstOrDefault(x => x.ID == item.ModuleID);
AddOrAppendSerie("Cmd", "", bomba?.ComandoEstado ?? false ? 100 : 0);
AddOrAppendSerie("Potência", "%", bomba?.LeituraPotencia);
AddOrAppendSerie("Pressão", "psi", bomba?.ComandoPressao);
break;
case S_Code.sPRS:
AddOrAppendSerie("Pressão", "psi", rover.Atuador?.PressaoLinhaPsi);
break;
case S_Code.sFLX:
AddOrAppendSerie("Fluxo", "mL/s", rover.Atuador?.VazaoInstantaneaMLs);
AddOrAppendSerie("Média", "mL/s", rover.Atuador?.VazaoMediaMLs);
break;
case S_Code.sMAS:
AddOrAppendSerie("Volume", "L", rover.Atuador?.VolumeReservatorioL);
AddOrAppendSerie("Massa", "Kg", rover.Atuador?.MassaReservatorioKg);
AddOrAppendSerie("Percentual", "%", rover.Atuador?.PercentualReservatorio);
break;
}
break;
case T_Code.Mov:
var mov = rover.Movimentacao?.Modulos?.FirstOrDefault(x => x.Modulo_ID == item.ModuleID);
AddOrAppendSerie("Tensão", "V", mov?.Tensao);
AddOrAppendSerie("Corrente M", "A", mov?.CorrenteMotor);
AddOrAppendSerie("Corrente B", "A", mov?.CorrenteBarramento);
AddOrAppendSerie("Ciclo", "%", mov?.CicloTrabalho);
AddOrAppendSerie("Temperatura", "°C", mov?.TemperaturaDriver);
AddOrAppendSerie("RPM", "", mov?.RPM_Roda);
break;
case T_Code.Npc:
var npc = rover.PerformanceNcp;
AddOrAppendSerie("GPU %", "%", npc?.GPU_load);
AddOrAppendSerie("GPU °C", "°C", npc?.GPU_temp);
AddOrAppendSerie("CPU %", "%", npc?.CPU_load);
AddOrAppendSerie("CPU °C", "°C", npc?.CPU_temp);
AddOrAppendSerie("RAM", "MB", npc?.RAM_usage);
break;
case T_Code.Ipb:
var conexao = rover.ModulosSaude?.FirstOrDefault(x => x.modulo == T_Code.Ipb);
AddOrAppendSerie("Latência", "ms", conexao?.detalhes?["avg_rtt"]?.Value<double?>());
AddOrAppendSerie("Jitter", "ms", conexao?.detalhes?["jitter"]?.Value<double?>());
AddOrAppendSerie("Timeout", "%", conexao?.detalhes?["tmout_pct"]?.Value<double?>());
AddOrAppendSerie("Perda", "%", conexao?.detalhes?["loss_pct"]?.Value<double?>());
AddOrAppendSerie("Banda", "%", conexao?.detalhes?["bw_util_pct"]?.Value<double?>());
break;
case T_Code.Gps:
var gps = rover.Gnss;
AddOrAppendSerie("Precisão", "cm", gps?.PrecisaoCm);
AddOrAppendSerie("Altitude", "m", gps?.Altitude);
AddOrAppendSerie("Idade", "s", gps?.IdadeCorrecao);
AddOrAppendSerie("Satélites", "", gps?.NumeroSatelites);
break;
case T_Code.Bat:
var bat = rover.Bateria;
AddOrAppendSerie("Tensão", "V", bat?.TensaoInstantanea);
AddOrAppendSerie("Corrente", "A", bat?.CorrenteInstantanea);
AddOrAppendSerie("Temperatura", "°C", bat?.Temperatura);
break;
case T_Code.Imu:
var imu = rover.Imu;
AddOrAppendSerie("Movimento", "", imu?.IndiceMovimento);
AddOrAppendSerie("Estabilidade", "", imu?.IndiceEstabilidade);
AddOrAppendSerie("Rugosidade", "", imu?.IndiceRugosidade);
AddOrAppendSerie("Impacto", "", imu?.IndiceImpacto);
break;
}
}
}
}