Save data in a file with Python API

Hello,
I’m trying to write a python program that saves the data that I acquire from the things network in a text file. This is my code (very similar to https://www.thethingsnetwork.org/docs/applications/python/).

import time
import ttn

app_id = "foo"
access_key = "ttn-account.eiP<redacted>Zzg"

def uplink_callback(msg, client):
  print("Received uplink from ", msg.dev_id)
  save_file()
  print(msg)


def save_file():
    #Code to save a text file

handler = ttn.HandlerClient(app_id, access_key)

# using mqtt client
mqtt_client = handler.data()
mqtt_client.set_uplink_callback(uplink_callback)
try:
    while 1:
        time.sleep(1)
except KeyboardInterrupt:
    print("Programm closed.")
    mqtt_client.close()
except:
    print("Error.")
    mqtt_client.close()

I would create a function (save_file) that saves the information of msg in a file. Now the programm print on screen this information

Received uplink from stm32-b-l072z-lrwan1

MSG(app_id=‘test-application-for-st-lora-nodes’, dev_id=‘stm32-b-l072z-lrwan1’, hardware_serial=‘3435313160379011’, port=2, counter=131, confirmed=True, payload_raw=‘AAD4APg=’, metadata=MSG(time=‘2020-05-29T10:23:05.019674139Z’, frequency=868.3, modulation=‘LORA’, data_rate=‘SF7BW125’, airtime=51456000, coding_rate=‘4/5’, gateways=[MSG(gtw_id=‘eui-0080e1ffff015232’, timestamp=1749644820, time=’’, channel=6, rssi=-57, snr=8.8, rf_chain=0)]))

I need in the file the time, the dev_id and the payload (even if is different from payload that I see on the things network)

image

The TTN implementation has been left behind / deprecated.

paho-mqtt · PyPI seems to be the client of choice now.

As examples found here and there are most of the time bullshit or not working directly without heavy re-coding, I give you a real working code that I use for my lora tracker.
Combined with a website which read the json file generated by this python script, I obtain this:
image


# https://www.thethingsnetwork.org/forum/t/a-python-program-to-listen-to-your-devices-with-mqtt/9036/6
# Get data from MQTT server
# Run this with python 3, install paho.mqtt prior to use

import paho.mqtt.client as mqtt
import json
import base64
from haversine import haversine
from geojson import Feature, Point, dump

APPEUI = "zzzzzzzzzzz73"
APPID  = "yyyyyyyyyyyyt"
PSW    = 'ttn-account-vxxxxxxxxxxxxxxOppFc'

#Call back functions

# gives connection message
def on_connect(mqttc, mosq, obj,rc):
    print("Connected with result code:"+str(rc))
    # subscribe for all devices of user
    mqttc.subscribe('+/devices/+/up')

# gives message from device
def on_message(mqttc,obj,msg):
    try:
        #print(msg.payload)
        x = json.loads(msg.payload.decode('utf-8'))
        device = x["dev_id"]
        counter = x["counter"]
        payload_raw = x["payload_raw"]
        payload_fields = x["payload_fields"]
        datetime = x["metadata"]["time"]
        gateways = x["metadata"]["gateways"]
        SF = x["metadata"]["data_rate"]
        y =  json.dumps(payload_fields)
        y_dict = json.loads(y)
        latitude = y_dict["latitude"]
        longitude = y_dict["longitude"]
        dist = round( (haversine((++encode lontitude here++,--encode your latiturde here ---),(longitude,latitude))),3)
        
        for gw in gateways:
            gateway_id = gw["gtw_id"]
            rssi = gw["rssi"]
            snr =  gw["snr"]
            
        #print(datetime + ", " + device + ", " + str(counter) + ", "+ gateway_id + ", "+ str(rssi) + ", " + str(snr) + ", "+ str(payload_fields))
        print(datetime + ", " + gateway_id + ", "+ str(rssi) + ", " + str(snr) + ", "+ str(SF)+ ", "+ str(round(latitude,6)) + ", "+ str(round(longitude,6)) + ", " + str(dist))
        my_point = Point((longitude,latitude))
        my_feature = json.dumps(Feature(geometry=my_point, properties= {"datetime": str(datetime),"gateway_id": str (gateway_id),"rssi": str (rssi),"snr": str (snr),"SF": str (SF),"dist": str (dist)}))
        print (my_feature)
        with open("track.geojson","a") as outfile:
            outfile.write (my_feature + '\n')
        outfile.close()
    except Exception as e:
        print(e)
        pass

def on_publish(mosq, obj, mid):
    print("mid: " + str(mid))

def on_subscribe(mosq, obj, mid, granted_qos):
    print("Subscribed: " + str(mid) + " " + str(granted_qos))

def on_log(mqttc,obj,level,buf):
    print("message:" + str(buf))
    print("userdata:" + str(obj))

mqttc= mqtt.Client()
# Assign event callbacks
mqttc.on_connect=on_connect
mqttc.on_message=on_message

mqttc.username_pw_set(APPID, PSW)
mqttc.connect("eu.thethings.network",1883,60)

# and listen to server
run = True
while run:
    mqttc.loop()
1 Like

updated version for v3

# https://www.thethingsnetwork.org/forum/t/a-python-program-to-listen-to-your-devices-with-mqtt/9036/6
# Get data from MQTT server
# Run this with python 3,6
# install paho.mqtt prior to use

import paho.mqtt.client as mqtt
import json
import base64
import os
from datetime import datetime as dt
from haversine import haversine
from geojson import Feature, Point, dump

longitudep = 0
latitudep = 0
timep = dt.now()

APPEUI = "eui-0000000000000000"
APPID  = "dynamitron@ttn"
PSW    = "NNSXS.DWR5MSJB3WMQEYFZRURSJMYJCD6YEI.X62QC2GUUYMZV4K6R5KDDYDXC6E5ZRLJE6SZKG7VZXQE6GQKYZ5A"

#Call back functions

# gives connection message
def on_connect(mqttc, mosq, obj,rc):
    print("Connected with result code:"+str(rc))
    mqttc.subscribe('v3/+/devices/+/up')                # subscribe for all devices of user


def on_message(mqttc,obj,msg):                          # analyse message when it pops up from device
    try:
        x = json.loads(msg.payload.decode('utf-8'))     # x is a dictionnary
        uplink = x["uplink_message"]
        datetime = uplink["rx_metadata"][0]["time"]
        datetime = datetime.replace ("T","@")
        datetime = datetime[0:19]
        gateway_id = uplink["rx_metadata"][0]["gateway_ids"]["gateway_id"]       
        rssi = uplink["rx_metadata"][0]["rssi"]
        snr = uplink["rx_metadata"][0]["snr"]
        SF = uplink["settings"]["data_rate"]["lora"]["spreading_factor"]
        latitude= uplink["decoded_payload"]["latitude"]
        longitude= uplink["decoded_payload"]["longitude"]
        dist = round((haversine((50.026525,4.044700),(latitude,longitude,))),3)  
        
        global longitudep
        global latitudep
        global timep       
             
        distp = round((haversine((latitudep,longitudep),(latitude,longitude))),3)
        time_delta = dt.now()-timep
        speed = distp /((time_delta.total_seconds())/3600)
        
        longitudep = longitude
        latitudep = latitude
        timep = dt.now()       

        my_point = Point((longitude,latitude))
        my_feature = json.dumps(Feature(geometry=my_point, properties= {"datetime": str(datetime),"gateway_id": str (gateway_id),"rssi": str (rssi),"snr": str (snr),"SF": str (SF),"dist": str (dist),"speed":str (round(speed,1))}))

        if ((latitude!=0) and (longitude!=0) and (distp>0.015)):
            with open("track.geojson","a") as outfile:
                outfile.write (my_feature + '\n')
            outfile.close()
        file_size = os.path.getsize(r'track.geojson')

        #if (file_size > 10240):
        #   os.system("sed -i '1d' track.geojson")


        #print(msg.payload)
        #print (uplink)
        print (datetime)
        print(gateway_id) 
        print(rssi)  
        print(snr) 
        print(SF) 
        print(latitude) 
        print(longitude)         
        print (dist)
        print (speed)
        #print (my_feature)
        print ("file size:",file_size,"bytes")
        print ("------------------------------------")
        
    except Exception as e:
        print(e)
        pass

def on_publish(mosq, obj, mid):
    print("mid: " + str(mid))

def on_subscribe(mosq, obj, mid, granted_qos):
    print("Subscribed: " + str(mid) + " " + str(granted_qos))

def on_log(mqttc,obj,level,buf):
    print("message:" + str(buf))
    print("userdata:" + str(obj))

mqttc= mqtt.Client()
# Assign event callbacks
mqttc.on_connect=on_connect
mqttc.on_message=on_message

mqttc.username_pw_set(APPID, PSW)
mqttc.connect("eu1.cloud.thethings.network",1883,60)

# listen to server
run = True
while run:
    mqttc.loop()

1 Like