In this article, we will learn how to access raspberry pi from anywhere in the world using MQTT. This will all be done with a python script.
Several applications are already available to access Linux-based terminals over remote/network, but they all require port forwarding, but MQTT allows without port forwarding.
We will not need any port forwarding. This will also be platform-independent because we will be using python to interact with the system to run it inside Linux, Windows even in OSX.
Tools Required/ libraries required
MQTT based python library – paho
Linux / Windows System
We will be linking the MQTT protocol stack with the terminal using python. Python’s library “OS” is also capable of interacting with system processes and terminals.
So, we will be writing a python script that will communicate with an MQTT broker and transfer and receive data. All the incoming data will be piped (transferred) into the system terminal process.
The output of the system processes will also be redirected in an MQTT response/ message on a topic (MQTT uses topics to communicate).
The terminal script is subscribed to a topic – terminal
Publishing on topic – terminal/output
The clients are subscribed to a topic – terminal/output
Publishing on topic – terminal
Both are connected with broker – broker.hivemq.com
On port – 1883
How does the system work?
The system is installed with the python script, listening to a specific MQTT topic (terminal), and connected to a MQTT broker. Any client who wants to access the terminal is publishing commands on that topic (terminal). When a client sends a command to our terminal script, it will read it, and the command is filtered out from that message. That command is then sent to the terminal, the result of that command is combined on a string and published to that client on that topic.
Understanding the source code
We can write two scripts, one for the terminal itself another is for accessing it.
We will be dividing our source code into two categories to understand easily.
- Interacting with the system terminal
- MQTT communication
Interacting with the system terminal
Python is a high-level programming/scripting language. Python has several libraries available to do stuff. First of all, we will need a library, which can interact, with our system; also it must be independent of platform. So, there is a library called “OS” in built-in python to access the operating system. We will import the library on the top of our script. With this, you can do a lot of work easily.
Now we know that the script should be multi-tasking or threaded, because sometimes a command takes long time to complete and we do not want that in that period when we pass another command it gets rejected. That can be done using subprocess library so let import it too.
Now that we have imported libraries we need to make a variable, which can hold the command and its output. Later we will see how to store commands to that variable from MQTT.
For saving command – data
For command output – stdout_value
All we need is done. We will be sending and receiving data on these variables. So, lets create a subprocess, which will directly send the command from “data” to the terminal and store the output to “stdout_value” variables.
The meaning of that line is now the following:
proc = Is a variable that stores the complete sub-process, input-output, and errors.
subprocess.Popen = this means we are telling process that we will be piping (giving input and taking output) some data and taking some of it out.
stdout = Stores the output of the above process.
stderr = Stores the error if any
stdin = is for string input command input
Now that we have started the process, we need to take the command’s output out and the error if there is any.
stdout_value = proc.stdout.read() + proc.stderr.read()
Now we are stroring the output by reading the “proc.stdout.read()”.
The “stdout_value” is the variable which we will send to our client on MQTT for output. So, lets send it below and learn how MQTT communication is done.
First of all, we will import libraries that are necessary for MQTT.
import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish
now we will declare a variable named client with mqtt client.
client = mqtt.Client()
Now we will make two functions, which are callbacks 1. For receiving messages 2. Doing something on connection successful.
client.on_connect = on_connect
client.on_message = on_message
Finally, we will connect to MQTT broker on a port, and start the client inside a nonblocking loop
client.connect(“broker.hivemq.com”, 1883, 60)
After the connection is successful we can send messages using this publish method.
publish.single(topic, message_data, hostname=”broker.hivemq.com”)
or we can create a function / method to do that.
This method takes the input parameter “msg” as the message we need to send to the broker with the topic.
Now that we have a function which triggers on receiving any data from MQTT broker. We will store any incoming message from broker to a variable message, inside the “on_message” method.
message = str(msg.payload)
The incoming message syntax will be.
cmd:” command to execute”
Now we need to remove the “cmd:” string and store the remaining command
in the “data” variable to process the command.
data = message.replace(“cmd:”,””)
Now to send the output we call our send method with the output parameters and transmit the result.
The access script is just a function, which receives messages from MQTT broker and takes input form user to publish to script, which is self-explained inside the code.
So, this is how we can access the complete system using MQTT.
Note – Do not use common topics to create terminal access because you will be giving access of the whole system.
You may also like:
Filed Under: Tutorials