From 600555596de416b2e1c5d6503949192a39cd3f27 Mon Sep 17 00:00:00 2001 From: Rodrigo Bertoldo de Sousa Martins Date: Tue, 10 Feb 2026 14:58:13 -0300 Subject: [PATCH] datacom: add ONU with custom VLAN Signed-off-by: Rodrigo Bertoldo de Sousa Martins --- src/bot/handler.js | 179 +++++++++++++++++++++++++++++++++++++++++++ src/nlp/processor.js | 30 ++++++++ 2 files changed, 209 insertions(+) diff --git a/src/bot/handler.js b/src/bot/handler.js index 7f9d35b..e9619ee 100644 --- a/src/bot/handler.js +++ b/src/bot/handler.js @@ -173,6 +173,11 @@ class BotHandler { await this.handleAdicionarOnu(chatId, target); break; + case 'adicionar_onu_vlan': + console.log(`➕ Executando handleAdicionarOnuVlan com target: ${target}, vlanId: ${intent.vlanId}`); + await this.handleAdicionarOnuVlan(chatId, target, intent.vlanId); + break; + case 'buscar_cliente': console.log(`🔍 Executando handleBuscarCliente com target: ${target}`); await this.handleBuscarCliente(chatId, target); @@ -401,6 +406,11 @@ Digite /help para ver todos os comandos disponíveis! • "cadastrar ABCD12345678" • "add onu SERIAL_NUMBER" +**➕ ADICIONAR ONU COM VLAN CUSTOMIZADA:** +• "adicionar onu vlan 603 DACM91569513" +• "add onu vlan 700 ABCD12345678" +• "adicionar vlan 603 SERIAL_NUMBER" + **🗑️ REMOVER ONU:** • "remover onu DACM91569513" • "deletar ABCD12345678" @@ -992,6 +1002,51 @@ Digite /help para ver todos os comandos disponíveis! ); } + /** + * Comando para adicionar ONU com VLAN customizada + */ + async handleAdicionarOnuVlan(chatId, serialNumber, vlanId) { + if (!serialNumber) { + await this.bot.sendMessage(chatId, '❌ Por favor, informe o serial da ONU.\n\nExemplo: `adicionar onu vlan 603 FHTT12345678`', { parse_mode: 'Markdown' }); + return; + } + + if (!vlanId || isNaN(vlanId) || vlanId < 1 || vlanId > 4094) { + await this.bot.sendMessage(chatId, '❌ VLAN ID inválida. Deve ser um número entre 1 e 4094.\n\nExemplo: `adicionar onu vlan 603 FHTT12345678`', { parse_mode: 'Markdown' }); + return; + } + + // Perguntar em qual OLT adicionar + const oltOptions = this.ssh.listOLTs(); + + if (oltOptions.length === 0) { + await this.bot.sendMessage(chatId, '❌ Nenhuma OLT disponível configurada.'); + return; + } + + let keyboard = { + inline_keyboard: oltOptions.map(olt => [ + { text: `🏢 ${olt.name}`, callback_data: `add_onu_vlan_${olt.id}_${vlanId}_${serialNumber}` } + ]) + }; + + // Adicionar opção de cancelar + keyboard.inline_keyboard.push([ + { text: '❌ Cancelar', callback_data: 'cancel_action' } + ]); + + await this.bot.sendMessage(chatId, + `➕ **Adicionar ONU com VLAN Customizada**\n\n` + + `📱 **Serial:** ${serialNumber}\n` + + `🏷️ **VLAN:** ${vlanId}\n\n` + + '🏢 Selecione a OLT onde deseja adicionar a ONU:', + { + reply_markup: keyboard, + parse_mode: 'Markdown' + } + ); + } + /** * Comando não reconhecido */ @@ -1097,6 +1152,9 @@ Digite /help para ver todos os comandos disponíveis! } else if (data.startsWith('remove_onu_')) { console.log(`🔍 Chamando handleRemoveOnuCallback`); await this.handleRemoveOnuCallback(callbackQuery, data); + } else if (data.startsWith('add_onu_vlan_')) { + console.log(`🔍 Chamando handleAddOnuVlanCallback`); + await this.handleAddOnuVlanCallback(callbackQuery, data); } else if (data.startsWith('add_onu_')) { console.log(`🔍 Chamando handleAddOnuCallback`); await this.handleAddOnuCallback(callbackQuery, data); @@ -2265,6 +2323,127 @@ Digite /help para ver todos os comandos disponíveis! } } + /** + * Handle callback para iniciar processo de adição de ONU com VLAN customizada + */ + async handleAddOnuVlanCallback(callbackQuery, data) { + const chatId = callbackQuery.message.chat.id; + // Formato: add_onu_vlan_olt_dito_603_SERIAL ou add_onu_vlan_olt_pedro_afonso_603_SERIAL + // Índices: [0]_[1]_[2]_[3]_[4]_[5]_[6] + const parts = data.split('_'); + + let oltId, vlanId, serialNumber; + + if (parts.length >= 9 && parts[4] === 'pedro' && parts[5] === 'afonso') { + // Caso: add_onu_vlan_olt_pedro_afonso_VLANID_SERIAL + oltId = parts[3] + '_' + parts[4] + '_' + parts[5]; // "olt_pedro_afonso" + vlanId = parts[6]; + serialNumber = parts.slice(7).join('_'); // Serial pode ter underscores + } else if (parts.length >= 7) { + // Caso: add_onu_vlan_olt_dito_VLANID_SERIAL ou add_onu_vlan_olt_colmeia_VLANID_SERIAL + oltId = parts[3] + '_' + parts[4]; // "olt_dito" ou "olt_colmeia" + vlanId = parts[5]; + serialNumber = parts.slice(6).join('_'); // Serial pode ter underscores + } else { + // Fallback + oltId = parts[3]; + vlanId = parts[4]; + serialNumber = parts.slice(5).join('_'); + } + + await this.bot.answerCallbackQuery(callbackQuery.id); + + await this.bot.editMessageText( + `🔍 **Analisando ONU ${serialNumber}**\n\n` + + `🏢 OLT: ${oltId.replace('olt_', '').replace(/_/g, '\\_').toUpperCase()}\n` + + `📱 Serial: ${serialNumber}\n` + + `🏷️ VLAN customizada: ${vlanId}\n\n` + + `⏳ Descobrindo slot e próximo ONU ID disponível...`, + { + chat_id: chatId, + message_id: callbackQuery.message.message_id, + parse_mode: 'Markdown' + } + ); + + try { + // Usar a mesma função addOnuBySerial mas sem a vlanId (vamos usar a customizada) + const result = await this.ssh.addOnuBySerial(oltId, serialNumber); + + if (result.success && result.readyForAddition) { + // ONU analisada - mostrar informações e pedir confirmação + const keyboard = { + inline_keyboard: [ + [ + { text: '✅ CONFIRMAR ADIÇÃO', callback_data: `confirm_add_${oltId}_${result.slot.replace(/\//g, '-')}_${result.onuId}_${vlanId}_${serialNumber}` } + ], + [ + { text: '❌ Cancelar', callback_data: 'cancel_action' } + ] + ] + }; + + await this.bot.editMessageText( + `✅ **CONFIRMAÇÃO DE ADIÇÃO COM VLAN CUSTOMIZADA**\n\n` + + `📱 **Serial:** ${serialNumber}\n` + + `📍 **Slot descoberto:** ${result.slot}\n` + + `🔢 **ONU ID a usar:** ${result.onuId}\n` + + `🏷️ **VLAN ID customizada:** ${vlanId}\n` + + `🏢 **OLT:** ${oltId.replace('olt_', '').replace(/_/g, '\\_').toUpperCase()}\n\n` + + `📋 **ONU IDs em uso no slot:** ${result.usedIds.join(', ')}\n\n` + + `⚡ **Configurações que serão aplicadas:**\n` + + `• Line-profile: DM986-100\n` + + `• Ethernet: porta 1\n` + + `• Native VLAN: ${vlanId} (customizada)\n` + + `• Service-port: novo (auto) com VLAN ${vlanId}\n\n` + + `✅ **Confirme que deseja adicionar esta ONU:**`, + { + chat_id: chatId, + message_id: callbackQuery.message.message_id, + parse_mode: 'Markdown', + reply_markup: keyboard + } + ); + } else { + let errorMessage = `❌ **Não foi possível adicionar a ONU**\n\n` + + `📱 **Serial:** ${serialNumber}\n` + + `🏷️ **VLAN:** ${vlanId}\n` + + `🏢 **OLT:** ${oltId.replace('olt_', '').replace(/_/g, '\\_').toUpperCase()}\n\n`; + + if (result.message) { + errorMessage += `❌ **Erro:** ${result.message}\n\n`; + } + + if (result.message && result.message.includes('discovered-onus')) { + errorMessage += `💡 **Dica:** Verifique se a ONU está ligada e descoberta pela OLT.\n` + + `Use o comando: \`show interface gpon discovered-onus\``; + } else if (result.message && result.message.includes('todos os ONU IDs')) { + errorMessage += `💡 **Dica:** O slot está lotado. Considere usar outro slot ou remover ONUs inutilizadas.`; + } else { + errorMessage += `💡 Verifique a conectividade com a OLT ou se a ONU está descoberta.`; + } + + await this.bot.editMessageText(errorMessage, { + chat_id: chatId, + message_id: callbackQuery.message.message_id, + parse_mode: 'Markdown' + }); + } + } catch (error) { + console.error('Erro ao analisar ONU para adição com VLAN customizada:', error); + await this.bot.editMessageText( + `❌ **Erro interno**\n\n` + + `Não foi possível analisar a ONU.\n` + + `Erro: ${error.message}`, + { + chat_id: chatId, + message_id: callbackQuery.message.message_id, + parse_mode: 'Markdown' + } + ); + } + } + /** * Handle callback para confirmar adição de ONU */ diff --git a/src/nlp/processor.js b/src/nlp/processor.js index 43a8b04..adef546 100644 --- a/src/nlp/processor.js +++ b/src/nlp/processor.js @@ -14,6 +14,7 @@ class NLPProcessor { 'ver_sinal': ['ver sinal', 'verificar sinal', 'sinal', 'check signal', 'signal'], 'remover_onu': ['remover onu', 'deletar onu', 'apagar onu', 'remove onu', 'delete onu'], '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'], 'ping': ['ping', 'testar', 'test', 'conectividade'], 'admin': ['admin', 'administração', 'administracao', 'painel'], 'usuarios_autorizados': ['usuarios autorizados', 'users autorizados', 'lista usuarios', 'listar usuarios autorizados'], @@ -55,6 +56,9 @@ class NLPProcessor { // Padrões específicos para ver sinal /^(ver|verificar|check)\s+(sinal|signal)\s+([A-Z0-9]+)$/i, /^(sinal|signal)\s+([A-Z0-9]+)$/i, + // Padrões específicos para adicionar ONU com VLAN customizada + /^(adicionar|add|criar|cadastrar|registrar)\s+(onu|ont)\s+vlan\s+(\d+)\s+([A-Z0-9]+)$/i, + /^(adicionar|add|criar)\s+vlan\s+(\d+)\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, @@ -281,6 +285,32 @@ class NLPProcessor { // Padrões específicos para adicionar ONU if (/adicionar|add|criar|cadastrar|registrar/i.test(action)) { + // Padrão especial: "adicionar onu vlan XXX SERIAL" ou "add onu vlan XXX SERIAL" + if (/vlan/i.test(fullMatch)) { + let vlanId, serialNumber; + + // Formato: "adicionar onu vlan XXX SERIAL" + if (match.length === 5 && /onu|ont/i.test(fullMatch)) { + vlanId = match[3]; // VLAN ID + serialNumber = match[4]; // Serial + } + // Formato: "adicionar vlan XXX SERIAL" + else if (match.length === 4) { + vlanId = match[2]; // VLAN ID + serialNumber = match[3]; // Serial + } + + if (vlanId && serialNumber) { + return { + action: 'adicionar_onu_vlan', + target: serialNumber.trim().toUpperCase(), + vlanId: parseInt(vlanId), + confidence: 0.95, + type: 'add_onu_vlan_pattern' + }; + } + } + // Padrão 1: "adicionar onu SERIAL" ou "add ont SERIAL" if (/onu|ont/i.test(fullMatch)) { let serialNumber = match[3]; // Terceiro grupo capturado (serial após "onu/ont")