agrobot_base/AgroBase/AgroMonitor/Forms/frmMonitoramento.cs

345 lines
16 KiB
C#

using AgroBase.Models;
using AgroBase.Services;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enums;
namespace AgroMonitor.Forms
{
public partial class frmMonitoramento : Form
{
AsyncTaskTimerModel tmrLeituras;
string EquipamentoSelecionado = "";
DateTime MomentoLog = DateTime.Now;
private MapasModel Mapa;
Dictionary<byte, List<LoRaProtocoloTransmissaoModel>> Logs = new Dictionary<byte, List<LoRaProtocoloTransmissaoModel>>();
Keys UltimoComandoEnviado = Keys.None;
bool ultimStatusoEmergencia = false;
public frmMonitoramento()
{
InitializeComponent();
}
private void frmMonitoramento_Load(object sender, EventArgs e)
{
tmrLeituras = new AsyncTaskTimerModel("tmrLeituras", tmrLeituras_Tick, 1000, this);
tmrLeituras.Start();
cmbTipoMovimento.Items.Clear();
cmbTipoMovimento.Items.AddRange(Enum.GetNames(typeof(TipoMovimentoDirecional)));
cmbTipoMovimento.SelectedIndex = 0;
Mapa = new MapasModel()
{
pnlMapa = pnlMapa,
lblMapa = lblMapa,
};
lock (VariaveisMonitoramento._EquipamentosConectadosLogsLock)
{
Logs = new Dictionary<byte, List<LoRaProtocoloTransmissaoModel>>(VariaveisMonitoramento.EquipamentosConectadosLogs);
}
}
private async Task tmrLeituras_Tick()
{
if (cmbEquipamento.Text != "")
{
EquipamentoSelecionado = cmbEquipamento.Text;
}
if (cmbEquipamento.Items.Count != VariaveisMonitoramento.EquipamentosConectados.Count())
{
cmbEquipamento.Items.Clear();
cmbEquipamento.Items.AddRange(VariaveisMonitoramento.EquipamentosConectados.Keys.Select(x => x.ToString()).ToArray());
if (cmbEquipamento.Items.Contains(EquipamentoSelecionado))
{
cmbEquipamento.SelectedIndex = cmbEquipamento.Items.IndexOf(EquipamentoSelecionado);
}
}
if (cmbEquipamento.SelectedIndex > -1)
{
AtualizarDadosTela();
}
// Verifica atualizações nos equipamentos conectados
VerificarAtualizacoesEquipamentos();
int enderecoEquipamentoEmFoco = cmbEquipamento.SelectedIndex > -1 ? Convert.ToInt32(cmbEquipamento.Text) : Convert.ToInt32(LoRaBaseService.parametrosModel.address);
foreach (var eq in VariaveisMonitoramento.EquipamentosConectados)
{
int enderecoEquipamentoLog = Convert.ToInt32(eq.Key);
bool foco = enderecoEquipamentoEmFoco == enderecoEquipamentoLog && chbFoco.Checked;
GPSService.EnviarCoordenadasParaMapa(eq.Value.Coordenadas.Latitude, eq.Value.Coordenadas.Longitude, eq.Value.Coordenadas.Orientacao, foco, eq.Key);
}
}
private void VerificarAtualizacoesEquipamentos()
{
foreach (var key in VariaveisMonitoramento.EquipamentosConectados.Keys)
{
lock (VariaveisMonitoramento._EquipamentosConectadosLogsLock)
{
// Verifica se o equipamento foi atualizado
if (!Logs.ContainsKey(key) || !EquipamentosIguais(VariaveisMonitoramento.EquipamentosConectadosLogs[key], Logs[key]))
{
// Se sim, consuma o último valor (último log)
//ConsumirUltimoValor(VariaveisMonitoramento.EquipamentosConectadosLogs[key]);
// Atualiza o estado anterior da lista EquipamentosConectados
Logs[key] = new List<LoRaProtocoloTransmissaoModel>(VariaveisMonitoramento.EquipamentosConectadosLogs[key]);
}
}
}
}
private bool EquipamentosIguais(List<LoRaProtocoloTransmissaoModel> listaAtual, List<LoRaProtocoloTransmissaoModel> listaAnterior)
{
// Verifica se as listas são iguais
return listaAtual.SequenceEqual(listaAnterior);
}
private void ConsumirUltimoValor(List<LoRaProtocoloTransmissaoModel> equipamento)
{
// Consumir o último valor (último log) do equipamento atualizado
if (equipamento.Count > 0)
{
var ultimoLog = equipamento[equipamento.Count - 1];
int enderecoEquipamentoEmFoco = cmbEquipamento.SelectedIndex > -1 ? Convert.ToInt32(cmbEquipamento.Text) : Convert.ToInt32(LoRaBaseService.parametrosModel.address);
int enderecoEquipamentoLog = Convert.ToInt32(ultimoLog.EnderecoCarro);
bool foco = enderecoEquipamentoEmFoco == enderecoEquipamentoLog && chbFoco.Checked;
GPSService.EnviarCoordenadasParaMapa(ultimoLog.Coordenadas.Latitude, ultimoLog.Coordenadas.Longitude, ultimoLog.Coordenadas.Orientacao, foco, enderecoEquipamentoLog);
}
}
private void cmbEquipamento_SelectedIndexChanged(object sender, EventArgs e)
{
MomentoLog = MomentoLog.AddMinutes(-1);
AtualizarDadosTela();
}
private void AtualizarDadosTela()
{
byte Endereco = Convert.ToByte(cmbEquipamento.Text);
if (Endereco == LoRaBaseService.parametrosModel.address)
{
MomentoLog = DateTime.Now;
txtLeitura.Text = MomentoLog.ToString("HH:mm:ss");
txtOrientacao.Text = GPSService.UltimaLeitura.OrientacaoReal.ToString("0.00");
txtLatitude.Text = GPSService.UltimaLeitura.Latitude.ToString();
txtLongitude.Text = GPSService.UltimaLeitura.Longitude.ToString();
txtFix.Text = GPSService.UltimaLeitura.QualidadeFix.ToString();
txtDistanciaEntreLeituras.Text = (GPSService.UltimaLeitura.Distancia * 100.0).ToString("0.00") + " cm";
txtNSatelites.Text = GPSService.UltimaLeitura.NumeroSatelites.ToString();
txtPrecisao.Text = GPSService.UltimaLeitura.PrecisaoCm.ToString("0.00") + " cm";
txtStatusFix.Text = BaseFixService.ProgressoStr;
txtCodigoFalha.Text = "";
txtStatusOperacao.Text = "";
txtStatusCarro.Text = "";
txtTempoDecorrido.Text = "";
txtTempoEstimado.Text = "";
FuncoesGlobais.PreencheValorProgressBar(pgbProgressoOperacao, 0);
FuncoesGlobais.PreencheValorProgressBar(pgbProgressoRua, 0);
FuncoesGlobais.PreencheValorProgressBar(pgbBateria, 0);
lblBateriaDados.Text = "0,00%";
FuncoesGlobais.PreencheValorProgressBar(pgbReservatorio, 0);
lblReservatorioDados.Text = "0,00%";
FuncoesGlobais.PreencheValorProgressBar(pgbHerbicidaAplicado, 0);
lblHerbicidaDados.Text = "0,00 L (0,00 ml/erva)";
lblErvasIdentificadas.Text = "0 ervas";
FuncoesGlobais.PreencheValorProgressBar(pgbPressao, 0);
lblPressaoDados.Text = "0,00 psi";
FuncoesGlobais.PreencheValorProgressBar(pgbTemperaturaMotores, 0);
lblTemperaturaMotoresDados.Text = "0,00 ºC";
FuncoesGlobais.PreencheValorProgressBar(pgbTemperaturaCampo, 0);
lblTemperaturaCampoDados.Text = "0,00 ºC";
FuncoesGlobais.PreencheValorProgressBar(pgbVelocidade, 0);
lblVelocidadeDados.Text = "0,00 km/h";
}
else if (Endereco > 0x00 && VariaveisMonitoramento.EquipamentosConectados.Any(x => x.Key == Endereco))
{
var Equipamento = VariaveisMonitoramento.EquipamentosConectados[Endereco];
bool Conectado = Equipamento.RecebidoEm.AddMilliseconds(VariaveisEquipamento.TempoEntrePingsConexao) > DateTime.Now;
txtCarroConectado.Text = Conectado ? "Sim" : "Não";
if (Equipamento.RecebidoEm > MomentoLog)
{
MomentoLog = Equipamento.Momento;
txtLeitura.Text = Equipamento.Momento.ToString("ddd HH:mm:ss");
txtOrientacao.Text = Equipamento.Coordenadas.Orientacao.ToString("0.00");
txtLatitude.Text = Equipamento.Coordenadas.Latitude.ToString();
txtLongitude.Text = Equipamento.Coordenadas.Longitude.ToString();
txtFix.Text = Equipamento.Coordenadas.Correcao.ToString();
txtCodigoFalha.Text = Equipamento.CodigoFalha.ToString();
txtStatusOperacao.Text = (Equipamento.Operacao?.statusOperacao ?? StatusOperacao.NaoIniciado).ToString();
txtStatusCarro.Text = (Equipamento.Operacao?.statusCarro ?? StatusCarroMapa.Parado).ToString();
txtTempoDecorrido.Text = TimeSpan.FromSeconds(Equipamento.Operacao?.TempoOperacao ?? 0).ToString(@"hh\:mm\:ss");
txtTempoEstimado.Text = Equipamento.Operacao?.TempoEstimado ?? "";
FuncoesGlobais.PreencheValorProgressBar(pgbProgressoOperacao, Equipamento.Operacao?.PercentualOperacao ?? 0);
FuncoesGlobais.PreencheValorProgressBar(pgbProgressoRua, Equipamento.Operacao?.PercentualRua ?? 0);
FuncoesGlobais.PreencheValorProgressBar(pgbBateria, Equipamento.Sensores?.PercentualBateria ?? 0);
lblBateriaDados.Text = $"{(Equipamento.Sensores?.PercentualBateria ?? 0).ToString("0.00")}%";
FuncoesGlobais.PreencheValorProgressBar(pgbReservatorio, Equipamento.Sensores?.PercentualReservatorio ?? 0);
lblReservatorioDados.Text = $"{(Equipamento.Sensores?.PercentualReservatorio ?? 0).ToString("0.00")}%";
FuncoesGlobais.PreencheValorProgressBar(pgbHerbicidaAplicado, Equipamento.Sensores?.HerbicidaConsumido ?? 0);
lblHerbicidaDados.Text = $"{(Equipamento.Sensores?.HerbicidaConsumido ?? 0).ToString("0.00")} L ({(Equipamento.Sensores?.HerbicidaPorErva ?? 0).ToString("0.00")} ml/erva)";
lblErvasIdentificadas.Text = $"{(Equipamento.Sensores?.ErvasIdentificadas ?? 0)} ervas";
FuncoesGlobais.PreencheValorProgressBar(pgbPressao, Equipamento.Sensores?.PressaoLinha ?? 0);
lblPressaoDados.Text = $"{(Equipamento.Sensores?.PressaoLinha ?? 0).ToString("0.00")} psi";
FuncoesGlobais.PreencheValorProgressBar(pgbTemperaturaMotores, Equipamento.Sensores?.TemperaturaMotores ?? 0);
lblTemperaturaMotoresDados.Text = $"{(Equipamento.Sensores?.TemperaturaMotores ?? 0).ToString("0.00")} ºC";
FuncoesGlobais.PreencheValorProgressBar(pgbTemperaturaCampo, Equipamento.Sensores?.TemperaturaCampo ?? 0);
lblTemperaturaCampoDados.Text = $"{(Equipamento.Sensores?.TemperaturaCampo ?? 0).ToString("0.00")} ºC";
FuncoesGlobais.PreencheValorProgressBar(pgbVelocidade, Equipamento.Sensores?.Velocidade ?? 0);
lblVelocidadeDados.Text = $"{(Equipamento.Sensores?.Velocidade ?? 0).ToString("0.00")} km/h";
}
}
}
private void btnCarregar_Click(object sender, EventArgs e)
{
Mapa.btnCarregar_Click(sender, e, "", true);
}
private void btnControle_KeyDown(object sender, KeyEventArgs e)
{
EnviarComandoControleEquipamento(e.KeyCode, ultimStatusoEmergencia);
}
private void btnControle_KeyUp(object sender, KeyEventArgs e)
{
EnviarComandoControleEquipamento(Keys.Escape, ultimStatusoEmergencia);
}
private void EnviarComandoControleEquipamento(Keys Tecla, bool emergencia, T_Code Disp = T_Code.Vzo)
{
Dictionary<Keys, Keys> DeParaTeclas = new Dictionary<Keys, Keys>()
{
{ Keys.W, Keys.Up },
{ Keys.S, Keys.Down },
{ Keys.A, Keys.Left },
{ Keys.D, Keys.Right },
{ Keys.Escape, Keys.Escape },
{ Keys.Space, Keys.Space },
};
if (emergencia == ultimStatusoEmergencia && (Tecla == UltimoComandoEnviado || !DeParaTeclas.ContainsKey(Tecla) || cmbEquipamento.SelectedIndex < 0))
{
return;
}
byte Endereco = Convert.ToByte(cmbEquipamento.Text);
if (Endereco == LoRaBaseService.parametrosModel.address)
{
return;
}
UltimoComandoEnviado = Tecla;
Keys[] TeclasDir = { Keys.A, Keys.D };
Keys[] TeclasMov = { Keys.W, Keys.S, Keys.Space };
OperacaoControleBaseModel Controle = new OperacaoControleBaseModel()
{
Momento = DateTime.Now,
Tecla = DeParaTeclas[Tecla],
TipoMovimento = (TipoMovimentoDirecional)cmbTipoMovimento.SelectedIndex,
PercentualVelocidadeSP = tkbVelocidadeSP.Value,
AnguloMP = tkbAnguloMP.Value,
VelocidadeMP = 50,
Dispositivo = Disp,
Emergencia = emergencia
};
if (Disp == T_Code.Vzo)
{
if (Tecla == Keys.Escape || (!TeclasDir.Contains(Tecla) && !TeclasMov.Contains(Tecla)))
{
Controle.Dispositivo = T_Code.Vzo;
}
else if (TeclasDir.Contains(Tecla))
{
Controle.Dispositivo = T_Code.Dir;
}
else if (TeclasMov.Contains(Tecla))
{
Controle.Dispositivo = T_Code.Mov;
}
}
LoRaBaseService.EnviarDadosComandoControle(Controle, Endereco);
ultimStatusoEmergencia = emergencia;
}
private void btnParar_Click(object sender, EventArgs e)
{
if (btnParar.Text == "Parar")
{
EnviarComandoControleEquipamento(Keys.Escape, true);
btnParar.Text = "Retomar";
}
else
{
EnviarComandoControleEquipamento(Keys.Escape, false);
btnParar.Text = "Parar";
}
}
private void btnVerFalha_Click(object sender, EventArgs e)
{
tvwFalhas.Visible = !tvwFalhas.Visible;
if (!tvwFalhas.Visible)
{
return;
}
byte Endereco = 0x00;
byte.TryParse(cmbEquipamento.Text, out Endereco);
if (Endereco > 0x00 && VariaveisMonitoramento.EquipamentosConectados.Any(x => x.Key == Endereco))
{
var Equipamento = VariaveisMonitoramento.EquipamentosConectados[Endereco];
//OperacaoModel.PopularTreeView(tvwFalhas, Equipamento.CodigoFalha);
}
else
{
tvwFalhas.Visible = false;
MessageBox.Show("Selecione um equipamento para ver o código de falhas", "Equipamento não selecionado", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void tkbVelocidadeSP_ValueChanged(object sender, EventArgs e)
{
double Percentual = tkbVelocidadeSP.Value;
int RPM = Convert.ToInt32((Percentual / 100.0) * VariaveisEquipamento.RPM_Max_Roda);
double Velocidade = FuncoesMatematicas.CalculaVelocidadeRPM(RPM);
lblVelocidadeSP.Text = $"Velocidade: {tkbVelocidadeSP.Value}% {Velocidade.ToString("0.00")} km/h";
}
private void tkbAnguloMP_ValueChanged(object sender, EventArgs e)
{
lblAngulo.Text = $"Angulo: {tkbAnguloMP.Value}°";
}
}
}