================================================================================
           IOT PRACTICAL EXAMINATION - COMPREHENSIVE REVISION NOTES & CHEAT SHEET
================================================================================

1. ONE-TIME DEPENDENCY INSTALLATION
--------------------------------------------------------------------------------
Run this command in terminal before starting any question:
pip install streamlit paho-mqtt aiocoap requests pandas scikit-learn matplotlib pyserial numpy

================================================================================
2. TERMINAL EXECUTION ARCHITECTURE (ORDER OF RUNNING)
--------------------------------------------------------------------------------
When doing any 2-tier or 3-tier IoT question, ALWAYS launch in this order:

- For CoAP Questions (e.g. Q3, Q4, CQ1, CQ2, CQ8, SQ3):
  Terminal 1: python server.py          (Starts CoAP Server listening on UDP port 5683)
  Terminal 2: python client.py          (CoAP Client: tests GET requests & ML inference)
  Terminal 3: streamlit run app.py      (Streamlit Web Dashboard on http://localhost:8501)

- For MQTT Questions (e.g. 04, 06, CQ3, CQ4, CQ5, CQ7, SQ4):
  Terminal 1: python subscriber.py      (Or mqtt_bridge.py: begins listening for packets)
  Terminal 2: python publisher.py       (Starts publishing telemetry packets to HiveMQ)
  Terminal 3: streamlit run app.py      (Web Dashboard visualizing incoming MQTT data)

- For ESP32 Hardware Questions (e.g. 01, 02, 03, CQ6, SQ7):
  1. Open Arduino IDE, select Board: "DOIT ESP32 DEVKIT V1", select COM Port.
  2. Upload sketch.ino. Set Serial Monitor baud rate to 115200.
  3. Close Serial Monitor before running Python serial listener (COM port cannot be shared).
  4. Run: python serial_classifier.py OR streamlit run app.py.

================================================================================
3. PROTOCOLS, PORTS & BROKERS CHEAT SHEET
--------------------------------------------------------------------------------
- CoAP (Constrained Application Protocol):
  * Transport: UDP (Port 5683)
  * URI Scheme: coap://127.0.0.1:5683/<resource_name>
  * Library: aiocoap
  * Asynchronous loop: asyncio.run(...)
  * Content Format 50 = application/json

- MQTT (Message Queuing Telemetry Transport):
  * Transport: TCP (Port 1883)
  * Public Broker: broker.hivemq.com (or test.mosquitto.org)
  * Library: paho-mqtt
  * Paho-MQTT Version 2 syntax:
      client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
  * Callbacks: client.on_connect, client.on_message

- HTTP REST & Cloud:
  * Transport: TCP / HTTPS (Port 443)
  * Library: requests
  * Methods: requests.get(url, headers=...) and requests.post(url, headers=..., json=payload)

- Streamlit Web Dashboard:
  * Port: 8501 (http://localhost:8501)
  * Launch: streamlit run app.py

================================================================================
4. DATASETS & MACHINE LEARNING MODELS MAPPING
--------------------------------------------------------------------------------
1. Room Occupancy Classification:
   * Dataset: datatraining.txt (UCI Occupancy Detection)
   * Features: Temperature, Humidity, Light, CO2
   * Target: Occupancy (0 = Vacant, 1 = Occupied)
   * Model: DecisionTreeClassifier(max_depth=5, random_state=42)
   * Key Metric: accuracy_score, confusion_matrix

2. Air Quality Classification:
   * Dataset: city_day.csv (India National Air Quality)
   * Features: PM2.5, PM10, NO2, SO2, O3
   * Target: AQI_Bucket (Good, Satisfactory, Moderate, Poor, Very Poor, Severe)
   * Model: RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42)
   * Gotcha: Always fill NaNs with median: df[col] = df[col].fillna(df[col].median())

3. Temperature Prediction (Regression):
   * Dataset: PRSA_Data_Aotizhongxin_20130301-20170228.csv (Beijing PRSA)
   * Features: PM2.5, PM10, PRES, DEWP, WSPM
   * Target: TEMP (continuous in °C)
   * Model: LinearRegression()
   * Key Metrics: r2_score (variance explained), mean_absolute_error (MAE)

4. Weather Condition Classification:
   * Dataset: Open-Meteo Historical Archive API (Kochi)
   * Features: temperature_2m, relative_humidity_2m, precipitation, cloud_cover, wind_speed_10m, surface_pressure
   * Target: weather_class (mapped from weather_code):
       - Codes 0, 1        -> "Clear"
       - Codes 2, 3        -> "Cloudy"
       - Codes 51, 53, 55  -> "Drizzle"
       - Codes 61, 63, 65  -> "Rain"
   * Model: DecisionTreeClassifier or RandomForestClassifier

================================================================================
5. SUPABASE CLOUD DATABASE SETUP & API SYNTAX
--------------------------------------------------------------------------------
- Supabase REST URL Format:
  https://<project-ref>.supabase.co/rest/v1/<table_name>

- Active Credentials (from your workspace):
  URL: https://gtbhqmcbztuvgsbhyzdg.supabase.co/rest/v1
  KEY: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imd0YmhxbWNienR1dmdzYmh5emRnIiwicm9sZSI6ImFub24iLCJpYXQiOjE3OTM1ODMzNDksImV4cCI6MjEwOTE1OTM0OX0.dNmQlR39JRWqMW03iDIwYtg4dvJzPopTc_a8LdRHgyQ

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

- Insert Row (POST):
  resp = requests.post(f"{SUPABASE_URL}/{TABLE}", headers=headers, json=record)

- Fetch Recent Rows (GET):
  resp = requests.get(f"{SUPABASE_URL}/{TABLE}?select=*&order=id.desc&limit=50", headers=headers)
  data = resp.json()

- Critical Supabase Gotcha:
  If POST returns 401 or 403 Forbidden: In Supabase Dashboard -> Table Editor -> Select Table ->
  RLS (Row Level Security) must either have an "Enable Insert for Anon" policy, or be temporarily disabled.

================================================================================
6. FREE PUBLIC REST APIS (NO API KEY REQUIRED)
--------------------------------------------------------------------------------
- Kochi Weather:
  https://api.open-meteo.com/v1/forecast?latitude=9.93&longitude=76.27&current=temperature_2m,relative_humidity_2m,surface_pressure,wind_speed_10m

- Kochi Air Quality:
  https://air-quality-api.open-meteo.com/v1/air-quality?latitude=9.93&longitude=76.27&current=pm10,pm2_5,nitrogen_dioxide,sulphur_dioxide,ozone

- USGS Global Earthquakes (GeoJSON):
  https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson

- International Space Station Real-Time Coordinates:
  http://api.open-notify.org/iss-now.json

================================================================================
7. STREAMLIT ESSENTIALS FOR EXAM
--------------------------------------------------------------------------------
- Structure of a 30-Mark Dashboard:
  1. Header / Title:
     st.set_page_config(layout="wide")
     st.title("🛰️ System Title")
  2. Metric Cards Row:
     col1, col2, col3, col4 = st.columns(4)
     col1.metric("Parameter 1", f"{val1} °C")
     col2.metric("Parameter 2", f"{val2} %")
  3. Prediction Banner:
     if pred == 1:
         st.error("🚨 HAZARD / OCCUPIED")
     else:
         st.success("✅ SAFE / VACANT")
  4. Time-Series Chart:
     st.line_chart(df[['feature1', 'feature2']])
  5. Data Table & Export:
     st.dataframe(df, use_container_width=True)
     st.download_button("Export CSV", df.to_csv(index=False), "data.csv")

- Crucial Streamlit Performance Tip:
  Always cache model training using @st.cache_resource:
  @st.cache_resource
  def load_and_train_model():
      ...
      return model
  This prevents the model from retraining every time a button is clicked or a slider is moved!

================================================================================
8. COMMON EXAM ERRORS & QUICK FIXES
--------------------------------------------------------------------------------
1. OSError: [Errno 10048] address already in use (Port 5683 or Port 8501)
   Cause: A previous Python server process was not closed properly.
   Fix: In PowerShell run:
        Get-Process python | Stop-Process -Force
        Or close the previous terminal tab and reopen.

2. Paho-MQTT TypeError / Deprecation Warning:
   Fix:
   try:
       client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
   except AttributeError:
       client = mqtt.Client()

3. Missing Dataset File (city_day.csv, datatraining.txt, etc.):
   Fix: All our code bank scripts (CQ1-CQ8, Q1-Q4, SQ1-SQ7) include automatic
        synthetic dataset generators, so if the CSV is not found, it automatically
        generates realistic training data so your code never crashes during evaluation!

4. COM Port Access Denied (pyserial):
   Cause: The Arduino IDE Serial Monitor is already open and occupying the COM port.
   Fix: Close the Serial Monitor in Arduino IDE before running the Python script.

5. CoAP Client Timeout:
   Cause: CoAP Server (server.py) was not started before client.py.
   Fix: Keep Terminal 1 running server.py continuously in the background.
================================================================================
