agrobot_base/AgroBase/AgroBase/Models/Modules/AtuadorModel.cs

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);
}
}
}