ajustes no controle analogico e ponte ip

This commit is contained in:
Diego Freitas 2026-03-18 15:11:10 -03:00
parent 743c88dce4
commit 48fc2ad6b8
5 changed files with 313 additions and 78 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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,
}
}

View File

@ -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;

View File

@ -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;
}