Raspberry Pi Pico W: отправка электронной почты через SMTP-сервер (MicroPython)
Узнайте, как отправлять электронные письма с Raspberry Pi Pico, используя SMTP-сервер. Эта функция может быть полезна в ваших проектах автоматизации и IoT для отправки уведомлений, сообщений с показаниями датчиков и многого другого. Мы будем программировать Raspberry Pi Pico с использованием прошивки MicroPython.
Впервые работаете с Raspberry Pi Pico? Начните знакомство с Raspberry Pi Pico здесь.
Предварительные требования – прошивка MicroPython
Для выполнения этого руководства вам необходимо установить прошивку MicroPython на плату Raspberry Pi Pico. Вам также понадобится IDE для написания и загрузки кода на плату.
Рекомендуемая IDE для MicroPython на Raspberry Pi Pico – это Thonny IDE. Следуйте следующему руководству, чтобы узнать, как установить Thonny IDE, прошить MicroPython и загрузить код на плату.
Знакомство с SMTP-серверами
SMTP означает Simple Mail Transfer Protocol (простой протокол передачи почты) и является интернет-стандартом для передачи электронной почты. Для отправки электронных писем с помощью Raspberry Pi Pico вам необходимо подключить его к SMTP-серверу.
Модуль uMail
Для удобной отправки электронных писем с MicroPython мы будем использовать модуль uMail. Этот модуль не входит в стандартную коллекцию библиотек MicroPython, поэтому нам нужно будет загрузить его отдельно на нашу плату – инструкции по этому поводу мы предоставим позже в руководстве.
Настройки SMTP-сервера
Для отправки электронных писем с Raspberry Pi Pico вам нужна электронная почта отправителя, и вам необходимо знать настройки SMTP-сервера вашей почты. Ниже вы найдёте настройки для наиболее популярных почтовых провайдеров.
Настройки SMTP-сервера Gmail
Если вы используете аккаунт Gmail, вот параметры SMTP-сервера:
SMTP-сервер: smtp.gmail.com
Имя пользователя SMTP: Полный адрес Gmail
Пароль SMTP: Ваш пароль Gmail
Порт SMTP (TLS): 587
Порт SMTP (SSL): 465
Требуется SMTP TLS/SSL: да
Настройки SMTP-сервера Outlook
Для аккаунтов Outlook настройки SMTP-сервера следующие:
SMTP-сервер: smtp.office365.com
Имя пользователя SMTP: Полный адрес электронной почты Outlook
Пароль SMTP: Ваш пароль Outlook
Порт SMTP: 587
Требуется SMTP TLS/SSL: Да
Настройки SMTP-сервера Live или Hotmail
Для аккаунтов Live или Hotmail настройки SMTP-сервера следующие:
SMTP-сервер: smtp.live.com
Имя пользователя SMTP: Полный адрес электронной почты Live/Hotmail
Пароль SMTP: Ваш пароль Windows Live Hotmail
Порт SMTP: 587
Требуется SMTP TLS/SSL: Да
Если вы используете другого почтового провайдера, вам нужно найти его настройки SMTP-сервера – вы легко найдёте их с помощью быстрого поиска в Google.
Электронная почта отправителя (новый аккаунт)
Мы рекомендуем создать новый аккаунт электронной почты для отправки писем на ваш основной личный адрес. Не используйте основной личный адрес электронной почты для отправки писем через Raspberry Pi Pico. Если что-то пойдёт не так в вашем коде или если по ошибке вы сделаете слишком много запросов, ваш аккаунт может быть заблокирован или временно отключён.
Мы будем использовать аккаунт Gmail.com для отправки писем, но вы можете использовать любого другого почтового провайдера. Адрес получателя может быть вашей личной почтой без каких-либо проблем.
Создание аккаунта отправителя
Создайте новый аккаунт электронной почты для отправки писем с Raspberry Pi Pico. Если вы хотите использовать аккаунт Gmail, перейдите по этой ссылке, чтобы создать новый.
Создание пароля приложения
Вам нужно создать пароль приложения, чтобы новые устройства могли отправлять электронные письма с использованием вашего аккаунта Gmail. Пароль приложения – это 16-значный код, который даёт менее защищённому приложению или устройству разрешение на доступ к вашему аккаунту Google. Узнайте больше о входе с паролями приложений здесь.
Пароль приложения можно использовать только с аккаунтами, в которых включена двухэтапная аутентификация.
Откройте свой аккаунт Google.
На панели навигации выберите Безопасность.
В разделе «Вход в Google» выберите Двухэтапная аутентификация > Начать.
Следуйте инструкциям на экране.
После включения двухэтапной аутентификации вы можете создать пароль приложения.
Откройте свой аккаунт Google.
В строке поиска найдите Пароль приложения (App Password).
Нажмите на меню Пароли приложений.
Теперь вы можете создать новый пароль приложения для использования с Raspberry Pi Pico. Дайте ему имя. Например: Pi Pico.
Нажмите Создать. Ваш пароль приложения будет отображён. Скопируйте его в безопасное место, потому что он вам понадобится позже (даже если написано, что вам это не нужно).
Теперь у вас должен быть пароль приложения, который вы будете использовать в MicroPython-скрипте Raspberry Pi Pico для отправки писем.
Если вы используете другого почтового провайдера, узнайте, как создать пароль приложения. Вы сможете найти инструкции с помощью быстрого поиска в Google «ваш_почтовый_провайдер + создать пароль приложения».
Загрузка модуля uMail
Для отправки писем мы будем использовать модуль uMail. Вы можете ознакомиться с его страницей на Github и несколькими примерами. Эта библиотека не входит в стандартную библиотеку MicroPython по умолчанию. Поэтому вам нужно загрузить следующий файл на Raspberry Pi Pico (сохраните его под именем umail.py), прежде чем использовать библиотеку.
# uMail (MicroMail) for MicroPython Copyright (c) 2018 Shawwwn <shawwwn1@gmai.com> https://github.com/shawwwn/uMail/blob/master/umail.py License: MIT
import usocket
DEFAULT_TIMEOUT = 10 # sec
LOCAL_DOMAIN = '127.0.0.1'
CMD_EHLO = 'EHLO'
CMD_STARTTLS = 'STARTTLS'
CMD_AUTH = 'AUTH'
CMD_MAIL = 'MAIL'
AUTH_PLAIN = 'PLAIN'
AUTH_LOGIN = 'LOGIN'
class SMTP:
def cmd(self, cmd_str):
sock = self._sock;
sock.write('%s\r\n' % cmd_str)
resp = []
next = True
while next:
code = sock.read(3)
next = sock.read(1) == b'-'
resp.append(sock.readline().strip().decode())
return int(code), resp
def __init__(self, host, port, ssl=False, username=None, password=None):
import ssl
self.username = username
addr = usocket.getaddrinfo(host, port)[0][-1]
sock = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM)
sock.settimeout(DEFAULT_TIMEOUT)
sock.connect(addr)
if ssl:
sock = ssl.wrap_socket(sock)
code = int(sock.read(3))
sock.readline()
assert code==220, 'cant connect to server %d, %s' % (code, resp)
self._sock = sock
code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
assert code==250, '%d' % code
if not ssl and CMD_STARTTLS in resp:
code, resp = self.cmd(CMD_STARTTLS)
assert code==220, 'start tls failed %d, %s' % (code, resp)
self._sock = ssl.wrap_socket(sock)
if username and password:
self.login(username, password)
def login(self, username, password):
self.username = username
code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
assert code==250, '%d, %s' % (code, resp)
auths = None
for feature in resp:
if feature[:4].upper() == CMD_AUTH:
auths = feature[4:].strip('=').upper().split()
assert auths!=None, "no auth method"
from ubinascii import b2a_base64 as b64
if AUTH_PLAIN in auths:
cren = b64("\0%s\0%s" % (username, password))[:-1].decode()
code, resp = self.cmd('%s %s %s' % (CMD_AUTH, AUTH_PLAIN, cren))
elif AUTH_LOGIN in auths:
code, resp = self.cmd("%s %s %s" % (CMD_AUTH, AUTH_LOGIN, b64(username)[:-1].decode()))
assert code==334, 'wrong username %d, %s' % (code, resp)
code, resp = self.cmd(b64(password)[:-1].decode())
else:
raise Exception("auth(%s) not supported " % ', '.join(auths))
assert code==235 or code==503, 'auth error %d, %s' % (code, resp)
return code, resp
def to(self, addrs, mail_from=None):
mail_from = self.username if mail_from==None else mail_from
code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
assert code==250, '%d' % code
code, resp = self.cmd('MAIL FROM: <%s>' % mail_from)
assert code==250, 'sender refused %d, %s' % (code, resp)
if isinstance(addrs, str):
addrs = [addrs]
count = 0
for addr in addrs:
code, resp = self.cmd('RCPT TO: <%s>' % addr)
if code!=250 and code!=251:
print('%s refused, %s' % (addr, resp))
count += 1
assert count!=len(addrs), 'recipient refused, %d, %s' % (code, resp)
code, resp = self.cmd('DATA')
assert code==354, 'data refused, %d, %s' % (code, resp)
return code, resp
def write(self, content):
self._sock.write(content)
def send(self, content=''):
if content:
self.write(content)
self._sock.write('\r\n.\r\n') # the five letter sequence marked for ending
line = self._sock.readline()
return (int(line[:3]), line[4:].strip().decode())
def quit(self):
self.cmd("QUIT")
self._sock.close()
Создайте новый файл в Thonny IDE и вставьте предыдущий код;
Перейдите в File > Save as… и выберите Raspberry Pi Pico;
Сохраните файл с именем umail.py (не меняйте имя).
На этом этапе библиотека должна быть успешно загружена на вашу плату. Теперь вы можете использовать функции библиотеки в своём коде, импортировав библиотеку: import umail.
Отправка писем с Raspberry Pi Pico (MicroPython) – код
Следующий MicroPython-скрипт отправляет простое электронное письмо при первой загрузке/перезагрузке платы Raspberry Pi Pico.
# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-w-send-email-micropython/
# Micropython lib to send emails: https://github.com/shawwwn/uMail
import umail
import network
import time
# Your network credentials
ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'
# Email details
sender_email = 'REPLACE_WITH_THE_SENDER_EMAIL'
sender_name = 'Raspberry Pi Pico'
sender_app_password = 'REPLACE_WITH_THE_SENDER_EMAIL_APP_PASSWORD'
recipient_email ='REPLACE_WITH_THE_RECIPIENT_EMAIL'
email_subject ='Hello from RPi Pico W'
# 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:
print(wlan.status())
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:
print('Failed to connect to Wi-Fi')
return False
else:
print('Connection successful!')
network_info = wlan.ifconfig()
print('IP address:', network_info[0])
return True
# Connect to your network
init_wifi(ssid, password)
# Send the email
smtp = umail.SMTP('smtp.gmail.com', 465, ssl=True) # Gmail's SSL port
try:
smtp.login(sender_email, sender_app_password)
smtp.to(recipient_email)
smtp.write("From:" + sender_name + "<"+ sender_email+">\n")
smtp.write("Subject:" + email_subject + "\n")
smtp.write("Hello from the Raspberry Pi Pico. Testing.")
smtp.send()
print("Email Sent Successfully")
except Exception as e:
print("Failed to send email:", e)
finally:
smtp.quit()
Вам нужно вставить свои данные в код перед загрузкой на плату: SSID и пароль, электронную почту отправителя, имя отправителя и соответствующий пароль приложения (это именно пароль приложения, а не пароль электронной почты), электронную почту получателя и тему письма.
После ввода всех данных вы можете запустить код для тестирования. Если вы хотите, чтобы код работал без подключения к компьютеру, вам нужно сохранить его на Raspberry Pi Pico под именем main.py.
Как работает код
Сначала подключите необходимые библиотеки. Библиотеку umail, которую мы загрузили ранее на Pico, чтобы мы могли отправлять электронные письма, и библиотеку network, чтобы настроить Pico как Wi-Fi-станцию для подключения к интернету (локальной сети).
import umail
import network
Вставьте учётные данные вашей сети, SSID и пароль, в следующие переменные, чтобы ваша плата могла подключиться к интернету:
ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'
Вставьте данные электронной почты: адрес отправителя, имя отправителя и соответствующий пароль приложения. Вам нужно создать пароль приложения – обычный пароль электронной почты не будет работать, смотрите раздел Создание пароля приложения.
# Email details
sender_email = 'REPLACE_WITH_THE_SENDER_EMAIL'
sender_name = 'Raspberry Pi Pico'
sender_app_password = 'REPLACE_WITH_THE_SENDER_EMAIL_APP_PASSWORD'
Вставьте электронную почту получателя в переменную recipient_email:
recipient_email ='REPLACE_WITH_THE_RECIPIENT_EMAIL'
Тема письма установлена на Hello from RPi Pico W, но вы можете изменить её в переменной email_subject.
email_subject ='Hello from RPi Pico W'
Мы создали функцию init_wifi(), которая принимает в качестве аргументов SSID и пароль сети, к которой вы хотите подключиться. Вы должны вызвать эту функцию позже, чтобы подключить плату Pico к интернету.
# 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:
print(wlan.status())
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:
print('Failed to connect to Wi-Fi')
return False
else:
print('Connection successful!')
network_info = wlan.ifconfig()
print('IP address:', network_info[0])
return True
Перед отправкой электронного письма нам нужно подключить Raspberry Pi Pico к интернету, поэтому вызовите функцию init_wifi() (передайте в качестве аргументов ssid и password).
# Connect to your network
init_wifi(ssid, password)
Теперь мы наконец можем начать подготовку и отправку электронного письма.
Начните с создания SMTP-клиента, используя настройки SMTP вашего почтового провайдера, с именем smtp. Здесь мы используем аккаунт Gmail. Измените настройки, если вы используете другого почтового провайдера – укажите сервер, порт и требуется ли SSL или нет.
smtp = umail.SMTP('smtp.gmail.com', 465, ssl=True) # Gmail's SSL port
Далее у нас есть операторы try и except для отправки письма или вывода сообщения об ошибке в случае неудачи.
Затем войдите в свой аккаунт с помощью метода login() на клиенте smtp – передайте в качестве аргументов электронную почту и соответствующий пароль приложения.
smtp.login(sender_email, sender_app_password)
Установите получателя с помощью метода to() и передайте электронную почту получателя в качестве аргумента:
smtp.to(recipient_email)
Затем используйте метод write() для написания письма. Вы можете использовать этот метод следующим образом для установки имени отправителя.
smtp.write("From:" + sender_name + "<"+ sender_email+">\n")
Вы можете использовать следующую строку для установки темы письма.
smtp.write("Subject:" + email_subject + "\n")
Наконец, вы можете написать содержимое вашего письма. Это просто тестовое письмо. Мы устанавливаем сообщение «Hello from the Raspberry Pi Pico. Testing.». Метод write() отправляет письмо на SMTP-сервер.
smtp.write("Hello from the Raspberry Pi Pico. Testing.")
Если вам нужно отправить длинную строку в качестве тела письма, разбейте сообщение на более мелкие части и отправьте каждую часть с помощью метода write() – смотрите документацию библиотеки uMail.
Наконец, используйте метод send() для того, чтобы SMTP-сервер отправил письмо получателю.
smtp.send()
Если отправка письма не удалась, будет выведено сообщение об ошибке:
except Exception as e:
print("Failed to send email:", e)
В конце закройте соединение с сервером с помощью метода quit().
finally:
smtp.quit()
Демонстрация
После загрузки модуля umail.py вы можете запустить наш пример кода для тестирования отправки электронного письма.
Pico должен подключиться к интернету и отправить электронное письмо.
Через некоторое время вы должны получить новое письмо на электронную почту получателя.
Откройте письмо, чтобы проверить его содержимое.
Заключение
В этом руководстве вы узнали, как отправлять электронные письма с Raspberry Pi Pico W с помощью MicroPython. Отправка электронного письма через SMTP-сервер очень проста благодаря модулю uMail для MicroPython.
Мы показали вам простой пример отправки электронных писем. Теперь вы можете использовать это в своих проектах для отправки уведомлений, показаний датчиков и других приложений.
Надеемся, что это руководство было для вас полезным.