-
Notifications
You must be signed in to change notification settings - Fork 0
/
meshtastic-mqtt.py
executable file
·111 lines (91 loc) · 4.26 KB
/
meshtastic-mqtt.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# python3.6
import meshtastic_mqtt.portnums_pb2 as portnums_pb2
from portnums_pb2 import ENVIRONMENTAL_MEASUREMENT_APP, POSITION_APP
import random
import json
import mesh_pb2 as mesh_pb2
import mqtt_pb2 as mqtt_pb2
import environmental_measurement_pb2
from paho.mqtt import client as mqtt_client
import requests
import hassapi as hass
class MeshtasticMQTT(hass.Hass):
#MQTT Broker details:
broker = '10.147.253.250'
port = 1883
topic = "msh/1/c/#"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 100)}'
username = 'user'
password = 'pass'
traccarHost = '10.147.253.250'
def connect_mqtt(self) -> mqtt_client:
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt_client.Client(self.client_id)
client.username_pw_set(self.username, self.password)
client.on_connect = on_connect
client.connect(self.broker, self.port)
return client
def subscribe(self, client: mqtt_client):
def on_message(client, userdata, msg):
#print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
se = mqtt_pb2.ServiceEnvelope()
se.ParseFromString(msg.payload)
print(se)
mp = se.packet
if mp.decoded.portnum == POSITION_APP:
pos = mesh_pb2.Position()
pos.ParseFromString(mp.decoded.payload)
print(getattr(mp, "from"))
print(pos)
owntracks_payload = {
"_type": "location",
"lat": pos.latitude_i * 1e-7,
"lon": pos.longitude_i * 1e-7,
"tst": pos.time,
"batt": pos.battery_level,
"alt": pos.altitude
}
if owntracks_payload["lat"] != 0 and owntracks_payload["lon"] != 0:
#client.publish("owntracks/"+str(getattr(mp, "from"))+"/meshtastic_node", json.dumps(owntracks_payload))
if len(self.traccarHost) > 0:
traccarURL = "http://"+self.traccarHost+":5055?id="+str(getattr(mp, "from"))+"&lat="+str(pos.latitude_i * 1e-7)+"&lon="+str(pos.longitude_i * 1e-7)+"&altitude="+str(pos.altitude)+"&battery_level="+str(pos.battery_level)+"&hdop="+str(pos.PDOP)+"&accuracy="+str(pos.PDOP*0.03)
print(traccarURL)
submitted = requests.get(traccarURL)
print(submitted)
#lets also publish the battery directly
if pos.battery_level > 0:
client.publish("meshtastic/"+str(getattr(mp, "from"))+"/battery", pos.battery_level)
elif mp.decoded.portnum == ENVIRONMENTAL_MEASUREMENT_APP:
env = environmental_measurement_pb2.EnvironmentalMeasurement()
env.ParseFromString(mp.decoded.payload)
print(env)
client.publish("meshtastic/"+str(getattr(mp, "from"))+"/temperature", env.temperature)
client.publish("meshtastic/"+str(getattr(mp, "from"))+"/relative_humidity", env.relative_humidity)
elif mp.decoded.portnum == portnums_pb2.NODEINFO_APP:
info = mesh_pb2.User()
info.ParseFromString(mp.decoded.payload)
#print(MessageToJson(info))
client.publish("meshtastic/"+str(getattr(mp, "from"))+"/user", MessageToJson(info))
elif mp.decoded.portnum == portnums_pb2.TEXT_MESSAGE_APP:
text = {
"message": mp.decoded.payload.decode("utf-8"),
"from": getattr(mp, "from"),
"to": mp.to
}
client.publish("meshtastic/"+str(getattr(mp, "from"))+"/text_message", json.dumps(text))
client.subscribe(self.topic)
client.on_message = on_message
def run(self):
client = self.connect_mqtt()
self.subscribe(client)
client.loop_forever()
def initialize(self):
self.run()
#if __name__ == '__main__':
# mm = MeshtasticMQTT()
# mm.run()