adicionado modulo can no health worker
This commit is contained in:
parent
7f7ea84bd2
commit
cdbcb8f1d7
|
|
@ -0,0 +1,118 @@
|
|||
import time
|
||||
from shared.contexto_global_redis import ContextoGlobalRedis
|
||||
from shared.enums import StatusModulo, T_Code
|
||||
from health_worker.modulos.base import ModuloDiagnosticoBase
|
||||
|
||||
class ModuloCAN(ModuloDiagnosticoBase):
|
||||
def __init__(self):
|
||||
self.t_code = T_Code.Can
|
||||
self.nome = "CAN"
|
||||
self.timeout = 5
|
||||
|
||||
def atualizar_saude(self):
|
||||
try:
|
||||
now = time.perf_counter()
|
||||
m = ContextoGlobalRedis.get_modulo(self.t_code) or {}
|
||||
|
||||
SAUDE_MIN_ALERTA = 80
|
||||
PESO_POR_ERRO = 10 # cada erro pode pesar até 10%
|
||||
PESO_MAX_ERROS = 40 # máximo 40% de penalização vinda só de erros críticos
|
||||
JANELA_RESET_EC = 600.0 # 10 minutos
|
||||
|
||||
conectado = bool(m.get("conectado", False))
|
||||
inicado = bool(m.get("iniciado", False))
|
||||
executando = bool(m.get("executando", False))
|
||||
erros_criticos = int(m.get("erros_criticos", 0))
|
||||
|
||||
# períodos-alvo (segundos) — se vier 0/None, usa fallback prudente
|
||||
tb_tx = float(m.get("tempo_base_tx", 1.0)) or 1.0
|
||||
tb_rx = float(m.get("tempo_base_rx", 1.0)) or 1.0
|
||||
|
||||
# timestamps monotônicos (segundos)
|
||||
last_tx = float(m.get("last_tx", 0.0))
|
||||
last_rx = float(m.get("last_rx", 0.0))
|
||||
last_ec = float(m.get("last_ec", 0.0))
|
||||
|
||||
age_tx = max(0.0, now - last_tx)
|
||||
age_rx = max(0.0, now - last_rx)
|
||||
age_ec = max(0.0, now - last_ec)
|
||||
|
||||
# tempo-limite pra considerar "morto": 3 períodos ou 3s (o que for maior)
|
||||
timeout_rx = max(30.0, 3.0 * tb_rx)
|
||||
timeout_tx = max(30.0, 3.0 * tb_tx) # informativo (RX é vital)
|
||||
|
||||
saude = 100
|
||||
motivos = []
|
||||
|
||||
if not conectado:
|
||||
saude = 0
|
||||
motivos.append("desconectado")
|
||||
else:
|
||||
if not inicado:
|
||||
saude -= 50
|
||||
motivos.append("não iniciado")
|
||||
|
||||
if executando:
|
||||
# Penalização por atraso relativo ao período-alvo
|
||||
# Ex.: se tb_rx=1s e age_rx=1.5s → atraso_rel=0.5 → penaliza 0.5*70=35%
|
||||
atraso_rel_rx = max(0.0, (age_rx / tb_rx) - 1.0)
|
||||
atraso_rel_tx = max(0.0, (age_tx / tb_tx) - 1.0)
|
||||
|
||||
p_rx = int(min(round(atraso_rel_rx * 60), 60)) # RX pesa mais (até 70%)
|
||||
p_tx = int(min(round(atraso_rel_tx * 40), 40)) # TX pesa menos (até 40%)
|
||||
|
||||
if p_rx > 0:
|
||||
saude -= p_rx
|
||||
motivos.append(f"RX atrasado {age_rx:.2f}s (-{p_rx}%)")
|
||||
if p_tx > 0:
|
||||
saude -= p_tx
|
||||
motivos.append(f"TX atrasado {age_tx:.2f}s (-{p_tx}%)")
|
||||
|
||||
if erros_criticos > 0 and age_ec <= JANELA_RESET_EC:
|
||||
# penalidade base cresce com o número de erros, limitada pelo teto
|
||||
penalidade_base = min(erros_criticos * PESO_POR_ERRO, PESO_MAX_ERROS)
|
||||
|
||||
# fator de recência: 1 se acabou de acontecer, 0 se está no limite da janela
|
||||
fator_recencia = max(0.0, 1.0 - (age_ec / JANELA_RESET_EC))
|
||||
|
||||
p_ec = int(round(penalidade_base * fator_recencia))
|
||||
|
||||
if p_ec > 0:
|
||||
saude -= p_ec
|
||||
motivos.append(f"{erros_criticos} erros críticos, último há {age_ec:.0f}s (-{p_ec}%)")
|
||||
|
||||
saude = max(saude, 0)
|
||||
|
||||
status = StatusModulo.OPERANTE
|
||||
if not conectado:
|
||||
status = StatusModulo.DESCONECTADO
|
||||
elif saude <= 0:
|
||||
status = StatusModulo.FALHA
|
||||
elif saude < SAUDE_MIN_ALERTA:
|
||||
status = StatusModulo.ALERTA
|
||||
|
||||
payload = {
|
||||
"conectado": conectado,
|
||||
"status": status.value,
|
||||
"saude": saude,
|
||||
"motivos": motivos,
|
||||
"saude_individual": [],
|
||||
"condicoes_operacionais": [],
|
||||
"detalhes": {
|
||||
"age_rx_s": age_rx,
|
||||
"age_tx_s": age_tx,
|
||||
"age_ec_s": age_ec,
|
||||
"timeout_rx_s": timeout_rx,
|
||||
"timeout_tx_s": timeout_tx,
|
||||
"periodo_alvo_rx_s": tb_rx,
|
||||
"periodo_alvo_tx_s": tb_tx,
|
||||
},
|
||||
}
|
||||
|
||||
ContextoGlobalRedis.atualizar_ctx_dict(
|
||||
ContextoGlobalRedis.ModKey(self.t_code),
|
||||
saude=payload
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Erro ao atualizar saude do modulo {self.t_code.name}: {e}")
|
||||
|
||||
Loading…
Reference in New Issue