import network
from machine import I2C, Pin
from time import gmtime, time, sleep
import dht
from ds1307 import DS1307
from umqtt.simple import MQTTClient
#------------------------------------------------------------------------------
# Dados do MQTT e Variaveis Gerais
MQTT_CLIENT_ID1 = "PucCompSciTurmaBSend"
MQTT_CLIENT_ID2 = "PucCompSciTurmaBReceive"
MQTT_BROKER    = "test.mosquitto.org"
MQTT_TOPIC1     = "PosteFelizSend"
MQTT_TOPIC2     = "PosteFelizReceive"
SensorDHT = dht.DHT22(Pin(26))
Motion = False
I2C_ADDR = 0x68
GasUpper = False
GasDigital = Pin(16,Pin.IN)
MovimentoCount = 0
#-------------------------------------------------------------------------------
# Manda Mensagem
def SendMessage(Mensagem):
    client1 = MQTTClient(MQTT_CLIENT_ID1, MQTT_BROKER) # Redefine o cliente e o broker
    client1.connect() # Conecta no servidor'''
    client1.publish(MQTT_TOPIC1,Mensagem) # Publica a mensagem
    client1.disconnect() # Desconecta do servidor
    #Conectar e desconectar foi o unico jeito que não deu erro para mim
#--------------------------------------------------------------------------------
# Detecta Movimento
def MotionInterrupt(pin): # Função para quando o movimento é interrompido
    global Motion
    Motion = True
    #Obs: (pin) é necessario para o código funcionar, pois o IRQ alimenta o valor para a função
MotionSensor = Pin(23,Pin.IN) #Define o pin do sensor de movimento
MotionSensor.irq(trigger=Pin.IRQ_RISING,handler=MotionInterrupt) #Interrupt Request, é ativa quando movimento é detectado
#-------------------------------------------------------------------------------
# Setup Relógio
i2c = I2C(0, scl=Pin(19), sda=Pin(22), freq=100000)
ds1307 = DS1307(addr=I2C_ADDR, i2c=i2c)
def Time(): #Função que retorna string do tempo
    Hora = "{:02d}:{:02d}:{:02d} - {:02d}/{:02d}/{:04d}".format( # Dentro das aspas, mostra onde inserir os valores e quantos digitos para cada
    ds1307.hour, ds1307.minute, ds1307.second, ds1307.day, ds1307.month, ds1307.year)# Ordem para os dados
    return Hora # Retorna a string
#-------------------------------------------------------------------------------
# Detector de gás
def GasTrigger (pin): 
  global GasUpper # Define a variavel como global
  if GasDigital.value() == 0: #0 = Gás detectado
    GasUpper = True
  if GasDigital.value() == 1: #1 = Gás não detectado
    GasUpper = False
    
GasDigital.irq(trigger=Pin.IRQ_FALLING or Pin.IRQ_RISING,handler=GasTrigger) #Dá trigger quando o threshold é ultrapassado, e quando volta ao normal
# Conecta Na Internet
print("Conectando")
Wifi = network.WLAN(network.STA_IF) #STA_IF serve para indicar que o ESP32 irá procurar redes, no lugar de servir como roteador
Wifi.active(True) # Ativa a interface
Wifi.connect('Wokwi-GUEST', '') #Conecta na rede padrão
TempoEspera = 0
while not Wifi.isconnected() and TempoEspera != 50: # Espera uma conexão ser feita
    print("-", end="") #Print em varios "-" todos na mesma linha
    sleep(.1)
    TempoEspera += 1
#------------------------------------------------------------------------------
# MQTT Listen
def callback(topic,msg):
    print(msg.decode)
print("Connecting to MQTT server... ", end="")
client2 = MQTTClient(MQTT_CLIENT_ID2, MQTT_BROKER)
client2.set_callback(callback)
client2.connect()
client2.subscribe(MQTT_TOPIC2)
print("Connected!")
#--------------------------------------------------------------------------------
# Main Loop
if Wifi.isconnected(): 
    print("Wifi conectado")
    while True:
        if(Motion):
            SensorDHT.measure()
            MovimentoCount += 1
            SendMessage(f"{MovimentoCount}° Movimento Detectado: {Time()}\nTemperatura: {SensorDHT.temperature()}°C\nHumidade: {SensorDHT.humidity()}%")
            sleep(5)
            Motion = False
        if(GasUpper):
            SendMessage(f"Nível elevado de gás detectado - {Time()}")
            if GasDigital.value == 1: # Caso os níveis de gás caiam, o trigger não tava funcionando enquanto estava True
                GasUpper = False
        client1.check_msg()
        sleep(1)