import network
import time
import dht
import ujson
from machine import Pin
from umqtt.simple import MQTTClient

SSID = "Wokwi-GUEST"
PASSWORD = ""

MQTT_BROKER = "broker.emqx.io"
MQTT_PORT = 1883
MQTT_TOPIC_1 = "/uni559/ryan/data_sensor"
MQTT_TOPIC_2 = "/uni559/ryan/aktuasi_led"
MQTT_USERNAME = "emqx"
MQTT_PASSWORD = "public"

DHT_PIN = Pin(25)
LED_PIN = Pin(23, Pin.OUT)
BUZZER_PIN = Pin(13, Pin.OUT)
dht_sensor = dht.DHT22(DHT_PIN)

prev_temperature = None
prev_humidity = None

def connect_wifi():
    print("Connecting to WiFi...")
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(SSID, PASSWORD)

    while not wlan.isconnected():
        time.sleep(0.5)
        print(".", end="")
    print("\nWiFi connected!")
    print("IP Address: ", wlan.ifconfig()[0])

def connect_mqtt():
    print("Connecting to MQTT broker...")
    client = MQTTClient("WokwiESP32Client", MQTT_BROKER, MQTT_PORT, MQTT_USERNAME, MQTT_PASSWORD)
    client.set_callback(on_message)
    client.connect()
    client.subscribe(MQTT_TOPIC_2)
    print("Connected to MQTT Broker!")
    print(f"Subscribed to topic {MQTT_TOPIC_2}")
    return client

def on_message(topic, msg):
    print(f"Received message: {msg} on topic: {topic}")
    if topic.decode() == MQTT_TOPIC_2:
        try:
            payload = ujson.loads(msg)
            command = payload.get("msg", "").lower()
            if command == "on":
                LED_PIN.on()
                print("LED turned ON")
            elif command == "off":
                LED_PIN.off()
                print("LED turned off")
            else:
                print("Unknown command received for LED.")
        except Exception as e:
            print("Error parsing message: ", str(e))

def main():
    global prev_temperature, prev_humidity

    connect_wifi()
    client = connect_mqtt()

    while True:
        try:
            dht_sensor.measure()
            temperature = round(dht_sensor.temperature(), 2)
            humidity = round(dht_sensor.humidity(), 2)

            if temperature > 30:
                BUZZER_PIN.on()
                print("Buzzer ON: High Temperature!")
            else:
                BUZZER_PIN.off()

            if temperature != prev_temperature or humidity != prev_humidity:
                prev_humidity = humidity
                prev_temperature = temperature

                payload = {
                    "temperature": temperature,
                    "humidity": humidity
                }

                client.publish(MQTT_TOPIC_1, str(payload).replace("'", '"'))
                print("Data sent to MQTT broker:", payload)
            else:
                print("No change in temperature or humidity. Data not sent.")
            
            client.check_msg()

            time.sleep(2)

        except Exception as e:
            print("Error: ", str(e))
            time.sleep(2)

if __name__ == "__main__":
    main()