はじめに(対象読者・この記事でわかること)

この記事は、Arduino(ESP32/ESP8266)でセンサー値をLINEに通知したいけれど「月200件まで」の無料レート制限が気になって踏み出せない、というメイカー/モノづくり初心者の方を対象にしています。
読み進めることで、①LINE Messaging APIのレート制限の仕組み、②Arduinoスケッチ内で簡単に実装できる「送信間隔調整&カウンタ永続化」の手法、③意図せず制限を突破してしまう「デバッグ連打」を防ぐコツ、が丸わかりします。今すぐ既存コードに3行追加するだけで、月の送信残数を気にせず運用できるようになります。

前提知識

  • Arduino IDEでスケッチを書き込める(シリアルモニタの使い方を知っている)
  • LINE DevelopersコンソールでBotを作成し、アクセストークンを取得済みである
  • 簡単なJSONとHTTP POSTの知識があると尚好印象

LINE Messaging APIのレート制限を知ろう

LINE Messaging APIの無料枠は「1チャネルあたり月200件」です。これは「Webhookイベント数」ではなく「Botが送る応答メッセージ数」の方です。Arduinoからセンサー値をpush的に通知しようとすると、1日1回でも30日で30件、1時間ごとにすると720件とあっという間に上限に到達します。
加えて、200件を超えた瞬間から「Quota exceeded」エラーが返され、当月は一切送れなくなるため、IoT機器の見守り用途では致命的です。本記事では、Arduino側で「送信回数をカウント」「上限に達しそうなら無駄な通知を諦める」「月をまたいでリセット」する仕組みを、Arduino IDEだけで完結して実装します。

Arduinoスケッチでレート制限を回避する実装

ステップ1:EEPROM(またはPreferences)で送信回数を永続化する

ESP32の場合、EEPROMより簡単なPreferencesライブラリを使います。
#include <Preferences.h>
Preferences pref;
const char NAMESPACE[] = "line_cnt";
const int MONTHLY_LIMIT = 200;

setup()で
pref.begin(NAMESPACE, false);
unsigned int sendCount = pref.getUInt("count", 0);
unsigned int lastMonth = pref.getUInt("month", 0);

月が変わったかチェック
if (month() != lastMonth) {
sendCount = 0;
pref.putUInt("month", month());
}

これで「月をまたいで自動リセット」が完了です。

ステップ2:通知関数内で残数チェック+バッチリ節約送信

bool sendLINE(String message) {
if (sendCount >= MONTHLY_LIMIT) {
Serial.println("[LINE] 今月の上限到達。送信見送り");
return false;
}
HTTPClient https;
https.begin("https://api.line.me/v2/bot/message/push");
https.addHeader("Content-Type", "application/json");
https.addHeader("Authorization", "Bearer " + String(ACCESS_TOKEN));

String json = "{\"to\":\"" + String(USER_ID) + "\",\"messages\":[{\"type\":\"text\",\"text\":\"" + message + "\"}]}";
int httpCode = https.POST(json);
https.end();

if (httpCode == 200) {
sendCount++;
pref.putUInt("count", sendCount);
Serial.print("送信成功 残 ");
Serial.println(MONTHLY_LIMIT - sendCount);
return true;
}
return false;
}

loop()からは
if (センサー値が閾値超え) {
sendLINE("温度異常! " + String(temp) + "℃");
}

これで200件を超える送信は一切行われます。

ステップ3:開発中の「デバッグ連打」を防ぐ

開発段階で毎回リセットするとEEPROMがクリアされず、すぐに200件消費してしまう。
対策として、ボタン1つで「強制リセットカウンタ」を実装します。
if (digitalPinToInterrupt(BUTTON_PIN)) {
sendCount = 0;
pref.putUInt("count", 0);
Serial.println("カウンタを手動リセット");
}

あとはボタンを長押しすれば、即座にカウントが0に。製品出荷時にこの関数をコメントアウトしておけば、誤爆を防げます。

ハマった点:リトライループで無限増殖

もしWi-Fi瞬断でPOST失敗→即リトライを実装すると、1回のセンサー異常で数十件消費する事態が起きます。
→ リトライは3回までに留め、送信成功/リトライ上限到達のどちらも「1イベント=1カウント消費」とカウントアップする設計に変更。これで安全です。

解決策

上記の通り「カウントアップは送信API呼び出し時に1回だけ」に統一。
加えて、EEPROM/Preferencesのライフタイムは約100,000回書き換え保証なので、1時間に1回更新しても10年超の寿命を実現します。

まとめ

本記事では、Arduino(ESP32)×LINE Messaging APIで「月200件」のレート制限を気にせず通知する方法を解説しました。

  • EEPROM/Preferencesで送信回数を永続化
  • 月跨ぎで自動リセットし、残数を常に把握
  • 開発中はボタン1つでカウントリセット、製品版では無効化

これで、無料枠をフル活用しながら、見守り・異常検知システムをスマホへ確実に届けられます。
次回は「複合家電の状態を1つのLINE Botに集約し、メッセージ種別でレートを最適化する」高度編をお届けします。

参考資料

  • LINE Messaging API 公式ドキュメント(レート制限)
    https://developers.line.biz/ja/reference/messaging-api/
  • ESP32 Preferences ライブラリリファレンス
    https://github.com/espressif/arduino-esp32/tree/master/libraries/Preferences
  • Arduino EEPROM ライブラリ使用例
    https://www.arduino.cc/reference/en/libraries/eeprom/