Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
Arrow up icon
GO TO TOP
Internet of Things Programming Projects

You're reading from   Internet of Things Programming Projects Build exciting IoT projects using Raspberry Pi 5, Raspberry Pi Pico, and Python

Arrow left icon
Product type Paperback
Published in Jun 2024
Publisher Packt
ISBN-13 9781835082959
Length 458 pages
Edition 2nd Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Colin Dow Colin Dow
Author Profile Icon Colin Dow
Colin Dow
Arrow right icon
View More author details
Toc

Table of Contents (21) Chapters Close

Preface 1. Part 1: Setting Up the Raspberry Pi for IoT Development FREE CHAPTER
2. Chapter 1: Understanding the Raspberry Pi 3. Chapter 2: Harnessing Web Services with the Raspberry Pi 4. Chapter 3: Building an IoT Weather Indicator 5. Chapter 4: Building an IoT Information Display 6. Part 2: Building an IoT Home Security Dashboard
7. Chapter 5: Exploring the GPIO 8. Chapter 6: Building an IoT Alarm Module 9. Chapter 7: Building an IoT Button 10. Chapter 8: Creating an IoT Alarm Dashboard 11. Part 3: Creating a LoRa-Enabled IoT Monitoring Station
12. Chapter 9: Understanding LoRa 13. Chapter 10: Integrating LoRa with the Internet 14. Part 4: Building an IoT Robot Car
15. Chapter 11: Introducing ROS 16. Chapter 12: Creating an IoT Joystick 17. Chapter 13: Introducing Advanced Robotic Eyes for Security (A.R.E.S.) 18. Chapter 14: Adding Computer Vision to A.R.E.S. 19. Index 20. Other Books You May Enjoy

Developing weather display applications

Now that we are experienced IoT application developers, we are ready to take our skills to the next level and create more intricate projects. In this section, we will leverage the capabilities of Raspberry Pi and Sense HAT to create a weather display application and a weather-dependent GO-NO-GO decision-making application.

In Figure 2.13, we see a diagram depicting a call to the OpenWeather API from our Raspberry Pi and Sense HAT, enclosed within its custom case. For our weather display application, we will follow a similar approach to the scrolling stock ticker:

Figure 2.13 – Using the OpenWeather API to get the current weather conditions

Figure 2.13 – Using the OpenWeather API to get the current weather conditions

We will first acquire an API key from OpenWeather and verify the API call by printing the response to the Shell for testing purposes. We will then utilize the Sense HAT to create a ticker-style display that displays the current weather conditions.

Finally, we will replace the scrolling display with visuals as we build a weather-dependent GO-NO-GO decision-making application.

We will start by obtaining an API key.

Getting an API key

To utilize the OpenWeather web service, it is necessary to obtain an API key. This API key serves as a unique identifier that grants access to the OpenWeather web service. The key is acquired by creating an account on the OpenWeather website and generating an API key by subscribing to the appropriate service. The API key acts as a credential to authenticate and authorize our requests to the OpenWeather web service, enabling us to retrieve weather data for various locations around the world. It’s important to keep the API key confidential and securely store it as it grants access to the OpenWeather API on our behalf.

To obtain a free API key from OpenWeather, we start by navigating to the OpenWeather price page located at https://openweathermap.org/price. We then scroll down to the Current weather and forecasts collection section and click on the Get API key button:

Figure 2.14 – Obtaining an API key from OpenWeather

Figure 2.14 – Obtaining an API key from OpenWeather

We follow the instructions for creating a new account. After successfully creating the account, we gain access to our personal dashboard. Inside the personal dashboard, we navigate to the API keys tab and locate the API key in the Key box.

We copy and paste our key into a text editor as we require this key every time we make a call to the OpenWeather web service. As a free user, we are limited to 60 API requests per minute and a total of 1,000,000 API requests per month. This should be more than enough for our application.

With our OpenWeather API key, we can now start to write code to test out the web service.

Creating a scrolling weather information ticker

With our OpenWeather API key, Raspberry Pi, and Sense HAT, we will now create a scrolling weather information device that mimics the functionality of our scrolling stock ticker. We will start by acquiring weather data and display the results in the Shell of Thonny.

After we are satisfied that our API key and web service work, we will integrate the web service data with the Sense HAT, displaying scrolling text that displays the temperature and weather conditions.

Testing the web service

Before integrating the OpenWeather API into our Raspberry Pi and Sense HAT, we will ensure its functionality with a simple program. To create the test code, we do the following:

  1. We launch Thonny on our Raspberry Pi, activate the ch2-env Python virtual environment, and create a new tab. Inside the tab, we write the following code:
    import requests
    url = "https://api.openweathermap.org/data/2.5/weather"
    api_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    location = "Toronto"
    params = {
        "q": location,
        "appid": api_key,
        "units": "metric"
    }
    response = requests.get(url, params=params)
    if response.status_code == 200:
        data = response.json()
        temperature = data["main"]["temp"]
        description = data["weather"][0]["description"]
        print(f"The current temperature in {location} is {temperature}°C.")
        print(f"The weather is {description}.")
    else:
        print("Error: Failed to retrieve weather information.")

    Before we run our code, let’s break it down:

    1. We start by importing the requests module to make HTTP requests.
    2. We then set the url variable to the OpenWeather API endpoint.
    3. We set the api_key variable with our OpenWeather API key.
    4. We set the location variable to the desired location for which we want to retrieve weather information. For our example, this is "Toronto".
    5. We then create a dictionary called params with the parameters for the API request, including the location, API key, and desired units.
    6. A GET request is sent to the OpenWeather API using requests.get(), with url and params as arguments.
    7. We then check whether the response status code is 200 (indicating a successful request).
    8. If the response is successful, we parse the JSON data from the response using response.json() and then do the following:
      1. We extract the temperature and weather description from the parsed data.
      2. We then print the current temperature and weather information for the specified location.
    9. If there is an error (response status code other than 200), we print an error message indicating the failure to retrieve weather information.
  2. We save our code as weather-api-test.py and then run it by clicking on the green run button, hitting F5 on the keyboard, or clicking on the Run menu option at the top and then Run current script.

After we execute the code, we should observe a message in the Shell:

Figure 2.15 – OpenWeather API information on the weather in Toronto

Figure 2.15 – OpenWeather API information on the weather in Toronto

As we can see, it is 29.15 °C and clear in Toronto at the time of this writing. If the web service call did not work, we would’ve seen an Error: Failed to retrieve weather information error in the console.

With our understanding of how to use the OpenWeather API, we are now ready to use the Sense HAT to create our scrolling weather information ticker. For this, we may reuse much of the code we wrote for our scrolling stock ticker application.

Scrolling weather information on Sense HAT

As we highlighted in our previous project, the versatility of our scrolling stock ticker application allows us to adapt it to display various types of information beyond stocks. In this section, we will leverage this adaptability by integrating the OpenWeather API and our API key to transform our ticker into a dynamic weather display, scrolling real-time weather data such as temperature and current conditions. We will be able to reuse a lot of the code from the scrolling stock ticker. To create the scrolling ticker code, we do the following:

  1. We launch Thonny on our Raspberry Pi, activate the ch2-env Python virtual environment, and create a new tab. We will start with our imports:
    import requests
    from sense_hat import SenseHat
    import time

Important note

As we have already covered these imports with our scrolling stock ticker application, we do not need to cover them again.

  1. After our imports, we set our variables:
    api_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    location = 'Toronto'
    base_url = 'https://api.openweathermap.org/data/2.5/weather'
    params = {
        'q': location,
        'appid': api_key,
        'units': 'metric'
    }
    sense = SenseHat()
    sense.set_rotation(270)
    last_call_time = time.time() - 30
    last_weather_info = ""

    In this code block, we do the following:

    1. We start by assigning the api_key variable to our OpenWeather API key.
    2. We set the location variable to the desired location for which we want to retrieve weather information. For our example, this is 'Toronto'.
    3. We then set the base_url variable to the OpenWeather API endpoint.
    4. We create a dictionary called params with the parameters for the API request, including the location, API key, and desired units.
    5. A GET request is sent to the OpenWeather API using requests.get(), with url and params as arguments.
    6. We then create an instance of the SenseHat class and assign it to the sense variable to interact with the Sense HAT (or emulator).
    7. We set the rotation of the Sense HAT display to 270 degrees using sense.set_rotation(270). This is so that it matches the orientation of the Raspberry Pi in our custom case. We could comment this line out for the emulator.
    8. We set last_call_time to the current time minus 30 seconds.
    9. We then add last_weather_info, which is a variable that stores the previous weather information.
  2. Below our variable declarations, we implement an infinite loop to continuously display the weather ticker information; however, to comply with API rate limits of 60 requests per minute and 1,000,000 requests per month, we introduce a time delay of 30 seconds between each web service call. We type the following code below our variable declarations:
    while True:
        current_time = time.time()
        if current_time - last_call_time >= 30:
            response = requests.get(base_url,
                       params=params)
            data = response.json()
            temperature = data['main']['temp']
            description = data['weather'][0]['description']
            weather_info = f"{location}: {temperature}°C, {description}"
            last_weather_info = weather_info
            sense.show_message(weather_info, scroll_speed=0.05, text_colour=[255, 255, 255])
            last_call_time = current_time
        else:
            sense.show_message(last_weather_info, scroll_speed=0.05, text_colour=[255, 255, 255])
        time.sleep(1)
  3. As in our scrolling stock ticker application, the heart of our code is wrapped in a while True loop, which ensures continuous execution of the main code:
    1. We set the current_time variable to the current time using time.time().
    2. Our code then checks whether the difference between current_time and last_call_time is greater than or equal to 30 seconds.
    3. If True, the following happens:
      1. A GET request is sent to the OpenWeather API using requests.get(), with base_url and params as arguments.
      2. The response is parsed as JSON using response.json() and assigned to the data variable.
      3. We extract the temperature and weather description from the parsed data and store it as weather_info.
      4. The last_weather_info variable is updated to store the current weather_info value.
      5. weather_info is displayed on the Sense HAT’s dot-matrix display using sense.show_message(), with a scrolling speed of 0.05 seconds and white text color (255,255,255).
      6. The last_call_time variable is updated to the current time (current_time) to mark the timestamp of the last API call.
    4. If False, the previous last_weather_info variable is displayed on the Sense HAT display with a scrolling speed of 0.05 seconds and white text color (255,255,255).
    5. Our program then sleeps for 1 second using time.sleep(1) before the next iteration of the loop. This is done to regulate resource consumption and control the update frequency of the Sense HAT’s dot-matrix display.
  4. We save our code as weather-scroll.py and then run it by clicking on the green run button, hitting F5 on the keyboard, or clicking on the Run menu option at the top and then Run current script.

After we execute the code, we should observe weather information scrolling across the dot-matrix screen of the Sense HAT. If we are utilizing the emulator, a message will scroll across the simulated dot-matrix display. Figure 2.16 provides a visual representation of how this appears when using the emulator:

Figure 2.16 – Weather information scrolling across the simulated dot-matrix display

Figure 2.16 – Weather information scrolling across the simulated dot-matrix display

One key takeaway is the power of leveraging existing code to create new applications. Despite inherent differences between stock information and weather data, the process of obtaining information for both fields remain remarkably similar. With this realization, we unlock the potential to create a wide range of dynamic and engaging displays using the same underlying code structure.

Here are a few examples of other applications we could build:

  • News updates: By modifying the code, we can integrate our device with news APIs to display real-time headlines or updates from popular news sources.
  • Social media notifications: By connecting our application to social media APIs, we can configure it to display notifications from popular platforms such as Twitter or Facebook.
  • Sports scores: With the integration of sports data APIs, our stock ticker application can be transformed into a real-time sports scoreboard. It can display live scores, game updates, or upcoming game schedules.
  • Personalized reminders: By extending the functionality of the code, we can program the stock ticker application to display personalized reminders or to-do lists.

In our next and final project for the chapter, we will replace our scrolling text displays with dot-matrix images and animations. This shift from scrolling text elevates the user experience and will make our projects more visually appealing.

Developing a GO-NO-GO application for decision-making

Consider the role of a youth baseball league convener, responsible for ensuring the safety of playing fields. Critical to this responsibility is making weather-based decisions. If the field is excessively wet, it can impact gameplay, potentially leading to game postponements or cancellations:

Figure 2.17 – Should the game go on?

Figure 2.17 – Should the game go on?

Another factor to consider is the age of the players. For younger players, playing in the rain raises concerns, as parents are often present and may express dissatisfaction with unfavorable weather conditions. On the other hand, older players, who typically travel to games independently, may be less affected by wet conditions.

These decision-making scenarios represent an opportunity to develop an IoT application that displays a visual indicator, such as a GO or NO-GO graphic, based on weather conditions and player age (Figure 2.17). Imagine a setup with Raspberry Pi and Sense HATs for each baseball diamond, where the Sense HAT display provides real-time guidance on whether the game should proceed as scheduled, be postponed, or be canceled altogether. This IoT application enables efficient decision-making and enhances the overall experience and safety of the youth baseball league.

In our simplified example, we will focus on incorporating basic decision-making into our IoT application. Based on the age of the players and the presence of rain, the Sense HAT will show either a green checkmark or an animated red X sign. While we could introduce additional complexity, the primary objective of this exercise is to demonstrate how decision-making can be integrated into an IoT application. By incorporating these visual indicators, we empower real-time decision-making. Instead of relying solely on the convener, our IoT application takes charge by providing immediate guidance on whether games should proceed or be postponed.

We will start by writing Sense HAT code for indication. For GO, we will show a simple green checkmark against a black background. For NO-GO, we will display a flashing red X. We will run our application using the Sense HAT emulator as it is easier to display screenshots for this book; however, it is strongly encouraged to use the Sense HAT as this makes our application a true IoT device.

We will start by writing code to display a green checkmark.

Creating a checkmark on our Sense HAT

In this section, we will create code that displays a green checkmark against a black background on the Sense HAT emulator. To enhance code implementation and organization, we will encapsulate the functionality within a Python class. This approach simplifies the integration process and promotes code reusability, allowing us to easily incorporate the green checkmark display into our IoT application project.

Prior to writing the code for the GO-NO-GO application, we will create a project directory named GO-NO-GO on our Raspberry Pi. This dedicated folder will serve as a centralized location for organizing and managing files and resources associated with our project. To create the checkmark code, we do the following:

  1. We launch Thonny on our Raspberry Pi, activate the ch2-env virtual environment, and create a new tab. Inside the tab, we write the following code:
    from sense_emu import SenseHat
    class GreenCheck:
        black = (0, 0, 0)
        green = (0, 255, 0)
        check_mark_pixels = [
            black, black, black, black,
            black, black, black, green,
            black, black, black, black,
            black, black, green, green,
            black, black, black, black,
            black, black, green, green,
            black, black, black, black,
            black, green, green, black,
            green, black, black, black,
            green, green, black, black,
            black, green, black, black,
            green, green, black, black,
            black, green, green, green,
            green, black, black, black,
            black, black, black, green,
            black, black, black, black
        ]
        def __init__(self, rotation=0):
            self.sense = SenseHat()
            self.sense.set_rotation(rotation)
        def display(self):
            self.sense.set_pixels(self.check_mark_pixels)
    if __name__ == "__main__":
        greenCheck = GreenCheck(rotation = 270)
        greenCheck.display()

    In our code, we do the following:

    1. We start by importing the SenseHat class from the sense_hat module (use sense_emu for the emulator)
    2. We then define a GreenCheck class for displaying a green checkmark on the Sense HAT
    3. We set color values for black and green as RGB tuples.
    4. We then define a list of pixel values representing the checkmark shape.
    5. The GreenCheck class is initialized with an optional rotation parameter, which defaults to 0.
    6. Inside the __init__ method, we create a Sense HAT instance and set the rotation to the value of rotation.
    7. We define a display method that sets the Sense HAT’s pixels to the checkmark pixel values.
    8. We use if __name__ == "__main__" to check whether the code is being run directly (not imported).
    9. If True, we do the following:
      1. We create an instance of the GreenCheck class named greenCheck with a rotation value of 270.
      2. We call the display() method to show a green checkmark on the Sense HAT.
  2. We save our code as green_checkmark.py in the GO-NO-GO folder and then run it by clicking on the green run button, hitting F5 on the keyboard, or clicking on the Run menu option at the top and then Run current script.
  3. After we execute the code, we should see a green checkmark against a black background on our Sense HAT emulator:
Figure 2.18 – Green checkmark against black background on Sense HAT’s dot-matrix display

Figure 2.18 – Green checkmark against black background on Sense HAT’s dot-matrix display

With the completion of the green checkmark code, we will now shift our focus toward creating a NO-GO animation (flashing red X) for our application.

Creating a NO-GO animation on our Sense HAT

The NO-GO animation we have designed consists of a flashing effect on the Sense HAT emulator display, alternating between a red X sign on a black background and a full red display. To create code for the flashing X sign, we do the following:

  1. We launch Thonny on our Raspberry Pi, activate the ch2-env Python virtual environment, and create a new tab. Inside the tab, we start by importing the packages we need:
    from sense_emu import SenseHat
    import time
  2. Once we have our packages defined, we then start to wrap our code up in a Python class:
    class RedXAnimation:
        black = (0, 0, 0)
        red = (255, 0, 0)
        frame1 = [
            red, black, black, black,
            black, black, black, red,
            black, red, black, black,
            black, black, red, black,
            black, black, red, black,
            black, red, black, black,
            black, black, black, red,
            red, black, black, black,
            black, black, black, red,
            red, black, black, black,
            black, black, red, black,
            black, red, black, black,
            black, red, black, black,
            black, black, red, black,
            red, black, black, black,
            black, black, black, red
        ]
        frame2 = [
            red, red, red, red, red, red, red, red,
            red, red, red, red, red, red, red, red,
            red, red, red, red, red, red, red, red,
            red, red, red, red, red, red, red, red,
            red, red, red, red, red, red, red, red,
            red, red, red, red, red, red, red, red,
            red, red, red, red, red, red, red, red,
            red, red, red, red, red, red, red, red
        ]

    In our code, we do the following:

    1. We start by defining a RedXAnimation class.
    2. We then set color values for black and red as RGB tuples.
    3. We define frame1 as a list of pixel values representing a red X sign on a black background.
    4. We define frame2 as a list of pixel values representing a full red display.
  3. From here, we write code for the initialize method in the class:
        def __init__(self, rotation=0):
            self.sense = SenseHat()
            self.sense.set_rotation(rotation)

    In our code, we do the following:

    1. We use the __init__ method to initialize the RedXAnimation object with an optional rotation parameter (defaulted to 0).
    2. Inside __init__, a SenseHat instance is created, and the rotation is set based on the provided rotation value.
  4. The display_animation() method will cycle through the 2 frames for 59 seconds. We do this to align with future client code:
        def display_animation(self, duration):
            num_frames = 2
            frame_duration = duration / num_frames
            start_time = time.time()
            end_time = start_time + 59
            while time.time() < end_time:
                for frame in [self.frame1, self.frame2]:
                    self.sense.set_pixels(frame)
                    time.sleep(frame_duration)

    In our code, the following happens:

    1. Our display_animation() method takes a duration parameter.
    2. We set the number of frames to 2.
    3. We calculate the duration for each frame by dividing the total duration by the number of frames.
    4. We set the start_time variable to the current time using time.time().
    5. We calculate the end_time value by adding 59 seconds to the start_time variable.
    6. We create a loop that runs until the current time exceeds the end_time value:
      1. Our code iterates over each frame in the list [self.frame1, self.frame2].
      2. We set the Sense HAT display pixels to the current frame using self.sense.set_pixels(frame).
      3. We then pause the execution for the frame duration using time.sleep(frame_duration).
  5. We use the if __name__ == "__main__": block to ensure that the test code is executed only when the script is run directly (not imported as a module):
    if __name__ == "__main__":
        animation = RedXAnimation(rotation=270)
        animation.display_animation(duration=1)

    In our code, the following happens:

    1. An instance of the RedXAnimation class is created with a rotation value of 270 degrees, assigned to the animation variable.
    2. The display_animation() method of the animation object is called, specifying a duration of 1 second.
  6. We save our code as flashing_x.py in the GO-NO-GO folder and then run it by clicking on the green run button, hitting F5 on the keyboard, or clicking on the Run menu option at the top and then Run current script.

After executing the code, we should observe an animation of a red X sign against a black background turn into a full screen of red and back again. In Figure 2.19, we can see what this would look like on the emulator:

Figure 2.19 – NO-GO animation in red screen mode

Figure 2.19 – NO-GO animation in red screen mode

The NO-GO animation we have created in this section provides a highly effective visual indicator on the Sense HAT display. By alternating between a red X sign on a black background and a full red display, this animation conveys unfavorable conditions that would necessitate the cancellation of a game.

Setting the geolocation for other cities

For finding a city’s geolocation information such as latitude and longitude, websites such as GPS Coordinates (https://gps-coordinates.org/) and Latitude and Longitude Finder (https://www.latlong.net/) are useful. They allow us to input an address or place and receive its precise coordinates.

To finish off our application, we will now write the web service and logic layer, and we will incorporate our green checkmark and red X sign animation.

Writing GO-NO-GO client code

Now, it’s time to dive into the exciting phase (subjective, of course) of writing code to determine whether a game should be a GO or NO-GO based on weather conditions and the age of the players. Our approach will be straightforward: if it’s raining and the players are under 16 years of age, it’s a NO-GO; otherwise, it’s a GO. While we can certainly implement more complex logic, including Machine Learning (ML) if there are multiple parameters to consider, for simplicity, we’ll focus on this basic decision-making process. We do so with the following:

  1. To create the client code, we launch Thonny on our Raspberry Pi, activate our ch2-env Python virtual environment, and create a new tab. Inside the tab, we start by importing the packages we need:
    import requests
    import time
    from green_checkmark import GreenCheck
    from flashing_x import RedXAnimation

    We’ve covered the first three packages already. For the two modules, we do the following:

    • We import the GreenCheck class from the green_checkmark module to display a green checkmark for the GO decision.
    • We import the RedXAnimation class from the flashing_x module to display a flashing red X sign animation when the decision is NO-GO.
  2. With our packages and modules in place, we now set our variables:
    latitude = '42.346268'
    longitude = '-71.095764'
    go = GreenCheck(rotation=270)
    no_go = RedXAnimation(rotation=270)
    timer = 1
    age = 12
    base_url = "https://api.openweathermap.org/data/2.5/weather"
    api_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    params = {
        'lat': latitude,
        'lon': longitude,
        'appid': api_key,
        'units': 'metric'
    }

    In our code, we do the following:

    1. We set latitude to '42.346268' and longitude to '-71.095764' for our baseball diamond. For example, this is the GPS coordinates for Fenway Park in Boston, Massachusetts, US.
    2. We create a GreenCheck object named go with a rotation value of 270 degrees.
    3. We create a RedXAnimation object named no_go with a rotation value of 270 degrees.
    4. We set our timer value to 1 second.
    5. We set the age of our players to 12.
    6. Our code sets the base_url value to "https://api.openweathermap.org/data/2.5/weather".
    7. Next, we add our OpenWeather api_key value.
    8. We then define a params dictionary we will use with our web service call (latitude, longitude, api_key, and units).
  3. We use an infinite loop to check the weather conditions every 60 seconds and update the display on our Sense HAT accordingly:
    while True:
        response = requests.get(base_url, params=params)
        if response.status_code == 200:
            data = response.json()
            temperature = data['main']['temp']
            description = data['weather'][0]['main']
            print(f"The current temperature is {temperature}°C.")
            print(f"The weather is {description}.")
            if description == 'Thunderstorm' or description == 'Rain' and age < 16:
                print("NO-GO!")
                no_go.display_animation(duration=1)
                timer = 1
            else:
                print("GO!")
                go.display()
                timer = 60
        else:
            print("Error: Failed to retrieve weather information.")
        time.sleep(timer)

    In our code, we set up an infinite loop using while True:

    1. We make a GET request to the OpenWeather API using requests.get() and store the response in response.
    2. If the response status code is 200, we do the following:
      1. We parse the JSON response into a Python dictionary using response.json() and assign it to data.
      2. We then retrieve the current temperature from data['main']['temp'] and store it in temperature.
      3. We retrieve a weather description from data['weather'][0]['main'] and store it in description.
      4. We then print the current temperature and weather description. If the weather description is 'Thunderstorm' or ('Rain' and age < 16), we print "NO-GO!" to the Shell, display the NO-GO animation using no_go.display_animation(duration=1), and set the timer variable to 1 second. This is to make the total time before calling the web service 60 seconds, as the animation will go on for 59 seconds. Otherwise, we print "GO!" to the Shell and display the green checkmark animation using go.display() and then set the timer variable to 60 seconds.
    3. If the response status code is not 200, we print an error message.
    4. We pause the execution for the value of timer seconds using time.sleep(timer). This will result in a 60-second delay between calls to the OpenWeather web service.
  4. We save our code as go-no-go.py in the GO-NO-GO folder and then run it by clicking on the green run button, hitting F5 on the keyboard, or clicking on the Run menu option at the top and then Run current script.

    Upon running the code, we will observe the dot-matrix screen of our Sense HAT (or emulator) displaying either a green checkmark or a flashing red X sign, indicating a GO or NO-GO condition for a game at Fenway Park in Boston. As illustrated in Figure 2.20, the current status is a NO-GO for the game involving our players (under 16 years of age) due to the presence of thunderstorms:

Figure 2.20 – Screenshot of the GO-NO-GO application using the Sense HAT emulator

Figure 2.20 – Screenshot of the GO-NO-GO application using the Sense HAT emulator

As mentioned earlier, the flexibility of our code allows for easy expansion of the decision-making logic. In addition to weather data, we can extend our application to consider other factors such as wind speed, humidity, or any on-site sensor readings. By integrating sensors placed directly at the baseball diamond, we can gather real-time data on soil moisture levels or other measurements of interest. This sensor information can then be broadcasted to the internet, enabling us to seamlessly integrate it into our application.

To make our application more dynamic, we can incorporate scheduling information to determine the age of players scheduled to play at a specific baseball diamond at any given time. By extracting this information from a spreadsheet or an online repository, we can automate the process of obtaining player age data and other game-related information such as whether the game is a playoff game. This allows our application to dynamically adjust its decision-making process, ensuring a more accurate GO or NO-GO decision.

Building other GO-NO-GO applications

The GO-NO-GO application marks the last project in the book we will build using the Sense HAT. As we have demonstrated, the combination of the Raspberry Pi and Sense HAT makes for a powerful IoT device. It’s not hard to imagine how we could easily change our baseball GO-NO-GO application for other scenarios. The following are a few examples of other GO-NO-GO applications we could build:

  • Flight status checker: By integrating with a flight tracking API, we could build an application that can display a GO or NO-GO status for a specific flight.
  • Traffic condition monitor: Utilizing a traffic data API, we could build an application that can assess current traffic conditions on a specific route or at a particular location.
  • Event availability indicator: Integrating with an event ticketing API, we could build an application that can determine the availability of tickets for a desired event.
  • Public transportation tracker: By connecting to a public transportation API, we could build an application that can provide real-time updates on the status of buses, trains, or other forms of public transportation.

The GO-NO-GO IoT application is but a glimpse into our vast potential in utilizing web services with IoT. With the Raspberry Pi and Sense HAT, our potential expands to diverse IoT applications, monitoring various data and fostering innovation beyond weather-related scenarios.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime