1126 lines
45 KiB
C#
1126 lines
45 KiB
C#
using AgroBase.Services;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
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 string Modulo_ID { get; set; } = T_Code.Atu.ToString();
|
|
public bool RequisitarDados { get; set; } = false;
|
|
private bool _MensagemConexaoRecebida { get; set; } = false;
|
|
public bool MensagemConexaoRecebida(bool Reset = false)
|
|
{
|
|
if (Reset)
|
|
{
|
|
_MensagemConexaoRecebida = false;
|
|
}
|
|
return _MensagemConexaoRecebida;
|
|
}
|
|
|
|
public static int _TaxaAmostragem { get; set; } = 500;
|
|
public bool Conectado { get; set; } = false;
|
|
public DateTime UltimoProtocoloRecebido { get; set; } = DateTime.MaxValue.AddDays(-1);
|
|
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 bool AtuacaoNivelAlto { get; set; } = true;
|
|
public List<AtuadorBicoModel> BicosPulverizadores { get; set; } = new List<AtuadorBicoModel>();
|
|
public AtuadorBombaModel BombaPressurizadora { get; set; } = new AtuadorBombaModel();
|
|
public List<SensorModel> Sensores { get; set; } = new List<SensorModel>();
|
|
public string ScriptDeteccaoErvas { get; set; } = PythonService.ScriptWeedDetector;
|
|
|
|
public AsyncTaskTimerModel tmrRegistrador;
|
|
|
|
#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 _MassaLeitura { get; set; }
|
|
public double MassaReservatorio
|
|
{
|
|
get
|
|
{
|
|
double leituraMassa = _MassaLeitura * -1;
|
|
leituraMassa += _MassaLeituraExtra;
|
|
|
|
double FatorLeitura = _MassaRef / _MassaLeituraRef;
|
|
double Massa = FatorLeitura * leituraMassa;
|
|
|
|
return Massa;
|
|
}
|
|
}
|
|
public double VolumeReservatorio
|
|
{
|
|
get
|
|
{
|
|
return MassaReservatorio / DensidadeHerbicida;
|
|
}
|
|
}
|
|
public double PercentualReservatorio
|
|
{
|
|
get
|
|
{
|
|
return VolumeReservatorio / Variaveis.OperacaoEmAndamento.CapacidadeReservatorio * 100;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region VAZAO
|
|
public double VolumeVazaoAferido { get; set; } = 0;
|
|
public double _FluxoMlRef { get; set; } = 600;
|
|
public double _FluxoPulsoRef { get; set; } = 538;
|
|
public int _LeituraPulsos { get; set; }
|
|
public int _LeituraPeriodo { get; set; }
|
|
public double VazaoFluxoMLpS
|
|
{
|
|
get
|
|
{
|
|
if (_LeituraPeriodo == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
double FatorLeitura = (double)_FluxoMlRef / (double)_FluxoPulsoRef;
|
|
double Frequencia = ((double)_LeituraPulsos / (double)_LeituraPeriodo * 1000);
|
|
//double vazao = (_LeituraPulsos * FatorLeitura) / ((double)_LeituraPeriodo / 1000);
|
|
//double vazao = ((double)1 / FatorLeitura) * (60 * 1000 / _LeituraPeriodo);
|
|
//double vazao = ((double)_LeituraPulsos / (((double)_LeituraPeriodo / 1000) * 8.1)) + 3;
|
|
//double Fator = (double)_LeituraPulsos / (double)_LeituraPeriodo;
|
|
|
|
//double vazao = ((double)_LeituraPulsos / (double)_LeituraPeriodo * 1000) * ;
|
|
|
|
//double vazao = Frequencia * 1.22;
|
|
|
|
double Rh = 0.0047;
|
|
double Rt = 0.0037;
|
|
double vazao = (Frequencia * 2 * Math.PI * Rh * Math.PI * (Rt * Rt)) * 1000000;
|
|
|
|
Console.WriteLine("Pulsos: " + _LeituraPulsos + " - Periodo: " + _LeituraPeriodo + " ms - Vazão: " + vazao.ToString("0.00000"));
|
|
|
|
return vazao;
|
|
}
|
|
}
|
|
}
|
|
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.Atuado);
|
|
|
|
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();
|
|
}
|
|
public void AtualizaPercentualErvas()
|
|
{
|
|
double tempoTotalOperacao = Variaveis.OperacaoEmAndamento.Tempo.TotalMilliseconds;
|
|
|
|
if (tempoTotalOperacao > 0)
|
|
{
|
|
var percentual = Math.Round((TempoAtuado / tempoTotalOperacao) * 100.0, 2);
|
|
Variaveis.OperacaoEmAndamento.Sensoriamento.PercentualErvasTerreno = percentual;
|
|
}
|
|
else
|
|
{
|
|
Variaveis.OperacaoEmAndamento.Sensoriamento.PercentualErvasTerreno = 0;
|
|
}
|
|
}
|
|
|
|
#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 _LeituraPressao { get; set; }
|
|
public double PressaoLinha { get; set; } = 0;
|
|
public double PressaoLinhaCalc
|
|
{
|
|
get
|
|
{
|
|
double tensao = FuncoesMatematicas.Map(_LeituraPressao, 0, 4095, 0, 3300) / 1000.0;
|
|
|
|
double pressao = FuncoesMatematicas.Map(tensao, _PressaoVmin, _PressaoVmax, 0, _PressaoMax);
|
|
|
|
return pressao;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
|
|
public static AtuadorModel CarregarParametrosIniciais()
|
|
{
|
|
AtuadorModel Atuador = new AtuadorModel()
|
|
{
|
|
QuantidadeBicos = 10,
|
|
Conectado = false,
|
|
BicosPulverizadores = new List<AtuadorBicoModel>(),
|
|
BombaPressurizadora = new AtuadorBombaModel()
|
|
{
|
|
ID = "BOMBA",
|
|
Comandar = false,
|
|
Ligado = false,
|
|
Inicializado = false,
|
|
Pressao = 0,
|
|
//PressaoSP = 80,
|
|
Testando = false,
|
|
Funcoes = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.ENA,
|
|
FuncoesPinout.CS,
|
|
FuncoesPinout.INA,
|
|
FuncoesPinout.INB,
|
|
FuncoesPinout.PWM,
|
|
}
|
|
},
|
|
Sensores = new List<SensorModel>()
|
|
{
|
|
new SensorModel()
|
|
{
|
|
ID = "FLXLN",
|
|
Descricao = "Fluxo na linha principal",
|
|
Prioridade = 23,
|
|
Componente = S_Code.sFLX,
|
|
Aferir = false,
|
|
Inicializado = false,
|
|
Testando = false,
|
|
Funcoes = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.Fluxo,
|
|
},
|
|
DelayAmostragem = 100,
|
|
UnidadeMedida = "mL/s",
|
|
Parametros = new List<string[]>(),
|
|
},
|
|
new SensorModel()
|
|
{
|
|
ID = "MASRS",
|
|
Descricao = "Massa do reservatório de herbicida",
|
|
Prioridade = 3,
|
|
Componente = S_Code.sMAS,
|
|
Aferir = false,
|
|
Inicializado = false,
|
|
Testando = false,
|
|
Funcoes = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.DT,
|
|
FuncoesPinout.SCK,
|
|
},
|
|
DelayAmostragem = 1000,
|
|
UnidadeMedida = "Kg",
|
|
Parametros = new List<string[]>(),
|
|
},
|
|
new SensorModel()
|
|
{
|
|
ID = "PRSLN",
|
|
Descricao = "Pressão na linha principal",
|
|
Prioridade = 3,
|
|
Componente = S_Code.sPRS,
|
|
Aferir = false,
|
|
Inicializado = false,
|
|
Testando = false,
|
|
Funcoes = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.Pressao,
|
|
},
|
|
DelayAmostragem = 1000,
|
|
UnidadeMedida = "psi",
|
|
Parametros = new List<string[]>()
|
|
{
|
|
new string[] { "Vmin", "000.00" },
|
|
new string[] { "Vmax", "004.50" },
|
|
new string[] { "Pmax", "174.04" },
|
|
},
|
|
},
|
|
},
|
|
};
|
|
for (int i = 0; i < Atuador.QuantidadeBicos; i++)
|
|
{
|
|
Atuador.BicosPulverizadores.Add(new AtuadorBicoModel()
|
|
{
|
|
ID = "B" + (i + 1).ToString("00"),
|
|
Posicao = i + 1,
|
|
Comandar = false,
|
|
Atuado = false,
|
|
Funcoes = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.Solenoide,
|
|
},
|
|
StatusBico = false,
|
|
MediaNivelFluxo = 0
|
|
});
|
|
}
|
|
return Atuador;
|
|
}
|
|
|
|
public static void LimparDados(AtuadorModel Dados)
|
|
{
|
|
Dados.Conectado = false;
|
|
|
|
Dados.BicosPulverizadores.ForEach(x =>
|
|
{
|
|
x.Inicializado = false;
|
|
});
|
|
|
|
Dados.Sensores.ForEach(x =>
|
|
{
|
|
x.Inicializado = false;
|
|
});
|
|
|
|
Dados.BombaPressurizadora.Inicializado = false;
|
|
|
|
ReiniciarLeituras(Dados);
|
|
}
|
|
|
|
public static void ReiniciarLeituras(AtuadorModel Dados)
|
|
{
|
|
Dados.PressaoLinha = 0;
|
|
|
|
Dados.BicosPulverizadores.ForEach(x =>
|
|
{
|
|
x.Atuado = false;
|
|
x.StatusBico = false;
|
|
x.Atuacoes = 0;
|
|
x.TempoAtuado = 0;
|
|
x.InicioAtuacao = DateTime.MinValue;
|
|
});
|
|
|
|
Dados.Sensores.ForEach(x =>
|
|
{
|
|
x.Leituras = new List<double>();
|
|
x.ValorMinimo = 0;
|
|
x.ValorMaximo = 0;
|
|
});
|
|
|
|
Dados.BombaPressurizadora.Pressao = 0;
|
|
Dados.BombaPressurizadora.BombaAtuada = false;
|
|
Dados.BombaPressurizadora.Ligado = false;
|
|
Dados.BombaPressurizadora.Potencia = 0;
|
|
Dados.VolumeVazaoAferido = 0;
|
|
Dados.VolumeVazaoML = 0;
|
|
Dados.TempoAtuado = 0;
|
|
Dados.InicioAtuacao = DateTime.MinValue;
|
|
Dados._LeituraPeriodo = 0;
|
|
Dados._LeituraPressao = 0;
|
|
Dados._LeituraPulsos = 0;
|
|
Dados._MassaLeitura = Dados._MassaLeituraExtra;
|
|
}
|
|
|
|
public Dictionary<string, List<string>> ProtocoloConfiguracao(bool Conectar)
|
|
{
|
|
// Inicializar o dicionário
|
|
var configDictionary = new Dictionary<string, List<string>>() { { Modulo_ID, new List<string>() } };
|
|
|
|
// Adicionar configurações dos Bicos Pulverizadores
|
|
var bicosConfig = BicosPulverizadores.Where(x => x.Comandar).Select(x => x.ProtocoloConfiguracaoBico(Conectar)).ToList();
|
|
configDictionary[Modulo_ID].AddRange(bicosConfig);
|
|
|
|
// Adicionar configuração da Bomba Pressurizadora
|
|
if (BombaPressurizadora.Comandar)
|
|
{
|
|
string bombaConfig = BombaPressurizadora.ProtocoloConfiguracaoBomba(Conectar);
|
|
configDictionary[Modulo_ID].Add(bombaConfig);
|
|
}
|
|
|
|
// Adicionar configurações dos Sensores
|
|
var sensoresConfig = Sensores.Where(x => x.Aferir).Select(x => x.ProtocoloConfiguracaoSensor(Pinout, Conectar)).ToList();
|
|
configDictionary[Modulo_ID].AddRange(sensoresConfig);
|
|
|
|
// Adicionar configuração do ProtocoloMOD
|
|
string protocoloMOD =
|
|
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
|
|
"MD" + SerialService.SplitParams +
|
|
(Conectar ? "1" : "0") + SerialService.SplitParams +
|
|
_TaxaAmostragem.ToString() + SerialService.SplitParams +
|
|
(AtuacaoNivelAlto ? "1" : "0") + SerialService.SplitParams +
|
|
(RequisitarDados ? "1" : "0");
|
|
|
|
configDictionary[Modulo_ID].Add(protocoloMOD);
|
|
|
|
configDictionary[Modulo_ID].Add(ProtocoloVerificacao(false));
|
|
|
|
return configDictionary;
|
|
}
|
|
|
|
public string ProtocoloVerificacao(bool Completo)
|
|
{
|
|
if (Completo)
|
|
{
|
|
string ProtocoloCheck =
|
|
SerialService.BeginLine +
|
|
0 + SerialService.SplitMessage +
|
|
Modulo_ID + SerialService.SplitMessage +
|
|
((int)F_Code.Chk).ToString() + SerialService.SplitMessage +
|
|
"check" +
|
|
SerialService.EndLine;
|
|
|
|
return ProtocoloCheck;
|
|
}
|
|
else
|
|
{
|
|
string ProtocoloCheck =
|
|
((int)F_Code.Chk).ToString() + SerialService.SplitMessage +
|
|
"check";
|
|
|
|
return ProtocoloCheck;
|
|
}
|
|
}
|
|
|
|
public void RecebeProtocoloSerial(string Protocolo)
|
|
{
|
|
UltimoProtocoloRecebido = DateTime.Now;
|
|
|
|
string Mod_ID = Protocolo.Split(SerialService.SplitMessage[0])[0];
|
|
string mensagem = Protocolo.Substring(Mod_ID.Length + 1, Protocolo.Length - Mod_ID.Length - 1);
|
|
if (!string.IsNullOrEmpty(Protocolo) && mensagem[0].ToString() == SerialService.BeginSensor)
|
|
{
|
|
string[] Dados = mensagem.Replace(SerialService.BeginSensor, "").Split(SerialService.EndLine[0])[0].Split(';');
|
|
string _id = Dados[1].Trim();
|
|
S_Code TipoSensor = (S_Code)(int.Parse(Dados[0]));
|
|
/*AtuadorBicoModel Bico = BicosPulverizadores.FirstOrDefault(x => x.ID.Trim() == _id);
|
|
SensorModel Sensor = Sensores.FirstOrDefault(x => x.ID.Trim() == _id);
|
|
AtuadorBombaModel Bomba = _id == BombaPressurizadora.ID.Trim() ? BombaPressurizadora : null;
|
|
if (Bico == null && Sensor == null && Bomba == null)
|
|
{
|
|
if (_id == "MD")
|
|
{
|
|
Conectado = Dados[2] == "1";
|
|
_MensagemConexaoRecebida = true;
|
|
}
|
|
return;
|
|
}*/
|
|
try
|
|
{
|
|
switch (TipoSensor)
|
|
{
|
|
/*case S_Code.sCFG:
|
|
{
|
|
bool Inicializado = Dados[2] == "1";
|
|
if (Bico != null)
|
|
{
|
|
Bico.Inicializado = Inicializado;
|
|
}
|
|
if (Sensor != null)
|
|
{
|
|
Sensor.Inicializado = Inicializado;
|
|
}
|
|
if (Bomba != null)
|
|
{
|
|
Bomba.Inicializado = Inicializado;
|
|
}
|
|
break;
|
|
}
|
|
case S_Code.sTST:
|
|
{
|
|
bool Testando = Dados[1] == "1";
|
|
if (Bico != null)
|
|
{
|
|
Bico.Testando = Testando;
|
|
}
|
|
if (Sensor != null)
|
|
{
|
|
Sensor.Testando = Testando;
|
|
}
|
|
break;
|
|
}
|
|
case S_Code.sBIC:
|
|
{
|
|
bool StatusBico = Dados[2] == "1";
|
|
Bico.StatusBico = StatusBico;
|
|
break;
|
|
}
|
|
case S_Code.sFLX:
|
|
{
|
|
int pulsos = 0;
|
|
int.TryParse(Dados[2].Replace(".", ","), out pulsos);
|
|
int tempo = 0;
|
|
int.TryParse(Dados[3].Replace(".", ","), out tempo);
|
|
|
|
_LeituraPulsos = pulsos;
|
|
_LeituraPeriodo = tempo;
|
|
|
|
if (VazaoFluxoMLpS > 0)
|
|
{
|
|
foreach (var bico in BicosPulverizadores.Where(x => x.Atuado))
|
|
{
|
|
bico.MediaNivelFluxo = VazaoFluxoMLpS / BicosPulverizadores.Count(y => y.Atuado);
|
|
};
|
|
|
|
double periodoAtual = Sensor.Leituras.Any() ? (double)_LeituraPeriodo - Sensor.Leituras[1] : (double)_LeituraPeriodo;
|
|
VolumeVazaoML += (VazaoFluxoMLpS) * (periodoAtual / 1000);
|
|
|
|
Variaveis.OperacaoEmAndamento.OpMapaGPS.Sensoriamento.HerbicidaConsumido = (VolumeVazaoML / 1000);
|
|
}
|
|
|
|
Sensor.Leituras = new List<double>()
|
|
{
|
|
pulsos,
|
|
tempo
|
|
};
|
|
break;
|
|
}
|
|
case S_Code.sMAS:
|
|
{
|
|
double massa = 0;
|
|
double.TryParse(Dados[2].Replace(".", ","), out massa);
|
|
_MassaLeitura = massa;
|
|
|
|
Sensor.Leituras = new List<double>()
|
|
{
|
|
massa
|
|
};
|
|
break;
|
|
}
|
|
case S_Code.sPRS:
|
|
{
|
|
double pressao = 0;
|
|
double.TryParse(Dados[2].Replace(".", ","), out pressao);
|
|
double leitura = 0;
|
|
double.TryParse(Dados[3].Replace(".", ","), out leitura);
|
|
|
|
PressaoLinha = pressao;
|
|
_LeituraPressao = leitura;
|
|
|
|
BombaPressurizadora.Pressao = PressaoLinha;
|
|
|
|
Sensor.Leituras = new List<double>()
|
|
{
|
|
pressao,
|
|
};
|
|
break;
|
|
}
|
|
case S_Code.sBMB:
|
|
{
|
|
bool Ligado = Dados[2] == "1";
|
|
Bomba.Ligado = Ligado;
|
|
double potencia = 0;
|
|
double.TryParse(Dados[3].Replace(".", ","), out potencia);
|
|
Bomba.Potencia = potencia;
|
|
break;
|
|
}
|
|
*/
|
|
case S_Code.sATU:
|
|
{
|
|
#region BICOS
|
|
|
|
BicosPulverizadores.FirstOrDefault(x => x.ID.Contains("1")).Inicializado = Dados[2] == "1";
|
|
BicosPulverizadores.FirstOrDefault(x => x.ID.Contains("1")).StatusBico = Dados[3] == "1";
|
|
|
|
BicosPulverizadores.FirstOrDefault(x => x.ID.Contains("2")).Inicializado = Dados[4] == "1";
|
|
BicosPulverizadores.FirstOrDefault(x => x.ID.Contains("2")).StatusBico = Dados[5] == "1";
|
|
|
|
BicosPulverizadores.FirstOrDefault(x => x.ID.Contains("3")).Inicializado = Dados[6] == "1";
|
|
BicosPulverizadores.FirstOrDefault(x => x.ID.Contains("3")).StatusBico = Dados[7] == "1";
|
|
|
|
BicosPulverizadores.FirstOrDefault(x => x.ID.Contains("4")).Inicializado = Dados[8] == "1";
|
|
BicosPulverizadores.FirstOrDefault(x => x.ID.Contains("4")).StatusBico = Dados[9] == "1";
|
|
|
|
#endregion
|
|
|
|
#region BOMBA
|
|
|
|
BombaPressurizadora.Inicializado = Dados[10] == "1";
|
|
BombaPressurizadora.Ligado = Dados[11] == "1";
|
|
double.TryParse(Dados[12], out double p);
|
|
BombaPressurizadora.Potencia = p;
|
|
|
|
#endregion
|
|
|
|
#region FLUXO
|
|
|
|
var SenFlx = Sensores.FirstOrDefault(x => x.Componente == S_Code.sFLX);
|
|
if (SenFlx != null)
|
|
{
|
|
SenFlx.Inicializado = Dados[13] == "1";
|
|
int.TryParse(Dados[14].Replace(".", ","), out int pulsos);
|
|
int.TryParse(Dados[15].Replace(".", ","), out int tempo);
|
|
_LeituraPulsos = pulsos;
|
|
_LeituraPeriodo = tempo;
|
|
|
|
if (VazaoFluxoMLpS > 0)
|
|
{
|
|
foreach (var bico in BicosPulverizadores.Where(x => x.Atuado))
|
|
{
|
|
bico.MediaNivelFluxo = VazaoFluxoMLpS / BicosPulverizadores.Count(y => y.Atuado);
|
|
};
|
|
|
|
double periodoAtual = SenFlx.Leituras.Any() ? (double)_LeituraPeriodo - SenFlx.Leituras[1] : (double)_LeituraPeriodo;
|
|
VolumeVazaoML += (VazaoFluxoMLpS) * (periodoAtual / 1000);
|
|
|
|
Variaveis.OperacaoEmAndamento.OpMapaGPS.Sensoriamento.HerbicidaConsumido = (VolumeVazaoML / 1000);
|
|
}
|
|
SenFlx.Leituras = new List<double>()
|
|
{
|
|
pulsos,
|
|
tempo
|
|
};
|
|
|
|
DefineLimitesSensor(SenFlx);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region MASSA
|
|
|
|
var SenMas = Sensores.FirstOrDefault(x => x.Componente == S_Code.sMAS);
|
|
if (SenMas != null)
|
|
{
|
|
SenMas.Inicializado = Dados[16] == "1";
|
|
double.TryParse(Dados[17].Replace(".", ","), out double massa);
|
|
_MassaLeitura = massa;
|
|
|
|
SenMas.Leituras = new List<double>()
|
|
{
|
|
massa
|
|
};
|
|
}
|
|
|
|
DefineLimitesSensor(SenMas);
|
|
|
|
#endregion
|
|
|
|
#region PRSSAO
|
|
|
|
var SenPrs = Sensores.FirstOrDefault(x => x.Componente == S_Code.sPRS);
|
|
if (SenPrs != null)
|
|
{
|
|
SenPrs.Inicializado = Dados[18] == "1";
|
|
double.TryParse(Dados[19].Replace(".", ","), out double pressao);
|
|
double.TryParse(Dados[20].Replace(".", ","), out double leitura);
|
|
|
|
PressaoLinha = pressao;
|
|
_LeituraPressao = leitura;
|
|
|
|
BombaPressurizadora.Pressao = PressaoLinha;
|
|
|
|
SenPrs.Leituras = new List<double>()
|
|
{
|
|
pressao,
|
|
};
|
|
|
|
DefineLimitesSensor(SenPrs);
|
|
}
|
|
|
|
#endregion
|
|
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
/*if (Sensor != null)
|
|
{
|
|
DefineLimitesSensor(Sensor);
|
|
}*/
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DefineLimitesSensor(SensorModel Sensor)
|
|
{
|
|
if (Sensor.Leituras[0] > Sensor.ValorMaximo)
|
|
{
|
|
Sensor.ValorMaximo = Sensor.Leituras[0];
|
|
}
|
|
else if (Sensor.Leituras[0] < Sensor.ValorMinimo)
|
|
{
|
|
Sensor.ValorMinimo = Sensor.Leituras[0];
|
|
}
|
|
}
|
|
|
|
public void DefineStatusConexao(string Mod_ID, bool conecatdo)
|
|
{
|
|
if (Mod_ID == Modulo_ID)
|
|
{
|
|
Conectado = conecatdo;
|
|
|
|
Variaveis.OperacaoEmAndamento.DispAtu.AcaoConexao();
|
|
}
|
|
}
|
|
|
|
public string GetTaxaAmostragem()
|
|
{
|
|
return _TaxaAmostragem.ToString("00000");
|
|
}
|
|
|
|
public void SetTaxaAmostragem(int TaxaAmostragem)
|
|
{
|
|
_TaxaAmostragem = TaxaAmostragem;
|
|
}
|
|
|
|
public bool GetStatusConexao()
|
|
{
|
|
return Conectado;
|
|
}
|
|
|
|
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()
|
|
{
|
|
tmrRegistrador.SetInterval(_TaxaAmostragem);
|
|
|
|
|
|
Conectado = UltimoProtocoloRecebido.AddMilliseconds(10 * _TaxaAmostragem) >= DateTime.Now;
|
|
}
|
|
|
|
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();
|
|
|
|
bool _bombaOperante = BombaPressurizadora.Inicializado;
|
|
|
|
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();
|
|
|
|
if (!_bombaOperante)
|
|
{
|
|
ModsComFalha.Add(BombaPressurizadora.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);
|
|
}
|
|
|
|
}
|
|
|
|
public class AtuadorBicoModel
|
|
{
|
|
public string ID { get; set; }
|
|
public int Posicao { get; set; }
|
|
private bool _atuado;
|
|
public bool Atuado
|
|
{
|
|
get
|
|
{
|
|
return _atuado;
|
|
}
|
|
set
|
|
{
|
|
_atuado = value;
|
|
|
|
AtualizaTempoAtuado();
|
|
}
|
|
}
|
|
public bool Comandar { get; set; }
|
|
public bool Inicializado { get; set; }
|
|
public bool Testando { get; set; }
|
|
public List<FuncoesPinout> Funcoes { get; set; }
|
|
public bool StatusBico { get; set; }
|
|
public double MediaNivelFluxo { get; set; }
|
|
|
|
|
|
public string ProtocoloConfiguracaoBico(bool Conectar)
|
|
{
|
|
var _pinout = new PinoutDataModel()
|
|
{
|
|
ExpansorGPIO = AtuadorModel.Pinout.ExpansorGPIO,
|
|
EnderecoExpansor = AtuadorModel.Pinout.EnderecoExpansor,
|
|
Pinos = AtuadorModel.Pinout.Pinos.ToList(),
|
|
};
|
|
_pinout.Pinos = _pinout.Pinos.Where(x => x.ComponenteID == ID).ToList();
|
|
string Protocolo = ((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
|
|
ID + SerialService.SplitParams +
|
|
(Conectar ? "1" : "0") + SerialService.SplitParams +
|
|
(Comandar ? "1" : "0") + SerialService.SplitParams +
|
|
Posicao.ToString() + SerialService.SplitParams +
|
|
PinoutModel.PinoProtocolo(_pinout, Funcoes);
|
|
|
|
return Protocolo;
|
|
}
|
|
|
|
public string ProtocoloComando()
|
|
{
|
|
if (Comandar)
|
|
{
|
|
string ProtocoloBico =
|
|
((int)F_Code.Cmd).ToString() + SerialService.SplitMessage +
|
|
ID + SerialService.SplitParams +
|
|
(Atuado ? "1" : "0");
|
|
|
|
return ProtocoloBico;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
public string ProtocoloTeste()
|
|
{
|
|
if (Comandar)
|
|
{
|
|
string ProtocoloBico =
|
|
((int)F_Code.Tst).ToString() + SerialService.SplitMessage +
|
|
ID;
|
|
return ProtocoloBico;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
|
|
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()
|
|
{
|
|
ID = this.ID,
|
|
Posicao = this.Posicao,
|
|
Atuado = this.Atuado,
|
|
Comandar = this.Comandar,
|
|
Inicializado = this.Inicializado,
|
|
Testando = this.Testando,
|
|
Funcoes = this.Funcoes,
|
|
StatusBico = this.StatusBico,
|
|
MediaNivelFluxo = this.MediaNivelFluxo,
|
|
};
|
|
|
|
return clone;
|
|
}
|
|
}
|
|
|
|
public class AtuadorBombaModel
|
|
{
|
|
public string ID { get; set; }
|
|
public bool BombaAtuada { get; set; }
|
|
public bool Ligado { get; set; }
|
|
public bool Comandar { get; set; }
|
|
public bool Inicializado { get; set; }
|
|
public bool Testando { get; set; }
|
|
public List<FuncoesPinout> Funcoes { get; set; } = new List<FuncoesPinout>();
|
|
//public double PressaoSP { get; set; }
|
|
public double Pressao { get; set; }
|
|
public double Potencia { get; set; }
|
|
|
|
|
|
public string ProtocoloConfiguracaoBomba(bool Conectar)
|
|
{
|
|
var _pinout = new PinoutDataModel()
|
|
{
|
|
ExpansorGPIO = AtuadorModel.Pinout.ExpansorGPIO,
|
|
EnderecoExpansor = AtuadorModel.Pinout.EnderecoExpansor,
|
|
Pinos = AtuadorModel.Pinout.Pinos.ToList(),
|
|
};
|
|
_pinout.Pinos = _pinout.Pinos.Where(x => x.ComponenteID == ID).ToList();
|
|
string Protocolo = ((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
|
|
ID + SerialService.SplitParams +
|
|
(Conectar ? "1" : "0") + SerialService.SplitParams +
|
|
(Comandar ? "1" : "0") + SerialService.SplitParams +
|
|
//PressaoSP.ToString("000") + SerialService.SplitParams +
|
|
Variaveis.OperacaoEmAndamento.Controle.PressaoLinha.ToString() + SerialService.SplitParams +
|
|
PinoutModel.PinoProtocolo(_pinout, Funcoes);
|
|
|
|
return Protocolo;
|
|
}
|
|
|
|
public string ProtocoloComando()
|
|
{
|
|
if (Comandar)
|
|
{
|
|
string ProtocoloBomba =
|
|
((int)F_Code.Cmd).ToString() + SerialService.SplitMessage +
|
|
ID.PadRight(5, ' ') + SerialService.SplitParams +
|
|
(BombaAtuada ? "1" : "0") + SerialService.SplitParams +
|
|
//PressaoSP.ToString();
|
|
Variaveis.OperacaoEmAndamento.Controle.PressaoLinha.ToString();
|
|
return ProtocoloBomba;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
public string ProtocoloTeste()
|
|
{
|
|
if (Comandar)
|
|
{
|
|
string ProtocoloBomba =
|
|
((int)F_Code.Tst).ToString() + SerialService.SplitMessage +
|
|
ID;
|
|
return ProtocoloBomba;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
|
|
public AtuadorBombaModel Clone()
|
|
{
|
|
AtuadorBombaModel clone = new AtuadorBombaModel()
|
|
{
|
|
ID = this.ID,
|
|
Ligado = this.Ligado,
|
|
Comandar = this.Comandar,
|
|
Inicializado = this.Inicializado,
|
|
Testando = this.Testando,
|
|
Funcoes = this.Funcoes,
|
|
Pressao = this.Pressao,
|
|
//PressaoSP = this.PressaoSP,
|
|
};
|
|
|
|
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);
|
|
|
|
// 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);
|
|
}
|
|
|
|
}
|
|
}
|