← Índice
Secciones (6) ▾

NumChat PWA Demo: Especificación de Interfaz de Usuario y Arquitectura de Conectividad Acústica

Este documento contiene la especificación de diseño visual, flujo de usuario y arquitectura técnica para la Progressive Web App (PWA) de Demostración de NumChat. El objetivo de este diseño es permitir que cualquier desarrollador web front-end implemente un prototipo funcional en menos de 48 horas que funcione 100% offline (Modo Avión) y simule la transmisión acústica/ultrasónica del protocolo semántico de 4 bytes.


1. Arquitectura de Conexión de Cero Fricción (Connectionless Broadcast)

A diferencia de las conexiones tradicionales (Bluetooth, Wi-Fi Direct) que requieren un proceso de emparejamiento (pairing/handshake), NumChat funciona bajo un modelo descentralizado de difusión pura:


2. Mapa de Pantallas e Interfaz de Usuario (Mockup ASCII)

La PWA consta de una sola página reactiva (Single Page Application) con pestañas deslizantes para alternar entre los roles de Emisor (A) y Receptor (B).

Vista General de la Interfaz

+-------------------------------------------------------------+
|                         NUMCHAT                             |
|          [ MODO AVIÓN OFFLINE (Aislado de Red) ]            |
+-------------------------------------------------------------+
|      [ PESTAÑA: EMISOR (A) ]    |    [ PESTAÑA: RECEPTOR (B) ] |
+-------------------------------------------------------------+
|                                                             |
|  +-------------------------------------------------------+  |
|  |             CARTUCHO DE DEMO: SOS-10K                 |  |
|  +-------------------------------------------------------+  |
|                                                             |
|  [!] COMANDOS SEMÁNTICOS DE EMERGENCIA RÁPIDA:               |
|                                                             |
|  +-------------------------------------------------------+  |
|  | [ BOTÓN VERDE ]  EVACUACIÓN DE SEGURIDAD (18.0 kHz)   |  |
|  | "Código 5020: Evacuación Failsafe Global"             |  |
|  +-------------------------------------------------------+  |
|  | [ BOTÓN AMARILLO ] ADVERTENCIA DE TEMPERATURA (18.5 kHz) |  |
|  | "Código 2010: Sobrecalentamiento en Gabinete LED B"   |  |
|  +-------------------------------------------------------+  |
|  | [ BOTÓN ROJO ]     CORTOCIRCUITO CRÍTICO (19.0 kHz)   |  |
|  | "Código 1020: Peligro de Incendio Eléctrico"          |  |
|  +-------------------------------------------------------+  |
|                                                             |
|  +-------------------------------------------------------+  |
|  |               MÓDULO DE ESCUCHA PASIVA                |  |
|  |                                                       |  |
|  |     [ BOTÓN: INICIAR ESCUCHA EN ESTE TELÉFONO ]       |  |
|  |                                                       |  |
|  |  Estado: Esperando señal sónica local...               |  |
|  |  +-------------------------------------------------+  |  |
|  |  | ESTADO DE ALERTA: IDLE                          |  |  |
|  |  +-------------------------------------------------+  |  |
|  +-------------------------------------------------------+  |
+-------------------------------------------------------------+

3. Especificación Técnica de Emisión y Recepción (Web Audio API)

La transmisión de los 4 bytes en el aire se simula asignando cada código semántico crítico del cartucho de demostración a una frecuencia de portadora de audio ultra-específica.

A. Algoritmo del Emisor (Transmisor)

El emisor debe generar un tono puro (onda senoidal) a la frecuencia seleccionada. Para evitar clics audibles molestos en el altavoz y simular una ráfaga limpia de 150 ms, se debe aplicar una rampa de volumen (envolvente ADSR simplificada):

  1. Frecuencia portadora ($f$): Se selecciona según el comando (ej. 19,000 Hz para Cortocircuito).
  2. Tiempo de ataque ($t_{attack}$): Rampa lineal de ganancia de 0 a 1 en 10 milisegundos.
  3. Tiempo de sostenido ($t_{sustain}$): Ganancia en 1 durante 130 milisegundos.
  4. Tiempo de caída ($t_{release}$): Rampa lineal de ganancia de 1 a 0 en 10 milisegundos.
  5. Duración Total: 150 ms de emisión.
// Ejemplo de implementación de emisión
function emitirTonoNumChat(frecuencia) {
    const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    const oscillator = audioCtx.createOscillator();
    const gainNode = audioCtx.createGain();

    oscillator.type = 'sine';
    oscillator.frequency.setValueAtTime(frecuencia, audioCtx.currentTime);

    // Envolvente de volumen (Previene transitorios audibles y ahorra energía)
    gainNode.gain.setValueAtTime(0, audioCtx.currentTime);
    gainNode.gain.linearRampToValueAtTime(1, audioCtx.currentTime + 0.010); // Ataque
    gainNode.gain.setValueAtTime(1, audioCtx.currentTime + 0.140);
    gainNode.gain.linearRampToValueAtTime(0, audioCtx.currentTime + 0.150); // Caída

    oscillator.connect(gainNode);
    gainNode.connect(audioCtx.destination);

    oscillator.start();
    oscillator.stop(audioCtx.currentTime + 0.150);
}

B. Algoritmo del Receptor (Detector Pasivo)

El receptor utiliza el micrófono del dispositivo y calcula en tiempo real una Transformada Rápida de Fourier (FFT) para identificar si la amplitud en los bins de frecuencia específicos supera el umbral de ruido ambiental.

  1. Parámetros FFT: Tamaño del búfer (fftSize) = 2048.
  2. Cálculo del tamaño del Bin ($Hz$ por Bin): $$\text{Resolución} = \frac{\text{Frecuencia de Muestreo (ej. 44100 Hz)}}{\text{fftSize (2048)}} \approx 21.53\text{ Hz por Bin}$$
  3. Fórmula de mapeo de frecuencia a Bin: $$\text{Bin Destino} = \text{redondear}\left(\frac{\text{Frecuencia Objetivo}}{\text{Resolución}}\right)$$
  4. Umbral de Activación (Threshold): Para evitar falsos positivos producidos por ruido ambiental de la sala, la amplitud del bin objetivo debe superar un valor absoluto de 180 (en una escala de 0 a 255) durante al menos 2 ciclos de análisis consecutivos.

4. Estructura del Cartucho de Demostración Embebido (cartridge-demo.json)

Para que la PWA sea autónoma, el siguiente diccionario de correspondencia semántica se incrusta directamente en una constante JavaScript local de la aplicación. Mapea la frecuencia acústica recibida con el identificador semántico binario de 4 bytes y el mensaje traducido al lenguaje humano:

{
  "cartridge_metadata": {
    "id": "SOS-10K",
    "version": "1.0.4",
    "jurisdiction": "Global-Emergency",
    "total_codes": 3
  },
  "semantic_mappings": [
    {
      "frequency_hz": 18000,
      "payload_hex": "0x803C139C",
      "priority": "CRITICAL_FAILSafe",
      "display_color": "#0284c7",
      "translations": {
        "es": "🚨 ALERTA CIVIL: ¡EVACUACIÓN INMEDIATA DEL SECTOR!",
        "en": "🚨 CIVIL ALERT: IMMEDIATE SECTOR EVACUATION REQUIRED!"
      }
    },
    {
      "frequency_hz": 18500,
      "payload_hex": "0x401407DA",
      "priority": "WARNING_HIGH",
      "display_color": "#f59e0b",
      "translations": {
        "es": "⚠️ ADVERTENCIA: SOBRECALENTAMIENTO LED (Brillo reducido al 30%)",
        "en": "⚠️ WARNING: LED OVERHEATING (Brightness reduced to 30%)"
      }
    },
    {
      "frequency_hz": 19000,
      "payload_hex": "0xC01403FC",
      "priority": "CRITICAL_DANGER",
      "display_color": "#ef4444",
      "translations": {
        "es": "🔥 PELIGRO: CORTOCUITO DETECTADO (Corte de energía activado)",
        "en": "🔥 DANGER: SHORT CIRCUIT DETECTED (Power cutoff engaged)"
      }
    }
  ]
}

5. Estrategia Offline (Service Worker)

Para garantizar que la aplicación web funcione en Modo Avión estricto inmediatamente después de que el inversor o los bomberos escaneen el código QR, se debe registrar un service-worker.js que intercepte y guarde en la memoria caché local los recursos críticos del proyecto:

const CACHE_NAME = 'numchat-demo-v1';
const ASSETS = [
  '/',
  '/index.html',
  '/styles.css',
  '/app.js',
  '/manifest.json',
  '/favicon.ico'
];

// Instalar el Service Worker y almacenar recursos en caché
self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => cache.addAll(ASSETS))
      .then(() => self.skipWaiting())
  );
});

// Responder desde la caché cuando esté offline
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => response || fetch(event.request))
  );
});

6. Pruebas de Alcance y Calibración para la Demostración

Al realizar la demo presencial ante inversores o bomberos, calibra la distancia según el modo elegido:

  1. Demostración Silenciosa (Ultrasonidos - 18 kHz a 19 kHz):
    • Rango recomendado: 1.5 a 3 metros de distancia máxima entre teléfonos.
    • Motivo: Los altavoces de los teléfonos de consumo atenúan fuertemente las frecuencias superiores a 16 kHz debido a limitaciones físicas del hardware comercial.
  2. Demostración de Larga Distancia (Tonos Audibles - 1.5 kHz a 3 kHz):
    • Rango recomendado: 15 a 25 metros.
    • Modificación: Ajusta las frecuencias del código JS a 1500 Hz, 2000 Hz y 2500 Hz. Los altavoces del teléfono proyectarán el pitido a máxima potencia, permitiendo hacer la demostración a lo largo de un pasillo completo o en una nave industrial de bomberos.

Diseño técnico registrado y protegido bajo la autoría digital inmutable de NumChat.