ttn_fetch.py

Arduino MKR WAN 1310 · Archivo : ttn_fetch.py · Lenguaje : Python · Uso : Récupérer les uplinks LoRaWAN depuis l'API TTN

En el lado servidor, este script Python consulta la API de The Things Network v3 para recuperar los últimos uplinks de una MKR WAN 1310: marca de tiempo, RSSI visto por la pasarela y carga base64. El ladrillo base de un panel o una alerta por correo.

Hardware

Una Arduino MKR WAN 1310 (microcontrolador SAMD21, módem LoRa pilotado por un ESP32 integrado que también expone Wi-Fi, antena LoRa y antena Wi-Fi). Una cuenta TTN, una aplicación con dispositivo unido, un token API (CLI ttn-lvc o clave de integración).

Cableado

Ninguno; la placa ni siquiera hace falta para probar: usa uplinks ya recibidos.

Funcionamiento

GET /as/applications/{app}/devices/{dev}/uplinks devuelve tramas descifradas por el servidor. El campo frm_payload va en base64: decodifícalo con base64.b64decode para recuperar tus bytes.

Ejecución

Instala Arduino SAMD Boards y la librería MKRWAN 2.x (MKRWAN1310), selecciona la placa y carga. La 1310 se controla con comandos AT a través de su ESP32 interno; para LoRa, prevé una segunda placa LoRa al otro lado.

Variantes

Pásate a MQTT (mqtt.ttn.cloud) para tiempo real sin sondeo o programa el script con cron para un archivo diario.

ttn_fetch.py

#!/usr/bin/env python3
"""Uplinks TTN v3 d'une application via l'API HTTP.

Usage : TTN_TOKEN=xxx python ttn_fetch.py [app] [device]
Le token doit etre une cle d'integration "Link API".
"""
import os
import sys

import requests

BASE = "https://eu1.cloud.thethings.network/api/v3"
APP = sys.argv[1] if len(sys.argv) > 1 else "mon-app"
DEV = sys.argv[2] if len(sys.argv) > 2 else "mon-device"
HEADERS = {"Authorization": f"Bearer {os.environ['TTN_TOKEN']}"}


def principal() -> None:
    url = f"{BASE}/as/applications/{APP}/devices/{DEV}/uplinks"
    r = requests.get(url, params={"limit": 10, "order": "DESC"},
                     headers=HEADERS, timeout=15)
    r.raise_for_status()
    for up in reversed(r.json().get("uplinks", [])):
        t = up.get("received_at", "?")[:19]
        meta = up.get("received_at_metadata", {})
        rssi = meta.get("lorawan_metadata", {}).get(
            "received_signal_strength", "?")
        print(f"{t} rssi={rssi} b64={up.get('frm_payload', '')}")


if __name__ == "__main__":
    principal()

← Volver a la ficha