はじめに:Pico WからLINEへ通知を送るIoTシステムの総仕上げ
自作スマートリモコン 第3回
はじめに:Pico WからLINEへ通知を送るコードを完成させる
こんにちは、ニンジンです🥕
この記事では、Raspberry Pi Pico Wの温度データを、Wi-Fi経由でスマホのLINEに通知するMicroPythonコードを完成させます。urequestsでLINE Messaging APIを叩くプッシュ送信の書き方、初心者がほぼ必ずハマる「日本語メッセージを送るとエラー400になる」問題の対処、そしてPCから切り離してコンセントで自動稼働させるmain.pyの作り方まで解説します。
前提として、第1回(配線・温度取得)と第2回(LINE Messaging APIの設定)が終わっている必要があります。第2回で取得した「ユーザーID」と「チャネルアクセストークン(長期)」を手元に用意してください。
この記事で分かること
- MicroPythonでPico Wを自宅Wi-Fiに接続するコード(
network.WLAN) urequestsでLINE Messaging APIのプッシュ送信を行うコード- 日本語メッセージがエラー400になる原因と、
.encode('utf-8')での対策 - Status Code 400 / 401 / 200なのに届かない、それぞれのチェックポイント
- Pico Wに
main.pyを保存してPC不要で自動稼働させる方法
Pico WのWi-Fi接続テスト:MicroPythonでネットワークにつなぐ
まずはPico Wの内蔵Wi-Fiで、自宅のルーターに接続できるかをテストします。Thonnyで新しいファイルを開き、下のコードを貼り付けます。WIFI_SSIDとWIFI_PASSWORDは自分の環境に書き換えてください。
# Wifi_Connection_test.py
import network
import time
# Wi-Fi情報をご自身の環境に書き換えてください
WIFI_SSID = "あなたのWi-FiのSSID"
WIFI_PASSWORD = "あなたのWi-Fiのパスワード"
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
print(f"Wi-Fi({WIFI_SSID})に接続中...")
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
# 接続を少し待つ(最大10秒)
timeout = 10
while timeout > 0:
if wlan.isconnected():
break
timeout -= 1
print(".")
time.sleep(1)
if wlan.isconnected():
print("Wi-Fi接続に成功しました!")
# Pico Wに割り当てられたIPアドレスを表示
print("IP設定:", wlan.ifconfig())
else:
print("Wi-Fi接続に失敗しました。SSIDやパスワードを確認してください。")テスト結果
LINE送信テストとStatus Code別のチェックポイント
Wi-Fiがつながったら、第2回で設定したLINE Messaging APIへ送信テストをします。文字化けの問題を切り分けるため、まずは半角英数字だけのメッセージで通信の成功を確かめます。
下のコードを新しいファイルに貼り付け、WIFI_SSID / WIFI_PASSWORD / LINE_TOKEN / USER_ID の4つを自分の値に書き換えて実行します。
# get_line_message.py
import network
import time
import urequests
import json
# --- ここをご自身の環境のものに書き換えて下さい ---
WIFI_SSID = "あなたのWi-FiのSSID"
WIFI_PASSWORD = "あなたのWi-Fiのパスワード"
LINE_TOKEN = "あなたのトークン(b7+ux...)"
USER_ID = "あなたのユーザーID(U...)"
# --------------------------------------------------
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
print("Connecting to Wi-Fi...")
while not wlan.isconnected():
time.sleep(1)
print("Wi-Fi Connected!")
url = "https://api.line.me/v2/bot/message/push"
# f-stringを使って、完全に1本の文字列にしてヘッダーを作ります
auth_header = f"Bearer {LINE_TOKEN}"
headers = {
"Content-Type": "application/json",
"Authorization": auth_header
}
payload = {
"to": USER_ID,
"messages": [
{
"type": "text",
"text": "Hello from Pico W! Test OK."
}
]
}
print("Sending to LINE...")
try:
# データをLINEのサーバーへ送信します
response = urequests.post(url, data=json.dumps(payload), headers=headers)
print("Status Code:", response.status_code)
print("Response:", response.text)
response.close()
except Exception as e:
print("Error:", e)テスト結果
うまくいかないときのチェックポイント
400Bad Request と出る
Aデータ形式が不正、とLINEに弾かれています。① LINE_TOKEN や USER_ID の "" の中に余計なスペースや改行が入っていないか、② メッセージを日本語(全角)に書き換えて実行していないか(日本語対策は次のセクション)を確認します。
401Unauthorized と出る
Aチャネルアクセストークンが違います。第2回で発行した b7+ux… から始まる長い文字列が、途中で切れずに正しく貼れているか確認してください。
200成功なのにスマホに届かない
AUSER_ID が別人のIDになっているか、LINE Official Account Managerの「応答設定」でWebhookがオフのままです。第2回の設定を見直してください。
通信[Errno 104] ECONNRESET などが出る
AWi-Fiが不安定か、TLS処理で弾かれています。Pico WのUSBを抜き差しして再起動し、もう一度実行してみてください。
日本語メッセージを送るとエラー400になる原因と対策
送信テストのメッセージを「テスト成功」などの日本語(全角文字)に変えて実行すると、多くの場合 Status Code: 400(Bad Request) で弾かれます。
原因は文字コードです。urequests.post() に data=json.dumps(payload) と文字列のまま渡すと、日本語部分のバイト長とヘッダーが食い違い、LINE側に「壊れたデータ」と判定されてしまいます。
json.dumps(payload).encode('utf-8') でバイト列(bytes)に変換してから data= に渡します。あわせてヘッダーの Content-Type を application/json; charset=UTF-8 にします。次のセクションの本番コードには、この対策を最初から組み込んであります。本番コード:室温超過でLINE通知する自動アラートプログラム
第1回の温度取得コードと、日本語対応版のLINE送信コードを1つにまとめたものが下の Main_Temp_Line_bot.py です。コード上部の4つの設定(Wi-Fi情報・LINEトークン・ユーザーID)を自分の環境に書き換えてください。しきい値の ALERT_TEMP(既定28℃)とチェック間隔の CHECK_INTERVAL(既定10秒)も好みで調整できます。
# Main_Temp_Line_bot.py
import machine
import dht
import network
import time
import urequests
import json
# --- ここをご自身の環境のものに書き換えて下さい ---
WIFI_SSID = "SSIDを入力"
WIFI_PASSWORD = "Passwordを入力"
LINE_TOKEN = "b7+u・・・で始まるLINEトークンを入力"
USER_ID = "U・・・・から始まるユーザーIDを入力"
# --------------------------------------------------
# --- 2. 見守りの設定 ---
ALERT_TEMP = 28 # この温度(℃)を超えたらLINEを送る
CHECK_INTERVAL = 10 # 温度をチェックする間隔(秒) ※テスト用に短くしています
# --------------------------------------------
# センサーとWi-Fiの初期設定
sensor = dht.DHT11(machine.Pin(15))
wlan = network.WLAN(network.STA_IF)
def connect_wifi():
wlan.active(True)
if not wlan.isconnected():
print("Wi-Fiに接続中...")
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
while not wlan.isconnected():
time.sleep(1)
print("Wi-Fi接続成功! IP:", wlan.ifconfig()[0])
def send_line(message):
try:
connect_wifi()
url = "https://api.line.me/v2/bot/message/push"
headers = {
"Content-Type": "application/json; charset=UTF-8", # 文字コードを指定
"Authorization": f"Bearer {LINE_TOKEN}"
}
payload = {
"to": USER_ID,
"messages": [{"type": "text", "text": message}]
}
# ★ココが重要! json.dumps(payload) をさらに .encode('utf-8') で変換します
binary_data = json.dumps(payload).encode('utf-8')
# data= にバイナリデータを渡す
response = urequests.post(url, data=binary_data, headers=headers)
print(f"LINE送信結果ステータス: {response.status_code}")
response.close()
except Exception as e:
print(f"LINE送信エラー: {e}")
# メイン処理開始
print("温湿度監視システムを起動しました")
send_line("温湿度監視システムが起動しました!監視を開始します。")
# 一度LINEを送ったら、しばらく連続送信を防ぐためのフラグ
alert_sent = False
while True:
try:
# センサーから値を読み取る
sensor.measure()
temp = sensor.temperature()
humidity = sensor.humidity()
print(f"【現在値】 温度: {temp}°C, 湿度: {humidity}%")
# 温度がしきい値を超えた場合の判定
if temp >= ALERT_TEMP:
if not alert_sent:
# まだアラートを送っていない場合のみ送信
msg = f"【警告】室温が{temp}°Cになりました!エアコンを確認してください!(湿度: {humidity}%)"
print("警報レベル到達!LINEを送ります。")
send_line(msg)
alert_sent = True # フラグを立てて、連続送信を防ぐ
else:
if alert_sent:
# 温度が安全圏内に戻ったらフラグをリセットし、安心通知を送る
print("温度が安全圏に戻りました。")
send_line(f"室温が{temp}°Cに下がりました。安全圏内です。")
alert_sent = False
except OSError as e:
print("センサーの読み取りエラー(スキップします)")
# 指定した時間だけ待つ
time.sleep(CHECK_INTERVAL)動作確認
alert_sent フラグは、28℃を超えている間ずっと10秒おきに何十通も通知が飛ぶのを防ぐためのものです。一度送ると True になり、27℃以下に戻ると解除通知を送って False に戻ります。
PC不要で自動化:Pico Wにmain.pyを保存して独立稼働させる
ここまではThonnyの「実行」ボタンで動かしてきました。実用するにはPCを24時間つなぎっぱなしにはできないので、プログラムをPico W本体に保存して、コンセントに挿すだけで動くようにします。
main.py なのか:Raspberry Pi Pico系は、電源が入ると本体内の main.py を自動実行する仕様です。この名前で保存しておけば、PCなしでも起動と同時にプログラムが走ります。保存できたらPico WからUSBケーブルを抜き、5V ACアダプター(スマホの充電器で可)につないで部屋のコンセントに挿します。PCなしで自動的にWi-Fiに接続し、LINEに起動通知が届けば完成です。
よくある質問(FAQ)
QurequestsがImportErrorになります。
AurequestsはMicroPython(Pico)に組み込まれているモジュールです。標準のPython(CPython)では動きません。Thonny下部のインタプリタ表示が「MicroPython (Raspberry Pi Pico)」になっているか確認してください。
Q日本語対策を入れたのにStatus Code 400のままです。
A送信直前にjson.dumps(payload).encode('utf-8')でbytesへ変換しているか、ヘッダーのContent-Typeに; charset=UTF-8を付けているかを確認します。トークンやユーザーIDの前後に空白・改行が混ざっているケースも多いです。
QPico WがWi-Fiに接続できません。
APico Wは2.4GHz帯のWi-Fiのみ対応です。ルーターの5GHz専用SSIDを指定していると接続できないので、2.4GHz側のSSIDとパスワードを使ってください。ステルスSSIDや企業向けの認証(WPA2-Enterprise)も接続できません。
Qalert_sentフラグは何のためにありますか?
A28℃を超えている間、チェックのたびに通知が何十通も飛ぶのを防ぐためのフラグです。一度アラートを送るとTrueになり、27℃以下に戻ると解除通知を送ってFalseに戻します。
Qしきい値やチェック間隔を変えたいです。
Aコード上部のALERT_TEMP(既定28)とCHECK_INTERVAL(既定10秒)を書き換えます。テスト用に10秒にしていますが、実運用では60〜300秒くらいに延ばすとWi-Fiとセンサーの負荷が下がります。
Qmain.pyを修正・削除したくなったらどうしますか?
AThonnyで「ファイル」>「開く」>「Raspberry Pi Pico」からmain.pyを開いて編集・保存します。削除はThonnyのファイルビューで右クリックから行えます。BOOTSELでの初期化は不要です。
自作スマートリモコンシリーズ(全5回)
- ラズパイPico WとDHT11で温湿度を測定する方法|配線図とMicroPythonコード
- LINE Messaging APIの始め方|チャネル作成とアクセストークン・ユーザーIDの取得手順
- Pico WからLINEへ通知を送るMicroPythonコード|urequestsでプッシュ送信・日本語エラー400対策(この記事)
- ラズパイPico Wで赤外線リモコンを自作|受信・送信回路と38kHz PWM制御
- GASを中継サーバーにLINEからPico Wを遠隔操作する方法|Webhookとポーリングで双方向通信
Follow me on X
本ブログの中の人「ニンジン🥕」はXやってます。新着記事はいち早くポストでお知らせしているので、見逃したくない方は @ninjin_py_vba をフォローしてみてください🥕
@ninjin_py_vba をフォローシリーズ記事一覧
電子工作・自動化ツールの製作記録をシリーズごとにまとめています。気になるテーマからお読みください。
-
FILE.01 — IoT
Raspberry Pi Pico W × GASラズパイPico W×GASで自作!「LINEで動く温湿度&スマートリモコン」完全ロードマップ
「外出中のペットの室温が心配…」そんな思いからスタートしたIoT自作プロジェクトの総集編。温湿度監視からエアコン遠隔操作まで、仕組みをゼロから作りたい方のための全5回の開発記録です。
シリーズを読む -
FILE.02 — CNC
Arduino × レーザー刻印CNCCNC自作シリーズ
高精度な加工を目指し、本格的な自作CNC製作に挑戦中。現在は基幹パーツであるオリエンタルモーターの納品を待つ「設計・準備編」を公開。ハードとソフトの両面から、理想のマシンを形にする過程をリアルタイムにお届けします。
シリーズを読む -
FILE.03 — XY軸制御
Raspberry Pi × ステッピングモーターXYテーブルシリーズ
Raspberry Piとステッパモーターを使い、ゼロから2軸制御に挑む記録。OS設定から回路設計、多軸制御のPythonコードまで、躓きやすいポイントを徹底図解。電子工作初心者が「動く感動」を味わうための実戦ガイドです。
シリーズを読む -
FILE.04 — 業務自動化
Python × Excel × CustomTkinter【Python開発記】NINJIN Mail制作記
PythonとExcelを連携させ、実務で即戦力となるメール送信ツールを開発。CustomTkinterによるUI構築や、ミスを防ぐテンプレート活用術など、現場の「痒い所に手が届く」自動化ノウハウを細部まで丁寧に解説します。
シリーズを読む -
FILE.05 — 業務自動化
Python × Excel × GUIアプリ化Invoice Maker(請求書・見積書自動作成)
手作業の請求書作成から卒業!PythonでExcelデータを読み込み一括PDF化する「Invoice_Maker」の作り方を全3回で解説。基本ロジックからGUIアプリ化まで、実務で役立つ自動化ノウハウが満載です。
シリーズを読む










コメント