From 878e7b519549217fc25253441d8bd4cf05e7b5fd Mon Sep 17 00:00:00 2001 From: Diego Freitas Date: Mon, 23 Mar 2026 09:44:45 -0300 Subject: [PATCH] Adicionado regra tatica para parar o carro se a bomba cavitar --- .../Models/Operacoes/OperacaoModel.cs | 11 +++++-- AgroBase/AgroBase/Models/Variaveis.cs | 1 + .../Operadores/HealthWorkerService.cs | 12 ++++++- .../manager_worker/modulos/regras_taticas.py | 33 +++++++++++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs b/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs index 30f59c3ed..f2c5ffbb0 100644 --- a/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs +++ b/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs @@ -2387,6 +2387,7 @@ namespace AgroBase.Models var _DispMvd = Variaveis.OperacaoEmAndamento.DispMvd; var _DispAtu = Variaveis.OperacaoEmAndamento.DispAtu; var _DispSen = Variaveis.OperacaoEmAndamento.DispSen; + var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle; var _Controle = Variaveis.OperacaoEmAndamento.Controle; var _Bateria = _DispSen?.Dados?.ContadorCarga; var _Reservatorio = _DispAtu?.Dados?.ContadorCarga; @@ -2419,6 +2420,7 @@ namespace AgroBase.Models IndiceImpacto = imu_iniciado ? sIMU.impacto_idx : 0, } : new OperacaoSensoriamentoLogImuModel(); + var bombaLinha = _DispAtu?.Dados?.BombasPressurizadoras?.FirstOrDefault(x => x.ID == "BMBLN"); var dadosAtuador = _DispAtu != null ? new OperacaoSensoriamentoLogAtuModel() { QtdCamerasSolo = _DispSen.Dados.CamerasSolo.Count, @@ -2437,10 +2439,11 @@ namespace AgroBase.Models VazaoInstantaneaCalc = _DispAtu.Dados.VazaoFluxoMLpSInstantaneaCalc, 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), + ComandoBomba = bombaLinha.ComandoAtuar, + LeituraComandoBomba = bombaLinha._EstadoLeitura == Estado.Ligado, + LeituraPotenciaBomba = FuncoesMatematicas.Clamp(bombaLinha._Potencia, 0, 100), VolumeVazaoMl = _DispAtu.Dados.VolumeVazadoML, + BombaCavitada = _DispAtu.Dados.Conectado && _DispAtu.Dados.PressaoLinha < pControle.AtuPressaoLinha && _DispAtu.Dados.PressaoLinha < VariaveisEquipamento.PressaoMinimaCavitacao && bombaLinha._EstadoLeitura == Estado.Ligado && bombaLinha._Potencia > 20, 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), AnguloBarraEsquerda = _DispAtu.Dados.AnguloBarraEsquerda, AnguloBarraDireita = _DispAtu.Dados.AnguloBarraDireita, @@ -2755,6 +2758,7 @@ namespace AgroBase.Models public double LPorMinuto { get; set; } public double TempoEstimadoRestanteMinutos { get; set; } public double DistanciaEstimadaRestanteMetros { get; set; } + public bool BombaCavitada { get; set; } public Dictionary Iniciados { get; set; } public List Bicos { get; set; } public DateTime UltimoComandoRespondido { get; set; } @@ -2786,6 +2790,7 @@ namespace AgroBase.Models AnguloBarraEsquerda = AnguloBarraEsquerda, AnguloBarraDireita = AnguloBarraDireita, AnguloBarraAltura = AnguloBarraAltura, + BombaCavitada = BombaCavitada, Iniciados = new Dictionary(Iniciados ?? new Dictionary()), UltimoComandoRespondido = UltimoComandoRespondido, LPorMetro = LPorMetro, diff --git a/AgroBase/AgroBase/Models/Variaveis.cs b/AgroBase/AgroBase/Models/Variaveis.cs index e0325ee05..2397db831 100644 --- a/AgroBase/AgroBase/Models/Variaveis.cs +++ b/AgroBase/AgroBase/Models/Variaveis.cs @@ -469,6 +469,7 @@ namespace AgroBase.Models public static double DistanciaEntreBicosCm { get; set; } = 50; public static double DensidadeHerbicida { get; set; } = 1.0; public static double CapacidadeReservatorio { get; set; } = 30; + public static double PressaoMinimaCavitacao { get; set; } = 30.0; public static double ReducaoDirecional { get; set; } = 20.0; public static int RPM_Min_Roda { get; set; } = 15; public static int RPM_Max_Roda diff --git a/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs b/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs index 77f943742..d2951f42a 100644 --- a/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs +++ b/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs @@ -179,6 +179,15 @@ namespace AgroBase.Services.Operadores percentual_reservatorio = _Sensoriamento.Atuador?.PercentualReservatorio ?? 0, percentual_bateria = _Sensoriamento.Bateria?.PercentualBateria ?? 0, } + ), + ("Atuador", new + { + pressao_linha = _Sensoriamento.Atuador?.PressaoLinha ?? 0, + potencia_bomba = _Sensoriamento.Atuador?.LeituraPotenciaBomba ?? 0, + estado_bomba = _Sensoriamento.Atuador?.LeituraComandoBomba ?? false, + tempo_bomba_atuada = _Sensoriamento.Atuador?.TempoBombaAtuada ?? 0, + bomba_cavitada = _Sensoriamento.Atuador?.BombaCavitada ?? false, + } ) ); @@ -295,7 +304,6 @@ namespace AgroBase.Services.Operadores qtd_bicos = _Parametros.QtdBicos, tempo_atuacao = pControle.AtuDuracaoAtuacao, capacidade_reservatorio = _Parametros.CapacidadeReservatorio, - pressao_linha = pControle.AtuPressaoLinha, percent_vertical_deteccao = pControle.AtuPercentualInicioPulverizacao / 100.0, height_area_deteccao = pControle.AtuAlturaAreaPulverizacao / 100.0, pct_erva_bico_on = pControle.AtuPercentualErvasBicoOn / 100.0, @@ -346,6 +354,8 @@ namespace AgroBase.Services.Operadores ("oak_parada_por_bloqueio", pControle.OakParadaPorObstaculo), ("imu_parada_por_inclinacao", pControle.ImuParadaPorInclinacao), + ("pressao_linha", pControle.AtuPressaoLinha), + ("registrar_dados_pos_processamento", pControle.RegistrarDadosPosProcessamento) ); } diff --git a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/regras_taticas.py b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/regras_taticas.py index e9c4996a2..533a45553 100644 --- a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/regras_taticas.py +++ b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/regras_taticas.py @@ -18,6 +18,12 @@ class RegrasTaticas: "ts_inicio_false": None, "ultimo_estado_bruto": False, }, + "bomba_cavitada": { + "ativo": False, + "ts_inicio_true": None, + "ts_inicio_false": None, + "ultimo_estado_bruto": False, + }, } def verifica_controle_liberado(self, ignorar_parada=False): @@ -26,6 +32,7 @@ class RegrasTaticas: freio_necessario = False _controle = ContextoGlobalRedis.get_controle() _operacao = ContextoGlobalRedis.get_operacao() + _contexto = ContextoGlobalRedis.get_contexto() status_operacao = StatusOperacao(_operacao.get("status", StatusOperacao.NaoIniciado.value)) finalizando = _operacao.get("finalizando", False) @@ -81,6 +88,32 @@ class RegrasTaticas: motivos.append(f"Inclinação perigosa detectada. roll: {roll:.2f}/{ang_roll_max}, pitch: {pitch:.2f}/{ang_pitch_max}") freio_necessario = True + pulverizador_automatico = _controle.get("pulverizador_automatico", False) + if pulverizador_automatico: + _atu = ContextoGlobalRedis.get_modulo(T_Code.Atu) + _atu_saude = StatusModulo(_atu.get("saude", {}).get("status", StatusModulo.DESCONECTADO.value)) + atu_operante = _atu_saude in [StatusModulo.OPERANTE, StatusModulo.ALERTA] + + bomba_cavitada = _contexto.get("Atuador", {}).get("bomba_cavitada", False) + pressao_sp = _controle.get("pressao_linha", 0) + pressao_atual = _contexto.get("Atuador", {}).get("pressao_linha", 0) + + cavitacao_persistente = self._avaliar_persistencia( + nome="bomba_cavitada", + estado_bruto=(atu_operante and bomba_cavitada), + tempo_acionar=5.0, + tempo_liberar=5.0 + ) + + if not atu_operante: + motivos.append(f"Pulverizador mandatório não operante: {_atu_saude.name}") + elif cavitacao_persistente: + motivos.append( + f"Cavitação na bomba pressurizadora da linha! " + f"Pressão: {pressao_sp}/{pressao_atual} psi" + ) + freio_necessario = False + return motivos, freio_necessario except Exception as e: