ajustes no controle analogico e ponte ip
This commit is contained in:
parent
743c88dce4
commit
48fc2ad6b8
|
|
@ -28,7 +28,9 @@ namespace AgroBase
|
|||
new DeParaComandos() { key = Keys.Right, Dispositivo = T_Code.Dir, botaoJoy = BotoesJoystick.AEDireita, PararAoSoltar = true },
|
||||
new DeParaComandos() { key = Keys.R, Dispositivo = T_Code.Dir, botaoJoy = BotoesJoystick.R3, PararAoSoltar = false },
|
||||
new DeParaComandos() { key = Keys.Up, Dispositivo = T_Code.Mov, botaoJoy = BotoesJoystick.Xis, PararAoSoltar = true },
|
||||
new DeParaComandos() { key = Keys.Up, Dispositivo = T_Code.Mov, botaoJoy = BotoesJoystick.R2A, PararAoSoltar = true },
|
||||
new DeParaComandos() { key = Keys.Down, Dispositivo = T_Code.Mov, botaoJoy = BotoesJoystick.Quadrado, PararAoSoltar = true },
|
||||
new DeParaComandos() { key = Keys.Down, Dispositivo = T_Code.Mov, botaoJoy = BotoesJoystick.L2A, PararAoSoltar = true },
|
||||
new DeParaComandos() { key = Keys.Space, Dispositivo = T_Code.Mov, botaoJoy = BotoesJoystick.Bolinha, PararAoSoltar = true },
|
||||
new DeParaComandos() { key = Keys.Subtract, Dispositivo = T_Code.Mov, botaoJoy = BotoesJoystick.L1, PararAoSoltar = false },
|
||||
new DeParaComandos() { key = Keys.Add, Dispositivo = T_Code.Mov, botaoJoy = BotoesJoystick.R1, PararAoSoltar = false },
|
||||
|
|
@ -602,7 +604,7 @@ namespace AgroBase
|
|||
|
||||
percent = FuncoesMatematicas.Clamp(percent, 0, 100);
|
||||
|
||||
Console.WriteLine($"botao: {botao}, valor: {valor}, percentual: {percent * 100.0:F2}%");
|
||||
//Console.WriteLine($"botao: {botao}, valor: {valor}, percentual: {percent * 100.0:F2}%");
|
||||
|
||||
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
|
||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||
|
|
@ -687,13 +689,13 @@ namespace AgroBase
|
|||
Pressionado = true;
|
||||
}
|
||||
// Controle Direcao dos Motores BLDC (MOV)
|
||||
else if (Comando.Comando == Keys.Up && UltimaDirecao != Direcao.Frente)
|
||||
else if (Comando.Comando == Keys.Up) // && UltimaDirecao != Direcao.Frente
|
||||
{
|
||||
Comando.Dispositivo = T_Code.Mov;
|
||||
DirecaoAtual = Direcao.Frente;
|
||||
Pressionado = true;
|
||||
}
|
||||
else if (Comando.Comando == Keys.Down && UltimaDirecao != Direcao.Tras)
|
||||
else if (Comando.Comando == Keys.Down) // && UltimaDirecao != Direcao.Tras
|
||||
{
|
||||
Comando.Dispositivo = T_Code.Mov;
|
||||
DirecaoAtual = Direcao.Tras;
|
||||
|
|
@ -706,13 +708,13 @@ namespace AgroBase
|
|||
Pressionado = true;
|
||||
}
|
||||
// Controle de Rotação dos Motores de Passo (DIR)
|
||||
else if (Comando.Comando == Keys.Left && UltimaDirecao != Direcao.Esquerda)
|
||||
else if (Comando.Comando == Keys.Left) // && UltimaDirecao != Direcao.Esquerda
|
||||
{
|
||||
Comando.Dispositivo = T_Code.Dir;
|
||||
DirecaoAtual = Direcao.Esquerda;
|
||||
Pressionado = true;
|
||||
}
|
||||
else if (Comando.Comando == Keys.Right && UltimaDirecao != Direcao.Direita)
|
||||
else if (Comando.Comando == Keys.Right) // && UltimaDirecao != Direcao.Direita
|
||||
{
|
||||
Comando.Dispositivo = T_Code.Dir;
|
||||
DirecaoAtual = Direcao.Direita;
|
||||
|
|
@ -765,7 +767,8 @@ namespace AgroBase
|
|||
{
|
||||
case T_Code.Mov:
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.ForEach(x => x.MovMotor.EnviarComandoControle(DirecaoAtual));
|
||||
//Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.ForEach(x => x.MovMotor.EnviarComandoControle(DirecaoAtual));
|
||||
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(false, new List<T_Code>() { Comando.Dispositivo });
|
||||
break;
|
||||
}
|
||||
case T_Code.Dir:
|
||||
|
|
@ -783,19 +786,20 @@ namespace AgroBase
|
|||
}
|
||||
else
|
||||
{
|
||||
foreach (var mod in Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos)
|
||||
{
|
||||
if (modsControlar == null || modsControlar.Contains(mod.DirMotor.Mod_ID))
|
||||
{
|
||||
mod.DirMotor.EnviarComandoControle(DirecaoAtual);
|
||||
|
||||
if (mod.MovMotor.CompensacaoNecessaria)
|
||||
{
|
||||
Direcao ultimaDirecaoMov = Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Mov)?.UltimaDirecao ?? Direcao.Parado;
|
||||
mod.MovMotor.EnviarComandoControle(ultimaDirecaoMov);
|
||||
}
|
||||
}
|
||||
};
|
||||
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(false, new List<T_Code>() { Comando.Dispositivo });
|
||||
//foreach (var mod in Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos)
|
||||
//{
|
||||
// if (modsControlar == null || modsControlar.Contains(mod.DirMotor.Mod_ID))
|
||||
// {
|
||||
// mod.DirMotor.EnviarComandoControle(DirecaoAtual);
|
||||
//
|
||||
// if (mod.MovMotor.CompensacaoNecessaria)
|
||||
// {
|
||||
// Direcao ultimaDirecaoMov = Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Mov)?.UltimaDirecao ?? Direcao.Parado;
|
||||
// mod.MovMotor.EnviarComandoControle(ultimaDirecaoMov);
|
||||
// }
|
||||
// }
|
||||
//};
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -510,6 +510,12 @@ namespace AgroBase.Models
|
|||
};
|
||||
p.ModulosMandatorios = new List<OperacaoModulosMandatoriosModel>()
|
||||
{
|
||||
new OperacaoModulosMandatoriosModel()
|
||||
{
|
||||
Dispositivo = T_Code.Ipb,
|
||||
Mandatorio = true,
|
||||
Utilizar = true,
|
||||
},
|
||||
new OperacaoModulosMandatoriosModel()
|
||||
{
|
||||
Dispositivo = T_Code.Mov,
|
||||
|
|
@ -772,6 +778,12 @@ namespace AgroBase.Models
|
|||
};
|
||||
p.ModulosMandatorios = new List<OperacaoModulosMandatoriosModel>()
|
||||
{
|
||||
new OperacaoModulosMandatoriosModel()
|
||||
{
|
||||
Dispositivo = T_Code.Ipb,
|
||||
Mandatorio = true,
|
||||
Utilizar = true,
|
||||
},
|
||||
new OperacaoModulosMandatoriosModel()
|
||||
{
|
||||
Dispositivo = T_Code.Mov,
|
||||
|
|
@ -832,7 +844,6 @@ namespace AgroBase.Models
|
|||
|
||||
p.ModulosMandatorios.Add(new OperacaoModulosMandatoriosModel() { Dispositivo = T_Code.Npc, Mandatorio = true, Utilizar = true });
|
||||
p.ModulosMandatorios.Add(new OperacaoModulosMandatoriosModel() { Dispositivo = T_Code.Can, Mandatorio = true, Utilizar = true });
|
||||
p.ModulosMandatorios.Add(new OperacaoModulosMandatoriosModel() { Dispositivo = T_Code.Ipb, Mandatorio = true, Utilizar = true });
|
||||
p.ModulosMandatorios.Add(new OperacaoModulosMandatoriosModel() { Dispositivo = T_Code.Bat, Mandatorio = true, Utilizar = true });
|
||||
p.ModulosMandatorios.ForEach(m => m.ComponentesEmUso = Variaveis.OperacaoEmAndamento.PreencherComponentesEmUso(m.Dispositivo));
|
||||
|
||||
|
|
@ -1298,7 +1309,7 @@ namespace AgroBase.Models
|
|||
|
||||
foreach (var Ctrl in _Controle.TiposControle.Where(x => Dispositivos.Contains(x.Tipo)))
|
||||
{
|
||||
if (!ForcarEnvio)
|
||||
if (!ForcarEnvio && false)
|
||||
{
|
||||
if (mm.Any(x => x.Dispositivo == Ctrl.Tipo && !x.Utilizar))
|
||||
continue;
|
||||
|
|
@ -1360,6 +1371,7 @@ namespace AgroBase.Models
|
|||
bool envioNecessario = ForcarEnvio || _Controle.RPM_SP != _ControleAnterior.RPM_SP;
|
||||
if (envioNecessario || modsAtualizar.Any())
|
||||
{
|
||||
Console.WriteLine($"Vai enviar comando MOV");
|
||||
foreach (var Mod in Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.Where(x => envioNecessario ? true : modsAtualizar.Contains(x.Modulo_ID)))
|
||||
{
|
||||
Mod.MovMotor.EnviarComandoControle(_Controle.Direcao);
|
||||
|
|
@ -1402,6 +1414,7 @@ namespace AgroBase.Models
|
|||
var modsAtualizar = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.Where(Mod => !Mod.DirMotor.AtingiuAnguloSP).Select(x => x.Modulo_ID).ToList();
|
||||
if (!MKS057DCanService.Referenciando && (envioNecessario || modsAtualizar.Any()))
|
||||
{
|
||||
Console.WriteLine($"Vai enviar comando DIR");
|
||||
foreach (var Mod in Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.Where(x => envioNecessario ? true : modsAtualizar.Contains(x.Modulo_ID)))
|
||||
{
|
||||
Mod.DirMotor.EnviarComandoControle(_Controle.Direcao);
|
||||
|
|
|
|||
|
|
@ -87,6 +87,15 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
self.bw_safe_mbps = 05.0 # alvo saudável (até aqui não penaliza)
|
||||
self.bw_hard_mbps = 2.5 # acima disso é zona vermelha
|
||||
|
||||
self.link_state = "OK" # OK | DEGRADED | CRITICAL
|
||||
self._cycles_degraded = 0
|
||||
self._cycles_critical = 0
|
||||
self._cycles_recovered = 0
|
||||
self._distancia_inicio_degradado = None
|
||||
self._distancia_inicio_critico = None
|
||||
self._max_distancia_ok = 0.0
|
||||
self._max_distancia_desde_degradado = 0.0
|
||||
|
||||
|
||||
|
||||
def _start_ping_async_if_needed(self):
|
||||
|
|
@ -558,11 +567,11 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
# LATÊNCIA
|
||||
if rtts:
|
||||
avg_rtt = statistics.mean(rtts)
|
||||
if avg_rtt <= 30: latency_score = 100
|
||||
elif avg_rtt <= 50: latency_score = 80
|
||||
elif avg_rtt <= 100: latency_score = 50
|
||||
elif avg_rtt <= 200: latency_score = 20
|
||||
else: latency_score = 0
|
||||
if avg_rtt <= 40: latency_score = 100
|
||||
elif avg_rtt <= 70: latency_score = 85
|
||||
elif avg_rtt <= 120: latency_score = 65
|
||||
elif avg_rtt <= 200: latency_score = 35
|
||||
else: latency_score = 10
|
||||
else:
|
||||
latency_score = 0
|
||||
|
||||
|
|
@ -572,10 +581,10 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
else:
|
||||
timeout_pct = 100.0
|
||||
|
||||
if timeout_pct <= 5: timeout_score = 100
|
||||
elif timeout_pct <= 10: timeout_score = 80
|
||||
elif timeout_pct <= 15: timeout_score = 50
|
||||
elif timeout_pct <= 30: timeout_score = 20
|
||||
if timeout_pct <= 2: timeout_score = 100
|
||||
elif timeout_pct <= 5: timeout_score = 85
|
||||
elif timeout_pct <= 10: timeout_score = 60
|
||||
elif timeout_pct <= 20: timeout_score = 30
|
||||
else: timeout_score = 0
|
||||
|
||||
# LOSS
|
||||
|
|
@ -584,22 +593,24 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
else:
|
||||
loss_pct = 100.0
|
||||
|
||||
if loss_pct <= 2: loss_score = 100
|
||||
elif loss_pct <= 5: loss_score = 80
|
||||
elif loss_pct <= 8: loss_score = 50
|
||||
elif loss_pct <= 15: loss_score = 20
|
||||
if loss_pct <= 1: loss_score = 100
|
||||
elif loss_pct <= 3: loss_score = 90
|
||||
elif loss_pct <= 5: loss_score = 75
|
||||
elif loss_pct <= 8: loss_score = 55
|
||||
elif loss_pct <= 12: loss_score = 30
|
||||
else: loss_score = 0
|
||||
|
||||
# JITTER
|
||||
if len(rtts) > 2:
|
||||
jitter = statistics.pstdev(rtts)
|
||||
if jitter <= 10: jitter_score = 100
|
||||
elif jitter <= 20: jitter_score = 70
|
||||
elif jitter <= 40: jitter_score = 30
|
||||
else: jitter_score = 0
|
||||
if jitter <= 12: jitter_score = 100
|
||||
elif jitter <= 25: jitter_score = 85
|
||||
elif jitter <= 40: jitter_score = 65
|
||||
elif jitter <= 70: jitter_score = 40
|
||||
else: jitter_score = 15
|
||||
else:
|
||||
jitter = 0.0
|
||||
jitter_score = 1
|
||||
jitter_score = 85
|
||||
|
||||
# NIC ERRORS
|
||||
if nic_error_rates:
|
||||
|
|
@ -607,17 +618,18 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
else:
|
||||
err_rate = 0.0
|
||||
|
||||
if err_rate <= 0.1: nic_score = 100
|
||||
elif err_rate <= 1: nic_score = 70
|
||||
elif err_rate <= 5: nic_score = 40
|
||||
else: nic_score = 0
|
||||
if err_rate <= 0.05: nic_score = 100
|
||||
elif err_rate <= 0.2: nic_score = 90
|
||||
elif err_rate <= 1.0: nic_score = 70
|
||||
elif err_rate <= 3.0: nic_score = 45
|
||||
else: nic_score = 20
|
||||
|
||||
# HEARTBEAT (igual)
|
||||
t0, t1 = 1.0, 3.0
|
||||
x = (atraso - t0) / (t1 - t0)
|
||||
x = max(0.0, min(1.0, x))
|
||||
gamma = 1.6
|
||||
hb_score = int(round(100 * (1.0 - (x ** gamma))))
|
||||
if atraso <= 1.5: hb_score = 100
|
||||
elif atraso <= 3.0: hb_score = 80
|
||||
elif atraso <= 5.0: hb_score = 50
|
||||
elif atraso <= 8.0: hb_score = 20
|
||||
else: hb_score = 0
|
||||
|
||||
return (
|
||||
latency_score, timeout_score, loss_score, jitter_score, nic_score, hb_score,
|
||||
|
|
@ -797,38 +809,50 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
bw_score_s, bw_util_pct_s, bw_state_s = self._bandwidth_score(bw_total_s)
|
||||
|
||||
health_f = (
|
||||
0.20 * ls_f +
|
||||
0.10 * tmout_f +
|
||||
0.15 * ls_f +
|
||||
0.18 * tmout_f +
|
||||
0.25 * los_f +
|
||||
0.10 * js_f +
|
||||
0.10 * ns_f +
|
||||
0.10 * hbs_f +
|
||||
0.15 * bw_score_f
|
||||
0.08 * js_f +
|
||||
0.05 * ns_f +
|
||||
0.22 * hbs_f +
|
||||
0.07 * bw_score_f
|
||||
)
|
||||
|
||||
health_s = (
|
||||
0.20 * ls_s +
|
||||
0.10 * tmout_s +
|
||||
0.15 * ls_s +
|
||||
0.18 * tmout_s +
|
||||
0.25 * los_s +
|
||||
0.10 * js_s +
|
||||
0.10 * ns_s +
|
||||
0.10 * hbs_s +
|
||||
0.15 * bw_score_s
|
||||
0.08 * js_s +
|
||||
0.05 * ns_s +
|
||||
0.22 * hbs_s +
|
||||
0.07 * bw_score_s
|
||||
)
|
||||
|
||||
health = 0.70 * health_s + 0.30 * health_f
|
||||
|
||||
health = 0.80 * health_s + 0.20 * health_f
|
||||
|
||||
# Se o FAST gritar "caos", derruba a saúde na hora (não espera a slow)
|
||||
if loss_pct_f >= 8 or tmout_pct_f >= 10:
|
||||
if loss_pct_f >= 12:
|
||||
health = min(health, 55)
|
||||
elif loss_pct_f >= 8 and loss_pct_s >= 5:
|
||||
health = min(health, 65)
|
||||
|
||||
# Timeout
|
||||
if tmout_pct_f >= 20:
|
||||
health = min(health, 45)
|
||||
elif tmout_pct_f >= 10 and tmout_pct_s >= 5:
|
||||
health = min(health, 60)
|
||||
|
||||
# Se saturou banda no FAST, corta também (comandos atrasam)
|
||||
if bw_util_pct_f >= 95:
|
||||
health = min(health, 55)
|
||||
if bw_util_pct_f >= 98 and (loss_pct_f >= 5 or tmout_pct_f >= 5):
|
||||
health = min(health, 65)
|
||||
|
||||
# Se heartbeat atrasou muito, isso é sério
|
||||
if atraso_f >= 3.0:
|
||||
health = min(health, 40)
|
||||
if atraso_f >= 8.0:
|
||||
health = min(health, 30)
|
||||
elif atraso_f >= 5.0:
|
||||
health = min(health, 45)
|
||||
elif atraso_f >= 3.0 and atraso_s >= 2.0:
|
||||
health = min(health, 60)
|
||||
|
||||
saude = round(health, 1)
|
||||
|
||||
|
|
@ -872,7 +896,7 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
# 1) Latência
|
||||
cond_lat = []
|
||||
if ls_f < SAUDE_MIN_ALERTA:
|
||||
severidade = int(max(0, 100 - ls_f))
|
||||
severidade = min(89, int(max(0, 100 - ls_f)))
|
||||
c = {
|
||||
"label": "Latência ICMP",
|
||||
"valor": avg_rtt_f if avg_rtt_f is not None else -1,
|
||||
|
|
@ -905,7 +929,7 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
# 2) Timeouts
|
||||
cond_timeout = []
|
||||
if tmout_f < SAUDE_MIN_ALERTA:
|
||||
severidade = int(max(0, 100 - tmout_f))
|
||||
severidade = severidade = min(89, int(max(0, 100 - tmout_f)))
|
||||
c = {
|
||||
"label": "Timeout",
|
||||
"valor": round(tmout_pct_f, 2),
|
||||
|
|
@ -934,7 +958,7 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
# 2) Perda de pacotes
|
||||
cond_loss = []
|
||||
if los_f < SAUDE_MIN_ALERTA:
|
||||
severidade = int(max(0, 100 - los_f))
|
||||
severidade = severidade = min(89, int(max(0, 100 - los_f)))
|
||||
c = {
|
||||
"label": "Perda de Pacotes",
|
||||
"valor": round(loss_pct_f, 2),
|
||||
|
|
@ -963,7 +987,7 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
# 3) Jitter
|
||||
cond_jit = []
|
||||
if js_f < SAUDE_MIN_ALERTA:
|
||||
severidade = int(max(0, 100 - js_f))
|
||||
severidade = severidade = min(89, int(max(0, 100 - js_f)))
|
||||
c = {
|
||||
"label": "Jitter (variação de latência)",
|
||||
"valor": round(jitter_f, 2),
|
||||
|
|
@ -992,7 +1016,7 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
# 4) Erros na NIC
|
||||
cond_nic = []
|
||||
if ns_f < SAUDE_MIN_ALERTA:
|
||||
severidade = int(max(0, 100 - ns_f))
|
||||
severidade = severidade = min(89, int(max(0, 100 - ns_f)))
|
||||
c = {
|
||||
"label": "Erros na interface de rede",
|
||||
"valor": round(err_rate_f, 3),
|
||||
|
|
@ -1021,7 +1045,7 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
# 5) Heartbeat
|
||||
cond_hb = []
|
||||
if hbs_f < SAUDE_MIN_ALERTA:
|
||||
severidade = int(max(0, 100 - hbs_f))
|
||||
severidade = severidade = min(89, int(max(0, 100 - hbs_f)))
|
||||
c = {
|
||||
"label": "Atraso de heartbeat",
|
||||
"valor": round(atraso_f, 2),
|
||||
|
|
@ -1050,7 +1074,7 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
# 6) Banda / Saturação
|
||||
cond_bw = []
|
||||
if bw_score_f < SAUDE_MIN_ALERTA:
|
||||
severidade = int(max(0, 100 - bw_score_f))
|
||||
severidade = severidade = min(89, int(max(0, 100 - bw_score_f)))
|
||||
c = {
|
||||
"label": "Uso de banda",
|
||||
"valor": round(bw_util_pct_f, 1),
|
||||
|
|
@ -1079,14 +1103,188 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
"em_uso": True,
|
||||
})
|
||||
|
||||
|
||||
|
||||
# RISCO REAL
|
||||
risk_score = (
|
||||
0.32 * (100 - los) +
|
||||
0.24 * (100 - tmout) +
|
||||
0.22 * (100 - hbs) +
|
||||
0.10 * (100 - ls) +
|
||||
0.07 * (100 - js) +
|
||||
0.03 * (100 - bw_score) +
|
||||
0.02 * (100 - ns)
|
||||
)
|
||||
risk_score = max(0.0, min(100.0, risk_score))
|
||||
|
||||
degradado_agora = (
|
||||
loss_pct_s >= 5 or
|
||||
tmout_pct_s >= 4 or
|
||||
atraso_s >= 4.0 or
|
||||
(loss_pct_f >= 8 and loss_pct_s >= 3) or
|
||||
(tmout_pct_f >= 10 and tmout_pct_s >= 3) or
|
||||
(jitter_s >= 35 and loss_pct_s >= 3)
|
||||
)
|
||||
|
||||
critico_agora = (
|
||||
loss_pct_s >= 10 or
|
||||
tmout_pct_s >= 8 or
|
||||
atraso_s >= 6.0 or
|
||||
(loss_pct_f >= 15 and loss_pct_s >= 5) or
|
||||
(tmout_pct_f >= 20 and tmout_pct_s >= 5) or
|
||||
((loss_pct_s >= 6) and (atraso_s >= 5.0))
|
||||
)
|
||||
|
||||
colapso_agora = (
|
||||
loss_pct_s >= 15 or
|
||||
tmout_pct_s >= 12 or
|
||||
atraso_s >= 8.0 or
|
||||
not conectado
|
||||
)
|
||||
|
||||
if colapso_agora:
|
||||
self._cycles_critical += 2
|
||||
self._cycles_degraded += 1
|
||||
self._cycles_recovered = 0
|
||||
elif critico_agora:
|
||||
self._cycles_critical += 1
|
||||
self._cycles_degraded += 1
|
||||
self._cycles_recovered = 0
|
||||
elif degradado_agora:
|
||||
self._cycles_degraded += 1
|
||||
self._cycles_critical = max(0, self._cycles_critical - 1)
|
||||
self._cycles_recovered = 0
|
||||
else:
|
||||
self._cycles_recovered += 1
|
||||
self._cycles_degraded = max(0, self._cycles_degraded - 1)
|
||||
self._cycles_critical = max(0, self._cycles_critical - 1)
|
||||
|
||||
self._cycles_degraded = min(self._cycles_degraded, 30)
|
||||
self._cycles_critical = min(self._cycles_critical, 30)
|
||||
self._cycles_recovered = min(self._cycles_recovered, 30)
|
||||
|
||||
prev_state = self.link_state
|
||||
if self._cycles_critical >= 8:
|
||||
self.link_state = "CRITICAL"
|
||||
elif self._cycles_degraded >= 12:
|
||||
self.link_state = "DEGRADED"
|
||||
elif self._cycles_recovered >= 20:
|
||||
self.link_state = "OK"
|
||||
|
||||
# entrou em DEGRADED agora
|
||||
if prev_state != "DEGRADED" and self.link_state == "DEGRADED":
|
||||
self._distancia_inicio_degradado = distancia_base if distancia_base >= 0 else 0.0
|
||||
self._max_distancia_desde_degradado = self._distancia_inicio_degradado
|
||||
|
||||
# enquanto estiver degradado, atualiza a maior distância observada
|
||||
if self.link_state == "DEGRADED" and distancia_base is not None and distancia_base >= 0:
|
||||
self._max_distancia_desde_degradado = max(
|
||||
self._max_distancia_desde_degradado,
|
||||
distancia_base
|
||||
)
|
||||
|
||||
# entrou em CRITICAL agora
|
||||
if prev_state != "CRITICAL" and self.link_state == "CRITICAL":
|
||||
self._distancia_inicio_critico = distancia_base if distancia_base >= 0 else 0.0
|
||||
|
||||
# voltou para OK, limpa marcos
|
||||
if prev_state != "OK" and self.link_state == "OK":
|
||||
self._distancia_inicio_degradado = None
|
||||
self._distancia_inicio_critico = None
|
||||
self._max_distancia_desde_degradado = 0.0
|
||||
|
||||
if self.link_state == "OK" and distancia_base >= 0:
|
||||
self._max_distancia_ok = max(self._max_distancia_ok, distancia_base)
|
||||
|
||||
# Condição 1: Link degradado persistente
|
||||
if self.link_state == "DEGRADED":
|
||||
condicoes.append({
|
||||
"label": "Enlace degradado persistente",
|
||||
"valor": round(risk_score, 1),
|
||||
"severidade": 75,
|
||||
"descricao": (
|
||||
f"Rede degradando de forma persistente. "
|
||||
f"Loss slow {loss_pct_s:.1f}%, timeout slow {tmout_pct_s:.1f}%, "
|
||||
f"heartbeat {atraso_s:.1f}s. Não aumentar distância da base."
|
||||
),
|
||||
"acoes": [
|
||||
"Bloquear avanço para longe da base",
|
||||
"Reduzir vídeo/logs/telemetria não crítica",
|
||||
"Permitir apenas manter posição ou retornar"
|
||||
]
|
||||
})
|
||||
# Condição 2: Cerca invisível de rede violada
|
||||
dist_violando_cerca = (
|
||||
self.link_state == "DEGRADED" and
|
||||
self._distancia_inicio_degradado is not None and
|
||||
distancia_base is not None and
|
||||
distancia_base >= 0 and
|
||||
self._max_distancia_desde_degradado > self._distancia_inicio_degradado + 2.0 and
|
||||
distancia_base > self._distancia_inicio_degradado + 1.0
|
||||
)
|
||||
if dist_violando_cerca:
|
||||
condicoes.append({
|
||||
"label": "Avanço além da margem segura de rede",
|
||||
"valor": round(distancia_base, 2),
|
||||
"severidade": 92,
|
||||
"descricao": (
|
||||
f"O rover continuou se afastando após a rede entrar em degradação persistente. "
|
||||
f"Distância atual {distancia_base:.1f} m."
|
||||
),
|
||||
"acoes": [
|
||||
"Parar avanço imediatamente",
|
||||
"Retornar em direção à base",
|
||||
"Manter apenas tráfego essencial"
|
||||
]
|
||||
})
|
||||
#Condição 3: Link crítico persistente
|
||||
if self.link_state == "CRITICAL":
|
||||
condicoes.append({
|
||||
"label": "Risco crítico de perda de comunicação",
|
||||
"valor": round(risk_score, 1),
|
||||
"severidade": 96,
|
||||
"descricao": (
|
||||
f"Enlace crítico e persistente. "
|
||||
f"Loss slow {loss_pct_s:.1f}%, timeout slow {tmout_pct_s:.1f}%, "
|
||||
f"heartbeat {atraso_s:.1f}s."
|
||||
),
|
||||
"acoes": [
|
||||
"Parar operação",
|
||||
"Iniciar retorno seguro",
|
||||
"Priorizar mensagens de controle e heartbeat"
|
||||
]
|
||||
})
|
||||
#Condição 4: Colapso iminente
|
||||
if colapso_agora and self._cycles_critical >= 1:
|
||||
condicoes.append({
|
||||
"label": "Colapso iminente do enlace",
|
||||
"valor": round(risk_score, 1),
|
||||
"severidade": 99,
|
||||
"descricao": (
|
||||
f"Perda iminente de comunicação. "
|
||||
f"Loss slow {loss_pct_s:.1f}%, timeout slow {tmout_pct_s:.1f}%, "
|
||||
f"heartbeat {atraso_s:.1f}s."
|
||||
),
|
||||
"acoes": [
|
||||
"Parada imediata",
|
||||
"Abortar avanço",
|
||||
"Executar fail-safe de retorno"
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# -------- STATUS GERAL DO MÓDULO --------
|
||||
status = StatusModulo.OPERANTE
|
||||
if not conectado:
|
||||
status = StatusModulo.DESCONECTADO
|
||||
elif saude <= 0:
|
||||
elif self.link_state == "CRITICAL":
|
||||
status = StatusModulo.FALHA
|
||||
elif saude < SAUDE_MIN_ALERTA:
|
||||
elif self.link_state == "DEGRADED" or saude < SAUDE_MIN_ALERTA:
|
||||
status = StatusModulo.ALERTA
|
||||
else:
|
||||
status = StatusModulo.OPERANTE
|
||||
|
||||
payload = {
|
||||
"conectado": conectado,
|
||||
|
|
@ -1119,6 +1317,18 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
"bw_safe_mbps": self.bw_safe_mbps,
|
||||
"bw_hard_mbps": self.bw_hard_mbps,
|
||||
"bw_pressure_pct": bw_pressure_pct,
|
||||
|
||||
"link_state": self.link_state,
|
||||
"risk_score": round(risk_score, 1),
|
||||
"cycles_degraded": self._cycles_degraded,
|
||||
"cycles_critical": self._cycles_critical,
|
||||
"cycles_recovered": self._cycles_recovered,
|
||||
"pode_avancar": self.link_state == "OK",
|
||||
"deve_conter_avanco": self.link_state == "DEGRADED",
|
||||
"deve_parar_por_rede": self.link_state == "CRITICAL",
|
||||
"distancia_inicio_degradado": self._distancia_inicio_degradado,
|
||||
"distancia_inicio_critico": self._distancia_inicio_critico,
|
||||
"max_distancia_ok": self._max_distancia_ok,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -127,7 +127,10 @@ namespace OperationControl.Controls
|
|||
|
||||
public event EventHandler<StreetMapClickedEventArgs>? StreetMapClicked;
|
||||
private bool ParametrizandoOperacao =>
|
||||
(VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Modo ?? ModoOperacao.NaoDefinido) == ModoOperacao.MapaGPS &&
|
||||
(
|
||||
(VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Modo ?? ModoOperacao.NaoDefinido) == ModoOperacao.MapaGPS ||
|
||||
(VariaveisControleOperacao.RoverEmFoco?.Modo ?? ModoOperacao.NaoDefinido) == ModoOperacao.MapaGPS
|
||||
) &&
|
||||
!(VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Iniciada ?? false) &&
|
||||
(VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Status ?? StatusOperacao.NaoIniciado) == StatusOperacao.Parametrizando &&
|
||||
((App)System.Windows.Application.Current).Shell.Dock?._vm?._viewOperacaoRight?._vm?.SecaoAtual == ViewModels.Views.Operacao.SecaoRightBar.Parametrizacao;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ namespace OperationControl.ViewModels.Views.Operacao.Monitoramento
|
|||
}
|
||||
}
|
||||
|
||||
private AgroBase.Models.Enums.ModoOperacao? modoOperacaoAtual { get; set; }
|
||||
|
||||
public ParametrizacaoViewModel()
|
||||
{
|
||||
CarregarParametrosPadraoCommand = new RelayCommand(p => CarregarParametrosPadrao((AgroBase.Models.Enums.ModoOperacao)p));
|
||||
|
|
@ -56,8 +58,10 @@ namespace OperationControl.ViewModels.Views.Operacao.Monitoramento
|
|||
private void CarregarParametrosPadrao(AgroBase.Models.Enums.ModoOperacao modo)
|
||||
{
|
||||
var p = OperacaoModel.CarregarParametrosOperacaoPadrao(modo, false);
|
||||
modoOperacaoAtual = p.Modo;
|
||||
p.Descricao = $"{p.Modo} - Padrão";
|
||||
Parametros = p;
|
||||
VariaveisControleOperacao.RoverEmFoco.Modo = modo;
|
||||
}
|
||||
|
||||
private void ReiniciarOperacao()
|
||||
|
|
@ -69,6 +73,7 @@ namespace OperationControl.ViewModels.Views.Operacao.Monitoramento
|
|||
{
|
||||
if (origem == null) return;
|
||||
Parametros = origem;
|
||||
modoOperacaoAtual = origem.Modo;
|
||||
OperacaoConcluida = (VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Status ?? AgroBase.Models.Enums.StatusOperacao.NaoIniciado) == AgroBase.Models.Enums.StatusOperacao.Concluido;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue