# ==================================================
# AEROTECH IOT WEATHER STATION
# FINAL DEPLOYMENT VERSION (Verified)
# ==================================================

from machine import Pin, I2C, ADC
import time
import network
import urequests
import bme280
import math
import machine

# ==================================================
# 1. WI-FI CONFIGURATION (EDIT BEFORE DEPLOYING!)
# ==================================================

# UNIVERSITY (Use this for Deployment) ---
# Remove the '#' from the next two lines when at University:
WIFI_SSID = "YOUR WIFI ID"
WIFI_PASS = "YOUR WIFI PASSWORD"      

# --- OPTION B: HOME/TEST ---
# Add a '#' to the start of these lines before going to University:
# WIFI_SSID = "Minyoongipreciousbaby"
# WIFI_PASS = "minsuga03"

# ==================================================
# 2. SYSTEM SETTINGS
# ==================================================
WRITE_API_KEY = "YOUR API KEY"
THINGSPEAK_URL = "YOUR THINGSPEAK URL"

# 20 Minutes * 60 Seconds = 1200 Seconds
SEND_INTERVAL = 1200  
BASELINE_CLEAN = 10000

# ==================================================
# 3. SENSOR & WIND SETUP
# ==================================================
# Wind Calibration
CLICKS_PER_REV = 2
WIND_FACTOR = 5
RADIUS_METERS = 0.068
CIRCUMFERENCE = 2 * math.pi * RADIUS_METERS

# BME280 Setup
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
bme = None
while bme is None:
    try:
        bme = bme280.BME280(i2c=i2c, address=0x76)
        print("✅ BME280 Connected!")
    except Exception as e:
        print("⚠️ BME280 not found. Retrying...")
        time.sleep(2)

# Other Sensors
mq135 = ADC(26)
hall_sensor = Pin(14, Pin.IN, Pin.PULL_UP)
wind_clicks = 0

# Wind Counter (Interrupt)
def count_wind(pin):
    global wind_clicks
    wind_clicks += 1

hall_sensor.irq(trigger=Pin.IRQ_FALLING, handler=count_wind)

# ==================================================
# 4. WI-FI UPLOAD FUNCTION (RETURNS STATUS)
# ==================================================
def send_to_cloud(t, h, p, g, w):
    """Connects, Uploads, and Disconnects. Returns TRUE if successful."""
    upload_success = False # Assume failure initially
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.config(pm=0xa11140) 
    
    print(f"Connecting to {WIFI_SSID}...")
    wlan.connect(WIFI_SSID, WIFI_PASS)
    
    # Increased timeout to 30s for University Networks
    max_wait = 30
    while max_wait > 0:
        if wlan.isconnected():
            break
        max_wait -= 1
        time.sleep(1)

    if wlan.isconnected():
        print("Connected! Uploading...")
        try:
            url = (
                f"{THINGSPEAK_URL}?api_key={WRITE_API_KEY}"
                f"&field1={t:.2f}&field2={h:.2f}&field3={p:.2f}"
                f"&field4={g:.0f}&field5={w:.2f}"
            )
            response = urequests.get(url)
            print("Status:", response.text)
            response.close()
            # If we get here, no error happened
            upload_success = True 
        except Exception as e:
            print("Upload Error:", e)
    else:
        print("❌ WiFi Connection Failed.")

    print("Going dark (WiFi OFF)...")
    wlan.active(False) 
    return upload_success # Returns True or False

# ==================================================
# 5. MAIN LOOP (RETRY LOGIC + FULL LOGS)
# ==================================================
print("AeroTech Deployment System ACTIVE")
print(f"Interval: {SEND_INTERVAL/60} minutes.")

# Ensure WiFi is off initially
wlan_init = network.WLAN(network.STA_IF)
wlan_init.active(False)

# Variables
sum_temp = 0
sum_hum = 0
sum_pres = 0
sum_gas = 0
reading_count = 0

# [IMMEDIATE START TRICK]
# Forces immediate upload on first run
last_sent_time = time.time() - SEND_INTERVAL 

while True:
    try:
        current_time = time.time()

        # A. Read Sensors
        t, p_raw, h = bme.read_compensated_data()
        p_kpa = p_raw * 25.6 
        gas_raw = mq135.read_u16()

        sum_temp += t
        sum_hum += h
        sum_pres += p_kpa
        sum_gas += gas_raw
        reading_count += 1
        
        # B. Check Time (20 Minutes)
        if (current_time - last_sent_time) >= SEND_INTERVAL:
            
            # 1. Prepare Data
            current_clicks = wind_clicks
            # Note: We do NOT reset wind_clicks yet!
            
            if reading_count == 0: reading_count = 1
            
            avg_temp = sum_temp / reading_count
            avg_hum = sum_hum / reading_count
            avg_pres = sum_pres / reading_count
            avg_gas = sum_gas / reading_count
            
            # Wind Calculation
            revolutions = current_clicks / CLICKS_PER_REV
            elapsed = current_time - last_sent_time
            if elapsed == 0: elapsed = 1
            rps = revolutions / elapsed
            wind_speed_mps = rps * CIRCUMFERENCE * WIND_FACTOR

            # 2. Local Report (FULL LOGS RESTORED)
            diff = avg_gas - BASELINE_CLEAN
            if diff < 3000: air_status = "GOOD"
            elif diff < 10000: air_status = "MODERATE"
            else: air_status = "POOR"

            suggestion = "Conditions are normal."
            if wind_speed_mps > 5.0: suggestion = "⚠️ WARNING: Strong wind detected!"
            elif air_status == "POOR": suggestion = "⚠️ CRITICAL: Poor Air Quality!"
            elif wind_speed_mps > 1.5 and avg_temp < 32: suggestion = "✅ PERFECT: Great weather outside!"
            elif avg_temp > 35: suggestion = "⚠️ HOT: Stay hydrated."
            
            print("\n" + "="*30)
            print(f"🌡️ Temp: {avg_temp:.2f} C")
            print(f"💧 Hum:  {avg_hum:.1f} %")
            print(f"💨 Wind: {wind_speed_mps:.2f} m/s")
            print(f"🍃 Air:  {air_status}")
            print(f"💡 Note: {suggestion}")
            print("="*30 + "\n")

            # 3. Upload to Cloud (CHECK SUCCESS)
            is_uploaded = send_to_cloud(avg_temp, avg_hum, avg_pres, avg_gas, wind_speed_mps)

            if is_uploaded:
                # ✅ SUCCESS: Reset everything and wait 20 mins
                print("✅ Upload Complete. Resetting timer.")
                
                sum_temp = 0
                sum_hum = 0
                sum_pres = 0
                sum_gas = 0
                reading_count = 0
                wind_clicks = 0 # Only reset wind if data was sent!
                
                # Reset Timer to NOW
                last_sent_time = time.time()
                
            else:
                # ❌ FAILED: Do NOT reset timer.
                print("⚠️ Upload Failed. Retrying in 60 seconds...")
                time.sleep(60) 
                # Loop repeats immediately, triggering upload again

        # C. Deep Sleep (5 Seconds standard loop)
        time.sleep(5)

    except Exception as e:
        print("Fatal Error:", e)
        time.sleep(5)
