import network
import socket
import time
from machine import Pin, PWM, I2C
from dht import DHT22
from uQR import QRCode
import ssd1306

# Configure Access Point
SSID = "ESP32-AP"
PASSWORD = "12345678"

# Pin configuration
LED_PIN = 2  # GPIO for LED
DHT_PIN = 19  # GPIO for DHT22 sensor
TRIG_PIN = 5  # GPIO for HC-SR04 TRIG
ECHO_PIN = 18  # GPIO for HC-SR04 ECHO

# Initialize I2C for the OLED display
WIDTH = 128
HEIGHT = 64
i2c = I2C(scl=Pin(20), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c)

# Initialize devices
led = PWM(Pin(LED_PIN), freq=1000)
led.duty(0)  # Start with LED off
dht_sensor = DHT22(Pin(DHT_PIN))
trig = Pin(TRIG_PIN, Pin.OUT)
echo = Pin(ECHO_PIN, Pin.IN)

# Global variables for sensor data
temperature = None
humidity = None
distance = None

# Function to read DHT22 sensor data
def read_dht_sensor():
    global temperature, humidity
    try:
        dht_sensor.measure()
        temperature = dht_sensor.temperature()
        humidity = dht_sensor.humidity()
    except Exception as e:
        print("Error reading DHT22:", e)

# Function to read distance from HC-SR04
def read_ultrasonic():
    global distance
    try:
        trig.value(0)
        time.sleep_us(2)
        trig.value(1)
        time.sleep_us(10)
        trig.value(0)

        while echo.value() == 0:
            pass
        start_time = time.ticks_us()

        while echo.value() == 1:
            pass
        end_time = time.ticks_us()

        duration = time.ticks_diff(end_time, start_time)
        distance = (duration / 2) * 0.0343
    except Exception as e:
        print("Error reading ultrasonic sensor:", e)

# Function to generate and display a Wi-Fi QR Code with URL on OLED
def generate_wifi_qr_code(ssid, password, ip):
    qr_code_data = f"WIFI:T:WPA;S:{ssid};P:{password};; URL:{ip}"

    # Create the QR code object
    qr = QRCode()
    qr.add_data(qr_code_data)
    qr.make()
    qr_matrix = qr.get_matrix()

    # Clear the OLED display
    oled.fill(0)

    # Get scaling factors and offsets for centering
    size = len(qr_matrix)
    scale = min(WIDTH // (size + 2), HEIGHT // (size + 2))
    x_offset = (WIDTH - size * scale) // 2
    y_offset = (HEIGHT - size * scale) // 2

    # Draw QR code onto the OLED
    for y, row in enumerate(qr_matrix):
        for x, cell in enumerate(row):
            if cell:  # Draw only if the cell is part of the QR code
                oled.fill_rect(
                    x * scale + x_offset, y * scale + y_offset, scale, scale, 1
                )

    # Display the QR code
    oled.show()

# Function to control LED based on HTTP request parameters
def control_led(params):
    if "state=on" in params:
        led.duty(512)
        print("LED turned ON")
    elif "state=off" in params:
        led.duty(0)
        print("LED turned OFF")
    elif "brightness=" in params:
        try:
            brightness = int(params.split("brightness=")[-1])
            if 0 <= brightness <= 1023:
                led.duty(brightness)
                print(f"LED brightness set to {brightness}")
        except ValueError:
            print("Invalid brightness value")

# Start Access Point
def start_access_point():
    ap = network.WLAN(network.AP_IF)
    ap.active(True)
    ap.config(essid=SSID, password=PASSWORD, authmode=3)
    ap.config(max_clients=5)

    while not ap.active():
        print("Activating Access Point...")
        time.sleep(1)

    print("Access Point Activated")
    print("Network Name (SSID):", SSID)
    print("IP Address:", ap.ifconfig()[0])

    # Generate the QR code on the OLED display
    generate_wifi_qr_code(SSID, PASSWORD, f"http://{ap.ifconfig()[0]}:80")

    return ap.ifconfig()[0]

# Start a web server
def start_web_server(ip):
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((ip, 80))
    server_socket.listen(5)
    print(f"Web Server Started at http://{ip}:80")

    while True:
        client_socket, client_address = server_socket.accept()
        print("Client connected:", client_address)

        read_dht_sensor()
        read_ultrasonic()

        request = client_socket.recv(1024).decode('utf-8')
        print("Request:", request)

        if "GET /?" in request:
            params = request.split("GET /?")[-1].split(" ")[0]
            control_led(params)

        response = f"""
HTTP/1.1 200 OK

<!DOCTYPE html>
<html>
<head>
    <title>ESP32 Web Server</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body {{
            font-family: Arial, sans-serif;
            background: linear-gradient(to right, #4CAF50, #2E7D32);
            color: white;
            text-align: center;
            padding: 20px;
        }}
        h1 {{
            color: #FFEB3B;
            margin-bottom: 20px;
        }}
        .container {{
            max-width: 600px;
            margin: auto;
            background: rgba(255, 255, 255, 0.1);
            padding: 20px;
            border-radius: 10px;
        }}
        .sensor {{
            font-size: 18px;
        }}
        button, input {{
            padding: 10px;
            margin: 5px;
        }}
    </style>
</head>
<body>
    <div class="container">
        <h1>ESP32 Web Server</h1>
        <div class="sensor">
            <p>Temperature: {temperature}&#8451;</p>
            <p>Humidity: {humidity}%</p>
            <p>Distance: {distance:.2f} cm</p>
        </div>
        <form action="/" method="get">
            <button name="state" value="on">Turn LED On</button>
            <button name="state" value="off">Turn LED Off</button>
        </form>
        <form action="/" method="get">
            <input type="number" name="brightness" placeholder="Set Brightness (0-1023)">
            <button type="submit">Set Brightness</button>
        </form>
    </div>
</body>
</html>
"""
        client_socket.sendall(response.encode('utf-8'))
        client_socket.close()

# Main function
def main():
    ip = start_access_point()
    print(f"Access point IP address: {ip}")
    start_web_server(ip)

# Run the main function
main()
$abcdeabcde151015202530354045505560fghijfghij