.. note::

    Ciao, benvenuto nella Community di appassionati di SunFounder Raspberry Pi, Arduino e ESP32 su Facebook! Approfondisci le tue conoscenze su Raspberry Pi, Arduino e ESP32 insieme ad altri appassionati.

    **Perché unirti?**

    - **Supporto Esperto**: Risolvi problemi post-vendita e sfide tecniche con l'aiuto della nostra community e del nostro team.
    - **Impara e Condividi**: Scambia consigli e tutorial per migliorare le tue competenze.
    - **Anteprime Esclusive**: Ottieni accesso anticipato agli annunci di nuovi prodotti e alle anteprime.
    - **Sconti Speciali**: Approfitta di sconti esclusivi sui nostri prodotti più recenti.
    - **Promozioni Festive e Giveaway**: Partecipa a promozioni festive e concorsi a premi.

    👉 Sei pronto a esplorare e creare con noi? Clicca su [|link_sf_facebook|] e unisciti oggi stesso!

7. Configurazione di un Web Server
====================================

In questo articolo, imparerai come trasformare Pico W in un web server che ti 
permette di operare il circuito e ottenere letture dai sensori attraverso un browser.

|setup_web|

**1. Componenti necessari**

In questo progetto, abbiamo bisogno dei seguenti componenti.

È sicuramente conveniente acquistare un kit completo, ecco il link:

.. list-table::
    :widths: 20 20 20
    :header-rows: 1

    *   - Nome	
        - ELEMENTI IN QUESTO KIT
        - LINK
    *   - Kit Kepler	
        - 450+
        - |link_kepler_kit|

Puoi anche acquistarli separatamente dai link qui sotto.

.. list-table::
    :widths: 5 20 5 20
    :header-rows: 1

    *   - SN
        - COMPONENTE	
        - QUANTITÀ
        - LINK

    *   - 1
        - :ref:`cpn_pico_w`
        - 1
        - |link_picow_buy|
    *   - 2
        - Cavo Micro USB
        - 1
        - 
    *   - 3
        - :ref:`cpn_breadboard`
        - 1
        - |link_breadboard_buy|
    *   - 4
        - :ref:`cpn_wire`
        - Diverse
        - |link_wires_buy|
    *   - 5
        - :ref:`cpn_resistor`
        - 4(1-330Ω, 2-220Ω, 1-10KΩ)
        - |link_resistor_buy|
    *   - 6
        - :ref:`cpn_rgb`
        - 1
        - |link_rgb_led_buy|
    *   - 7
        - :ref:`cpn_thermistor`
        - 1
        - |link_thermistor_buy|
    *   - 8
        - :ref:`cpn_lipo_charger`
        - 1
        -  
    *   - 9
        - Batteria 18650
        - 1
        -  
    *   - 10
        - Supporto Batteria
        - 1
        -  

**2. Costruisci il Circuito**

    .. warning:: 
        
        Assicurati che il modulo caricabatterie Li-po sia collegato come mostrato nello schema. Altrimenti, un cortocircuito potrebbe danneggiare la batteria e il circuito.

.. image:: img/wiring/7.web_page_bb.png
    :width: 800


**3. Esegui il Codice**

#. Apri il file ``7_web_page.py`` nel percorso ``kepler-kit-main/iot``.
#. Clicca sul pulsante **Esegui script corrente** o premi F5 per eseguirlo. Dopo una connessione riuscita, vedrai l'IP del Pico W.

    .. image:: img/7_web_server.png

    .. note::

        Prima di eseguire il codice, assicurati di avere gli script ``do_connect.py`` e ``secrets.py`` nel tuo Pico W, in caso contrario fai riferimento a :ref:`iot_access` per crearli.

#. Inserisci l'indirizzo IP del Pico W nel tuo browser per accedere alla pagina web creata per questo progetto. Clicca su qualsiasi pulsante per cambiare il colore dei LED RGB e aggiornare la temperatura e l'umidità.

    .. image:: img/web-1.png
        :width: 500

#. Se desideri che questo script si avvii automaticamente, puoi salvarlo nel Raspberry Pi Pico W come ``main.py``.

**Come funziona?**

La pagina web che stai visitando è effettivamente ospitata su un server, e il socket sul server invierà la pagina web quando la visitiamo.
Un socket è il modo in cui un server può ascoltare un client che vuole connettersi ad esso.

In questo progetto, Pico W è il tuo server, e il tuo computer sta accedendo alla pagina web ospitata su Pico W tramite un browser.

Per prima cosa creiamo un socket, che richiede un indirizzo IP e |link_port|. La connessione di rete e il modo per ottenere l'IP sono descritti in :ref:`iot_access`. Per la porta, usiamo la 80.
Dopo aver configurato il socket, lo restituiamo e lo utilizziamo per il passo successivo.

`socket library - Python Docs <https://docs.python.org/3/library/socket.html>`_ 

.. code-block:: python

    import socket

    def open_socket(ip):
        # Open a socket
        address = (ip, 80)
        connection = socket.socket()
        connection.bind(address)
        connection.listen(1)
        print(connection)
        return(connection)

Successivamente, configura il tuo servizio web dove il socket che hai configurato in precedenza sarà utilizzato.
Il seguente codice permetterà al tuo Pico W di ricevere richieste di accesso dal tuo browser.

.. code-block:: python

    def serve(connection):
        while True:
            client = connection.accept()[0]
            request = client.recv(1024)
            client.close()

Successivamente, hai bisogno di una pagina html da inviare al visitatore. Questo esempio memorizza una semplice pagina html sotto forma di caratteri nella variabile ``html``.

.. note:: 
    Se vuoi essere in grado di scrivere il tuo html, puoi ottenere aiuto su |link_html|.

.. code-block:: python

    def webpage(value):
        html = f"""
                <!DOCTYPE html>
                <html>
                <body>
                <form action="./red">
                <input type="submit" value="red " />
                </form>
                <form action="./green">
                <input type="submit" value="green" />
                </form>
                <form action="./blue">
                <input type="submit" value="blue" />
                </form>
                <form action="./off">
                <input type="submit" value="off" />
                </form>
                <p>Temperature is {value} degrees Celsius</p>
                </body>
                </html>
                """
        return html

Invia la pagina html al visitatore.

.. code-block:: python
    :emphasize-lines: 5,6

    def serve(connection):
        while True:
            client = connection.accept()[0]
            request = client.recv(1024)
            html=webpage(0)
            client.send(html)
            client.close()

La pagina può essere accessibile tramite il tuo browser se combini le parti sopra. Se vuoi vedere l'effetto, esegui il codice qui sotto con Thonny.

.. code-block:: python

    import machine
    import socket

    from secrets import *
    from do_connect import *

    def webpage(value):
        html = f"""
                <!DOCTYPE html>
                <html>
                <body>
                <form action="./red">
                <input type="submit" value="red " />
                </form>
                <form action="./green">
                <input type="submit" value="green" />
                </form>
                <form action="./blue">
                <input type="submit" value="blue" />
                </form>
                <form action="./off">
                <input type="submit" value="off" />
                </form>
                <p>Temperature is {value} degrees Celsius</p>
                </body>
                </html>
                """
        return html

    def open_socket(ip):
        # Open a socket
        address = (ip, 80)
        connection = socket.socket()
        connection.bind(address)
        connection.listen(1)
        print(connection)
        return(connection)

    def serve(connection):
        while True:
            client = connection.accept()[0]
            request = client.recv(1024)
            html=webpage(0)
            client.send(html)
            client.close()

    try:
        ip=do_connect()
        if ip is not None:
            connection=open_socket(ip)
            serve(connection)
    except KeyboardInterrupt:
        machine.reset()


Quando esegui il codice sopra, vedrai che visualizza solo una pagina web, non ti permette di controllare i LED RGB, né mostra le letture dei sensori.
Il servizio web ha bisogno di ulteriori perfezionamenti.

La prima cosa che dobbiamo sapere è quali informazioni il server riceve quando il browser accede alla pagina web. Pertanto, modifica leggermente ``serve()`` per stampare ``request``.

.. code-block:: python
    :emphasize-lines: 5,6

    def serve(connection):
        while True:
            client = connection.accept()[0]
            request = client.recv(1024)
            request = str(request)
            print(request)  
            html=webpage(0)
            client.send(html)
            client.close()

Riesegui lo script e la Shell stamperà il seguente messaggio quando premiamo un tasto sulla pagina web.

.. code-block:: 

    b'GET /red? HTTP/1.1\r\nHost: 192.168.18.162\r\nConnection: keep-alive.......q=0.5\r\n\r\n'
    b'GET /favicon.ico HTTP/1.1\r\nHost: 192.168.18.162\r\nConnection: keep-alive.......q=0.5\r\n\r\n'
    b'GET /blue? HTTP/1.1\r\nHost: 192.168.18.162\r\nConnection: keep-alive.......q=0.5\r\n\r\n'
    b'GET /favicon.ico HTTP/1.1\r\nHost: 192.168.18.162\r\nConnection: keep-alive.......q=0.5\r\n\r\n'

Sono troppo lunghi da leggere!!! 

Ma tutto ciò di cui abbiamo davvero bisogno è il piccolo pezzo di informazione davanti a ``/red?``, ``/blue?``.
Ci dice quale pulsante è stato premuto. Quindi abbiamo perfezionato ``serve()`` un po' per estrarre le informazioni sul tasto premuto.

.. code-block:: python
    :emphasize-lines: 6,7,8,9

    def serve(connection):
        while True:
            client = connection.accept()[0]
            request = client.recv(1024)
            request = str(request)
            try:
                request = request.split()[1]
            except IndexError:
                pass
            print(request)  
            html=webpage(0)
            client.send(html)
            client.close()

Riesegui il programma e la Shell stamperà il seguente messaggio quando premiamo un tasto sulla pagina web.

.. code-block:: 

    /red?
    /favicon.ico
    /blue?
    /favicon.ico
    /off?
    /favicon.ico

Poi, dobbiamo solo cambiare il colore del LED RGB in base al valore di ``request``.

.. code-block:: python

    def serve(connection):
        while True:
            client = connection.accept()[0]
            request = client.recv(1024)
            request = str(request)
            try:
                request = request.split()[1]
            except IndexError:
                pass
            
            print(request)
            
            if request == '/off?':
                red.low()
                green.low()
                blue.low()
            elif request == '/red?':
                red.high()
                green.low()
                blue.low()
            elif request == '/green?':
                red.low()
                green.high()
                blue.low()
            elif request == '/blue?':
                red.low()
                green.low()
                blue.high()
 
            html=webpage(0)
            client.send(html)
            client.close()

L'ultima cosa è visualizzare il valore del termistore sulla pagina web (vedi :ref:`py_temp` per i dettagli sull'uso del termistore).
Questa parte è in realtà realizzata modificando il testo sull'html.
Impostiamo i parametri nella funzione ``webpage(value)`` e cambiamo semplicemente i parametri in ingresso per modificare il numero visualizzato sulla pagina web.

.. code-block:: python
    :emphasize-lines: 30,31

    def serve(connection):
        while True:
            client = connection.accept()[0]
            request = client.recv(1024)
            request = str(request)
            try:
                request = request.split()[1]
            except IndexError:
                pass
            
            #print(request)
            
            if request == '/off?':
                red.low()
                green.low()
                blue.low()
            elif request == '/red?':
                red.high()
                green.low()
                blue.low()
            elif request == '/green?':
                red.low()
                green.high()
                blue.low()
            elif request == '/blue?':
                red.low()
                green.low()
                blue.high()

            value='%.2f'%temperature()    
            html=webpage(value)
            client.send(html)
            client.close()





.. https://projects.raspberrypi.org/en/projects/get-started-pico-w/3