PR

GASとLINE Bot(Webhook)でPico Wを遠隔操作!双方向通信の作り方

ハードウェア制御 / 電子工作
スポンサーリンク

はじめに:IoTスマートリモコンの総仕上げ!ラズパイPico WとLINEを連携させよう

こんにちは、ニンジンです🥕
本記事は「愛犬を守る!格安IoT温湿度見守りLINE Botの作り方」の第5回になります。これまでの連載をまだお読みでない方は、ぜひ以下の記事からチェックしてみてくださいね。

全5回にわたってお届けしてきた「愛犬を守る!格安IoT温湿度見守りLINE Botの作り方」も、いよいよ今回が最終回です。

前回の第4回では、Raspberry Pi Pico W(ラズパイPico W)に電子部品を組み込み、エアコンの赤外線信号をハック(学習・発信)するハードウェア改造を行いました。 今回は、その完成した赤外線送信機を外の世界(LINE)と繋ぎ、スマホからいつでもどこでもエアコンを遠隔操作できる「完全自作スマートリモコン」へと進化させます!

PCの呪縛から解き放たれ、単体で24時間動き続ける真のIoTデバイスが完成する感動の瞬間を、ぜひ一緒に味わいましょう。

スポンサーリンク

Pico W単体では外から操作できない?「GAS」を使ったネットワーク構築の仕組み

本格的な作業に入る前に、少しだけ「通信の仕組み」について解説します。 現在、Pico WからLINEへ「暑いよ!」と通知を送ることはできています。しかし、逆にスマホのLINEから「冷房をつけて!」とPico Wに直接命令を送ることは、簡単にはできません。

なぜなら、ご自宅のWi-Fiルーターには強力なセキュリティ(ファイアウォール)があり、外からの見知らぬアクセスをすべて弾いてしまうからです。 VPNや専用のWebサーバーを立てる方法もありますが、ハードルが高すぎますよね。そこで今回は、無料で使えるGoogle Apps Script(GAS)を「インターネット上の私書箱(中継サーバー)」として利用し、疑似的な双方向通信を実現します!


【今回の通信の流れ(仕組み)】

  • [スマホ] からLINEに「冷房ON」と送る。
  • [LINEのサーバー] が、ネット上の私書箱 [GAS] に「冷房ONの命令が来たよ」とメモを残す(Webhook機能)。
  • 家の中にいる [Pico W] が、10秒ごとに [GAS] を覗きに行き(ポーリング)、「あ、命令が来てる!」と受け取って赤外線を発射する。

この「GASを経由したバケツリレー方式」を使えば、ルーターの設定を一切いじることなく、安全かつ確実に遠隔操作が可能になります!

スポンサーリンク

中継サーバー構築:Google Apps Script (GAS) の設定とデプロイ手順

1.Google Apps Script (GAS) の作成

それでは、中継サーバーとなるGASの準備を進めましょう。

Googleドライブ( https://drive.google.com/ )にアクセスします。

お手持ちのアカウントにてログインします。

画面左上の「+新規」をクリックします。

「その他」「Google Apps Script」をクリックします。

「スクリプトを作成」をクリックします。

左上の「無題のプロジェクト」をクリックします。

「PicoW_IR_Chaser」など分かりやすい名前に変更します。


最初から書かれている数行のコードをすべて消去し、以下のJavaScriptコードを貼り付けて保存します。

// スクリプトプロパティ(GASの簡易データベース)を使って状態を管理します
const PROPERTY_KEY = 'AIR_CON_SIGNAL';

// 1. LINEからメッセージを受け取る関数 (Webhook)
function doPost(e) {
try {
const jsonString = e.postData.contents;
const data = JSON.parse(jsonString);

// LINEからのイベントを取得
const event = data.events[0];
if (event && event.type === 'message' && event.message.type === 'text') {
const userMessage = event.message.text;
const properties = PropertiesService.getScriptProperties();

// 送られてきたメッセージの内容によって、保存する命令(ステータス)を変える
if (userMessage.includes("冷房")) {
properties.setProperty(PROPERTY_KEY, "COOL_ON");
} else if (userMessage.includes("停止")) {
properties.setProperty(PROPERTY_KEY, "COOL_OFF");
} else if (userMessage.includes("現在の温度は")) {
properties.setProperty(PROPERTY_KEY, "GET_TEMP");
}
}

return ContentService.createTextOutput(JSON.stringify({status: 'post_success'}))
.setMimeType(ContentService.MimeType.JSON);
} catch(error) {
return ContentService.createTextOutput(JSON.stringify({status: 'error', message: error.toString()}))
.setMimeType(ContentService.MimeType.JSON);
}
}

// 2. Pico Wから「命令ある?」と確認しにくる関数
function doGet(e) {
const properties = PropertiesService.getScriptProperties();
const currentSignal = properties.getProperty(PROPERTY_KEY) || "NONE";

// Pico Wに現在のステータスを返す
const responseData = { signal: currentSignal };

// 何かしらの命令(NONE以外)があったら、確認されたのでリセット(消去)する
if (currentSignal !== "NONE") {
properties.setProperty(PROPERTY_KEY, "NONE");
}

return ContentService.createTextOutput(JSON.stringify(responseData))
.setMimeType(ContentService.MimeType.JSON);
}

2.GAS のデプロイ(インターネット上に公開)

このコードを世界中(LINEやPico W)からアクセスできるように公開します。

画面右上の「デプロイ」ボタン >「新しいデプロイ」をクリックします。

種類の選択(歯車アイコン)で「ウェブアプリ」を選択します。

各項目を以下のように設定してください。

  • 説明: v1(何でもOK
  • ウェブアプリを実行: 自分
  • アクセスできるユーザー: 全員(※Pico WやLINEがアクセスできるようにするため)
  • 「デプロイ」ボタンを押します。

※初回は「アクセスの承認」を求められるので、「アクセスを承認」ボタンを押し、
  ご自身のアカウントを選んで、詳細リンクから「PicoW_IR_Chaser(安全ではないページ)に移動」をクリックして許可してください。

デプロイが完了すると、「ウェブアプリのURL」が表示されます。これをコピーしてメモ帳などに控えておいてください。

スポンサーリンク

LINE BotとGASを紐付ける!Webhook URLとLINE応答機能の設定

次に、LINEにメッセージが来たら、先ほど作ったGASに情報が飛ぶように紐付けを行います。

3.LINE DevelopersでのWebhook設定

LINE Developersにアクセスします。

LINE Developers

LINE Developers のコンソールにログインします。

今回使っている Messaging API の「チャネル(温湿度自動アラート)」を開きます。

  • 「Messaging API設定」 タブを開き、下の方にある 「Webhook設定」 を探します。
  • 「Webhook URL」 の項目に、先ほどコピーした GASの「ウェブアプリのURL」 を貼り付けて保存します。
  • 保存後、「Webhookの利用」のスイッチをON にします。

4.LINE Official Account Managerでの応答設定

LINE Official Account Manager( https://manager.line.biz/ )にアクセスしてログインします。

今回作成したBotのアカウント(温湿度自動アラート)をクリックします。

画面を下にスクロールし中央付近の「応答設定」 をクリックします。

設定項目を以下のように変更してください。

  • チャット:オフ
  • あいさつメッセージ: 任意(ONでもOFFでも可)
  • Webhook: オン (GASに転送するために必須)
  • 応答メッセージ: オフ (必須)

ここまでできたら、中継サーバーの準備は完了です。

スポンサーリンク

ラズパイPico Wに最終プログラムを書き込む(Pythonコード公開)

いよいよ大詰めです。
以下のコードを貼り付け、上部の設定項目(Wi-Fi情報、LINEのトークン、USER_ID、先ほど取得したGASのURL)をあなた自身のものに書き換えてください。
また、前回取得したエアコンの赤外線データ(数字のリスト)も指定の箇所に貼り付けます。

#main.py

import machine
import dht
import network
import time
import urequests
import json
import gc

# 起動時のパーツ立ち上がりを待つ(超重要!)
time.sleep(3)

# --- 1. ご自身の環境に書き換えてください ---
WIFI_SSID = "あなたのWi-Fi_SSID"
WIFI_PASSWORD = "あなたのWi-Fi_パスワード"
LINE_TOKEN = "あなたのLINE_チャンネルアクセストークン"
USER_ID = "あなたのLINE_ユーザーID"

# 🔴 先ほど取得したGASのウェブアプリURL
GAS_URL = "https://script.google.com/macros/s/XXXXX/exec"

# --- 2. 見守りとピンの設定 ---
ALERT_TEMP = 28 # 警告温度
CHECK_INTERVAL = 10 # チェック間隔(秒)
TX_PIN = 17 # 赤外線LEDピン

# --- 3. エアコン信号データ(※前回取得した数字のリストに書き換えてください) ---
COOL_ON_DATA = [4307, 4535, 480, 1667, ...]
COOL_OFF_DATA = [4368, 4507, 476, 1605, ...]

sensor = dht.DHT11(machine.Pin(15))
wlan = network.WLAN(network.STA_IF)

def connect_wifi():
wlan.active(True)
if not wlan.isconnected():
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
timeout = 15
while not wlan.isconnected() and timeout > 0:
time.sleep(1)
timeout -= 1
if not wlan.isconnected():
machine.reset()

def send_ir(data):
pwm = machine.PWM(machine.Pin(TX_PIN))
pwm.freq(38000)
def pwm_on(): pwm.duty_u16(21845)
def pwm_off(): pwm.duty_u16(0)
is_on = True
for us in data:
if is_on: pwm_on()
else: pwm_off()
time.sleep_us(us)
is_on = not is_on
pwm_off()
pwm.deinit()

def send_line(message):
response = None
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}]}
response = urequests.post(url, data=json.dumps(payload).encode('utf-8'), headers=headers)
except Exception:
pass
finally:
if response:
try: response.close()
except: pass

def check_gas_command():
response = None
try:
connect_wifi()
response = urequests.get(GAS_URL)
if response.status_code in [301, 302, 303, 307, 308]:
redirect_url = response.headers.get('location') if hasattr(response, 'headers') else None
response.close()
response = None
if redirect_url: response = urequests.get(redirect_url)
else: return "NONE"

text_data = response.text
if text_data.startswith('<'): return "NONE"
return json.loads(text_data).get("signal", "NONE")
except Exception:
return "NONE"
finally:
if response:
try: response.close()
except: pass

# --- メイン処理 ---
send_line("遠隔エアコン操作システムが起動しました!監視と命令待ちを開始します。")
alert_sent = False
error_count = 0

while True:
try:
sensor.measure()
temp = sensor.temperature()
humidity = sensor.humidity()

if temp >= ALERT_TEMP:
if not alert_sent:
send_line(f"【警告】室温が{temp}°Cになりました!エアコンを確認してください。(湿度: {humidity}%)")
alert_sent = True
else:
if alert_sent:
send_line(f"室温が{temp}°Cに下がりました。安全圏内です。")
alert_sent = False

cmd = check_gas_command()
if cmd == "COOL_ON":
send_ir(COOL_ON_DATA)
send_line(f"エアコンに冷房ON信号を送信しました。(現在の室温: {temp}°C)")
elif cmd == "COOL_OFF":
send_ir(COOL_OFF_DATA)
send_line(f"冷房OFFの信号を発信しました。(現在の室温: {temp}°C)")
elif cmd == "GET_TEMP":
send_line(f"現在のお部屋の状況です。\n温度: {temp}°C\n湿度: {humidity}%")

error_count = 0

except Exception:
error_count += 1
time.sleep(5)
if error_count >= 5: machine.reset() # 連続エラー時はシステム再起動

finally:
gc.collect() # メモリ解放
time.sleep(CHECK_INTERVAL)

💡🥕のワンポイント解説:なぜ今回のコードには「print文」が一つも無いのか?

これまでテスト用に使っていたコードには、動作確認のために print("冷房ONを検知しました") のような記述がたくさんありました。しかし、今回の本番用 main.py では、あえてこれらをすべて削除しています。

実はこれ、PCから切り離して単体動作(スタンドアロン化)させた際の「フリーズ」を防ぐための、非常に重要な工夫なんです!

PC(Thonny)に繋いでいる時は、print で出力されたテキストをPC側が受け取って画面に表示してくれます。しかし、PCから抜いてコンセントから直接給電した場合、テキストの「受け先」がいなくなってしまいます。 受け先がないまま print で出力し続けると、Pico Wの内部メモリ(バッファ)に送信待ちのテキストがどんどん溜まり続け、やがてメモリを圧迫してシステム全体がフリーズしてしまいます。

本番運用では print を完全に無くし、エラー処理(except)も pass で綺麗に流してあげることで、Pico Wの限られたメモリを「温湿度計測」と「通信」だけに100%集中させることができ、長期間の安定稼働が実現します。

スポンサーリンク

スマホからエアコン遠隔操作!PC不要の完全スタンドアロン化テスト

まずはThonnyの再生ボタンを押して、エラーが出ないかテストします。 LINEに起動メッセージが届いたら、スマホから 冷房ON停止現在の温度は と送信してみてください。エアコンから「ピッ」と音が鳴り、完了通知が返ってきたら大成功です!

Thonnyにて「main.py」を実行して下さい。
ターミナルに「soft reboot」と表示されます。

スマホに「遠隔エアコン操作システムが起動しました!監視と命令待ちを開始します。」とメッセージが受信されます。

  • 「冷房ON」とメッセージを送付します。
  • 10秒以内に「LINEからの命令を受信し、エアコンに冷房ON信号を送信しました。」のメッセージが受信され、「エアコンから「ピッ」と音が鳴り冷房ON」されます。
    ※赤外線LEDの照射範囲にエアコンが来るように配置して下さい。
  • 温湿度センサーを息を吹きかけて、温度を上げます。
  • スマホに警告メッセージが受信されます。
    ※前回の機能はそのまま引き継がれています

・室温が27℃以下になると、スマホに「室温が27℃に下がりました。安全圏内です。」とメッセージが受信されます。
※前回の機能はそのまま引き継がれています

  • 「停止」とメッセージを送付します。
  • 10秒以内に「LINEからの命令を受信し、冷房OFF信号を発信しました。」のメッセージが受信され、「エアコンが停止」されます。
    ※赤外線LEDの照射範囲にエアコンが来るように配置して下さい。
  • 「現在の温度は」とメッセージを送付します。
  • 10秒以内に「現在のお部屋の状況です」のメッセージが受信され、温湿度の状況が確認できます。

🛠 もし上手く動かなかったら?(よくあるエラーと解決策)

テスト実行でエラーが出てしまっても焦らないでください!この連携システムで誰もが一度はハマる「定番の罠」と解決策をまとめました。

Q1. スマホのLINEから「冷房」と送っても、Pico Wが全く反応しない!
  • 原因の90%はこれ!「Webhook URLの更新忘れ」です。
    GASのコードを少しでも書き換えた場合、必ず「新しいデプロイ」を行ってURLを再発行する必要があります。古いURLのままLINE側(Webhook設定)を放置していると、命令が届きません。
  • 対策: GASで再度「新しいデプロイ」を行い、発行された新しいURLを、Pico Wの GAS_URL とLINE Developersの Webhook URL両方に貼り直してみてください。
Q2. Thonnyの画面に「HTMLを受信しました」や「JSONエラー」と表示される
  • 原因:GASのアクセス権限エラー Pico WがGASにアクセスした際、JSONデータではなく「Googleのログイン画面(HTML)」を返されてしまっている状態です。
  • 対策: GASのデプロイ画面で「アクセスできるユーザー」が「全員」になっているか必ず確認してください。(※「Googleアカウントを持つ全員」ではないので注意!)
Q3. SyntaxError: invalid syntax と出てプログラムがすぐ止まる
  • 原因:Python特有の「インデント(空白)のズレ」 Pythonは行の先頭の空白(スペース)の数でプログラムのまとまりを判断します。コードをコピペした際に、ifelif の縦のラインがズレていたり、最後の :(コロン)が消えていたりするとこのエラーになります。
  • 対策: エラーが出た行番号の周辺を見て、スペースの数や記号の抜けがないか確認しましょう。

これらの壁を乗り越えて無事に動いたら、いよいよ最後の仕上げです!

スポンサーリンク

最終ステップ:PC不要で完全自動化!Pico Wにmain.pyを保存して独立稼働させる方法

第3回の記事のおさらいですね

ここまではテストのために、PCを開いてThonnyから「実行」ボタンを押して動かしてきました。でも、実用的に使うためにPCを24時間繋ぎっぱなしにしておくわけにはいきませんよね。

そこで最後は、Pico WをPCから完全に切り離します!プログラムを本体に記憶させて、コンセントに挿すだけで自動的に監視を始めてくれる**「あなただけの小さなIoT見守り家電」**へと進化させましょう!

Thonnyのメニューから 「ファイル」>「名前を付けて保存」 を選びます。

保存先に 「Raspberry Pi Pico」 を選びます。

ファイル名を必ず main.py」 にして保存してください。

💡 なぜ main.py なのか?
Raspberry Pi Picoは、電源が入った瞬間に内部にある main.py という名前のファイルを自動で実行する仕様になっています。

保存できたら、Pico WからUSBケーブルを抜き、スマホの充電器など(5V ACアダプター)に繋いで部屋のコンセントに直接挿してみてください。

数秒後、Wi-Fiに自動接続し、スマホに「遠隔エアコン操作システムが起動しました!」と通知がくれば、見事「スタンドアロン(独立)化」の完了です。 これで、PCの電源が切れていても24時間365日、あなたのお部屋の温度を見守り、いつでもエアコンを操作できる最強のIoTデバイスが誕生です!

スポンサーリンク

おわりに:手作りIoTで実現する愛犬のための快適・安心なスマートホーム

全5回にわたる記事を読んで頂き、本当にありがとうございました!

最初はただの小さな基板だったRaspberry Pi Pico Wが、電子パーツと配線で物理世界と繋がり、Pythonコードで脳を与えられ、Wi-FiとGASを経由してLINEというクラウドサービスと結びつきました。 これこそが、ハードウェアからソフトウェア、ネットワークまでを一気通貫で作り上げる「IoT(Internet of Things)開発」の醍醐味です。

市販のスマートリモコンを買えば数千円で済みますが、自分でトラブルシューティングを行いながら仕組みを理解して作り上げたこのシステムは、何事にも代えがたい「最高の生きたノウハウ」になったはずです。 ぜひ、このシステムを活用して、愛犬にとって快適な環境を整えてあげてください!

ニンジン🥕は、今後も「日々の課題をプログラムで解決する」楽しさと技術を発信していきます。次回作にもぜひご期待ください!


第1回:ハードウェア準備&温度取得編はこちら

第2回:LINE Messaging APIの最新設定編はこちら

第3回:PythonでLINE通知&完全自動化編

第4回:赤外線受信・発信編

スポンサーリンク

他のシリーズ




PythonでExcel請求書を自動PDF化!openpyxlからCustomTkinterによる一括GUIツール開発まで完全解説
PythonでExcel請求書を自動PDF化するツール「Invoice Maker」の制作シリーズ全3回をまとめて解説。openpyxlとpywin32による基本ロジック、for文でのループ処理、CustomTkinterを使ったGUIアプリ化まで、業務自動化の全ステップをこの1記事で確認できます。
【完全版】ゼロから作る自作CNCロードマップ!Arduino制御とレーザー刻印機への全手順
Arduino×GRBL×1064nm赤外線レーザーで自作するCNCマシンの全工程を、全10回のロードマップで完全解説。要素設計から本筐体の組み立て、配線エラーの解決、設計データ配布までを網羅します。
ラズパイPico W×GASで自作!「LINEで動く温湿度&スマートリモコン」完全ロードマップ
ペットの熱中症対策に。Pico W+GASでスマホからエアコンを遠隔操作する自作スマートリモコンをLINE Botで作る全5回の総集編。回路図・Pythonコード・API設定・フリーズ対策まで全部まとめました。
GASとLINE Bot(Webhook)でPico Wを遠隔操作!双方向通信の作り方
ラズパイPico WとLINEを連携して自作スマートリモコンを完成させよう!第5回ではGoogle Apps Script(GAS)を中継サーバーとして使い、外部からエアコンを遠隔操作する仕組みと、PC不要で動かす完全スタンドアロン化の手順を解説します。
ラズパイPico Wで赤外線リモコンを自作!送受信回路とPWM制御のやり方
Raspberry Pi Pico Wを使ってエアコンの赤外線信号をハック!自作IoTスマートリモコンの要となるハードウェア改造手順を解説します。受光モジュールの配線、38kHzの信号解析、トランジスタを使ったIR送信回路の組み方まで、実践的な電子工作ノウハウを公開。

コメント