Diferència entre revisions de la pàgina «Recursos sobre The Things Network»

De The Things Network Catalunya Wiki
Jump to navigation Jump to search
(Donar-se d'alta a TheThingsNetwork.org)
m (Configurar un node (dispositu/sensor/mota))
 
(7 revisions intermèdies per 3 usuaris que no es mostren)
Línia 1: Línia 1:
Aquesta pàgina recull recursos online interessant sobre diferents aspectes relacionats amb The Things Network.
+
Aquesta pàgina recull recursos online sobre diferents aspectes relacionats amb The Things Network.
  
 
== Donar-se d'alta a TheThingsNetwork.org ==
 
== Donar-se d'alta a TheThingsNetwork.org ==
Línia 5: Línia 5:
 
* Introducció a la consola de The Things Network ([https://youtu.be/JrNjY-pGuno How To: The Things Network Console Introduction])
 
* Introducció a la consola de The Things Network ([https://youtu.be/JrNjY-pGuno How To: The Things Network Console Introduction])
  
== Configurar una pasarel·la (gateway) ==
+
== Configurar una passarel·la (gateway) ==
  
 
=== The Things Gateway ===
 
=== The Things Gateway ===
Línia 19: Línia 19:
 
=== Altres gateways ===
 
=== Altres gateways ===
  
== Configurar un node (dispositu/sensor/mota) ==
+
== Monitorització d'una passarel·la (gateway) ==
 +
 
 +
=== Amb Node-RED ===
 +
 
 +
Node-RED es un motor de fluxes especialment orientat a treballar amb IoT, que permet definir gràficament fluxes de serveis i que és compatible amb estàndards com REST, MQTT, Websocket, AMQP… a més, existeixen "nodes" de tercers que proporcionen integracions amb Twitter, Telegram, Pushover,... Està basat en NodeJS i té una interfície web. Pot executar-se en dispositus limitats com Raspberry o en allotjaments al núvol.
 +
 
 +
Aquest node et permet monitoritzar periòdicament les teves passarel·les i enviar una notificació a un chat de telegram quan es produeixi algun canvi d'estat.
 +
 
 +
https://flows.nodered.org/flow/c983777897c5b87f21a158fe5efc5e39
 +
 
 +
[[Fitxer:Ttn-gw-monitor-flow.png]]
 +
 
 +
=== Amb python ===
 +
 
 +
Amb la mateixa lògica que el fluxe anterior per Node-RED també poder consultar l'estat de les nostres passarel·les amb un senzill script python:
 +
 
 +
config.py
 +
 
 +
<pre>
 +
 
 +
# Gateways
 +
GATEWAYS = [
 +
    {'id':'eui-0000000000000001', 'name':'ttn-gw01',      'active':True},
 +
    {'id':'eui-0000000000000002', 'name':'ttn-gw02',      'active':True},
 +
]
 +
 
 +
# Mail notifications
 +
MAIL_ENABLED = False
 +
MAIL_SUBJECT = 'TTN GW Down'
 +
MAIL_FROM = 'user@server.com'
 +
MAIL_TO = 'user@server.com'
 +
</pre>
 +
 
 +
gw-monitor.py
 +
 
 +
<pre>
 +
 
 +
import sys
 +
 
 +
## API stuff
 +
import requests
 +
 
 +
## time, timestamp & epoch stuff
 +
import time
 +
import calendar
 +
from dateutil.parser import parse as date_parse
 +
 
 +
## mail stuff
 +
import smtplib
 +
from email.mime.text import MIMEText
 +
from email.mime.multipart import MIMEMultipart
 +
 
 +
## configuration
 +
import config
 +
 
 +
## colored output
 +
class bcolors:
 +
    HEADER = '\033[95m'
 +
    OKBLUE = '\033[94m'
 +
    OKGREEN = '\033[92m'
 +
    WARNING = '\033[93m'
 +
    FAIL = '\033[91m'
 +
    ENDC = '\033[0m'
 +
    BOLD = '\033[1m'
 +
    UNDERLINE = '\033[4m'
 +
 
 +
# Maximum ping time in seconds (3 minutes)
 +
MAX_PING_TIME = 180
 +
 
 +
text = "\n\nSome GW is down, please take some action\n"
 +
 
 +
# API URLs are like http://noc.thethingsnetwork.org:8085/api/v2/gateways/eui-fcc23dfffe0f306c
 +
url = 'http://noc.thethingsnetwork.org:8085/api/v2/gateways/'
 +
 
 +
def send_mail(text):
 +
 
 +
    print("Sending email alert:")
 +
    print(text)
 +
 
 +
    msg = MIMEMultipart('alternative')
 +
    msg.attach(MIMEText(text, 'plain'))
 +
    msg['Subject'] = config.MAIL_SUBJECT
 +
    msg['From'] = config.MAIL_FROM
 +
    msg['To'] = config.MAIL_TO
 +
    s = smtplib.SMTP('localhost')
 +
    s.sendmail(msg['From'], msg['To'] , msg.as_string())
 +
    s.quit()
 +
 
 +
# iterate over list of GWs
 +
for gw in config.GATEWAYS:
 +
    if gw['active']:
 +
        urlGW = url + gw['id']
 +
        resp = requests.get(url=urlGW)
 +
 
 +
        # If response code is OK (200) continue
 +
        if resp.status_code == 200:
 +
            data = resp.json()
 +
            dt = date_parse( data['timestamp'] )
 +
            epoch_gw = calendar.timegm(dt.timetuple())
 +
            epoch_now = calendar.timegm(time.gmtime())
 +
            delta_epoch = epoch_now - epoch_gw
 +
 
 +
            if delta_epoch > MAX_PING_TIME:
 +
                print gw['name'] + " is " + bcolors.FAIL + "OFFLINE" + bcolors.ENDC + " for " + format(int(delta_epoch / 3600)) + " hours"
 +
                text = text + gw['name'] + " is " + bcolors.FAIL + "OFFLINE" + bcolors.ENDC + " for " + format(int(delta_epoch / 3600)) + " hours"
 +
                text = text + "\n"
 +
                send_alert_email = True
 +
            else:
 +
                print gw['name'] + " is " + bcolors.OKGREEN + "ONLINE" + bcolors.ENDC
 +
        else:
 +
            print gw['name'] + bcolors.WARNING + " no status" + bcolors.ENDC
 +
 
 +
if config.MAIL_ENABLED:
 +
    send_mail(text)
 +
 
 +
sys.exit()
 +
</pre>
 +
 
 +
== Configurar un node (dispositiu/sensor/mota) ==
  
 
=== Modes d'activació ===
 
=== Modes d'activació ===
  
Les comunicacions a TTN estan encriptades amb dues claus: la '''clau de xarxa''' (network session key o NWKSKEY) i la '''clau d'aplicació''' (application session key o APPSKEY). El node ha de conèixer aquestes dues claus per poder enviar un missatge fins a lpalicatiu final. Aquestes dues claus les pot saber d'avantmà (per que les codifiquem en el nostre programa) o les pot obtenir d'un procés de negociació amb el backend.
+
Les comunicacions a TTN estan encriptades amb dues claus: la '''clau de xarxa''' (network session key o NWKSKEY) i la '''clau d'aplicació''' (application session key o APPSKEY). El node ha de conèixer aquestes dues claus per poder enviar un missatge fins a aplicatiu final. Aquestes dues claus les pot saber d'avantmà (per que les codifiquem en el nostre programa) o les pot obtenir d'un procés de negociació amb el backend.
  
Si les sap d'avantmà el node fa servir un sistema d'activació anomenat '''ABP (Activation By Personalisation)'''. És la forma més senzilla de connectar un node a la xarxa i també la més ràpida perquè no hi ha una comunicaciuó prèvia per negociar res. També, per tant, és la millor opció per estalviar energia. Per contra, en no haver comunicació prèvia, tampoc hi ha cap seguretat d'estar en una zona de cobertura sense fer ACKs. També, en cas que el codi o el node es perdin o es robin caldria reprogramar tota la resta de nodes de la mateixa aplicació per assegurar que ningú s'introdueix a la xarxa.
+
Si les sap d'avantmà el node fa servir un sistema d'activació anomenat '''ABP (Activation By Personalisation)'''. És la forma més senzilla de connectar un node a la xarxa i també la més ràpida perquè no hi ha una comunicació prèvia per negociar res. També, per tant, és la millor opció per estalviar energia. Per contra, en no haver comunicació prèvia, tampoc hi ha cap seguretat d'estar en una zona de cobertura sense fer ACKs. També, en cas que el codi o el node es perdin o es robin caldria reprogramar tota la resta de nodes de la mateixa aplicació per assegurar que ningú s'introdueix a la xarxa.
  
 
En el sistema '''OTAA (Over The Air Activation)''', el primer que fa el node és negociar amb el backend unes claus per la sessió. El node ha d'estar registrat prèviament al backend per que aquest validi que aquest té dret a connectar-se a la xarxa i li proporcioni unes claus exclusives per ell. És un sistema més complex i requereix d'un temps inicial per establir la comunicació, per contra és més segur ja que en cas de pèrdua només cal donar de baixa el node al backend.
 
En el sistema '''OTAA (Over The Air Activation)''', el primer que fa el node és negociar amb el backend unes claus per la sessió. El node ha d'estar registrat prèviament al backend per que aquest validi que aquest té dret a connectar-se a la xarxa i li proporcioni unes claus exclusives per ell. És un sistema més complex i requereix d'un temps inicial per establir la comunicació, per contra és més segur ja que en cas de pèrdua només cal donar de baixa el node al backend.
  
Com activar un The Thins Uno (https://youtu.be/kqI78zkhaFQ How To: The Things Uno Part 1 - Activation)
+
* Com activar un The Things Uno (https://youtu.be/kqI78zkhaFQ How To: The Things Uno Part 1 - Activation)
 +
* Com activar un The Things Node (https://youtu.be/tapK6EINx1k How To: The Things Node Activation)
  
 
== Integracions ==
 
== Integracions ==
Línia 35: Línia 154:
 
=== Persistir les dades a The Things Network ===
 
=== Persistir les dades a The Things Network ===
  
Com configurar la consola per que emmagatzemi les dades durant un màxim de 30 dies i com recuperar-les ([https://youtu.be/kVf8GmCbOuE How to: Storage integration])
+
* Com configurar la consola per que emmagatzemi les dades durant un màxim de 30 dies i com recuperar-les ([https://youtu.be/kVf8GmCbOuE How to: Storage integration])
  
 
=== Obtenir les dades via MQTT ===
 
=== Obtenir les dades via MQTT ===
 +
 +
==== Fent servir Mosquitto ====
 +
 +
Mosquitto és un broker MQTT open source que ve acompanyat d'una sèrie d'eines per publicar i subscriure's a missatges des de la línia de comandes.
 +
 +
<pre>
 +
# Bash mosquitto client for TTN
 +
# Uses mqsquitto_sub and jq:
 +
#
 +
# sudo apt install mosquitto-clients jq
 +
#
 +
 +
USER="test"
 +
PASS="ttn-account-v2.ALT..."
 +
 +
mosquitto_sub -h eu.thethings.network -u $USER -P $PASS -t "+/devices/+/up" | jq --unbuffered
 +
</pre>
 +
 +
==== Amb python ====
 +
 +
Aquest senzill script de python permet consultar les dades de qualsevol aplicació fent servir MQTT. Et caldrà configurar el ID de l'aplicatiu i una clau d'accés amb permissos per rebre els missatges.
 +
 +
<pre>
 +
# Simple Python client to show node activity from ttn MQTT brooker with credentials
 +
# Author: R.Schimmel
 +
# www.schimmel-bisolutions.nl
 +
#
 +
# pip install paho-mqtt
 +
 +
import sys
 +
import json
 +
from pygments import highlight, lexers, formatters
 +
import paho.mqtt.client as mqtt
 +
 +
# configuration
 +
app_id = "test"
 +
access_key = "ttn-account-v2.ALT..."
 +
 +
# callback functions
 +
def on_connect(client, userdata, flags, rc):
 +
    print("Subscribing...")
 +
    # subscribe for all devices of user
 +
    client.subscribe('+/devices/+/up')
 +
 +
def on_subscribe(client, userdata, mid, granted_qos):
 +
    print("Subscribed")
 +
 +
def on_message(client, userdata, msg):
 +
    formatted_json = json.dumps(json.loads(msg.payload), indent=4)
 +
    colorful_json = highlight(unicode(formatted_json, 'UTF-8'), lexers.JsonLexer(), formatters.TerminalFormatter())
 +
    print(colorful_json)
 +
 +
client = mqtt.Client()
 +
client.on_connect = on_connect
 +
client.on_message = on_message
 +
client.on_subscribe = on_subscribe
 +
client.username_pw_set(app_id, access_key)
 +
 +
print("Connecting...")
 +
client.connect("eu.thethings.network", 1883, 60)
 +
 +
# and listen to server
 +
client.loop_forever()
 +
</pre>
  
 
=== Integració amb Node-RED ===
 
=== Integració amb Node-RED ===
  
 
=== Integració amb IFTTT ===
 
=== Integració amb IFTTT ===

Revisió de 19:26, 21 gen 2020

Aquesta pàgina recull recursos online sobre diferents aspectes relacionats amb The Things Network.

Donar-se d'alta a TheThingsNetwork.org

Configurar una passarel·la (gateway)

The Things Gateway


NOTA: Si durant el procés d'activació la gateway es reseteja continuament comprova que el mòdul del concentrador (la placa allargada a propo de l'antena) està ben introduit al sòcol miniPCIe.

Altres gateways

Monitorització d'una passarel·la (gateway)

Amb Node-RED

Node-RED es un motor de fluxes especialment orientat a treballar amb IoT, que permet definir gràficament fluxes de serveis i que és compatible amb estàndards com REST, MQTT, Websocket, AMQP… a més, existeixen "nodes" de tercers que proporcionen integracions amb Twitter, Telegram, Pushover,... Està basat en NodeJS i té una interfície web. Pot executar-se en dispositus limitats com Raspberry o en allotjaments al núvol.

Aquest node et permet monitoritzar periòdicament les teves passarel·les i enviar una notificació a un chat de telegram quan es produeixi algun canvi d'estat.

https://flows.nodered.org/flow/c983777897c5b87f21a158fe5efc5e39

Ttn-gw-monitor-flow.png

Amb python

Amb la mateixa lògica que el fluxe anterior per Node-RED també poder consultar l'estat de les nostres passarel·les amb un senzill script python:

config.py


# Gateways
GATEWAYS = [
    {'id':'eui-0000000000000001', 'name':'ttn-gw01',       'active':True},
    {'id':'eui-0000000000000002', 'name':'ttn-gw02',       'active':True},
]

# Mail notifications
MAIL_ENABLED = False
MAIL_SUBJECT = 'TTN GW Down'
MAIL_FROM = 'user@server.com'
MAIL_TO = 'user@server.com'

gw-monitor.py


import sys

## API stuff
import requests

## time, timestamp & epoch stuff
import time
import calendar
from dateutil.parser import parse as date_parse

## mail stuff
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

## configuration
import config

## colored output
class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

# Maximum ping time in seconds (3 minutes)
MAX_PING_TIME = 180

text = "\n\nSome GW is down, please take some action\n"

# API URLs are like http://noc.thethingsnetwork.org:8085/api/v2/gateways/eui-fcc23dfffe0f306c
url = 'http://noc.thethingsnetwork.org:8085/api/v2/gateways/'

def send_mail(text):

    print("Sending email alert:")
    print(text)

    msg = MIMEMultipart('alternative')
    msg.attach(MIMEText(text, 'plain'))
    msg['Subject'] = config.MAIL_SUBJECT
    msg['From'] = config.MAIL_FROM
    msg['To'] = config.MAIL_TO
    s = smtplib.SMTP('localhost')
    s.sendmail(msg['From'], msg['To'] , msg.as_string())
    s.quit()

# iterate over list of GWs
for gw in config.GATEWAYS:
    if gw['active']:
        urlGW = url + gw['id']
        resp = requests.get(url=urlGW)

        # If response code is OK (200) continue
        if resp.status_code == 200:
            data = resp.json()
            dt = date_parse( data['timestamp'] )
            epoch_gw = calendar.timegm(dt.timetuple())
            epoch_now = calendar.timegm(time.gmtime())
            delta_epoch = epoch_now - epoch_gw

            if delta_epoch > MAX_PING_TIME:
                print gw['name'] + " is " + bcolors.FAIL + "OFFLINE" + bcolors.ENDC + " for " + format(int(delta_epoch / 3600)) + " hours"
                text = text + gw['name'] + " is " + bcolors.FAIL + "OFFLINE" + bcolors.ENDC + " for " + format(int(delta_epoch / 3600)) + " hours"
                text = text + "\n"
                send_alert_email = True
            else:
                print gw['name'] + " is " + bcolors.OKGREEN + "ONLINE" + bcolors.ENDC
        else:
            print gw['name'] + bcolors.WARNING + " no status" + bcolors.ENDC

if config.MAIL_ENABLED:
    send_mail(text)

sys.exit()

Configurar un node (dispositiu/sensor/mota)

Modes d'activació

Les comunicacions a TTN estan encriptades amb dues claus: la clau de xarxa (network session key o NWKSKEY) i la clau d'aplicació (application session key o APPSKEY). El node ha de conèixer aquestes dues claus per poder enviar un missatge fins a aplicatiu final. Aquestes dues claus les pot saber d'avantmà (per que les codifiquem en el nostre programa) o les pot obtenir d'un procés de negociació amb el backend.

Si les sap d'avantmà el node fa servir un sistema d'activació anomenat ABP (Activation By Personalisation). És la forma més senzilla de connectar un node a la xarxa i també la més ràpida perquè no hi ha una comunicació prèvia per negociar res. També, per tant, és la millor opció per estalviar energia. Per contra, en no haver comunicació prèvia, tampoc hi ha cap seguretat d'estar en una zona de cobertura sense fer ACKs. També, en cas que el codi o el node es perdin o es robin caldria reprogramar tota la resta de nodes de la mateixa aplicació per assegurar que ningú s'introdueix a la xarxa.

En el sistema OTAA (Over The Air Activation), el primer que fa el node és negociar amb el backend unes claus per la sessió. El node ha d'estar registrat prèviament al backend per que aquest validi que aquest té dret a connectar-se a la xarxa i li proporcioni unes claus exclusives per ell. És un sistema més complex i requereix d'un temps inicial per establir la comunicació, per contra és més segur ja que en cas de pèrdua només cal donar de baixa el node al backend.

Integracions

Persistir les dades a The Things Network

Obtenir les dades via MQTT

Fent servir Mosquitto

Mosquitto és un broker MQTT open source que ve acompanyat d'una sèrie d'eines per publicar i subscriure's a missatges des de la línia de comandes.

# Bash mosquitto client for TTN
# Uses mqsquitto_sub and jq:
#
# sudo apt install mosquitto-clients jq
#

USER="test"
PASS="ttn-account-v2.ALT..."

mosquitto_sub -h eu.thethings.network -u $USER -P $PASS -t "+/devices/+/up" | jq --unbuffered

Amb python

Aquest senzill script de python permet consultar les dades de qualsevol aplicació fent servir MQTT. Et caldrà configurar el ID de l'aplicatiu i una clau d'accés amb permissos per rebre els missatges.

# Simple Python client to show node activity from ttn MQTT brooker with credentials
# Author: R.Schimmel
# www.schimmel-bisolutions.nl
#
# pip install paho-mqtt

import sys
import json
from pygments import highlight, lexers, formatters
import paho.mqtt.client as mqtt

# configuration
app_id = "test"
access_key = "ttn-account-v2.ALT..."

# callback functions
def on_connect(client, userdata, flags, rc):
    print("Subscribing...")
    # subscribe for all devices of user
    client.subscribe('+/devices/+/up')

def on_subscribe(client, userdata, mid, granted_qos):
    print("Subscribed")

def on_message(client, userdata, msg):
    formatted_json = json.dumps(json.loads(msg.payload), indent=4)
    colorful_json = highlight(unicode(formatted_json, 'UTF-8'), lexers.JsonLexer(), formatters.TerminalFormatter())
    print(colorful_json)

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.on_subscribe = on_subscribe
client.username_pw_set(app_id, access_key)

print("Connecting...")
client.connect("eu.thethings.network", 1883, 60)

# and listen to server
client.loop_forever()

Integració amb Node-RED

Integració amb IFTTT