diagnosticar: fix TX/RX Fiberhome p2
Signed-off-by: Rodrigo Bertoldo de Sousa Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
1 parent
c50167bd45
commit
97357badeb
1 file changed
+58
-44
+58
-44
@@ -640,7 +640,13 @@ class FiberhomeManager {
|
|||||||
this.logger.debug('Processando respostas dos comandos TL1 detalhados');
|
this.logger.debug('Processando respostas dos comandos TL1 detalhados');
|
||||||
|
|
||||||
for (const resposta of dadosONU.detalhados) {
|
for (const resposta of dadosONU.detalhados) {
|
||||||
if (!resposta || !resposta.response) continue;
|
// Pular respostas com DENY ou sem dados
|
||||||
|
if (!resposta || !resposta.response || resposta.success === false) {
|
||||||
|
if (resposta && !resposta.success) {
|
||||||
|
this.logger.warn(`⚠️ Comando retornou DENY: ${resposta.comando}`);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const dados = resposta.response;
|
const dados = resposta.response;
|
||||||
|
|
||||||
@@ -668,65 +674,57 @@ class FiberhomeManager {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (headerIndex !== -1) {
|
if (headerIndex !== -1) {
|
||||||
// Encontrar linha de dados (após o header, ignora traços e metadados)
|
// Encontrar linha de dados (após header — tem pelo menos um número decimal)
|
||||||
const linhaDados = linhas.slice(headerIndex + 1).find(l =>
|
const linhaDados = linhas.slice(headerIndex + 1).find(l =>
|
||||||
l.trim() &&
|
l.trim() &&
|
||||||
!/^[-\s]+$/.test(l) &&
|
!/^[-\s]+$/.test(l) &&
|
||||||
!/COMPLD|total_blocks|block_number|FH_/i.test(l) &&
|
!/COMPLD|total_blocks|block_number|FH_/i.test(l) &&
|
||||||
/[+-]?\d+[,.]\d+/.test(l) // linha de dados tem número decimal
|
/[+-]?\d+[,.]\d+/.test(l)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (linhaDados) {
|
if (linhaDados) {
|
||||||
// Parsear header e dados para mapear colunas por nome
|
// Usar split por qualquer whitespace (suporta tanto tab quanto espaço simples/múltiplo)
|
||||||
const headers = linhas[headerIndex].trim().split(/\t|\s{2,}/).map(h => h.trim());
|
const headers = linhas[headerIndex].trim().split(/\s+/);
|
||||||
const valores = linhaDados.trim().split(/\t|\s{2,}/).map(v => v.trim());
|
const valores = linhaDados.trim().split(/\s+/);
|
||||||
this.logger.debug(`📊 LST-OMDDM headers: [${headers.join('][')}]`);
|
this.logger.debug(`📊 LST-OMDDM headers (${headers.length}): [${headers.join('][')}]`);
|
||||||
this.logger.debug(`📊 LST-OMDDM valores: [${valores.join('][')}]`);
|
this.logger.debug(`📊 LST-OMDDM valores (${valores.length}): [${valores.join('][')}]`);
|
||||||
|
|
||||||
const colIdx = (name) => headers.findIndex(h => h.toLowerCase() === name.toLowerCase());
|
const colIdx = (name) => headers.findIndex(h => h.toLowerCase() === name.toLowerCase());
|
||||||
const rxIdx = colIdx('RxPower');
|
const rxIdx = colIdx('RxPower');
|
||||||
const txIdx = colIdx('TxPower');
|
const txIdx = colIdx('TxPower');
|
||||||
|
|
||||||
// Fallback: se header parse falhou, usar posição fixa (ONUID=0, RxPower=1, TxPower=3)
|
// Nota: no TL1 FiberHome, RxPower = sinal que a OLT recebe (= TX da ONU)
|
||||||
// Nota: no TL1 da FiberHome, RxPower = sinal recebido pela OLT (= TX da ONU),
|
// TxPower = sinal que a OLT envia (= RX da ONU)
|
||||||
// TxPower = sinal transmitido pela OLT (= RX da ONU). Por isso invertemos.
|
// Posições fixas de fallback: ONUID=0, RxPower=1, TxPower=3
|
||||||
const oltRxRaw = (rxIdx >= 0 ? valores[rxIdx] : valores[1])?.replace(',', '.');
|
const oltRxRaw = (rxIdx >= 0 ? valores[rxIdx] : valores[1])?.replace(',', '.');
|
||||||
const oltTxRaw = (txIdx >= 0 ? valores[txIdx] : valores[3])?.replace(',', '.');
|
const oltTxRaw = (txIdx >= 0 ? valores[txIdx] : valores[3])?.replace(',', '.');
|
||||||
|
|
||||||
const COMP_RX = 2.7;
|
const COMP_RX = 2.7;
|
||||||
const COMP_TX = -2.7;
|
const COMP_TX = -2.7;
|
||||||
|
|
||||||
// OLT RxPower → potência de TX da ONU (o que a ONU envia)
|
|
||||||
if (oltRxRaw && oltRxRaw !== '--' && !isNaN(parseFloat(oltRxRaw))) {
|
if (oltRxRaw && oltRxRaw !== '--' && !isNaN(parseFloat(oltRxRaw))) {
|
||||||
resultado.txPower = `${(parseFloat(oltRxRaw) + COMP_RX).toFixed(2)} dBm`;
|
resultado.txPower = `${(parseFloat(oltRxRaw) + COMP_RX).toFixed(2)} dBm`;
|
||||||
this.logger.info(`✅ TxPower ONU (OLT RxPower bruto=${oltRxRaw}) → ${resultado.txPower}`);
|
this.logger.info(`✅ TxPower ONU ← OLT RxPower ${oltRxRaw} → ${resultado.txPower}`);
|
||||||
}
|
}
|
||||||
// OLT TxPower → potência de RX da ONU (o que a ONU recebe)
|
|
||||||
if (oltTxRaw && oltTxRaw !== '--' && !isNaN(parseFloat(oltTxRaw))) {
|
if (oltTxRaw && oltTxRaw !== '--' && !isNaN(parseFloat(oltTxRaw))) {
|
||||||
resultado.rxPower = `${(parseFloat(oltTxRaw) + COMP_TX).toFixed(2)} dBm`;
|
resultado.rxPower = `${(parseFloat(oltTxRaw) + COMP_TX).toFixed(2)} dBm`;
|
||||||
this.logger.info(`✅ RxPower ONU (OLT TxPower bruto=${oltTxRaw}) → ${resultado.rxPower}`);
|
this.logger.info(`✅ RxPower ONU ← OLT TxPower ${oltTxRaw} → ${resultado.rxPower}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.logger.warn('⚠️ LST-OMDDM: header encontrado mas sem linha de dados numéricos');
|
this.logger.warn('⚠️ LST-OMDDM: header encontrado mas sem linha de dados numéricos');
|
||||||
|
this.logger.debug('LST-OMDDM linhas:', linhas.slice(headerIndex, headerIndex + 5).join(' | '));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Header não encontrado — tentar regex direto no buffer
|
// Header não encontrado — regex direto no buffer como último recurso
|
||||||
// OLT RxPower = TX da ONU; OLT TxPower = RX da ONU
|
this.logger.warn('⚠️ LST-OMDDM: header ONUID não encontrado, tentando regex');
|
||||||
const oltRxMatch = dados.match(/RxPower[\s\t]+([+-]?\d+[,.]\d+)/i);
|
this.logger.debug('LST-OMDDM resposta completa:', dados);
|
||||||
const oltTxMatch = dados.match(/TxPower[\s\t]+([+-]?\d+[,.]\d+)/i);
|
// Procurar primeiro número negativo após "COMPLD" = RxPower
|
||||||
if (oltRxMatch) {
|
const rxDireto = dados.match(/(-\d+\.\d+)/);
|
||||||
const v = parseFloat(oltRxMatch[1].replace(',', '.')) + 2.7;
|
if (rxDireto) {
|
||||||
|
// Sem contexto de coluna: assume que é OLT RxPower (=TX da ONU)
|
||||||
|
const v = parseFloat(rxDireto[1]) + 2.7;
|
||||||
resultado.txPower = `${v.toFixed(2)} dBm`;
|
resultado.txPower = `${v.toFixed(2)} dBm`;
|
||||||
this.logger.info(`✅ TxPower ONU via regex fallback → ${resultado.txPower}`);
|
this.logger.info(`✅ TxPower ONU via regex último recurso → ${resultado.txPower}`);
|
||||||
}
|
|
||||||
if (oltTxMatch) {
|
|
||||||
const v = parseFloat(oltTxMatch[1].replace(',', '.')) - 2.7;
|
|
||||||
resultado.rxPower = `${v.toFixed(2)} dBm`;
|
|
||||||
this.logger.info(`✅ RxPower ONU via regex fallback → ${resultado.rxPower}`);
|
|
||||||
}
|
|
||||||
if (!oltRxMatch && !oltTxMatch) {
|
|
||||||
this.logger.warn('⚠️ LST-OMDDM: não foi possível extrair RxPower/TxPower da resposta');
|
|
||||||
this.logger.debug('LST-OMDDM resposta completa:', dados);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -743,29 +741,35 @@ class FiberhomeManager {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (headerLanIdx !== -1) {
|
if (headerLanIdx !== -1) {
|
||||||
const headers = linhasLan[headerLanIdx].trim().split(/\t|\s{2,}/).map(h => h.trim());
|
// Usar split por qualquer whitespace (suporta espaço simples e múltiplo)
|
||||||
|
const headers = linhasLan[headerLanIdx].trim().split(/\s+/);
|
||||||
|
// Linha de dados: próxima linha não-vazia que contenha UP ou DOWN
|
||||||
const linhaDados = linhasLan.slice(headerLanIdx + 1).find(l =>
|
const linhaDados = linhasLan.slice(headerLanIdx + 1).find(l =>
|
||||||
l.trim() && !/^[-\s]+$/.test(l) &&
|
l.trim() &&
|
||||||
!/COMPLD|total_blocks|block_number/i.test(l)
|
!/^[-\s;]+$/.test(l) &&
|
||||||
|
!/COMPLD|total_blocks|block_number/i.test(l) &&
|
||||||
|
/\b(UP|DOWN|DISABLE|ENABLE)\b/i.test(l)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (linhaDados) {
|
if (linhaDados) {
|
||||||
const valores = linhaDados.trim().split(/\t|\s{2,}/).map(v => v.trim());
|
const valores = linhaDados.trim().split(/\s+/);
|
||||||
const hLower = headers.map(h => h.toLowerCase());
|
const hLower = headers.map(h => h.toLowerCase());
|
||||||
const idxAdm = hLower.findIndex(h => h === 'adminstatus');
|
this.logger.debug(`📊 LAN headers (${headers.length}): [${headers.join('][')}]`);
|
||||||
|
this.logger.debug(`📊 LAN valores (${valores.length}): [${valores.join('][')}]`);
|
||||||
|
|
||||||
const idxOper = hLower.findIndex(h => h === 'operstatus');
|
const idxOper = hLower.findIndex(h => h === 'operstatus');
|
||||||
const idxSpeed = hLower.findIndex(h => h === 'speed');
|
const idxSpeed = hLower.findIndex(h => h === 'speed');
|
||||||
const idxDuplex= hLower.findIndex(h => h === 'duplex');
|
const idxDuplex= hLower.findIndex(h => h === 'duplex');
|
||||||
|
|
||||||
|
// Fallback posições: AdminStatus=0, OperStatus=1, Duplex=2, PVID=3, VLANPRI=4, Speed=5
|
||||||
const operVal = idxOper >= 0 ? valores[idxOper] : valores[1];
|
const operVal = idxOper >= 0 ? valores[idxOper] : valores[1];
|
||||||
const speedVal = idxSpeed >= 0 ? valores[idxSpeed] : valores[5];
|
const speedVal = idxSpeed >= 0 ? valores[idxSpeed] : valores[5];
|
||||||
const duplexVal= idxDuplex>= 0 ? valores[idxDuplex]: valores[2];
|
const duplexVal= idxDuplex>= 0 ? valores[idxDuplex]: valores[2];
|
||||||
|
|
||||||
const isUp = /^up$/i.test(operVal);
|
const isUp = /^up$/i.test(operVal);
|
||||||
const speedClean = speedVal && !/^(--|auto)$/i.test(speedVal) ? speedVal : null;
|
const speedClean = speedVal && !/^(--|auto)$/i.test(speedVal) ? speedVal : null;
|
||||||
const duplexClean = duplexVal && !/^(--|auto|full|half)$/i.test(duplexVal)
|
const duplexClean = /full/i.test(duplexVal) ? 'Full-Duplex'
|
||||||
? null : (/full/i.test(duplexVal) ? 'Full-Duplex' : duplexVal && /half/i.test(duplexVal) ? 'Half-Duplex' : null);
|
: /half/i.test(duplexVal) ? 'Half-Duplex' : null;
|
||||||
|
|
||||||
const speedLabel = speedClean
|
const speedLabel = speedClean
|
||||||
? (duplexClean ? `${speedClean} ${duplexClean}` : speedClean)
|
? (duplexClean ? `${speedClean} ${duplexClean}` : speedClean)
|
||||||
: null;
|
: null;
|
||||||
@@ -776,13 +780,23 @@ class FiberhomeManager {
|
|||||||
speed: speedLabel
|
speed: speedLabel
|
||||||
};
|
};
|
||||||
this.logger.info(`✅ Porta LAN 1: ${isUp ? 'UP' : 'DOWN'} ${speedLabel || ''}`);
|
this.logger.info(`✅ Porta LAN 1: ${isUp ? 'UP' : 'DOWN'} ${speedLabel || ''}`);
|
||||||
|
} else {
|
||||||
|
this.logger.warn('⚠️ LST-ONULANINFO: header encontrado mas sem linha de dados (UP/DOWN)');
|
||||||
|
this.logger.debug('LAN linhas após header:', linhasLan.slice(headerLanIdx, headerLanIdx + 5));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Fallback: tentar extrair OperStatus via regex
|
// Fallback: detectar UP/DOWN em qualquer lugar da resposta
|
||||||
const upMatch = dados.match(/OperStatus[\s\t]+UP/i) ||
|
this.logger.warn('⚠️ LST-ONULANINFO: header AdminStatus/OperStatus não encontrado, usando fallback');
|
||||||
dados.match(/(?:^|\t)UP(?:\t|$)/m);
|
this.logger.debug('LAN resposta completa:', dados);
|
||||||
if (upMatch !== null) {
|
const upMatch = /\bUP\b/.test(dados);
|
||||||
resultado.portasEthernet[0] = { porta: 1, status: 'active', speed: null };
|
const downMatch = /\bDOWN\b/i.test(dados);
|
||||||
|
if (upMatch || downMatch) {
|
||||||
|
const speedMatch = dados.match(/\b(\d+[MG])\b/i);
|
||||||
|
resultado.portasEthernet[0] = {
|
||||||
|
porta: 1,
|
||||||
|
status: upMatch ? 'active' : 'inactive',
|
||||||
|
speed: speedMatch ? speedMatch[1] : null
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user