meshtastic-mqtt
meshtastic-mqtt copied to clipboard
Detailed instructions for Home Assistant
Hi, Could you give some more precise instructions on how to use this with Home Assistant (and AppDaemon). Do all the scripts need to be in AppDaemon or only the main meshtastic-mqtt.py? What to put in apps.yaml? What exactly does "on appdaemon remove the argument here" mean ? How do you get a device/entities that you can interact with in Home Assistant ?
All Ive been using app daemon for is a place to leave this script running. It doesn't actually interact with home assistant at all. I'd love to make a proper integration for home assistant sometime, that would probably use this script as a major component
Here's what my apps folder looks like. This repo has diverged from the script I've got in there at the moment, I might have a look to see if there's a way to run a script from pip in home assistant somehow.

Hi, I put this files in appdaemon but how can runit ?
Edit the meshtastic_mqtt.py script, and import the hassapi stuff and change the class definition:
#uncomment for AppDaemon
import hassapi as hass
#swap for AppDaemon
class MeshtasticMQTT(hass.Hass=None):
#class MeshtasticMQTT():
Then down the bottom comment out this bit:
#in appdaemon comment this block out
#if __name__ == '__main__':
# main()
Finally, restart AppDaemon and watch the Log tab as it starts up, you should eventually see a message saying meshtastic-mqtt has started:
2022-02-18 19:52:38.561113 INFO AppDaemon: Initializing app meshtastic-mqtt using class MeshtasticMQTT from module meshtastic-mqtt
Looks promising
I have to do something else ?
EDIT THIS IS WRONG... SE BELOW
Oops yea you need to add this to apps.yaml:
meshtastic-mqtt:
module: "meshtastic-mqtt"
class: MeshtasticMQTT
I got that wrong. Sorry the version mismatch has me behind a little. Your apps.yaml should be
meshtastic_mqtt:
module: "meshtastic_mqtt"
class: MeshtasticMQTT
Getting there! Remove the =None
so the class definition looks like
class MeshtasticMQTT(hass.Hass):
Aright...
Ok I really need to do some work here I guess. Below is my entire script that is running on my AppDaemon. It's a bit different to what is in this repo but it is working on my one:
# python3.6
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):
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 = 'emqx'
# password = 'public'
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("user", "pass")
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("/mesh/"+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("/mesh/"+str(getattr(mp, "from"))+"/temperature", env.temperature)
client.publish("/mesh/"+str(getattr(mp, "from"))+"/relative_humidity", env.relative_humidity)
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()
I had to uncomment mqtt password
Oh yea the protobufs have changed too.. I will create a seperate repo for this and push up my current working files. Its diverged too much. Stand by...
https://github.com/joshpirihi/meshtastic-mqtt-appdaemon
Great work!
Still need some tweaks
That's working! You can ignore all the warnings there, it's just ignoring the protobufs as it should. If you connect a node to your mqtt you should now get some data out of it
Where should it appear ?
it should create a meshtastic/ topic tree. What do you see on the AppDaemon Log tab now? Is the broker and username and password set properly?
I've just tweaked the main script on the repo to make the mqtt credentials a bit easier to set, they were hard coded.
In config of username and password username said "usename"
Should be fixed now
Does your mqtt broker require credentials? If it doesn't, you'll need to comment out the line client.username_pw_set()
Yes my mqtt require credentials.
Yeah, same error...
I have these packages installed
What does your whole script look like? Are you defining username
and password
? It looks like it may be an issue with them
This script?
Ohh sorry man my python is not great. Change the username_pw_set to
client.username_pw_set(self.username, self.password)
Success! connected to the mqtt but still not decode the message.
As packets are published by your gateway node, meshtastic-mqtt will translate them. That Log page should start showing some traffic if the mqtt is connected up properly