From 41a8d1b6c5f3fdb8ce342514eb5a28ab9408057f Mon Sep 17 00:00:00 2001 From: Rodrigo Bertoldo de Sousa Martins Date: Tue, 10 Feb 2026 20:08:57 -0300 Subject: [PATCH] fiberhome: add remove onu option Signed-off-by: Rodrigo Bertoldo de Sousa Martins --- src/bot/handler.js | 133 +++++++++++++++++++++++++++ src/fiberhome/manager_tl1.js | 173 +++++++++++++++++++++++++++++++++++ src/nlp/processor.js | 27 ++++++ 3 files changed, 333 insertions(+) diff --git a/src/bot/handler.js b/src/bot/handler.js index cea71ce..73ac122 100644 --- a/src/bot/handler.js +++ b/src/bot/handler.js @@ -186,6 +186,11 @@ class BotHandler { await this.handleAdicionarOnuFiberhome(chatId, target, userId); break; + case 'remover_onu_fiberhome': + console.log(`🗑️ Executando handleRemoverOnuFiberhome com target: ${target}`); + await this.handleRemoverOnuFiberhome(chatId, target, userId); + break; + case 'buscar_cliente': console.log(`🔍 Executando handleBuscarCliente com target: ${target}`); await this.handleBuscarCliente(chatId, target); @@ -1267,6 +1272,54 @@ Digite /help para ver todos os comandos disponíveis! } } + /** + * Handler para remover ONU Fiberhome via TL1 + */ + async handleRemoverOnuFiberhome(chatId, serialNumber, userId) { + try { + // Validar serial + if (!serialNumber || serialNumber.length !== 12) { + await this.bot.sendMessage(chatId, + '❌ Serial inválido. O serial deve conter 12 caracteres.\n\n' + + 'Exemplo: `FHTT199cf3c8`' + ); + return; + } + + // Escapar caracteres especiais + const serialEscaped = serialNumber.replace(/_/g, '\\_'); + + // Solicitar confirmação + const keyboard = { + inline_keyboard: [ + [ + { text: '✅ Sim, remover', callback_data: `confirm_remove_fh_${serialNumber}` }, + { text: '❌ Cancelar', callback_data: 'cancel_action' } + ] + ] + }; + + await this.bot.sendMessage(chatId, + `🗑️ *Remover ONU Fiberhome*\n\n` + + `📱 *Serial:* ${serialEscaped}\n\n` + + `⚠️ Esta ação irá remover a ONU e todas as suas configurações.\n\n` + + `Deseja confirmar a remoção?`, + { + reply_markup: keyboard, + parse_mode: 'Markdown' + } + ); + + } catch (error) { + console.error('❌ Erro ao preparar remoção de ONU Fiberhome:', error); + await this.bot.sendMessage(chatId, + `❌ *Erro ao preparar remoção*\n\n` + + `⚠️ ${error.message}`, + { parse_mode: 'Markdown' } + ); + } + } + /** * Comando não reconhecido */ @@ -1306,6 +1359,14 @@ Digite /help para ver todos os comandos disponíveis! if (data.startsWith('cmd_')) { console.log(`🔍 Condição cmd_ atendida`); await this.handleCommandCallback(callbackQuery, data); + } else if (data.startsWith('confirm_remove_fh_')) { + console.log(`🔍 Chamando handleConfirmRemoveFiberhomeCallback`); + try { + await this.handleConfirmRemoveFiberhomeCallback(callbackQuery, data); + } catch (confirmError) { + console.error(`❌ Erro em handleConfirmRemoveFiberhomeCallback:`, confirmError); + await this.bot.answerCallbackQuery(callbackQuery.id, 'Erro na confirmação'); + } } else if (data.startsWith('confirm_remove_')) { console.log(`🔍 Chamando handleConfirmRemoveCallback`); try { @@ -2428,6 +2489,78 @@ Digite /help para ver todos os comandos disponíveis! } } + /** + * Handle callback para confirmar remoção de ONU Fiberhome via TL1 + */ + async handleConfirmRemoveFiberhomeCallback(callbackQuery, data) { + const chatId = callbackQuery.message.chat.id; + console.log(`🔍 handleConfirmRemoveFiberhomeCallback chamado com data: ${data}`); + + // Formato: confirm_remove_fh_SERIAL + const serialNumber = data.replace('confirm_remove_fh_', '').toUpperCase(); + console.log(`🔍 Serial a remover: ${serialNumber}`); + + await this.bot.answerCallbackQuery(callbackQuery.id); + + // Escapar caracteres especiais + const serialEscaped = serialNumber.replace(/_/g, '\\_'); + + await this.bot.editMessageText( + `🗑️ *Removendo ONU Fiberhome...*\n\n` + + `📱 *Serial:* ${serialEscaped}\n\n` + + `⏳ Aguarde...`, + { + chat_id: chatId, + message_id: callbackQuery.message.message_id, + parse_mode: 'Markdown' + } + ); + + try { + // Executar comando TL1 de remoção + const resultado = await this.fiberhomeTL1.removerOnuFiberhome(serialNumber); + + if (resultado.success) { + await this.bot.editMessageText( + `✅ *ONU Fiberhome Removida com Sucesso!*\n\n` + + `📱 *Serial:* ${serialEscaped}\n` + + `🏢 *OLT:* ${resultado.details.olt.replace(/_/g, '\\_')}\n` + + `📡 *Porta:* ${resultado.details.porta}\n\n` + + `🔄 A ONU foi removida do sistema.`, + { + chat_id: chatId, + message_id: callbackQuery.message.message_id, + parse_mode: 'Markdown' + } + ); + } else { + await this.bot.editMessageText( + `❌ *Erro na Remoção*\n\n` + + `📱 *Serial:* ${serialEscaped}\n\n` + + `⚠️ *Erro:* ${resultado.error}\n\n` + + `🔄 Verifique o status da ONU ou tente novamente`, + { + chat_id: chatId, + message_id: callbackQuery.message.message_id, + parse_mode: 'Markdown' + } + ); + } + } catch (error) { + console.error('❌ Erro ao remover ONU Fiberhome:', error); + await this.bot.editMessageText( + `❌ *Erro Interno*\n\n` + + `📱 *Serial:* ${serialEscaped}\n\n` + + `⚠️ ${error.message}`, + { + chat_id: chatId, + message_id: callbackQuery.message.message_id, + parse_mode: 'Markdown' + } + ); + } + } + /** * Handle callback para iniciar processo de adição de ONU */ diff --git a/src/fiberhome/manager_tl1.js b/src/fiberhome/manager_tl1.js index cc3ab4a..f5d4928 100644 --- a/src/fiberhome/manager_tl1.js +++ b/src/fiberhome/manager_tl1.js @@ -646,6 +646,179 @@ class FiberhomeManager { } } + /** + * Buscar ONU registrada no sistema + */ + async buscarOnuRegistrada(serial) { + try { + this.logger.debug('Buscando ONU registrada no sistema', { serial }); + + // 1. Descobrir nome da OLT + const lstDeviceCmd = `LST-DEVICE:::${this.commandId++}::;`; + const deviceResult = await this.executarComandoTL1(lstDeviceCmd); + + if (!deviceResult.success) { + throw new Error('Falha ao listar dispositivos OLT'); + } + + console.log('📋 Resposta LST-DEVICE:', deviceResult.data); + + // Extrair nome da OLT da resposta + const deviceLines = deviceResult.data.split('\n'); + let nameOlt = null; + + for (const line of deviceLines) { + if (line.includes('AN5516') || line.includes('AN5116')) { + const parts = line.split(/\s+/).filter(p => p.trim()); + if (parts.length > 0) { + nameOlt = parts[0]; // Primeiro campo é o DEVNAME + break; + } + } + } + + if (!nameOlt) { + throw new Error('Nome da OLT não encontrado'); + } + + console.log(`✅ Nome da OLT descoberto: ${nameOlt}`); + + // 2. Listar todas as ONUs registradas + const lstOnuCmd = `LST-ONU::OLTID=${nameOlt}:${this.commandId++}::;`; + console.log(`📋 Listando ONUs registradas...`); + + const onuResult = await this.executarComandoTL1(lstOnuCmd); + + if (!onuResult.success) { + throw new Error('Falha ao listar ONUs registradas'); + } + + console.log('📋 ONUs registradas:', onuResult.data); + + // 3. Procurar a ONU pelo MAC/Serial + const onuLines = onuResult.data.split('\n'); + let onuInfo = null; + + for (const line of onuLines) { + // Procurar linha que contenha o serial (case-insensitive) + if (line.toUpperCase().includes(serial.toUpperCase())) { + console.log(`🔍 Linha encontrada: ${line}`); + + // Extrair informações da linha + // Formato esperado: campos separados por tabs ou espaços + const parts = line.split(/\s+/).filter(p => p.trim() && p !== '--'); + + console.log(`📋 Parts extraídos:`, parts); + + if (parts.length >= 4) { + // Tentar extrair PONID que pode estar em vários formatos: + // - 1-1-12-14 (frameId-slotId-portId-onuId) + // - NA-NA-12-14 + // - 12-14 + for (const part of parts) { + // Regex mais flexível: aceita N-N-N-N ou NA-NA-N-N + const ponidMatch = part.match(/^(?:\d+|\w+)-(?:\d+|\w+)-(\d+)-(\d+)$/); + if (ponidMatch) { + console.log(`✅ PONID identificado: ${part}`); + onuInfo = { + nameOlt: nameOlt, + portAlias: part, + slot: ponidMatch[1], + porta: ponidMatch[2] + }; + break; + } + } + } + + if (onuInfo) { + console.log(`✅ ONU info completa:`, onuInfo); + break; + } else { + console.log(`❌ Não conseguiu extrair PONID da linha`); + } + } + } + + if (!onuInfo) { + throw new Error('ONU não encontrada entre as ONUs registradas'); + } + + console.log(`✅ ONU encontrada:`, onuInfo); + return onuInfo; + + } catch (error) { + this.logger.error('Erro ao buscar ONU registrada', { serial, error: error.message }); + throw error; + } + } + + /** + * Remover ONU Fiberhome via TL1 + */ + async removerOnuFiberhome(serial) { + try { + this.logger.debug('Removendo ONU Fiberhome via TL1', { serial }); + + // Conectar ao UNM2000 + const conectado = await this.conectarUNM2000(); + if (!conectado) { + throw new Error('Não foi possível conectar ao UNM2000'); + } + + // Normalizar serial para maiúsculas + serial = serial.toUpperCase(); + + // Buscar a ONU registrada no sistema + this.logger.debug('Buscando ONU registrada', { serial }); + const onuInfo = await this.buscarOnuRegistrada(serial); + + if (!onuInfo) { + throw new Error('ONU não encontrada no sistema'); + } + + const { nameOlt, portAlias } = onuInfo; + this.logger.debug('ONU encontrada', { nameOlt, portAlias }); + + // Executar comando DEL-ONU + const delOnuCmd = `DEL-ONU::OLTID=${nameOlt},PONID=${portAlias}:${this.commandId++}::ONUIDTYPE=MAC,ONUID=${serial};`; + + this.logger.debug('Executando comando DEL-ONU', { comando: delOnuCmd }); + const delResult = await this.executarComandoTL1(delOnuCmd); + + if (!delResult.success) { + throw new Error(`Falha ao remover ONU: ${delResult.error}`); + } + + this.logger.info('ONU Fiberhome removida com sucesso', { + serial, + olt: nameOlt, + porta: portAlias + }); + + return { + success: true, + message: 'ONU removida com sucesso', + details: { + olt: nameOlt, + porta: portAlias, + serial: serial, + slot: onuInfo.slot, + ponPort: onuInfo.porta + } + }; + + } catch (error) { + this.logger.error('Erro ao remover ONU Fiberhome', { + serial, error: error.message + }); + return { + success: false, + error: error.message + }; + } + } + /** * Desconectar TL1 */ diff --git a/src/nlp/processor.js b/src/nlp/processor.js index 66b49b4..5a10585 100644 --- a/src/nlp/processor.js +++ b/src/nlp/processor.js @@ -16,6 +16,7 @@ class NLPProcessor { 'adicionar_onu': ['adicionar onu', 'add onu', 'criar onu', 'cadastrar onu', 'registrar onu'], 'adicionar_onu_vlan': ['adicionar onu vlan', 'add onu vlan', 'criar onu vlan', 'cadastrar onu vlan'], 'adicionar_onu_fiberhome': ['adicionar onu fiberhome', 'add onu fiberhome', 'criar onu fiberhome', 'cadastrar onu fiberhome', 'registrar onu fiberhome'], + 'remover_onu_fiberhome': ['remover onu fiberhome', 'deletar onu fiberhome', 'apagar onu fiberhome', 'remove onu fiberhome', 'delete onu fiberhome'], 'ping': ['ping', 'testar', 'test', 'conectividade'], 'admin': ['admin', 'administração', 'administracao', 'painel'], 'usuarios_autorizados': ['usuarios autorizados', 'users autorizados', 'lista usuarios', 'listar usuarios autorizados'], @@ -63,6 +64,9 @@ class NLPProcessor { // Padrões específicos para adicionar ONU Fiberhome via TL1 /^(adicionar|add|criar|cadastrar|registrar)\s+(onu|ont)\s+fiberhome\s+([A-Z0-9]+)$/i, /^(fiberhome)\s+(onu|ont)\s+([A-Z0-9]+)$/i, + // Padrões específicos para remover ONU Fiberhome via TL1 + /^(remover|deletar|apagar|remove|delete)\s+(onu|ont)\s+fiberhome\s+([A-Z0-9]+)$/i, + /^(fiberhome)\s+(remover|deletar|apagar|remove|delete)\s+(onu|ont)\s+([A-Z0-9]+)$/i, // Padrões específicos para adicionar ONU /^(adicionar|add|criar|cadastrar|registrar)\s+(onu|ont)\s+([A-Z0-9]+)$/i, /^(adicionar|add|criar|cadastrar|registrar)\s+([A-Z0-9]+)$/i, @@ -364,6 +368,29 @@ class NLPProcessor { // Padrões específicos para remover ONU if (/remover|deletar|apagar|remove|delete/i.test(action)) { + // Padrão especial: "remover onu fiberhome SERIAL" + if (/fiberhome/i.test(fullMatch)) { + let serialNumber; + + // Formato: "remover onu fiberhome SERIAL" + if (match.length === 4 && /onu|ont/i.test(fullMatch)) { + serialNumber = match[3]; // Serial + } + // Formato: "fiberhome remover onu SERIAL" + else if (match.length === 5 && match[1] === 'fiberhome') { + serialNumber = match[4]; // Serial + } + + if (serialNumber) { + return { + action: 'remover_onu_fiberhome', + target: serialNumber.trim().toUpperCase(), + confidence: 0.95, + type: 'remove_onu_fiberhome_pattern' + }; + } + } + // Padrão 1: "remover onu SERIAL" ou "remover ont SERIAL" if (/onu|ont/i.test(fullMatch)) { let serialNumber = match[3]; // Terceiro grupo capturado (serial após "onu/ont")