Ajustes nas variaveis e calculos de vazao

This commit is contained in:
Diego Freitas 2025-12-19 09:01:58 -03:00
parent 2325d866fe
commit 888927c4f5
4 changed files with 85 additions and 114 deletions

View File

@ -142,7 +142,7 @@ namespace AgroBase.Forms.Atuador
grdSensoriamento.Rows[3].Cells[1].Value = BombaPressurizadora._Potencia; grdSensoriamento.Rows[3].Cells[1].Value = BombaPressurizadora._Potencia;
grdSensoriamento.Rows[4].Cells[1].Value = DispAtu.Dados.PressaoLinha.ToString("0.00000"); grdSensoriamento.Rows[4].Cells[1].Value = DispAtu.Dados.PressaoLinha.ToString("0.00000");
grdSensoriamento.Rows[5].Cells[1].Value = DispAtu.Dados.PressaoLinhaCalc.ToString("0.00000"); grdSensoriamento.Rows[5].Cells[1].Value = DispAtu.Dados.PressaoLinhaCalc.ToString("0.00000");
grdSensoriamento.Rows[6].Cells[1].Value = DispAtu.Dados.VazaoFluxoMLpSMedia.ToString("0.00000"); grdSensoriamento.Rows[6].Cells[1].Value = DispAtu.Dados.VazaoMediaMLs.ToString("0.00000");
grdSensoriamento.Rows[7].Cells[1].Value = DispAtu.Dados.ContadorCarga.MassaAtual_Kg.ToString("0.00000"); grdSensoriamento.Rows[7].Cells[1].Value = DispAtu.Dados.ContadorCarga.MassaAtual_Kg.ToString("0.00000");
grdSensoriamento.Rows[8].Cells[1].Value = DispAtu.Dados.ContadorCarga.VolumeAtual_L.ToString("0.00000"); grdSensoriamento.Rows[8].Cells[1].Value = DispAtu.Dados.ContadorCarga.VolumeAtual_L.ToString("0.00000");
grdSensoriamento.Rows[9].Cells[1].Value = DispAtu.Dados.ContadorCarga.PercentualAtual.ToString("0.00"); grdSensoriamento.Rows[9].Cells[1].Value = DispAtu.Dados.ContadorCarga.PercentualAtual.ToString("0.00");

View File

@ -121,28 +121,25 @@ namespace AgroBase.Models.Modules
return q_mL_s; return q_mL_s;
} }
} }
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 private DateTime _ultimoRegistroVazao; // Armazena o horário da última atualização
private readonly Dictionary<string, double> _tempoAtuadoBicoSeg = new Dictionary<string, double>(); public double VazaoMediaMLs { get; set; }
public double VazaoFluxoMLpSMedia { get; set; } public double VolumeVazadoML { get; set; }
public double VolumeVazaoML { get; set; } public double TempoAtuado { get; set; }
public DateTime InicioAtuacao { get; set; } = DateTime.MinValue; private List<AtuadorBicoModel> bicosAtivosAnterior;
public double TempoAtuado { get; set; } = 0;
private bool bicoAtivoAnterior = false;
public void AtualizaTempoAtuadoGeral() public void AtualizaTempoAtuadoGeral()
{ {
DateTime agora = DateTime.Now; DateTime agora = DateTime.Now;
// Quem está ativo AGORA // Quem está ativo AGORA
var bicosAtivos = BicosPulverizadores.Where(x => x.Inicializado && x.ComandoAtuar).ToList(); var bicosAtivos = BicosPulverizadores.Where(x => x.Inicializado && x._EstadoLeitura == Estado.Ligado).ToList();
bool algumBicoAtivo = bicosAtivos.Count > 0; bool algumBicoAtivo = bicosAtivos.Count > 0;
bool algumBicoAtivoAnterior = bicosAtivosAnterior?.Any() ?? false;
// Início de uma "sessão" (transição OFF -> ON) // Início de uma "sessão" (transição OFF -> ON)
if (algumBicoAtivo && !bicoAtivoAnterior) if (algumBicoAtivo && !algumBicoAtivoAnterior)
{ {
InicioAtuacao = agora;
_ultimoRegistroVazao = agora; // inicia integração a partir daqui _ultimoRegistroVazao = agora; // inicia integração a partir daqui
// (opcional) se você quer métricas por sessão, zere volumes/médias aqui // (opcional) se você quer métricas por sessão, zere volumes/médias aqui
@ -151,28 +148,64 @@ namespace AgroBase.Models.Modules
} }
// Fim de sessão (transição ON -> OFF) // Fim de sessão (transição ON -> OFF)
if (!algumBicoAtivo && bicoAtivoAnterior) if (!algumBicoAtivo && algumBicoAtivoAnterior)
{ {
if (InicioAtuacao != DateTime.MinValue) AtualizaVazaoEVolume(bicosAtivosAnterior, agora);
{
TempoAtuado += (agora - InicioAtuacao).TotalMilliseconds;
InicioAtuacao = DateTime.MinValue;
}
_ultimoRegistroVazao = DateTime.MinValue; _ultimoRegistroVazao = DateTime.MinValue;
VazaoMediaMLs = TempoAtuado > 0 ? (VolumeVazadoML / TempoAtuado) : 0;
// zera instantânea quando não tem bico ativo // zera instantânea quando não tem bico ativo
foreach (var b in BicosPulverizadores) foreach (var b in BicosPulverizadores)
b.VazaoInstantaneaMLs = 0; b.VazaoInstantaneaMLs = 0;
} }
// Atualiza indicadores
AtualizaPercentualErvas();
// Integra vazão/volume enquanto tiver bico ativo // Integra vazão/volume enquanto tiver bico ativo
AtualizaVazaoEVolume(bicosAtivos, agora); AtualizaVazaoEVolume(bicosAtivos, agora);
bicoAtivoAnterior = algumBicoAtivo; // Atualiza indicadores
AtualizaPercentualErvas();
bicosAtivosAnterior = new List<AtuadorBicoModel>(bicosAtivos);
}
private void AtualizaVazaoEVolume(List<AtuadorBicoModel> bicosAtivos, DateTime agora)
{
// Só integra se houver bicos ativos
if (bicosAtivos == null || bicosAtivos.Count == 0)
return;
// Captura vazão total instantânea (ml/s)
double vazaoTotalInst = VazaoFluxoMLpSInstantanea;
if (_ultimoRegistroVazao == default || _ultimoRegistroVazao == DateTime.MinValue)
return;
// dt em segundos
double dt = (agora - _ultimoRegistroVazao).TotalSeconds;
_ultimoRegistroVazao = agora;
if (dt <= 0) return;
// ======== GERAL ========
VolumeVazadoML += vazaoTotalInst * dt;
TempoAtuado += dt;
VazaoMediaMLs = TempoAtuado > 0 ? (VolumeVazadoML / TempoAtuado) : 0;
// ======== POR BICO (divide por ativos) ========
double vazaoPorBicoInst = vazaoTotalInst / bicosAtivos.Count;
foreach (var bico in bicosAtivos)
{
// Instantânea por bico
bico.VazaoInstantaneaMLs = vazaoPorBicoInst;
// Volume por bico (ml) = (ml/s) * s
bico.VolumeVazadoML += vazaoPorBicoInst * dt;
bico.TempoAtuado += dt;
bico.VazaoMediaMLs = bico.TempoAtuado > 0 ? (bico.VolumeVazadoML / bico.TempoAtuado) : 0;
}
} }
private void AtualizaPercentualErvas() private void AtualizaPercentualErvas()
{ {
@ -189,52 +222,7 @@ namespace AgroBase.Models.Modules
PercentualErvasTerreno = 0; PercentualErvasTerreno = 0;
} }
} }
private void AtualizaVazaoEVolume(List<AtuadorBicoModel> bicosAtivos, DateTime agora)
{
// Só integra se houver bicos ativos
if (bicosAtivos == null || bicosAtivos.Count == 0)
return;
// Captura vazão total instantânea (ml/s)
double vazaoTotalInst = VazaoFluxoMLpSInstantanea;
// Primeiro tick: arma o relógio
if (_ultimoRegistroVazao == DateTime.MinValue)
{
_ultimoRegistroVazao = agora;
return;
}
// dt em segundos
double dt = (agora - _ultimoRegistroVazao).TotalSeconds;
_ultimoRegistroVazao = agora;
if (dt <= 0)
return;
// Vazão instantânea por bico (distribuição uniforme)
double vazaoPorBicoInst = vazaoTotalInst / bicosAtivos.Count;
foreach (var bico in bicosAtivos)
{
// Instantânea por bico
bico.VazaoInstantaneaMLs = vazaoPorBicoInst;
// Volume por bico (ml) = (ml/s) * s
bico.VolumeVazadoML += vazaoPorBicoInst * dt;
// Tempo atuado por bico (seg)
string key = bico.ID; // ou bico.ID_Num.ToString()
if (!_tempoAtuadoBicoSeg.ContainsKey(key))
_tempoAtuadoBicoSeg[key] = 0;
_tempoAtuadoBicoSeg[key] += dt;
// Média por bico (ml/s) = volume / tempo
double tempoBico = _tempoAtuadoBicoSeg[key];
bico.VazaoMediaMLs = tempoBico > 0 ? (bico.VolumeVazadoML / tempoBico) : 0;
}
}
#endregion #endregion
@ -832,7 +820,11 @@ namespace AgroBase.Models.Modules
Dados.BicosPulverizadores.ForEach(x => Dados.BicosPulverizadores.ForEach(x =>
{ {
x.ComandoAtuar = false; x.ComandoAtuar = false;
x.ReiniciarDados(); x.VazaoInstantaneaMLs = 0;
x.VolumeVazadoML = 0;
x.VazaoMediaMLs = 0;
x.TempoAtuado = 0;
x.Atuacoes = 0;
x.ValoresLeituras.ForEach(l => x.ValoresLeituras.ForEach(l =>
{ {
l.atual = new CanCommandFreqModel<dynamic>(); l.atual = new CanCommandFreqModel<dynamic>();
@ -849,13 +841,14 @@ namespace AgroBase.Models.Modules
}); });
Dados.VolumeVazaoAferido = 0; Dados.VolumeVazaoAferido = 0;
Dados._somaVazao = 0;
Dados._contadorLeituras = 0;
Dados._ultimoRegistroVazao = DateTime.MinValue; Dados._ultimoRegistroVazao = DateTime.MinValue;
Dados.VolumeVazaoML = 0; Dados.VolumeVazadoML = 0;
Dados.VazaoFluxoMLpSMedia = 0; Dados.VazaoMediaMLs = 0;
Dados.TempoAtuado = 0; Dados.TempoAtuado = 0;
Dados.InicioAtuacao = DateTime.MinValue; Dados.AnguloBarraAltura = 0;
Dados.AnguloBarraDireita = 0;
Dados.AnguloBarraEsquerda = 0;
Dados.PercentualErvasTerreno = 0;
} }
public async Task<bool> VerificaDispositivoConectado() public async Task<bool> VerificaDispositivoConectado()
@ -1305,9 +1298,10 @@ namespace AgroBase.Models.Modules
var bico = BicosPulverizadores.FirstOrDefault(x => x.ID_Num == id_num); var bico = BicosPulverizadores.FirstOrDefault(x => x.ID_Num == id_num);
if (bico == null) return; if (bico == null) return;
if (bico._estadoLeituraAnterior != bico._EstadoLeitura) if (bico._estadoLeituraAnterior == Estado.Desligado && bico._EstadoLeitura == Estado.Ligado)
{ {
bico.AtualizaTempoAtuado(); bico.Atuacoes++;
bico._estadoLeituraAnterior = bico._EstadoLeitura;
} }
} }
break; break;
@ -1349,7 +1343,7 @@ namespace AgroBase.Models.Modules
} }
} }
public List<SensorValoresLeituraModel> ValoresLeituras { get; set; } public List<SensorValoresLeituraModel> ValoresLeituras { get; set; }
public Estado _estadoLeituraAnterior { get; private set; } = Estado.Desligado; public Estado _estadoLeituraAnterior { get; set; } = Estado.Desligado;
public Estado _EstadoLeitura => (Estado)(ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura)?.atual?.valor ?? 0); public Estado _EstadoLeitura => (Estado)(ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura)?.atual?.valor ?? 0);
public int _AnguloBicoLeitura => ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.LeituraAngulo)?.atual?.valor ?? 0; public int _AnguloBicoLeitura => ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.LeituraAngulo)?.atual?.valor ?? 0;
@ -1386,37 +1380,8 @@ namespace AgroBase.Models.Modules
public List<List<double[]>> TrechosAtuado { get; set; } = new List<List<double[]>>(); public List<List<double[]>> TrechosAtuado { get; set; } = new List<List<double[]>>();
public int Atuacoes { get; private set; } = 0; public int Atuacoes { get; set; } = 0;
private DateTime InicioAtuacao { get; set; } = DateTime.MinValue; public double TempoAtuado { get; set; } = 0;
public double TempoAtuado { get; private set; } = 0;
public void ReiniciarDados()
{
Atuacoes = 0;
InicioAtuacao = DateTime.MinValue;
TempoAtuado = 0;
}
public void AtualizaTempoAtuado()
{
//if (!Variaveis.OperacaoEmAndamento.Iniciado) return;
Estado estado_atual = _EstadoLeitura;
DateTime agora = DateTime.Now;
if (estado_atual == Estado.Ligado)
{
InicioAtuacao = agora;
TrechosAtuado.Add(new List<double[]>());
Atuacoes++;
}
else if (estado_atual == Estado.Desligado)
{
if (InicioAtuacao != DateTime.MinValue)
{
TempoAtuado += (agora - InicioAtuacao).TotalMilliseconds;
InicioAtuacao = DateTime.MinValue;
}
}
_estadoLeituraAnterior = estado_atual;
}
public AtuadorBicoModel Clone() public AtuadorBicoModel Clone()
@ -1435,11 +1400,15 @@ namespace AgroBase.Models.Modules
Funcoes = Funcoes, Funcoes = Funcoes,
ID = ID, ID = ID,
ID_Num = ID_Num, ID_Num = ID_Num,
InicioAtuacao = InicioAtuacao, Servo_ID_Num = Servo_ID_Num,
VolumeVazadoML = VolumeVazadoML,
TrechosAtuado = TrechosAtuado,
VazaoInstantaneaMLs = VazaoInstantaneaMLs,
_estadoLeituraAnterior = _estadoLeituraAnterior,
ValoresLeituras = new List<SensorValoresLeituraModel>(ValoresLeituras), ValoresLeituras = new List<SensorValoresLeituraModel>(ValoresLeituras),
VazaoMediaMLs = VazaoMediaMLs, VazaoMediaMLs = VazaoMediaMLs,
Posicao = Posicao, Posicao = Posicao,
TempoAtuado = TempoAtuado TempoAtuado = TempoAtuado,
}; };
return clone; return clone;

View File

@ -1780,8 +1780,8 @@ namespace AgroBase.Models
PotenciaBomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault()?._Potencia ?? 0, PotenciaBomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault()?._Potencia ?? 0,
BombaLigada = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ComandoAtuar, BombaLigada = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ComandoAtuar,
VazaoFluxoMLpSInstantanea = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VazaoFluxoMLpSInstantanea, VazaoFluxoMLpSInstantanea = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VazaoFluxoMLpSInstantanea,
VazaoFluxoMLpSMedia = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VazaoFluxoMLpSMedia, VazaoFluxoMLpSMedia = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VazaoMediaMLs,
VolumeVazaoML = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VolumeVazaoML, VolumeVazaoML = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VolumeVazadoML,
QuantidadeBicos = Variaveis.OperacaoEmAndamento.Parametros.QtdBicos ?? VariaveisEquipamento.QuantidadeBicosPulverizadores, QuantidadeBicos = Variaveis.OperacaoEmAndamento.Parametros.QtdBicos ?? VariaveisEquipamento.QuantidadeBicosPulverizadores,
TempoPulverizadorAtuado = Variaveis.OperacaoEmAndamento.DispAtu.Dados.TempoAtuado, TempoPulverizadorAtuado = Variaveis.OperacaoEmAndamento.DispAtu.Dados.TempoAtuado,
Bicos = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BicosPulverizadores.Select(Bico => new AtuBicoSensoriamentoLogModel() Bicos = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BicosPulverizadores.Select(Bico => new AtuBicoSensoriamentoLogModel()
@ -2340,7 +2340,7 @@ namespace AgroBase.Models
{ {
QtdCamerasSolo = _DispSen.Dados.CamerasSolo.Count, QtdCamerasSolo = _DispSen.Dados.CamerasSolo.Count,
CapacidadeReservatorio = VariaveisEquipamento.CapacidadeReservatorio, CapacidadeReservatorio = VariaveisEquipamento.CapacidadeReservatorio,
HerbicidaConsumido = _DispAtu.Dados.VolumeVazaoML, HerbicidaConsumido = _DispAtu.Dados.VolumeVazadoML,
PercentualErvasTerreno = _DispAtu.Dados.PercentualErvasTerreno, PercentualErvasTerreno = _DispAtu.Dados.PercentualErvasTerreno,
HerbicidaPorErva = _Reservatorio.HerbicidaPorAtuacao, HerbicidaPorErva = _Reservatorio.HerbicidaPorAtuacao,
ErvasNoRadar = WeedWorkerService.DadosLeitura?.Analise?.ervas_no_radar ?? false, ErvasNoRadar = WeedWorkerService.DadosLeitura?.Analise?.ervas_no_radar ?? false,
@ -2352,12 +2352,12 @@ namespace AgroBase.Models
PressaoLinhaCalc = _DispAtu.Dados.PressaoLinhaCalc, PressaoLinhaCalc = _DispAtu.Dados.PressaoLinhaCalc,
VazaoInstantanea = _DispAtu.Dados.VazaoFluxoMLpSInstantanea, VazaoInstantanea = _DispAtu.Dados.VazaoFluxoMLpSInstantanea,
VazaoInstantaneaCalc = _DispAtu.Dados.VazaoFluxoMLpSInstantaneaCalc, VazaoInstantaneaCalc = _DispAtu.Dados.VazaoFluxoMLpSInstantaneaCalc,
VazaoMedia = _DispAtu.Dados.VazaoFluxoMLpSMedia, VazaoMedia = _DispAtu.Dados.VazaoMediaMLs,
TempoBombaAtuada = _DispAtu.Dados.TempoAtuado, TempoBombaAtuada = _DispAtu.Dados.TempoAtuado,
ComandoBomba = _DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ComandoAtuar, ComandoBomba = _DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ComandoAtuar,
LeituraComandoBomba = _DispAtu.Dados.BombasPressurizadoras.FirstOrDefault()._EstadoLeitura == Estado.Ligado, LeituraComandoBomba = _DispAtu.Dados.BombasPressurizadoras.FirstOrDefault()._EstadoLeitura == Estado.Ligado,
LeituraPotenciaBomba = FuncoesMatematicas.Clamp(_DispAtu.Dados.BombasPressurizadoras.FirstOrDefault()._Potencia, 0, 100), LeituraPotenciaBomba = FuncoesMatematicas.Clamp(_DispAtu.Dados.BombasPressurizadoras.FirstOrDefault()._Potencia, 0, 100),
VolumeVazaoMl = _DispAtu.Dados.VolumeVazaoML, VolumeVazaoMl = _DispAtu.Dados.VolumeVazadoML,
Iniciados = _DispAtu.Dados.Sensores.Select(s => new { s.ID, s.Inicializado }).Union(_DispAtu.Dados.BicosPulverizadores.Select(b => new { b.ID, b.Inicializado })).Union(_DispAtu.Dados.BombasPressurizadoras.Select(b => new { b.ID, b.Inicializado })).ToDictionary(x => x.ID, x => x.Inicializado), Iniciados = _DispAtu.Dados.Sensores.Select(s => new { s.ID, s.Inicializado }).Union(_DispAtu.Dados.BicosPulverizadores.Select(b => new { b.ID, b.Inicializado })).Union(_DispAtu.Dados.BombasPressurizadoras.Select(b => new { b.ID, b.Inicializado })).ToDictionary(x => x.ID, x => x.Inicializado),
Servos = _DispAtu.Dados.Servos?.ToDictionary(x => x.ID, y => (y._AnguloControle, y._AnguloLeiutra, y.Incremental)), Servos = _DispAtu.Dados.Servos?.ToDictionary(x => x.ID, y => (y._AnguloControle, y._AnguloLeiutra, y.Incremental)),
AnguloBarraEsquerda = _DispAtu.Dados.AnguloBarraEsquerda, AnguloBarraEsquerda = _DispAtu.Dados.AnguloBarraEsquerda,

View File

@ -295,6 +295,8 @@ namespace AgroBase.Services.Operadores
private static void AtualizarDadosModulos() private static void AtualizarDadosModulos()
{ {
if (Variaveis.OperacaoEmAndamento.DispMvd == null) return; if (Variaveis.OperacaoEmAndamento.DispMvd == null) return;
if (Variaveis.OperacaoEmAndamento.DispAtu == null) return;
if (Variaveis.OperacaoEmAndamento.DispSen == null) return;
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento; var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
var agora = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var agora = DateTimeOffset.UtcNow.ToUnixTimeSeconds();