Offline field reports via LoRa mesh → OpenStreetMap Notes
El OSM Mesh Notes Gateway es un sistema que permite a personas en terreno (sin conexión a Internet) enviar reportes de mapeo usando dispositivos LoRa mesh (Meshtastic) que se convierten automáticamente en notas de OpenStreetMap.
Cuando un usuario en campo envía un mensaje con el comando #osmnote desde su dispositivo Meshtastic (como un T-Echo), el gateway lo recibe por radio LoRa, valida su ubicación GPS, y lo convierte en una nota pública de OSM. Si no hay Internet disponible, el reporte se guarda en una cola local y se envía automáticamente cuando la conexión se restaura.
Este sistema está diseñado para funcionar de forma autónoma en una Raspberry Pi con un dispositivo Meshtastic conectado por USB, operando 24/7 sin intervención manual.
Este proyecto nace de la necesidad de permitir reportes de mapeo en situaciones donde:
- No hay Internet disponible: Zonas remotas, áreas afectadas por desastres naturales, o lugares donde la infraestructura de telecomunicaciones está caída o es inexistente.
- Se requiere mapeo colaborativo: Comunidades que necesitan documentar cambios en el territorio, daños por desastres, o mejoras necesarias en infraestructura.
- Conectividad intermitente: El gateway funciona como un "puente" entre la red LoRa mesh local (que no requiere Internet) y OpenStreetMap (que sí lo requiere), almacenando reportes localmente cuando no hay conexión.
El sistema prioriza robustez y simplicidad de despliegue, permitiendo que comunidades locales puedan desplegar su propio gateway con hardware accesible y software de código abierto.
El flujo básico es el siguiente:
-
Usuario en campo: Envía un reporte desde su dispositivo Meshtastic (T-Echo) usando el comando
#osmnote <mensaje>. El dispositivo debe tener GPS activo y estar al aire libre para obtener ubicación. -
Red LoRa mesh: El mensaje viaja por radio LoRa hasta llegar al gateway, sin necesidad de Internet.
-
Gateway:
- Recibe el mensaje por USB desde el dispositivo Meshtastic conectado
- Valida que haya GPS reciente (últimos 60 segundos)
- Verifica que no sea un duplicado
- Guarda el reporte en una base de datos local (SQLite)
-
Envío a OSM:
- Si hay Internet: Envía inmediatamente a la API de OSM Notes
- Si no hay Internet: Guarda en cola y envía automáticamente cuando se restaura la conexión
-
Confirmación: El usuario recibe una confirmación por mensaje directo (DM) con el ID de la nota creada o el ID de cola si quedó pendiente.
┌─────────────┐ LoRa ┌──────────┐ USB ┌─────────────┐
│ T-Echo │ ──────────────> │ Heltec │ ────────────> │ Raspberry │
│ (Campo) │ (Radio) │ V3 │ (Serial) │ Pi │
└─────────────┘ └──────────┘ └─────────────┘
│
│ Internet
▼
┌─────────────┐
│ OSM Notes │
│ API │
└─────────────┘
Enviar un reporte desde tu dispositivo Meshtastic:
#osmnote Bache grande en carretera principal. Necesita reparación urgente.
Respuesta del gateway:
✅ Nota creada: Q-12345
📍 Ubicación: Barrio Centro
🌐 Ver en OSM: https://www.openstreetmap.org/note/456789
📖 Ver más ejemplos y casos de uso reales: docs/EXAMPLES.md
- Raspberry Pi 3 (o superior) con Raspberry Pi OS
- Dispositivo Meshtastic (Heltec V3) conectado por USB
- Conexión a Internet (para envío a OSM, puede ser intermitente)
- Python 3.8+
# Clonar repositorio
git clone https://github.com/OSM-Notes/osm-mesh-notes-gateway.git
cd osm-mesh-notes-gateway
# Instalar (requiere sudo)
sudo bash scripts/install_pi.shEl script de instalación configura todo automáticamente:
- Instala dependencias del sistema
- Crea entorno virtual Python
- Configura servicio systemd
- Agrega usuario al grupo
dialoutpara acceso serial
- Detectar puerto serial:
# Usar el script de detección automática (recomendado)
bash scripts/detect_serial.sh
# O manualmente
ls -l /dev/ttyACM* /dev/ttyUSB*- Editar configuración (
/var/lib/lora-osmnotes/.env):
SERIAL_PORT=/dev/ttyACM0 # Ajustar según tu dispositivo
DRY_RUN=false
TZ=America/Bogota- Iniciar servicio:
sudo systemctl start lora-osmnotes
sudo systemctl enable lora-osmnotes # Iniciar al arrancar- Verificar funcionamiento:
sudo journalctl -u lora-osmnotes -fDesde la app Meshtastic en tu teléfono (conectado por Bluetooth al T-Echo):
Crear una nota:
#osmnote Árbol caído bloquea la calle
Respuesta:
✅ Nota creada: Q-12345
📍 Ubicación: Barrio Centro
🌐 Ver en OSM: https://www.openstreetmap.org/note/456789
Otros comandos útiles:
#osmhelp- Muestra ayuda básica#osmmorehelp- Muestra ayuda adicional detallada#osmstatus- Verifica estado del gateway#osmlist- Lista tus notas recientes#osmcount- Cuenta tus notas (hoy y total)#osmnodes- Lista nodos conocidos en la red
📖 Ver más ejemplos y casos de uso reales: docs/EXAMPLES.md
Para más información, consulta la documentación técnica:
- docs/FIELD_DEPLOYMENT_GUIDE.md -
⚠️ Guía de despliegue en terreno - Checklist y elementos necesarios para desplegar en campo - docs/spec.md - Especificación canónica del MVP (fuente de verdad)
- docs/architecture.md - Arquitectura del sistema y diseño
- docs/message-format.md - Formato de mensajes Meshtastic
- docs/API.md - Referencia de API interna
- docs/SECURITY.md - Guía de seguridad
- docs/TROUBLESHOOTING.md - Solución de problemas
- docs/TIME_CONFIGURATION.md - Configuración de tiempo y sincronización
- docs/EXAMPLES.md - 📖 Ejemplos de uso y casos de uso reales
- CONTRIBUTING.md - Guía para contribuidores
- docs/DEDUP_API_EXTENSIONS.md - Propuesta de API de deduplicación global para múltiples gateways
- docs/OUT_OF_SCOPE_MOBILE_GATEWAY.md - Mejoras futuras fuera del alcance actual (gateways móviles)
Este sistema NO debe usarse para:
- Emergencias médicas o situaciones que requieran atención inmediata
- Reportes que requieran respuesta de autoridades
- Comunicación crítica que dependa de disponibilidad garantizada
- Canal público: Los mensajes viajan por un canal LoRa público, cualquier nodo en el mismo canal puede leerlos
- Datos personales: NO envíes información personal identificable (nombres, números de teléfono, direcciones específicas)
- Notas públicas: Las notas creadas en OSM son públicas y visibles para cualquiera
- Advertencias automáticas: Todos los mensajes del sistema incluyen advertencias de privacidad
El gateway procesa solo mensajes que contengan comandos específicos (hashtags como #osmnote, #osmhelp, #osmmorehelp, etc.). Los mensajes de texto libre sin comandos son ignorados y no se responde a ellos.
Los usuarios pueden enviar comandos desde la app Meshtastic:
| Comando | Descripción |
|---|---|
#osmnote <mensaje> |
Crea una nota de OSM. Requiere GPS reciente (≤60s) |
#osmhelp |
Muestra instrucciones de uso básicas |
#osmmorehelp |
Muestra ayuda adicional detallada |
#osmstatus |
Estado del gateway (activo, Internet, colas) |
#osmcount |
Conteo de notas creadas (hoy + total) |
#osmlist [n] |
Lista últimas n notas (default: 5, max: 20) |
#osmqueue |
Tamaño de cola total y del nodo |
#osmnodes |
Lista todos los nodos conocidos en la red mesh |
Variantes aceptadas para #osmnote: #osm-note, #osm_note
Este proyecto fue desarrollado como parte del esfuerzo de mapeo colaborativo para comunidades en zonas con conectividad limitada.
Desarrollado por: OSM-Notes Project Team
Con el apoyo de:
- AC3 - Apoyo técnico y validación en campo
- NASA Lifelines - Financiamiento y contexto de aplicación en respuesta a desastres
Autores: Ver AUTHORS para la lista completa de contribuidores.
- OSM Diary (inglés, alto nivel) - Overview del proyecto y casos de uso
- osm.lat Blog (español, técnico) - Detalles técnicos y guía de despliegue
Este proyecto está licenciado bajo GPL-3.0. Ver archivo LICENSE.
Para información sobre cómo citar este software, ver CITATION.cff.
Las contribuciones son bienvenidas. Por favor:
- Fork el proyecto: https://github.com/OSM-Notes/osm-mesh-notes-gateway
- Crea una rama para tu feature
- Commit tus cambios
- Push a la rama
- Abre un Pull Request
Ver CONTRIBUTING.md para más detalles.
Para reportar problemas o solicitar features, abre un issue en GitHub: https://github.com/OSM-Notes/osm-mesh-notes-gateway/issues
Para problemas comunes, consulta docs/TROUBLESHOOTING.md.
1. Verificar logs del servicio:
# Ver logs en tiempo real
sudo journalctl -u lora-osmnotes -f
# Ver últimos 50 líneas
sudo journalctl -u lora-osmnotes -n 50
# Ver logs desde hoy
sudo journalctl -u lora-osmnotes --since today2. Verificar permisos del puerto serial:
# Detectar dispositivo automáticamente
bash scripts/detect_serial.sh
# Verificar permisos manualmente
ls -l /dev/ttyACM0 # o /dev/ttyUSB0 según tu dispositivo
# Si no tienes permisos, agregar usuario a grupo dialout
sudo usermod -a -G dialout $USER
# IMPORTANTE: Cerrar sesión y volver a iniciar para aplicar cambios3. Verificar que el dispositivo está conectado:
# Ver dispositivos USB conectados
lsusb | grep -i meshtastic
# Ver dispositivos seriales disponibles
ls -l /dev/ttyACM* /dev/ttyUSB*
# Verificar que el puerto configurado existe
cat /var/lib/lora-osmnotes/.env | grep SERIAL_PORT4. Verificar estado del servicio:
# Estado del servicio
sudo systemctl status lora-osmnotes
# Reiniciar servicio
sudo systemctl restart lora-osmnotes
# Ver si está habilitado para iniciar al arrancar
sudo systemctl is-enabled lora-osmnotesProblema de permisos del puerto serial:
# Verificar grupo del usuario actual
groups
# Si no está en dialout, agregarlo
sudo usermod -a -G dialout $USER
# CERRAR SESIÓN Y VOLVER A INICIAR (requerido)
# Luego verificar:
groups | grep dialoutProblema de permisos del directorio de datos:
# Verificar permisos
ls -l /var/lib/lora-osmnotes
# Corregir permisos (ajustar usuario según tu sistema)
sudo chown -R $USER:$USER /var/lib/lora-osmnotes
# O si es para el servicio:
sudo chown -R pi:pi /var/lib/lora-osmnotes # Ajustar según tu usuarioVerificar conexión serial:
# Usar script de detección
bash scripts/detect_serial.sh
# Probar conexión directa (requiere permisos)
sudo screen /dev/ttyACM0 9600
# Presionar Ctrl+A luego K para salirVerificar configuración:
# Ver puerto configurado
cat /var/lib/lora-osmnotes/.env | grep SERIAL_PORT
# Ver logs para errores de conexión
sudo journalctl -u lora-osmnotes | grep -i "serial\|connection\|error"Verificar conexión a Internet:
ping -c 3 api.openstreetmap.org
curl -I https://api.openstreetmap.org/api/0.6/notes.jsonVerificar logs:
# Buscar errores relacionados con OSM
sudo journalctl -u lora-osmnotes | grep -i "osm\|error\|failed"
# Ver estado de notas en la base de datos
sudo sqlite3 /var/lib/lora-osmnotes/gateway.db "SELECT local_queue_id, status, last_error FROM notes WHERE status='pending' LIMIT 10;"Nota: El sistema respeta un mínimo de 3 segundos entre envíos. Si hay muchas notas pendientes, puede tardar.
Para problemas más complejos o detallados, consulta la guía completa de troubleshooting.
El sistema valida la posición GPS antes de crear notas:
- Sin GPS: Rechaza si no hay posición en cache
- GPS viejo (>60s): Rechaza con mensaje de error
- GPS aproximado (15-60s): Acepta pero marca como "posición aproximada"
- GPS reciente (≤15s): Acepta normalmente
El sistema evita crear notas duplicadas si coinciden:
- Mismo
node_idemisor - Texto normalizado idéntico
- Ubicación muy cercana (redondeada a 4 decimales ≈ 11m)
- Mismo bucket temporal de 120 segundos
El sistema usa SQLite para almacenar reportes localmente cuando no hay Internet, garantizando que ningún reporte se pierda. Los reportes pendientes se envían automáticamente cuando se restaura la conexión.
.
├── src/gateway/ # Código fuente principal
├── tests/ # Tests con pytest
├── scripts/ # Scripts de instalación y utilidades
│ ├── install_pi.sh # Instalación automática
│ └── detect_serial.sh # Detección de dispositivos seriales
├── systemd/ # Archivos systemd
├── docs/ # Documentación técnica
├── README.md # Este archivo
├── CONTRIBUTING.md # Guía de contribución
├── CHANGELOG.md # Historial de cambios
├── CITATION.cff # Información de citación
└── AUTHORS # Autores y contribuidores
# Instalar dependencias de desarrollo
pip install -e ".[dev]"
# Ejecutar tests
pytest
# Con cobertura
pytest --cov=gateway --cov-report=htmlEl proyecto incluye hooks de pre-commit para asegurar calidad de código:
# Instalar pre-commit
pip install pre-commit
# Instalar los hooks
pre-commit install
# Ejecutar manualmente en todos los archivos
pre-commit run --all-filesLos hooks verifican automáticamente:
- Formato de código (Black, Ruff)
- Linting (Ruff)
- Seguridad (Bandit)
- Validación de archivos (YAML, JSON, TOML)
- Detección de conflictos de merge