Raspberry Pi Pico W: сохранение сетевых учетных данных в отдельном файле (MicroPython)

В этом кратком руководстве для Raspberry Pi Pico W вы узнаете, как сохранить сетевые учетные данные в отдельном файле, сохраненном в файловой системе Pico (в дополнение к вашему скрипту main.py).

При создании сетевых проектов может быть полезно сохранять параметры конфигурации, такие как SSID и пароль, в отдельном файле, хранящемся в файловой системе Pico. Затем вы можете легко ссылаться на этот файл в своем основном коде для использования этих учетных данных. Это не только практично, но и предотвращает случайное раскрытие ваших сетевых учетных данных или конфиденциальной информации при обмене кодом с другом или в интернете.

Raspberry Pi Pico W — сохранение сетевых учетных данных в отдельном файле MicroPython

Примечание

Впервые работаете с Raspberry Pi Pico? Начните здесь: Начало работы с Raspberry Pi Pico 2 и Pico 2 W

Необходимые условия

Для выполнения этого руководства вам потребуется:

1) Плата Raspberry Pi Pico W или Raspberry Pi Pico 2W (эти модели поддерживают Wi-Fi).

2) Прошивка MicroPython, установленная на вашу плату Raspberry Pi Pico, и IDE для написания и загрузки кода. Следуйте этому руководству: Программирование Raspberry Pi Pico с помощью MicroPython.

Создание файла конфигурации

1. Откройте Thonny IDE и установите соединение с вашим Raspberry Pi Pico W.

2. Создайте новый файл.

3. Напишите следующее внутри этого файла, но замените на ваши сетевые учетные данные:

wifi_ssid = 'REPLACE_WITH_YOUR_SSID'
wifi_password = 'REPLACE_WITH_YOUR_PASSWORD'

4. Сохраните файл в файловой системе Raspberry Pi Pico. В Thonny IDE перейдите в File > Save as.. > Raspberry Pi Pico и сохраните файл с именем config.py.

Сохранение файла на Raspberry Pi Pico — Thonny IDE Сохранение файла config.py в файловой системе Pico в Thonny IDE

Импорт сетевых учетных данных

После создания файла с вашими сетевыми учетными данными вы можете легко импортировать их в свой основной код следующим образом:

from config import wifi_ssid, wifi_password

Затем вы можете использовать переменные wifi_ssid и wifi_password для инициализации Wi-Fi при вызове функции wlan.connect().

wlan.connect(wifi_ssid, wifi_password)

Веб-сервер с файлом config.py

Чтобы показать вам, как применить это в практическом примере, вот простой скрипт веб-сервера «Hello, World», который использует учетные данные SSID и пароля из внешнего файла для подключения к интернету.

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details: https://RandomNerdTutorials.com/raspberry-pi-pico-w-save-network-credentials/

import network
import socket
import time
import random

# Import SSID and password from the config.py file
from config import wifi_ssid, wifi_password

# HTML template for the webpage
webpage = """
        <!DOCTYPE html>
        <html>
        <head>
            <title>Pico Web Server</title>
            <meta name="viewport" content="width=device-width, initial-scale=1">
        </head>
        <body>
            <h1>Raspberry Pi Pico Web Server</h1>
            <p>Hello, World!</p>
        </body>
        </html>
        """

# Init Wi-Fi Interface
def init_wifi(ssid, password):
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    # Connect to your network
    wlan.connect(ssid, password)
    # Wait for Wi-Fi connection
    connection_timeout = 10
    while connection_timeout > 0:
        if wlan.status() >= 3:
            break
        connection_timeout -= 1
        print('Waiting for Wi-Fi connection...')
        time.sleep(1)
    # Check if connection is successful
    if wlan.status() != 3:
        return False
    else:
        print('Connection successful!')
        network_info = wlan.ifconfig()
        print('IP address:', network_info[0])
        return True

if init_wifi(wifi_ssid, wifi_password):
    # Set up socket and start listening
    addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
    s = socket.socket()
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(addr)
    s.listen()
    print('Listening on', addr)

# Main loop to listen for connections
while True:
    try:
        conn, addr = s.accept()
        print('Got a connection from', addr)

        # Receive and parse the request
        request = conn.recv(1024)
        request_str = request.decode('utf-8')
        print('Request content:')

        # Split headers and body
        headers, body = request_str.split('\r\n\r\n', 1)
        print('Headers:\n', headers)
        print('Body:\n', body)

        # Generate HTML response
        response = webpage

        # Send the HTTP response and close the connection
        conn.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
        conn.send(response)
        conn.close()

    except OSError as e:
        conn.close()
        print('Connection closed')

Посмотреть исходный код

Запустите этот код на вашем Raspberry Pi Pico.

Кнопка запуска в Thonny IDE

Через некоторое время он подключится к вашей сети и отобразит свой IP-адрес.

RPi Pico успешно подключается к сети Wi-Fi и выводит свой IP-адрес

Вы можете получить доступ к веб-серверу в вашем веб-браузере, набрав IP-адрес.

Веб-сервер Raspberry Pi Pico Hello World

Как видите, нет необходимости вставлять учетные данные в ваш основной код, если вы сохранили их во внешнем файле, который находится в файловой системе Pico и на который ссылается основной код.


Сохранение нескольких сетевых учетных данных

Вместо сохранения одной комбинации SSID и пароля, может быть полезно использовать несколько комбинаций. Для этого вы можете создать JSON-файл с несколькими комбинациями SSID и пароля.

Создание JSON-файла

Создайте новый файл в Thonny IDE со следующим содержимым.

[
    {"ssid": "your_ssid_1", "password": "your_password_1"},
    {"ssid": "your_ssid_2", "password": "your_password_2"},
    {"ssid": "your_ssid_3", "password": "your_password_3"}
]

Замените your_ssid1 и your_password_1 на первую комбинацию SSID и пароля, и так далее. Вы можете добавить столько комбинаций, сколько вам нужно, или иметь только одну или две.

Сохраните его на вашем Raspberry Pi Pico с именем: wifi_credentials.json. В Thonny IDE перейдите в File > Save as… > Raspberry Pi Pico. Назовите его wifi_credentials.json.

Сохранение JSON-файла с учетными данными Wi-Fi на RPi Pico

Подключение к сети с использованием JSON-файла

С несколькими изменениями в предыдущем примере мы можем использовать этот JSON-файл для перебора различных комбинаций SSID и пароля. Вот измененный код:

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details: https://RandomNerdTutorials.com/raspberry-pi-pico-w-save-network-credentials/

import network
import socket
import time
import json

# HTML template for the webpage
webpage = """
        <!DOCTYPE html>
        <html>
        <head>
            <title>Pico Web Server</title>
            <meta name="viewport" content="width=device-width, initial-scale=1">
        </head>
        <body>
            <h1>Raspberry Pi Pico Web Server</h1>
            <p>Hello, World!</p>
        </body>
        </html>
        """

def init_wifi_from_file(file_path='wifi_credentials.json'):
    try:
        with open(file_path, 'r') as file:
            credentials = json.load(file)
    except OSError:
        print(f"Error: Unable to read {file_path}. Make sure the file exists and is properly formatted.")
        return False

    for cred in credentials:
        ssid = cred.get('ssid')
        password = cred.get('password')
        if ssid and password:
            if init_wifi(ssid, password):
                return True

    print("Unable to connect to any Wi-Fi network.")
    return False

# Init Wi-Fi Interface
def init_wifi(ssid, password):
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.disconnect()

    print(f"Trying to connect to Wi-Fi network with SSID: {ssid}")

    wlan.connect(ssid, password)

    # Wait for Wi-Fi connection
    connection_timeout = 10
    while connection_timeout > 0:
        if wlan.isconnected():
            print('Connection successful!')
            network_info = wlan.ifconfig()
            print('IP address:', network_info[0])
            return True

        connection_timeout -= 1
        print('Waiting for Wi-Fi connection...')
        time.sleep(1)

    print(f"Failed to connect to Wi-Fi network with SSID: {ssid}")
    return False

# Set up Wi-Fi
if not init_wifi_from_file():
    print("Exiting program.")
else:
    try:
        # Set up socket and start listening
        addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
        s = socket.socket()
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind(addr)
        s.listen()
        print('Listening on', addr)

        # Main loop to listen for connections
        while True:
            try:
                conn, addr = s.accept()
                print('Got a connection from', addr)

                # Receive and parse the request
                request = conn.recv(1024)
                request_str = request.decode('utf-8')
                print('Request content:')

                # Split headers and body
                headers, body = request_str.split('\r\n\r\n', 1)
                print('Headers:\n', headers)
                print('Body:\n', body)

                # Generate HTML response
                response = webpage

                # Send the HTTP response and close the connection
                conn.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
                conn.send(response)
                conn.close()

            except OSError as e:
                conn.close()
                print('Connection closed')

    except KeyboardInterrupt:
        print('Server stopped by user.')

Посмотреть исходный код

Как работает код

Давайте кратко рассмотрим соответствующие части этого примера.

Мы создаем новую функцию, которая будет инициализировать Wi-Fi с учетными данными, сохраненными в JSON-файле.

def init_wifi_from_file(file_path='wifi_credentials.json'):
    try:
        with open(file_path, 'r') as file:
            credentials = json.load(file)
    except OSError:
        print(f"Error: Unable to read {file_path}. Make sure the file exists
                   and is properly formatted.")
        return False
    for cred in credentials:
        ssid = cred.get('ssid')
        password = cred.get('password')
        if ssid and password:
            if init_wifi(ssid, password):
                return True
    print("Unable to connect to any Wi-Fi network.")
    return False

Она открывает файл и сохраняет содержимое JSON в переменную credentials.

with open(file_path, 'r') as file:
    credentials = json.load(file)

Затем мы перебираем все элементы JSON, и для каждой комбинации SSID/пароль пытаемся подключиться к Wi-Fi:

for cred in credentials:
    ssid = cred.get('ssid')
    password = cred.get('password')
    if ssid and password:
        if init_wifi(ssid, password):
            return True

Затем, прежде чем продолжить работу веб-сервера, мы проверяем, удалось ли подключиться к какой-либо из сетей Wi-Fi. Если не удалось, программа завершит работу.

# Set up Wi-Fi
if not init_wifi_from_file():
    print("Exiting program.")

В противном случае она продолжит выполнение остальной части кода для создания веб-сервера.

Тестирование примера

Запустите этот предыдущий пример на вашей плате. Он попытается подключиться к вашей сети, используя каждую комбинацию SSID и пароля, пока не установит соединение.

В моем случае, чтобы протестировать этот пример, я намеренно ввел правильные учетные данные только во второй вариант. Вы можете видеть, что он несколько раз пытается подключиться, используя первую пару SSID/пароль. Попытка не удается, поэтому он попробует второй вариант.

Raspberry Pi Pico пытается подключиться к различным сетям

С этим вторым вариантом он успешно подключится к сети. Этот подход может быть полезен, если вы работаете над своим проектом в разных местах с разными сетями.

Заключение

В этом кратком примере мы показали вам, как загружать учетные данные Wi-Fi из отдельного файла. Это может быть полезно, потому что вам не нужно вводить свои учетные данные в каждый код, который вы хотите протестировать, и это предотвращает случайное раскрытие ваших сетевых учетных данных.

Если вы хотите, чтобы ваш Raspberry Pi Pico пробовал более одной комбинации SSID/пароль, вы можете создать JSON-файл с несколькими комбинациями.

При создании проектов веб-серверов или любых сетевых проектов выберите метод, который наиболее подходит для вашего приложения.

Надеемся, что это краткое руководство оказалось для вас полезным. У нас есть другие руководства, связанные с Wi-Fi на Raspberry Pi Pico, которые могут вам понравиться: