import socket
from machine import ADC, Pin, WIZNET_PIO_SPI
import time
import network


adc = ADC(Pin(26))
HallSensor = Pin(14, Pin.IN, Pin.PULL_DOWN)

# W5x00 chip initialization
def w5x00_init(ip_info=None):
    ip_info = ('192.168.11.20','255.255.255.0','192.168.11.1','8.8.8.8')
    spi = WIZNET_PIO_SPI(baudrate=31_250_000, mosi=Pin(23), miso=Pin(22), sck=Pin(21))  # W55RP20 PIO_SPI
    nic = network.WIZNET5K(spi, Pin(20), Pin(25))  # spi, cs, reset pin
    nic.active(True)
    delay = 1

    if ip_info:
        # Static IP
        nic.ifconfig(ip_info)
    else:
        # DHCP
        for i in range(5):  # DHCP sometimes fails, so we try multiple attempts
            try:
                nic.ifconfig("dhcp")
            except Exception as e:
                print(f"Attempt {i + 1} failed, retrying in {delay} second(s)...({e})")
            time.sleep(delay)

    while not nic.isconnected():
        print("Waiting for the network to connect...")
        time.sleep(1)
        # print(nic.regs())

    print("IP Address:", nic.ifconfig())
    return nic


def main(micropython_optimize=False):
    nic = w5x00_init()
    s = socket.socket()
    Message = "  "
    Date_Time = " "
    # Binding to all interfaces - server will be accessible to other hosts!
    ai = socket.getaddrinfo("0.0.0.0", 8080)
    print("Bind address info:", ai)
    addr = ai[0][-1]

    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(addr)
    s.listen(5)
    print("Listening, connect your browser to http://<this_host>:8080/")

    counter = 0
    while True:
        res = s.accept()
        client_sock = res[0]
        client_addr = res[1]
        print("Client address:", client_addr)
        print("Client socket:", client_sock)

        if not micropython_optimize:
            # To read line-oriented protocol (like HTTP) from a socket (and
            # avoid short read problem), it must be wrapped in a stream (aka
            # file-like) object. That's how you do it in CPython:
            client_stream = client_sock.makefile("rwb")
        else:
            # .. but MicroPython socket objects support stream interface
            # directly, so calling .makefile() method is not required. If
            # you develop application which will run only on MicroPython,
            # especially on a resource-constrained embedded device, you
            # may take this shortcut to save resources.
            client_stream = client_sock

        print("Request:")
        req = client_stream.readline()
        print(req)
        while True:
            h = client_stream.readline()
           
            if h == b"" or h == b"\r\n":
                break
            print(h)
            if not(HallSensor.value()):
                Message = "<<   Someone opened your rack!!  >>"
                # send email or Telegram or Whatsapp message
                seconds = time.time()
                local_time = time.localtime(seconds)
                Local_date= str(local_time[0]) + "/" + str(local_time[1]) +  "/" + str(local_time[2]) 
                Local_time= str(local_time[3]) +  ":" + str(local_time[4])
                Date_Time = Local_date + "  " + Local_time
            CONTENT = b"""\
    HTTP/1.0 200 OK

    <body bgcolor="yellow">
    <div id="clock"></div>
    <h1 align="center">Rack security monitoring</h1>
    <script>
        function updateClock() {
            const now = new Date();
            const hours = String(now.getHours()).padStart(2, '0');
            const minutes = String(now.getMinutes()).padStart(2, '0');
            const seconds = String(now.getSeconds()).padStart(2, '0');
            const date = now.toLocaleDateString();

            //document.getElementById('clock').textContent = `${date} ${hours}:${minutes}:${seconds}`;
        }
        setInterval(updateClock, 1000);
        updateClock(); // inizializza subito l'orologio
        setInterval(function() {window.location.reload();}, 2000); // 2000 millisecondi = 2 secondi

    </script>
    <h2 align="center">Real Time Temperature: """ + ' ' + str(0.00366*adc.read_u16()-19) + \
    " &degC" + "</h2>" + "<h1 align="'center'">" + Message + "</h1>" \
    + "<h1 align="'center'">" + Date_Time + "</h1>"

        client_stream.write(CONTENT)
        client_stream.close()
        if not micropython_optimize:
            client_sock.close()
        counter += 1
        print()

main()
