================================================================================
  Experiment 8: CoAP Server & Client Dashboard
================================================================================

FULL QUESTION:
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.

SHORT QUESTION:
CoAP (aiocoap) UDP server transferring sensor telemetry to an interactive Streamlit client dashboard.

================================================================================
README & SETUP INSTRUCTIONS:
================================================================================
# Experiment 8: CoAP Server & Client Dashboard

## Objective
Establish a CoAP (Constrained Application Protocol) Server on UDP port 5683 and fetch current sensor data on demand using a Streamlit CoAP client dashboard.

## Requirements
```bash
pip install aiocoap streamlit
```

## How to Run
1. Start the CoAP Server in Terminal 1:
   ```bash
   python server.py
   ```
2. Start the Streamlit Dashboard in Terminal 2:
   ```bash
   streamlit run client.py
   ```
3. Open browser at `http://localhost:8501` and click **Get Temperature**.

================================================================================
SOURCE CODE FILES:
================================================================================

1. server.py
--------------------------------------------------------------------------------
import asyncio
from aiocoap import Context, Message, resource

class TemperatureResource(resource.Resource):
    async def render_get(self, request):
        temperature = "29.5"
        print(f"CoAP GET requested. Serving: {temperature} C")
        return Message(payload=temperature.encode("utf-8"))

async def main():
    root = resource.Site()
    root.add_resource(["temperature"], TemperatureResource())

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

    print("CoAP Server Active on coap://127.0.0.1:5683/temperature")
    print("Waiting for CoAP GET requests...")

    await asyncio.get_running_loop().create_future()

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

2. client.py
--------------------------------------------------------------------------------
import streamlit as st
import asyncio
from aiocoap import Context, Message, GET

async def get_temperature():
    protocol = await Context.create_client_context()
    try:
        request = Message(code=GET, uri="coap://127.0.0.1:5683/temperature")
        response = await protocol.request(request).response
        return response.payload.decode("utf-8")
    finally:
        await protocol.shutdown()

st.title("CoAP Environmental Monitor")

if st.button("Get Temperature"):
    try:
        loop = asyncio.new_event_loop()
        temperature = loop.run_until_complete(get_temperature())
        st.success("CoAP Content received")
        st.write(f"Temperature: {temperature} C")
    except Exception as e:
        st.error(f"Error: {e}")
--------------------------------------------------------------------------------
