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

# MQTT Server Parameters
MQTT_CLIENT_ID = "demoDave"
MQTT_BROKER    = "broker.emqx.io"
MQTT_USER      = ""
MQTT_PASSWORD  = ""
SENSOR_TOPIC     = "/S1GM4/Dave/data_sensor"
LED_TOPIC = "/S1GM4/Dave/aktuasi_led"

led = Pin(2, Pin.OUT)
sensor = dht.DHT22(Pin(15))

# WIFI Connection
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!")

# MQTT Server connection
print("Connecting to MQTT server... ", end="")
client = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER, user=MQTT_USER, password=MQTT_PASSWORD)
client.connect()
print("Connected!")

# MQTT callback for LED control
def mqtt_callback(topic, msg):
    print(f"Received message on {topic.decode()}: {msg.decode()}")
    try:
        message = ujson.loads(msg.decode())  # Parse JSON message
        if "msg" in message:
            command = message["msg"].lower()
            if command == "on":
                led.on()
                print("LED turned ON")
            elif command == "off":
                led.off()
                print("LED turned OFF")
            else:
                print(f"Unknown command: {command}")
        else:
            print("Invalid message format: 'msg' key not found")
    except ValueError as e:
        print(f"Error parsing JSON: {e}")

client.set_callback(mqtt_callback)
client.subscribe(LED_TOPIC)
print(f"Subscribed to topic: {LED_TOPIC}")

# Build the message in JSON format and send the message only if there is a change
prev_weather = ""
while True:
  client.check_msg() 
  time.sleep(0.1)
  print("Measuring weather conditions... ", end="")
  sensor.measure() 
  message = ujson.dumps({
    "temp": sensor.temperature(),
    "humidity": sensor.humidity(),
  })
  if message != prev_weather:
    print("Updated!")
    print("Reporting to MQTT topic {}: {}".format(SENSOR_TOPIC, message))
    # Send the message
    client.publish(SENSOR_TOPIC, message)
    prev_weather = message
  else:
    print("No change")
  time.sleep(1)