diff --git a/AgroBase/AgroBase/Forms/Atuador/frmAtuCalibragem.cs b/AgroBase/AgroBase/Forms/Atuador/frmAtuCalibragem.cs index a3b6ddba7..e4fbc7ae9 100644 --- a/AgroBase/AgroBase/Forms/Atuador/frmAtuCalibragem.cs +++ b/AgroBase/AgroBase/Forms/Atuador/frmAtuCalibragem.cs @@ -142,7 +142,7 @@ namespace AgroBase.Forms.Atuador grdSensoriamento.Rows[3].Cells[1].Value = BombaPressurizadora._Potencia; 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[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[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"); diff --git a/AgroBase/AgroBase/Models/Modules/AtuadorModel.cs b/AgroBase/AgroBase/Models/Modules/AtuadorModel.cs index 8046ad621..2a0193d27 100644 --- a/AgroBase/AgroBase/Models/Modules/AtuadorModel.cs +++ b/AgroBase/AgroBase/Models/Modules/AtuadorModel.cs @@ -121,28 +121,25 @@ namespace AgroBase.Models.Modules 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 readonly Dictionary _tempoAtuadoBicoSeg = new Dictionary(); - public double VazaoFluxoMLpSMedia { get; set; } - public double VolumeVazaoML { get; set; } - public DateTime InicioAtuacao { get; set; } = DateTime.MinValue; - public double TempoAtuado { get; set; } = 0; - private bool bicoAtivoAnterior = false; + public double VazaoMediaMLs { get; set; } + public double VolumeVazadoML { get; set; } + public double TempoAtuado { get; set; } + private List bicosAtivosAnterior; public void AtualizaTempoAtuadoGeral() { DateTime agora = DateTime.Now; // 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 algumBicoAtivoAnterior = bicosAtivosAnterior?.Any() ?? false; + // 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 // (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) - if (!algumBicoAtivo && bicoAtivoAnterior) + if (!algumBicoAtivo && algumBicoAtivoAnterior) { - if (InicioAtuacao != DateTime.MinValue) - { - TempoAtuado += (agora - InicioAtuacao).TotalMilliseconds; - InicioAtuacao = DateTime.MinValue; - } + AtualizaVazaoEVolume(bicosAtivosAnterior, agora); _ultimoRegistroVazao = DateTime.MinValue; + VazaoMediaMLs = TempoAtuado > 0 ? (VolumeVazadoML / TempoAtuado) : 0; // zera instantânea quando não tem bico ativo foreach (var b in BicosPulverizadores) b.VazaoInstantaneaMLs = 0; } - // Atualiza indicadores - AtualizaPercentualErvas(); - // Integra vazão/volume enquanto tiver bico ativo AtualizaVazaoEVolume(bicosAtivos, agora); - bicoAtivoAnterior = algumBicoAtivo; + // Atualiza indicadores + AtualizaPercentualErvas(); + + bicosAtivosAnterior = new List(bicosAtivos); + } + private void AtualizaVazaoEVolume(List 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() { @@ -189,52 +222,7 @@ namespace AgroBase.Models.Modules PercentualErvasTerreno = 0; } } - private void AtualizaVazaoEVolume(List 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 @@ -832,7 +820,11 @@ namespace AgroBase.Models.Modules Dados.BicosPulverizadores.ForEach(x => { x.ComandoAtuar = false; - x.ReiniciarDados(); + x.VazaoInstantaneaMLs = 0; + x.VolumeVazadoML = 0; + x.VazaoMediaMLs = 0; + x.TempoAtuado = 0; + x.Atuacoes = 0; x.ValoresLeituras.ForEach(l => { l.atual = new CanCommandFreqModel(); @@ -849,13 +841,14 @@ namespace AgroBase.Models.Modules }); Dados.VolumeVazaoAferido = 0; - Dados._somaVazao = 0; - Dados._contadorLeituras = 0; Dados._ultimoRegistroVazao = DateTime.MinValue; - Dados.VolumeVazaoML = 0; - Dados.VazaoFluxoMLpSMedia = 0; + Dados.VolumeVazadoML = 0; + Dados.VazaoMediaMLs = 0; Dados.TempoAtuado = 0; - Dados.InicioAtuacao = DateTime.MinValue; + Dados.AnguloBarraAltura = 0; + Dados.AnguloBarraDireita = 0; + Dados.AnguloBarraEsquerda = 0; + Dados.PercentualErvasTerreno = 0; } public async Task VerificaDispositivoConectado() @@ -1305,9 +1298,10 @@ namespace AgroBase.Models.Modules var bico = BicosPulverizadores.FirstOrDefault(x => x.ID_Num == id_num); 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; @@ -1349,7 +1343,7 @@ namespace AgroBase.Models.Modules } } public List 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 int _AnguloBicoLeitura => ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.LeituraAngulo)?.atual?.valor ?? 0; @@ -1386,37 +1380,8 @@ namespace AgroBase.Models.Modules public List> TrechosAtuado { get; set; } = new List>(); - public int Atuacoes { get; private set; } = 0; - private DateTime InicioAtuacao { get; set; } = DateTime.MinValue; - 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()); - Atuacoes++; - } - else if (estado_atual == Estado.Desligado) - { - if (InicioAtuacao != DateTime.MinValue) - { - TempoAtuado += (agora - InicioAtuacao).TotalMilliseconds; - InicioAtuacao = DateTime.MinValue; - } - } - _estadoLeituraAnterior = estado_atual; - } + public int Atuacoes { get; set; } = 0; + public double TempoAtuado { get; set; } = 0; public AtuadorBicoModel Clone() @@ -1435,11 +1400,15 @@ namespace AgroBase.Models.Modules Funcoes = Funcoes, ID = ID, ID_Num = ID_Num, - InicioAtuacao = InicioAtuacao, + Servo_ID_Num = Servo_ID_Num, + VolumeVazadoML = VolumeVazadoML, + TrechosAtuado = TrechosAtuado, + VazaoInstantaneaMLs = VazaoInstantaneaMLs, + _estadoLeituraAnterior = _estadoLeituraAnterior, ValoresLeituras = new List(ValoresLeituras), VazaoMediaMLs = VazaoMediaMLs, Posicao = Posicao, - TempoAtuado = TempoAtuado + TempoAtuado = TempoAtuado, }; return clone; diff --git a/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs b/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs index f97862395..2fbe3e13c 100644 --- a/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs +++ b/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs @@ -1780,8 +1780,8 @@ namespace AgroBase.Models PotenciaBomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault()?._Potencia ?? 0, BombaLigada = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ComandoAtuar, VazaoFluxoMLpSInstantanea = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VazaoFluxoMLpSInstantanea, - VazaoFluxoMLpSMedia = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VazaoFluxoMLpSMedia, - VolumeVazaoML = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VolumeVazaoML, + VazaoFluxoMLpSMedia = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VazaoMediaMLs, + VolumeVazaoML = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VolumeVazadoML, QuantidadeBicos = Variaveis.OperacaoEmAndamento.Parametros.QtdBicos ?? VariaveisEquipamento.QuantidadeBicosPulverizadores, TempoPulverizadorAtuado = Variaveis.OperacaoEmAndamento.DispAtu.Dados.TempoAtuado, Bicos = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BicosPulverizadores.Select(Bico => new AtuBicoSensoriamentoLogModel() @@ -2340,7 +2340,7 @@ namespace AgroBase.Models { QtdCamerasSolo = _DispSen.Dados.CamerasSolo.Count, CapacidadeReservatorio = VariaveisEquipamento.CapacidadeReservatorio, - HerbicidaConsumido = _DispAtu.Dados.VolumeVazaoML, + HerbicidaConsumido = _DispAtu.Dados.VolumeVazadoML, PercentualErvasTerreno = _DispAtu.Dados.PercentualErvasTerreno, HerbicidaPorErva = _Reservatorio.HerbicidaPorAtuacao, ErvasNoRadar = WeedWorkerService.DadosLeitura?.Analise?.ervas_no_radar ?? false, @@ -2352,12 +2352,12 @@ namespace AgroBase.Models PressaoLinhaCalc = _DispAtu.Dados.PressaoLinhaCalc, VazaoInstantanea = _DispAtu.Dados.VazaoFluxoMLpSInstantanea, VazaoInstantaneaCalc = _DispAtu.Dados.VazaoFluxoMLpSInstantaneaCalc, - VazaoMedia = _DispAtu.Dados.VazaoFluxoMLpSMedia, + VazaoMedia = _DispAtu.Dados.VazaoMediaMLs, TempoBombaAtuada = _DispAtu.Dados.TempoAtuado, ComandoBomba = _DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ComandoAtuar, LeituraComandoBomba = _DispAtu.Dados.BombasPressurizadoras.FirstOrDefault()._EstadoLeitura == Estado.Ligado, 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), Servos = _DispAtu.Dados.Servos?.ToDictionary(x => x.ID, y => (y._AnguloControle, y._AnguloLeiutra, y.Incremental)), AnguloBarraEsquerda = _DispAtu.Dados.AnguloBarraEsquerda, diff --git a/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs b/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs index c9a6564be..4484cbc5b 100644 --- a/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs +++ b/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs @@ -295,6 +295,8 @@ namespace AgroBase.Services.Operadores private static void AtualizarDadosModulos() { if (Variaveis.OperacaoEmAndamento.DispMvd == null) return; + if (Variaveis.OperacaoEmAndamento.DispAtu == null) return; + if (Variaveis.OperacaoEmAndamento.DispSen == null) return; var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento; var agora = DateTimeOffset.UtcNow.ToUnixTimeSeconds();