2016-05-03 8 views
3

MQTT Frage:Python MQTT Skript auf Raspberry Pi zum Senden und Empfangen von Nachrichten

Hallo, Ich versuche, ein MQTT Netzwerk zwischen mehrere Raspberry Pi (beginnend mit zwei) einzurichten. Ich habe einen Raspberry Pi (RPi-A), MQTT-Client, mit einem Thermistor-Sensor angeschlossen und eine Himbeere (RPi-B), MQTT-Broker/Client, als ein Hub für mein Netzwerk. Durch Python Scripting möchte ich die Temperatur alle 30 Minuten von RPi-A über MQTT zu Thema Sensor/Daten gesendet und von RPi-B erhalten. Wenn RPi-B eine Nachricht von RPi-A über Thema Sensor/Daten empfängt, möchte ich es mit einer Anweisung über MQTT Thema Sensor/Anweisungen zu RPi-A antworten. Unten ist mein Skript, bisher kann RPi-A Nachrichten senden und RPi-B kann sie empfangen, aber ich kann nicht herausfinden, wie RPi-B reagieren kann.

Im Grunde genommen versuche ich zu verstehen, ist es möglich, dass ein MQTT-Gerät gleichzeitig als Broker und als Client fungiert? Und, kann ein Client sowohl Nachrichten senden und empfangen und wenn ja, wie alle oben genannten über Python implementieren? Ich habe viele Blogs, offizielle MQTT-Artikel und die Dokumentation des Paho-Moduls gelesen (was für mich sehr schwer zu ergründen ist), kann das aber immer noch nicht herausfinden. Ihre Hilfe wäre am nützlichsten/geschätzt.

-Code RPi-A (mit Thermistorsensor):

from sense_hat import SenseHat 
import time 
import paho.mqtt.client as mqtt 
import paho.mqtt.publish as publish 
sense = SenseHat() 

Broker = "192.168.1.252" 

sub_topic = "sensor/instructions" # receive messages on this topic 

pub_topic = "sensor/data"  # send messages to this topic 


############### sensehat inputs ################## 

def read_temp(): 
    t = sense.get_temperature() 
    t = round(t) 
    return t 

def read_humidity(): 
    h = sense.get_humidity() 
    h = round(h) 
    return h 

def read_pressure(): 
    p = sense.get_pressure() 
    p = round(p) 
    return p 

def display_sensehat(message): 
    sense.show_message(message) 
    time.sleep(10) 

############### MQTT section ################## 

# when connecting to mqtt do this; 

def on_connect(client, userdata, flags, rc): 
    print("Connected with result code "+str(rc)) 
    client.subscribe(sub_topic) 

# when receiving a mqtt message do this; 

def on_message(client, userdata, msg): 
    message = str(msg.payload) 
    print(msg.topic+" "+message) 
    display_sensehat(message) 

def publish_mqtt(sensor_data): 
    mqttc = mqtt.Client("python_pub") 
    mqttc.connect(Broker, 1883) 
    mqttc.publish(pub_topic, sensor_data) 
    #mqttc.loop(2) //timeout = 2s 

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


client = mqtt.Client() 
client.on_connect = on_connect 
client.on_message = on_message 
client.connect(Broker, 1883, 60) 


while True: 
    sensor_data = [read_temp(), read_humidity(), read_pressure()] 
    publish.single("monto/solar/sensors", str(sensor_data), hostname = Broker) 
    time.sleep(1*60) 

-Code RPi-B (Netzwerkhub):

import time 
import paho.mqtt.client as mqtt 
import paho.mqtt.publish as publish 

Broker = "192.168.1.252" 

sub_topic = "sensor/data" # receive messages on this topic 

pub_topic = "sensor/instructions"    # send messages to this topic 


# mqtt section 

# when connecting to mqtt do this; 

def on_connect(client, userdata, flags, rc): 
    print("Connected with result code "+str(rc)) 
    client.subscribe(sub_topic) 

# when receiving a mqtt message do this; 

def on_message(client, userdata, msg): 
    message = str(msg.payload) 
    print(msg.topic+" "+message) 
    publish_mqtt(‘got your message’) 

# to send a message 

def publish_mqtt(sensor_data): 
    mqttc = mqtt.Client("monto_hub") 
    mqttc.connect(Broker, 1883) 
    mqttc.publish(pub_topic, "this is the master speaking") 
    #mqttc.loop(2) //timeout = 2s 

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


client = mqtt.Client() 
client.on_connect = on_connect 
client.on_message = on_message 
client.connect(Broker, 1883, 60) 
client.loop_forever() 
+0

Welchen tatsächlichen Fehler sehen Sie? Der Code sieht ungefähr richtig aus (RPI-A benötigt keinen MQTT-Client-Code vor der Schleife, da Sie 'publish.single' verwenden) und der RPI-B-Code sieht auf den ersten Blick gut aus. – hardillb

+0

@hardillb danke für die Antwort, ich will RPi-A zu empfangen mqtt Nachrichten von RPi-B sowie senden sie, so dass ich dachte, ich würde den Client-mqtt-Code benötigen. Ich bekomme per se keinen Fehler, aber RPi-B scheint keine Nachrichten als Reaktion auf RPi-A zu senden. –

+0

Sorry verpasste das bisschen. Antwort zur Verfügung gestellt – hardillb

Antwort

5

Der einfachste Weg ist es, die Netzwerkschleife in einem separaten Thread zu starten Verwenden Sie die client.loop_start()-Funktion, dann verwenden Sie die normale client.publish Methode

from sense_hat import SenseHat 
import time 
import paho.mqtt.client as mqtt 
import paho.mqtt.publish as publish 
sense = SenseHat() 

Broker = "192.168.1.252" 

sub_topic = "sensor/instructions" # receive messages on this topic 

pub_topic = "sensor/data"  # send messages to this topic 


############### sensehat inputs ################## 

def read_temp(): 
    t = sense.get_temperature() 
    t = round(t) 
    return t 

def read_humidity(): 
    h = sense.get_humidity() 
    h = round(h) 
    return h 

def read_pressure(): 
    p = sense.get_pressure() 
    p = round(p) 
    return p 

def display_sensehat(message): 
    sense.show_message(message) 
    time.sleep(10) 

############### MQTT section ################## 

# when connecting to mqtt do this; 

def on_connect(client, userdata, flags, rc): 
    print("Connected with result code "+str(rc)) 
    client.subscribe(sub_topic) 

# when receiving a mqtt message do this; 

def on_message(client, userdata, msg): 
    message = str(msg.payload) 
    print(msg.topic+" "+message) 
    display_sensehat(message) 

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


client = mqtt.Client() 
client.on_connect = on_connect 
client.on_message = on_message 
client.connect(Broker, 1883, 60) 
client.loop_start() 

while True: 
    sensor_data = [read_temp(), read_humidity(), read_pressure()] 
    client.publish("monto/solar/sensors", str(sensor_data)) 
    time.sleep(1*60) 
+0

Super Zeug, das funktionierte ein Vergnügen :) vielen Dank.
Sollte ich die client.loop_forever() auch auf RPi-B verwenden oder sollte ich sie durch client.loop_start() ersetzen? –

+0

Lass es so wie es ist, für diesen Anwendungsfall ist es korrekt – hardillb

Verwandte Themen