genieacs: try fix search

Signed-off-by: Rodrigo Bertoldo de Sousa Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
rodrigo committed 2026-04-01 09:24:00 -03:00
1 parent c003631efc
commit a701b85754
2 files changed
+39 -7

No files matched your search

+36 -4
View File
@@ -8,6 +8,7 @@ const logger = require('../utils/logger');
*/
const DEVICE_PROJECTION = [
'_tags',
'Tags',
'DeviceID.SerialNumber',
'DeviceID.ProductClass',
'DeviceID.Manufacturer',
@@ -110,23 +111,45 @@ class GenieACSApi {
/**
* Busca um dispositivo por serial number.
* Tenta exato primeiro; se não encontrar, tenta uppercase (usuário pode ter digitado minúsculo).
* @param {string} serial - Serial number
* @param {Object} instance - Instância de GenieACSConfig
*/
async buscarDispositivo(serial, instance) {
logger.info(`[GenieACS] Buscando serial "${serial}" em ${instance.name}`);
return this._buscar({ 'DeviceID.SerialNumber': serial }, instance, 'serial');
// Tentativa 1: exato como foi informado
const r1 = await this._buscar({ 'DeviceID.SerialNumber': serial }, instance, 'serial');
if (r1.success) return r1;
// Tentativa 2: uppercase (seriais costumam ser armazenados em maiúsculas)
const upper = serial.toUpperCase();
if (upper !== serial) {
logger.info(`[GenieACS] Tentando serial em uppercase: "${upper}"`);
return this._buscar({ 'DeviceID.SerialNumber': upper }, instance, 'serial');
}
return r1;
}
/**
* Busca um dispositivo pela TAG (nome de usuário TopSapp).
* No GenieACS, as tags são armazenadas no campo _tags (array de strings).
* Usa regex case-insensitive para não depender de maiúsculas/minúsculas.
* @param {string} tag - Valor da tag (ex.: login PPPoE do cliente)
* @param {Object} instance - Instância de GenieACSConfig
*/
async buscarPorTag(tag, instance) {
logger.info(`[GenieACS] Buscando por TAG "${tag}" em ${instance.name}`);
return this._buscar({ '_tags': tag }, instance, 'tag');
// Escapa caracteres especiais de regex no valor da tag
const tagEscaped = tag.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
// Tentativa 1: campo _tags com regex case-insensitive (formato array)
const r1 = await this._buscar(
{ '_tags': { '$regex': `^${tagEscaped}$`, '$options': 'i' } },
instance, 'tag'
);
if (r1.success) return r1;
// Tentativa 2: campo Tags.<nome> = true (formato objeto, como exibido na UI)
logger.info(`[GenieACS] Tentando campo Tags.${tag} em ${instance.name}`);
return this._buscar({ [`Tags.${tag.toLowerCase()}`]: true }, instance, 'tag');
}
/**
@@ -141,7 +164,16 @@ class GenieACSApi {
const autoChannel5 = get('InternetGatewayDevice.LANDevice.1.WLANConfiguration.2.AutoChannelEnable');
// _tags é um array direto na raiz do objeto (não segue o padrão _value)
const tags = Array.isArray(raw._tags) ? raw._tags : [];
// Tags também pode vir como objeto { clickcolmeia2025: { _value: true } } (formato UI do GenieACS)
let tags = [];
if (Array.isArray(raw._tags)) {
tags = raw._tags;
} else if (raw.Tags && typeof raw.Tags === 'object') {
// Extrai as chaves do objeto Tags onde o valor é true
tags = Object.entries(raw.Tags)
.filter(([k, v]) => k !== '_timestamp' && (v === true || (v && v._value === true)))
.map(([k]) => k);
}
return {
deviceId : raw._id || null,
+3 -3
View File
@@ -171,7 +171,7 @@ class NLPProcessor {
const serial = match[match.length - 1] || match[2];
return {
action: 'ver_roteador',
target: serial ? serial.trim().toUpperCase() : null,
target: serial ? serial.trim() : null,
confidence: 0.95,
type: 'genieacs_pattern'
};
@@ -754,11 +754,11 @@ class NLPProcessor {
// Detectar "ver roteador SERIAL" / "roteador SERIAL" via GenieACS
if (/roteador|cpe/i.test(text) && !/onu|ont|sinal|signal/i.test(text)) {
const rrMatch = text.match(/(?:ver|info|status|dados)?\s*(?:roteador|cpe)\s+([A-Z0-9_-]+)/i);
const rrMatch = text.match(/(?:ver|info|status|dados)?\s*(?:roteador|cpe)\s+([A-Z0-9_@.-]+)/i);
if (rrMatch && rrMatch[1]) {
return {
action: 'ver_roteador',
target: rrMatch[1].trim().toUpperCase(),
target: rrMatch[1].trim(),
confidence: 0.9,
type: 'keyword_roteador'
};