2016-05-03 3 views
3

MQTT вопрос:питон MQTT скрипт на Raspberry Pi отправлять и получать сообщения

Привет, Я пытаюсь создать MQTT сеть между несколькими малина Pis (начиная с двух). У меня есть один малиновый pi (RPi-A), клиент MQTT, с прикрепленным датчиком термистора и одной малиной (RPi-B), брокером/клиентом MQTT, выступающей в качестве концентратора для моей сети. С помощью сценариев python я бы хотел, чтобы температуру отправляли каждые 30 минут от RPi-A через MQTT до темы датчика/данных и получали RPi-B. Когда RPi-B получает сообщение от RPi-A через датчик тем или данных, я хочу, чтобы он ответил инструкцией с помощью датчика/инструкций темы MQTT на RPi-A. Ниже мой сценарий, пока RPi-A может отправлять сообщения, а RPi-B получает их, но я не могу понять, как RPi-B может ответить.

В принципе, я пытаюсь понять, возможно ли, чтобы устройство MQTT одновременно выступало как брокером, так и клиентом? И может ли клиент отправлять и получать сообщения, и если да, то как реализовать все вышеперечисленное с помощью python? Я читал много блогов, официальные статьи MQTT и документацию модуля paho (что для меня очень сложно понять), но до сих пор не могу понять это. Ваша помощь будет наиболее полезной/оцененной.

код RPi-А (с датчиком терморезистора):

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) 

код RPi-В (сетевой концентратор):

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

Какую фактическую ошибку вы видите? Код выглядит правильно (RPI-A не нуждается ни в одном из кода клиента MQTT перед циклом, поскольку вы используете 'publish.single'), а код RPI-B выглядит нормально на первый взгляд. – hardillb

+0

@hardillb спасибо за ответ, я хочу, чтобы RPi-A получал сообщения mqtt от RPi-B, а также отправлял их, поэтому я думал, что мне нужен код client-mqtt. Я не получаю ошибку как таковой, но RPi-B, похоже, не отправляет сообщения в ответ на RPi-A. –

+0

Извините, пропустил этот бит. Ответ предоставлен – hardillb

ответ

5

Самый простой способ, чтобы начать цикл сети в отдельном потоке используя функцию client.loop_start(), затем используйте обычный метод client.publish

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

Супер материал, который работал с удовольствием :) Большое вам спасибо.
Должен ли я использовать client.loop_forever() в RPi-B или заменить его на client.loop_start()? –

+0

Оставьте это как есть, для этого варианта использования это правильно – hardillb

Смежные вопросы