Raspberry Pi RF Temperature Monitor




I have a friend that owns a business with 2 walk in coolers storing perishable ingredients she needs to use. Occasionally she has issues with the coolers getting warmer than they should due to mechanical breakdowns. On one occasion, the cooler broke down on the weekend when no one was around and she lost some of the food. I built a temperature monitoring and alarm system using off the shelf Acurite Freezer - Refrigerator temperature sensors with a Raspberry Pi set up to intercept the RF signal from the temperature sensors and send an email if the temperatures were out of bounds.

Step 1: What You Need

Here is the part list linked to Amazon if you would like to buy them there (cost around $105 total):

AcuRite 00986A2 Refrigerator/Freezer Wireless Digital Thermometer

Mini USB RTL-SDR, RTL2832U & ESD-Safe Antenna Input.

Raspberry Pi 3 with 2.5A Micro USB Power Supply (UL Listed)

Samsung 32GB EVO Plus Class 10 Micro SDHC with Adapter 80mb/s (MB-MC32DA/AM)

Raspberry Pi 3 case

There are a few websites that will guide you in setting up your RPi for the first time if needed.

Life Hacker

Raspberry Pi Org

I set mine up 'headless' and use VNC to connect to it. The links above show how to do this.

Step 2: Sensor Setup

Setup the Acurite temperature sensors according to the instructions provided with it.

You can use any other temperature measuring device that sends an RF signal. This project assumes it is sending the signal on 433mHz so you may need to adjust the software if using a device that sends on a different frequency.

  1. Install rtl-sdr using the add /remove software included in the RPi standard menu. I installed all 3 packages - tools, development files, and library.
  2. Get and build / install rtl_433 from https://github.com/merbanan/rtl_433 (may need to also install cmake). This package supports a fair number of sensors. I am using the Acurite 986 which is protocol 40. You may be able to substitute other sensors as indicated in the package documentation.

  3. At this point, with the sensors in place in the refrigerator and freezer, the RTL dongle plugged into the RPi, you should be able to open a terminal window and run 'rtl_433 -G' and see the Acurite 986 send measurements. (Note: you will also see any other devices that transmit at 433 mHz). The Acurite 986 sends measurements every couple of minutes so you will have to wait to see the results.
  4. Here is what my RPi reports when I run 'rtl_433 -G':

2017-02-28 10:50:26 Acurite 986 sensor 0x154c - 1R: 3.9 C 39 F

2017-02-28 10:50:39 : HIDEKI TS04 sensor Rolling Code: 9 Channel: 3 Battery: OK Temperature: 10.7 C Humidity: 34 %

2017-02-28 10:50:39 : HIDEKI TS04 sensor Rolling Code: 9 Channel: 3 Battery: OK Temperature: 10.7 C Humidity: 34 %

2017-02-28 10:50:39 : HIDEKI TS04 sensor Rolling Code: 9 Channel: 3 Battery: OK Temperature: 10.7 C Humidity: 34 %

^CSignal caught, exiting!

Step 3: Install Python Script to Capture Measurements

Create a folder for your project. I used /home/pi/Documents/FreezerProjects for mine. If you use a different folder you will need to update the python script to reflect that.

Download the record_986.py script attached and place in your folder.

This script does the following:

  • Starts up the rtl_433 service with parameters for using protocol 40 (Acurite 986), records in json format, and runs in quiet mode.
  • Waits for a measurement to be reported by the rtl_433 service. Updates the refrigerator or freezer .dat file as appropriate and appends the measurements to the Stats.csv file

The R.dat and F.dat files are read every 15 minutes by another python script described in the next step. The Stats.csv file is used on a weekly basis in the creation of a graph.

I set this script to run on every reboot. I use gnome-schedule to set cron jobs - use whatever you are comfortable with.

I installed gnome-scheduler via the Add / Remove software from the RPi menu -> Preferences.

Note: script assumes you have sys, subprocess, threading and datetime python modules installed. You can check to see installed python modules by opening a python shell and typing help('modules'). If any are missing, use pip to add them. (see https://packaging.python.org/installing).

crontab setting:

@reboot python /home/pi/Documents/FreezerProjects/record_986.py > t986.log &

Step 4: Install Python Script to Monitor Temperature Readings

Add the attached file temp4sensor.py to your folder.

This script does the following:

  • Reads a configuration file with the temperature range to check, along with email and text message addresses to use for alerts.
  • When it executes, it reads the R.dat and F.dat files updated by the record_986.py script to see if they are in the range specified in the configuration file.
  • If either reading is out of range, the script sends an email and text message.
  • The script uses a gmail account to send the messages from. There are other methods to send messages if this doesn't work for you.
  • If a message is sent, the script will modify a file save.dat with a '1' to prevent continuously sending a message. I reset this file every day a 8:00 am with a small cron job.

Script assumes the following python modules are installed:

time, decimal, smtplib, email.mime.text, time, sleep, threading, json, pickle

I set this up to execute every 15 minutes - you can adjust it in your crontab.

crontab setting:

*/15 * * * * python /home/pi/Documents/FreezerProjects/temp4sensor.py > Mtemp.log

In your project folder create a text file named t4sensorjson.cfg with the following contents:

"S1_Low" : "32",

"S1_High": "47",

"S2_Low" : "-7",

"S2_High": "29",

"TextID" : "NNNNNNNNNN@vtext.com",

"EmailID": ["person1@comcast.net", "person2@gmail.com"]


S1 is the refrigerator settings, S2 is the freezer settings - set to whatever you like. textID is the phone number to text using the required format for the phone service provider (e.g., @vtext.com for Verizon cellphones).

EmailID is an array of multiple email addresses as needed.

At this point, you should have a working temperature monitoring and alerting application!

The following steps are enhancements I built to add value to the basic application.

Step 5: Daily File Reset

Download the attached file and save it in your project folder.

Set a crontab entry to run this script every day at 8:00 to reset the text message sent flag file.

crontab setting:

0 8 * * * python /home/pi/Documents/FreezerProjects/onceperday.py

Step 6: Create and Email Weekly Graph

Create an executable shell script file with the following content:

# produce graph file, email the graph, and reset the collection files

> t986.log

> Mtemp.log

cd /home/pi/Documents/FreezerProjects

cp Stats.csv Stats.bak

cp messages.csv messages.bak

python graph2.py && python test_mail.py

> messages.csv

> Stats.csv

echo 'DateTime,Sensor,Value' > Stats.csv

Download and save the attached files in your project folder. Update test_mail.py with your email account settings.

The shell script will zero out the t986 and Mtemp logs so they do not grow too large. Then it will back up the Stats.csv and messages,csv files in case you need to use them for trouble shooting.

Next the shell script will execute the graph2 python script to create the graph file - image attached to this step - and then email it to the email addresses set up earlier in the configuration file.

Finally the shell script will reset the messages and Stats files to initial states.

Python script requires these modules: csv, dateutil, subprocess, pandas, matplotlib, matplotlib.pyplot, json.

I set this up to run every Monday morning at 9:00 AM.

crontab settings: 0 9 * * 7 /home/pi/Documents/FreezerProjects/graph.sh

Step 7: Use IBM Watson-IOT and Node-Red to Create a Dashboard (optional)

The Raspberry Pi 3 with the NOOBS basic Debian OS comes with Node-Red pre-installed. I already had an IBM Bluemix account and so it was fairly easy to set up the dashboard.

  1. If you don't already have one, set up a free 30 day trial account on IBM Bluemix. IBM Bluemix Signup
  2. After 30 days, you can upgrade your account. I set the memory for the application to 256MB and do not get charged for usage as IBM currently allows the first 375GB-hours at no charge (.25 GB X 24 hrs/day X 31 days/month = 186 GB-hours/month).
  3. Follow the directions on IBM Bluemix to get your RPi communicating with the Bluemix platform and Node-Red. Here is a link: https://developer.ibm.com/recipes/tutorials/deploy-watson-iot-node-on-raspberry-pi/
  4. Refer to the picture of the Raspberry Pi Node-Red Flow 1 and create the nodes and connect them as shown.
    1. Create 2 Watch nodes to watch the timestamps of the R1 and F1 dat files. Once a reading is received by the python script, the .dat file will have the latest temperature value and trigger the Node-Red flow.
    2. For each watch node, create a change node to move msg.payload to msg.filename
    3. For each change node, create a file node to read the temperature values. Output as utf8.
    4. For each file node, create a function node with the appropriate function:
      1. msg.payload = {"d":{"Rtemp":msg.payload.replace("t=","").replace("'C\n","")}};
        return msg;

      2. msg.payload = {"d":{"Ftemp":msg.payload.replace("t=","").replace("'C\n","")}};
        return msg;

    5. Connect both function outputs to the Watson IoT node.
    6. Add any debug messages if you wish.
  5. You will need to enable the node-red-dashboard if it is not in your node-red starter IBM Bluemix application. This can be accomplished by enabling the continuous delivery and have a tool chain. Add node-red-dashboard to your project dependencies in the package.json file and deploy. Now when you open up your node-red flow editor, you should see 'dashboard' in your palette.
  6. We will also need node-red-contrib-moment added to package.json if it is missing from the palette as we will use this to format the update date time in the dashboard.
  7. Refer to the picture of IBM Bluemix Node-Red flows and connect them as shown.
    1. There should already be a connection from the starter code to begin. This node receives the temperature values from the RPi node-red flow.
    2. Create 2 switch nodes to separate the R temp and the F temp into separate flows.
      1. SplitRefrigFreeze "Property msg.payload.d.Ftemp is not null" for the freezer flow and

      2. "Property msg.payload.d.Rtemp is not null" for the refrigerator flow

    3. For each switch node, create a function node to read the temperature value.
      1. return {payload:msg.payload.d.Ftemp} and

      2. return {payload:msg.payload.d.Rtemp}

    4. For each switch node, create a function node to record the date-time a reading was received.
      1. msg.timestamp = new Date().toISOString()
        return msg;

    5. Create a moment node to format the date time to your timezone and preference. I am using "llll" for my format.
    6. Next create gauges, charts and text and connect up the temperatures and moment output as shown. Use the dashboard sidebar tab to manage the widget layout. See https://github.com/node-red/node-red-dashboard

Step 8: Remote Access (optional)

Since this will be located in a store, I ended up using TeamViewer on my home PC and Raspberry Pi. There is a beta version for the RPi and it appears to work pretty well.

Sometimes the RPi TeamViewer would 'hang' so I set a crontab to reboot it every other day at 2:00 am so I could still get to it remotely without having to have someone "unplug - plug it back in" onsite.


RPi beta:


Step 9: Remote Reboot Using Node-Red (optional)

Sometimes I may want to reboot my Raspberry Pi remotely. I created an additional flow in my IBM Bluemix Node-Red app to send a reboot command to the RPi.

On the Raspberry Pi create the following Flow 2:

  1. See the RPi Node-Red reboot flow picture for the connections.
    1. Create a watson iot input node and fill it in with the appropriate credentials to communicate with watson iot.
    2. Create a delay node and set it for 15 seconds (optional)
    3. Create a exec node with 'sudo reboot' command
    4. Add any debug messages if you want

On the Bluemix Node-Red application, create the following Flow 2:

  1. See the IBM Bluemix Node-Red reboot flow picture for the connections
    1. Create an injector node to kick off the flow
    2. Connect the injector node to a function node with this function:
      1. msg.payload = '{"delay": 2}'
        return msg;

    3. Create a json node
    4. Create a watson iot output node and fill it in with the appropriate credentials to connect to the Raspberry Pi.



    • Trash to Treasure

      Trash to Treasure
    • Arduino Contest 2019

      Arduino Contest 2019
    • Tape Contest

      Tape Contest

    11 Discussions


    5 months ago

    Hey John, great job on your site. Is it easy for you to edit this stage of the instructions to include some extra tips? I noticed a few things that you might want to call out in this stage of the instructable because of things I bet have changed in the past year in the underlying packages:
    1. When using python3 to execute your script, I get datatyping errors. Backtracking to python2 resolved them. I was too lazy to fix the datatypes to make Python3 work, but we could perhaps post a version for version 2 and 3.
    2. I notice in your instructions you filter your rtl command with parameter "40" for the Acurite 986, when in my version, the 986 is mapped to parameter "41". Indeed, my bet is you are running older versions where this indeed works, but we may want to give this as a warning so people don't need to debug like I did.

    Once again, you made my life so much easier, I'm totally happy to continue to feedback new improvements if you are open to them! Thanks Andrew

    2 replies

    Reply 5 months ago

    Hi Andrew, thanks for the feedback!
    I am planning on updating to the newer versions of packages and adding an enhancement for 'spurious' signals. I have been seeing an occasional 'spike' in temp reading and the log shows that it is actually coming from a different sensor. It could be an older sensor that is just laying around the shop, but anyway, I think I should add some logic to NOT alarm unless the increase is 'steady'.
    Probably a couple of weeks before I have the time to work on this...


    Reply 5 months ago

    Hey John, get this -- I also was seeing spurious signals that were always on the "rising side". I think i root caused it! I "think" when running on batteries, the micro has a quick running reset, and after that - the temperature shows a spike in value - but quickly goes back down to the freezer temperature. The reason I think this -- is I've slowly started replacing the batteries in my sensors with DC power supplies (i don't want to have to deal with batteries), and since the replacement of the power source to a DC supply - no more spurious spikes in temp value.


    11 months ago

    This is such a great idea. I recently lost (again) the contents of my refrigerator/freezer in my garage and I wanted a way to track it and generate an alert and capture historical data. Just so happens I have an extra Raspberry Pi 3 hanging around. :)

    Just ordered the sensor and attenea today from Amazon. I will give this a go over the weekend and post back my results. If I improve upon your scripts, I will pass them along.

    Again, thanks for the idea. greatly appreciate it!


    Question 11 months ago

    That is a great idea, thanks for the quick feedback. Another thing has come up, have you ever seen "stderr: Async read stalled, exiting!" in the t986 log? Seems related to 433_rtl, and a simple reboot seems to have things working again. I've only seen it once so maybe it was a one off fluke, but figure it wouldn't hurt to ask if you've come across it. Do I need to periodically reboot the process, or set up some sort of watchdog to reset if the log doesn't update.? I feel like this could be improved by a stale data/loss of coms alarm. I'm brainstorming options now, but wonder if you've considered anything. Thanks again!

    1 answer

    Answer 11 months ago

    I have not seen that error message so hopefully it was just a rare event. I do have 1 of the installations rebooting weekly but if you included step 6 in your project, you should be cleaning up the logs and resetting stats and messages at least once per week...


    Question 11 months ago on Step 3

    First off, this is extremely helpful, and exactly what I was looking for! Great little project!

    The 986 has changed it's output, so I had to update the python which parses the raw data into csv. However, I believe the 986 sends out the reading twice in case the first time doesn't go through or I don't know why it shows up twice. So my CSV file is full of duplicate entries. I didn't want to have to figure out how to run a check if the timestamp and device ID already exists, but I feel like that may be the path to go. I tried adding a sleep timer to the script, hoping it would miss the 2nd instance, but either I placed the sleep timer in the wrong part of the code, or that method isn't going to work. So I'm reaching out to see if there are other ways to insure duplicate entries aren't being written to .dat and .csv.

    1 answer

    Answer 11 months ago

    Thanks for using this project! I actually have 3 different sites running this now and everyone of them has the duplicate entries - I am also not sure why the 986 sends them twice sometimes...

    I did add a small step to 'dedup' the Stats file once per week when I make a graph of the history using this shell command:

    sort -r -u Stats.csv -o Stats.csv

    You could put this in a command shell script and run it periodically with the Scheduler...or, add it to the python script and execute it after recording the temps....



    2 years ago

    Awesome build! As a Hvac/r servicer I can see many uses for this tool. I plan on making one also. Thanks for sharing,and I voted.

    1 reply

    Reply 2 years ago

    Thanks for the vote! Let me know if you have any questions.


    2 years ago

    That was nice of you to help her out like that :)