The MQTT letterbox Part 2: Sending alerts from MQTT // Project
This is part 2 of my Uber letterbox where I show you how to send notifications to your phone when someone delivers a letter. If you haven’t seen Part 1 yet, then check that out first.
Software
For this I’ll be using MQTTwarn with IFTTTT.
MQTTwarn is a great bit of Python code created by Jan-Piet Mens. He has created a framework that supports a bucket load of Internet services and it’s fairly easy to add your own.
So, first we need to install the required Python PIP package.
apt-get install python-pip
Then install the PAHO MQTT package via Python PIP.
pip install paho-mqtt
Next install GIT as we’ll be using it to pull the source code from GitHub.
apt-get install git
Then we can pull the source, which will place it in the /opt directory.
cd /opt
git clone https://github.com/jpmens/mqttwarn.git
Then change to that directory.
cd /opt/mqttwarn
Add the mqttwarn user.
useradd --shell /bin/bash --home-dir /opt/mqttwarn mqttwarn
Copy the startup defaults file,
cp -i etc/mqttwarn.default /etc/default/mqttwarn
the systemd service file so it’ll start as a service.
cp -i etc/mqttwarn.service /lib/systemd/system/
the logrotate file so we don’t fill up the filesystem with logs,
cp -i etc/mqttwarn.logrotate /etc/logrotate.d/mqttwarn
create the mqttwarn log file directory and change the owner to the mqttwarn user.
mkdir /var/log/mqttwarn
chown mqttwarn:mqttwarn /var/log/mqttwarn
Before you start the service you’ll need to make a change to the service file, which is to remove the virtual Python environment. If you use it, then of course leave it in.
systemctl enable mqttwarn
Moving to your phone install the IFTTT app from the App Store. There’s also an Android app for this. It’s all the same process really. Once installed you’ll need to create an account, or if you have one already, just login.
mkdir -p /etc/mqttwarn
vi /etc/mqttwarn/mqttwarn.ini
There are several key elements to the ini file.
[defaults]
hostname = 'mqtt.homenet'
port = 1883
username = mqttwarn
password = mqttwarn
clientid = 'mqttwarn'
lwt = 'Home/MQTTwarn/State'
skipretained = False
cleansession = False
; MQTTv31 = 3 | MQTTv311 = 4
protocol = 4
; logging
logformat = '%(asctime)-15s %(levelname)-5s [%(module)s] %(message)s'
logfile = '/var/log/mqttwarn/mqttwarn.log'
; one of: CRITICAL, DEBUG, ERROR, INFO, WARN
loglevel = DEBUG
; name the service providers you will be using.
launch = file, log, ifttt
[config:file]
append_newline = True
targets = {
'mylog' : ['/tmp/mqtt.log']
}
[config:log]
targets = {
'info' : [ 'info' ]
}
[config:ifttt]
targets = {
'notify' : [ 'dT2dZsuX_QeBZL-FSO040L', 'LetterBox' ]
}
[Home/#]
targets = file:mylog, log:info
[Home/LetterBox/Delivery]
targets = ifttt:notify
The hostname of your MQTT server and the port number that the MQTT service is listening on.
hostname = 'mqtt.homenet'
port = 1883
The username and password of the MQTT user. Check out my MQTT installation video on how to do this.
username = mqttwarn
password = mqttwarn
Or if you’re in a hurry you can type this at the shell prompt.
mosquitto_passwd /etc/mosquitto/passwd mqttwarn
The clientid is used by the MQTT Broker to name clients.
clientid = 'mqttwarn'
The ‘lwt’ option will Publish a Topic message to the MQTT Broker when mqttwarn stops and starts.
lwt = 'Home/MQTTwarn/State'
We don’t need to worry about skipretained and cleansession for the moment.
skipretained = False
cleansession = False
Make sure you set your protocol to version 4 for new installs otherwise you’ll see authorized errors in the log file
protocol = 4
Where the location and message format can be configured here.
logformat = '%(asctime)-15s %(levelname)-5s [%(module)s] %(message)s'
logfile = '/var/log/mqttwarn/mqttwarn.log'
loglevel = DEBUG
You can also create functions that will translate MQTT data formats to service formats, but I’m not using this, so it’s commented out.
#functions = 'samplefuncs'
Next I load up three service providers: file, log and IFTTT.
launch = file, log, ifttt
These are referenced by these three sections. The file service will simply log data to a file.
[config:file]
append_newline = True
targets = {
'mylog' : ['/tmp/mqtt.log']
}
The log service will send messages to syslog,
[config:log]
targets = {
'info' : [ 'info' ]
}
and the IFTTT service is the one we’re interested in. Remember the key that I said to record? You’ll need to enter it here, and also the Event name from the WebHooks service from IFTTT.
[config:ifttt]
targets = {
'notify' : [ 'dT2dZsuX_QeBZL-FSO040L', 'LetterBox' ]
}
Next you’ll need to tell mqttwarn what services are subscribed to what topics. You can see that all Topics starting from Home will be sent to syslog and a local file,
[Home/#]
targets = file:mylog, log:info
and only Topics from Home/LetterBox/Delivery will be sent to IFTTT.
[Home/LetterBox/Delivery]
targets = ifttt:notify
Now, just restart the mqttwarn service and you’re done. That’s it! Pretty easy.
systemctl restart mqttwarn
So, does it work? Using a fake publish message from the MQTT server. Yup. Works OK.
[config:ifttt]
targets = {
'notify' : [ 'dT2dZsuX_QeBZL-FSO040L', 'LetterBox' ],
'check' : [ 'dT2dZsuX_QeBZL-FSO040L', 'LetterBoxCheck' ]
}
[Home/#]
targets = file:mylog, log:info
[Home/LetterBox/Delivery]
targets = ifttt:notify
[Home/LetterBox/Check]
targets = ifttt:check
Then moving back to the IFTTT website we need to create a new applet based on the WebHook service, this time use the event name you used in the mqttwarn file, and set the notification message to something appropriate and click Finish.
[config:ifttt]
targets = {
'notify' : [ 'dT2dZsuX_QeBZL-FSO040L', 'LetterBox' ],
'check' : [ 'dT2dZsuX_QeBZL-FSO040L', 'LetterBoxCheck' ],
'state' : [ 'dT2dZsuX_QeBZL-FSO040L', 'LetterBoxState' ]
}
[Home/#]
targets = file:mylog, log:info
[Home/LetterBox/Delivery]
targets = ifttt:notify
[Home/LetterBox/Check]
targets = ifttt:check
[Home/LetterBox/State]
targets = ifttt:state
Yup, works well.
So I picked up this one from Jaycar. It had everything reliably water-proofed. You could probably pick one up cheaper, but make sure it’s a 6V version as the DFrobot charger can’t handle anything over that.
The other end of the cable I trimmed and tinned so I could screw into the DFrobot LiPo solar charger and allow me to remove either the panel or ESP8266 box for maintenance.
Setup
Installing the solar panel was easy. I used hot glue for this as I wanted to be able to take it off easily should I need to, and also didn’t want to drill any mounting holes into the letterbox making it less waterproof. Since it was a cold day, I had to pre-heat both the letterbox and ESP box so that the hot glue would stick better to the metal. Then ran some glue on the edges of the ESP box and held it in place until the glue hardened.
Testing
So that the battery would start out fully charged I left it overnight connected up to my bench power supply limited to 160mA current and 6v. So, how well does it work?
First a mail delivery test. Cool!
In a followup video I’ll be looking at battery optimization, because there could be some weeks where there’s not enough sun to charge the LiPo and it’d be good to be able to get a full week out of a single charge.
I’ve also created a tutorial of this video on instructables.com and entered it into the IoT competition. So, if you liked this project head on over to instructables.com and vote on my project.