diagnosticar: fix porta ethernet; sinal; OLT Datacom
Signed-off-by: Rodrigo Bertoldo de Sousa Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
1 parent
0dbab52aa1
commit
f786091146
2 files changed
+132
-44
No files matched your search
+77
-33
@@ -1045,6 +1045,8 @@ Digite /help para ver todos os comandos disponíveis!
|
|||||||
const nomePlano = servico.descricao || servico.nome || 'N/A';
|
const nomePlano = servico.descricao || servico.nome || 'N/A';
|
||||||
const endereco = servico.instalacao_endereco || servico.end_rua || null;
|
const endereco = servico.instalacao_endereco || servico.end_rua || null;
|
||||||
const cidade = servico.instalacao_cidade || null;
|
const cidade = servico.instalacao_cidade || null;
|
||||||
|
// Campo base/AP usado para rotear para a OLT correta
|
||||||
|
const baseInfo = servico.base || (servico.id_ap ? `AP ${servico.id_ap}` : null);
|
||||||
|
|
||||||
// Executar consultas em paralelo: Juniper + ONU
|
// Executar consultas em paralelo: Juniper + ONU
|
||||||
const [juniperResult, onuResult] = await Promise.all([
|
const [juniperResult, onuResult] = await Promise.all([
|
||||||
@@ -1052,7 +1054,7 @@ Digite /help para ver todos os comandos disponíveis!
|
|||||||
? this.ssh.getJuniperSubscriberInfo('juniper', pppoeLogin).catch(e => ({ success: false, error: e.message }))
|
? this.ssh.getJuniperSubscriberInfo('juniper', pppoeLogin).catch(e => ({ success: false, error: e.message }))
|
||||||
: Promise.resolve({ success: false, skipped: true }),
|
: Promise.resolve({ success: false, skipped: true }),
|
||||||
serial
|
serial
|
||||||
? this._diagnosticarONU(serial).catch(e => ({ success: false, error: e.message }))
|
? this._diagnosticarONU(serial, baseInfo).catch(e => ({ success: false, error: e.message }))
|
||||||
: Promise.resolve({ success: false, skipped: true })
|
: Promise.resolve({ success: false, skipped: true })
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -1106,7 +1108,7 @@ Digite /help para ver todos os comandos disponíveis!
|
|||||||
msg += '\n';
|
msg += '\n';
|
||||||
|
|
||||||
if (onuResult.portaEthernet) {
|
if (onuResult.portaEthernet) {
|
||||||
const ethOk = /forward|up|1gbit|100mbit/i.test(onuResult.portaEthernet);
|
const ethOk = /forward|up|active|1gbit|100mbit/i.test(onuResult.portaEthernet);
|
||||||
msg += ` ${ethOk ? '🟢' : '🔴'} Porta Ethernet: ${onuResult.portaEthernet}\n`;
|
msg += ` ${ethOk ? '🟢' : '🔴'} Porta Ethernet: ${onuResult.portaEthernet}\n`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1120,37 +1122,66 @@ Digite /help para ver todos os comandos disponíveis!
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diagnóstico de ONU: detecta tipo (Datacom/FiberHome) e retorna dados estruturados
|
* Mapeia o campo base/AP do TopSapp para o ID da OLT Datacom (ou 'fiberhome')
|
||||||
*/
|
*/
|
||||||
async _diagnosticarONU(serial) {
|
_resolverOLTporBase(baseInfo) {
|
||||||
const serialUpper = serial.toUpperCase();
|
if (!baseInfo) return null;
|
||||||
|
const b = String(baseInfo).toUpperCase();
|
||||||
if (serialUpper.startsWith('DACM')) {
|
if (/INTERNET\s+FIBRA\s+OPTICA/i.test(b)) return 'fiberhome';
|
||||||
return await this._diagnosticarONUDatacom(serial);
|
if (/COLMEIA/i.test(b)) return 'olt_colmeia';
|
||||||
} else {
|
if (/DITO/i.test(b)) return 'olt_dito';
|
||||||
return await this._diagnosticarONUFiberhome(serial);
|
if (/CANAA\s*2/i.test(b)) return 'olt_canaa2';
|
||||||
}
|
if (/CANAA/i.test(b)) return 'olt_canaa';
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _diagnosticarONUDatacom(serial) {
|
/**
|
||||||
const olts = this.ssh.listOLTs();
|
* Diagnóstico de ONU: detecta tipo (Datacom/FiberHome) e retorna dados estruturados
|
||||||
if (olts.length === 0) {
|
* @param {string} serial - Serial da ONU
|
||||||
return { success: false, error: 'Nenhuma OLT Datacom configurada' };
|
* @param {string|null} baseInfo - Campo base/AP do TopSapp para rotear para OLT correta
|
||||||
|
*/
|
||||||
|
async _diagnosticarONU(serial, baseInfo) {
|
||||||
|
const serialUpper = serial.toUpperCase();
|
||||||
|
const oltHint = this._resolverOLTporBase(baseInfo);
|
||||||
|
|
||||||
|
// Usar base description para decidir se é FiberHome
|
||||||
|
if (oltHint === 'fiberhome' ||
|
||||||
|
(!serialUpper.startsWith('DACM') && (serialUpper.startsWith('FHTT') || serialUpper.startsWith('FHGT')))) {
|
||||||
|
return await this._diagnosticarONUFiberhome(serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buscar ONU em todas as OLTs em paralelo
|
return await this._diagnosticarONUDatacom(serial, oltHint);
|
||||||
const searches = olts.map(olt =>
|
}
|
||||||
this.ssh.findOnuBySerial(olt.id, serial)
|
|
||||||
.then(r => ({ ...r, oltId: olt.id, oltName: olt.name }))
|
|
||||||
.catch(() => ({ success: false }))
|
|
||||||
);
|
|
||||||
const results = await Promise.allSettled(searches);
|
|
||||||
|
|
||||||
|
async _diagnosticarONUDatacom(serial, oltIdHint) {
|
||||||
let found = null;
|
let found = null;
|
||||||
for (const r of results) {
|
|
||||||
if (r.status === 'fulfilled' && r.value.success) {
|
// 1. Tentar na OLT indicada pelo campo base/AP do cadastro
|
||||||
found = r.value;
|
if (oltIdHint && this.ssh.equipamentos.has(oltIdHint)) {
|
||||||
break;
|
const r = await this.ssh.findOnuBySerial(oltIdHint, serial).catch(() => null);
|
||||||
|
if (r && r.success) {
|
||||||
|
const olt = this.ssh.equipamentos.get(oltIdHint);
|
||||||
|
found = { ...r, oltId: oltIdHint, oltName: olt.name };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Fallback: buscar em todas as OLTs Datacom
|
||||||
|
if (!found) {
|
||||||
|
const olts = this.ssh.listOLTs();
|
||||||
|
if (olts.length === 0) {
|
||||||
|
return { success: false, error: 'Nenhuma OLT Datacom configurada' };
|
||||||
|
}
|
||||||
|
const searches = olts.map(olt =>
|
||||||
|
this.ssh.findOnuBySerial(olt.id, serial)
|
||||||
|
.then(r => ({ ...r, oltId: olt.id, oltName: olt.name }))
|
||||||
|
.catch(() => ({ success: false }))
|
||||||
|
);
|
||||||
|
const results = await Promise.allSettled(searches);
|
||||||
|
for (const r of results) {
|
||||||
|
if (r.status === 'fulfilled' && r.value.success) {
|
||||||
|
found = r.value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1207,21 +1238,34 @@ Digite /help para ver todos os comandos disponíveis!
|
|||||||
return { success: false, error: resultado.error || 'ONU não encontrada na FiberHome' };
|
return { success: false, error: resultado.error || 'ONU não encontrada na FiberHome' };
|
||||||
}
|
}
|
||||||
|
|
||||||
const portaPrincipal = resultado.portasEthernet && resultado.portasEthernet.length > 0
|
// Preferir porta com dados reais de velocidade; cair para primeira disponível
|
||||||
? resultado.portasEthernet[0]
|
const portas = resultado.portasEthernet || [];
|
||||||
: null;
|
const portaComDados = portas.find(p => p.status !== 'unknown' && p.speed);
|
||||||
|
const portaAtiva = portas.find(p => p.status === 'active');
|
||||||
|
const portaBase = portaComDados || portaAtiva || (portas.length > 0 ? portas[0] : null);
|
||||||
|
|
||||||
|
let portaEthernetStr = null;
|
||||||
|
if (portaBase && portaBase.status !== 'unknown') {
|
||||||
|
const statusLabel = portaBase.status === 'active' ? 'up' : 'down';
|
||||||
|
portaEthernetStr = portaBase.speed
|
||||||
|
? `${statusLabel} — ${portaBase.speed}`
|
||||||
|
: statusLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rxPower: retornar null se for 'N/A' para que a UI mostre 'N/A' via fallback
|
||||||
|
const rxPower = resultado.rxPower && resultado.rxPower !== 'N/A' ? resultado.rxPower : null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
type: 'fiberhome',
|
type: 'fiberhome',
|
||||||
oltName: 'FiberHome',
|
oltName: 'FiberHome AN5516',
|
||||||
slot: resultado.slot,
|
slot: resultado.slot,
|
||||||
pon: resultado.pon,
|
pon: resultado.pon,
|
||||||
onuId: resultado.onuId,
|
onuId: resultado.onuId,
|
||||||
online: resultado.online,
|
online: resultado.online,
|
||||||
rxPower: resultado.rxPower,
|
rxPower,
|
||||||
txPower: resultado.txPower,
|
txPower: resultado.txPower !== 'N/A' ? resultado.txPower : null,
|
||||||
portaEthernet: portaPrincipal ? `${portaPrincipal.status}` : null
|
portaEthernet: portaEthernetStr
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+55
-11
@@ -723,18 +723,62 @@ class FiberhomeManager {
|
|||||||
|
|
||||||
// Processar LST-ONULANINFO (portas ethernet)
|
// Processar LST-ONULANINFO (portas ethernet)
|
||||||
if (resposta.comando && resposta.comando.includes('LST-ONULANINFO')) {
|
if (resposta.comando && resposta.comando.includes('LST-ONULANINFO')) {
|
||||||
// Extrair informações das portas
|
const linhasLan = dados.split(/[\r\n]+/);
|
||||||
const portMatches = dados.matchAll(/PORT\s*=\s*(\d+).*?STATUS\s*=\s*(\w+)/gi);
|
// Detectar linha de cabeçalho (formato tabular TL1)
|
||||||
for (const match of portMatches) {
|
const headerLan = linhasLan.find(l =>
|
||||||
const portNum = parseInt(match[1]);
|
/ONUPORT/i.test(l) || (/SPEED/i.test(l) && /ONUNO/i.test(l))
|
||||||
const status = match[2].toLowerCase();
|
);
|
||||||
|
|
||||||
if (portNum >= 1 && portNum <= 4) {
|
if (headerLan) {
|
||||||
if (!resultado.portasEthernet[portNum-1]) {
|
// Formato TL1 tab-separado
|
||||||
resultado.portasEthernet[portNum-1] = { porta: portNum, status: 'unknown' };
|
const headerFields = headerLan.trim().split(/\t/).map(f => f.trim().toUpperCase());
|
||||||
|
const idxPort = headerFields.findIndex(h => h === 'ONUPORT');
|
||||||
|
const idxState = headerFields.findIndex(h => h === 'ADMINSTATE' || h === 'CURSTATE' || h === 'STATUS');
|
||||||
|
const idxSpeed = headerFields.findIndex(h => h === 'CURRNEGOTYPE' || h === 'SPEED');
|
||||||
|
const idxDuplex = headerFields.findIndex(h => h === 'DUPLEXMODE' || h === 'DUPLEX');
|
||||||
|
|
||||||
|
for (const linha of linhasLan) {
|
||||||
|
if (linha === headerLan || !linha.trim() ||
|
||||||
|
/---+|COMPLD|total_blocks/i.test(linha)) continue;
|
||||||
|
const campos = linha.trim().split(/\t/).map(f => f.trim());
|
||||||
|
if (campos.length < 4) continue;
|
||||||
|
|
||||||
|
// ONUPORT formato: NA-NA-slot-pon-portnum
|
||||||
|
const portField = idxPort >= 0 ? campos[idxPort] : '';
|
||||||
|
const portMatch = portField.match(/[^-](\d+)$/);
|
||||||
|
if (!portMatch) continue;
|
||||||
|
const portNum = parseInt(portMatch[1]);
|
||||||
|
if (portNum < 1 || portNum > 8) continue;
|
||||||
|
|
||||||
|
const stateVal = idxState >= 0 ? campos[idxState] : '';
|
||||||
|
const speedVal = idxSpeed >= 0 ? campos[idxSpeed] : '';
|
||||||
|
const duplexVal = idxDuplex >= 0 ? campos[idxDuplex] : '';
|
||||||
|
|
||||||
|
const isUp = /up|enable|active/i.test(stateVal);
|
||||||
|
const speedClean = speedVal && !/^(?:auto|--)$/i.test(speedVal) ? speedVal : null;
|
||||||
|
const duplexClean = duplexVal && !/^(?:auto|--)$/i.test(duplexVal) ? duplexVal : null;
|
||||||
|
const speedLabel = speedClean
|
||||||
|
? (duplexClean ? `${speedClean} ${duplexClean}` : speedClean)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
resultado.portasEthernet[portNum - 1] = {
|
||||||
|
porta: portNum,
|
||||||
|
status: isUp ? 'active' : 'inactive',
|
||||||
|
speed: speedLabel
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Fallback: formato key=value legado
|
||||||
|
const portMatches = dados.matchAll(/PORT\s*[=:]\s*(\d+).*?STATUS\s*[=:]\s*(\w+)/gis);
|
||||||
|
for (const match of portMatches) {
|
||||||
|
const portNum = parseInt(match[1]);
|
||||||
|
const status = match[2].toLowerCase();
|
||||||
|
if (portNum >= 1 && portNum <= 4) {
|
||||||
|
resultado.portasEthernet[portNum - 1] = {
|
||||||
|
porta: portNum,
|
||||||
|
status: status === 'up' ? 'active' : status === 'down' ? 'inactive' : 'unknown'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
resultado.portasEthernet[portNum-1].status = status === 'up' ? 'active' :
|
|
||||||
status === 'down' ? 'inactive' : 'unknown';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user