Salta el contingut

Montar un Observer de MeshCore

¿Qué es un Observer?

Un Observer es un nodo MeshCore (repetidor, room server o companion) que escucha el tráfico de la malla cercana y reporta lo que oye a un broker MQTT por internet. MeshCore Catalunya usa los datos de los observers para alimentar el mapa, el análisis de cobertura y el análisis de red a través de CoreScope, el mapa en vivo y Beacon. Los observers se pueden configurar para compartir solo advertisements —lo justo para aparecer en el mapa— sin exponer el contenido del resto de tráfico. Puedes dejar de compartir datos cuando quieras.

Solo dispositivos compatibles

El firmware de observer solo está disponible para dispositivos compatibles. Comprueba que tu hardware lo soporta antes de empezar: no todos los dispositivos MeshCore soportan el firmware de packet logging que requiere esta configuración.

Usa modo Repetidor siempre que puedas

No uses Room Server salvo que tengas un motivo concreto: limita la participación en la malla y no aporta ninguna ventaja frente a Repetidor en la mayoría de escenarios. Si no lo tienes claro, pregunta en la comunidad antes de seguir.

Elige tu método de instalación

Hay tres formas de montar un Observer:

Método Mejor para
Firmware Observer nativo Dispositivos que soportan el firmware observer MQTT de forma nativa
Puente por ordenador (mctomqtt) Repetidor o room server conectado por USB a una Raspberry Pi o equipo Linux
Puente Companion Nodos companion; usa un software de puente distinto

Estado actual en Catalunya

Métodos operativos y verificados en producción (27/06/2026): el Método 3 (companion / packet-capture) publica a Catalunya por usuario/contraseña, y el Método 4 (Home Assistant / meshcore-ha) hace lo mismo para nodos ya integrados en HA — la vía recomendada si el nodo vive en HA por TCP/WiFi. El Método 2 (mctomqtt) usa la misma vía y broker (para repetidores/room servers). El Método 1 (firmware nativo) sigue por confirmar: la config documentada usa token Ed25519 (campo audience), que nuestro Mosquitto no usa. Un nodo nativo sí puede publicar al analizador global (LetsMesh / mapa oficial), pero para Catalunya usa el Método 2, 3 o 4.


Método 1: Firmware Observer nativo

Paso 1: Descargar y flashear el firmware

Instalación nueva

Usa el MeshCore MQTT Observer Flasher online para encontrar, descargar y flashear el firmware correcto de tu dispositivo directamente desde el navegador.

Los ficheros -merged borran el dispositivo

Los ficheros marcados como -merged hacen un borrado completo y son solo para instalaciones nuevas. Flashear un -merged sobre un MeshCore ya configurado borra todos los ajustes, claves y configuración. Si actualizas una instalación existente, usa siempre la variante sin -merged.

Actualizar por OTA

Si ya tienes MeshCore funcionando, puedes actualizar de forma inalámbrica con la app companion y un navegador en lugar del flasher web y el USB:

  1. Descarga el firmware de app desde el Observer Flasher (opción app firmware, no el merged).
  2. Abre Remote Management en la app companion: selecciona tu nodo e introduce la contraseña de admin.
  3. Abre la línea de comandos (Command Line) y ejecuta start ota.
  4. Ve a la página de subida OTA:
    • Si el nodo no está en Wi-Fi, emite un hotspot MeshCore-OTA: conéctate y ve a http://192.168.4.1/update.
    • Si ya está en Wi-Fi, busca su IP (en la pantalla del nodo o en la tabla DHCP del router) y ve a http://<ip-del-nodo>/update.
  5. Sube el fichero .bin y espera a que termine.
  6. Verifica la versión en Remote Management.

Paso 2: Aplicar los ajustes de Catalunya

Con el firmware instalado, abre la línea de comandos en Remote Management e introduce:

set timezone Europe/Madrid
set path.hash.mode 2
set advert.interval 240
set mqtt.iata BCN

Conexión a los brokers:

set mqtt1.preset analyzer-eu

Verifica el preset del analizador EU

En redes de EE. UU. el preset es analyzer-us. Para Europa usa la variante EU; confirma el nombre exacto en tu firmware. Este preset publica al analizador global de LetsMesh y al mapa oficial de MeshCore, no al broker de Catalunya.

El broker de Catalunya por firmware nativo (mqtt2) está por confirmar

La configuración documentada del segundo broker (mqtt2.server / mqtt2.audience) usa autenticación por token Ed25519, que nuestro Mosquitto no usa. Falta confirmar si el firmware nativo admite además usuario/contraseña. Hasta verificarlo, para publicar a Catalunya usa el Método 2 o el Método 3.

Ajustes restantes del nodo (válidos en cualquier caso):

set mqtt.rx on
set mqtt.tx advert
set wifi.ssid tu-red-wifi
set wifi.pwd tu-contraseña-wifi
set bridge.enabled on
set flood.advert.interval 72

Wi-Fi sin comillas

Sustituye tu-red-wifi y tu-contraseña-wifi por tus credenciales reales. No las pongas entre comillas.

Si este nodo es solo observer (no repite):

set repeat off
set flood.advert.interval 168

Opcional pero recomendado, enlaza el observer a tu companion (mejora la analítica):

set mqtt.owner clave-publica-de-tu-companion
reboot

Método 2: Puente por ordenador (USB + Raspberry Pi)

Este es el método recomendado y operativo en Catalunya. Captura el tráfico desde un repetidor o room server conectado por USB y lo publica al broker de Catalunya (broker.livemap-meshcorecat.com). Puede publicar a varios brokers a la vez (p. ej. LetsMesh + Catalunya) sin conflicto.

Requisitos

  • Una Raspberry Pi (Zero 2 / 3 / 4) u otro Linux/macOS siempre encendido.
  • Un repetidor o room server MeshCore con firmware con packet-logging (Paso 1).
  • Conexión USB entre el nodo y el equipo Linux.
  • Python 3.11+.
  • Las credenciales de publicación de Catalunya (cat-pub, incluidas más abajo).

Firmware que NO sirve

El firmware normal de chat no expone los paquetes. Tampoco sirve el fork VBart/MeshCoreTel, que solo publica a sus propios brokers.

Paso 1: Firmware compatible

El radio tiene que exponer los paquetes por el puerto serie. Usa el MeshCore MQTT Observer Flasher y selecciona tu placa con la variante observer / repeater con packet logging.

  • Instalación nueva: usa el fichero -merged (borra todo).
  • Actualización: usa la variante sin -merged para no perder claves ni ajustes.

Paso 2: Preparar la Pi

Actualiza e instala las dependencias base (necesarias para compilar ed25519-orlp si no hay wheel precompilado):

sudo apt update
sudo apt install -y python3 python3-venv python3-dev build-essential
python3 --version    # tiene que ser 3.11+

Localiza el puerto serie del radio (normalmente /dev/ttyUSB0 o /dev/ttyACM0):

ls /dev/ttyUSB* /dev/ttyACM* 2>/dev/null

Paso 3: Conectar y ejecutar el instalador

Con el nodo conectado por USB, ejecuta:

curl -fsSL https://raw.githubusercontent.com/Cisien/meshcoretomqtt/main/install.sh | sudo bash

El instalador crea un usuario de sistema mctomqtt, instala en /opt/mctomqtt/ con la config en /etc/mctomqtt/, monta un venv de Python, configura el servicio systemd mctomqtt y te guía por una configuración interactiva (que puedes saltar y editar los ficheros a mano).

Configuración

Los presets van en config.d/10-<preset>.toml y tus ajustes en 99-user.toml. Puedes tener varios [[broker]] activos a la vez.

config.d/99-user.toml — ajustes generales y puerto serie:

[general]
iata = "BCN"

[serial]
ports = ["/dev/ttyUSB0"]

Ajusta el puerto y el IATA

Cambia /dev/ttyUSB0 por el puerto real del Paso 2. iata = "BCN" te hace publicar bajo el prefijo de Catalunya; si usas otro código de tu zona, avísame para saber bajo qué tópico buscarte.

config.d/20-catalunya.toml — broker de Catalunya:

[[broker]]
name = "catalunya"
enabled = true
server = "broker.livemap-meshcorecat.com"
port = 8883
keepalive = 60
qos = 0
retain = true

[broker.tls]
enabled = true
verify = true

[broker.auth]
method = "password"
username = "cat-pub"
password = "CatMesh2026pub"

Sobre la contraseña

El usuario cat-pub (contraseña CatMesh2026pub) es write-only: solo publica, no puede leer nada del broker, por eso es compartible entre observers.

Alternativa por WebSocket seguro

Si el TLS por TCP da problemas en tu red, cambia en el bloque del broker el puerto y añade el transporte, dejando el resto igual:

port = 8084
transport = "websockets"

¿Publicar también a LetsMesh u otros?

mctomqtt publica a todos los [[broker]] con enabled = true a la vez. Para añadir LetsMesh se pone otro bloque con method = "token" y su audience.

Arrancar el servicio

sudo systemctl restart mctomqtt
sudo systemctl enable mctomqtt
sudo journalctl -u mctomqtt -f

Deberías ver el puerto serie abriéndose, paquetes llegando del radio y un connect al broker catalunya sin errores de TLS ni de auth.

Hasta 5 minutos para aparecer

Puede tardar unos minutos desde que el observer conecta hasta que sale en la lista. El nodo necesita que se oiga un advertisement antes de aparecer en el mapa, pero los datos de paquetes ya se registran mientras tanto.


Método 3: Puente Companion

A diferencia de repetidores y room servers, los observers companion no requieren firmware especial: el build companion estándar ya soporta packet logging. Este método usa un software de puente distinto a mctomqtt y corre en un equipo macOS o Linux conectado al companion por USB, BLE o Wi-Fi.

Requisitos

  • Un equipo macOS o Linux (p. ej. Raspberry Pi) con conexión a internet.
  • Un dispositivo companion MeshCore accesible por USB, BLE o Wi-Fi.

Paso 1: Instalar Node.js LTS

Instala NVM y luego Node.js LTS:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install --lts

Paso 2: Ejecutar el instalador

sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/agessaman/meshcore-packet-capture/main/install.sh)"

Usa esta sintaxis exacta

El instalador necesita root. Evita bash <(curl ...) (aunque lo ponga la guía original de ChiMesh): con sudo da error /dev/fd/63: No such file or directory. La forma sudo bash -c "$(curl ...)" descarga el script como texto dentro del proceso root y funciona siempre.

Solo para companion

meshcore-packet-capture es solo para nodos companion. Si tienes un repetidor o room server, usa el Método 2.

Paso 3: Configurar el MQTT de Catalunya

meshcore-packet-capture soporta autenticación usuario/contraseña además del modo token, así que publica a nuestro Mosquitto igual que mctomqtt. La guía original de ChiMesh muestra los campos Server / Port / Audience porque su broker usa token Ed25519; para Catalunya no se usa Audience: se configura el broker en modo usuario/contraseña.

Ajuste Valor para Catalunya
Server broker.livemap-meshcorecat.com
Port 8883 (TLS por TCP)
TLS activado
Auth usuario/contraseña (no token)
Usuario cat-pub
Contraseña CatMesh2026pub
Audience (vacío, no se usa)
IATA BCN

Si prefieres editar el fichero, en .env.local (los brokers 1 y 2 suelen ser LetsMesh US/EU, así que Catalunya va como broker 3):

# MQTT Broker 3 (Catalunya)
PACKETCAPTURE_MQTT3_ENABLED=true
PACKETCAPTURE_MQTT3_SERVER=broker.livemap-meshcorecat.com
PACKETCAPTURE_MQTT3_PORT=8883
PACKETCAPTURE_MQTT3_USE_TLS=true
PACKETCAPTURE_MQTT3_USE_AUTH_TOKEN=false
PACKETCAPTURE_MQTT3_USERNAME=cat-pub
PACKETCAPTURE_MQTT3_PASSWORD=CatMesh2026pub
PACKETCAPTURE_MQTT3_KEEPALIVE=120

Alternativa WSS

Si el TLS por TCP da problemas, usa PACKETCAPTURE_MQTT3_PORT=8084 y añade PACKETCAPTURE_MQTT3_TRANSPORT=websockets.

Verificado en producción (27/06/2026)

USE_AUTH_TOKEN=false es lo que evita que espere el audience. Las variables _USERNAME / _PASSWORD están confirmadas: probado en el RPi4 con un observer publicando a broker.livemap-meshcorecat.com, con status y packets visibles bajo meshcore/BCN/... y sin errores de TLS ni de token.

Conflicto de puerto serie con otros servicios (Remote Terminal, etc.)

En un mismo equipo, solo un proceso puede abrir el puerto serie del radio a la vez. Si ya corre otro servicio sobre el mismo nodo por USB (p. ej. Remote Terminal / meshcore.service sobre /dev/ttyUSB0), packet-capture en modo serial se lo quitará y el otro dejará de arrancar. No conviven los dos por serie en el mismo Pi.

Soluciones para que convivan (mismo Heltec, dos servicios):

  • USB + WiFi (recomendado): deja un servicio por USB serie y pon el otro en TCP contra el puerto WiFi del companion (por defecto 5000). Ver más abajo.
  • BLE: una de las dos vías por Bluetooth en lugar de serie.
  • Radios separados: un companion para cada servicio.
  • ser2net: compartir el mismo serie por TCP a varios clientes.

Convivencia USB + TCP/WiFi (mismo nodo)

Si el Heltec tiene WiFi (firmware con WiFi habilitado), expone TCP (puerto 5000). Configura packet-capture en modo tcp apuntando a la IP del nodo (ponle reserva DHCP en el router para que no cambie), dejando el USB libre para el otro servicio. Comprueba antes que el puerto responde: nc -vz 192.168.188.XX 5000.

Una sola sesión TCP por nodo (probado 27/06/2026)

Muchos builds del companion aceptan una única conexión TCP a la vez. Si el nodo ya está conectado por TCP a otra cosa (p. ej. Home Assistant), packet-capture no puede entrar en paralelo: se produce un bucle de reconexión cada ~2 s (TCP Connection started repetido) y ninguna de las dos vías queda estable. En ese caso, no uses packet-capture sobre ese nodo: si el nodo ya vive en HA, publica a Catalunya desde HA (ver Método 4). El modo TCP solo sirve si ese puerto del nodo está libre.

Formato de configuración según la instalación. Hay dos esquemas; mira cuál usa la tuya (el log lo dice al arrancar: Loading config override: ...):

En ~/.meshcore-packet-capture/.env.local:

PACKETCAPTURE_CONNECTION_TYPE=tcp
PACKETCAPTURE_TCP_HOST=192.168.188.XX   # IP del nodo
PACKETCAPTURE_TCP_PORT=5000
# PACKETCAPTURE_SERIAL_PORTS=...        # comentado: ya no usa serie

En /etc/meshcore-packet-capture/config.d/99-user.toml — la clave TCP va dentro de [capture] (no en una sección [tcp] aparte):

[capture]
connection_type = "tcp"
tcp_host = "192.168.188.XX"
tcp_port = 5000
advert_interval_hours = 11

#[serial]
#ports = ["/dev/serial/by-id/usb-..."]   # comentado: ya no usa serie

En este esquema el broker de Catalunya también va aquí, como [[broker]]:

[[broker]]
name = "catalunya"
enabled = true
server = "broker.livemap-meshcorecat.com"
port = 8883
keepalive = 120
qos = 0
retain = true
[broker.tls]
enabled = true
verify = true
[broker.auth]
method = "password"
username = "cat-pub"
password = "CatMesh2026pub"

La migración no copia tus brokers custom

Al migrar de .env.local a config.d/*.toml, el instalador trae IATA y los presets LetsMesh, pero puede dejarse atrás brokers añadidos a mano (como Catalunya). Verifica con grep -i catalunya /etc/meshcore-packet-capture/config.d/99-user.toml; si no está, añádelo como arriba.

Tras cambiar la config: sudo systemctl restart meshcore-packet-capture.service y en el log busca Using connection type: tcp y Connecting via TCP to 192.168.188.XX:5000 (si dice localhost, la clave TCP no se aplicó). Vigila unos minutos que no entre en bucle de reconexión.

Paso 4 (opcional): Publicar también a MeshMapper

El mismo observer puede publicar a la vez a Catalunya, LetsMesh y MeshMapper. MeshMapper sí usa el broker WebSocket + token Ed25519, así que aquí se usa audience (a diferencia del broker de Catalunya). Es la misma autenticación que ya usan los brokers LetsMesh (MQTT1/MQTT2), de modo que si esos funcionan, este también.

Datos del broker de MeshMapper:

Ajuste Valor
Server mqtt.meshmapper.net
Port 443
Transport websockets
TLS activado (verificar certificado)
Auth MeshCore Auth Token (no usuario/contraseña)
Token audience mqtt.meshmapper.net
IATA BCN

En .env.local, como broker 4:

# MQTT Broker 4 - MeshMapper
PACKETCAPTURE_MQTT4_ENABLED=true
PACKETCAPTURE_MQTT4_SERVER=mqtt.meshmapper.net
PACKETCAPTURE_MQTT4_PORT=443
PACKETCAPTURE_MQTT4_TRANSPORT=websockets
PACKETCAPTURE_MQTT4_USE_TLS=true
PACKETCAPTURE_MQTT4_USE_AUTH_TOKEN=true
PACKETCAPTURE_MQTT4_TOKEN_AUDIENCE=mqtt.meshmapper.net
PACKETCAPTURE_MQTT4_KEEPALIVE=120

# MQTT Topics for Broker 4 (MeshMapper) - Default Pattern
PACKETCAPTURE_MQTT4_TOPIC_STATUS=meshcore/{IATA}/{PUBLIC_KEY}/status
PACKETCAPTURE_MQTT4_TOPIC_PACKETS=meshcore/{IATA}/{PUBLIC_KEY}/packets

Requiere export de clave privada

El modo token firma con la clave Ed25519 del nodo, así que el firmware debe tener el export de clave privada habilitado. Si LetsMesh (MQTT1/MQTT2) ya publica, este export ya funciona y MeshMapper conectará igual. El observer aparecerá en el Admin Portal de tu región (pestaña Observers) con el check del broker MeshMapper una vez reciba paquetes.


Método 4: Publicar desde Home Assistant (meshcore-ha)

Si el nodo ya está integrado en Home Assistant (integración meshcore-ha), no necesitas packet-capture ni mctomqtt: la propia integración sabe publicar a MQTT. Es la vía recomendada para un nodo que ya vive en HA, sobre todo si está conectado a HA por TCP/WiFi, porque así un único proceso habla con el radio y evitas el conflicto de "una sola sesión TCP".

Verificado en producción (27/06/2026)

Probado con el V3 Teià (HA por WiFi/TCP) publicando a Catalunya vía meshcore-ha 2.8.0: status online con source: meshcore-ha, modelo y firmware correctos, y packets entrando en vivo bajo meshcore/BCN/.... Un intento previo con packet-capture por TCP al mismo nodo entró en bucle de reconexión por compartir el puerto con HA; publicar desde HA lo resolvió.

meshcore-ha soporta usuario/contraseña o token, así que el broker de Catalunya (Mosquitto) le va directo, sin audience. En la UI de Home Assistant: Ajustes → Dispositivos y servicios → MeshCore → Configurar, sección de subida MQTT (MQTT Upload / Broker), y añade un broker en una ranura libre:

Campo Valor
Server / Host broker.livemap-meshcorecat.com
Port 8883
TLS activado
Auth usuario/contraseña
Usuario cat-pub
Contraseña CatMesh2026pub
IATA BCN
Modo packets / adverts
Topic por defecto (meshcore/{IATA}/{PUBLIC_KEY}/...)

Guarda (la integración se recarga sola) y verifica desde el servidor:

mosquitto_sub -h broker.livemap-meshcorecat.com -p 8883 \
  -u cat-sub -P CatMesh2026sub --capath /etc/ssl/certs \
  -t 'meshcore/BCN/<PUBLIC_KEY>/#' -v

Debe salir un status online con "source": "meshcore-ha" y packets en vivo.

¿Sale ONLINE pero con la etiqueta antigua?

Si en Beacon o en el broker el nodo aparece con un client_version viejo (p. ej. meshcore-packet-capture/unknown), suele ser un mensaje retain o la caché de Beacon. El estado real lo da el status en vivo (--no-retain); para forzar Beacon, docker compose exec redis redis-cli FLUSHDB y recarga.


Notas adicionales

  • Comprobación desde el lado Catalunya (lo hago yo desde el servidor, con el usuario de solo lectura cat-sub):

    mosquitto_sub -h broker.livemap-meshcorecat.com -p 8883 \
      -u cat-sub -P <password-sub> \
      --capath /etc/ssl/certs \
      -t 'meshcore/+/#' -v
    

    El + muestra cualquier IATA, así se ve de inmediato bajo qué prefijo entra el nuevo observer.

  • Para dejar de compartir datos: sudo systemctl stop mctomqtt (y disable si no quieres que vuelva a arrancar).

Problemas típicos (Método 2)

Síntoma Causa probable Solución
No abre el puerto serie Puerto incorrecto o sin permisos Revisa ls /dev/ttyUSB* /dev/ttyACM*; el usuario mctomqtt debe estar en el grupo dialout
Error TLS al conectar Reloj desincronizado o CA no encontrada Verifica NTP (timedatectl); prueba la variante WSS por 8084
Auth rejected Usuario/contraseña mal Confirma cat-pub y la password exacta (sin espacios)
Conecta pero no publica nada El radio no tiene firmware con packet-logging Reflashea con la variante observer/debug del Paso 1
No aparece bajo BCN IATA distinto en [general] Pon iata = "BCN" en 99-user.toml y reinicia

¿Dudas durante la instalación?

Mándame el output de journalctl -u mctomqtt -f y lo miramos.