スクリプトだけでMQTT受信データを表示する


以前からMQTTで受信した最新のデータをLCDに表示したいと考えていました。
pythonスクリプトを作れば簡単にできますが、shellスクリプトだけで可能なことが分かりました。

まず、必要なパッケージをインストールします。
$ sudo apt install mosquitto-clients

$ sudo apt install moreutils

次に、以下のスクリプトを作ります。
mosquitto_subには受信日時を表示するオプションが有りませんが、moreutilsパッケージに含まれている ts(timestamp input)を使えば、
現在日時を追加することができます。
#!/bin/bash
#set -x

#mosquitto_sub -h 192.168.10.40 -p 1883  -t "/mqtt/espnow" >> /home/pi/hoge.log

mosquitto_sub -h 192.168.10.40 -p 1883  -t "/mqtt/espnow" -v | ts "%y/%m/%d %H:%M:%S" >> /home/pi/hoge.log

このスクリプトを実行するとhoge.logには以下の様に、日時、MQTTのtopic、payloadが記録されます。
20/12/14 11:04:03 /mqtt/espnow 00000091 3100 5 60
20/12/14 11:05:02 /mqtt/espnow 00000092 3101 5 60
20/12/14 11:06:02 /mqtt/espnow 00000093 3103 5 60
20/12/14 11:07:01 /mqtt/espnow 00000094 3100 5 60
20/12/14 11:08:00 /mqtt/espnow 00000095 3102 5 60
20/12/14 11:09:00 /mqtt/espnow 00000096 3103 5 60
20/12/14 11:09:59 /mqtt/espnow 00000097 3103 5 60
20/12/14 11:10:59 /mqtt/espnow 00000098 3102 5 60
20/12/14 11:11:58 /mqtt/espnow 00000099 3103 5 60
20/12/14 11:12:58 /mqtt/espnow 0000009a 3102 5 60
20/12/14 11:13:57 /mqtt/espnow 0000009b 3103 5 60
20/12/14 11:14:57 /mqtt/espnow 0000009c 3103 5 60
20/12/14 11:15:56 /mqtt/espnow 0000009d 3103 5 60
20/12/14 11:16:56 /mqtt/espnow 0000009e 3103 5 60
20/12/14 11:17:55 /mqtt/espnow 0000009f 3103 5 60
20/12/14 11:18:55 /mqtt/espnow 000000a0 3103 5 60
20/12/14 11:19:54 /mqtt/espnow 000000a1 3103 5 60


こちらの 手順でスクリプトをサービスに登録しますが、その前に/var/log/journalのディレクトリを作ります。
これをしないと、systemctlでstatusを確認した時に
Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.
の警告になります。
こ ちらに回避策が公開されていました。

ただ、この回避策を行っても
Warning: Unable to locate configuration directory, default config not loaded.
の警告がでます。
mosquittoを1.6.3に更新すれば回避できるみたいですが、実害無さそうなので放置しています。
$ sudo vi /etc/systemd/system/hoge.service

$ sudo mkdir /var/log/journal

$ sudo systemctl list-unit-files --type=service | grep hoge

$ sudo systemctl enable hoge

$ sudo systemctl list-unit-files --type=service | grep hoge

$ sudo systemctl --system daemon-reload

$ sudo systemctl start hoge

$ sudo systemctl status hoge



inotifywaitというコマンドでファイルの変化を監視することができます。
以下のスクリプトでhoge.logへの書き込みを監視します。
payload変数にはMQTTのpayloadをスペースで区切って設定しています。
#!/bin/bash
#set -x

file="/home/pi/hoge.log"

if [ ! -e ${file} ]; then
  touch ${file}
fi

while true
do
  inotifywait -e modify ${file} -o /tmp/inotify.log
  now=`tail -n 1 hoge.log | cut -f1,2 -d " "`
  payload=`tail -n 1 hoge.log | cut -f4,5 -d " "`
  echo $now
  echo $payload
done

このスクリプト(inotify.sh)を実行すると、MQTTでSubscribeした内容を表示します。
$ ./inotify.sh
Setting up watches.
Watches established.
20/12/14 11:09:00
00000096 3103
20/12/14 11:09:00
00000096 3103
20/12/14 11:09:59
00000097 3103
20/12/14 11:09:59
00000097 3103
20/12/14 11:10:59
00000098 3102
20/12/14 11:10:59
00000098 3102

あとは$nowと$payloadの変数をLCDに表示してやるだけですが、
なぜかこのスクリプトをサービスで起動すると正しく動きませんでした。
cronの起動時コマンド(@reboot)として登録しました。