melhorado saude do atuador, incluido cavitacao na propria bomba
This commit is contained in:
parent
d7f1689610
commit
64fce863d5
|
|
@ -719,7 +719,7 @@ namespace AgroBase.Models.Modules
|
||||||
analise_health = true,
|
analise_health = true,
|
||||||
maximo = 120,
|
maximo = 120,
|
||||||
minimo = 0,
|
minimo = 0,
|
||||||
nominal = 85,
|
nominal = 20,
|
||||||
unidade_medida = "PSI"
|
unidade_medida = "PSI"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -764,7 +764,7 @@ namespace AgroBase.Models.Modules
|
||||||
posicao = CanMessagePosicaoDados.Dados1,
|
posicao = CanMessagePosicaoDados.Dados1,
|
||||||
indice = 2,
|
indice = 2,
|
||||||
analise_health = true,
|
analise_health = true,
|
||||||
maximo = 20,
|
maximo = 100,
|
||||||
minimo = 0,
|
minimo = 0,
|
||||||
nominal = 0,
|
nominal = 0,
|
||||||
unidade_medida = "mL/s"
|
unidade_medida = "mL/s"
|
||||||
|
|
@ -1080,7 +1080,7 @@ namespace AgroBase.Models.Modules
|
||||||
},
|
},
|
||||||
new SensorValoresLeituraModel()
|
new SensorValoresLeituraModel()
|
||||||
{
|
{
|
||||||
funcao = FuncoesPinout.PressaoSPExtra,
|
funcao = FuncoesPinout.BitmapDiagnostico,
|
||||||
posicao = CanMessagePosicaoDados.Dados2,
|
posicao = CanMessagePosicaoDados.Dados2,
|
||||||
indice = 5,
|
indice = 5,
|
||||||
},
|
},
|
||||||
|
|
@ -2329,7 +2329,42 @@ namespace AgroBase.Models.Modules
|
||||||
public double _PotenciaFinal => ValoresLeituras?.FirstOrDefault(x => x.posicao == CanMessagePosicaoDados.Dados2 && x.funcao == FuncoesPinout.Potencia)?.atual?.valor ?? 0;
|
public double _PotenciaFinal => ValoresLeituras?.FirstOrDefault(x => x.posicao == CanMessagePosicaoDados.Dados2 && x.funcao == FuncoesPinout.Potencia)?.atual?.valor ?? 0;
|
||||||
public double _PressaoSensor => ValoresLeituras?.FirstOrDefault(x => x.posicao == CanMessagePosicaoDados.Dados2 && x.funcao == FuncoesPinout.Pressao)?.atual?.valor ?? 0;
|
public double _PressaoSensor => ValoresLeituras?.FirstOrDefault(x => x.posicao == CanMessagePosicaoDados.Dados2 && x.funcao == FuncoesPinout.Pressao)?.atual?.valor ?? 0;
|
||||||
public double _PressaoSPControle => ValoresLeituras?.FirstOrDefault(x => x.posicao == CanMessagePosicaoDados.Dados2 && x.funcao == FuncoesPinout.PressaoSP)?.atual?.valor ?? 0;
|
public double _PressaoSPControle => ValoresLeituras?.FirstOrDefault(x => x.posicao == CanMessagePosicaoDados.Dados2 && x.funcao == FuncoesPinout.PressaoSP)?.atual?.valor ?? 0;
|
||||||
public bool _PressaoSPForaDoMapa => ValoresLeituras?.FirstOrDefault(x => x.posicao == CanMessagePosicaoDados.Dados2 && x.funcao == FuncoesPinout.PressaoSPExtra)?.atual?.valor ?? false;
|
|
||||||
|
private int _BitmapDiagnostico
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var valor = ValoresLeituras?
|
||||||
|
.FirstOrDefault(x =>
|
||||||
|
x.posicao == CanMessagePosicaoDados.Dados2 &&
|
||||||
|
x.funcao == FuncoesPinout.BitmapDiagnostico)
|
||||||
|
?.atual?.valor;
|
||||||
|
|
||||||
|
if (valor == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return Convert.ToInt32(valor);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private bool TemFlagDiagnostico(int bit)
|
||||||
|
{
|
||||||
|
return (_BitmapDiagnostico & (1 << bit)) != 0;
|
||||||
|
}
|
||||||
|
public bool _PressaoSPForaDoMapa => TemFlagDiagnostico(0);
|
||||||
|
public bool _FluxoInsuficiente => TemFlagDiagnostico(1);
|
||||||
|
public bool _RecuperacaoFluxoAtiva => TemFlagDiagnostico(2);
|
||||||
|
public bool _CavitacaoSuspeita => TemFlagDiagnostico(3);
|
||||||
|
public bool _Cavitada => TemFlagDiagnostico(4);
|
||||||
|
public bool _CorteSegurancaAtivo => TemFlagDiagnostico(5);
|
||||||
|
public bool _PressaoSPLimitadoPorCapacidade => TemFlagDiagnostico(6);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public int Atuacoes { get; set; }
|
public int Atuacoes { get; set; }
|
||||||
|
|
@ -2912,7 +2947,7 @@ namespace AgroBase.Models.Modules
|
||||||
int potenciaFinal = data.Length > 4 ? data[4] : 0;
|
int potenciaFinal = data.Length > 4 ? data[4] : 0;
|
||||||
int pressaoSensor = data.Length > 5 ? data[5] : 0;
|
int pressaoSensor = data.Length > 5 ? data[5] : 0;
|
||||||
int pressaoSpControle = data.Length > 6 ? data[6] : 0;
|
int pressaoSpControle = data.Length > 6 ? data[6] : 0;
|
||||||
bool pressaoSpForaDoMapa = data.Length > 7 && data[7] == 1;
|
byte flags = data.Length > 7 ? data[7] : (byte)0;
|
||||||
AtualizarDados(
|
AtualizarDados(
|
||||||
ID_Num,
|
ID_Num,
|
||||||
posicao,
|
posicao,
|
||||||
|
|
@ -2924,7 +2959,7 @@ namespace AgroBase.Models.Modules
|
||||||
potenciaFinal,
|
potenciaFinal,
|
||||||
pressaoSensor,
|
pressaoSensor,
|
||||||
pressaoSpControle,
|
pressaoSpControle,
|
||||||
pressaoSpForaDoMapa
|
flags
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -442,6 +442,7 @@ namespace AgroBase.Models.Modules
|
||||||
Botao,
|
Botao,
|
||||||
MalhaFechada,
|
MalhaFechada,
|
||||||
PressaoSPExtra,
|
PressaoSPExtra,
|
||||||
|
BitmapDiagnostico
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PinoutUtils
|
public static class PinoutUtils
|
||||||
|
|
|
||||||
|
|
@ -3551,17 +3551,19 @@ namespace AgroBase.Models
|
||||||
PotenciaFinal = bombaLinha?._PotenciaFinal ?? 0,
|
PotenciaFinal = bombaLinha?._PotenciaFinal ?? 0,
|
||||||
PressaoSensor = bombaLinha?._PressaoSensor ?? 0,
|
PressaoSensor = bombaLinha?._PressaoSensor ?? 0,
|
||||||
PressaoSPControle = bombaLinha?._PressaoSPControle ?? 0,
|
PressaoSPControle = bombaLinha?._PressaoSPControle ?? 0,
|
||||||
|
|
||||||
PressaoSPForaDoMapa = bombaLinha?._PressaoSPForaDoMapa ?? false,
|
PressaoSPForaDoMapa = bombaLinha?._PressaoSPForaDoMapa ?? false,
|
||||||
|
FluxoInsuficiente = bombaLinha?._FluxoInsuficiente ?? false,
|
||||||
|
RecuperacaoFluxoAtiva = bombaLinha?._RecuperacaoFluxoAtiva ?? false,
|
||||||
|
CavitacaoSuspeita = bombaLinha?._CavitacaoSuspeita ?? false,
|
||||||
|
Cavitada = bombaLinha?._Cavitada ?? false,
|
||||||
|
CorteSegurancaAtivo = bombaLinha?._CorteSegurancaAtivo ?? false,
|
||||||
|
PressaoSPLimitadoPorCapacidade = bombaLinha?._PressaoSPLimitadoPorCapacidade ?? false,
|
||||||
|
|
||||||
TempoPulverizadorAtuado = dadosAtu.TempoAtuado,
|
TempoPulverizadorAtuado = dadosAtu.TempoAtuado,
|
||||||
TempoBombaAtuada = dadosAtu.TempoAtuado,
|
TempoBombaAtuada = dadosAtu.TempoAtuado,
|
||||||
|
|
||||||
BombaCavitada =
|
BombaCavitada = dadosAtu.Conectado && (bombaLinha?._Cavitada ?? false),
|
||||||
dadosAtu.Conectado &&
|
|
||||||
dadosAtu.PressaoLinha < (pControle?.AtuPressaoLinha ?? 0) &&
|
|
||||||
dadosAtu.PressaoLinha < VariaveisEquipamento.PressaoMinimaCavitacao &&
|
|
||||||
bombaLinha?._EstadoLeitura == Estado.Ligado &&
|
|
||||||
(bombaLinha?._PotenciaFinal ?? bombaLinha?._Potencia ?? 0) > 20,
|
|
||||||
|
|
||||||
ModoControleAgitador = pControle?.AtuAgitadorModo ?? ModoAgitadorCalda.SemAgitacao,
|
ModoControleAgitador = pControle?.AtuAgitadorModo ?? ModoAgitadorCalda.SemAgitacao,
|
||||||
PotenciaAgitador = dadosAtu.AgitadorDeCalda?.PotenciaMediaAtiva ?? 0,
|
PotenciaAgitador = dadosAtu.AgitadorDeCalda?.PotenciaMediaAtiva ?? 0,
|
||||||
|
|
@ -4978,7 +4980,15 @@ namespace AgroBase.Models
|
||||||
public double PotenciaFinal { get; set; }
|
public double PotenciaFinal { get; set; }
|
||||||
public double PressaoSensor { get; set; }
|
public double PressaoSensor { get; set; }
|
||||||
public double PressaoSPControle { get; set; }
|
public double PressaoSPControle { get; set; }
|
||||||
|
|
||||||
|
// Flags de cavitaao
|
||||||
public bool PressaoSPForaDoMapa { get; set; }
|
public bool PressaoSPForaDoMapa { get; set; }
|
||||||
|
public bool FluxoInsuficiente { get; set; }
|
||||||
|
public bool RecuperacaoFluxoAtiva { get; set; }
|
||||||
|
public bool CavitacaoSuspeita { get; set; }
|
||||||
|
public bool Cavitada { get; set; }
|
||||||
|
public bool CorteSegurancaAtivo { get; set; }
|
||||||
|
public bool PressaoSPLimitadoPorCapacidade { get; set; }
|
||||||
|
|
||||||
public double TempoPulverizadorAtuado { get; set; }
|
public double TempoPulverizadorAtuado { get; set; }
|
||||||
public double TempoBombaAtuada { get; set; }
|
public double TempoBombaAtuada { get; set; }
|
||||||
|
|
@ -5055,7 +5065,14 @@ namespace AgroBase.Models
|
||||||
PotenciaFinal = PotenciaFinal,
|
PotenciaFinal = PotenciaFinal,
|
||||||
PressaoSensor = PressaoSensor,
|
PressaoSensor = PressaoSensor,
|
||||||
PressaoSPControle = PressaoSPControle,
|
PressaoSPControle = PressaoSPControle,
|
||||||
|
|
||||||
PressaoSPForaDoMapa = PressaoSPForaDoMapa,
|
PressaoSPForaDoMapa = PressaoSPForaDoMapa,
|
||||||
|
FluxoInsuficiente = FluxoInsuficiente,
|
||||||
|
RecuperacaoFluxoAtiva = RecuperacaoFluxoAtiva,
|
||||||
|
CavitacaoSuspeita = CavitacaoSuspeita,
|
||||||
|
Cavitada = Cavitada,
|
||||||
|
CorteSegurancaAtivo = CorteSegurancaAtivo,
|
||||||
|
PressaoSPLimitadoPorCapacidade = PressaoSPLimitadoPorCapacidade,
|
||||||
|
|
||||||
TempoPulverizadorAtuado = TempoPulverizadorAtuado,
|
TempoPulverizadorAtuado = TempoPulverizadorAtuado,
|
||||||
TempoBombaAtuada = TempoBombaAtuada,
|
TempoBombaAtuada = TempoBombaAtuada,
|
||||||
|
|
|
||||||
|
|
@ -432,6 +432,7 @@ namespace AgroBase.Services
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
op = Variaveis.OperacaoEmAndamento;
|
||||||
op.Sensoriamento.Operacao.ModsCalibragem.TryGetValue(T_Code.Mov, out var m);
|
op.Sensoriamento.Operacao.ModsCalibragem.TryGetValue(T_Code.Mov, out var m);
|
||||||
|
|
||||||
if (m == null)
|
if (m == null)
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,10 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
RESPOSTA_RECENTE_MS = 8000.0
|
RESPOSTA_RECENTE_MS = 8000.0
|
||||||
RESPOSTA_LENTA_MS = 4500.0
|
RESPOSTA_LENTA_MS = 4500.0
|
||||||
|
|
||||||
COMANDO_GRACE_MS = 900.0
|
COMANDO_GRACE_MS = 1500.0
|
||||||
COMANDO_ALERTA_MS = 2500.0
|
COMANDO_ALERTA_MS = 4000.0
|
||||||
COMANDO_FALHA_MS = 6000.0
|
COMANDO_FALHA_MS = 8000.0
|
||||||
|
PROCESSO_GRACE_MS = 2500.0
|
||||||
|
|
||||||
FREQ_MIN_DEFAULT_FACTOR = 0.35
|
FREQ_MIN_DEFAULT_FACTOR = 0.35
|
||||||
PENALIDADE_FREQ_MAX_PADRAO = 4
|
PENALIDADE_FREQ_MAX_PADRAO = 4
|
||||||
|
|
@ -467,8 +468,8 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
score = min(score, 90)
|
score = min(score, 90)
|
||||||
|
|
||||||
if label_sensor == "PRSLN":
|
if label_sensor == "PRSLN":
|
||||||
bomba_on = self._bomba_principal_ligada(ctx)
|
bomba_on = self._bomba_principal_ligada_fisica(ctx)
|
||||||
if bomba_on and not ctx["pressao_linha_regular"]:
|
if bomba_on and not self._pulverizacao_em_transicao(ctx) and not ctx["pressao_linha_regular"]:
|
||||||
pressao = ctx["pressao_linha"]
|
pressao = ctx["pressao_linha"]
|
||||||
motivos.append(f"Pressão baixa com bomba ligada ({pressao:.1f} psi)")
|
motivos.append(f"Pressão baixa com bomba ligada ({pressao:.1f} psi)")
|
||||||
condicoes.append({
|
condicoes.append({
|
||||||
|
|
@ -485,11 +486,11 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
score = min(score, 70)
|
score = min(score, 70)
|
||||||
|
|
||||||
if label_sensor == "FLXLN":
|
if label_sensor == "FLXLN":
|
||||||
bicos_on = len(ctx["bicos_ligados"]) > 0 or len(ctx["bicos_comandados"]) > 0
|
bicos_on = len(ctx["bicos_ligados"]) > 0
|
||||||
bomba_on = self._bomba_principal_ligada(ctx)
|
bomba_on = self._bomba_principal_ligada_fisica(ctx)
|
||||||
vazao = ctx["vazao_linha_mls"]
|
vazao = ctx["vazao_linha_mls"]
|
||||||
|
|
||||||
if bicos_on and bomba_on and vazao <= self.FLUXO_MIN_COM_BICOS_MLS:
|
if bicos_on and bomba_on and not self._pulverizacao_em_transicao(ctx) and vazao <= self.FLUXO_MIN_COM_BICOS_MLS:
|
||||||
motivos.append(f"Fluxo baixo com bicos e bomba ativos ({vazao:.1f} mL/s)")
|
motivos.append(f"Fluxo baixo com bicos e bomba ativos ({vazao:.1f} mL/s)")
|
||||||
condicoes.append({
|
condicoes.append({
|
||||||
"label": "Fluxo de linha",
|
"label": "Fluxo de linha",
|
||||||
|
|
@ -597,24 +598,27 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
}
|
}
|
||||||
|
|
||||||
if comando and not estado_on:
|
if comando and not estado_on:
|
||||||
severidade = 92 if tem_idade_comando and ultimo_comando_ms >= self.COMANDO_FALHA_MS else 75
|
severidade = 85 if tem_idade_comando and ultimo_comando_ms >= self.COMANDO_FALHA_MS else 70
|
||||||
motivos.append(f"Bico comandado ligado, mas leitura indica desligado ({label})")
|
|
||||||
|
motivos.append(f"Bico comandado ligado, mas leitura ainda indica desligado ({label})")
|
||||||
condicoes.append({
|
condicoes.append({
|
||||||
"label": "Bico",
|
"label": "Bico",
|
||||||
"valor": 0,
|
"valor": 0,
|
||||||
"severidade": severidade,
|
"severidade": severidade,
|
||||||
"classe": "falha_hardware" if severidade > 90 else "processo",
|
"classe": "processo",
|
||||||
"descricao": f"Bico {label} comandado ligado, mas estado lido está desligado",
|
"descricao": f"Bico {label} comandado ligado, mas estado lido ainda está desligado",
|
||||||
"acoes": [
|
"acoes": [
|
||||||
"Verificar solenoide do bico.",
|
"Aguardar próxima atualização CAN.",
|
||||||
"Verificar comando físico no ATU.",
|
"Verificar solenoide do bico se a divergência persistir.",
|
||||||
"Conferir alimentação e retorno do bico.",
|
"Conferir alimentação e retorno do bico.",
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
score = min(score, 35 if severidade > 90 else 70)
|
|
||||||
|
score = min(score, 55 if severidade >= 85 else 75)
|
||||||
|
|
||||||
if not comando and estado_on:
|
if not comando and estado_on:
|
||||||
severidade = 95 if tem_idade_comando and ultimo_comando_ms >= self.COMANDO_ALERTA_MS else 85
|
severidade = 95 if tem_idade_comando and ultimo_comando_ms >= self.COMANDO_FALHA_MS else 82
|
||||||
|
|
||||||
motivos.append(f"Bico ligado sem comando ({label})")
|
motivos.append(f"Bico ligado sem comando ({label})")
|
||||||
condicoes.append({
|
condicoes.append({
|
||||||
"label": "Bico",
|
"label": "Bico",
|
||||||
|
|
@ -627,7 +631,8 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
"Verificar se o comando de desligamento chegou ao ATU.",
|
"Verificar se o comando de desligamento chegou ao ATU.",
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
score = min(score, 25 if severidade > 90 else 60)
|
|
||||||
|
score = min(score, 25 if severidade > 90 else 65)
|
||||||
|
|
||||||
erro_ang = abs(angulo - angulo_desejado)
|
erro_ang = abs(angulo - angulo_desejado)
|
||||||
|
|
||||||
|
|
@ -747,24 +752,27 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
}
|
}
|
||||||
|
|
||||||
if comando and not bomba_ligada:
|
if comando and not bomba_ligada:
|
||||||
severidade = 92 if tem_idade_comando and ultimo_comando_ms >= self.COMANDO_FALHA_MS else 78
|
severidade = 85 if tem_idade_comando and ultimo_comando_ms >= self.COMANDO_FALHA_MS else 70
|
||||||
motivos.append(f"Bomba {label} comandada ligada, mas leitura não indica acionamento")
|
|
||||||
|
motivos.append(f"Bomba {label} comandada ligada, mas leitura ainda não indica acionamento")
|
||||||
condicoes.append({
|
condicoes.append({
|
||||||
"label": "Bomba",
|
"label": "Bomba",
|
||||||
"valor": potencia,
|
"valor": potencia,
|
||||||
"severidade": severidade,
|
"severidade": severidade,
|
||||||
"classe": "falha_hardware" if severidade > 90 else "processo",
|
"classe": "processo",
|
||||||
"descricao": f"Bomba {label} comandada ligada, mas estado/potência indicam desligado",
|
"descricao": f"Bomba {label} comandada ligada, mas estado/potência ainda indicam desligado",
|
||||||
"acoes": [
|
"acoes": [
|
||||||
"Verificar relé/driver da bomba.",
|
"Aguardar próxima atualização CAN.",
|
||||||
"Verificar alimentação da bomba.",
|
"Verificar relé/driver da bomba se a divergência persistir.",
|
||||||
"Conferir comando físico Command1 do ATU.",
|
"Conferir alimentação e retorno da bomba.",
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
score = min(score, 35 if severidade > 90 else 68)
|
|
||||||
|
score = min(score, 55 if severidade >= 85 else 75)
|
||||||
|
|
||||||
if not comando and bomba_ligada:
|
if not comando and bomba_ligada:
|
||||||
severidade = 95 if tem_idade_comando and ultimo_comando_ms >= self.COMANDO_ALERTA_MS else 85
|
severidade = 95 if tem_idade_comando and ultimo_comando_ms >= self.COMANDO_FALHA_MS else 82
|
||||||
|
|
||||||
motivos.append(f"Bomba {label} ligada sem comando")
|
motivos.append(f"Bomba {label} ligada sem comando")
|
||||||
condicoes.append({
|
condicoes.append({
|
||||||
"label": "Bomba",
|
"label": "Bomba",
|
||||||
|
|
@ -777,7 +785,8 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
"Verificar se comando de desligamento chegou ao ATU.",
|
"Verificar se comando de desligamento chegou ao ATU.",
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
score = min(score, 25 if severidade > 90 else 60)
|
|
||||||
|
score = min(score, 25 if severidade > 90 else 65)
|
||||||
|
|
||||||
if eh_principal and comando and bomba_ligada:
|
if eh_principal and comando and bomba_ligada:
|
||||||
pressao_ref = pressao if pressao > 0 else ctx["pressao_linha"]
|
pressao_ref = pressao if pressao > 0 else ctx["pressao_linha"]
|
||||||
|
|
@ -799,7 +808,13 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
})
|
})
|
||||||
score = min(score, 25)
|
score = min(score, 25)
|
||||||
|
|
||||||
elif pressao_alvo > 0 and pressao_ref < max(0, pressao_alvo - self.PRESSAO_TOL_PSI):
|
elif (
|
||||||
|
pressao_alvo > 0 and
|
||||||
|
pressao_ref < max(0, pressao_alvo - self.PRESSAO_TOL_PSI) and
|
||||||
|
not ctx["calibrando"] and
|
||||||
|
not ctx["finalizando"] and
|
||||||
|
not self._pulverizacao_em_transicao(ctx)
|
||||||
|
):
|
||||||
severidade = 88 if len(ctx["bicos_ligados"]) > 0 else 75
|
severidade = 88 if len(ctx["bicos_ligados"]) > 0 else 75
|
||||||
motivos.append(f"Pressão abaixo do SP ({pressao_ref:.1f}/{pressao_alvo:.1f} psi)")
|
motivos.append(f"Pressão abaixo do SP ({pressao_ref:.1f}/{pressao_alvo:.1f} psi)")
|
||||||
condicoes.append({
|
condicoes.append({
|
||||||
|
|
@ -855,7 +870,9 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
calibrando = ctx["calibrando"]
|
calibrando = ctx["calibrando"]
|
||||||
bomba_principal = ctx["bomba_principal"]
|
bomba_principal = ctx["bomba_principal"]
|
||||||
|
|
||||||
bomba_principal_on = self._bomba_principal_ligada(ctx)
|
em_transicao = self._pulverizacao_em_transicao(ctx)
|
||||||
|
bomba_principal_on = self._bomba_principal_ligada_fisica(ctx)
|
||||||
|
bomba_principal_cmd = self._bomba_principal_comandada(ctx)
|
||||||
bicos_cmd = len(ctx["bicos_comandados"]) > 0
|
bicos_cmd = len(ctx["bicos_comandados"]) > 0
|
||||||
bicos_on = len(ctx["bicos_ligados"]) > 0
|
bicos_on = len(ctx["bicos_ligados"]) > 0
|
||||||
|
|
||||||
|
|
@ -933,7 +950,15 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
})
|
})
|
||||||
score = min(score, 80)
|
score = min(score, 80)
|
||||||
|
|
||||||
if (bicos_cmd or bicos_on) and auto and not bomba_principal_on and not calibrando:
|
if (
|
||||||
|
(bicos_cmd or bicos_on) and
|
||||||
|
auto and
|
||||||
|
not bomba_principal_on and
|
||||||
|
not bomba_principal_cmd and
|
||||||
|
not calibrando and
|
||||||
|
not ctx["finalizando"] and
|
||||||
|
not em_transicao
|
||||||
|
):
|
||||||
pulverizacao_incoerente = True
|
pulverizacao_incoerente = True
|
||||||
motivos.append("Bicos ativos ou comandados com bomba principal desligada")
|
motivos.append("Bicos ativos ou comandados com bomba principal desligada")
|
||||||
condicoes.append({
|
condicoes.append({
|
||||||
|
|
@ -950,7 +975,14 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
})
|
})
|
||||||
score = min(score, 35)
|
score = min(score, 35)
|
||||||
|
|
||||||
if bomba_principal_on and bicos_on and ctx["vazao_linha_mls"] <= self.FLUXO_MIN_COM_BICOS_MLS:
|
if (
|
||||||
|
bomba_principal_on and
|
||||||
|
bicos_on and
|
||||||
|
not calibrando and
|
||||||
|
not ctx["finalizando"] and
|
||||||
|
not em_transicao and
|
||||||
|
ctx["vazao_linha_mls"] <= self.FLUXO_MIN_COM_BICOS_MLS
|
||||||
|
):
|
||||||
motivos.append("Fluxo ausente com bomba e bicos ligados")
|
motivos.append("Fluxo ausente com bomba e bicos ligados")
|
||||||
condicoes.append({
|
condicoes.append({
|
||||||
"label": "Fluxo de pulverização",
|
"label": "Fluxo de pulverização",
|
||||||
|
|
@ -964,7 +996,13 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
})
|
})
|
||||||
score = min(score, 62)
|
score = min(score, 62)
|
||||||
|
|
||||||
if bomba_principal_on and not ctx["pressao_linha_regular"]:
|
if (
|
||||||
|
bomba_principal_on and
|
||||||
|
not calibrando and
|
||||||
|
not ctx["finalizando"] and
|
||||||
|
not em_transicao and
|
||||||
|
not ctx["pressao_linha_regular"]
|
||||||
|
):
|
||||||
motivos.append("Pressão de linha irregular com bomba ligada")
|
motivos.append("Pressão de linha irregular com bomba ligada")
|
||||||
condicoes.append({
|
condicoes.append({
|
||||||
"label": "Pressão de pulverização",
|
"label": "Pressão de pulverização",
|
||||||
|
|
@ -1251,7 +1289,15 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
return item
|
return item
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _bomba_principal_ligada(self, ctx):
|
def _bomba_principal_comandada(self, ctx):
|
||||||
|
bomba = ctx.get("bomba_principal")
|
||||||
|
if not bomba:
|
||||||
|
return False
|
||||||
|
|
||||||
|
dados = bomba.get("dados", {})
|
||||||
|
return self._estado_desejado_ligado(dados)
|
||||||
|
|
||||||
|
def _bomba_principal_ligada_fisica(self, ctx):
|
||||||
bomba = ctx.get("bomba_principal")
|
bomba = ctx.get("bomba_principal")
|
||||||
if not bomba:
|
if not bomba:
|
||||||
return False
|
return False
|
||||||
|
|
@ -1259,9 +1305,29 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
dados = bomba.get("dados", {})
|
dados = bomba.get("dados", {})
|
||||||
estado = self._get(dados, "estado_leitura", self._campo_atual(dados, "EstadoLeitura", 0))
|
estado = self._get(dados, "estado_leitura", self._campo_atual(dados, "EstadoLeitura", 0))
|
||||||
potencia = self._float(self._get(dados, "potencia", self._campo_atual(dados, "Potencia", 0)), 0)
|
potencia = self._float(self._get(dados, "potencia", self._campo_atual(dados, "Potencia", 0)), 0)
|
||||||
comando = self._bool(dados.get("comando_atuar", False))
|
|
||||||
|
|
||||||
return self._estado_ligado(estado) or potencia > self.POTENCIA_MIN_BOMBA_LIGADA or comando
|
return self._estado_ligado(estado) or potencia > self.POTENCIA_MIN_BOMBA_LIGADA
|
||||||
|
|
||||||
|
def _comando_em_transicao(self, dados, janela_ms=None):
|
||||||
|
janela_ms = janela_ms if janela_ms is not None else self.PROCESSO_GRACE_MS
|
||||||
|
ultimo_comando_ms = self._float(dados.get("ultimo_comando_ms", 999999), 999999)
|
||||||
|
return ultimo_comando_ms < 900000 and ultimo_comando_ms < janela_ms
|
||||||
|
|
||||||
|
def _pulverizacao_em_transicao(self, ctx):
|
||||||
|
bomba = ctx.get("bomba_principal")
|
||||||
|
|
||||||
|
if bomba and self._comando_em_transicao(bomba.get("dados", {})):
|
||||||
|
return True
|
||||||
|
|
||||||
|
for b in ctx.get("bicos_comandados", []) or []:
|
||||||
|
if self._comando_em_transicao(b.get("dados", {})):
|
||||||
|
return True
|
||||||
|
|
||||||
|
for b in ctx.get("bicos_ligados", []) or []:
|
||||||
|
if self._comando_em_transicao(b.get("dados", {})):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def _obter_ultima_resposta_ms(self, dados):
|
def _obter_ultima_resposta_ms(self, dados):
|
||||||
if not isinstance(dados, dict):
|
if not isinstance(dados, dict):
|
||||||
|
|
@ -1332,6 +1398,9 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
if not isinstance(dados, dict):
|
if not isinstance(dados, dict):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if "comando_atuar" in dados:
|
||||||
|
return self._bool(dados.get("comando_atuar", False))
|
||||||
|
|
||||||
for key in [
|
for key in [
|
||||||
"estado_desejado",
|
"estado_desejado",
|
||||||
"status_desejado",
|
"status_desejado",
|
||||||
|
|
@ -1341,7 +1410,7 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
||||||
if key in dados:
|
if key in dados:
|
||||||
return self._estado_ligado(dados.get(key))
|
return self._estado_ligado(dados.get(key))
|
||||||
|
|
||||||
return self._bool(dados.get("comando_atuar", False))
|
return False
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
||||||
|
|
@ -310,6 +310,27 @@ class BombaPressurizadora_v2 : public ComponenteCAN {
|
||||||
bool LinhaArmadaPorFluxo = false;
|
bool LinhaArmadaPorFluxo = false;
|
||||||
bool FalhaArmamentoLinhaAtual = false;
|
bool FalhaArmamentoLinhaAtual = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Detector de cavitacao consolidado na firmware.
|
||||||
|
Nao corta a bomba neste primeiro momento.
|
||||||
|
Apenas informa estado diagnostico para o C# via CAN.
|
||||||
|
*/
|
||||||
|
bool HabilitarDetectorCavitacao = true;
|
||||||
|
|
||||||
|
double PressaoMinimaCavitacaoPsi = 8.0;
|
||||||
|
double MargemPressaoSPCavitacaoPsi = 6.0;
|
||||||
|
double PotenciaMinimaParaDetectarCavitacaoPct = 25.0;
|
||||||
|
double VazaoMinimaCavitacaoMLs = 2.0;
|
||||||
|
|
||||||
|
unsigned long TempoIgnorarAposLigarBombaMs = 1500;
|
||||||
|
unsigned long TempoIgnorarAposMudancaBicosMs = 900;
|
||||||
|
unsigned long TempoParaSuspeitarCavitacaoMs = 900;
|
||||||
|
unsigned long TempoParaConfirmarCavitacaoMs = 2500;
|
||||||
|
unsigned long TempoParaLimparCavitacaoMs = 1800;
|
||||||
|
|
||||||
|
bool CavitacaoSuspeitaAtual = false;
|
||||||
|
bool CavitadaAtual = false;
|
||||||
|
|
||||||
void ConfigurarBicos(BicoPulverizador_v2** bicos, size_t qtdBicos) {
|
void ConfigurarBicos(BicoPulverizador_v2** bicos, size_t qtdBicos) {
|
||||||
_bicos = bicos;
|
_bicos = bicos;
|
||||||
_qtdBicos = qtdBicos;
|
_qtdBicos = qtdBicos;
|
||||||
|
|
@ -615,6 +636,8 @@ class BombaPressurizadora_v2 : public ComponenteCAN {
|
||||||
PercentualPotenciaLeitura = constrain(PotenciaFinalAtual, 0.0, 100.0);
|
PercentualPotenciaLeitura = constrain(PotenciaFinalAtual, 0.0, 100.0);
|
||||||
PotenciaLeitura = (int)round(PercentualPotenciaLeitura);
|
PotenciaLeitura = (int)round(PercentualPotenciaLeitura);
|
||||||
EstadoLeitura = (PercentualPotenciaLeitura > 2.0) ? Estado::Ligado : Estado::Desligado;
|
EstadoLeitura = (PercentualPotenciaLeitura > 2.0) ? Estado::Ligado : Estado::Desligado;
|
||||||
|
|
||||||
|
AtualizarDetectorCavitacao();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequisitarDados() {
|
void RequisitarDados() {
|
||||||
|
|
@ -694,7 +717,7 @@ class BombaPressurizadora_v2 : public ComponenteCAN {
|
||||||
data.push_back(LimitarByte(PotenciaFinalAtual)); // data[4]
|
data.push_back(LimitarByte(PotenciaFinalAtual)); // data[4]
|
||||||
data.push_back(LimitarByte(PressaoSensorAtual)); // data[5]
|
data.push_back(LimitarByte(PressaoSensorAtual)); // data[5]
|
||||||
data.push_back(LimitarByte(PressaoSPControleAtual)); // data[6]
|
data.push_back(LimitarByte(PressaoSPControleAtual)); // data[6]
|
||||||
data.push_back(PressaoSPForaDoMapaAtual ? 1 : 0); // data[7]
|
data.push_back(MontarFlagsDiagnosticoBomba()); // data[7]
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -732,9 +755,18 @@ class BombaPressurizadora_v2 : public ComponenteCAN {
|
||||||
unsigned long _inicioSemFluxoMs = 0;
|
unsigned long _inicioSemFluxoMs = 0;
|
||||||
unsigned long _inicioComFluxoMs = 0;
|
unsigned long _inicioComFluxoMs = 0;
|
||||||
|
|
||||||
|
unsigned long _ultimoComandoLigadoMs = 0;
|
||||||
|
unsigned long _ultimaMudancaBicosCavitacaoMs = 0;
|
||||||
|
unsigned long _inicioCondicaoCavitacaoMs = 0;
|
||||||
|
unsigned long _inicioCondicaoNormalCavitacaoMs = 0;
|
||||||
|
|
||||||
|
uint8_t _ultimaQtdBicosCavitacao = 0;
|
||||||
|
Estado _ultimoEstadoControleCavitacao = Estado::Desligado;
|
||||||
|
|
||||||
void ResetarControle() {
|
void ResetarControle() {
|
||||||
ResetarIntegralPressao();
|
ResetarIntegralPressao();
|
||||||
ResetarSupervisorFluxo();
|
ResetarSupervisorFluxo();
|
||||||
|
ResetarDetectorCavitacao();
|
||||||
ResetarKick();
|
ResetarKick();
|
||||||
_ultimoControleMs = 0;
|
_ultimoControleMs = 0;
|
||||||
_ultimoTempoDtMs = 0;
|
_ultimoTempoDtMs = 0;
|
||||||
|
|
@ -760,6 +792,7 @@ class BombaPressurizadora_v2 : public ComponenteCAN {
|
||||||
void ResetarEstadosDeBicosFechados() {
|
void ResetarEstadosDeBicosFechados() {
|
||||||
ResetarIntegralPressao();
|
ResetarIntegralPressao();
|
||||||
ResetarSupervisorFluxo();
|
ResetarSupervisorFluxo();
|
||||||
|
ResetarDetectorCavitacao();
|
||||||
ResetarKick();
|
ResetarKick();
|
||||||
PotenciaFeedForwardAtual = 0.0;
|
PotenciaFeedForwardAtual = 0.0;
|
||||||
CorrecaoPIAtual = 0.0;
|
CorrecaoPIAtual = 0.0;
|
||||||
|
|
@ -1421,6 +1454,159 @@ class BombaPressurizadora_v2 : public ComponenteCAN {
|
||||||
return (a > b) ? a : b;
|
return (a > b) ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResetarDetectorCavitacao() {
|
||||||
|
CavitacaoSuspeitaAtual = false;
|
||||||
|
CavitadaAtual = false;
|
||||||
|
|
||||||
|
_inicioCondicaoCavitacaoMs = 0;
|
||||||
|
_inicioCondicaoNormalCavitacaoMs = 0;
|
||||||
|
_ultimaMudancaBicosCavitacaoMs = 0;
|
||||||
|
_ultimoComandoLigadoMs = 0;
|
||||||
|
|
||||||
|
_ultimaQtdBicosCavitacao = 0;
|
||||||
|
_ultimoEstadoControleCavitacao = _EstadoControle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AtualizarDetectorCavitacao() {
|
||||||
|
unsigned long agora = millis();
|
||||||
|
|
||||||
|
if (!HabilitarDetectorCavitacao) {
|
||||||
|
ResetarDetectorCavitacao();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_EstadoControle != _ultimoEstadoControleCavitacao) {
|
||||||
|
_ultimoEstadoControleCavitacao = _EstadoControle;
|
||||||
|
|
||||||
|
if (_EstadoControle == Estado::Ligado) {
|
||||||
|
_ultimoComandoLigadoMs = agora;
|
||||||
|
} else {
|
||||||
|
ResetarDetectorCavitacao();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QtdBicosLigados != _ultimaQtdBicosCavitacao) {
|
||||||
|
_ultimaQtdBicosCavitacao = QtdBicosLigados;
|
||||||
|
_ultimaMudancaBicosCavitacaoMs = agora;
|
||||||
|
|
||||||
|
_inicioCondicaoCavitacaoMs = 0;
|
||||||
|
CavitacaoSuspeitaAtual = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_EstadoControle != Estado::Ligado) {
|
||||||
|
ResetarDetectorCavitacao();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QtdBicosLigados == 0) {
|
||||||
|
ResetarDetectorCavitacao();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SensorFluxoDisponivel() || sensorPressao == nullptr) {
|
||||||
|
CavitacaoSuspeitaAtual = false;
|
||||||
|
CavitadaAtual = false;
|
||||||
|
_inicioCondicaoCavitacaoMs = 0;
|
||||||
|
_inicioCondicaoNormalCavitacaoMs = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool emJanelaIgnorada = false;
|
||||||
|
|
||||||
|
if (_ultimoComandoLigadoMs > 0 && (agora - _ultimoComandoLigadoMs) < TempoIgnorarAposLigarBombaMs) {
|
||||||
|
emJanelaIgnorada = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_ultimaMudancaBicosCavitacaoMs > 0 && (agora - _ultimaMudancaBicosCavitacaoMs) < TempoIgnorarAposMudancaBicosMs) {
|
||||||
|
emJanelaIgnorada = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emJanelaIgnorada) {
|
||||||
|
_inicioCondicaoCavitacaoMs = 0;
|
||||||
|
CavitacaoSuspeitaAtual = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bombaRealmenteAtiva =
|
||||||
|
EstadoLeitura == Estado::Ligado &&
|
||||||
|
PotenciaFinalAtual >= PotenciaMinimaParaDetectarCavitacaoPct;
|
||||||
|
|
||||||
|
bool pressaoMuitoBaixa =
|
||||||
|
PressaoFiltrada <= PressaoMinimaCavitacaoPsi;
|
||||||
|
|
||||||
|
bool pressaoAbaixoDoSP =
|
||||||
|
_PressaoSP > 0.0 &&
|
||||||
|
PressaoFiltrada <= (_PressaoSP - MargemPressaoSPCavitacaoPsi);
|
||||||
|
|
||||||
|
bool semFluxo =
|
||||||
|
!FluxoPresenteAtual &&
|
||||||
|
VazaoFluxoCorrigidaAtualMLs <= VazaoMinimaCavitacaoMLs;
|
||||||
|
|
||||||
|
bool condicaoCavitacao =
|
||||||
|
bombaRealmenteAtiva &&
|
||||||
|
pressaoMuitoBaixa &&
|
||||||
|
pressaoAbaixoDoSP &&
|
||||||
|
semFluxo;
|
||||||
|
|
||||||
|
if (condicaoCavitacao) {
|
||||||
|
if (_inicioCondicaoCavitacaoMs == 0) {
|
||||||
|
_inicioCondicaoCavitacaoMs = agora;
|
||||||
|
}
|
||||||
|
|
||||||
|
_inicioCondicaoNormalCavitacaoMs = 0;
|
||||||
|
|
||||||
|
unsigned long tempoCondicao = agora - _inicioCondicaoCavitacaoMs;
|
||||||
|
|
||||||
|
CavitacaoSuspeitaAtual =
|
||||||
|
tempoCondicao >= TempoParaSuspeitarCavitacaoMs;
|
||||||
|
|
||||||
|
if (tempoCondicao >= TempoParaConfirmarCavitacaoMs) {
|
||||||
|
CavitadaAtual = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_inicioCondicaoCavitacaoMs = 0;
|
||||||
|
CavitacaoSuspeitaAtual = false;
|
||||||
|
|
||||||
|
bool condicaoNormal =
|
||||||
|
_EstadoControle != Estado::Ligado ||
|
||||||
|
QtdBicosLigados == 0 ||
|
||||||
|
FluxoPresenteAtual ||
|
||||||
|
VazaoFluxoCorrigidaAtualMLs > VazaoMinimaCavitacaoMLs ||
|
||||||
|
PressaoFiltrada >= (PressaoMinimaCavitacaoPsi + 3.0) ||
|
||||||
|
PotenciaFinalAtual < PotenciaMinimaParaDetectarCavitacaoPct;
|
||||||
|
|
||||||
|
if (CavitadaAtual && condicaoNormal) {
|
||||||
|
if (_inicioCondicaoNormalCavitacaoMs == 0) {
|
||||||
|
_inicioCondicaoNormalCavitacaoMs = agora;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((agora - _inicioCondicaoNormalCavitacaoMs) >= TempoParaLimparCavitacaoMs) {
|
||||||
|
CavitadaAtual = false;
|
||||||
|
_inicioCondicaoNormalCavitacaoMs = 0;
|
||||||
|
}
|
||||||
|
} else if (!condicaoNormal) {
|
||||||
|
_inicioCondicaoNormalCavitacaoMs = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t MontarFlagsDiagnosticoBomba() {
|
||||||
|
uint8_t flags = 0;
|
||||||
|
|
||||||
|
if (PressaoSPForaDoMapaAtual) flags |= (1 << 0);
|
||||||
|
if (FluxoInsuficienteAtual) flags |= (1 << 1);
|
||||||
|
if (RecuperacaoFluxoAtiva) flags |= (1 << 2);
|
||||||
|
if (CavitacaoSuspeitaAtual) flags |= (1 << 3);
|
||||||
|
if (CavitadaAtual) flags |= (1 << 4);
|
||||||
|
if (CorteSegurancaAtivo) flags |= (1 << 5);
|
||||||
|
if (PressaoSPLimitadoPorCapacidade) flags |= (1 << 6);
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
void MostrarLog(String mensagem) {
|
void MostrarLog(String mensagem) {
|
||||||
if (DebugMode) {
|
if (DebugMode) {
|
||||||
PrintTela("[BMB " + _ID + "] " + mensagem);
|
PrintTela("[BMB " + _ID + "] " + mensagem);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue