from machine import Pin, ADC
import network
import dht
import time
import urequests

# ThingSpeak 設定
CHANNEL_ID = '2920894'
API_KEY = 'J5PRB4PSE2HB7S3R'
HOST = 'http://api.thingspeak.com'
THINGSPEAK_URL = f'{HOST}/update?api_key={API_KEY}'

# Wi-Fi 設定
SSID = 'Wokwi-GUEST'
PASSWORD = ''

# 初始化感測器與 LED
p0 = Pin(2, Pin.IN)  # DHT22 連接到 GPIO2
d = dht.DHT22(p0)
water_level_sensor = ADC(Pin(35))  # 使用 GPIO34 來讀取水位電位器的值
water_level_sensor.atten(ADC.ATTN_0DB)  # 設置範圍為 0-3.3V
led_red = Pin(14, Pin.OUT)  # 紅色 LED
led_yellow = Pin(25, Pin.OUT)  # 黃色 LED
led_green = Pin(27, Pin.OUT)  # 綠色 LED
sw1 = Pin(5, Pin.IN, Pin.PULL_UP)  # SW1 按鈕

# 記錄變數
button_press_count = 0
temperature_history = []
humidity_history = []
water_level_history = []

# 連接 Wi-Fi
sta = network.WLAN(network.STA_IF)
sta.active(True)
sta.connect('Wokwi-GUEST','')

while not sta.isconnected():
    print(".", end="")
    time.sleep(0.1)
print(" Connected!")

# 上傳資料至 ThingSpeak
def upload_data(temp, hum, water_level):
    url = f'{THINGSPEAK_URL}&field1={temp}&field2={hum}&field3={water_level}'
    try:
        response = urequests.get(url)
        if response.status_code == 200:
            print('資料上傳成功')
        else:
            print('資料上傳失敗,狀態碼:', response.status_code)
    except Exception as e:
        print('上傳資料時發生錯誤:', e)

# 讀取感測器資料
def read_sensors():
    d.measure()
    temp = d.temperature()
    hum = d.humidity()

    # 讀取電位器的模擬值並將其轉換為水位百分比(0-100%)
    water_level_value = water_level_sensor.read()  # 讀取 0-4095 之間的數值
    water_level_percentage = (water_level_value / 4095) * 100  # 轉換為 0-100%

    return temp, hum, water_level_percentage

# 處理異常警報
def handle_alerts(temp, hum, water_level):
    if water_level < 30:
        led_red.on()
        print('Warning! Water level is too low!')
    else:
        led_red.off()

    if temp > 32:
        led_yellow.on()
        print('Warning! Temp. is too High!')
    else:
        led_yellow.off()

    if hum > 45:
        led_green.on()
        print('Warning! Hum. is too High!')
    else:
        led_green.off()

# 處理 SW1 按鈕事件
def handle_button():
    global button_press_count
    if not sw1.value():  # 按鈕被按下
        time.sleep(0.1)  # 防止抖動
        if not sw1.value():  # 確認按鈕仍被按下
            button_press_count += 1
            if button_press_count % 2 == 1:
                led_red.on()
                led_green.on()
                print('Warning! SW Touched!')
            else:
                led_red.off()
                led_green.off()
                print('Warning disable!!')

# 記錄資料
def record_data(temp, hum, water_level):
    temperature_history.append(temp)
    humidity_history.append(hum)
    water_level_history.append(water_level)
    if len(temperature_history) > 10:
        temperature_history.pop(0)
        humidity_history.pop(0)
        water_level_history.pop(0)

# 計算平均值
def calculate_averages():
    avg_temp = sum(temperature_history) / len(temperature_history)
    avg_hum = sum(humidity_history) / len(humidity_history)
    avg_water_level = sum(water_level_history) / len(water_level_history)
    return avg_temp, avg_hum, avg_water_level

# 開始執行
while True:
    temp, hum, water_level = read_sensors()  # 讀取感測器資料
    handle_alerts(temp, hum, water_level)  # 處理警報
    record_data(temp, hum, water_level)  # 記錄資料
    if len(temperature_history) == 10:
        avg_temp, avg_hum, avg_water_level = calculate_averages()  # 計算平均值
        upload_data(avg_temp, avg_hum, avg_water_level)  # 上傳資料
    handle_button()  # 處理按鈕事件
    time.sleep(15)  # 每 15 秒更新一次