Home Assistant で水やりを知らせて自動化する — 通知からポンプ制御まで

鉢の土が乾いたことに気づくのは、たいてい葉がしおれてからだ。土壌水分センサーを挿せば乾き具合は数字で見えるが、数字を見に行く習慣がなければ結果は同じだ。そこで Home Assistant で水やりを自動化しようと考えると、今度は別の不安が出てくる。ポンプが止まらなかったら床はどうなるのか。サーバーが再起動したら、途中まで回っていたポンプは誰が止めるのか。
本記事は、この二つの不安を順に片づける手順をまとめたものだ。最初は「乾いたらスマートフォンに知らせる」だけの自動化を組み、それが安定してからポンプ制御に進む。ポンプを動かす段階では、止める仕組みを Home Assistant だけに任せないことを設計の中心に置く。最後に、ローカルで動かす LLM に植物の状態を要約させ、通知文を読みやすくする方法と、その限界も書く。
※本記事にはアフィリエイト広告(PR)が含まれます。
なお、当サイトは本記事の構成を実機で動かしていない。手順は Home Assistant と ESPHome の公式ドキュメント、および外部の製作記事に基づいており、該当箇所に参照先のリンクを張っている。バージョンの記述は 2026 年 9 月時点(Home Assistant の最新は 2026.9.4、2026-09-27 公開)のものである。
- 水やりの自動化が失敗する場所 — 止まらないポンプと届かない通知
- Home Assistant で水やりを自動化する構成を先に決める
- 第1段階: 乾いたら通知するだけの自動化を組む
- Plant Monitor で水分・照度・温度をまとめて見る
- 第2段階: ポンプを ESPHome のスイッチとして用意する
- 止まらない事態への備え — 水位センサーと実行回数の上限
- Home Assistant 側でポンプを動かす自動化を書く
- ローカル LLM に植物の状態を要約させて通知文を作る
- LLM に任せるのは要約まで — ポンプを動かす判断は自動化に残す
- ポンプ・水位センサー・スマートプラグの選び方
- 組み上げる前に確かめる項目
- まとめ — 通知で観察し、止める仕組みを二重にしてからポンプを動かす
- 参照
水やりの自動化が失敗する場所 — 止まらないポンプと届かない通知

水やりの自動化で起きる失敗は、大きく二つに分かれる。一つは水をやりすぎる失敗で、ポンプが止まらない、同じ自動化が何度も動く、センサーが乾いた値を返し続ける、といった原因で起きる。もう一つは気づけない失敗で、通知が一度しか来ない、あるいは来すぎて無視するようになる、というものだ。
前者の原因は、多くの場合「ポンプを止める命令」が一か所にしかないことだ。Home Assistant の自動化で「ポンプを入れる → 30 秒待つ → ポンプを切る」と書くと、止める命令は Home Assistant の中の待ち時間にだけ存在する。その待ち時間の途中で Home Assistant が再起動したり、Wi-Fi が切れてマイコンに命令が届かなかったりすれば、ポンプは入ったままになる。Home Assistant Community の水やり製作記事への返信でも、「Home Assistant との接続が切れた場合に備えて、ESPHome 側に最大運転時間を設定した」と書かれている。
後者の原因は、トリガーの性質を知らないまま組むことだ。Home Assistant の Numeric state トリガーは、値がしきい値をまたいだときに発火し、同じ側にとどまっている間は再発火しない。つまり「水分が 30 を下回った」通知は、下回った瞬間に 1 回だけ届く。その通知を見落とすと、土が乾いたままでも次の通知は来ない。
もう一つ知っておくべき性質がある。Numeric state トリガーには for で「しきい値を下回った状態が一定時間続いたら」という条件を付けられるが、公式ドキュメントはこの for のタイマーは Home Assistant の再起動や自動化の再読み込みでリセットされると明記している。通知の用途でも、これは「遅れて届く」とは限らない。Numeric state トリガーは値がしきい値をまたいだときに発火するので、再起動や再読み込みの時点ですでにしきい値を下回っていた場合は、値がいったんしきい値を上回ってから再び下回るまで発火しない。通知を取り逃す場合があるということだ。ポンプを止める時間の管理に同じ仕組みを使えば、リセットされた時点でポンプを止める予定そのものが消える。本記事が段階を分け、ポンプの停止をマイコン側に持たせる理由はここにある。
Home Assistant で水やりを自動化する構成を先に決める

Home Assistant による水やりの自動化は、次の三層で考えると整理しやすい。
- 測る層: 土壌水分センサーを ESP32 などのマイコンにつなぎ、ESPHome で Home Assistant に値を送る
- 判断する層: Home Assistant の自動化が、しきい値と時間で「知らせる」「水をやる」を決める
- 動かす層: ポンプを ESPHome のスイッチ、または市販のスマートプラグで入り切りする
最初に組むのは測る層と判断する層だけで、動かす層は後回しにする。通知だけの期間に、センサーの値がどのくらいの速さで下がるのか、水をやった直後にどこまで戻るのか、しきい値の近くで値が上下にぶれないかを観察しておくと、ポンプ制御に進んだときのしきい値と運転時間を根拠のある値にできる。
Home Assistant のインストール方式は、現行の公式ページでは Home Assistant Operating System と Home Assistant Container の 2 種類だ。公式が推奨するのは OS 版で、Container 版では Apps(旧称アドオン)が使えない。ESPHome のダッシュボードを Home Assistant の中で動かしたい場合や、ローカル LLM 関連の追加ソフトを同じ機械に置きたい場合は、OS 版のほうが手順が短くなる。
電気の扱いについても最初に決めておく。本記事で扱うのは、USB 給電や DC 12V 以下で動く小型ポンプに限る。商用電源(AC100V)で動くポンプをリレーで直接開閉する工作は扱わない。水のそばで家庭用コンセントの電圧を配線するのは、失敗したときの被害が低電圧の場合と比べものにならないからだ。
第1段階: 乾いたら通知するだけの自動化を組む

最初の自動化は、土壌水分が一定時間しきい値を下回ったら、スマートフォンの Home Assistant Companion App に通知を送るものだ。Companion App は公式のアプリで(iOS・Android のほか macOS 版もある)、アプリにログインした端末は notify.mobile_app_ に続けてデバイス ID を付けた名前で通知の宛先に並ぶ。通知には最低限 message を指定する必要がある。
YAML で書くと次のようになる。エンティティ名・しきい値・時間は書式を示すための例で、しきい値はお使いのセンサーを乾いた土と湿った土で確かめた値から決めてほしい。
alias: 鉢の水分が下がったら知らせる
triggers:
- trigger: numeric_state
entity_id: sensor.monstera_soil_moisture
below: 30
for:
minutes: 30
- trigger: homeassistant
event: start
conditions:
- condition: numeric_state
entity_id: sensor.monstera_soil_moisture
below: 30
actions:
- action: notify.mobile_app_my_phone
data:
title: 水やりの時期です
message: >-
モンステラの土壌水分が {{ states('sensor.monstera_soil_moisture') }}% まで下がりました。
for を付けているのは、センサーの値がしきい値の近くで上下したときに通知が何度も届くのを防ぐためだ。for の既定値は 00:00:00 で、付けなければ下回った瞬間に発火する。30 分下回り続けたことを条件にすると、一時的なぶれは通知にならない。前の節で書いたとおり、このタイマーは再起動でリセットされ、その時点ですでに乾いていれば Numeric state トリガーは発火しない。そこで二つ目のトリガーとして、Home Assistant の起動が終わったときに動く homeassistant トリガー(event: start)を加え、条件で「今も 30 を下回っているか」を確かめてから通知する。起動の直後は ESPHome の機器がまだつながっておらず値が読めないことがあるので、取り逃しをさらに減らしたい場合は、1 時間ごとなどに動く time_pattern トリガーを同じ形で足す方法もある(その場合は乾いている間、その間隔で通知が繰り返し届く)。
自動化エディタの画面から組む場合は、トリガーの選択肢に測定対象ごとの目的別トリガーが並ぶ。Home Assistant の公式ドキュメントは、測りたい量の名前が付いたトリガーがあればそちらを使うよう案内しており、水分(moisture)用のトリガーと条件も用意されている。Numeric state は汎用のトリガーとして引き続き使えるので、YAML で書く場合は上の形で問題ない。
この段階で確かめておきたいのは次の三点だ。
- 通知が 1 回だけ届き、水をやって値が戻った後、再び乾いたときにまた 1 回届くこと
- 水をやった直後の値と、しきい値を下回るまでの日数
- 夜間や外出中に通知が来たとき、実際に水をやれたかどうか
三点目は、そのまま「ポンプが必要か」の判断材料になる。通知を見て水をやれているなら、ポンプを付けずに通知だけで運用を終えるのも十分に合理的な選択だ。
Plant Monitor で水分・照度・温度をまとめて見る

鉢が増えてきたら、Home Assistant の Plant Monitor 統合(YAML のキーは plant:)で植物ごとに測定値をまとめると管理しやすくなる。Plant Monitor は、水分・導電率・照度・温度・電池残量を 1 つの植物としてまとめて表示し、それぞれに最小値と最大値を設定できる(電池残量だけは最小値のみ)。どれかが範囲を外れると、植物の状態が problem になる。設定は configuration.yaml に書く。
plant:
monstera:
sensors:
moisture: sensor.monstera_soil_moisture
temperature: sensor.living_room_temperature
brightness: sensor.window_illuminance
min_moisture: 20
max_moisture: 60
ここで使った min_moisture: 20 と max_moisture: 60 は、Plant Monitor の既定値をそのまま書いたものだ。導電率の既定値は 500〜3000、照度の判定期間 check_days の既定値は 3 日である。これらは統合の既定値であって、特定の植物に適した値ではない。植物の種類や鉢の大きさ、センサーの校正結果に合わせて書き換えてほしい。
照度の判定には癖がある。照度は昼と夜で大きく変わるため、Plant Monitor は現在の値ではなく、過去数日間の最大値が min_brightness より低かった場合にだけ problem を報告する。冬の窓辺で「日中の最も明るい時間でも足りていない」状態を拾う仕組みなので、夜に照度が 0 になっても問題にはならない。
Plant Monitor を使うと、通知の自動化も単純になる。水分・温度・照度のしきい値を個別の自動化で見る代わりに、植物のエンティティが problem になったら知らせる、という 1 本の自動化で済む。どの項目が原因かは植物エンティティの属性に入っているので、通知文でそれを示すこともできる。後の節で扱うローカル LLM による要約は、この「まとめた状態」を入力として使うと効果が出やすい。
Plant Monitor の温度に使うセンサーが手元に無ければ、Home Assistant に統合がある市販の温湿度計を使う方法もある。
第2段階: ポンプを ESPHome のスイッチとして用意する

通知だけの運用でしきい値と乾く速さがつかめたら、ポンプ制御に進む。ここからは、ESP32 に書き込んだ ESPHome でポンプを入り切りする構成を基本にする。スマートプラグを使う構成は後の節で触れる。
ESPHome でポンプを扱う最小の設定は、GPIO スイッチだ。ESP32 の GPIO からリレーや MOSFET のモジュールを駆動し、その先に低電圧のポンプをつなぐ。ポンプに流れる電流を ESP32 の端子から直接取ることはできないので、間に必ずスイッチ用のモジュールを入れる。
switch:
- platform: gpio
pin: GPIO26
name: "Water Pump"
id: water_pump
restore_mode: ALWAYS_OFF
on_turn_on:
- delay: 20s
- switch.turn_off: water_pump
この設定には二つの安全策が入っている。
一つ目は restore_mode: ALWAYS_OFF だ。ESPHome のスイッチは、起動したときの状態を restore_mode で指定できる。ALWAYS_OFF は「起動時は常にオフ」で、ESPHome のドキュメントによればこれが既定値だ。既定値なので書かなくても同じ動作になるが、停電や再起動の後にポンプが勝手に回り出さないことを設定ファイルの上で明示するために書いておく価値がある。
二つ目は on_turn_on の中の delay と switch.turn_off だ。スイッチがオンになると、マイコン自身が一定時間後に自分でオフにする。ESPHome 公式の GPIO スイッチのページでも、on_turn_on を使って「一瞬だけピンを切り替える」スイッチを作る例が示されている(公式例の待ち時間は 500 ミリ秒)。同じ仕組みを、ポンプの最大運転時間として使う。ESPHome の delay は処理を止めずに裏で時間を数えるので、待っている間もセンサーの読み取りなど他の処理は続く。
上の 20s は書式を示すための例で、推奨値ではない。鉢の大きさ、ポンプの流量、チューブの太さで適切な時間はまったく変わる。実際には、ポンプを受け皿の上で手動で動かし、必要な水量に何秒かかるかを測ってから決めること。そのうえで最大運転時間は「1 回の水やりに必要な時間を少し上回る値」にし、Home Assistant 側の自動化がそれより短い時間で止めるようにする。こうすると、通常は Home Assistant が止め、Home Assistant が止め損ねたときだけマイコンが止める、という二重の停止になる。
ポンプを入り切りする ESPHome のノードは、小型の ESP32 ボードで足りる。ケースに収めやすいのが次のボードだ。
止まらない事態への備え — 水位センサーと実行回数の上限

最大運転時間だけでは防げない失敗がある。貯水タンクが空になった状態でポンプが回る空運転だ。水中ポンプは水中で使う前提の製品が多く、DFRobot は FIT0563 の製品ページで「このポンプは水中でのみ使用すること」と注記し、Adafruit も 3V の水中ポンプについて「常に水中に置いて呼び水をしておく必要がある」と書いている。空運転で何秒もてば壊れるかという数値はメーカーから示されていないので、「空運転をさせない」ことを前提に組む。
そのために、タンクに水位センサーを付けてポンプのオンと連動させる。最も単純なのはフロートスイッチで、水位が下がると接点が切り替わるので、ESP32 の GPIO でそのまま読める。ESPHome 公式の Cookbook には、フロートの接点が入ったらポンプのスイッチを切る構成例が載っている(ただしこの例は商用電源を開閉する Sonoff Basic を使った、ESPHome 1.10.1 時代の古い構成だ。本記事では停止の考え方だけを参考にし、配線は参考にしていない)。
低電圧のポンプ向けに同じ考え方を書くと、次のようになる。
binary_sensor:
- platform: gpio
name: "Tank Water Low"
id: tank_low
pin:
number: GPIO27
mode:
input: true
pullup: true
on_press:
- switch.turn_off: water_pump
switch:
- platform: gpio
pin: GPIO26
name: "Water Pump"
id: water_pump
restore_mode: ALWAYS_OFF
on_turn_on:
- if:
condition:
binary_sensor.is_on: tank_low
then:
- switch.turn_off: water_pump
- delay: 20s
- switch.turn_off: water_pump
フロートの接点がオンになる(水位が下がった)と、その時点でポンプを切る。加えて、ポンプがオンになった直後に水位を確かめ、すでに水位が低ければすぐに切る。この二つを入れておくと、Home Assistant から見て「水が無いのにポンプを入れた」場合でも、マイコン側で空運転を止められる。フロートの接点がどちら向きに入るかは製品と取り付け方で変わるので、inverted の要否は実物で確かめてほしい。
光学式や静電容量式の水位センサーを使う場合は、出力電圧に注意する。たとえば DFRobot の非接触水位センサー SEN0204 は動作電圧が DC 5〜24V、応答時間 500 ミリ秒、防水は IP67 だが、出力の High は電源電圧と同じになると仕様に書かれている。5V 以上で動かすと、そのままでは ESP32 の 3.3V の入力に合わない可能性があるので、つなぐ前に出力電圧を確かめ、必要ならレベル変換を入れること。
もう一つの歯止めは、一定時間内にポンプを動かせる回数の上限だ。センサーが外れて乾いた値を返し続けたり、センサーの線が切れたりすると、自動化は「乾いている」と判断して何度もポンプを動かす。GitHub で公開されている ESP32 の水やり装置(rasclatt-dot-com の ESP32-Plant-Waterer-for-ESPHome)は、Home Assistant の history_stats センサーで直近 4 時間に水やりの自動化が何回動いたかを数え、自動化が繰り返し動いて水をやりすぎるのを防ぐ条件に使っている。回数の上限は、Home Assistant 側の条件として自動化に加える。
Home Assistant 側でポンプを動かす自動化を書く

ここまでの仕組みを前提に、Home Assistant 側の自動化を書く。流れは「乾いた状態が続いた → 水位と実行回数を確かめる → ポンプを入れる → 待つ → ポンプを切る → 知らせる」だ。水位か回数のどちらかが条件を外れたときは、ポンプを動かさずに動かさなかったことを知らせる。確かめる処理を自動化の conditions ではなく actions の中の if に置いているのはこのためで、conditions に書くと、条件を外れたときには自動化が黙って終わる。
alias: 鉢が乾いたら給水する
mode: single
triggers:
- trigger: numeric_state
entity_id: sensor.monstera_soil_moisture
below: 30
for:
minutes: 30
actions:
- if:
- condition: state
entity_id: binary_sensor.tank_water_low
state: "off"
- condition: numeric_state
entity_id: sensor.pump_runs_last_4h
below: 2
then:
- action: switch.turn_on
target:
entity_id: switch.water_pump
- delay:
seconds: 15
- action: switch.turn_off
target:
entity_id: switch.water_pump
- action: notify.mobile_app_my_phone
data:
message: モンステラに給水しました。
- delay:
minutes: 20
- if:
- condition: numeric_state
entity_id: sensor.monstera_soil_moisture
below: 30
then:
- action: notify.mobile_app_my_phone
data:
title: 給水後も値が戻りません
message: >-
給水から 20 分たっても土壌水分が
{{ states('sensor.monstera_soil_moisture') }}% のままです。
センサーが土から外れていないか確かめてください。
else:
- action: notify.mobile_app_my_phone
data:
title: 給水を見送りました
message: >-
タンクの水位低下({{ states('binary_sensor.tank_water_low') }})か、
直近 4 時間の給水回数({{ states('sensor.pump_runs_last_4h') }})の上限により、
ポンプを動かしていません。
sensor.pump_runs_last_4h は、前の節で書いた history_stats で実行回数を数えるセンサーだ。configuration.yaml に次のように書くと、直近 4 時間にポンプのスイッチが「オン」の状態にあった回数を数えるセンサーができる。
sensor:
- platform: history_stats
name: pump_runs_last_4h
entity_id: switch.water_pump
state: "on"
type: count
end: "{{ now() }}"
duration:
hours: 4
history_stats は start・end・duration のうち 2 つを指定する決まりで、ここでは end と duration で「今から 4 時間前まで」を表している。type: count は、期間内に対象のエンティティが指定した状態にあった回数を数える。公式ドキュメントは、これが「オンにされた回数(状態の遷移)」とは違い、期間の始まりの時点ですでにオンだった場合もその 1 回として数えると注記している。ポンプが 4 時間前の境目をまたいで回っていた場合などに 1 回多く数えることがあるが、上限として使う分には給水を止める側にずれるだけだ。公式ドキュメントによれば、このセンサーは元のエンティティが変化したとき、変化がなければ 1 分ごとに更新される。
switch.water_pump や binary_sensor.tank_water_low は説明用の ID だ。ESPHome の機器から Home Assistant に登録されたエンティティの実際の ID は、エンティティの一覧で確かめて置き換えてほしい。ここでも数値はすべて例である。Home Assistant 側の待ち時間(例では 15 秒)は、マイコン側の最大運転時間(例では 20 秒)より短くしておく。
給水の後に 20 分待って値を確かめているのは、センサーが土から外れた場合に備えるためだ。外れたセンサーは乾いた値を返し続けるが、Numeric state トリガーは同じ側にとどまる間は再発火しないので、この自動化は 1 回給水したきり動かなくなり、実行回数の上限にも届かない。給水しても値が戻らないことを知らせる処理がなければ、その後の異常に気づけない。20 分という待ち時間も例で、水が土に広がって値が変わるまでの時間を通知だけの段階で測ってから決めるとよい。この後半の待ちも再起動で失われるが、失われるのは確認の通知だけで、ポンプはすでに止まっている。
この自動化で Home Assistant が再起動した場合を考えてみる。delay の途中で再起動すると、この自動化の実行は中断され、switch.turn_off は実行されない。それでもマイコン側の delay は ESP32 の中で数え続けているので、最大運転時間でポンプは止まる。Wi-Fi が切れて Home Assistant の「切れ」の命令が届かない場合も同じだ。逆に、ESP32 が停電などで再起動した場合は、ESPHome が動き出した時点で restore_mode: ALWAYS_OFF によってオフになる。
ただし、この二重の停止が効くのは ESP32 の上で ESPHome が正常に動いている間に限られる。ESPHome の GPIO スイッチのページは、リセットの直後、ESPHome のコードが動き出す前には GPIO のプルアップが有効になっていることがあり、ESPHome が切る前にリレーが入りうると注意している。ALWAYS_OFF は起動した後の初期状態を決める設定で、起動前の端子の状態までは決めない。ESP32 が固まったり電源が落ちたりしたときも、マイコン側の delay は動かない。
この二つは分けて考える。ESP32 の電源が落ちた場合は GPIO の出力もなくなるので、ポンプが止まるかどうかは、モジュールの入力回路のプルアップ・プルダウンや、リレー接点の配線で決まる。一方、ESP32 が電源の入ったまま固まった場合は、GPIO が最後に設定された出力レベルのまま残りうる。オンの出力が残れば、モジュールの選び方だけではポンプを止められない。
なお、ESPHome の inverted は信号の向きを設定に合わせるためのもので、公式の GPIO スイッチのページにも、Low でオンになるスイッチを inverted: true で設定する例がある。inverted を使うかどうかでは安全かどうかを判断できない。使うモジュールの入力の極性と配線を確かめ、組み上げたら、ポンプ側の電源を入れたまま ESP32 の電源だけを抜いてポンプが止まることと、ESP32 の電源を戻したときにポンプが入らないことを確かめる。この試験で分かるのは電源が落ちたときと起動したときの動きで、ESP32 が固まったときの停止は、この構成では保証しない。止まらなかった場合に備え、タンクの水量を受け皿からあふれない量にするなど、被害を小さくする工夫を併用してほしい。
土壌水分が戻るまで待ってから止めたい場合は、delay の代わりに wait_for_trigger や wait_template を使い、timeout を付ける方法もある。Home Assistant のスクリプトの仕様では、待ちに timeout を付けると、条件が満たされなくても一定時間後に次の処理へ進む。ただし continue_on_timeout: false を付けると、タイムアウトした時点でスクリプト自体が打ち切られる。このとき後ろに書いた switch.turn_off も実行されないので、ポンプを止める用途では付けてはいけない。センサーの値は水が土に広がるまで遅れて変わるため、実際には固定時間で止めてしばらく様子を見るほうが扱いやすいはずだ。
市販のスマートプラグで組む場合は、USB ポンプを USB 電源アダプターにつなぎ、そのアダプターをスマートプラグに挿して入り切りする。Home Assistant の TP-Link Smart Home 統合は、Tapo のプラグ P100・P105・P110・P110M・P115・P125M・P135・TP15 に対応し、電源タップの P300 なども対応機種に入っている(Tapo は TP-Link アカウントの認証情報が必要だ)。プラグ側で時間を数える仕組みは機種によって違う。たとえば Tapo P110M は TP-Link の製品ページに「自動オフタイマー」があり、「プラグ側で給電時間を指定することができ、一定時間経過後に給電が止まる」と書かれている。P105 の販売ページにはカウントダウンの「タイマー設定」がある。Home Assistant の TP-Link Smart Home 統合も、機器が対応していれば auto-on/off などの設定を操作できるとしている。
ただし、Wi-Fi やクラウドとの接続が切れた状態でもこの自動オフが働くかは、メーカーの資料で確認できなかった。スマートプラグで組むなら、自動オフを Tapo アプリか統合の設定で有効にしたうえで、給水中に Home Assistant を止めたり、ルーターからプラグを切り離したりして、実際に止まるかを確かめてほしい。あわせて、ポンプの吐出量を少なく抑え、受け皿からあふれない量を上限にするなど、止まらなかった場合の被害を小さくする工夫も要る。
ローカル LLM に植物の状態を要約させて通知文を作る

鉢が 3 つ、4 つと増えると、通知の文面が数字の羅列になる。水分・照度・温度の値が鉢の数だけ並んでも、どれから手を付ければよいかは読む側が考えなければならない。ここで LLM に状態を渡し、「今日やるべきこと」を短い文にまとめさせると、通知が読みやすくなる。家のセンサーの値を外部のサービスに送らずに済ませたいなら、ローカルで動く LLM を使う。ローカル LLM を置く理由と、手元の GPU でどこまでの仕事ができるかは、クラウドAIの請求書を見てローカルAIを考え直す — 手元のGPUで回る仕事と回らない仕事(2026-08-24 公開)で整理している。
Home Assistant には、ローカル LLM とつなぐ統合がいくつかある。
- llama.cpp 統合: 2026.8(2026-08-05 公開)で新たに追加された。ローカルの llama.cpp サーバー、または OpenAI 互換のエンドポイントを、Home Assistant の会話エージェントとして使える。ただし、この統合が提供するのは会話エージェントのみだ。なお llama.cpp 統合のドキュメントは、Ollama を使っているなら公式の Ollama 統合を使うよう案内している
- Ollama 統合: 2024.4 から存在する統合で、Ollama のサーバーは macOS・Linux・Windows で動く。ローカル LLM に家の機器を操作させる場合、公式ドキュメントは公開するエンティティを 25 個未満にするよう推奨しており、機器を操作できるのはツール呼び出しに対応したモデルだけだ
- LiteLLM 統合: llama.cpp 統合と同じ 2026.8 で追加され、多数のモデル提供元の前に OpenAI 互換の API を 1 つ置く形で使う
状態の要約を通知文にするには、Home Assistant の AI Task を使う。AI Task は単体で追加する統合ではなく、他の統合が提供する部品だ。ai_task.generate_data アクションに指示を渡すと、AI Task のエンティティが自由文または構造化データを生成し、その結果を通知などに使える。
actions:
- action: ai_task.generate_data
continue_on_error: true
data:
task_name: plant status summary
entity_id: ai_task.local_llm
instructions: >-
次の植物の状態を読み、今日やるべき手入れを日本語2文以内で書いてください。
数値は書き換えずにそのまま使ってください。
モンステラ: {{ states('plant.monstera') }}、
土壌水分 {{ states('sensor.monstera_soil_moisture') }}%
response_variable: summary
- if:
- condition: template
value_template: "{{ summary is defined and summary.data is defined }}"
then:
- action: notify.mobile_app_my_phone
data:
title: 植物の状態
message: >-
{{ summary.data }}(土壌水分 {{ states('sensor.monstera_soil_moisture') }}%)
else:
- action: notify.mobile_app_my_phone
data:
title: 植物の状態(要約なし)
message: >-
モンステラ: {{ states('plant.monstera') }}、
土壌水分 {{ states('sensor.monstera_soil_moisture') }}%
生成された文章は response_variable で受け取り、その data フィールドに入る。Home Assistant のスクリプトは、途中の処理がエラーになると既定でそこから先を実行しない。LLM のサーバーが止まっているときに通知そのものが消えないよう、ai_task.generate_data に continue_on_error: true を付け、要約が受け取れなかったときは数値だけの通知を送る分岐にしている。公式ドキュメントは、continue_on_error でも設定の誤りや Home Assistant が扱わないエラーは無視されないと注記しているので、この分岐が実際に働くかは後の確認表の手順で確かめてほしい。entity_id に指定する AI Task のエンティティは、LLM の統合が提供しているものを使う。ここで注意が要るのは、llama.cpp 統合は AI Task のエンティティを提供していないことだ。llama.cpp 統合だけを入れた状態では、この ai_task.generate_data の宛先がない。ローカルで AI Task のエンティティを用意する経路としては、Ollama 統合がある。Home Assistant 2026.9.4 の Ollama 統合のソースには AI Task の実装(ai_task.py)があり、統合の設定画面に「Add AI task」の項目を出す定義も入っている。統合のドキュメント本文にはまだ AI Task の記載がないため、Ollama のサーバーを登録した後、統合の画面で AI Task を追加でき、ai_task. で始まるエンティティが一覧に現れることを確かめてから、その ID を上の entity_id に書いてほしい。当サイトはこの構成も実機では動かしていない。
手元のパソコンでローカル LLM を動かすところから始めるなら、自前の生成 AI アプリを作る手順をまとめた入門書が参考になる。
LLM に任せるのは要約まで — ポンプを動かす判断は自動化に残す

ローカル LLM を会話エージェントとして使えば、「モンステラに水をやって」と話しかけてポンプを動かすこともできる。しかし本記事では、LLM に任せるのは状態の要約と通知文の作成までにし、ポンプの入り切りは通常の自動化で行う構成を勧める。
理由は、ポンプの操作に求められる性質と LLM の出力の性質が合わないからだ。ポンプを動かす判断は、同じ入力に対して毎回同じ結果を返し、条件を満たさないときには確実に動かないことが求められる。前の節までに書いた水位の確認、実行回数の上限、最大運転時間は、どれもその性質を保つための仕組みだ。LLM の出力は同じ入力でも変わりうるうえ、ツール呼び出しで機器を操作させると、その呼び出しが正しいかを確かめる責任は呼び出す側に残る。ローカル LLM のツール呼び出しで実行の責任をどこに置くかは、ローカルLLMのツール呼び出しを実務に繋ぐ — OpenAI互換APIとMCPの使いどころ(2026-08-26 公開)で詳しく扱っている。
要約に限れば、LLM が誤っても被害は通知の文面にとどまる。それでも、数値の書き換えや、存在しない問題を書き足すことはありうる。上の指示文で「数値は書き換えずにそのまま使ってください」と書いたのはそのためで、通知には LLM の要約だけでなく、元のセンサー値も並べて載せておくと、要約が実際の値と合っているかを読む側で確かめられる。上の例で要約の後ろに土壌水分の値を付け、要約に失敗したら数値だけを送る分岐を入れているのは、この二つのためだ。
ポンプ・水位センサー・スマートプラグの選び方

最後に、低電圧で組む前提で部品の選び方を整理する。仕様の数値は各メーカーの製品ページの記載だ。部品構成の実例としては、GitHub で公開されている LukasK13 の ESP-8266-Plant-Watering-V3 が、流量計・水位センサー・静電容量式の土壌センサーと 12V のポンプを組み合わせており、配線の参考になる。
| 部品 | 例 | 仕様(メーカー記載) | 向いている構成 |
|---|---|---|---|
| 水中ポンプ(小型) | DFRobot FIT0800 | DC 3〜6V、150〜370mA、揚程 25〜45cm、流量 80〜100L/H | 5V 系で ESP32 からリレー経由で制御 |
| 水中ポンプ(中型) | DFRobot FIT0563 | DC 6〜18V、65〜500mA、揚程 60〜420cm、流量 280〜500L/H | 12V 電源で複数の鉢に配る構成 |
| 水中ポンプ(最小) | Adafruit 4546(横型) | 3V・100mA | 試作。メーカーは長期設置を推奨していない |
| センサー+ポンプ一体 | M5Stack Unit Watering(U101) | 静電容量式の測定板、5W のポンプ | 配線を減らしたい場合 |
| 水位センサー | DFRobot SEN0204 | DC 5〜24V、応答 500ms、IP67 | 非接触でタンクの外から水位を見る |
| スマートプラグ | Tapo P105・P110M | TP-Link Smart Home 統合の対応機種 | USB ポンプの電源アダプターを入り切り |
ポンプを選ぶときに見落としやすいのは、流量が鉢には多すぎることだ。FIT0563 の流量はメーカーの公称値で 1 時間あたり 280〜500L で、鉢植え 1〜2 個に使うには余裕がありすぎる。流量の大きいポンプを使う場合は、運転時間を短くし、チューブを細くして調整する。Adafruit の 3V ポンプは安価で試作に向くが、メーカー自身が長期の設置には勧めないと書いているので、消耗品として扱い、予備を持っておくのが現実的だ。
なお、FIT0563 は国内の販売ページ(スイッチサイエンス)では「6~12V」「550L/H」と表記されており、上の表のメーカー公称値(6〜18V、280〜500L/H)と一致しない。どちらの仕様の製品が届くかは確認できなかったので、購入する場合は販売店に仕様と改訂を問い合わせてから使う電源を決めてほしい。
ESP32 からポンプを入り切りするスイッチには、M5Stack のミニリレーユニット(最大 3A・24V DC)のような低電圧向けのモジュールが使える。販売ページに AC の定格が併記されている製品もあるが、本記事の構成では AC の開閉には使わない。
複数の鉢や系統を順番に給水したくなったら、ESPHome の Sprinkler Controller コンポーネントがある。弁ごとに run_duration(運転時間)を持ち、ポンプや元弁もまとめて扱える、庭の散水コントローラーに近い仕組みだ。鉢植え 1〜2 個には大がかりだが、系統が増えたときの選択肢として覚えておくとよいだろう。
USB ポンプの電源アダプターを入り切りするなら、Home Assistant の TP-Link Smart Home 統合で扱える Tapo のスマートプラグが使える。自動オフの設定と、通信が切れたときに止まるかは本文の手順で確かめてほしい。
組み上げる前に確かめる項目

ポンプ制御を有効にする前に、次の項目を一つずつ確かめてほしい。どれも、水浸しの床を見てから気づくのでは遅い項目だ。
| 確かめること | 期待する動き | 確かめ方 |
|---|---|---|
| Home Assistant の再起動 | 給水中に再起動しても、マイコン側の最大運転時間でポンプが止まる | タンクを受け皿の上に置き、給水中に Home Assistant を再起動する |
| Wi-Fi の切断 | 命令が届かなくても、マイコン側で止まる | 給水中にルーターから ESP32 を切り離す |
| マイコンの電源断 | ESP32 の電源が切れた時点でポンプが止まる | ポンプ側の電源は入れたまま、給水中に ESP32 の電源だけを抜く |
| マイコンの再起動 | 電源を戻した後、ポンプがオフのまま(起動の瞬間にリレーが一度入らないかも見る) | 抜いた ESP32 の電源を挿し直す |
| タンクが空 | ポンプが入らない、または入ってもすぐ切れる。Home Assistant からは「給水を見送りました」の通知が届く | タンクの水を抜いた状態で自動化を動かす |
| センサーの外れ | 給水は 1 回で止まり、「給水後も値が戻りません」の通知が届く | センサーを土から抜いて乾いた値にする |
| 実行回数の上限 | 直近 4 時間に 2 回を超えて給水せず、「給水を見送りました」の通知が届く | 試験の間だけ for と給水後の 20 分の待ちを短くする。mode: single のため、実行中に値が動いても新しい実行は始まらないので、1 回の実行が終わってからセンサーを抜き差しして値をしきい値の上下に動かす。毎回 sensor.pump_runs_last_4h が増えたことを確かめてから次に進む |
| LLM サーバーの停止 | 数値だけの通知が届く | LLM のサーバーを止めた状態で自動化を動かす |
確かめるときは、ポンプの出口を鉢ではなくバケツや受け皿に向け、水があふれても困らない場所で行う。特に最初の 4 項目は、Home Assistant の停止、通信の切断、マイコンの電源断と再起動のそれぞれでポンプが入ったまま残らないことを確かめる項目だ。この構成が止められるのは、ESPHome が動いている間はマイコン側の最大運転時間、ESP32 の電源が落ちたときは使う回路でオフになることを確かめた場合、という条件つきの範囲だ。ESP32 が電源の入ったまま固まったときの停止は保証しない。ソフトウェアの設定だけですべてを保証するものではない。1 つでも期待どおりに動かなければ、ポンプ制御を有効にせず、通知だけの運用に戻すべきだ。
まとめ — 通知で観察し、止める仕組みを二重にしてからポンプを動かす

Home Assistant で水やりを自動化するときの要点は、次の四つだ。
- 通知から始める: Numeric state トリガーと
forで「乾いた状態が続いたら 1 回知らせる」自動化を作り、しきい値と乾く速さを観察する。通知だけで足りるなら、そこで止めてよい - 停止をマイコンにも持たせる: Home Assistant の
forやdelayは再起動・再読み込みで失われる。ESPHome のon_turn_onに最大運転時間を書き、restore_mode: ALWAYS_OFFで起動時はオフにする。ESP32 の電源が落ちたときに使う回路でポンプが止まることを確かめる(ESP32 が固まったときの停止は保証しない) - 空運転と繰り返しを防ぐ: 水位センサーでポンプを止め、Home Assistant 側では一定時間内の実行回数に上限を設け、給水を見送ったときと給水後に値が戻らないときに知らせる
- LLM は要約だけにする: ローカル LLM で状態を読みやすい通知文にまとめるのは有効だが、ポンプの入り切りは通常の自動化に残す。llama.cpp 統合は会話エージェントのみで AI Task を提供しない点に注意する
最初の一歩は、手元の土壌水分センサーに通知の自動化を 1 本付けることだ。しばらくの間の値の動きが記録に残っていれば、ポンプの運転時間もしきい値も、推測ではなく記録から決められる。
参照
- Numeric state trigger — Home Assistant
- Automation triggers — Home Assistant
- Script syntax — Home Assistant
- History Stats — Home Assistant
- Installation — Home Assistant
- Plant Monitor — Home Assistant
- 2026.8: Approachable by design — Home Assistant
- llama.cpp — Home Assistant
- Ollama — Home Assistant
- AI Task — Home Assistant
- AI Task: Generate data — Home Assistant
- TP-Link Smart Home — Home Assistant
- Notifications Introduction — Home Assistant Companion Docs
- GPIO Switch — ESPHome
- Switch Component — ESPHome
- Actions and Conditions — ESPHome
- Sprinkler Controller — ESPHome
- Sonoff Fish Pond Pump — ESPHome Cookbook
- ESP32-Plant-Waterer-for-ESPHome — rasclatt-dot-com(GitHub)
- ESP-8266-Plant-Watering-V3 — LukasK13(GitHub)
- Watering my house plants with ESPHome — Home Assistant Community
- Amphibious Horizontal Submersible Pump FIT0800 — DFRobot
- DC Mini Immersible Water Pump FIT0563 — DFRobot
- Submersible 3V DC Water Pump – Horizontal Type — Adafruit
- Watering Unit with Moisture Sensor and Pump — M5Stack
- Non-contact Digital Liquid Level Sensor SEN0204 — DFRobot
- M5Stack用ミニリレーユニット — スイッチサイエンス


