2

From my understanding:

  • Client can be any device as long as it has an MQTT library running on it, from a microcontroller to a server, but must be connected to an MQTT broker over any network

  • Broker is responsible for receiving all messages,and sending these messages to the clients who are subscribed.

So at the moment I have a bash script that filters out specific data from the MQTT stream. The filtered information is then stored into a csv file, and later called upon to update an MySQL table.

Q: How can I make it so that my bash script (that updates the MySQL table) is subscribed to the MQTT broker as a client, so every time new data is sent I can push/send it out to the MySQL table.

4 Answers 4

4

Personally, I found bish-bosh a tad over complicated for my tastes. I am not great with sql, but I'll take a stab at the mqtt part. You will need a listener running mosquitto_sub to read and exec commands, and on your terminal you need to subscribe to an output stream. Finally, you will need a handler to send commands with. For a listener, you can try something like this:

#!/bin/bash
##########################
# MQTT Shell Listen & Exec
host=$2
clean="output input cmds";p="backpipe";pid=$(cat pidfile)
ctrl_c() {
  echo "Cleaning up..."
  rm -f $p;rm "$clean";kill $pid 2>/dev/null
  if [[ "$?" -eq "0" ]];
  then
     echo "Exit success";exit 0
  else
     exit 1
  fi
}

listen(){
([ ! -p "$p" ]) && mkfifo $p
(mosquitto_sub -h $host -t input >$p 2>/dev/null) &
echo "$!" > pidfile
while read line <$p
do
  echo $line > cmds
  if grep -q "quit" cmds; then
    (rm -f $p;rm $clean;kill $pid) 2>/dev/null
    break
  else
    (bash cmds | tee out) && mosquitto_pub -h $host -t output -f out;>out
  fi
done
}

usage(){
echo "    Mqtt-Exec Listener Via Bash"
echo "  Usage: $0 <mqtt server>"
echo "  Subscripe to topic \"output\", publish to topic \"input\""
}

case "$1" in
-h|--host)
trap ctrl_c INT
listen
;;
*)
usage
exit 1
;;
esac

This works fine unless you're trying to stream stuff, in which case you will need to encode it somehow, or sed out new lines. But, this should work for simply sending commands over mqtt.

Than subscribe to the output stream so you can see the shell output.

mosquitto_sub -h $host -t input

Finally, for a handler, something like this:

#!/bin/sh
cmds="$@"
echo $cmd | mosquitto_pub -h $host -t input -l
exit

Than you can run that in a tmux session along with the handler and you have an interactive shell: Window 1:

./handle echo "This is an interactive mqtt shell!"

Window 2:

This is an interactive mqtt shell!
2

I would use xargs for the job. So for example

mosquitto_sub -h <yourhost> -t <yourtopic> | xargs -I %output% ./handleMessage.sh %output%

Or depending on the code complexity you can directly execute the command that writes the value to your MySQL-DB.

Otherwise you can access the MQTT output via $1 in your handle.sh script

Example script:

#!/bin/bash
echo "$1" >> MQTT-Values.csv
# Enter your command to write to MySQL here

I prefer using this code with mosquitto_sub because it is very lightweight, easy to understand and thus maintainable.

1

Have you seen bish-bosh? It should do the job.

MQTT shell script client, for bash, dash, BusyBox ash and others

https://github.com/raphaelcohn/bish-bosh

0

To me, bish-bosh was also too complicated. I couldn't even get it to work on my desktop ubuntu system, I'd probably never would have got it onto my router running busybox. I took Chev_603s script and made a mqtt logger out of it. I put it on github: https://github.com/pkoevesdi/MQTT-Logger. Everybody feel free to use and improve it.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .