1 contributor
#!/usr/bin/python3
import time
import csv2geojs
import json
import paho.mqtt.client as mqtt
MAXLRR=4
filename="mqttGeo.csv"
#filenameStatus="mqttGeo.html"
filenameBase="mqttGeo"
def htmlLatest(deveui,subID,FCnt,timeLatest,lat,lon,err,rssi):
htmlOutput="<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n"
htmlOutput+="<html>\n"
htmlOutput+="<head>\n"
htmlOutput+=" <title>mqttGeo Latest</title>\n"
htmlOutput+=" <meta charset=\"utf-8\" />\n"
htmlOutput+=" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"
htmlOutput+=" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n"
htmlOutput+=csv2geojs.networkSurveyAddLeaflet()
htmlOutput+="<style>\n"
htmlOutput+="html {\n"
htmlOutput+=" font-family: \"Lucida Sans\", sans-serif; text-align: center;\n"
htmlOutput+="}\n"
htmlOutput+="#deveui { font-size: 1.4em; }\n"
htmlOutput+="#fcnt { font-size: 1.8em; }\n"
htmlOutput+="#time { font-size: 1.4em; }\n"
htmlOutput+="#position { display: inline-block; font-size: 1.5em; }\n"
htmlOutput+="#rssi { font-size: 1.2em; }\n"
htmlOutput+="button {\n"
htmlOutput+=" position: relative;\n"
htmlOutput+=" width: 300px;\n"
htmlOutput+=" height: 40px;\n"
htmlOutput+=" margin: 10px auto;\n"
htmlOutput+=" padding: 0;\n"
htmlOutput+=" font-size: 22px;\n"
htmlOutput+=" text-align: center;\n"
htmlOutput+=" color: white;\n"
htmlOutput+=" border: none;\n"
htmlOutput+=" outline: none;\n"
htmlOutput+=" cursor: pointer;\n"
htmlOutput+=" overflow: hidden;\n"
htmlOutput+=" text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);\n"
htmlOutput+=" transition: transform 0.4s ease-in-out;\n"
htmlOutput+="}\n"
htmlOutput+=".btn-green {\n"
htmlOutput+=" background: #1abc9c;\n"
htmlOutput+=" border-bottom: 2px solid #12ab8d;\n"
htmlOutput+=" box-shadow: inset 0 -2px #12ab8d;\n"
htmlOutput+="}\n"
htmlOutput+="</style>\n"
htmlOutput+="<script type=\"text/javascript\">\n"
htmlOutput+="setTimeout(function(){\n"
htmlOutput+=" location = ''\n"
htmlOutput+="},1200000);\n"
htmlOutput+="</script>\n"
htmlOutput+="<body>\n"
htmlOutput+="<h2>mqttGeo Latest</h2>\n"
htmlOutput+=" <div id=\"mapid\" style=\"width: 95%; max-width: 400px; height: 200px; margin: auto\"></div>\n"
if 0 != lat and 0 != lon:
xmin=0.999999*lon
xmax=1.000001*lon
ymin=0.999999*lat
ymax=1.000001*lat
htmlOutput+="<script>\n"
zoomValue=19
circleOpacity=0.2
color=csv2geojs.networkSurveyColor(rssi)
if err < 3:
err=3
htmlOutput+=" var mymap = L.map('mapid').setView(["+str(lat)+", "+str(lon)+"], "+str(zoomValue)+");\n"
htmlOutput+="\n"
htmlOutput+=" L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token="+csv2geojs.networkSurveySetMapboxApiToken()+"', {\n"
htmlOutput+=" maxZoom: 20,\n"
htmlOutput+=" attribution: 'Map data © <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors, ' +\n"
htmlOutput+=" 'Imagery © <a href=\"https://www.mapbox.com/\">Mapbox</a>',\n"
htmlOutput+=" id: 'mapbox/streets-v11',\n"
htmlOutput+=" tileSize: 512,\n"
htmlOutput+=" zoomOffset: -1\n"
htmlOutput+=" }).addTo(mymap);\n"
htmlOutput+=" L.circle(["+str(lat)+","+str(lon)+"],{color: '"+color+"', fillcolor: '"+color+"', fillOpacity: "+str(circleOpacity)+", radius:"+str(err)+"}).addTo(mymap);\n"
htmlOutput+="</script>\n"
htmlOutput+="<p>\n"
htmlOutput+="<div id=\"deveui\">"+deveui+"</div>\n"
htmlOutput+="<div id=\"fcnt\">"+str(FCnt)+"</div>\n"
htmlOutput+="<div id=\"time\">"+timeLatest+"</div>\n"
htmlOutput+="<div id=\"position\">"+str(lat)+" "+str(lon)+" "+str(err)+"</div>\n"
htmlOutput+="<div id=\"rssi\">"+str(rssi)+"</div>\n"
htmlOutput+="</p>\n"
htmlOutput+="<p>\n"
htmlOutput+="<div id=\"reload\"><button class=\"btn-green\" onClick=\"window.location.reload();\">Reload</div>\n"
htmlOutput+="</p>\n"
htmlOutput+="</body>\n"
htmlOutput+="</html>\n"
filenameStatus=filenameBase+"-"+subID+".html"
with open(filenameStatus,"w") as f2:
f2.write(htmlOutput+"\n")
f2.close
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
client.subscribe("geoloc/#")
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
json_data=str(msg.payload.decode('ASCII'))
parseTopic=msg.topic.split('/')
if "uplink" in msg.topic:
csvLine=""
#print("Uplink received for SubID: "+parseTopic[1]+" and DevEUI: "+parseTopic[3])
try:
parsed=json.loads(json_data)
pattern = '%Y-%m-%dT%H:%M:%S.%f%z'
epoch = int(time.mktime(time.strptime(parsed['DevEUI_uplink']['Time'], pattern)))
FCnt=parsed['DevEUI_uplink']['FCntUp']
csvLine+=parseTopic[1]+","+parseTopic[3]+","+parsed['DevEUI_uplink']['Time']+","+str(epoch)+","+str(FCnt)
print("Uplink received for SubID: "+parseTopic[1]+" and DevEUI: "+parseTopic[3]+" Fcnt: "+str(FCnt))
except:
print("Uh ho")
lat=0
lon=0
err=0
if parsed['DevEUI_uplink']['payload'] is not None:
if parsed['DevEUI_uplink']['payload']['messageType'] == "POSITION_MESSAGE":
try:
lat=parsed['DevEUI_uplink']['payload']['gpsLatitude']
lon=parsed['DevEUI_uplink']['payload']['gpsLongitude']
err=parsed['DevEUI_uplink']['payload']['horizontalAccuracy']
except:
print("[WARN] GPS Timeout")
else:
print("[WARN] Not a position message:"+parsed['DevEUI_uplink']['payload']['messageType'])
else:
print("[WARN] No decoded payload")
csvLine+=","+str(lat)+","+str(lon)+","+str(err)
#print(csvLine)
# Append GW details
#parsed['DevEUI_uplink']['Lrrs']['Lrr']
#Lrrid
#LrrRSSI
#LrrSNR
count=0
rssi=100
for lrr in parsed['DevEUI_uplink']['Lrrs']['Lrr']:
count+=1
#print(lrr['Lrrid'])
if rssi == 100:
rssi=lrr['LrrRSSI']
csvLine+=","+lrr['Lrrid']+","+str(lrr['LrrRSSI'])+","+str(lrr['LrrSNR'])
i = 0
for i in range(count,MAXLRR):
csvLine+=",,,"
# Appending only if position is different from 0,0
if 0 != lat and 0 != lon:
with open(filename,'a+') as f:
f.write(csvLine+"\n")
f.close()
htmlLatest(parseTopic[3],parseTopic[1],FCnt,parsed['DevEUI_uplink']['Time'],lat,lon,err,rssi)
csv2geojs.networkSurvey(filename,parseTopic[1])
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
broker_address="192.168.1.33"
user="esp8266"
password="NjWxXrEMnOeaNtv8b40u"
port=1883
try:
client.username_pw_set(user, password=password)
except:
print("[FAILED]MQTT Set")
try:
client.connect(broker_address, port, 60)
except:
print("[FAILED]MQTT connect")
client.loop_forever()