================================================================================
  Experiment 5: HTTP REST API Cloud Storage & Web Dashboard (Supabase)
================================================================================

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

SHORT QUESTION:
Send sensor telemetry via HTTP REST API to Supabase cloud database and display on Streamlit web dashboard.

================================================================================
README & SETUP INSTRUCTIONS:
================================================================================
# Experiment 5: HTTP REST API Cloud Storage & Web Dashboard

## Objective
Transmit sensor data to a cloud database via HTTP POST requests and render records on an interactive web dashboard.

## Requirements
```bash
pip install requests streamlit pandas
```

## Cloud DB Table Setup (Supabase SQL)
```sql
create table sensor_readings (
  id bigint generated by default as identity primary key,
  created_at timestamp with time zone default timezone('utc'::text, now()) not null,
  temperature float not null,
  humidity float not null
);
```

## Execution
1. Update `SUPABASE_URL` and `SUPABASE_KEY` in both scripts.
2. In Terminal 1, run sender:
   ```bash
   python send_http_data.py
   ```
3. In Terminal 2, launch dashboard:
   ```bash
   streamlit run app_http.py
   ```

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

1. send_http_data.py
--------------------------------------------------------------------------------
import time
import os
import json
import random
from datetime import datetime
import requests

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
CACHE_FILE = os.path.join(BASE_DIR, "sensor_readings.json")

SUPABASE_URL = "https://YOUR_PROJECT_ID.supabase.co/rest/v1/sensor_readings"
SUPABASE_KEY = "YOUR_ANON_PUBLIC_KEY"

headers = {
    "apikey": SUPABASE_KEY,
    "Authorization": f"Bearer {SUPABASE_KEY}",
    "Content-Type": "application/json",
    "Prefer": "return=minimal"
}

def save_local_reading(reading: dict) -> None:
    try:
        readings = []
        if os.path.exists(CACHE_FILE):
            with open(CACHE_FILE, "r", encoding="utf-8") as f:
                readings = json.load(f)
        readings.insert(0, reading)
        readings = readings[:30]
        with open(CACHE_FILE, "w", encoding="utf-8") as f:
            json.dump(readings, f, indent=2)
    except Exception as err:
        print(f"Local cache write error: {err}")

print("Starting HTTP REST Sensor Transmitter (Press Ctrl+C to stop)...")
while True:
    payload = {
        "id": int(time.time()),
        "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        "temperature": round(random.uniform(22.0, 35.0), 2),
        "humidity": round(random.uniform(40.0, 80.0), 2)
    }

    save_local_reading(payload)

    if "YOUR_PROJECT_ID" not in SUPABASE_URL:
        try:
            response = requests.post(SUPABASE_URL, headers=headers, json=payload, timeout=5)
            print(f"Transmitted to Cloud: {payload} | Status: {response.status_code}")
        except Exception as e:
            print(f"Cloud transmission error: {e} | Saved locally to sensor_readings.json")
    else:
        print(f"[Demo Mode] Generated reading: {payload} (Saved to sensor_readings.json)")

    time.sleep(5)
--------------------------------------------------------------------------------

2. app_http.py
--------------------------------------------------------------------------------
import os
import json
import streamlit as st
import pandas as pd
import requests

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
CACHE_FILE = os.path.join(BASE_DIR, "sensor_readings.json")

SUPABASE_URL = "https://YOUR_PROJECT_ID.supabase.co/rest/v1/sensor_readings?select=*&order=id.desc&limit=20"
SUPABASE_KEY = "YOUR_ANON_PUBLIC_KEY"

headers = {
    "apikey": SUPABASE_KEY,
    "Authorization": f"Bearer {SUPABASE_KEY}"
}

st.title("HTTP REST Environmental Monitor")

if st.button("Refresh Telemetry"):
    st.rerun()

data = None
if "YOUR_PROJECT_ID" not in SUPABASE_URL:
    try:
        res = requests.get(SUPABASE_URL, headers=headers, timeout=5)
        if res.status_code == 200:
            data = res.json()
    except Exception:
        pass

if not data and os.path.exists(CACHE_FILE):
    try:
        with open(CACHE_FILE, "r", encoding="utf-8") as f:
            data = json.load(f)
    except Exception:
        pass

if not data:
    data = [
        {"id": 1, "created_at": "2026-10-31 12:00:00", "temperature": 28.5, "humidity": 65.2},
        {"id": 2, "created_at": "2026-10-31 12:05:00", "temperature": 29.1, "humidity": 63.8},
        {"id": 3, "created_at": "2026-10-31 12:10:00", "temperature": 29.8, "humidity": 62.0}
    ]

if data:
    latest = data[0]
    st.write(f"Temperature: {latest.get('temperature', 0)} C")
    st.write(f"Humidity: {latest.get('humidity', 0)} %")
    st.subheader("Historical Log")
    st.write(pd.DataFrame(data))
--------------------------------------------------------------------------------
