ESP-WROOM-02でMicroPythonを使い開発(メール編)

〔ESP32-WROOM-32E〕 〔マイコンのトップに戻る〕
[準備編] [module編] [GPIO編] [通信編] [ファイル編] [OLED編] [WiFi編]   [並行処理編] [色々編]


メールの送信実験を行います、これが出来るとESP-WROOM-02に配線したセンサー等から採取した内容を
メールで送る事が出来るでしょう。

《単純なメール》

@ ESP-WROOM-02ボードをUSBでPCに繋ぎます。
A "PyCharm"を起動させ、こちらのCを操作する必要が有ります。(起動時最初のみ設定)
B "main.py"を新規登録して下記スクリプトを"main.py"に貼り付けましょう。
  (登録済みなら上書き貼り付けでも行いましょう)
C 自分ちの環境に合わせてコード内の"設定情報"を書き換えましょう。
D ESP8266に書き込みます
  左側プロジェクトウインドウから"main.py"の文字を右クリックをして、[実行(U)'Flash main.py']を
  クリックします。

--------------------------------------------------------------------------------
import time
from ubinascii import b2a_base64
import network
import socket
import ssl

# 各々で設定情報を書き換える
ESSID = "BBUser"                          # Wi-Fi 接続先のネットワーク識別名
Password = ""                             # SSIDのパスワード
MailServerName = "smtp.mail.yahoo.co.jp"  # メールサーバー名
HostName = "192.168.4.1"                  # ESP8266のIPアドレス
FromName = "txnww????@yahoo.co.jp"        # メールの送信者
ToName = "txnww????@ybb.ne.jp"            # メールの送り先
UserName = "txnww????"                    # プロバイダーのアカウント(ユーザー名)
UserPass = "xxxxxxx"                      # プロバイダーのパスワード

# メールコマンドの発行を行う
def MsgCMD(sdt):
    _s = '%s\r\n' % sdt
    soc.write(_s)
    print(_s, end='')
    _s = soc.readline()
    print(_s)
    if int(_s.decode()[0:3]) < 400:
        return True
    else:
        return False

# 認証コマンドの発行を行う
def AUTHCMD(sdt):
    _s = '%s\r\n' % sdt
    soc.write(_s)
    print(_s, end='')
    while True:
        _s = soc.readline()
        print(_s)
        if _s[0:3] == b'334' or _s[0:3] == b'235':
            _ans = True
            break
        if _s[0:3] == b'500' or not _s:
            _ans = False
            break
    return _ans

# 実験用に30秒後に実行する(この間にREPLを起動しましょう)
time.sleep(30)

# Wi-Fi 接続を設定する為にクライアントオブジェクトのインターフェースを作成する
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
    sta_if.active(True)
    sta_if.connect(ESSID, Password)  # ステーションインターフェイスを有効にする
    while not sta_if.isconnected():  # WiFiネットワークに接続する
        pass
print('\r\n[network config]\r\n', sta_if.ifconfig())

# 指定されたアドレスファミリ、ソケットタイプ、プロトコル番号を使い、新しいソケットを作成する
addr = socket.getaddrinfo(MailServerName, 465)[0][-1]
soc = socket.socket()
soc.connect(addr)           # メールサーバーに接続
print('listening on', addr)
soc = ssl.wrap_socket(soc)  # SSL通信

while True:
    # 応答を待つ
    bMsg = soc.readline()
    print(bMsg)
    if bMsg.decode()[0:3] == '220':
        # 挨拶
        ans = MsgCMD('EHLO ' + HostName)
        if not ans: break
    else: break
    # SMTP認証
    AUTHCMD('AUTH LOGIN')
    s = b2a_base64(UserName).decode()   # BASE64に変換、bytes型オブジェクトで返る
    AUTHCMD(s[0:len(s)-1])              # データ後ろの改行文字を省く(例:b'UGFzc3dv\n')
    s = b2a_base64(UserPass).decode()
    ans = AUTHCMD(s[0:len(s)-1])
    if not ans: break
    # 送信者
    ans = MsgCMD('MAIL FROM: ' + FromName)
    if not ans: break
    # 送り先
    ans = MsgCMD('RCPT TO: ' + ToName)
    if not ans: break
    # メールデータ
    ans = MsgCMD('DATA')
    if not ans: break
    # データのヘッダ
    soc.write('To: ' + ToName + '\r\n')
    soc.write('From: ' + FromName + '\r\n')
    soc.write('Subject: ' + 'Mail test' + '\r\n\r\n')
    # データの本文
    soc.write('Did you receive the mail?' + '\r\n')
    ans = MsgCMD('.')
    if not ans: break
    # メール終了
    soc.write('QUIT\r\n')
    break

# ソケットを閉じる
soc.close()
# アクセスポイントインターフェイスを無効にする
sta_if.active(False)
--------------------------------------------------------------------------------------------------
E 起動後30秒したらメールが送られます。送れますように(´人д`)
  30秒以内に"PyCharm"のREPLを起動すればトレースが表示されます。

2017年頃は”SMTP-AUTH”承認は無かった気がするがぁ、2021年現在は導入されています。
でぇ、ここでは"AUTH LOGIN"で認証を行っていますがぁ、これはメールサーバーが対応している物で
認証を受ける必要が有ります。
”SMTP-AUTH”承認の話は、この辺りこの辺り(knootoさんページ)を参照しましょう。
又、Yahoo!メールサーバーでは、こんな設定もあるので皆さんのサーバーを見てみましょう。

《ファイルの添付付きメール》

今度は、前回の[Wi-Fi編]で扱った"hello.html"ファイルがESP8266のフラッシュメモリに保存されているので このファイルをメールで送ってみます。

@ ESP-WROOM-02ボードをUSBでPCに繋ぎます。
A "PyCharm"を起動させ、こちらのCを操作する必要が有ります。(起動時最初のみ設定)
B "main.py"を新規登録して下記スクリプトを"main.py"に貼り付けましょう。
  (登録済みなら上書き貼り付けでも行いましょう)
C 自分ちの環境に合わせてコード内の"設定情報"を書き換えましょう。
D ESP8266に書き込みます
  左側プロジェクトウインドウから"main.py"の文字を右クリックをして、[実行(U)'Flash main.py']を
  クリックします。

--------------------------------------------------------------------------------
import time
from ubinascii import b2a_base64
import network
import socket
import ssl

# 各々で設定情報を書き換える
ESSID = "BBUser"                          # Wi-Fi 接続先のネットワーク識別名
Password = ""                             # SSIDのパスワード
MailServerName = "smtp.mail.yahoo.co.jp"  # メールサーバー名
HostName = "192.168.4.1"                  # ESP8266のIPアドレス
FromName = "txnww????@yahoo.co.jp"        # メールの送信者
ToName = "txnww????@ybb.ne.jp"            # メールの送り先
UserName = "txnww????"                    # プロバイダーのアカウント(ユーザー名)
UserPass = "xxxxxxx"                      # プロバイダーのパスワード
# マルチパートヘッダ
MultiHead = "MIME-version: 1.0\r\nContent-type: multipart/mixed; boundary=\"border\"\r\n"

# メールコマンドの発行を行う
def MsgCMD(sdt):
    _s = '%s\r\n' % sdt
    soc.write(_s)
    print(_s, end='')
    _s = soc.readline()
    print(_s)
    if int(_s.decode()[0:3]) < 400:
        return True
    else:
        return False

# 認証コマンドの発行を行う
def AUTHCMD(sdt):
    _s = '%s\r\n' % sdt
    soc.write(_s)
    print(_s, end='')
    while True:
        _s = soc.readline()
        print(_s)
        if _s[0:3] == b'334' or _s[0:3] == b'235':
            _ans = True
            break
        if _s[0:3] == b'500' or not _s:
            _ans = False
            break
    return _ans

# 実験用に30秒後に実行する(この間にREPLを起動しましょう)
time.sleep(30)

# Wi-Fi 接続を設定する為にクライアントオブジェクトのインターフェースを作成する
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
    sta_if.active(True)
    sta_if.connect(ESSID, Password)  # ステーションインターフェイスを有効にする
    while not sta_if.isconnected():  # WiFiネットワークに接続する
        pass
print('\r\n[network config]\r\n', sta_if.ifconfig())

# 指定されたアドレスファミリ、ソケットタイプ、プロトコル番号を使い、新しいソケットを作成する
addr = socket.getaddrinfo(MailServerName, 465)[0][-1]
soc = socket.socket()
soc.connect(addr)           # メールサーバーに接続
print('listening on', addr)
soc = ssl.wrap_socket(soc)  # SSL通信

while True:
    # 応答を待つ
    bMsg = soc.readline()
    print(bMsg)
    if bMsg.decode()[0:3] == '220':
        # 挨拶
        ans = MsgCMD('EHLO ' + HostName)
        if not ans: break
    else: break
    # SMTP認証
    AUTHCMD('AUTH LOGIN')
    s = b2a_base64(UserName).decode()   # BASE64に変換、bytes型オブジェクトで返る
    AUTHCMD(s[0:len(s)-1])              # データ後ろの改行文字を省く(例:b'UGFzc3dv\n')
    s = b2a_base64(UserPass).decode()
    ans = AUTHCMD(s[0:len(s)-1])
    if not ans: break
    # 送信者
    ans = MsgCMD('MAIL FROM: ' + FromName)
    if not ans: break
    # 送り先
    ans = MsgCMD('RCPT TO: ' + ToName)
    if not ans: break
    # メールデータ
    ans = MsgCMD('DATA')
    if not ans: break
    # データのヘッダ
    soc.write('To: ' + ToName + '\r\n')
    soc.write('From: ' + FromName + '\r\n')
    soc.write('Subject: ' + 'Mail test(File attachment)' + '\r\n')
    soc.write(MultiHead + '\r\n')
    # パート1のヘッダ
    soc.write('--border\r\n')
    soc.write('Content-type: text/plain\r\n\r\n')
    # パート1のデータの本文
    soc.write('Did you receive the mail?' + '\r\n')
    soc.write('Have you receive the file?' + '\r\n')
    # パート2のヘッダ
    soc.write('--border\r\n')
    soc.write('Content-type: text/html\r\n'
              'Content-Disposition: attachment; filename=\"hello.html\"\r\n\r\n')
    # パート2のファイルデータ
    with open('hello.html', 'rt') as f:
        for i in f:
            soc.write(i)
    # メールデータ終了
    soc.write('--border--\r\n')
    ans = MsgCMD('.')
    if not ans: break
    # メール終了
    soc.write('QUIT\r\n')
    break

# ソケットを閉じる
soc.close()
# アクセスポイントインターフェイスを無効にする
sta_if.active(False)
--------------------------------------------------------------------------------------------------
E 起動後30秒したらメールが送られます。

ファイルの送付は、マルチパート方式で送ります。(青色文字が追加する部分です)
マルチパートの話は前に実験した"PIC+ENC28J60でTCP/IP(SMTP)"の"実験4"の記事か
ここのページを参考にしましょう。
送付するファイルのメディアタイプは今回は"text/html"としてHTMLファイルを送っていますが、
その他の場合はここの"MIMEタイプ(IANAメディアタイプ)"を参照しましょう。

《その他》

日本語メールを送る場合は、前に実験した"PIC+ENC28J60でTCP/IP(SMTP)"の"実験3"の記事を
参考にしましょう、このページでは割愛します。m(*T▽T*)m

※ SSLを使用時の既知の問題や制限事項が有るそうです、一読しておきましょう。



[WiFi編へ] [ページ上へ] [並行処理編へ]


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2021 Shigehiro Kimura All Rights Reserved.