================================================================================
  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
--------------------------------------------------------------------------------
"""
================================================================================
IOT EXPERIMENT 05: Cloud REST API Telemetry Ingestion (Supabase)
================================================================================
Develop an application that sends 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 Description: Transmits simulated IoT temperature and humidity readings to a Supabase PostgreSQL cloud database via HTTP REST POST requests with local offline caching.

"""
README / BEFORE RUNNING:
- Prerequisites: Python 3.x, requests (pip install requests).
- Configuration: Optional SUPABASE_URL and SUPABASE_KEY environment variables (falls back to local SQLite/JSON caching if cloud credentials are not supplied).
- How to Run: python send_http_data.py
- Expected Behavior: Sends sensor records, logs HTTP response status (201/200), and records telemetry in the database.
"""

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
--------------------------------------------------------------------------------
"""
================================================================================
IOT EXPERIMENT 05: Web Dashboard for HTTP Cloud Sensor Data
================================================================================
Develop an application that sends 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 Description: Flask/Dash web application providing a real-time graphical dashboard for sensor records retrieved from the cloud database via REST API.

"""
README / BEFORE RUNNING:
- Prerequisites: Python 3.x, flask, requests (pip install flask requests).
- Setup: Run 'python send_http_data.py' to seed or transmit records first.
- How to Run: python app_http.py (open http://localhost:5000 in your browser).
- Expected Behavior: Displays latest temperature and humidity gauges, historical trend table, and connection status.
"""

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.set_page_config(page_title="REST API Sensor Dashboard", layout="wide")
st.title("HTTP REST Environmental Monitor")
st.caption("Receiving Telemetry from Cloud Database (Supabase REST API)")

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

data = None
is_cloud = False

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()
            is_cloud = True
    except Exception:
        pass

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

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}
    ]
    st.info("Demonstration Mode: Displaying telemetry log (Configure Supabase credentials in script to sync with live cloud database).")
elif not is_cloud:
    st.info("Local Cache Mode: Displaying telemetry recorded by send_http_data.py.")

if data:
    latest = data[0]
    col1, col2 = st.columns(2)
    col1.metric("Latest Temperature", f"{latest.get('temperature', 0)} °C")
    col2.metric("Latest Humidity", f"{latest.get('humidity', 0)} %")

    df = pd.DataFrame(data)
    st.subheader("Historical Log")
    st.dataframe(df, use_container_width=True)
--------------------------------------------------------------------------------
