import network
import time
import dht
import machine
from umqtt.simple import MQTTClient
import sys

# Adafruit IO credentials
AIO_SERVER = "io.adafruit.com"
AIO_PORT = 1883
AIO_USER = "learnpracticaliot"  # Your Adafruit IO username
AIO_KEY = "aio_HqfU40RxeZld8rxJ1QljsomDIwWY"    # Your Adafruit IO key
AIO_FEED_TEMP = "learnpracticaliot/feeds/temperature"  # Change to your Adafruit IO feed
AIO_FEED_HUM = "learnpracticaliot/feeds/humidity"  # Change to your Adafruit IO feed
AIO_FEED_LED = "learnpracticaliot/feeds/led"  # Change to your Adafruit IO feed
AIO_FEED_LED1 = "learnpracticaliot/feeds/led1"  # Change to your Adafruit IO feed

# Initialize DHT11 sensor and LED
dht_sensor = dht.DHT22(machine.Pin(4))  # DHT11 on GPIO4
led = machine.Pin(2, machine.Pin.OUT)   # On Board LED at GPIO2 (adjust based on your setup)
led1 = machine.Pin(5, machine.Pin.OUT)  # External LED at GPIO5 (led1 is one of the adafruit IO feed)

WIFI_SSID     = 'Wokwi-GUEST' # Put your own WiFi SSID
WIFI_PASSWORD = ''          # No password

def connect_wifi():
    wifi = network.WLAN(network.STA_IF)
    wifi.active(True)
    wifi.disconnect()
    wifi.connect(WIFI_SSID,WIFI_PASSWORD)
    if not wifi.isconnected():
        print('connecting...to your wifi')
        timeout = 0
        while (not wifi.isconnected() and timeout < 10):
            print(10 - timeout)
            timeout = timeout + 1
            time.sleep(1) 
    if(wifi.isconnected()):
        print('connected')
    else:
        print('not connected')
        sys.exit()
connect_wifi() # Connecting to WiFi Router 

# MQTT callback function
def sub_cb(topic, msg):
    print(f"Received message: {msg} on topic: {topic}")
    # No message control needed, as we're directly checking sensor data
    if msg == b'ON':
        led1.value(1)
        print("Manually LED-External turned ON")
    elif msg == b'OFF':
        led1.value(0)
        print("Manually LED-External turned OFF")
    
# Connect to Adafruit IO using MQTT
def connect_and_subscribe():
    client = MQTTClient("esp32", AIO_SERVER, AIO_PORT, AIO_USER, AIO_KEY)
    client.set_callback(sub_cb)
    client.connect()
    #client.subscribe(AIO_FEED_TEMP)
    #client.subscribe(AIO_FEED_HUM)
    #client.subscribe(AIO_FEED_LED)
    client.subscribe(AIO_FEED_LED1)
    print("Connected to Adafruit IO and subscribed to feed ...")
    return client
'''
# Publish Sensor  Data
def publish_sensor_data(client, temp):
    print(f"Publishing temperature: {temp}°C to Adafruit IO")
    client.publish(AIO_FEED_TEMP, str(temp))
# Publish Sensor  Data
def publish_sensor_data(client, hum):
    print(f"Publishing humidity: {hum} % to Adafruit IO")
    client.publish(AIO_FEED_HUM, str(hum))
'''
# Main loop to read DHT11 sensor and control LED
def main():
    try:
        client = connect_and_subscribe()

        while True:
            dht_sensor.measure()  # Measure temperature and humidity
            temperature = dht_sensor.temperature()
            humidity = dht_sensor.humidity()
            
            print(f"Temperature: {temperature} °C")
            print(f"Humidity: {humidity} %")

            client.publish(AIO_FEED_TEMP,    
                  bytes(str(temperature), 'utf-8'),   # Publishing Temp feed to adafruit.io
                  qos=1)
    
            client.publish(AIO_FEED_HUM,    
                  bytes(str(humidity), 'utf-8'),   # Publishing Hum feed to adafruit.io
                  qos=1)
            print('Msg sent to Adafruit IO successfully...')

            '''
            # Publish temperature to Adafruit IO
            publish_sensor_data(client, temperature)
            # Publish humidity to Adafruit IO
            publish_sensor_data(client, humidity)
            '''
            # Control LED based on temperature
            if temperature > 30:
                led.value(1)  # Turn LED ON
                print("ON Board LED turned ON (temperature > 30°C)")
            else:
                led.value(0)  # Turn LED OFF
                print("On Board LED turned OFF (temperature <= 30°C)")
            print("*********************************************)")         
           
            # Delay before the next reading
            time.sleep(10)
            # Check for incoming MQTT messages
            client.check_msg()
    except OSError as e:
        print(f"Failed to read sensor: {e}")
        machine.reset()  # Reset the ESP32 on failure
        #sys.exit()

# Run the main function
if __name__ == "__main__":
    main()








'''
from machine import Pin, Timer
import network
import time
from umqtt.robust import MQTTClient
import sys
import dht

# DHT11 Sensor on Pin 4 (GPIO4) of ESP32
sensor = dht.DHT22(Pin(4))                
# Initialize LED on GPIO2
led = Pin(2, Pin.OUT)

WIFI_SSID     = 'Wokwi-GUEST' # Put your own WiFi SSID
WIFI_PASSWORD = ''             # Put WiFi password if no password then leave it as it is (empty)

mqtt_client_id      = bytes('client_'+'12321', 'utf-8') # Just a random client ID

ADAFRUIT_IO_URL     = 'io.adafruit.com' # Also known as ADAFRUIT_SERVER
ADAFRUIT_USERNAME   = 'learnpracticaliot' # Put your own (Find it from your Key Icon of your account)
ADAFRUIT_IO_KEY     = 'aio_HqfU40RxeZld8rxJ1QljsomDIwWY'

TEMP_FEED_ID      = 'temperature'
HUM_FEED_ID      = 'humidity'
ADAFRUIT_IO_FEED_LED = 'learnpracticaliot/feeds/led'   # Replace with your 

def connect_wifi():
    wifi = network.WLAN(network.STA_IF)
    wifi.active(True)
    wifi.disconnect()
    wifi.connect(WIFI_SSID,WIFI_PASSWORD)
    if not wifi.isconnected():
        print('connecting...to your wifi')
        timeout = 0
        while (not wifi.isconnected() and timeout < 10):
            print(10 - timeout)
            timeout = timeout + 1
            time.sleep(1) 
    if(wifi.isconnected()):
        print('connected')
    else:
        print('not connected')
        sys.exit()
connect_wifi() # Connecting to WiFi Router 

# Callback function to handle messages from Adafruit IO
def sub_cb(topic, msg):
    print(f"Received message: {msg} on topic: {topic}")
    # Read the DHT11 sensor data
    sensor.measure()
    temperature = sensor.temperature()  # Get temperature in Celsius
    if msg == b'ON' or temperature > 30:
        led.value(1)
        print("LED turned ON")
    elif msg == b'OFF' or temperature < 30 :
        led.value(0)
        print("LED turned OFF")

client = MQTTClient(client_id=mqtt_client_id,
                    server=ADAFRUIT_IO_URL, 
                    user=ADAFRUIT_USERNAME, 
                    password=ADAFRUIT_IO_KEY,
                    ssl=False)

try:            
    client.connect()
    client.set_callback(sub_cb)  # Set the callback function
    print('Connected to Adafruit IO MQTT Broker')
    client.subscribe(ADAFRUIT_IO_FEED_LED)  # Subscribe to the LED control feed

except Exception as e:
    print('could not connect to MQTT server {}{}'.format(type(e).__name__, e))
    sys.exit()
        
temp_feed = bytes('{:s}/feeds/{:s}'.format(ADAFRUIT_USERNAME, TEMP_FEED_ID), 'utf-8') # format - learnpracticaliot/feeds/temperature
hum_feed = bytes('{:s}/feeds/{:s}'.format(ADAFRUIT_USERNAME, HUM_FEED_ID), 'utf-8') # format - learnpracticaliot/feeds/humidity  

def sens_data(data):
    sensor.measure()                    # Measuring Sensor data
    temp = sensor.temperature()         # getting Temperature data from the measure()
    hum = sensor.humidity()             # getting Humidity
    client.publish(temp_feed,    
                  bytes(str(temp), 'utf-8'),   # Publishing Temp feed to adafruit.io
                  qos=0)
    
    client.publish(hum_feed,    
                  bytes(str(hum), 'utf-8'),   # Publishing Hum feed to adafruit.io
                  qos=0)

    print("Temperature - ", str(temp), "Deg. Celcius")
    print("Humidity - " , str(hum), "%") 
    print('Msg sent to Adafruit IO successfully...')
    
    # Check for incoming MQTT messages
    client.check_msg()
timer = Timer(0)
timer.init(period=5000, mode=Timer.PERIODIC, callback = sens_data)'''