1407 lines
53 KiB
C#
1407 lines
53 KiB
C#
using AgroBase.Forms.IHM;
|
|
using AgroBase.Services;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.IO.Ports;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using static AgroBase.Models.Enums;
|
|
|
|
namespace AgroBase.Models.Modules
|
|
{
|
|
public class AtuadorModel : DispositivoBaseModel
|
|
{
|
|
public T_Code Dispositivo { get; set; } = T_Code.Atu;
|
|
public string Modulo_ID { get; set; } = T_Code.Atu.ToString();
|
|
public byte _EnderecoCAN { get; set; } = 0x12;
|
|
public int _TaxaAmostragem { get; set; } = 1000;
|
|
public bool RequisitarDados { get; set; } = true;
|
|
public static int PingsConsiderarConexao { get; set; } = 5;
|
|
public static int TempoLimiteConexao
|
|
{
|
|
get
|
|
{
|
|
return PingsConsiderarConexao * (Variaveis.OperacaoEmAndamento?.DispSen?._TaxaAmostragem ?? 1000);
|
|
}
|
|
}
|
|
public bool Conectado
|
|
{
|
|
get
|
|
{
|
|
return DadosLeitura.UltimoComandoRespondido.AddMilliseconds(TempoLimiteConexao * 2) >= DateTime.Now; // DadosLeitura.Conectado &&
|
|
}
|
|
}
|
|
|
|
public static PinoutDataModel Pinout { get; set; }
|
|
public static List<FuncoesPinout> Funcoes { get; set; } = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.SDA,
|
|
FuncoesPinout.SCL,
|
|
};
|
|
public int QuantidadeBicos { get; set; } = 4;
|
|
public double DensidadeHerbicida { get; set; } = 1.1;
|
|
public List<AtuadorBicoModel> BicosPulverizadores { get; set; } = new List<AtuadorBicoModel>();
|
|
public List<AtuadorBombaModel> BombasPressurizadoras { get; set; } = new List<AtuadorBombaModel>();
|
|
public List<SensorModel> Sensores { get; set; } = new List<SensorModel>();
|
|
public AtuadorBombaModel BombaPressurizadora
|
|
{
|
|
get
|
|
{
|
|
return BombasPressurizadoras.FirstOrDefault();
|
|
}
|
|
}
|
|
public string ScriptDeteccaoErvas { get; set; } = PythonService.ScriptWeedDetector;
|
|
|
|
public AsyncTaskTimerModel tmrRegistrador;
|
|
private int _TempoReconexaoComponentes = 5;
|
|
private int _VezesLeituraReconexao = 0;
|
|
public AtuadorMensagemJsonModel DadosLeitura { get; set; } = new AtuadorMensagemJsonModel();
|
|
public AtuHandler _AtuHandler = new AtuHandler();
|
|
|
|
#region MASSA
|
|
public double _MassaRef { get; set; } = 0.8;
|
|
public double _MassaLeituraRef { get; set; } = 40876.37;
|
|
public double _MassaLeituraExtra { get; set; } = 1895800; // 2015000.0;
|
|
public double MassaReservatorio
|
|
{
|
|
get
|
|
{
|
|
return ((FirmwareSensorMassa)Sensores.FirstOrDefault(x => x.Componente == S_Code.sMAS)?.Leitura)?.Massa ?? 0;
|
|
}
|
|
}
|
|
public double VolumeReservatorio
|
|
{
|
|
get
|
|
{
|
|
return MassaReservatorio / DensidadeHerbicida;
|
|
}
|
|
}
|
|
public double PercentualReservatorio
|
|
{
|
|
get
|
|
{
|
|
return VolumeReservatorio / Variaveis.OperacaoEmAndamento.CapacidadeReservatorio * 100.0;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region VAZAO
|
|
public double VolumeVazaoAferido { get; set; } = 0;
|
|
public double _FluxoMlRef { get; set; } = 600;
|
|
public double _FluxoPulsoRef { get; set; } = 538;
|
|
public double VazaoFluxoMLpSInstantanea
|
|
{
|
|
get
|
|
{
|
|
return ((FirmwareSensorFluxo)Sensores.FirstOrDefault(x => x.Componente == S_Code.sFLX)?.Leitura)?.Vazao ?? 0;
|
|
}
|
|
}
|
|
private double _somaVazao; // Acumula a soma da vazão para calcular a média
|
|
private int _contadorLeituras; // Conta o número de leituras feitas
|
|
private DateTime _ultimoRegistroVazao; // Armazena o horário da última atualização
|
|
public double VazaoFluxoMLpSMedia { get; set; }
|
|
public double VolumeVazaoML { get; set; }
|
|
public DateTime InicioAtuacao { get; set; } = DateTime.MinValue;
|
|
public double TempoAtuado { get; set; } = 0;
|
|
public void AtualizaTempoAtuadoGeral()
|
|
{
|
|
bool algumBicoAtivo = BicosPulverizadores.Any(x => x.Inicializado && x.ComandoAtuar);
|
|
|
|
if (algumBicoAtivo)
|
|
{
|
|
if (InicioAtuacao == DateTime.MinValue)
|
|
{
|
|
InicioAtuacao = DateTime.Now;
|
|
}
|
|
else
|
|
{
|
|
TempoAtuado += (DateTime.Now - InicioAtuacao).TotalMilliseconds;
|
|
InicioAtuacao = DateTime.Now;
|
|
}
|
|
}
|
|
else if (InicioAtuacao != DateTime.MinValue)
|
|
{
|
|
TempoAtuado += (DateTime.Now - InicioAtuacao).TotalMilliseconds;
|
|
InicioAtuacao = DateTime.MinValue;
|
|
}
|
|
|
|
AtualizaPercentualErvas();
|
|
AtualizaVazaoEVolume();
|
|
}
|
|
public void AtualizaPercentualErvas()
|
|
{
|
|
double tempoTotalOperacao = Variaveis.OperacaoEmAndamento.Sensoriamento.TempoDecorridoSeg * 1000.0;
|
|
|
|
if (tempoTotalOperacao > 0)
|
|
{
|
|
var percentual = Math.Round((TempoAtuado / tempoTotalOperacao) * 100.0, 2);
|
|
PercentualErvasTerreno = percentual;
|
|
}
|
|
else
|
|
{
|
|
PercentualErvasTerreno = 0;
|
|
}
|
|
}
|
|
public void AtualizaVazaoEVolume()
|
|
{
|
|
// Captura a vazão instantânea
|
|
double vazaoInstantanea = VazaoFluxoMLpSInstantanea;
|
|
|
|
if (_ultimoRegistroVazao == DateTime.MinValue)
|
|
{
|
|
_ultimoRegistroVazao = DateTime.Now;
|
|
return;
|
|
}
|
|
|
|
// Calcula o tempo decorrido desde a última atualização (em segundos)
|
|
double intervaloSegundos = (DateTime.Now - _ultimoRegistroVazao).TotalSeconds;
|
|
_ultimoRegistroVazao = DateTime.Now;
|
|
|
|
if (intervaloSegundos > 0)
|
|
{
|
|
// Atualiza o volume total vazado
|
|
VolumeVazaoML += vazaoInstantanea * intervaloSegundos;
|
|
|
|
// Acumula a vazão para o cálculo da média
|
|
_somaVazao += vazaoInstantanea;
|
|
_contadorLeituras++;
|
|
}
|
|
|
|
VazaoFluxoMLpSMedia = _contadorLeituras > 0 ? _somaVazao / _contadorLeituras : 0;
|
|
|
|
var BicosAtuados = BicosPulverizadores.Where(x => x.Inicializado && x.ComandoAtuar).ToList();
|
|
double vazaoInstantaneaBico = vazaoInstantanea / ((double)BicosAtuados.Count());
|
|
foreach (var Bico in BicosAtuados)
|
|
{
|
|
Bico.MediaNivelFluxo = vazaoInstantaneaBico;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region PRESSAO
|
|
public double _PressaoVmin { get; set; } = 0.0;
|
|
public double _PressaoVmax { get; set; } = 4.5;
|
|
public double _PressaoMax { get; set; } = 174.045; // 1,2 MPa
|
|
public double PressaoLinha
|
|
{
|
|
get
|
|
{
|
|
return ((FirmwareSensorPressao)Sensores.FirstOrDefault(x => x.Componente == S_Code.sPRS)?.Leitura)?.Pressao ?? 0;
|
|
}
|
|
}
|
|
public double PressaoLinhaCalc
|
|
{
|
|
get
|
|
{
|
|
//double _LeituraPressao = ((FirmwareSensorPressao)Sensores.FirstOrDefault(x => x.Componente == S_Code.sPRS)?.Leitura)?.Leitura ?? 0;
|
|
double _LeituraPressao = 0;
|
|
double tensao = FuncoesMatematicas.Map(_LeituraPressao, 0, 4095, 0, 3300) / 1000.0;
|
|
|
|
double pressao = FuncoesMatematicas.Map(tensao, _PressaoVmin, _PressaoVmax, 0, _PressaoMax);
|
|
|
|
return pressao;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
public double PercentualErvasTerreno { get; set; } = 0;
|
|
|
|
public static AtuadorModel CarregarParametrosIniciais()
|
|
{
|
|
AtuadorModel Atuador = new AtuadorModel()
|
|
{
|
|
_EnderecoCAN = 0x12,
|
|
_TaxaAmostragem = 1000,
|
|
RequisitarDados = true,
|
|
QuantidadeBicos = 4,
|
|
BicosPulverizadores = new List<AtuadorBicoModel>(),
|
|
BombasPressurizadoras = new List<AtuadorBombaModel>()
|
|
{
|
|
new AtuadorBombaModel()
|
|
{
|
|
ID = "BOMBA",
|
|
ID_Num = 51,
|
|
Componente = S_Code.sBMB,
|
|
Comandar = true,
|
|
Testando = false,
|
|
Funcoes = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.ENA,
|
|
FuncoesPinout.CS,
|
|
FuncoesPinout.INA,
|
|
FuncoesPinout.INB,
|
|
FuncoesPinout.PWM,
|
|
}
|
|
}
|
|
},
|
|
Sensores = new List<SensorModel>()
|
|
{
|
|
new SensorModel()
|
|
{
|
|
ID = "FLXLN",
|
|
ID_Num = 61,
|
|
Descricao = "Fluxo na linha principal",
|
|
Componente = S_Code.sFLX,
|
|
Aferir = true,
|
|
Funcoes = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.Fluxo,
|
|
},
|
|
UnidadeMedida = "mL/s",
|
|
Parametros = new List<SensorParametroModel>()
|
|
},
|
|
new SensorModel()
|
|
{
|
|
ID = "MASRS",
|
|
ID_Num = 62,
|
|
Descricao = "Massa do reservatório de herbicida",
|
|
Componente = S_Code.sMAS,
|
|
Aferir = true,
|
|
Funcoes = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.DT,
|
|
FuncoesPinout.SCK,
|
|
},
|
|
UnidadeMedida = "Kg",
|
|
Parametros = new List<SensorParametroModel>()
|
|
},
|
|
new SensorModel()
|
|
{
|
|
ID = "PRSLN",
|
|
ID_Num = 63,
|
|
Descricao = "Pressão na linha principal",
|
|
Componente = S_Code.sPRS,
|
|
Aferir = true,
|
|
Funcoes = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.Pressao,
|
|
},
|
|
UnidadeMedida = "psi",
|
|
Parametros = new List<SensorParametroModel>()
|
|
{
|
|
new SensorParametroModel()
|
|
{
|
|
Descricao = "Vmin",
|
|
Valor = "0",
|
|
QtdBytes = 1,
|
|
Escalar = false,
|
|
Enviar = false
|
|
},
|
|
new SensorParametroModel()
|
|
{
|
|
Descricao = "Vmax",
|
|
Valor = "4.5",
|
|
QtdBytes = 1,
|
|
Escalar = true,
|
|
Enviar = false
|
|
},
|
|
new SensorParametroModel()
|
|
{
|
|
Descricao = "Pmax",
|
|
Valor = "174",
|
|
QtdBytes = 1,
|
|
Escalar = false,
|
|
Enviar = false
|
|
},
|
|
}
|
|
},
|
|
},
|
|
};
|
|
for (int i = 0; i < Atuador.QuantidadeBicos; i++)
|
|
{
|
|
int posicao = (i + 1);
|
|
Atuador.BicosPulverizadores.Add(new AtuadorBicoModel()
|
|
{
|
|
ID = "B" + posicao.ToString("00"),
|
|
ID_Num = 70 + posicao,
|
|
Componente = S_Code.sBIC,
|
|
Posicao = posicao,
|
|
Comandar = true,
|
|
ComandoAtuar = false,
|
|
AtuacaoNivelAlto = true,
|
|
Funcoes = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.Solenoide,
|
|
},
|
|
MediaNivelFluxo = 0
|
|
});
|
|
}
|
|
return Atuador;
|
|
}
|
|
|
|
public void LimparDados<T>(T _dados)
|
|
{
|
|
var Dados = _dados as AtuadorModel;
|
|
Dados.DadosLeitura = new AtuadorMensagemJsonModel();
|
|
Dados.DadosLeitura.Momento = DateTime.MinValue;
|
|
Dados.PercentualErvasTerreno = 0;
|
|
Dados.BombasPressurizadoras.ForEach(x => x.Funcoes = x.Funcoes.Distinct().ToList());
|
|
|
|
ReiniciarLeituras(Dados);
|
|
}
|
|
|
|
public void ReiniciarLeituras(AtuadorModel Dados)
|
|
{
|
|
Dados.Sensores.ForEach(x =>
|
|
{
|
|
x.Leitura = null;
|
|
});
|
|
|
|
Dados.BicosPulverizadores.ForEach(x =>
|
|
{
|
|
x.ComandoAtuar = false;
|
|
x.Atuacoes = 0;
|
|
x.TempoAtuado = 0;
|
|
x.InicioAtuacao = DateTime.MinValue;
|
|
x.Leitura = null;
|
|
});
|
|
|
|
Dados.BombasPressurizadoras.ForEach(x =>
|
|
{
|
|
x.Leitura = null;
|
|
x.ComandoAtuar = false;
|
|
});
|
|
|
|
Dados.VolumeVazaoAferido = 0;
|
|
Dados._somaVazao = 0;
|
|
Dados._contadorLeituras = 0;
|
|
Dados._ultimoRegistroVazao = DateTime.MinValue;
|
|
Dados.VolumeVazaoML = 0;
|
|
Dados.VazaoFluxoMLpSMedia = 0;
|
|
Dados.TempoAtuado = 0;
|
|
Dados.InicioAtuacao = DateTime.MinValue;
|
|
}
|
|
|
|
public async Task<bool> VerificaPortaATU(SerialPort porta)
|
|
{
|
|
if (!CanService.IsConnected)
|
|
{
|
|
CanService.DefinirPortaCOM(porta);
|
|
}
|
|
|
|
CanService.RegistrarHandler(_EnderecoCAN, _AtuHandler);
|
|
|
|
if (CanService.IsConnected)
|
|
{
|
|
RequisitarDadosModulo(F_Code.ChkTx);
|
|
|
|
await Task.Delay(1000);
|
|
|
|
if (Conectado)
|
|
{
|
|
DefinirDispositivo();
|
|
Variaveis.OperacaoEmAndamento.DispAtu?.EnviarProtocolosConfiguracao();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!CanService.Iniciado)
|
|
{
|
|
CanService.Fechar();
|
|
}
|
|
|
|
return Conectado;
|
|
}
|
|
|
|
private void DefinirDispositivo()
|
|
{
|
|
if (!SerialService.DispositivosMapeados.Any(x => x.Dispositivo == Dispositivo && x.Mod_ID == Modulo_ID))
|
|
{
|
|
SerialService.DispositivosMapeados.Add(new DispositivoDetalhesModel()
|
|
{
|
|
Endereco = CanService._portName,
|
|
Dispositivo = DadosLeitura.Dispositivo,
|
|
Erro = false,
|
|
Versao = DadosLeitura.Versao.ToString(),
|
|
Mod_ID = Modulo_ID,
|
|
});
|
|
}
|
|
}
|
|
|
|
public void RequisitarDadosModulo(F_Code dado)
|
|
{
|
|
Variaveis.OperacaoEmAndamento.DispAtu?.AdicionarMensagemFila(dado);
|
|
}
|
|
|
|
public List<byte[]> ProtocoloConfiguracao(bool Conectar)
|
|
{
|
|
// Inicializar o dicionário
|
|
List<byte[]> config = new List<byte[]>();
|
|
|
|
if (!DadosLeitura.Conectado)
|
|
{
|
|
// Adicionar configuração do ProtocoloMOD
|
|
var protocoloMOD = ModConfig(Conectar);
|
|
config.AddRange(protocoloMOD);
|
|
}
|
|
|
|
// Adicionar configurações dos Sensores que devem ser aferidos
|
|
List<byte[]> sensoresConfig = SensoresConfig(Conectar);
|
|
config.AddRange(sensoresConfig);
|
|
|
|
// Adicionar configurações dos Bicos
|
|
List<byte[]> bicosConfig = BicosConfig(Conectar);
|
|
config.AddRange(bicosConfig);
|
|
|
|
// Adicionar configurações das Bombas
|
|
List<byte[]> bombasConfig = BombasConfig(Conectar);
|
|
config.AddRange(bombasConfig);
|
|
|
|
return config;
|
|
}
|
|
|
|
private List<byte[]> ModConfig(bool Conectar)
|
|
{
|
|
var config1 = new List<byte>
|
|
{
|
|
Variaveis.ID_Num_sMOD,
|
|
(byte)CanMessagePosicaoDados.Config1,
|
|
(byte)S_Code.sMOD,
|
|
(byte)(Conectar ? 1 : 0),
|
|
(byte)(_TaxaAmostragem / 10),
|
|
(byte)(RequisitarDados ? 1 : 0),
|
|
};
|
|
|
|
var config2 = new List<byte>
|
|
{
|
|
Variaveis.ID_Num_sMOD,
|
|
(byte)CanMessagePosicaoDados.Config1,
|
|
(byte)S_Code.sMOD,
|
|
};
|
|
config2.AddRange(PinoutModel.PinoProtocolo(Pinout, Funcoes, false));
|
|
|
|
return new List<byte[]>
|
|
{
|
|
config1.ToArray(),
|
|
config2.ToArray()
|
|
};
|
|
}
|
|
|
|
private List<byte[]> SensoresConfig(bool Conectar)
|
|
{
|
|
var config = new List<byte[]>();
|
|
|
|
foreach (var sensor in Sensores.Where(x => x.Aferir && x.Inicializado != Conectar))
|
|
{
|
|
byte[] payload = sensor.ProtocoloConfiguracao(Pinout, Conectar, Dispositivo);
|
|
if (payload != null)
|
|
{
|
|
config.Add(payload);
|
|
}
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
private List<byte[]> BicosConfig(bool Conectar)
|
|
{
|
|
var config = new List<byte[]>();
|
|
|
|
foreach (var bico in BicosPulverizadores.Where(x => x.Comandar && x.Inicializado != Conectar))
|
|
{
|
|
var payload = bico.ProtocoloConfiguracao(Pinout, Conectar);
|
|
if (payload != null)
|
|
{
|
|
config.Add(payload);
|
|
}
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
private List<byte[]> BombasConfig(bool Conectar)
|
|
{
|
|
var config = new List<byte[]>();
|
|
|
|
foreach (var bomba in BombasPressurizadoras.Where(x => x.Comandar && x.Inicializado != Conectar))
|
|
{
|
|
var payload = bomba.ProtocoloConfiguracao(Pinout, Conectar);
|
|
if (payload != null)
|
|
{
|
|
config.AddRange(payload);
|
|
}
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
|
|
public void RecebeProtocoloModulo(string Protocolo)
|
|
{
|
|
try
|
|
{
|
|
if (string.IsNullOrWhiteSpace(Protocolo))
|
|
{
|
|
Console.WriteLine("Protocolo recebido está vazio ou nulo.");
|
|
return;
|
|
}
|
|
|
|
Protocolo = Protocolo.Substring(0, Protocolo.Length - 1);
|
|
|
|
// Valida se o protocolo possui um formato esperado
|
|
if (Protocolo.Length <= 1 || !Protocolo.EndsWith("}"))
|
|
{
|
|
Console.WriteLine("Protocolo recebido está em um formato inválido.");
|
|
return;
|
|
}
|
|
|
|
//Console.WriteLine($"JSON recebido: {Protocolo}");
|
|
|
|
// Tenta desserializar o JSON
|
|
var dadosLeitura = JsonConvert.DeserializeObject<AtuadorMensagemJsonModel>(Protocolo);
|
|
if (dadosLeitura == null)
|
|
{
|
|
Console.WriteLine("Falha ao desserializar o JSON.");
|
|
return;
|
|
}
|
|
|
|
dadosLeitura.Momento = DateTime.Now;
|
|
|
|
AtualizaDadosComponentes(dadosLeitura);
|
|
}
|
|
catch (JsonException ex)
|
|
{
|
|
Console.WriteLine($"Erro ao processar o JSON recebido: {ex.Message}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Erro inesperado no processamento do protocolo: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
private void AtualizaDadosComponentes(AtuadorMensagemJsonModel dadosLeitura)
|
|
{
|
|
DadosLeitura = dadosLeitura;
|
|
}
|
|
|
|
|
|
|
|
public void IniciarRegistrador()
|
|
{
|
|
if (!(tmrRegistrador?.IsRunning ?? false))
|
|
{
|
|
LimparDados(this);
|
|
|
|
PararRegistrador();
|
|
|
|
tmrRegistrador = new AsyncTaskTimerModel("tmrRegistrador_" + T_Code.Atu.ToString(), tmrRegistrador_Tick, _TaxaAmostragem);
|
|
tmrRegistrador.Start();
|
|
}
|
|
}
|
|
|
|
public void PararRegistrador()
|
|
{
|
|
tmrRegistrador?.Dispose();
|
|
}
|
|
|
|
public async Task tmrRegistrador_Tick()
|
|
{
|
|
if (Variaveis.Fechando)
|
|
{
|
|
return;
|
|
}
|
|
|
|
tmrRegistrador.SetInterval(_TaxaAmostragem);
|
|
|
|
if (SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Atu) && (_VezesLeituraReconexao >= _TempoReconexaoComponentes))
|
|
{
|
|
Variaveis.OperacaoEmAndamento.DispAtu?.EnviarProtocolosConfiguracao();
|
|
|
|
_VezesLeituraReconexao = 0;
|
|
}
|
|
else
|
|
{
|
|
_VezesLeituraReconexao++;
|
|
}
|
|
|
|
|
|
if (DadosLeitura.Conectado)
|
|
{
|
|
if (RequisitarDados)
|
|
{
|
|
RequisitarDadosModulo(F_Code.ReqTx);
|
|
}
|
|
|
|
VerificaControleLeitura();
|
|
}
|
|
}
|
|
|
|
|
|
public (bool, List<string>) StatusModulosATU()
|
|
{
|
|
var Bicos = BicosPulverizadores.Where(x => x.Comandar).ToList();
|
|
var BicosComFalha = Bicos.Where(x => !x.Inicializado).ToList();
|
|
bool _bicosOperantes = !BicosComFalha.Any();
|
|
|
|
var _bomba = BombaPressurizadora;
|
|
var _sensorFluxo = Sensores.FirstOrDefault(x => x.Componente == S_Code.sFLX);
|
|
bool _sensorFluxoOperante = (!_sensorFluxo?.Aferir ?? false) || ((_sensorFluxo?.Aferir ?? false) && (_sensorFluxo?.Inicializado ?? false));
|
|
var _sensorMassa = Sensores.FirstOrDefault(x => x.Componente == S_Code.sMAS);
|
|
bool _sensorMassaOperante = (!_sensorMassa?.Aferir ?? false) || ((_sensorMassa?.Aferir ?? false) && (_sensorMassa?.Inicializado ?? false));
|
|
var _sensorPressao = Sensores.FirstOrDefault(x => x.Componente == S_Code.sPRS);
|
|
bool _sensorPressaoOperante = (!_sensorPressao?.Aferir ?? false) || ((_sensorPressao?.Aferir ?? false) && (_sensorPressao?.Inicializado ?? false));
|
|
|
|
List<string> ModsComFalha = BicosComFalha.Select(x => x.ID).ToList();
|
|
|
|
bool _bombaOperante = _bomba?.Inicializado ?? false;
|
|
|
|
if (!_bombaOperante)
|
|
{
|
|
ModsComFalha.Add(_bomba?.ID);
|
|
}
|
|
if (!_sensorFluxoOperante)
|
|
{
|
|
ModsComFalha.Add(_sensorFluxo.ID);
|
|
}
|
|
if (!_sensorMassaOperante)
|
|
{
|
|
ModsComFalha.Add(_sensorMassa.ID);
|
|
}
|
|
if (!_sensorPressaoOperante)
|
|
{
|
|
ModsComFalha.Add(_sensorPressao.ID);
|
|
}
|
|
|
|
bool _atuadorOperante = _bombaOperante && _bicosOperantes && _sensorPressaoOperante;
|
|
|
|
return (_atuadorOperante, ModsComFalha);
|
|
}
|
|
|
|
private void VerificaControleLeitura()
|
|
{
|
|
if (!frmDiagnosticos.Diagnosticando)
|
|
{
|
|
// Caso a pressao de set point da bomba seja diferente da pressao de set point de controle, reenvia o comando para garantir a integridade do controle
|
|
if (BombaPressurizadora.LeituraPressaoSP != Variaveis.OperacaoEmAndamento.Controle.PressaoLinha)
|
|
{
|
|
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, true, BombaPressurizadora.ID);
|
|
}
|
|
|
|
if (Variaveis.OperacaoEmAndamento.Controle.PulverizadorAutomatico)
|
|
{
|
|
// Caso o comando do bico for diferente da leitura, reenvia o comando para garantir a integridade do controle
|
|
foreach (var bico in BicosPulverizadores.Where(x => x.Comandar && x.Inicializado))
|
|
{
|
|
if (bico.ComandoAtuar != bico.LeituraStatusBico)
|
|
{
|
|
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, bico.ComandoAtuar, bico.ID);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public class AtuadorBicoModel
|
|
{
|
|
public string ID { get; set; }
|
|
public int ID_Num { get; set; }
|
|
public int Posicao { get; set; }
|
|
public S_Code Componente { get; set; } = S_Code.sBIC;
|
|
public bool AtuacaoNivelAlto { get; set; }
|
|
private bool _atuado;
|
|
public bool ComandoAtuar
|
|
{
|
|
get
|
|
{
|
|
return _atuado;
|
|
}
|
|
set
|
|
{
|
|
_atuado = value;
|
|
|
|
AtualizaTempoAtuado();
|
|
}
|
|
}
|
|
public bool Comandar { get; set; }
|
|
public bool Testando { get; set; }
|
|
public List<FuncoesPinout> Funcoes { get; set; }
|
|
public bool LeituraStatusBico
|
|
{
|
|
get
|
|
{
|
|
return (Leitura?.Leitura ?? Estado.Desligado) == Estado.Ligado;
|
|
}
|
|
}
|
|
public double MediaNivelFluxo { get; set; }
|
|
private FirmwareRele _leitura = null;
|
|
public FirmwareRele Leitura
|
|
{
|
|
get
|
|
{
|
|
_leitura = Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.DadosLeitura?.BicosPulverizadores?.FirstOrDefault(x => x.ID == ID);
|
|
return _leitura;
|
|
}
|
|
set
|
|
{
|
|
_leitura = value;
|
|
}
|
|
}
|
|
public bool Inicializado
|
|
{
|
|
get
|
|
{
|
|
return Leitura?.Iniciado ?? false;
|
|
}
|
|
}
|
|
|
|
|
|
public byte[] ProtocoloConfiguracao(PinoutDataModel pinout, bool conectar)
|
|
{
|
|
var pino = pinout.Pinos.FirstOrDefault(p => p.ComponenteID == ID);
|
|
|
|
return new byte[]
|
|
{
|
|
(byte)ID_Num,
|
|
(byte)CanMessagePosicaoDados.Config1,
|
|
(byte)Componente,
|
|
(byte)(conectar ? 1 : 0),
|
|
(byte)(AtuacaoNivelAlto ? 1 : 0),
|
|
(byte)(pino?.Barramento ?? TiposBarramentos.CONTROLADOR),
|
|
(byte)(pino?.Pino ?? PinoutUtils.PINO_INVALIDO)
|
|
};
|
|
}
|
|
|
|
public (F_Code, byte[]) ProtocoloComando()
|
|
{
|
|
return (
|
|
F_Code.CmdTx,
|
|
new byte[]
|
|
{
|
|
(byte)ID_Num,
|
|
(byte)CanMessagePosicaoDados.Command1,
|
|
(byte)(ComandoAtuar ? Estado.Ligado : Estado.Desligado)
|
|
}
|
|
);
|
|
}
|
|
|
|
|
|
public int Atuacoes { get; set; } = 0;
|
|
public DateTime InicioAtuacao { get; set; } = DateTime.MinValue;
|
|
public double TempoAtuado { get; set; } = 0;
|
|
private void AtualizaTempoAtuado()
|
|
{
|
|
if (_atuado)
|
|
{
|
|
if (InicioAtuacao == DateTime.MinValue)
|
|
{
|
|
InicioAtuacao = DateTime.Now;
|
|
}
|
|
else
|
|
{
|
|
TempoAtuado += (DateTime.Now - InicioAtuacao).TotalMilliseconds;
|
|
InicioAtuacao = DateTime.Now;
|
|
}
|
|
}
|
|
else if (InicioAtuacao != DateTime.MinValue)
|
|
{
|
|
TempoAtuado += (DateTime.Now - InicioAtuacao).TotalMilliseconds;
|
|
InicioAtuacao = DateTime.MinValue;
|
|
}
|
|
|
|
if (Variaveis.OperacaoEmAndamento.DispAtu != null)
|
|
{
|
|
Variaveis.OperacaoEmAndamento.DispAtu.Dados.AtualizaTempoAtuadoGeral();
|
|
}
|
|
}
|
|
|
|
|
|
public AtuadorBicoModel Clone()
|
|
{
|
|
AtuadorBicoModel clone = new AtuadorBicoModel()
|
|
{
|
|
Comandar = Comandar,
|
|
AtuacaoNivelAlto = AtuacaoNivelAlto,
|
|
Atuacoes = Atuacoes,
|
|
ComandoAtuar = ComandoAtuar,
|
|
Componente = Componente,
|
|
Funcoes = Funcoes,
|
|
ID = ID,
|
|
ID_Num = ID_Num,
|
|
InicioAtuacao = InicioAtuacao,
|
|
Leitura = Leitura,
|
|
MediaNivelFluxo = MediaNivelFluxo,
|
|
Posicao = Posicao,
|
|
TempoAtuado = TempoAtuado,
|
|
Testando = Testando
|
|
};
|
|
|
|
return clone;
|
|
}
|
|
}
|
|
|
|
public class AtuadorBombaModel
|
|
{
|
|
public string ID { get; set; }
|
|
public int ID_Num { get; set; }
|
|
public bool ComandoAtuar { get; set; }
|
|
public S_Code Componente { get; set; } = S_Code.sBMB;
|
|
public bool LeituraEstado
|
|
{
|
|
get
|
|
{
|
|
return (Leitura?.Estado ?? Estado.Desligado) == Estado.Ligado;
|
|
}
|
|
}
|
|
public bool Comandar { get; set; }
|
|
public bool Testando { get; set; }
|
|
public List<FuncoesPinout> Funcoes { get; set; } = new List<FuncoesPinout>();
|
|
public double LeituraPotencia
|
|
{
|
|
get
|
|
{
|
|
return Leitura?.Potencia ?? 0;
|
|
}
|
|
}
|
|
public double LeituraPressaoSP
|
|
{
|
|
get
|
|
{
|
|
return Leitura?.PressaoSP ?? 0;
|
|
}
|
|
}
|
|
public double LeituraPressao
|
|
{
|
|
get
|
|
{
|
|
return Leitura?.Pressao ?? 0;
|
|
}
|
|
}
|
|
|
|
private FirmwareBombaPressurizadora _leitura = null;
|
|
public FirmwareBombaPressurizadora Leitura
|
|
{
|
|
get
|
|
{
|
|
_leitura = Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.DadosLeitura?.BombasPressurizadoras?.FirstOrDefault(x => x.ID == ID);
|
|
return _leitura;
|
|
}
|
|
set
|
|
{
|
|
_leitura = value;
|
|
}
|
|
}
|
|
public bool Inicializado
|
|
{
|
|
get
|
|
{
|
|
return Leitura?.Iniciado ?? false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public List<byte[]> ProtocoloConfiguracao(PinoutDataModel pinout, bool conectar)
|
|
{
|
|
List<byte> config1 = new List<byte>()
|
|
{
|
|
(byte)ID_Num,
|
|
(byte)CanMessagePosicaoDados.Config1,
|
|
(byte)Componente,
|
|
(byte)(conectar ? 1 : 0),
|
|
(byte)Variaveis.OperacaoEmAndamento.Controle.PressaoLinha,
|
|
(byte)(pinout.Pinos.FirstOrDefault(x => x.ComponenteID == ID && x.Funcao == FuncoesPinout.ENA)?.Pino ?? PinoutUtils.PINO_INVALIDO),
|
|
(byte)(pinout.Pinos.FirstOrDefault(x => x.Funcao == FuncoesPinout.CS)?.Pino ?? PinoutUtils.PINO_INVALIDO),
|
|
};
|
|
|
|
List<byte> config2 = new List<byte>()
|
|
{
|
|
(byte)ID_Num,
|
|
(byte)CanMessagePosicaoDados.Config2,
|
|
(byte)Componente,
|
|
(byte)(pinout.Pinos.FirstOrDefault(x => x.Funcao == FuncoesPinout.INA)?.Pino ?? PinoutUtils.PINO_INVALIDO),
|
|
(byte)(pinout.Pinos.FirstOrDefault(x => x.Funcao == FuncoesPinout.INB)?.Pino ?? PinoutUtils.PINO_INVALIDO),
|
|
(byte)(pinout.Pinos.FirstOrDefault(x => x.Funcao == FuncoesPinout.PWM)?.Pino ?? PinoutUtils.PINO_INVALIDO),
|
|
};
|
|
|
|
return new List<byte[]>()
|
|
{
|
|
config1.ToArray(),
|
|
config2.ToArray()
|
|
};
|
|
}
|
|
|
|
public (F_Code, byte[]) ProtocoloComando()
|
|
{
|
|
return (
|
|
F_Code.CmdTx,
|
|
new byte[]
|
|
{
|
|
(byte)ID_Num,
|
|
(byte)CanMessagePosicaoDados.Command1,
|
|
(byte)(ComandoAtuar ? Estado.Ligado : Estado.Desligado),
|
|
(byte)(Variaveis.OperacaoEmAndamento.Controle.PressaoLinha)
|
|
}
|
|
);
|
|
}
|
|
|
|
|
|
public AtuadorBombaModel Clone()
|
|
{
|
|
AtuadorBombaModel clone = new AtuadorBombaModel()
|
|
{
|
|
ID = this.ID,
|
|
Componente = this.Componente,
|
|
ID_Num = this.ID_Num,
|
|
ComandoAtuar = this.ComandoAtuar,
|
|
Comandar = this.Comandar,
|
|
Testando = this.Testando,
|
|
Funcoes = this.Funcoes,
|
|
};
|
|
|
|
return clone;
|
|
}
|
|
}
|
|
|
|
public class CalibragemVazao
|
|
{
|
|
public bool Calibrando { get; set; } = false;
|
|
public DateTime IniciadoEm { get; set; }
|
|
public double TempoCalibragem { get; set; } = 10000.0;
|
|
public double VolumeComputado { get; set; } = 0;
|
|
public List<double> PressoesAferidas { get; set; } = new List<double>();
|
|
public double MassaInicial { get; set; } = 0.0;
|
|
public double MassaFinal { get; set; } = 0.0;
|
|
public int QtdPulsos { get; set; } = 0;
|
|
public double Periodo { get; set; } = 0.0;
|
|
public double PressaoMedia
|
|
{
|
|
get
|
|
{
|
|
return PressoesAferidas.Average();
|
|
}
|
|
}
|
|
public double MassaPerdida
|
|
{
|
|
get
|
|
{
|
|
return (MassaInicial - MassaFinal) * 1000;
|
|
}
|
|
}
|
|
public double Q
|
|
{
|
|
get
|
|
{
|
|
return (double)VolumeComputado / (double)Periodo;
|
|
}
|
|
}
|
|
public double VolumeCalculado { get; set; } = 0.0;
|
|
public double d
|
|
{
|
|
get
|
|
{
|
|
return (double)MassaPerdida / (double)VolumeComputado;
|
|
}
|
|
}
|
|
public double x
|
|
{
|
|
get
|
|
{
|
|
return (double)VolumeComputado / (double)QtdPulsos;
|
|
}
|
|
}
|
|
public double Q2
|
|
{
|
|
get
|
|
{
|
|
return (double)x * (double)QtdPulsos;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public class AtuadorFuncoesGerais
|
|
{
|
|
|
|
public static void DesenharAtuadores(object sender, PaintEventArgs e, List<AtuBicoSensoriamentoLogModel> Bicos, bool BombaLigada, double PressaoLinha, double TempoBombaAtuada)
|
|
{
|
|
Panel myPanel = (Panel)sender;
|
|
|
|
// Habilita o double buffering temporariamente
|
|
myPanel.GetType().GetProperty("DoubleBuffered",
|
|
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
|
|
?.SetValue(myPanel, true, null);
|
|
|
|
Graphics g = e.Graphics;
|
|
|
|
int QuantidadeBicos = Bicos.Count;
|
|
int panelWidth = myPanel.Width;
|
|
int circleDiameter = 40; // Diâmetro dos círculos grandes
|
|
int smallCircleDiameter = circleDiameter / 2; // Diâmetro dos círculos pequenos
|
|
int spaceBetweenCircles = (panelWidth - (circleDiameter * QuantidadeBicos)) / (QuantidadeBicos + 1);
|
|
int yPosition = (myPanel.Height - circleDiameter) / 3; // Centralizado verticalmente
|
|
|
|
for (int i = 0; i < QuantidadeBicos; i++)
|
|
{
|
|
int xPosition = spaceBetweenCircles + (i * (circleDiameter + spaceBetweenCircles));
|
|
|
|
// Desenha o contorno do círculo
|
|
g.DrawEllipse(Pens.Red, xPosition, yPosition, circleDiameter, circleDiameter);
|
|
|
|
// Preenche o círculo se o bico estiver aceso
|
|
if (Bicos[i].Atuado)
|
|
{
|
|
g.FillEllipse(Brushes.Red, xPosition, yPosition, circleDiameter, circleDiameter);
|
|
}
|
|
|
|
// Número do bico
|
|
string bicoNumero = Bicos[i].ID;
|
|
Font font = new Font("Arial", 10, FontStyle.Bold);
|
|
SizeF stringSize = g.MeasureString(bicoNumero, font);
|
|
float textXPosition = xPosition + (circleDiameter - stringSize.Width) / 2;
|
|
float textYPosition = yPosition + (circleDiameter - stringSize.Height) / 2;
|
|
g.DrawString(bicoNumero, font, Brushes.Black, textXPosition, textYPosition);
|
|
|
|
// Média de vazão (dentro do círculo, abaixo do número do bico)
|
|
string mediaFluxoTexto = $"{Bicos[i].MediaNivelFluxo:0.0} mL/s";
|
|
Font fontMediaFluxo = new Font("Arial", 6, FontStyle.Regular);
|
|
SizeF stringSizeMediaFluxo = g.MeasureString(mediaFluxoTexto, fontMediaFluxo);
|
|
float textXPositionMediaFluxo = xPosition + circleDiameter + 3;
|
|
float textYPositionMediaFluxo = textYPosition + 3; // Abaixo do número do bico
|
|
g.DrawString(mediaFluxoTexto, fontMediaFluxo, Brushes.Gray, textXPositionMediaFluxo, textYPositionMediaFluxo);
|
|
|
|
// Quantidade de atuações (abaixo do círculo)
|
|
string bicoAtuacao = Bicos[i].Atuacoes.ToString("000");
|
|
Font fontA = new Font("Arial", 8, FontStyle.Bold);
|
|
SizeF stringSizeA = g.MeasureString(bicoAtuacao, fontA);
|
|
float textXPositionA = xPosition + (circleDiameter - stringSizeA.Width) / 2;
|
|
float textYPositionA = circleDiameter + yPosition + 5;
|
|
g.DrawString(bicoAtuacao, fontA, Brushes.Black, textXPositionA, textYPositionA);
|
|
|
|
// Tempo atuado em segundos (acima do círculo)
|
|
string tempoAtuadoSegundos = $"{(Bicos[i].TempoAtuado / 1000.0):0.0}s";
|
|
Font fontTempo = new Font("Arial", 7, FontStyle.Regular);
|
|
SizeF stringSizeTempo = g.MeasureString(tempoAtuadoSegundos, fontTempo);
|
|
float textXPositionTempo = xPosition + (circleDiameter - stringSizeTempo.Width) / 2;
|
|
float textYPositionTempo = yPosition - stringSizeTempo.Height - 3;
|
|
g.DrawString(tempoAtuadoSegundos, fontTempo, Brushes.Gray, textXPositionTempo, textYPositionTempo);
|
|
|
|
// Círculo pequeno de status
|
|
int smallCircleXPosition = Convert.ToInt32(xPosition + circleDiameter - smallCircleDiameter / 1.3);
|
|
int smallCircleYPosition = Convert.ToInt32(yPosition + circleDiameter - smallCircleDiameter / 1.3);
|
|
Pen smallCirclePen = Pens.Blue;
|
|
Brush smallCircleBrush = Bicos[i].StatusBico ? Brushes.Blue : Brushes.Transparent;
|
|
g.DrawEllipse(smallCirclePen, smallCircleXPosition, smallCircleYPosition, smallCircleDiameter, smallCircleDiameter);
|
|
g.FillEllipse(smallCircleBrush, smallCircleXPosition, smallCircleYPosition, smallCircleDiameter, smallCircleDiameter);
|
|
}
|
|
|
|
// Representação da bomba hidráulica no canto inferior direito
|
|
int bombaSize = 20; // Tamanho do círculo principal da bomba
|
|
int bombaXPosition = myPanel.Width - bombaSize - 20; // 20px de margem do canto direito
|
|
int bombaYPosition = myPanel.Height - bombaSize - 20; // 20px de margem do canto inferior
|
|
|
|
// Desenha o corpo da bomba (um círculo)
|
|
g.DrawEllipse(Pens.Black, bombaXPosition, bombaYPosition, bombaSize, bombaSize);
|
|
g.FillEllipse(BombaLigada ? Brushes.Green : Brushes.Gray, bombaXPosition, bombaYPosition, bombaSize, bombaSize);
|
|
|
|
// Define o centro do círculo para ajudar no desenho das hélices
|
|
int centerX = bombaXPosition + bombaSize / 2;
|
|
int centerY = bombaYPosition + bombaSize / 2;
|
|
int heliceSize = bombaSize - 6; // Ajuste para manter as hélices dentro do círculo
|
|
|
|
// Desenha hélices no formato de arcos ou semi-círculos dentro do círculo
|
|
Pen helicePen = new Pen(Color.Black, 1);
|
|
g.DrawArc(helicePen, centerX - heliceSize / 2, centerY - heliceSize / 2, heliceSize, heliceSize, 45, 180);
|
|
g.DrawArc(helicePen, centerX - heliceSize / 2, centerY - heliceSize / 2, heliceSize, heliceSize, 225, 180);
|
|
|
|
// Desenha o "cano" da bomba (retângulo)
|
|
int tuboLargura = 5;
|
|
int tuboAltura = 15;
|
|
int tuboXPosition = bombaXPosition + bombaSize / 2 - tuboLargura / 2;
|
|
int tuboYPosition = bombaYPosition - tuboAltura;
|
|
g.FillRectangle(Brushes.Black, tuboXPosition, tuboYPosition, tuboLargura, tuboAltura);
|
|
|
|
// Texto para o tempo de atuação acima da bomba
|
|
string tempoAtuacaoTexto = $"{(TempoBombaAtuada / 1000.0):0.0}s";
|
|
Font fontTempoAtuacao = new Font("Arial", 6, FontStyle.Regular);
|
|
SizeF stringSizeTempoAtuacao = g.MeasureString(tempoAtuacaoTexto, fontTempoAtuacao);
|
|
float textXPositionTempoAtuacao = bombaXPosition + bombaSize / 2 - stringSizeTempoAtuacao.Width / 2;
|
|
float textYPositionTempoAtuacao = bombaYPosition - stringSizeTempoAtuacao.Height - 16; // 2px acima do círculo
|
|
g.DrawString(tempoAtuacaoTexto, fontTempoAtuacao, Brushes.Gray, textXPositionTempoAtuacao, textYPositionTempoAtuacao);
|
|
|
|
// Texto pequeno para a pressão ao lado da bomba
|
|
string pressaoTexto = $"{PressaoLinha:0.0} psi";
|
|
Font fontPressao = new Font("Arial", 6, FontStyle.Regular);
|
|
SizeF stringSizePressao = g.MeasureString(pressaoTexto, fontPressao);
|
|
float textXPositionPressao = bombaXPosition + bombaSize / 2 - stringSizePressao.Width / 2;
|
|
float textYPositionPressao = bombaYPosition + bombaSize + 2; // 2px abaixo do círculo
|
|
g.DrawString(pressaoTexto, fontPressao, Brushes.Black, textXPositionPressao, textYPositionPressao);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class FirmwareBombaPressurizadora
|
|
{
|
|
public string ID { get; set; }
|
|
public bool Iniciado { get; set; }
|
|
public Estado Estado { get; set; }
|
|
public double Potencia { get; set; }
|
|
public double PressaoSP { get; set; }
|
|
public double Pressao { get; set; }
|
|
}
|
|
|
|
public class AtuadorMensagemJsonModel
|
|
{
|
|
public DateTime Momento { get; set; }
|
|
public bool Conectado { get; set; }
|
|
public T_Code Dispositivo { get; set; }
|
|
public int Versao { get; set; }
|
|
public string Mod_ID { get; set; }
|
|
public int QualidadeWifi { get; set; }
|
|
public int LatenciaLoop { get; set; }
|
|
public List<FirmwareRele> BicosPulverizadores { get; set; } = new List<FirmwareRele>();
|
|
public List<FirmwareBombaPressurizadora> BombasPressurizadoras { get; set; } = new List<FirmwareBombaPressurizadora>();
|
|
public List<FirmwareSensorFluxo> SensoresFluxo { get; set; } = new List<FirmwareSensorFluxo>();
|
|
public List<FirmwareSensorMassa> SensoresMassa { get; set; } = new List<FirmwareSensorMassa>();
|
|
public List<FirmwareSensorPressao> SensoresPressao { get; set; } = new List<FirmwareSensorPressao>();
|
|
public DateTime UltimoComandoRespondido { get; set; }
|
|
}
|
|
|
|
public class AtuHandler : ICanMessageHandler
|
|
{
|
|
private double ConverterByteParaDouble(byte[] data, int idx)
|
|
{
|
|
int raw = (data[idx] << 8) | data[idx + 1];
|
|
short _short = (short)raw;
|
|
double _value = _short / 100.0;
|
|
|
|
return _value;
|
|
}
|
|
|
|
private S_Code DetectarComponenteDoID_Num(int ID_Num)
|
|
{
|
|
if (ID_Num == Variaveis.ID_Num_sMOD) return S_Code.sMOD;
|
|
|
|
var Disp = Variaveis.OperacaoEmAndamento.DispAtu.Dados;
|
|
var sensor = Disp.Sensores.FirstOrDefault(x => x.ID_Num == ID_Num);
|
|
var bico = Disp.BicosPulverizadores.FirstOrDefault(x => x.ID_Num == ID_Num);
|
|
var bomba = Disp.BombasPressurizadoras.FirstOrDefault(x => x.ID_Num == ID_Num);
|
|
|
|
return sensor?.Componente ?? bico?.Componente ?? bomba?.Componente ?? S_Code.sVZO;
|
|
}
|
|
|
|
private void DefinirOuCriar(int CompID_Num, S_Code componente, bool Iniciado, List<dynamic> Parametros)
|
|
{
|
|
var Disp = Variaveis.OperacaoEmAndamento.DispAtu;
|
|
var item = Disp.Dados.DadosLeitura;
|
|
|
|
switch (componente)
|
|
{
|
|
case S_Code.sFLX:
|
|
{
|
|
var sensor = Disp.Dados.Sensores.FirstOrDefault(x => x.ID_Num == CompID_Num);
|
|
var _sensor = item.SensoresFluxo.FirstOrDefault(x => x.ID == sensor.ID);
|
|
if (_sensor == null)
|
|
{
|
|
_sensor = new FirmwareSensorFluxo()
|
|
{
|
|
ID = sensor.ID,
|
|
Iniciado = Iniciado,
|
|
Vazao = -1,
|
|
};
|
|
item.SensoresFluxo.Add(_sensor);
|
|
}
|
|
if (_sensor != null)
|
|
{
|
|
_sensor.Iniciado = Iniciado;
|
|
_sensor.Vazao = Parametros.Count > 0 ? Parametros[0] : -1;
|
|
}
|
|
break;
|
|
}
|
|
case S_Code.sPRS:
|
|
{
|
|
var sensor = Disp.Dados.Sensores.FirstOrDefault(x => x.ID_Num == CompID_Num);
|
|
var _sensor = item.SensoresPressao.FirstOrDefault(x => x.ID == sensor.ID);
|
|
if (_sensor == null)
|
|
{
|
|
_sensor = new FirmwareSensorPressao()
|
|
{
|
|
ID = sensor.ID,
|
|
Iniciado = Iniciado,
|
|
Pressao = -1,
|
|
};
|
|
item.SensoresPressao.Add(_sensor);
|
|
}
|
|
if (_sensor != null)
|
|
{
|
|
_sensor.Iniciado = Iniciado;
|
|
_sensor.Pressao = Parametros.Count > 0 ? Parametros[0] : -1;
|
|
}
|
|
break;
|
|
}
|
|
case S_Code.sMAS:
|
|
{
|
|
var sensor = Disp.Dados.Sensores.FirstOrDefault(x => x.ID_Num == CompID_Num);
|
|
var _sensor = item.SensoresMassa.FirstOrDefault(x => x.ID == sensor.ID);
|
|
if (_sensor == null)
|
|
{
|
|
_sensor = new FirmwareSensorMassa()
|
|
{
|
|
ID = sensor.ID,
|
|
Iniciado = Iniciado,
|
|
Massa = -1,
|
|
};
|
|
item.SensoresMassa.Add(_sensor);
|
|
}
|
|
if (_sensor != null)
|
|
{
|
|
_sensor.Iniciado = Iniciado;
|
|
_sensor.Massa = Parametros.Count > 0 ? Parametros[0] : -1;
|
|
}
|
|
break;
|
|
}
|
|
case S_Code.sBIC:
|
|
{
|
|
var sensor = Disp.Dados.BicosPulverizadores.FirstOrDefault(x => x.ID_Num == CompID_Num);
|
|
var _sensor = item.BicosPulverizadores.FirstOrDefault(x => x.ID == sensor.ID);
|
|
if (_sensor == null)
|
|
{
|
|
_sensor = new FirmwareRele()
|
|
{
|
|
ID = sensor.ID,
|
|
Iniciado = Iniciado,
|
|
Leitura = Estado.Desligado,
|
|
};
|
|
item.BicosPulverizadores.Add(_sensor);
|
|
}
|
|
if (_sensor != null)
|
|
{
|
|
_sensor.Iniciado = Iniciado;
|
|
_sensor.Leitura = Parametros.Count > 0 ? Parametros[0] : Estado.Desligado;
|
|
}
|
|
break;
|
|
}
|
|
case S_Code.sBMB:
|
|
{
|
|
var sensor = Disp.Dados.BombasPressurizadoras.FirstOrDefault(x => x.ID_Num == CompID_Num);
|
|
var _sensor = item.BombasPressurizadoras.FirstOrDefault(x => x.ID == sensor.ID);
|
|
if (_sensor == null)
|
|
{
|
|
_sensor = new FirmwareBombaPressurizadora()
|
|
{
|
|
ID = sensor.ID,
|
|
Iniciado = Iniciado,
|
|
Estado = Estado.Desligado,
|
|
Potencia = -1,
|
|
Pressao = -1,
|
|
PressaoSP = -1,
|
|
};
|
|
item.BombasPressurizadoras.Add(_sensor);
|
|
}
|
|
if (_sensor != null)
|
|
{
|
|
_sensor.Iniciado = Iniciado;
|
|
_sensor.Estado = Parametros.Count > 0 ? Parametros[0] : Estado.Desligado;
|
|
_sensor.Potencia = Parametros.Count > 1 ? Parametros[1] : -1;
|
|
_sensor.PressaoSP = Parametros.Count > 2 ? Parametros[2] : -1;
|
|
_sensor.Pressao = Parametros.Count > 3 ? Parametros[3] : -1;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ProcessarMensagem(CanMessage mensagem)
|
|
{
|
|
byte ID_Num = mensagem.DataRx[0];
|
|
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)mensagem.DataRx[1];
|
|
byte id = mensagem.Id;
|
|
var data = mensagem.DataRx;
|
|
|
|
var item = Variaveis.OperacaoEmAndamento.DispAtu.Dados.DadosLeitura;
|
|
|
|
S_Code componente = DetectarComponenteDoID_Num(ID_Num);
|
|
|
|
Console.WriteLine($"[ATU] Componente={componente.ToString()}, ID_Num={ID_Num}, Data={FuncoesGlobais.ConverterComandoBytesParaTexto(data)}");
|
|
|
|
switch (posicao)
|
|
{
|
|
case CanMessagePosicaoDados.Status:
|
|
{
|
|
if (componente == S_Code.sMOD)
|
|
{
|
|
T_Code tipoModulo = (T_Code)data[2];
|
|
bool conectado = data[3] == 1;
|
|
int versao = data[4];
|
|
|
|
Console.WriteLine($"[ATU] Resposta {ID_Num} recebida. Tipo={tipoModulo}, Conectado={conectado}, Versão={versao}");
|
|
|
|
item.Conectado = conectado;
|
|
item.Dispositivo = tipoModulo;
|
|
item.Versao = versao;
|
|
}
|
|
else
|
|
{
|
|
bool Iniciado = data[2] == 1;
|
|
DefinirOuCriar(ID_Num, componente, Iniciado, new List<dynamic>());
|
|
}
|
|
break;
|
|
}
|
|
case CanMessagePosicaoDados.Dados1:
|
|
{
|
|
switch (componente)
|
|
{
|
|
case S_Code.sBIC:
|
|
{
|
|
Estado estado = (Estado)data[2];
|
|
DefinirOuCriar(ID_Num, componente, true, new List<dynamic>() { estado });
|
|
break;
|
|
}
|
|
case S_Code.sFLX:
|
|
{
|
|
double vazao = ConverterByteParaDouble(data, 2);
|
|
DefinirOuCriar(ID_Num, componente, true, new List<dynamic>() { vazao });
|
|
break;
|
|
}
|
|
case S_Code.sMAS:
|
|
{
|
|
double massa = ConverterByteParaDouble(data, 2);
|
|
DefinirOuCriar(ID_Num, componente, true, new List<dynamic>() { massa });
|
|
break;
|
|
}
|
|
case S_Code.sPRS:
|
|
{
|
|
double pressao = ConverterByteParaDouble(data, 2);
|
|
DefinirOuCriar(ID_Num, componente, true, new List<dynamic>() { pressao });
|
|
break;
|
|
}
|
|
case S_Code.sBMB:
|
|
{
|
|
Estado estado = (Estado)data[2];
|
|
int percentualPotencia = data[3];
|
|
int pressaoSp = data[4];
|
|
int pressaoAtual = data[5];
|
|
DefinirOuCriar(ID_Num, componente, true, new List<dynamic>() { estado, percentualPotencia, pressaoSp, pressaoAtual });
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
Console.WriteLine($"[ATU] Resposta do {ID_Num} recebida. Parametros nao mapeados: {FuncoesGlobais.ConverterComandoBytesParaTexto(data)}");
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
item.UltimoComandoRespondido = DateTime.Now;
|
|
}
|
|
}
|
|
|
|
|
|
}
|