技術検証

Python×MQTTで赤外線コードを識別!マッチングと管理のしくみtitle_point

はじめに

前回は、ESP32で赤外線信号を受信し、MQTTを通じてサーバーに送信する仕組みを紹介しました。
第2話では、その信号データをどう識別し、管理していくのかという「サーバー側の頭脳」にあたる部分を、Pythonスクリプトで実装していきます。

MQTTメッセージの受信、保存、識別、そして新しい信号の登録と通知まで、仕組みの全体像を紹介します。


赤外線信号は完全一致しない?

赤外線リモコンの信号は、意外と毎回微妙に違います。環境ノイズや送信タイミングの影響で、完全一致はまずしません。

そこで今回は、以下のような「ゆるい一致ロジック」を導入します:

  • 信号の長さの差がある程度まで許容される

  • 各値の比率差が一定範囲内なら一致とみなす

この仕組みにより、似た信号をマッチングして、自動でコマンド名を割り当てられるようになります。


システム構成図(受信処理側)

[ESP32] ─(MQTT inputir/◯◯/1)→ [Pythonスクリプト] ─→ DB or ファイル保存
↓
判別できれば inputcmd/保存名/ポート
判別できなければ unknowncmd/◯◯/ポート

コードで見る:Pythonによるマッチング処理

以下はマッチング処理の一部抜粋です:

if is_similar(received_data, saved_data):
client.publish(f"inputcmd/{device_name}/{port}", json.dumps({"cmd": name}))
else:
client.publish(f"unknowncmd/{device_name}/{port}", json.dumps(received_data))

is_similar関数(例)

def is_similar(a, b, tolerance=0.3):
if abs(len(a) - len(b)) > 3:
return False
return all(abs(ai - bi) / max(ai, bi) < tolerance for ai, bi in zip(a, b))

新しい信号はどうするの?

識別できなかった信号は unknowncmd/◯◯/ポート にパブリッシュされます。

別のPythonスクリプト(unknown_handler.py)がこれを購読しており、手動で保存名を入力して登録できるようになっています。

保存名を入力してください(Enterでスキップ): tv_power
→ irdata/tv_power.json に保存しました。
→ savecmd/◯◯/1 にパブリッシュしました。

デバイス名との対応も保存

デバイスIDはハードウェアから自動で送られますが、わかりやすい名前に置き換えたい場合があります。

そのため、最初に不明なデバイスIDがきたら unknowndevice/ESP32_A1 に通知され、対応名を入力すれば devicedata/ESP32_A1.json に保存されます。

以後は保存名で処理され、トピックも inputcmd/風呂/1 のように読みやすくなります。


補足:保存形式はJSONで統一

登録されたコマンドは、irdata/ フォルダ以下に JSON 形式で保存されます。

[9000, 4500, 560, 1690, 560, 560, ...]

これにより、後で手動編集・比較もしやすく、バージョン管理やスプレッドシートとの連携にもつなげやすくなります。


おわりに

これで赤外線信号をサーバー側で受信し、「これは何のコマンドか?」を識別し、必要に応じて登録する仕組みが完成しました。

次回は、Googleスプレッドシートと連携して、これらのコマンドを「誰でも編集・管理できる」ようにしていきます!

次回 ▶️ 第3話:Googleスプレッドシートで家電操作をクラウド管理!社内運用もラクに


? 実際のコードが気になる方は GitHubリポジトリ にも公開予定です!
採用情報もぜひご覧ください → こちら