iot
DHT sensor library
Adafruit Unified Sensor

1.Develop an ESP32 program to read temperature and humidity values using a DHT22 sensor and display the readings using serial communication.

sketch.ino:

#include "DHT.h"

#define DHTPIN 4
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);

  dht.begin();

  Serial.println("DHT22 Sensor Started");
}

void loop() {
  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();

  if (isnan(humidity) || isnan(temperature)) {
    Serial.println("Failed to read from DHT22 sensor!");
    delay(2000);
    return;
  }

  Serial.print("Temperature: ");
  Serial.print(temperature);
  Serial.println(" °C");

  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.println(" %");

  Serial.println("--------------------");

  delay(2000);
}

diagram.json:


{
  "version": 1,
  "author": "Tony",
  "editor": "wokwi",
  "parts": [
    {
      "type": "board-esp32-devkit-c-v4",
      "id": "esp",
      "top": 0,
      "left": 0,
      "attrs": {}
    },
    {
      "type": "wokwi-dht22",
      "id": "dht",
      "top": -20,
      "left": 200,
      "attrs": {}
    }
  ],
  "connections": [
    ["esp:TX", "$serialMonitor:RX", "", []],
    ["esp:RX", "$serialMonitor:TX", "", []],
    ["dht:VCC", "esp:3V3", "red", []],
    ["dht:GND", "esp:GND.1", "black", []],
    ["dht:SDA", "esp:4", "green", []]
  ],
  "dependencies": {}
}


2.Develop an ESP32 program to read light intensity using an LDR module and display the readings using serial communication.

sketch.ino:


#define LDR_PIN 34

void setup() {
  Serial.begin(115200);

  Serial.println("LDR Sensor Started");
}

void loop() {
  int lightValue = analogRead(LDR_PIN);

  Serial.print("Light Intensity: ");
  Serial.println(lightValue);

  if (lightValue < 1500) {
    Serial.println("Low Light");
  }
  else if (lightValue < 3000) {
    Serial.println("Medium Light");
  }
  else {
    Serial.println("High Light");
  }

  Serial.println("--------------------");

  delay(1000);
}


diagram.json:


{
  "version": 1,
  "author": "Tony",
  "editor": "wokwi",
  "parts": [
    {
      "type": "board-esp32-devkit-c-v4",
      "id": "esp",
      "top": 0,
      "left": 0,
      "attrs": {}
    },
    {
      "type": "wokwi-photoresistor-sensor",
      "id": "ldr",
      "top": -20,
      "left": 200,
      "attrs": {}
    }
  ],
  "connections": [
    ["esp:TX", "$serialMonitor:RX", "", []],
    ["esp:RX", "$serialMonitor:TX", "", []],
    ["ldr:VCC", "esp:3V3", "red", []],
    ["ldr:GND", "esp:GND.1", "black", []],
    ["ldr:AO", "esp:34", "green", []]
  ],
  "dependencies": {}
}


3.Develop an ESP32 program to detect motion using a PIR sensor and display the detection status using serial communication.

sketch.ino:


#define PIR_PIN 4

void setup() {
  Serial.begin(115200);

  pinMode(PIR_PIN, INPUT);

  Serial.println("PIR Motion Detection Started");
}

void loop() {
  int motion = digitalRead(PIR_PIN);

  if (motion == HIGH) {
    Serial.println("Motion Detected!");
  }
  else {
    Serial.println("No Motion");
  }

  delay(1000);
}


diagram.json:


{
  "version": 1,
  "author": "Tony",
  "editor": "wokwi",
  "parts": [
    {
      "type": "board-esp32-devkit-c-v4",
      "id": "esp",
      "top": 0,
      "left": 0,
      "attrs": {}
    },
    {
      "type": "wokwi-pir-motion-sensor",
      "id": "pir",
      "top": -20,
      "left": 200,
      "attrs": {}
    }
  ],
  "connections": [
    ["esp:TX", "$serialMonitor:RX", "", []],
    ["esp:RX", "$serialMonitor:TX", "", []],
    ["pir:VCC", "esp:3V3", "red", []],
    ["pir:GND", "esp:GND.1", "black", []],
    ["pir:OUT", "esp:4", "green", []]
  ],
  "dependencies": {}
}


4.Develop an ESP32 program to read temperature and humidity data and publish it to an MQTT broker, and develop a Python subscriber program to receive and display the published data.


pip install paho-mqtt

sketch.ino:


#include <WiFi.h>
#include <PubSubClient.h>
#include "DHT.h"

// DHT22 configuration
#define DHTPIN 4
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);

// WiFi configuration
const char* ssid = "Wokwi-GUEST";
const char* password = "";

// MQTT broker configuration
const char* mqtt_server = "test.mosquitto.org";
const int mqtt_port = 1883;
const char* topic = "tony/iot/dht22";

WiFiClient espClient;
PubSubClient client(espClient);

void connectWiFi() {
  Serial.print("Connecting to WiFi");

  WiFi.begin(ssid, password, 6);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("\nWiFi Connected!");
}

void reconnectMQTT() {
  while (!client.connected()) {
    Serial.print("Connecting to MQTT...");

    if (client.connect("ESP32_DHT22_Tony")) {
      Serial.println("Connected!");
    }
    else {
      Serial.print("Failed, state: ");
      Serial.println(client.state());
      delay(2000);
    }
  }
}

void setup() {
  Serial.begin(115200);

  dht.begin();

  connectWiFi();

  client.setServer(mqtt_server, mqtt_port);

  Serial.println("DHT22 MQTT Publisher Started");
}

void loop() {
  if (!client.connected()) {
    reconnectMQTT();
  }

  client.loop();

  float temperature = dht.readTemperature();
  float humidity = dht.readHumidity();

  if (isnan(temperature) || isnan(humidity)) {
    Serial.println("DHT22 Read Failed!");
    delay(2000);
    return;
  }

  String payload = "{";
  payload += "\"temperature\":" + String(temperature, 2) + ",";
  payload += "\"humidity\":" + String(humidity, 2);
  payload += "}";

  client.publish(topic, payload.c_str());

  Serial.print("Published: ");
  Serial.println(payload);

  delay(5000);
}


diagram.json:


{
  "version": 1,
  "author": "Tony",
  "editor": "wokwi",
  "parts": [
    {
      "type": "board-esp32-devkit-c-v4",
      "id": "esp",
      "top": 0,
      "left": 0,
      "attrs": {}
    },
    {
      "type": "wokwi-dht22",
      "id": "dht",
      "top": -20,
      "left": 200,
      "attrs": {}
    }
  ],
  "connections": [
    ["esp:TX", "$serialMonitor:RX", "", []],
    ["esp:RX", "$serialMonitor:TX", "", []],
    ["dht:VCC", "esp:3V3", "red", []],
    ["dht:GND", "esp:GND.1", "black", []],
    ["dht:SDA", "esp:4", "green", []]
  ],
  "dependencies": {}
}

subscriber.py:


import paho.mqtt.client as mqtt

# MQTT broker configuration
BROKER = "test.mosquitto.org"
PORT = 1883
TOPIC = "tony/iot/dht22"

# Callback when connected
def on_connect(client, userdata, flags, rc):
    print("Connected to MQTT Broker!")

    client.subscribe(TOPIC)

    print("Subscribed to:", TOPIC)


# Callback when a message arrives
def on_message(client, userdata, msg):
    print("\nReceived MQTT Message:")
    print(msg.payload.decode())


# Create MQTT client
client = mqtt.Client()

client.on_connect = on_connect
client.on_message = on_message

# Connect to broker
client.connect(BROKER, PORT, 60)

print("Waiting for sensor data...")

# Keep receiving messages
client.loop_forever()



5.Develop an application that send temperature and humidity sensor data to a cloud server through an HTTP-based REST API, stores the received data in a cloud database(Supabase / Firebase), and displays the sensor readings on a web-based dashboard.

pip install flask requests supabase python-dotenv

iot_http_dashboard/
│
├── app.py
├── sensor.py
├── .env
├── requirements.txt
│
└── templates/
    └── index.html

supabase:

CREATE TABLE sensor_readings (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    temperature FLOAT NOT NULL,
    humidity FLOAT NOT NULL,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

.env:

SUPABASE_URL=https://YOUR_PROJECT_ID.supabase.co
SUPABASE_KEY=YOUR_SERVICE_ROLE_KEY

app.py:


from flask import Flask, request, jsonify, render_template
from supabase import create_client
from dotenv import load_dotenv
import os

load_dotenv()

app = Flask(__name__)

# Supabase connection
SUPABASE_URL = os.getenv("SUPABASE_URL")
SUPABASE_KEY = os.getenv("SUPABASE_KEY")

supabase = create_client(SUPABASE_URL, SUPABASE_KEY)


# Dashboard
@app.route("/")
def dashboard():
    return render_template("index.html")


# REST API: Receive and store sensor data
@app.route("/api/readings", methods=["POST"])
def receive_data():
    data = request.get_json()

    if not data or "temperature" not in data or "humidity" not in data:
        return jsonify({"error": "Invalid sensor data"}), 400

    reading = {
        "temperature": float(data["temperature"]),
        "humidity": float(data["humidity"])
    }

    result = supabase.table("sensor_readings").insert(reading).execute()

    return jsonify({
        "message": "Data stored successfully",
        "data": result.data
    }), 201


# REST API: Retrieve sensor records
@app.route("/api/readings", methods=["GET"])
def get_data():
    result = (
        supabase.table("sensor_readings")
        .select("*")
        .order("created_at", desc=True)
        .limit(50)
        .execute()
    )

    return jsonify(result.data)


if __name__ == "__main__":
    app.run(debug=True)

sensor.py:


import requests
import random
import time

URL = "http://127.0.0.1:5000/api/readings"

print("Temperature and Humidity Sensor Started")

while True:

    temperature = round(random.uniform(20, 40), 2)
    humidity = round(random.uniform(40, 90), 2)

    data = {
        "temperature": temperature,
        "humidity": humidity
    }

    try:
        response = requests.post(URL, json=data)

        print("Temperature:", temperature, "°C")
        print("Humidity:", humidity, "%")
        print("Server Response:", response.json())
        print("--------------------------")

    except requests.exceptions.RequestException as e:
        print("Connection Error:", e)

    time.sleep(5)


templates/index.html:


<!DOCTYPE html>
<html>
<head>
    <title>IoT Sensor Dashboard</title>

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <style>
        body {
            font-family: Arial;
            background: #eef2f7;
            text-align: center;
            padding: 30px;
        }

        h1 {
            color: #1e293b;
        }

        .cards {
            display: flex;
            justify-content: center;
            gap: 20px;
            flex-wrap: wrap;
        }

        .card {
            background: white;
            padding: 25px;
            width: 220px;
            border-radius: 12px;
            box-shadow: 0 3px 10px #ccc;
        }

        .value {
            font-size: 35px;
            color: #2563eb;
            font-weight: bold;
        }

        table {
            margin: 30px auto;
            width: 90%;
            background: white;
            border-collapse: collapse;
        }

        th, td {
            padding: 12px;
            border: 1px solid #ddd;
        }

        th {
            background: #2563eb;
            color: white;
        }
    </style>
</head>

<body>

    <h1>IoT Temperature & Humidity Dashboard</h1>

    <div class="cards">

        <div class="card">
            <h2>Temperature</h2>
            <div class="value" id="temperature">-- °C</div>
        </div>

        <div class="card">
            <h2>Humidity</h2>
            <div class="value" id="humidity">-- %</div>
        </div>

    </div>

    <h2>Sensor Reading History</h2>

    <table>
        <thead>
            <tr>
                <th>Temperature (°C)</th>
                <th>Humidity (%)</th>
                <th>Timestamp</th>
            </tr>
        </thead>

        <tbody id="readings"></tbody>
    </table>

    <script>
        async function loadReadings() {

            const response = await fetch("/api/readings");
            const data = await response.json();

            if (data.length > 0) {

                document.getElementById("temperature").innerText =
                    data[0].temperature + " °C";

                document.getElementById("humidity").innerText =
                    data[0].humidity + " %";
            }

            const table = document.getElementById("readings");

            table.innerHTML = "";

            data.forEach(item => {

                const row = `
                    <tr>
                        <td>${item.temperature}</td>
                        <td>${item.humidity}</td>
                        <td>${new Date(item.created_at).toLocaleString()}</td>
                    </tr>
                `;

                table.innerHTML += row;
            });
        }

        loadReadings();

        setInterval(loadReadings, 5000);
    </script>

</body>
</html>


6.Develop a dashboard that receives sensor data through the MQTT protocol, stores the data in a cloud database (Supabase / Firebase), retrieves the stored records using a web application, and displays the sensor readings on a web dashboard.

pip install flask paho-mqtt supabase python-dotenv


iot_mqtt_dashboard/
│
├── app.py
├── publisher.py
├── .env
├── requirements.txt
│
└── templates/
    └── index.html


supabase:

CREATE TABLE mqtt_readings (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    temperature FLOAT NOT NULL,
    humidity FLOAT NOT NULL,
    created_at TIMESTAMPTZ DEFAULT NOW()
);


.env:

SUPABASE_URL=https://YOUR_PROJECT_ID.supabase.co
SUPABASE_KEY=YOUR_SERVICE_ROLE_KEY

publisher.py:


import paho.mqtt.client as mqtt
import random
import json
import time

BROKER = "test.mosquitto.org"
PORT = 1883
TOPIC = "tony/iot/sensor"

client = mqtt.Client(
    callback_api_version=mqtt.CallbackAPIVersion.VERSION2,
    client_id="tony_sensor_publisher"
)

client.connect(BROKER, PORT, 60)
client.loop_start()

print("MQTT Publisher Started")

try:
    while True:

        temperature = round(random.uniform(20, 40), 2)
        humidity = round(random.uniform(40, 90), 2)

        data = {
            "temperature": temperature,
            "humidity": humidity
        }

        payload = json.dumps(data)

        client.publish(TOPIC, payload)

        print("Published:", payload)

        time.sleep(5)

except KeyboardInterrupt:
    print("Publisher Stopped")

finally:
    client.loop_stop()
    client.disconnect()


app.py:


from flask import Flask, jsonify, render_template
from supabase import create_client
from dotenv import load_dotenv
import paho.mqtt.client as mqtt
import os
import json
import threading

load_dotenv()

app = Flask(__name__)

# Supabase connection
supabase = create_client(
    os.getenv("SUPABASE_URL"),
    os.getenv("SUPABASE_KEY")
)

# MQTT configuration
BROKER = "test.mosquitto.org"
PORT = 1883
TOPIC = "tony/iot/sensor"


# MQTT callback
def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected to MQTT Broker!")
    client.subscribe(TOPIC)
    print("Subscribed to:", TOPIC)


# Receive MQTT messages
def on_message(client, userdata, msg):

    try:
        data = json.loads(msg.payload.decode())

        temperature = float(data["temperature"])
        humidity = float(data["humidity"])

        reading = {
            "temperature": temperature,
            "humidity": humidity
        }

        # Store in Supabase
        supabase.table("mqtt_readings").insert(reading).execute()

        print("Received and Stored:", reading)

    except Exception as e:
        print("Error:", e)


# MQTT subscriber
mqtt_client = mqtt.Client(
    callback_api_version=mqtt.CallbackAPIVersion.VERSION2,
    client_id="tony_dashboard_subscriber"
)

mqtt_client.on_connect = on_connect
mqtt_client.on_message = on_message


# Start MQTT in background thread
def start_mqtt():

    mqtt_client.connect(BROKER, PORT, 60)
    mqtt_client.loop_forever()


threading.Thread(target=start_mqtt, daemon=True).start()


# Dashboard
@app.route("/")
def dashboard():
    return render_template("index.html")


# Retrieve records from Supabase
@app.route("/api/readings")
def get_readings():

    result = (
        supabase.table("mqtt_readings")
        .select("*")
        .order("created_at", desc=True)
        .limit(50)
        .execute()
    )

    return jsonify(result.data)


if __name__ == "__main__":
    app.run(debug=True, use_reloader=False)


templates/index.html:


<!DOCTYPE html>
<html>
<head>
    <title>MQTT IoT Dashboard</title>

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <style>
        body {
            font-family: Arial;
            background: #eef2f7;
            text-align: center;
            padding: 30px;
        }

        h1 {
            color: #1e293b;
        }

        .cards {
            display: flex;
            justify-content: center;
            gap: 20px;
            flex-wrap: wrap;
        }

        .card {
            background: white;
            padding: 25px;
            width: 220px;
            border-radius: 12px;
            box-shadow: 0 3px 10px #ccc;
        }

        .value {
            font-size: 35px;
            color: #2563eb;
            font-weight: bold;
        }

        table {
            margin: 30px auto;
            width: 90%;
            background: white;
            border-collapse: collapse;
        }

        th, td {
            padding: 12px;
            border: 1px solid #ddd;
        }

        th {
            background: #2563eb;
            color: white;
        }
    </style>
</head>

<body>

    <h1>MQTT IoT Sensor Dashboard</h1>

    <div class="cards">

        <div class="card">
            <h2>Temperature</h2>
            <div class="value" id="temperature">-- °C</div>
        </div>

        <div class="card">
            <h2>Humidity</h2>
            <div class="value" id="humidity">-- %</div>
        </div>

    </div>

    <h2>Sensor Reading History</h2>

    <table>
        <thead>
            <tr>
                <th>Temperature (°C)</th>
                <th>Humidity (%)</th>
                <th>Timestamp</th>
            </tr>
        </thead>

        <tbody id="readings"></tbody>
    </table>

    <script>
        async function loadReadings() {

            const response = await fetch("/api/readings");
            const data = await response.json();

            if (data.length > 0) {

                document.getElementById("temperature").innerText =
                    data[0].temperature + " °C";

                document.getElementById("humidity").innerText =
                    data[0].humidity + " %";
            }

            const table = document.getElementById("readings");

            table.innerHTML = "";

            data.forEach(item => {

                table.innerHTML += `
                    <tr>
                        <td>${item.temperature}</td>
                        <td>${item.humidity}</td>
                        <td>${new Date(item.created_at).toLocaleString()}</td>
                    </tr>
                `;
            });
        }

        loadReadings();

        setInterval(loadReadings, 5000);
    </script>

</body>
</html>

7.Develop an IoT application that simulates temperature and humidity sensor data, publishes the data to ThingsBoard using the MQTT protocol, and visualizes the sensor readings on the ThingsBoard dashboard.

pip install paho-mqtt

thingsboard_iot/
│
└── publisher.py

publisher.py:


import paho.mqtt.client as mqtt
import random
import json
import time

# ThingsBoard configuration
BROKER = "mqtt.thingsboard.cloud"
PORT = 1883

# Replace with your ThingsBoard device access token
ACCESS_TOKEN = "YOUR_DEVICE_ACCESS_TOKEN"

# MQTT topic for ThingsBoard telemetry
TOPIC = "v1/devices/me/telemetry"


# Create MQTT client
client = mqtt.Client(
    client_id="temperature_sensor"
)

# Authenticate using device access token
client.username_pw_set(ACCESS_TOKEN)

# Connect to ThingsBoard
print("Connecting to ThingsBoard...")

client.connect(BROKER, PORT, 60)

client.loop_start()

print("Connected to ThingsBoard!")
print("Publishing sensor data...")


try:
    while True:

        # Simulate sensor readings
        temperature = round(random.uniform(20, 40), 2)
        humidity = round(random.uniform(40, 90), 2)

        # Prepare JSON telemetry
        data = {
            "temperature": temperature,
            "humidity": humidity
        }

        payload = json.dumps(data)

        # Publish telemetry
        result = client.publish(TOPIC, payload)

        result.wait_for_publish()

        print("Published:", payload)

        time.sleep(5)


except KeyboardInterrupt:
    print("Stopping sensor...")


finally:
    client.loop_stop()
    client.disconnect()

    print("Disconnected from ThingsBoard")



8.Develop a CoAP Server and CoAP Client to exchange IoT sensor data, where the current sensor data is transferred from the server to a dashboard.

pip install aiocoap flask

coap_environment/
│
├── server.py
├── client.py
├── app.py
│
└── templates/
    └── index.html


server.py:


import asyncio
import json
import random

from aiocoap import resource, Message
from aiocoap import Context, GET


class SensorResource(resource.Resource):

    async def render_get(self, request):

        temperature = round(random.uniform(20, 40), 2)
        humidity = round(random.uniform(40, 90), 2)

        data = {
            "temperature": temperature,
            "humidity": humidity
        }

        print("Sensor Data Generated:", data)

        return Message(
            payload=json.dumps(data).encode("utf-8")
        )


async def main():

    site = resource.Site()

    site.add_resource(
        ["sensor"],
        SensorResource()
    )

    await Context.create_server_context(
        site,
        bind=("127.0.0.1", 5683)
    )

    print("CoAP Server Started")
    print("Server Address: coap://127.0.0.1:5683")
    print("Sensor Resource: /sensor")

    await asyncio.get_running_loop().create_future()


if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("CoAP Server Stopped")

client.py:


import asyncio
import json

from aiocoap import Context, Message, GET


async def main():

    protocol = await Context.create_client_context()

    request = Message(
        code=GET,
        uri="coap://127.0.0.1:5683/sensor"
    )

    print("Sending CoAP GET Request...")

    response = await protocol.request(request).response

    data = json.loads(response.payload.decode())

    print("\nReceived Sensor Data")
    print("Temperature:", data["temperature"], "°C")
    print("Humidity:", data["humidity"], "%")

    await protocol.shutdown()


if __name__ == "__main__":
    asyncio.run(main())


app.py:


from flask import Flask, jsonify, render_template
import asyncio
import json

from aiocoap import Context, Message, GET

app = Flask(__name__)


async def get_sensor_data():

    protocol = await Context.create_client_context()

    try:
        request = Message(
            code=GET,
            uri="coap://127.0.0.1:5683/sensor"
        )

        response = await protocol.request(request).response

        return json.loads(response.payload.decode())

    finally:
        await protocol.shutdown()


@app.route("/")
def dashboard():
    return render_template("index.html")


@app.route("/api/sensor")
def sensor_data():

    try:
        data = asyncio.run(get_sensor_data())
        return jsonify(data)

    except Exception as e:
        return jsonify({"error": str(e)}), 500


if __name__ == "__main__":
    app.run(debug=True, use_reloader=False)


templates/index.html:


<!DOCTYPE html>
<html>
<head>
    <title>CoAP Environmental Dashboard</title>

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <style>
        body {
            font-family: Arial;
            background: #eef2f7;
            text-align: center;
            padding: 30px;
        }

        h1 {
            color: #1e293b;
        }

        .container {
            display: flex;
            justify-content: center;
            gap: 20px;
            flex-wrap: wrap;
        }

        .card {
            background: white;
            padding: 30px;
            width: 220px;
            border-radius: 12px;
            box-shadow: 0 3px 10px #ccc;
        }

        .value {
            font-size: 35px;
            color: #2563eb;
            font-weight: bold;
        }

        button {
            padding: 12px 25px;
            background: #2563eb;
            color: white;
            border: none;
            border-radius: 6px;
            cursor: pointer;
        }

        #status {
            margin: 20px;
        }
    </style>
</head>

<body>

    <h1>CoAP Environmental Monitoring</h1>

    <div class="container">

        <div class="card">
            <h2>Temperature</h2>
            <div class="value" id="temperature">-- °C</div>
        </div>

        <div class="card">
            <h2>Humidity</h2>
            <div class="value" id="humidity">-- %</div>
        </div>

    </div>

    <h3 id="status">Waiting for sensor data...</h3>

    <button onclick="loadData()">Get Latest Readings</button>

    <script>
        async function loadData() {

            document.getElementById("status").innerText =
                "Requesting data using CoAP GET...";

            try {

                const response = await fetch("/api/sensor");
                const data = await response.json();

                if (!response.ok) {
                    throw new Error(data.error || "Request failed");
                }

                document.getElementById("temperature").innerText =
                    data.temperature + " °C";

                document.getElementById("humidity").innerText =
                    data.humidity + " %";

                document.getElementById("status").innerText =
                    "Sensor data received successfully!";

            }
            catch (error) {

                document.getElementById("status").innerText =
                    "Error: " + error.message;

            }
        }

        loadData();

        setInterval(loadData, 5000);
    </script>

</body>
</html>


9.Implement MQTT communication using both an online MQTT broker (HiveMQ) and a local offline MQTT broker (Eclipse Mosquitto)  to publish, receive, and display IoT sensor data.

pip install paho-mqtt

mosquitto -h

mosquitto -v

mqtt_broker_demo/
│
├── publisher.py
└── subscriber.py

publisher.py:


import paho.mqtt.client as mqtt
import random
import json
import time

# Choose: "online" or "offline"
MODE = "online"

if MODE == "online":
    BROKER = "broker.hivemq.com"
else:
    BROKER = "127.0.0.1"

PORT = 1883

TOPIC = "tony/iot/environment"


client = mqtt.Client(
    client_id="tony_publisher"
)

print("Connecting to:", BROKER)

client.connect(BROKER, PORT, 60)

client.loop_start()

print("MQTT Publisher Started")

try:

    while True:

        temperature = round(random.uniform(20, 40), 2)
        humidity = round(random.uniform(40, 90), 2)

        data = {
            "temperature": temperature,
            "humidity": humidity
        }

        payload = json.dumps(data)

        client.publish(TOPIC, payload)

        print("Published:", payload)

        time.sleep(5)

except KeyboardInterrupt:
    print("Publisher stopped")

finally:
    client.loop_stop()
    client.disconnect()


subscriber.py:


import paho.mqtt.client as mqtt
import json

# Choose: "online" or "offline"
MODE = "online"

if MODE == "online":
    BROKER = "broker.hivemq.com"
else:
    BROKER = "127.0.0.1"

PORT = 1883

TOPIC = "tony/iot/environment"


def on_connect(client, userdata, flags, reason_code, properties):

    print("Connected to MQTT Broker!")

    client.subscribe(TOPIC)

    print("Subscribed to:", TOPIC)


def on_message(client, userdata, msg):

    data = json.loads(msg.payload.decode())

    print("\nReceived Sensor Data")

    print("Temperature:", data["temperature"], "°C")
    print("Humidity:", data["humidity"], "%")

    print("------------------------")


client = mqtt.Client(
    client_id="tony_subscriber",
    callback_api_version=mqtt.CallbackAPIVersion.VERSION2
)

client.on_connect = on_connect
client.on_message = on_message

print("Connecting to:", BROKER)

client.connect(BROKER, PORT, 60)

print("Waiting for messages...")

client.loop_forever()


10.Develop a CoAP-based Environmental Monitoring System that retrieves weather and air quality data from the Open-Meteo API on demand, displays the data on a client dashboard using CoAP GET requests, and stores the retrieved data in Cloud DB.

Weather API
https://api.open-meteo.com/v1/forecast?latitude=10.0159&longitude=76.3419&current=temperature_
2m,relative_humidity_2m,weather_code

Air Quality API
https://air-quality-api.open-meteo.com/v1/air-quality?latitude=10.0159&longitude=76.3419&current=pm10,pm2_5,carbon_
monoxide,nitrogen_
dioxide,ozone,european_aqi


pip install aiocoap flask requests supabase python-dotenv


supabase:

CREATE TABLE environmental_readings (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    temperature FLOAT,
    humidity FLOAT,
    weather_code INTEGER,
    pm10 FLOAT,
    pm2_5 FLOAT,
    carbon_monoxide FLOAT,
    nitrogen_dioxide FLOAT,
    ozone FLOAT,
    european_aqi FLOAT,
    created_at TIMESTAMPTZ DEFAULT NOW()
);


coap_environmental_monitor/
│
├── server.py
├── client.py
├── app.py
├── .env
│
└── templates/
    └── index.html


.env:

SUPABASE_URL=https://YOUR_PROJECT_ID.supabase.co
SUPABASE_KEY=YOUR_SERVICE_ROLE_KEY

server.py:


import asyncio
import json
import requests
import os

from aiocoap import resource, Message, Context
from supabase import create_client
from dotenv import load_dotenv

load_dotenv()

supabase = create_client(
    os.getenv("SUPABASE_URL"),
    os.getenv("SUPABASE_KEY")
)

WEATHER_URL = (
    "https://api.open-meteo.com/v1/forecast"
    "?latitude=10.0159&longitude=76.3419"
    "&current=temperature_2m,relative_humidity_2m,weather_code"
)

AIR_URL = (
    "https://air-quality-api.open-meteo.com/v1/air-quality"
    "?latitude=10.0159&longitude=76.3419"
    "&current=pm10,pm2_5,carbon_monoxide,"
    "nitrogen_dioxide,ozone,european_aqi"
)


class EnvironmentResource(resource.Resource):

    async def render_get(self, request):

        print("Fetching environmental data...")

        try:

            weather = requests.get(
                WEATHER_URL,
                timeout=15
            ).json()

            air = requests.get(
                AIR_URL,
                timeout=15
            ).json()

            current_weather = weather["current"]
            current_air = air["current"]

            data = {
                "temperature": current_weather["temperature_2m"],
                "humidity": current_weather["relative_humidity_2m"],
                "weather_code": current_weather["weather_code"],
                "pm10": current_air["pm10"],
                "pm2_5": current_air["pm2_5"],
                "carbon_monoxide": current_air["carbon_monoxide"],
                "nitrogen_dioxide": current_air["nitrogen_dioxide"],
                "ozone": current_air["ozone"],
                "european_aqi": current_air["european_aqi"]
            }

            # Store data in Supabase
            supabase.table(
                "environmental_readings"
            ).insert(data).execute()

            print("Data stored in Supabase")
            print(data)

            return Message(
                payload=json.dumps(data).encode("utf-8")
            )

        except Exception as e:

            print("Error:", e)

            return Message(
                code=128,
                payload=str(e).encode("utf-8")
            )


async def main():

    site = resource.Site()

    site.add_resource(
        ["environment"],
        EnvironmentResource()
    )

    await Context.create_server_context(
        site,
        bind=("127.0.0.1", 5683)
    )

    print("Environmental CoAP Server Started")
    print("Resource: /environment")

    await asyncio.get_running_loop().create_future()


if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("Server stopped")


client.py:


import asyncio
import json

from aiocoap import Context, Message, GET


async def main():

    protocol = await Context.create_client_context()

    request = Message(
        code=GET,
        uri="coap://127.0.0.1:5683/environment"
    )

    print("Requesting Environmental Data...")

    response = await protocol.request(request).response

    data = json.loads(response.payload.decode())

    print("\nWeather Information")

    print("Temperature:", data["temperature"], "°C")
    print("Humidity:", data["humidity"], "%")
    print("Weather Code:", data["weather_code"])

    print("\nAir Quality Information")

    print("PM10:", data["pm10"])
    print("PM2.5:", data["pm2_5"])
    print("Carbon Monoxide:", data["carbon_monoxide"])
    print("Nitrogen Dioxide:", data["nitrogen_dioxide"])
    print("Ozone:", data["ozone"])
    print("European AQI:", data["european_aqi"])

    await protocol.shutdown()


if __name__ == "__main__":
    asyncio.run(main())


app.py:


from flask import Flask, jsonify, render_template
from supabase import create_client
from dotenv import load_dotenv
import os

load_dotenv()

app = Flask(__name__)

supabase = create_client(
    os.getenv("SUPABASE_URL"),
    os.getenv("SUPABASE_KEY")
)


@app.route("/")
def dashboard():
    return render_template("index.html")


@app.route("/api/readings")
def readings():

    result = (
        supabase.table("environmental_readings")
        .select("*")
        .order("created_at", desc=True)
        .limit(20)
        .execute()
    )

    return jsonify(result.data)


if __name__ == "__main__":
    app.run(debug=True)


templates/index.html:


<!DOCTYPE html>
<html>
<head>
    <title>Environmental Monitoring Dashboard</title>

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <style>
        body {
            font-family: Arial;
            background: #eef2f7;
            text-align: center;
            padding: 25px;
        }

        h1 {
            color: #1e293b;
        }

        .grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
            gap: 15px;
            max-width: 1000px;
            margin: 30px auto;
        }

        .card {
            background: white;
            padding: 20px;
            border-radius: 12px;
            box-shadow: 0 3px 10px #ccc;
        }

        .value {
            font-size: 28px;
            color: #2563eb;
            font-weight: bold;
        }

        button {
            background: #2563eb;
            color: white;
            padding: 12px 25px;
            border: none;
            border-radius: 6px;
            cursor: pointer;
        }

        table {
            margin: 30px auto;
            border-collapse: collapse;
            background: white;
            width: 95%;
        }

        th, td {
            padding: 10px;
            border: 1px solid #ddd;
        }

        th {
            background: #2563eb;
            color: white;
        }
    </style>
</head>

<body>

    <h1>Environmental Monitoring Dashboard</h1>

    <button onclick="loadData()">Refresh Data</button>

    <div class="grid">

        <div class="card">
            <h3>Temperature</h3>
            <div class="value" id="temperature">--</div>
        </div>

        <div class="card">
            <h3>Humidity</h3>
            <div class="value" id="humidity">--</div>
        </div>

        <div class="card">
            <h3>PM10</h3>
            <div class="value" id="pm10">--</div>
        </div>

        <div class="card">
            <h3>PM2.5</h3>
            <div class="value" id="pm25">--</div>
        </div>

        <div class="card">
            <h3>Carbon Monoxide</h3>
            <div class="value" id="co">--</div>
        </div>

        <div class="card">
            <h3>Nitrogen Dioxide</h3>
            <div class="value" id="no2">--</div>
        </div>

        <div class="card">
            <h3>Ozone</h3>
            <div class="value" id="ozone">--</div>
        </div>

        <div class="card">
            <h3>European AQI</h3>
            <div class="value" id="aqi">--</div>
        </div>

    </div>

    <h2>Historical Readings</h2>

    <table>
        <thead>
            <tr>
                <th>Temperature</th>
                <th>Humidity</th>
                <th>PM2.5</th>
                <th>AQI</th>
                <th>Date</th>
            </tr>
        </thead>

        <tbody id="history"></tbody>
    </table>

    <script>
        async function loadData() {

            try {

                const response = await fetch("/api/readings");
                const data = await response.json();

                if (data.length === 0) return;

                const latest = data[0];

                document.getElementById("temperature").innerText =
                    latest.temperature + " °C";

                document.getElementById("humidity").innerText =
                    latest.humidity + " %";

                document.getElementById("pm10").innerText =
                    latest.pm10;

                document.getElementById("pm25").innerText =
                    latest.pm2_5;

                document.getElementById("co").innerText =
                    latest.carbon_monoxide;

                document.getElementById("no2").innerText =
                    latest.nitrogen_dioxide;

                document.getElementById("ozone").innerText =
                    latest.ozone;

                document.getElementById("aqi").innerText =
                    latest.european_aqi;

                const history = document.getElementById("history");

                history.innerHTML = "";

                data.forEach(item => {

                    history.innerHTML += `
                        <tr>
                            <td>${item.temperature}</td>
                            <td>${item.humidity}</td>
                            <td>${item.pm2_5}</td>
                            <td>${item.european_aqi}</td>
                            <td>${new Date(item.created_at).toLocaleString()}</td>
                        </tr>
                    `;
                });

            }
            catch (error) {
                console.log(error);
            }
        }

        loadData();

        setInterval(loadData, 10000);
    </script>

</body>
</html>



11.Write a Python program to retrieve the real-time location of the International Space Station (ISS) every 5 seconds, store 100 location records in a CSV file, analyze the latitude and longitude data, and plot latitude vs. time and longitude vs. time graphs.

Input: http://api.open-notify.org/iss-now.json

pip install requests pandas matplotlib

iss_tracking/
│
└── iss_tracking.py


iss_tracking.py:

import requests
import pandas as pd
import matplotlib.pyplot as plt
import time
from datetime import datetime

# ISS API
URL = "http://api.open-notify.org/iss-now.json"

records = []

print("ISS Location Tracking Started")

# Collect 100 records
for i in range(100):

    try:
        response = requests.get(URL, timeout=15)
        data = response.json()

        latitude = float(data["iss_position"]["latitude"])
        longitude = float(data["iss_position"]["longitude"])

        timestamp = datetime.now()

        records.append({
            "Time": timestamp,
            "Latitude": latitude,
            "Longitude": longitude
        })

        print(
            f"Record {i+1}: "
            f"Latitude={latitude}, Longitude={longitude}"
        )

    except Exception as e:
        print("Error:", e)

        if i < 99:
            time.sleep(5)

        continue

    if i < 99:
        time.sleep(5)


# Convert to DataFrame
df = pd.DataFrame(records)

# Save CSV
df.to_csv("iss_location.csv", index=False)

print("\nData saved to iss_location.csv")

# Statistical analysis
print("\nStatistical Analysis")
print(df[["Latitude", "Longitude"]].describe())

print("\nAverage Latitude:", df["Latitude"].mean())
print("Average Longitude:", df["Longitude"].mean())

# Latitude vs Time
plt.figure(figsize=(10, 5))
plt.plot(df["Time"], df["Latitude"], marker="o")
plt.xlabel("Time")
plt.ylabel("Latitude")
plt.title("ISS Latitude vs Time")
plt.xticks(rotation=45)
plt.grid()
plt.tight_layout()
plt.show()

# Longitude vs Time
plt.figure(figsize=(10, 5))
plt.plot(df["Time"], df["Longitude"], marker="o")
plt.xlabel("Time")
plt.ylabel("Longitude")
plt.title("ISS Longitude vs Time")
plt.xticks(rotation=45)
plt.grid()
plt.tight_layout()
plt.show()

print("\nISS Analysis Completed")



12.Retrieve earthquake data for the past 7 weeks using the USGS Earthquake API. Extract the following fields: Magnitude, Place, Time, Longitude, Latitude, Depth, and Tsunami Status. Perform statistical and time-series analysis on the retrieved earthquake data. Visualize the results using suitable charts and develop a dashboard to display the earthquake data, statistical analysis, time-series visualizations, and findings.

Input:
https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2026-08-07&endtime=2026-09-25&minmagnitude=2.5&orderby=time

pip install requests pandas matplotlib streamlit plotly

earthquake_dashboard/
│
└── app.py

streamlit

app.py:


import requests
import pandas as pd
import streamlit as st
import plotly.express as px

# USGS Earthquake API
URL = (
    "https://earthquake.usgs.gov/fdsnws/event/1/query"
    "?format=geojson"
    "&starttime=2026-08-07"
    "&endtime=2026-09-25"
    "&minmagnitude=2.5"
    "&orderby=time"
)

st.set_page_config(
    page_title="Earthquake Analytics Dashboard",
    layout="wide"
)

st.title("🌍 Earthquake Data Analytics Dashboard")
st.write("Analysis of earthquake data retrieved from the USGS API")

# Retrieve earthquake data
@st.cache_data(ttl=300)
def get_data():

    response = requests.get(URL, timeout=30)
    response.raise_for_status()

    json_data = response.json()

    records = []

    for feature in json_data["features"]:

        properties = feature["properties"]
        coordinates = feature["geometry"]["coordinates"]

        records.append({
            "Magnitude": properties["mag"],
            "Place": properties["place"],
            "Time": pd.to_datetime(
                properties["time"], unit="ms", utc=True
            ),
            "Longitude": coordinates[0],
            "Latitude": coordinates[1],
            "Depth": coordinates[2],
            "Tsunami": properties["tsunami"]
        })

    return pd.DataFrame(records)


try:

    df = get_data()

    if df.empty:
        st.warning("No earthquake records found.")
        st.stop()

    # Data preprocessing
    df = df.dropna(subset=["Magnitude", "Time"])

    df["Tsunami Status"] = df["Tsunami"].map({
        0: "No",
        1: "Yes"
    })

    # Sidebar
    st.sidebar.header("Filters")

    min_mag = float(df["Magnitude"].min())
    max_mag = float(df["Magnitude"].max())

    selected_mag = st.sidebar.slider(
        "Magnitude Range",
        min_value=min_mag,
        max_value=max_mag,
        value=(min_mag, max_mag)
    )

    filtered = df[
        (df["Magnitude"] >= selected_mag[0]) &
        (df["Magnitude"] <= selected_mag[1])
    ]

    # Key statistics
    st.subheader("Earthquake Statistics")

    c1, c2, c3, c4 = st.columns(4)

    c1.metric("Total Earthquakes", len(filtered))

    c2.metric(
        "Average Magnitude",
        round(filtered["Magnitude"].mean(), 2)
    )

    c3.metric(
        "Maximum Magnitude",
        round(filtered["Magnitude"].max(), 2)
    )

    c4.metric(
        "Average Depth (km)",
        round(filtered["Depth"].mean(), 2)
    )

    # Statistical analysis
    st.subheader("Statistical Analysis")

    st.dataframe(
        filtered[
            ["Magnitude", "Latitude", "Longitude", "Depth"]
        ].describe(),
        use_container_width=True
    )

    # Magnitude distribution
    st.subheader("Magnitude Distribution")

    fig1 = px.histogram(
        filtered,
        x="Magnitude",
        nbins=20,
        title="Earthquake Magnitude Distribution"
    )

    st.plotly_chart(fig1, use_container_width=True)

    # Top 10 strongest earthquakes
    st.subheader("Top 10 Strongest Earthquakes")

    top10 = filtered.nlargest(10, "Magnitude")

    fig2 = px.bar(
        top10,
        x="Place",
        y="Magnitude",
        title="Top 10 Earthquakes by Magnitude"
    )

    st.plotly_chart(fig2, use_container_width=True)

    # Time series analysis
    st.subheader("Earthquake Activity Over Time")

    daily = (
        filtered.set_index("Time")
        .resample("D")
        .size()
        .reset_index(name="Earthquake Count")
    )

    fig3 = px.line(
        daily,
        x="Time",
        y="Earthquake Count",
        title="Daily Earthquake Frequency",
        markers=True
    )

    st.plotly_chart(fig3, use_container_width=True)

    # Depth analysis
    st.subheader("Magnitude vs Depth")

    fig4 = px.scatter(
        filtered,
        x="Depth",
        y="Magnitude",
        color="Tsunami Status",
        hover_name="Place",
        title="Earthquake Magnitude vs Depth"
    )

    st.plotly_chart(fig4, use_container_width=True)

    # Earthquake location map
    st.subheader("Earthquake Locations")

    fig5 = px.scatter_geo(
        filtered,
        lat="Latitude",
        lon="Longitude",
        color="Magnitude",
        hover_name="Place",
        title="Global Earthquake Locations"
    )

    st.plotly_chart(fig5, use_container_width=True)

    # Tsunami analysis
    st.subheader("Tsunami Status")

    tsunami_count = (
        filtered["Tsunami Status"]
        .value_counts()
        .reset_index()
    )

    fig6 = px.pie(
        tsunami_count,
        names="Tsunami Status",
        values="count",
        title="Tsunami Warning Distribution"
    )

    st.plotly_chart(fig6, use_container_width=True)

    # Raw data
    st.subheader("Earthquake Records")

    st.dataframe(filtered, use_container_width=True)

    # Download CSV
    csv = filtered.to_csv(index=False).encode("utf-8")

    st.download_button(
        "Download Earthquake Data CSV",
        csv,
        "earthquake_data.csv",
        "text/csv"
    )

    # Findings
    st.subheader("Key Findings")

    st.write(
        "Total earthquakes:", len(filtered)
    )

    st.write(
        "Highest magnitude:", filtered["Magnitude"].max()
    )

    st.write(
        "Most active day:",
        daily.loc[daily["Earthquake Count"].idxmax(), "Time"].date()
    )

    st.write(
        "Tsunami-related records:",
        (filtered["Tsunami"] == 1).sum()
    )

except Exception as e:
    st.error(f"Error retrieving or processing data: {e}")



13.Analyze weather data collected from the Open-Meteo API and visualize temperature and humidity trends using bar charts and perform statistical analysis.

Input : https://api.open-meteo.com/v1/forecast?latitude=9.93&longitude=76.27&
current=temperature_2m,relative_humidity_2m,wind_speed_10m

pip install requests pandas plotly streamlit

streamlit

app.py:


import requests
import pandas as pd
import plotly.express as px
import streamlit as st

# Open-Meteo hourly weather API
URL = (
    "https://api.open-meteo.com/v1/forecast"
    "?latitude=9.93&longitude=76.27"
    "&hourly=temperature_2m,relative_humidity_2m"
    "&forecast_days=1&timezone=auto"
)

st.set_page_config(
    page_title="Weather Data Analysis",
    page_icon="🌤️",
    layout="wide"
)

st.title("Open-Meteo Weather Data Analysis")
st.write("Hourly temperature and humidity analysis for Kochi")

# Fetch weather data
@st.cache_data(ttl=900)
def get_weather_data():
    response = requests.get(URL, timeout=20)
    response.raise_for_status()
    return response.json()

try:
    data = get_weather_data()

    # Extract hourly data
    hourly = data["hourly"]

    df = pd.DataFrame({
        "Time": pd.to_datetime(hourly["time"]),
        "Temperature (°C)": hourly["temperature_2m"],
        "Humidity (%)": hourly["relative_humidity_2m"]
    })

    # Display raw data
    st.subheader("Hourly Weather Data")
    st.dataframe(df, use_container_width=True)

    # Statistical analysis
    st.subheader("Statistical Analysis")

    stats = df[["Temperature (°C)", "Humidity (%)"]].describe()
    st.dataframe(stats, use_container_width=True)

    col1, col2 = st.columns(2)

    with col1:
        st.metric(
            "Average Temperature",
            f"{df['Temperature (°C)'].mean():.2f} °C"
        )
        st.metric(
            "Maximum Temperature",
            f"{df['Temperature (°C)'].max():.2f} °C"
        )

    with col2:
        st.metric(
            "Average Humidity",
            f"{df['Humidity (%)'].mean():.2f}%"
        )
        st.metric(
            "Maximum Humidity",
            f"{df['Humidity (%)'].max():.2f}%"
        )

    # Temperature bar chart
    st.subheader("Temperature Trend")

    fig_temp = px.bar(
        df,
        x="Time",
        y="Temperature (°C)",
        title="Hourly Temperature",
        labels={"Time": "Time"}
    )

    st.plotly_chart(fig_temp, use_container_width=True)

    # Humidity bar chart
    st.subheader("Humidity Trend")

    fig_humidity = px.bar(
        df,
        x="Time",
        y="Humidity (%)",
        title="Hourly Relative Humidity",
        labels={"Time": "Time"}
    )

    st.plotly_chart(fig_humidity, use_container_width=True)

    # Download data
    csv = df.to_csv(index=False).encode("utf-8")

    st.download_button(
        "Download Weather Data as CSV",
        data=csv,
        file_name="weather_data.csv",
        mime="text/csv"
    )

except requests.exceptions.RequestException as e:
    st.error(f"API connection error: {e}")

except (KeyError, ValueError) as e:
    st.error(f"Error processing weather data: {e}")



14.Analyze the air-quality data of Kochi using the Open-Meteo Air Quality API. Retrieve hourly AQI, PM2.5, and PM10 data for Kochi. Perform statistical and time-series analysis and plot suitable charts to visualize changes in AQI, PM2.5, and PM10 levels over time. Visualize the results using suitable charts and develop a dashboard.

Input:https://air-quality-api.open-meteo.com/v1/air-quality?latitude=9.93&longitude=76.27&hourly=pm10,pm2_5,us_aqi&timezone=auto location?

pip install requests pandas plotly streamlit

streamlit

app.py:


import requests
import pandas as pd
import plotly.express as px
import streamlit as st

# Open-Meteo Air Quality API
URL = (
    "https://air-quality-api.open-meteo.com/v1/air-quality"
    "?latitude=9.93&longitude=76.27"
    "&hourly=pm10,pm2_5,us_aqi&timezone=auto"
)

st.set_page_config(
    page_title="Air Quality Dashboard",
    page_icon="🌍",
    layout="wide"
)

st.title("Open-Meteo Air Quality Dashboard")
st.write("Hourly air quality analysis for Kochi")

# Fetch data from API
@st.cache_data(ttl=900)
def get_air_quality():
    response = requests.get(URL, timeout=20)
    response.raise_for_status()
    return response.json()

try:
    data = get_air_quality()

    # Extract hourly data
    hourly = data["hourly"]

    df = pd.DataFrame({
        "Time": pd.to_datetime(hourly["time"]),
        "PM2.5": hourly["pm2_5"],
        "PM10": hourly["pm10"],
        "US AQI": hourly["us_aqi"]
    })

    # Display dataset
    st.subheader("Air Quality Dataset")
    st.dataframe(df, use_container_width=True)

    # Statistical analysis
    st.subheader("Statistical Analysis")

    stats = df[["PM2.5", "PM10", "US AQI"]].describe()
    st.dataframe(stats, use_container_width=True)

    # Key statistics
    col1, col2, col3 = st.columns(3)

    col1.metric("Average PM2.5", f"{df['PM2.5'].mean():.2f}")
    col2.metric("Average PM10", f"{df['PM10'].mean():.2f}")
    col3.metric("Average US AQI", f"{df['US AQI'].mean():.2f}")

    # Time-series chart for AQI
    st.subheader("AQI Trend")

    fig_aqi = px.line(
        df,
        x="Time",
        y="US AQI",
        title="Hourly US Air Quality Index",
        markers=True
    )

    st.plotly_chart(fig_aqi, use_container_width=True)

    # PM2.5 trend
    st.subheader("PM2.5 Trend")

    fig_pm25 = px.line(
        df,
        x="Time",
        y="PM2.5",
        title="Hourly PM2.5 Concentration",
        markers=True
    )

    st.plotly_chart(fig_pm25, use_container_width=True)

    # PM10 trend
    st.subheader("PM10 Trend")

    fig_pm10 = px.line(
        df,
        x="Time",
        y="PM10",
        title="Hourly PM10 Concentration",
        markers=True
    )

    st.plotly_chart(fig_pm10, use_container_width=True)

    # Compare pollutants
    st.subheader("Pollutant Comparison")

    comparison = df[["PM2.5", "PM10"]].mean().reset_index()
    comparison.columns = ["Pollutant", "Average Concentration"]

    fig_compare = px.bar(
        comparison,
        x="Pollutant",
        y="Average Concentration",
        title="Average PM2.5 vs PM10"
    )

    st.plotly_chart(fig_compare, use_container_width=True)

    # Download CSV
    csv = df.to_csv(index=False).encode("utf-8")

    st.download_button(
        "Download Air Quality Data",
        data=csv,
        file_name="air_quality_data.csv",
        mime="text/csv"
    )

except requests.exceptions.RequestException as e:
    st.error(f"API connection error: {e}")

except (KeyError, ValueError) as e:
    st.error(f"Error processing air quality data: {e}")



15.Develop a Decision Tree model to classify room occupancy as Occupied or Not Occupied using temperature, humidity, light, and CO₂ sensor data, and evaluate the model using accuracy score and a confusion matrix.

Dataset: https://archive.ics.uci.edu/dataset/357/occupancy%2Bdetection

pip install pandas numpy scikit-learn matplotlib seaborn ucimlrepo

occupancy.py:


import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

from ucimlrepo import fetch_ucirepo
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import (
    accuracy_score,
    confusion_matrix,
    classification_report,
    ConfusionMatrixDisplay
)

# Fetch UCI Occupancy Detection dataset
dataset = fetch_ucirepo(id=357)

X = dataset.data.features
y = dataset.data.targets

# Combine features and target
df = pd.concat([X, y], axis=1)

# Clean column names
df.columns = df.columns.str.strip()

# Select required features
features = ["Temperature", "Humidity", "Light", "CO2"]

# Prepare input and output
X = df[features]
y = df["Occupancy"].squeeze()

# Remove missing values
data = pd.concat([X, y.rename("Occupancy")], axis=1)
data = data.dropna()

X = data[features]
y = data["Occupancy"]

# Split dataset into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    random_state=42,
    stratify=y
)

# Create and train Decision Tree model
model = DecisionTreeClassifier(
    criterion="gini",
    max_depth=5,
    random_state=42
)

model.fit(X_train, y_train)

# Make predictions
y_pred = model.predict(X_test)

# Evaluate model
accuracy = accuracy_score(y_test, y_pred)

print("DECISION TREE OCCUPANCY DETECTION")
print("---------------------------------")
print("Accuracy:", round(accuracy * 100, 2), "%")

print("\nClassification Report:")
print(classification_report(y_test, y_pred))

# Confusion matrix
cm = confusion_matrix(y_test, y_pred)

print("Confusion Matrix:")
print(cm)

# Plot confusion matrix
ConfusionMatrixDisplay(
    confusion_matrix=cm,
    display_labels=["Not Occupied", "Occupied"]
).plot(cmap="Blues")

plt.title("Decision Tree Confusion Matrix")
plt.show()

# Feature importance
importance = pd.DataFrame({
    "Feature": features,
    "Importance": model.feature_importances_
})

print("\nFeature Importance:")
print(importance)

# Plot feature importance
plt.figure(figsize=(8, 5))

sns.barplot(
    data=importance,
    x="Importance",
    y="Feature"
)

plt.title("Feature Importance in Occupancy Detection")
plt.xlabel("Importance")
plt.ylabel("Sensor Features")
plt.tight_layout()
plt.show()

# Predict a new room condition
sample = pd.DataFrame(
    [[23.0, 27.0, 400.0, 600.0]],
    columns=features
)

prediction = model.predict(sample)[0]

print("\nNew Room Prediction:")

if prediction == 1:
    print("Room is Occupied")
else:
    print("Room is Not Occupied")



16.Using the provided historical IoT environmental sensor dataset, develop a Linear Regression model to predict temperature using PM2.5, PM10, pressure, dew point, and wind speed. Train and evaluate the model, and predict the temperature for a new set of sensor readings.

Dataset : https://archive.ics.uci.edu/dataset/501/beijing

pip install pandas numpy scikit-learn matplotlib seaborn ucimlrepo

temperature_prediction.py:


import requests
import zipfile
import io
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import (
    mean_absolute_error,
    mean_squared_error,
    r2_score
)

# Download UCI Beijing Multi-Site Air Quality dataset
url = "https://archive.ics.uci.edu/static/public/501/beijing+multi+site+air+quality+data.zip"

print("Downloading dataset...")

response = requests.get(url, timeout=60)
response.raise_for_status()

# Extract CSV files from ZIP
zip_file = zipfile.ZipFile(io.BytesIO(response.content))

csv_files = [
    name for name in zip_file.namelist()
    if name.lower().endswith(".csv")
]

# Combine data from all monitoring stations
dataframes = []

for file in csv_files:
    with zip_file.open(file) as f:
        station_df = pd.read_csv(f)
        dataframes.append(station_df)

df = pd.concat(dataframes, ignore_index=True)

print("Dataset loaded successfully!")
print("\nFirst five records:")
print(df.head())

# Select input features and target
features = ["PM2.5", "PM10", "PRES", "DEWP", "WSPM"]
target = "TEMP"

# Convert selected columns to numeric
for column in features + [target]:
    df[column] = pd.to_numeric(df[column], errors="coerce")

# Remove missing values
df = df[features + [target]].dropna()

print("\nDataset shape after cleaning:", df.shape)

# Prepare input and output
X = df[features]
y = df[target]

# Split dataset into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    random_state=42
)

# Create and train Linear Regression model
model = LinearRegression()
model.fit(X_train, y_train)

# Predict temperature
y_pred = model.predict(X_test)

# Evaluate model
mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)

print("\nLINEAR REGRESSION RESULTS")
print("-------------------------")
print("Mean Absolute Error:", round(mae, 2))
print("Mean Squared Error:", round(mse, 2))
print("Root Mean Squared Error:", round(rmse, 2))
print("R2 Score:", round(r2, 4))

# Compare actual and predicted temperatures
comparison = pd.DataFrame({
    "Actual Temperature": y_test.values[:10],
    "Predicted Temperature": y_pred[:10]
})

print("\nActual vs Predicted Temperature:")
print(comparison)

# Actual vs predicted graph
plt.figure(figsize=(8, 5))

sns.scatterplot(
    x=y_test,
    y=y_pred,
    alpha=0.4
)

plt.xlabel("Actual Temperature")
plt.ylabel("Predicted Temperature")
plt.title("Actual vs Predicted Temperature")

plt.tight_layout()
plt.show()

# Feature importance using regression coefficients
importance = pd.DataFrame({
    "Feature": features,
    "Coefficient": model.coef_
})

print("\nRegression Coefficients:")
print(importance)

plt.figure(figsize=(8, 5))

sns.barplot(
    data=importance,
    x="Coefficient",
    y="Feature"
)

plt.title("Feature Coefficients")
plt.tight_layout()
plt.show()

# Predict temperature for new sensor readings
sample = pd.DataFrame(
    [[35.0, 60.0, 1010.0, 5.0, 2.0]],
    columns=features
)

predicted_temperature = model.predict(sample)

print("\nPredicted Temperature for New Readings:")
print(round(predicted_temperature[0], 2), "°C")



17.Develop a Random Forest model to classify air quality into Good, Satisfactory, Moderate, Poor, Very Poor, or Severe using PM2.5, PM10, NO2, CO, SO2, and O3 data. Preprocess the dataset, train and evaluate the model, and predict the air quality category for a new set of pollutant readings.

Official Kaggle dataset: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india        
File Name: city_day.csv


pip install pandas numpy scikit-learn matplotlib seaborn

air_quality.py:


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
from sklearn.metrics import (
    accuracy_score,
    classification_report,
    confusion_matrix,
    ConfusionMatrixDisplay
)

# Load dataset
df = pd.read_csv("city_day.csv")

print("First five records:")
print(df.head())

# Select input features and target
features = ["PM2.5", "PM10", "NO2", "CO", "SO2", "O3"]
target = "AQI_Bucket"

# Check required columns
required_columns = features + [target]

missing_columns = [
    col for col in required_columns if col not in df.columns
]

if missing_columns:
    raise ValueError(f"Missing columns: {missing_columns}")

# Convert input features to numeric
for column in features:
    df[column] = pd.to_numeric(df[column], errors="coerce")

# Remove records without target labels
df = df.dropna(subset=[target])

# Prepare input and output
X = df[features]
y = df[target].astype(str)

print("\nDataset shape:", df.shape)

# Display class distribution
print("\nAir Quality Class Distribution:")
print(y.value_counts())

# Split dataset
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    random_state=42,
    stratify=y
)

# Create Random Forest pipeline
model = Pipeline([
    ("imputer", SimpleImputer(strategy="median")),
    ("classifier", RandomForestClassifier(
        n_estimators=100,
        random_state=42,
        class_weight="balanced",
        n_jobs=-1
    ))
])

# Train model
model.fit(X_train, y_train)

# Make predictions
y_pred = model.predict(X_test)

# Evaluate model
accuracy = accuracy_score(y_test, y_pred)

print("\nRANDOM FOREST CLASSIFICATION RESULTS")
print("------------------------------------")
print("Accuracy:", round(accuracy * 100, 2), "%")

print("\nClassification Report:")
print(classification_report(
    y_test,
    y_pred,
    zero_division=0
))

# Confusion matrix
labels = sorted(y.unique())

cm = confusion_matrix(
    y_test,
    y_pred,
    labels=labels
)

print("Confusion Matrix:")
print(cm)

# Plot confusion matrix
plt.figure(figsize=(9, 7))

sns.heatmap(
    cm,
    annot=True,
    fmt="d",
    cmap="Blues",
    xticklabels=labels,
    yticklabels=labels
)

plt.xlabel("Predicted Class")
plt.ylabel("Actual Class")
plt.title("Random Forest Confusion Matrix")
plt.tight_layout()
plt.show()

# Feature importance
classifier = model.named_steps["classifier"]

importance = pd.DataFrame({
    "Feature": features,
    "Importance": classifier.feature_importances_
})

importance = importance.sort_values(
    by="Importance",
    ascending=False
)

print("\nFeature Importance:")
print(importance)

# Plot feature importance
plt.figure(figsize=(8, 5))

sns.barplot(
    data=importance,
    x="Importance",
    y="Feature"
)

plt.title("Air Quality Feature Importance")
plt.tight_layout()
plt.show()

# Predict air quality for new readings
sample = pd.DataFrame(
    [[35.0, 60.0, 20.0, 0.8, 10.0, 30.0]],
    columns=features
)

prediction = model.predict(sample)

print("\nNew Air Quality Prediction:")
print("Predicted Category:", prediction[0])
