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()
    )

    protocol = 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()

    try:
        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"], "%")

    finally:
        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>
