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

# Setup LED dan Sensor DHT22
led = Pin(15, Pin.OUT)
sensor1 = dht.DHT22(Pin(4))
sensor2 = dht.DHT22(Pin(2))
tim = Timer(-1)

MQTT_CLIENT_ID = "mqttx_278862d0"
MQTT_BROKER    = "broker.emqx.io"
MQTT_USER      = ""
MQTT_PASSWORD  = ""
MQTT_TOPIC_PUB = "/uni010/dabbir/data_sensor"    
MQTT_TOPIC_SUB = "/uni010/dabbir/aktuasi_led"    

client = None
is_connected = False
prev_weather = ""

def connect_wifi():
    print("Connecting to WiFi", end="")
    sta_if = network.WLAN(network.STA_IF)
    sta_if.active(True)
    sta_if.connect('Wokwi-GUEST', '')
    while not sta_if.isconnected():
        print(".", end="")
        time.sleep(0.1)
    print(" Connected!")

def mqtt_connect():
    global client, is_connected
    try:
        print("Connecting to MQTT server... ", end="")
        client = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER, user=MQTT_USER, password=MQTT_PASSWORD)
        client.set_callback(sub_cb)
        client.connect()
        client.subscribe(MQTT_TOPIC_SUB)
        is_connected = True
        print("Connected!")
        print(f"Subscribed to {MQTT_TOPIC_SUB}")
        return True
    except Exception as e:
        print(f"Could not connect to MQTT server: {e}")
        is_connected = False
        return False

def sub_cb(topic, msg):
    topic_str = str(topic, 'UTF-8')
    msg_str = str(msg, 'UTF-8')
    print(f"Topic: {topic_str}")
    print(f"Message: {msg_str}")
    
    try:
        msg_json = ujson.loads(msg_str)
        command = msg_json.get("msg", "").upper()
        
        if command == "ON":
            led.on()
            print("LED is ON")
        elif command == "OFF":
            led.off()
            print("LED is OFF")
    except Exception as e:
        print(f"Error parsing message: {e}")

def pub_sensor_data(tim):
    global client, is_connected, prev_weather
    if not is_connected:
        mqtt_connect()
        return
        
    try:
        print("Measuring weather conditions... ", end="")
        sensor1.measure()
        sensor2.measure()
        
        message = ujson.dumps({
            "temp1": sensor1.temperature(),
            "humidity1": sensor1.humidity(),
            "temp2": sensor2.temperature(),
            "humidity2": sensor2.humidity(),
        })
        
        if message != prev_weather:
            print("Updated!")
            print(f"Publishing to {MQTT_TOPIC_PUB}: {message}")
            client.publish(MQTT_TOPIC_PUB, message)
            prev_weather = message
        else:
            print("No change in sensor data")
            
    except Exception as e:
        print(f"Error publishing: {e}")
        is_connected = False
        mqtt_connect()

connect_wifi()
mqtt_connect()

# Timer untuk publish data sensor setiap 5 detik
tim.init(period=5000, mode=Timer.PERIODIC, callback=lambda t: pub_sensor_data(t))

while True:
    try:
        if is_connected:
            client.check_msg()
        else:
            mqtt_connect()
        time.sleep(0.1)
    except Exception as e:
        print(f"Error in main loop: {e}")
        is_connected = False
        time.sleep(1)