Controlling a RaspberryPi GPIO pin with MQTT

good choice

Thanks for the information and also the tutorials you guys do.
hope fully one day I will get to the point as well . I am still learning the system and all the finer details and working.

thanks for your kind words. good luck and don’t hesitate to ask more questions if needed.
Once you finished your project, consider sharing it, it may help someone else

I will share once I am done and running.

1 Like

Hello .
I trying to continue your script witch ( so far ) two GPIOs - and it looks good and give no errors , but don’t know how to subscribe to more topics ( as many as GPIOs i want to use ).
I don’t know much python. I don’t know that will be better to make several files for every GPIO & topic i want to use or it can be done in one file. So far i have no idea how to subscribe more topics. Any idea ? In general in my house are working two RPI3 and many esp8266 - and actually i wanted to utilize not used gpios from both of RPI.

#!/usr/bin/python
# MQTT Controll GPIO pin
# Import package
import paho.mqtt.client as mqtt
#add for output
import RPi.GPIO as GPIO


# Define Variables
MQTT_HOST = "192.168.0.252"
MQTT_PORT = 1883
MQTT_KEEPALIVE_INTERVAL = 45
MQTT_TOPIC = "cmnd/STouch_BathRoom/power"
MQTT_TOPIC1 = "cmnd/STouchLivRoom1/power"
#
LED1 = 9
LED2 = 10
LED3 = 11

GPIO.setmode(GPIO.BCM)
GPIO.setup(LED1, GPIO.OUT)
try:
  # Define on connect event function
  # We shall subscribe to our Topic in this function
  def on_connect(self,mosq, obj, rc):
     mqttc.subscribe(MQTT_TOPIC, 0)
     print("Connect on "+MQTT_HOST)
  # Define on_message event function.
  # This function will be invoked every time,
  # a new message arrives for the subscribed topic
  def on_message(mosq, obj, msg):

     if (msg.topic=='Topic1'):
         if (msg.payload=='ON'):
           GPIO.output(LED1,True)
           print 'Lamp1 ON'
           print "Topic1: " + str(msg.topic)
           print "QoS: " + str(msg.qos)
     if (msg.payload=='OFF'):
           GPIO.output(LED1,False)
           print 'Lamp1 OFF'
           print "Topic1: " + str(msg.topic)
           print "QoS: " + str(msg.qos)

     if (msg.topic=='Topic2'):
         if (msg.payload=='ON'):
            GPIO.output(LED2,True)
            print 'Lamp2 ON'
            print "Topic2: " + str(msg.topic)
            print "Qos: " + str(msg.qos)
     if (msg.payload=='OFF'):
            GPIO.output(LED2,False)
            print 'Lamp2 OFF'
            print "Topic2 " + str(msg.topic)
            print "Qos: " + str(msg.topic1)



  def on_subscribe(mosq, obj, mid, granted_qos):
          print("Subscribed to Topic: " +
          MQTT_TOPIC + " with QoS: " + str(granted_qos))

    # Initiate MQTT Client
  mqttc = mqtt.Client()

    # Assign event callbacks
  mqttc.on_message = on_message
  mqttc.on_connect = on_connect
  mqttc.on_subscribe = on_subscribe

    # Connect with MQTT Broker
  mqttc.connect(MQTT_HOST, MQTT_PORT, MQTT_KEEPALIVE_INTERVAL)

    # Continue monitoring the incoming messages for subscribed topic
  mqttc.loop_forever()

except KeyboardInterrupt:
    # here you put any code you want to run before the program
    # exits when you press CTRL+C
    GPIO.cleanup()
#finally:
    #GPIO.cleanup() # this ensures a clean exit

Jerry, subscription can be done with a wildcard if the topics share a common denominator, or by stating the individual topics like this:
client.subscribe("home/#")
client.subscribe([(“home/light”,2),(“home/fan”,1),(“home/heating”,0)])
the numbers 2,1,0 I added do not stand for any sequence but as examples for the QoS that can be given as second parameter.

handling of the topics then is done with if statements in the callback function.
It is also possible to add a callback function for every topic,

mqttc.message_callback_add('home/light', on_message_light)
mqttc.message_callback_add('home/fan', on_message_fan)
mqttc.message_callback_add('home/heating', on_message_heat)

but i find that less elegant

if your topics are Bedroom/1, Bedroom/2 
 Bedroom/8 use:
client.subscribe("Bedroom/#")

if your topics are Bedroom1,Bedroom2
Bedroom8: use:
client.subscribe([(“Bedroom1”),(“Bedroom2”),........,(“Bedroom8”)])

nice thank you

1 Like

my pleasure, just in case, you can also call the subscribe function for every topic like
client.subscribe(“topic1”)
client.subscribe(“topic2”)
etc
you will get more than one subscription id then
 if that is somehow important to you
. Can als give the QoS as second parameter as shown in my reply to Jerry

Thank you Kees ! Ill try to make it work :slight_smile:

ill let u know progress - if any :wink:

Regards

1 Like

Thank you for that tutorial. It is that i need for my garage door :slight_smile:

1 Like

Hi i’ve got a problem whith my mqtt on raspberry pi in my garage. I use “ok google” command. Normally work well but a couple of days the door was open without my order. This is my mqtt.py script. Do you have any idea for secure the door openning?
#!/usr/bin/python

-- coding: utf-8 --

Import package

import paho.mqtt.client as mqtt
import time
#add for output
import RPi.GPIO as GPIO
GPIO.setwarnings(False)

Define Variables

MQTT_HOST = “192.168.1.9”
MQTT_PORT = 8883
MQTT_KEEPALIVE_INTERVAL = 45
MQTT_TOPIC_PG = “raspiB/PGaraje”
MQTT_TOPIC_PV = “raspiB/PValla”
MQTT_TOPIC_AllP = “raspiB/AllPGaraje”

Garaje = 11
Valla = 4
GPIO.setmode(GPIO.BCM)
GPIO.setup(Garaje, GPIO.OUT)
GPIO.setup(Valla, GPIO.OUT)
GPIO.output(Garaje,True)
GPIO.output(Valla,True)
try:

Define on connect event function

We shall subscribe to our Topic in this function

def on_connect(self,mqtt, obj, rc):
mqttc.subscribe(MQTT_TOPIC_PG, 0)
mqttc.subscribe(MQTT_TOPIC_PV, 0)
mqttc.subscribe(MQTT_TOPIC_AllP, 0)
print("Connect on "+MQTT_HOST,str(obj),"result code ",str(rc))

Define on_message event function.

This function will be invoked every time,

a new message arrives for the subscribed topic

def on_message(mqtt, obj, msg):
if (msg.topic==‘raspiB/PValla’):
if (msg.payload==‘ON’):
GPIO.output(Valla,False)
print (“Open Valla”)
print ("Topic: " + str(msg.topic))
print ("QoS: " + str(msg.qos))
if (msg.payload==‘OFF’):
GPIO.output(Valla,True)
print (‘Close Valla’)
print ("Topic: " + str(msg.topic))
print ("QoS: " + str(msg.qos))
if (msg.topic==‘raspiB/AllPGaraje’):
if (msg.payload==‘ON’):
GPIO.output(Valla,False)
GPIO.output(Garaje,False)
print (“Open All Garage Doors”)
print ("Topic: " + str(msg.topic))
print ("QoS: " + str(msg.qos))
if (msg.payload==‘OFF’):
GPIO.output(Valla,True)
GPIO.output(Garaje,True)
print (‘Close All Garage Doors’)
print ("Topic: " + str(msg.topic))
print ("QoS: " + str(msg.qos))
if (msg.topic==‘raspiB/PGaraje’):
if (msg.payload==‘ON’):
GPIO.output(Garaje,False)
print (“Open Garaje”)
print ("Topic: " + str(msg.topic))
print ("QoS: " + str(msg.qos))
if (msg.payload==‘OFF’):
GPIO.output(Garaje,True)
print (‘Close Garaje’)
print ("Topic: " + str(msg.topic))
print ("QoS: " + str(msg.qos))

def on_subscribe(mqtt, obj, mid, granted_qos):
print("Subscribed to Topic: " +
MQTT_TOPIC + " with QoS: " + str(granted_qos))

# Initiate MQTT Client

mqttc = mqtt.Client()

# Assign event callbacks

mqttc.on_message = on_message
mqttc.username_pw_set(username=“xxxxxxx”, password=“xxxxxxx”)
mqttc.on_connect = on_connect
mqttc.on_subscribe = on_subscribe

# Connect with MQTT Broker

mqttc.connect(MQTT_HOST, MQTT_PORT, MQTT_KEEPALIVE_INTERVAL)

# Continue monitoring the incoming messages for subscribed topic

mqttc.loop_forever()

except KeyboardInterrupt:
# here you put any code you want to run before the program
# exits when you press CTRL+C
GPIO.cleanup()
#finally:
#GPIO.cleanup() # this ensures a clean exit

Maeby with qs 2?

I am not sure, I would think that if it worked at first, your code should be OK.
I hope someone else can help you better

Yes it works well. the only problem is that twice i found the garage door opened.

I created small script to drive relays via gpio using mqtt. It basically change I/O state of gpio pin. You can configure relation mqtt topic -> gpio in json. I am using this to control my floor heating. Script is running as systemd service. It can integrate with mqtt binding in 2.4 version, it uses status topic. Maybe it will be useful for someone: https://github.com/pgrzegorz/rpirelaymqtt

1 Like