"""
MicroPython IoT LED Example for Wokwi.com

I recommend using your own HiveMQ instance,
using the public one doesn't seem to work reliably

Copyright (C) 2024, Michael R.

https://wokwi.com/projects/401109238012712961
"""

import network
import time
from machine import Pin, reset, PWM
import dht
import ujson
from umqtt.simple import MQTTClient
import ssl
 
# MQTT Server Parameters
MQTT_CLIENT_ID = "CodeBlue-Andin-led"
MQTT_BROKER    = "broker.emqx.io"
MQTT_USER      = ""
MQTT_PASSWORD  = ""
MQTT_TOPIC     = "CodeBlue/Andin/aktuasi_led"

# RGB
RED = 0
GREEN = 1
BLUE = 2

# Declare pins
pwm_pins = [23,22,21]

# Setup pins for PWM
pwms = [PWM(Pin(pwm_pins[RED])),PWM(Pin(pwm_pins[GREEN])),
                PWM(Pin(pwm_pins[BLUE]))]

# Set pwm frequency
[pwm.freq(1000) for pwm in pwms]

pwms[RED].duty_u16(65535)
pwms[GREEN].duty_u16(65535)
pwms[BLUE].duty_u16(0)

# Ping the MQTT broker since we are not publishing any message
last_ping = time.time()
ping_interval = 60

lastMessage = {}

# Received messages from subscriptions will be delivered to this callback
def sub_cb(topic, msg):
    print((topic, msg))
    global lastMessage
    lastMessage = ujson.loads(msg)
    if (lastMessage["temp"] >= 45):
      # Display RED
      pwms[RED].duty_u16(65535)
      pwms[GREEN].duty_u16(0)
      pwms[BLUE].duty_u16(0)
    else:
      # Display GREEN
      pwms[RED].duty_u16(0)
      pwms[GREEN].duty_u16(65535)
      pwms[BLUE].duty_u16(0)

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!")

print("Connecting to MQTT server... ", end="")
mqttClient = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER, user=MQTT_USER, password=MQTT_PASSWORD)
#mqttClient = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER, port=MQTT_PORT, ssl=True, ssl_params=MQTT_SSL_PARAMS, user=MQTT_USER, password=MQTT_PASSWORD)
mqttClient.set_callback(sub_cb)
mqttClient.connect()
mqttClient.subscribe(MQTT_TOPIC)

print(f"Connected to MQTT  Broker :: {MQTT_BROKER}, and waiting for callback function to be called!")
while True:
    # Non-blocking wait for message
    mqttClient.check_msg()
    # Then need to sleep to avoid 100% CPU usage, 
    # could also perform other tasks here if necessary

    if (time.time() - last_ping) >= ping_interval:
        mqttClient.ping()
        last_ping = time.time()
        now = time.localtime()
        print(f"Pinging MQTT Broker, last ping :: {now[0]}/{now[1]}/{now[2]} {now[3]}:{now[4]}:{now[5]}")
    time.sleep(1)
        
print("Disconnecting...")
mqttClient.disconnect()