#Atividade 2 - César Castilho
import machine #biblioteca para fazer a interface com os pinos de entrada e saída
import time #biblioteca para usar comandos relacionados ao tempo
from machine import PWM, Pin #biblioteca para utilizar as classes PWM e Pin
import network #bliblioteca para conexão de rede
import esp #bliblioteca do ESP32
import gc #bliblioteca para o garbage collector
import socket #bliblioteca para criação de sockets

esp.osdebug(None) #desliga as mensagens de debug da espressif 
gc.collect() #limpa os objetos não usados da memória do microcontrolador

#Definição dos pinos:
led = machine.Pin(18, machine.Pin.OUT) #definindo o pino 2 como saída para controlar o LED vermelho
led2 = Pin(19, Pin.OUT) #definindo o pino 0 para controlar o LED azul
bot = Pin(16, Pin.IN) #define o botão no pino 16 como entrada para controlar o botão
tone = PWM(Pin(17, Pin.OUT)) #define o pino 4 como saída PWM para controlar o buzzer

#Assegura que o buzzer não emita som antes de o sensor detectar algo:
tone.duty(0)

#Definição da interrupção:
tref = 0 #ajustando o tempo inicial para evitar o repique do botão

#Variáveis para controle:
botao_pressionado = False #flag para indicar se o botão está pressionado
sistema_ativado = False #flag para indicar se o sistema de vigilância está ativado
alarme_habilitado = False #flag para indicar se o alarme está habilitado

#Handler para leitura do botão:
def apertoubotao(pin):
    global tref #referência global para tref
    global botao_pressionado #referência global para botao_pressionado
    if (time.ticks_ms() - tref) > 300: #se o tempo desde o último evento for maior que 300 ms
        tref = time.ticks_ms()    
        botao_pressionado = not botao_pressionado #alterna o estado do botão pressionado
        print("Sensor detectou algo:", botao_pressionado)

bot.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=apertoubotao) #ajustando uma interrupção para o botão

#Função que se conecta a rede:
def conectar(rede, senha):
    wlan = network.WLAN(network.STA_IF) #cria uma interface de estação (cliente de rede)
    wlan.active(True) #ativa a interface de estação
    if not wlan.isconnected(): #verifica se não está conectado
        wlan.connect(rede, senha) #conecta à rede usando SSID e senha fornecidos
        while not wlan.isconnected(): #espera até conectar
            pass

#Página Web:
def pagina():
    estado_sistema = "Ativado" if sistema_ativado else "Desativado"  #define o estado do sistema
    estado_alarme = "Habilitado" if alarme_habilitado else "Desabilitado"  #define o estado do alarme
    html = """
    <html>
    <head>
    <title>Servidor Web de César</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link rel="icon" href="data:,">
    <style>
    html{font-family: Helvetica; display:inline-block; margin: 0px auto; text-align: center;}
    h1{color: #449944; padding: 4vh;}
    p{font-size: 1.5rem;}
    .button{
    background-color: #FFFF00;
    border-radius: 10px;
    padding: 16px 40px;
    font-size: 30px;
    margin: 2px;
    }
    .button2{background-color: #0000FF;}
    </style>
    </head>
    <body>
    <h1>Servidor WEB de César</h1>
    <p>Sistema de Vigilância: <strong>""" + estado_sistema + """</strong></p>
    <p>Alarme: <strong>""" + estado_alarme + """</strong></p>
    <p><a href="/?ativarSistema"><button class="button">Ativar Sistema</button></a></p>
    <p><a href="/?desativarSistema"><button class="button button2">Desativar Sistema</button></a></p>
    <p><a href="/?habilitarAlarme"><button class="button">Habilitar Alarme</button></a></p>
    <p><a href="/?desabilitarAlarme"><button class="button button2">Desabilitar Alarme</button></a></p>
    </body>
    </html>
    """
    return html  

#Conectando a rede wi-fi:
conectar('SSID_da_Sua_Rede', 'Senha_da_Sua_Rede') #conecta à rede com SSID e senha fornecidos

#Criação de sockets:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #cria um socket TCP/IP
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #permite reutilizar o endereço IP
s.bind(('', 80)) #liga o socket a qualquer endereço IP na porta 80
s.listen(4) #configura o número máximo de conexões recebidas para 4


#Loop principal:
while True:
    conexao, endr = s.accept() #aceita uma conexão, armazenando o socket e o endereço do cliente
    print('Conexão recebida de %s' % str(endr)) #imprime o endereço do cliente
    request = conexao.recv(1024) #recebe a requisição do cliente (máximo de 1024 bytes)
    request = str(request) #converte a requisição para string
    print('Solicitação recebida: %s' % request) #imprime a requisição recebida

#Verifica se a requisição é para ativar/desativar o sistema ou habilitar/desabilitar o alarme:
    if '/?ativarSistema' in request:
        sistema_ativado = True #ativa o sistema de vigilância
        print('Sistema de Vigilância Ativado!')
    if '/?desativarSistema' in request:
        sistema_ativado = False #desativa o sistema de vigilância
        print('Sistema de Vigilância Desativado!')
    if '/?habilitarAlarme' in request:
        alarme_habilitado = True #habilita o alarme
        print('Alarme Habilitado!')
    if '/?desabilitarAlarme' in request:
        alarme_habilitado = False #desabilita o alarme
        print('Alarme Desabilitado!')

    resposta = pagina() #gera a página HTML atualizada

#Envia a resposta HTTP com a página HTML:
    conexao.send('HTTP/1.1 200 OK\n')
    conexao.send('Content-Type: text/html\n')
    conexao.send('Connection: close\n\n')
    conexao.sendall(resposta) #envia toda a página HTML
    conexao.close() #fecha a conexão com o cliente

#Controla os LEDs e o buzzer de acordo com o estado do sistema e do alarme:
 if sistema_ativado and botao_pressionado and alarme_habilitado:
        tone.duty(512) #liga o buzzer com duty cycle 512
        if (time.ticks_ms() % 500) < 250: #alterna os LEDs a cada 250 ms
            led.value(True) #liga o LED vermelho
            led2.value(False) #desliga o LED azul
            tone.freq(350) #define a frequência do buzzer para 350 Hz
        else:
            led.value(False) #desliga o LED vermelho
            led2.value(True) #liga o LED azul
            tone.freq(300) #define a frequência do buzzer para 300 Hz
    else:
        tone.duty(0) #desliga o buzzer
        led.value(False) #desliga o LED vermelho
        led2.value(False) #desliga o LED azul
$abcdeabcde151015202530fghijfghij