Home » #Technology » Building a Weather Station with Raspberry Pi: Collecting and Pushing Data to an API

Building a Weather Station with Raspberry Pi: Collecting and Pushing Data to an API

With over 18 years of experience driving innovation in the tech corporate field, advising startups is a crucial part of my role in building the right tech solutions. While consulting for an IoT tech company, I helped them create their data command center. Now, I’ve decided to write this post on IoT concepts. Ready to dive into the exciting world of IoT? Let’s walk through the process of creating a weather station using a Raspberry Pi. You’ll learn how to gather temperature, humidity, and pressure data from sensors and push it to a REST API for storage and analysis.

Requirements

Hardware

To build your weather station, gather the following components:

  • Raspberry Pi: Any model with Wi-Fi capability will work.
  • DHT22 or DHT11 Sensor: These sensors measure temperature and humidity.
  • BMP180 Sensor: This sensor measures atmospheric pressure. (optional)
  • Breadboard and Jumper Wires: For connecting the sensors.
  • Power Supply: To power your Raspberry Pi.
Software

Make sure your Raspberry Pi is equipped with:

  • Raspberry Pi OS: The latest version is recommended.
  • Python 3: Go to programming language in modern development.
  • Flask: A lightweight framework to create the API.
  • Requests, Adafruit-DHT Library: A library for making HTTP requests and reading sensor data.
  • MySQL: To store the sensor data.

Step 1: Setting Up the Raspberry Pi

Begin by installing the necessary libraries on your Raspberry Pi. Open the terminal and run:

sudo apt update
sudo apt install python3-pip
pip3 install requests Adafruit-DHT

Step 2: Collecting Data from Sensors

Now, let’s write a function to read data from the DHT22 sensor and simulate reading from the BMP180 sensor:

import Adafruit_DHT
import requests
import time
import random

# Define sensor type and GPIO pin, this will set-up the GPIO pins for the sensors:
DHT_SENSOR = Adafruit_DHT.DHT22
DHT_PIN = 4  # Replace with your GPIO pin number

# API endpoint
API_URL = 'http://<your_api_server>/api/weather'  # Replace with your API URL

def read_sensors():
    """Read data from sensors."""
    humidity, temperature = Adafruit_DHT.read_retry(DHT_SENSOR, DHT_PIN)
    
    # Simulating pressure data as BMP180 reading
    pressure = round(random.uniform(980.0, 1050.0), 2)  # Dummy pressure data
    
    return temperature, humidity, pressure

def push_data_to_api(temperature, humidity, pressure):
    """Push collected data to the API."""
    data = {
        "temperature": temperature,
        "humidity": humidity,
        "pressure": pressure
    }
    
    try:
        response = requests.post(API_URL, json=data)
        if response.status_code == 200:
            print("Data pushed successfully:", response.json())
        else:
            print("Failed to push data:", response.status_code, response.text)
    except Exception as e:
        print("Error pushing data:", e)

def main():
    while True:
        temperature, humidity, pressure = read_sensors()
        
        if humidity is not None and temperature is not None:
            print(f"Temperature: {temperature:.1f}°C, Humidity: {humidity:.1f}%, Pressure: {pressure:.1f} hPa")
            push_data_to_api(temperature, humidity, pressure)
        else:
            print("Failed to retrieve data from the sensor")

        time.sleep(60)  # Push data every minute

if __name__ == '__main__':
    main()

Step 3: Creating the API to Push Data

The next step is to collect the data at the central command center (Server, running on cloud platform). To accomplish this, create an API that will receive and store the data in the database. Set up a Flask application to build the REST API that will handle and accept the incoming weather data:

from flask import Flask, request
import mysql.connector

app = Flask(__name__)

@app.route('/api/weather', methods=['POST'])
def push_data():
    data = request.json
    temperature = data['temperature']
    humidity = data['humidity']
    pressure = data['pressure']

    # Save to database (example with MySQL)
    db = mysql.connector.connect(user='your_user', password='your_pass', host='localhost', database='weather_db')
    cursor = db.cursor()
    cursor.execute("INSERT INTO weather (temperature, humidity, pressure) VALUES (%s, %s, %s)", (temperature, humidity, pressure))
    db.commit()
    cursor.close()
    db.close()
    return {"message": "Data saved successfully!"}, 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Step 4: Creating the API to Get the Last 7 Days Data Trend

Upon receiving the data at the central command center, we will share it for further analysis. To achieve this, extend the Flask application by adding an endpoint to retrieve weather data trends from the past 7 days:

@app.route('/api/weather/trend', methods=['GET'])
def get_trend():
    db = mysql.connector.connect(user='your_user', password='your_pass', host='localhost', database='weather_db')
    cursor = db.cursor(dictionary=True)
    cursor.execute("SELECT * FROM weather WHERE timestamp >= NOW() - INTERVAL 7 DAY")
    results = cursor.fetchall()
    cursor.close()
    db.close()
    return {"data": results}, 200

Step 5: Storing Data in the Database

To save data, we rely on MySQL, a go-to, easily configurable database. Let’s now create a MySQL database to store the weather data:

CREATE TABLE weather (
    id INT AUTO_INCREMENT PRIMARY KEY,
    temperature FLOAT,
    humidity FLOAT,
    pressure FLOAT,
    timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);

Step 6: Mock Script to Push Dummy Data

Even without a Raspberry Pi, you can create a script to simulate pushing data to the API. This is essential for testing purposes:

import requests
import random
import time

# API endpoint
API_URL = 'http://<your_api_server>/api/weather'  # Replace with your API URL

def push_data_to_api(temperature, humidity, pressure):
    """Push collected data to the API."""
    data = {
        "temperature": temperature,
        "humidity": humidity,
        "pressure": pressure
    }

    try:
        response = requests.post(API_URL, json=data)
        if response.status_code == 200:
            print("Data pushed successfully:", response.json())
        else:
            print("Failed to push data:", response.status_code, response.text)
    except Exception as e:
        print("Error pushing data:", e)

def main():
    while True:
        # Simulate reading sensor data
        temperature = round(random.uniform(20.0, 30.0), 2)
        humidity = round(random.uniform(40.0, 60.0), 2)
        pressure = round(random.uniform(980.0, 1050.0), 2)

        print(f"Temperature: {temperature:.1f}°C, Humidity: {humidity:.1f}%, Pressure: {pressure:.1f} hPa")
        push_data_to_api(temperature, humidity, pressure)

        time.sleep(60)  # Push data every minute

if __name__ == '__main__':
    main()

This tech-concept post gives you the head start needed to build your first IoT project, focusing on reading and storing data on a server. You can easily find Raspberry Pi basics and hardware connection tutorials on YouTube. This IoT project will not only boost your understanding of IoT but also lay a strong foundation for further exploration. Experiment by adding more sensors or integrating visualization tools to display your data. Be sure to share your experience and improvements with the open tech community!

#AskDushyant
#TechConcept #IoT #RespberryPi #Mysql #Python #Api 
Note: The example and pseudo code is for illustration only. You must modify and experiment with the concept to meet your specific needs.

Leave a Reply

Your email address will not be published. Required fields are marked *