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

# MQTT Server Parameters
MQTT_BROKER    = "broker.mqttdashboard.com"
MQTT_PORT      = 1883
MQTT_USER      = ""
MQTT_PASSWORD  = ""
MQTT_TOPIC     = "iotmc/temperatura/as2"
MQTT_STATUS_TOPIC = "iotmc/umidade/status"
MQTT_CONTROL_TOPIC = "iotmc/control"  # Novo tópico de controle
MQTT_CLIENT_ID = "clientId-5gbwvTLI6b-WK"

# Definir os pinos para os LEDs RGB e usar PWM
red = PWM(Pin(19), freq=1000)    # Frequência de 1kHz
green = PWM(Pin(5), freq=1000)   # Frequência de 1kHz
blue = PWM(Pin(2), freq=1000)    # Frequência de 1kHz

# Sensor DHT22 no pino 15
sensor = dht.DHT22(Pin(15))

# Variável de controle de execução
running = True

# Função para ajustar o brilho (duty cycle dos LEDs)
def set_color(red_duty, green_duty, blue_duty):
    red.duty(red_duty)
    green.duty(green_duty)
    blue.duty(blue_duty)

# Função para conectar ao WiFi
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!")

# Função de callback para receber mensagens de controle
def control_callback(topic, msg):
    global running  # Usar a variável global
    command = msg.decode('utf-8')  # Decodificar a mensagem
    if command == 'DESLIGAR':
        running = False
        print("Recebido comando para DESLIGAR.")
        set_color(1023, 1023, 1023)  # Apaga todos os LEDs ao desligar
    elif command == 'LIGAR':
        running = True
        print("Recebido comando para LIGAR.")

# Função para conectar ao MQTT
def connect_mqtt():
    global client  # Usa a variável global
    client = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER, user=MQTT_USER, password=MQTT_PASSWORD, keepalive=60)
    client.set_callback(control_callback)  # Configura a função callback
    try:
        client.connect()
        print("Conectado ao broker MQTT")
        client.subscribe(MQTT_CONTROL_TOPIC)  # Inscreve-se no tópico de controle
    except OSError as e:
        print("Falha na conexão ao broker MQTT: ", e)

# Conectar ao WiFi e MQTT
connect_wifi()
connect_mqtt()

prev_weather = ""  # Variável para armazenar a última mensagem enviada

while True:
    try:
        # Verifica se há mensagens MQTT (comando de controle) a cada ciclo
        client.check_msg()

         # Verificar se o loop deve continuar
        if not running:
            print("Sistema DESLIGADO. Aguardando comando para LIGAR...")
            time.sleep(1)  # Esperar um pouco antes de verificar novamente
            continue

        if running:
            print("Medindo condições climáticas... ", end="")
            sensor.measure()  # Mede temperatura e umidade
            temp = sensor.temperature()
            hum = sensor.humidity()
            temp = random.uniform(4, 45)  # Temperatura entre 4°C e 45°C
            hum = random.uniform(10, 99)  # Umidade entre 10% e 99%

            # Variável para armazenar a mensagem de status
            status = ""

            # Controle das cores dos LEDs de acordo com a umidade
            if hum < 30:  # Abaixo de 30% - Vermelho 
                set_color(0, 1023, 1023)  # Vermelho ligado, Verde e Azul apagados
                status = 'PERIGO ar muito seco - Ressecamento das vias aéreas'
            elif 31 <= hum <= 49:  # Entre 31% e 49% - Laranja
                set_color(0, 410, 1023)  # Vermelho mais forte que Verde, Azul apagado
                status = 'CUIDADO - Baixa umidade'
            elif 50 <= hum <= 59:  # Entre 50% e 59% - Amarelo 
                set_color(0, 0, 1023)  # Vermelho e Verde ligados, Azul apagado
                status = 'ATENÇÃO - Umidade moderada'
            elif 60 <= hum <= 69:  # Entre 60% e 69% - Verde 
                set_color(1023, 0, 1023)  # Somente o Verde ligado
                status = 'ÓTIMO - Recomendado pela OMS'
            elif 70 <= hum <= 79:  # Entre 70% e 79% - Azul 
                set_color(1023, 1023, 0)  # Somente o Azul ligado
                status = 'EXCELENTE - Alta umidade'
            elif hum >= 80:  # Acima de 80% - Violeta
                set_color(594, 1023, 839)  # Violeta (58% vermelho, 0% verde, 82% azul)
                status = 'PREOCUPANTE - aumento de proliferação de fungos e bactérias'

            # Criar mensagem em JSON após a definição do status
            message = ujson.dumps({
                "temp": round(temp, 1),
                "hum": round(hum, 1),
            })

            # Publicar status separadamente no tópico MQTT de status
            print("Enviando ao tópico MQTT_STATUS_TOPIC {}: {}".format(MQTT_STATUS_TOPIC, status))
            client.publish(MQTT_STATUS_TOPIC, status)

            # Aguardar 2 segundos entre as publicações para evitar sobrecarga
            time.sleep(2)

            # Enviar dados ao MQTT apenas se houver mudança no clima
            if message != prev_weather:
                print("Atualizado!")
                print("Enviando ao tópico MQTT {}: {}".format(MQTT_TOPIC, message))
                client.publish(MQTT_TOPIC, message)
                prev_weather = message
            else:
                print("Sem alterações")

            time.sleep(5)  # Pausa de 5 segundos antes da próxima leitura

        else:
            print("Sistema em espera. Aguardando comando LIGAR.")
            time.sleep(1)  # Aguarda 1 segundo antes de checar novamente

    except OSError as e:
        print("Erro de conexão MQTT: ", e)
        connect_mqtt()  # Tenta reconectar ao broker MQTT
        time.sleep(1)  # Espera um segundo antes de tentar novamente