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.

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

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.
Sensors Contest 2017

Participated in the
Sensors Contest 2017

Be the First to Share


    • Made with Math Contest

      Made with Math Contest
    • Multi-Discipline Contest

      Multi-Discipline Contest
    • Robotics Contest

      Robotics Contest

    17 Discussions


    Question 2 months ago

    im still having issues getting this to work as advertised :)

    i tried some more things today and got a little further but still not working properly.

    i changed all the directories in the scripts because i had files/logs being saved in /home/pi/ and all the other stuff was in /Documents/FreezerProjects/ so i changed them all to /Home/Pi/ and rebooted so everything is now in the same directory.

    then i disabled the cron scheduled tasks so i could run everything in a terminal window and watch what is happening.

    record_986.py seems to work just fine. it does its initial stuff and then displays sensor output regularly.

    however, only F1.dat is generated, and no R1.dat is nowhere to be found.

    so then i opened another terminal window and ran temp4sensor.py. it errored out immediately looking for a save.dat so i created an empty file called save.dat.

    then i ran it again. it errored out again but this time im stuck but i took a screenshot. see attached.

    has anyone got this to work on a 3b+ with updated raspbian lately?

    any ideas?



    1 answer

    Answer 2 months ago

    Hi Brian, for the temp4sensor.py error: I assume you created the save.dat file using the touch command? That created an empty file so that is the pickle error you are getting. You can fix this by using pickle.dump( 0, open( base_dir + "save.dat", "wb" ) ) from a python interpreter prompt. (terminal -> python -> import pickle...). This will seed the file with a 0 and then the temp4sensor.py will run.
    As far as the R1.dat and F1.dat errors, I am not sure as I can not recreate your error.
    I believe you may have updated record_986.py since your screenshot shows a different writeout (json?). I suspect that 'rorf' is not picking up the 'R'. The logic looks for 'rorf' with 'R' and if it doesn't find it just defaults to 'F' which would explain not seeing a R1.dat file.
    John V.


    Question 4 months ago on Step 3

    EDIT...... I had to set the protocol to 41. unfortunately it still is not sending emails.

    im not sure why. i do know that when i set up the crontabs, gnome-schedule was warning me something about starting in home/pi/ and that some of the logs are in home/pi/ and some are in the FreezerProjects directory. not sure if thats the issue.

    i also still have not determined if the python module 'email' contains 'email.mime.text' that i cant seem to get installed. same with the python module 'sleep'... is this included with 'time'? i saw references to 'time.sleep' online but im no python expert.

    i also can only find a F1.dat and not an R.dat.

    im wondering if enough stuff has changed with python and whats included with the current RPi image that this instructable cannot be implemented without a code rework... which is not my strong suit.

    ORIGINAL QUESTION .....im trying to set this freezer alarm up. step 2 is working perfectly.

    i have my files in the same directory as the instructable.

    i believe i have the crontabs setup correctly in gnome-schedule.

    upon reboot, i can look up what processes load and i see python and then rtl_433 and in /home/pi i can see mtemp.log and t986.log are updated but mtemp has nothing in it and t986.log stops at:

    "2019-06-04 18:25:27 - stderr: rtl_433 version unknown inputs file rtl_tcp RTL-SDR
    2019-06-04 18:25:27 - stderr: Trying conf file at "rtl_433.conf"...
    2019-06-04 18:25:27 - stderr: Trying conf file at "/home/pi/.config/rtl_433/rtl_433.conf"...
    2019-06-04 18:25:27 - stderr: Trying conf file at "/usr/local/etc/rtl_433/rtl_433.conf"...
    2019-06-04 18:25:27 - stderr: Trying conf file at "/etc/rtl_433/rtl_433.conf"...
    2019-06-04 18:25:27 - stderr: quiet option (-q) is default and deprecated. See -v to increase verbosity
    2019-06-04 18:25:27 - stderr:
    2019-06-04 18:25:27 - stderr: Consider using "-M newmodel" to transition to new model keys. This will become the default someday.
    2019-06-04 18:25:27 - stderr: A table of changes and discussion is at https://github.com/merbanan/rtl_433/pull/986.
    2019-06-04 18:25:27 - stderr:
    2019-06-04 18:25:27 - stderr: Registered 1 out of 126 device decoding protocols [ 40 ]
    2019-06-04 18:25:27 - stderr: Detached kernel driver
    2019-06-04 18:25:28 - stderr: Found Rafael Micro R820T tuner
    2019-06-04 18:25:28 - stderr: Exact sample rate is: 250000.000414 Hz
    2019-06-04 18:25:28 - stderr: [R82XX] PLL not locked!
    2019-06-04 18:25:28 - stderr: Sample rate set to 250000 S/s.
    2019-06-04 18:25:28 - stderr: Tuner gain set to Auto.
    2019-06-04 18:25:28 - stderr: Tuned to 433.920MHz."

    with nothing after it.

    also, with the python modules sleep and email.mime.text, i tried to install them with "python -m pip install sleep" and "python -m pip install email.mime.text" but it cant find those modules to install them. the raspberry pi is using python 2.7

    any idea what im doing wrong?



    1 answer

    Answer 4 months ago

    Hi Brian, as far as email is concerned, it is 'built-in' to Python so there is nothing to install. As long as the import statement is in the code, email should work. Are you using your gmail account? Correct username and password? You can write a separate program or use the python interpreter to try basic emailing. See the documentation for examples. Here is the link for version 2.7 email https://docs.python.org/2/library/email-examples.h...

    And yes, code 41 is correct so the log should be looking better....

    Hope that helps...


    11 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 11 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 11 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.


    1 year 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 1 year 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 1 year 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 1 year 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 1 year 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 :)