Raspberry PI Frost Alert

by awigmore in Circuits > Raspberry Pi

393 Views, 0 Favorites, 0 Comments

Raspberry PI Frost Alert

rapi.png

In this instructable we will create a simple frost alert using a Raspberry PI and a free Weather API to retrieve the weather forecast. The aim of the simple circuit is to use colored LED lights to inform the user if frost or low temperatures are expected. A red light indicates below freezing temperatures are expected, yellow light means low temperatures are expected and a green light means there are no cold temperatures expected.

Supplies

We are going to keep the project so you simply need a Raspberry PI that supports an internet connection, a breadboard, three LEDs, matching resistors and a few connector wires.

Create a Simple Circuit to Drive Three LED Lights

image-52.png

You can use any Raspberry PI providing that it is network enabled (so we can download the weather data) and can run Python 3 scripts (Python 2 should work too but you’ll have to modify the script a little to make it run).

We will be using three GPIO pins to drive our LEDS – 23, 24 and 25 for red, yellow and green colors respectively.

For each port, we connect a LED and a resistor (don’t forget the resistor otherwise you’ll risk damaging the LED or board). Then each are connected to the common ground (pin 6 in our case).

Create the Weather API Query to Retrieve the Weather Forecast

Now we have our simple circuit, we are ready to create a Python script to download the weather forecast and check for freezing temperatures.

Before we write our script, let’s take a look at a sample API call to retrieve the weather forecast for ‘Chicago, IL’ in the USA. The call is very simple – include the encoded location in the path and then add your API key to the key parameter.

https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/Chicago%2CIL?unitGroup=us&key=YOUR_API_KEY

If you don’t have an API key, head over to Visual Crossing Weather Data Services to sign up for you free account – you will be able to make up to 1000 requests for free every day. You can also create Timeline API requests interactively directly within the tool and explore the JSON output.

Create a Python Script to Download the Weather Forecast Data

We can now write the script we’ll need. At the top, we’ll had the libraries we’ll use:

import RPi.GPIO as GPIO
import urllib.parse
import urllib.request
import json
import time

For simplicity, we’ll set the parameters we need as variables:

UPDATEINTERVAL=5
API_KEY="YOUR_API_KEY"
LOCATION="New York City,NY"
FREEZING_TEMP=32 COLD_TEMP=40 UNIT_GROUP="us"

If you prefer to work in metric, change the UNIT_GROUP to metric and the freezing and cold temperature thresholds to 0 and 4 respectively.

Our first function is the call to retrieve the data from the Weather API:

def getWeatherForecast():
         requestUrl = "https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/" + urllib.parse.quote_plus(LOCATION) + "?key="+API_KEY+"&unitGroup="+UNIT_GROUP;
         try:
                 req = urllib.request.urlopen(requestUrl)
         except:
                 print("Could not read from:"+requestUrl);
                 return []
         rawForecastData = req.read()
         req.close()
         return json.loads(rawForecastData)

This method constructs the Weather API request using the location, API Key and unit group selected in the parameters. Then we submit the Weather API request and, assuming no errors, we parse the result as JSON so we can read the minimum temperatures predicted.

We now set up a loop to continuously retrieve the weather data, wait and then try again.

def main():
  while True:
    print("Fetching forecast...")
    
//retrieve the forecast
    weatherForecast = getWeatherForecast()
    if ('days' not in weatherForecast):
      print("Problem retrieving forecast")
    else:
//retrieve the days array 
      days=weatherForecast['days'];
      nextColdDayIndex=-1;
      nextFreezingDayIndex=-1;
      totalFreezingDays=0;
//loop through the days, checking the tempmin property
      for dayIndex in range(len(days)):
        tempmin=days[dayIndex]['tempmin'];
        if tempmin<FREEZING_TEMP:
          totalFreezingDays=totalFreezingDays+1;
          if nextFreezingDayIndex==-1:
            nextFreezingDayIndex=dayIndex;

        if tempmin<COLD_TEMP and nextColdDayIndex==-1:
          nextColdDayIndex=dayIndex;

//print the results
      if nextFreezingDayIndex!=-1:
        print("Freezing day:"+str(nextFreezingDayIndex)+", temp="+str(days[nextFreezingDayIndex]['tempmin']))

      if nextColdDayIndex!=-1:
        print("Cold day:"+str(nextColdDayIndex)+", temp="+str(days[nextColdDayIndex]['tempmin']))

//wait and then try again
    try:
      time.sleep(UPDATEINTERVAL)
    except KeyboardInterrupt:
      break
 
 

//call main to start the script
main();

In this simple case, we look at the ‘days’ property of the Weather Forecast JSON and, from there, examine the ‘tempmin’ property. This is the minimum temperature predicted for each day. We record the first day where the temperature will be below our FREEZING_TEMP threshold and the first day when it will be below the COLD_TEMP threshold.


After printing the status to the console, we wait for the ‘UPDATEINTERVAL’ number of seconds and then repeat the process

Enable the Appropriate LED Warning and Status Lights

The above script retrieves the weather forecast but only prints out the results to the console. To finish our simple frost alert project, we need to drive some LEDs.

To do this, we simply add the appropriate logic to the GPIO pins. At the start of our script, we initialize the pins:

GPIO.setmode(GPIO.BCM)
GPIO.setup(23,GPIO.OUT)
GPIO.setup(24,GPIO.OUT)
GPIO.setup(25,GPIO.OUT)

We set the pins to high and low, depending on our frost detection. Setting the pin high, will drive a signal through the LED to light them up:

GPIO.output(23,GPIO.HIGH)

Full Python Script

Here is the full script:

def main():
  while True:
    print("Fetching forecast...")
//turn on all the LEDs when retrieving the data
    GPIO.output(23,GPIO.HIGH)
    GPIO.output(24,GPIO.HIGH)
    GPIO.output(25,GPIO.HIGH)

    weatherForecast = getWeatherForecast()
    if ('days' not in weatherForecast):
      print("Problem retrieving forecast")
    else:
      days=weatherForecast['days'];
      nextColdDayIndex=-1;
      nextFreezingDayIndex=-1;
      totalFreezingDays=0;
      for dayIndex in range(len(days)):
        tempmin=days[dayIndex]['tempmin'];
        if tempmin