この世界にもう十分いるのは?「いつかやる」と語り続ける人たちだ。完璧なタイミング、完璧な環境、完璧な何かを待ちながら、何もしないで座っている夢見る人たち。その間にも人生は刻々と過ぎていく。
「幸福とはなんと素朴で質素なものだろう:ワイン一杯、焼き栗ひとつ、みすぼらしい小さな火鉢、波の音。それだけだ。」 ニコス・カザンザキス『その男ゾルバ』
ゾルバは待たなかった。ゾルバは踊った。ゾルバは見事に失敗して、それを笑い飛ばした。壮大な採掘事業が崩壊した時、文字通り崩壊した時、彼はワインのボトルを掴んで浜辺で踊り始めた。何もしないで座っているより、ゾルバのように失敗する方がいい。
今日、息子と僕は実行に移す。計画はできた。ハードウェアは準備万端。ほとんどは個別にテスト済みで、オートメーションは動き、センサーは検知し、コードはコンパイルできる。あとは全部が一緒に動くかどうかだ。何か問題が起きるか?おそらく。課題に対する準備はできてるか?もちろん。それが楽しいところだ。
計画なくして道はない。 ただ自分の声を聞きたいだけの人々。ただの夢。これは夢じゃない。これは実行計画書だ。
ミッション
今夜バーベキューで夕食を焼く頃には、この家は:
- 入った部屋の照明が点灯し、出ると背後でフェードアウトする
- ベッドが就寝を感知するとすべてのドアをロックする
- (また)閉め忘れたガレージを自動で閉める
- 実際に使われている部屋に基づいて空調を調整する
- 外部から同じセンシング技術を使われないようWiFiノイズを生成する
そしてAmazonには一切知られない。すべてローカルで動く。クラウドなし。サブスクなし。データ収集なし。
武器庫(配備済み)
頭脳:Raspberry Pi 5 - 準備完了
こいつは2週間前からデスクの上に座って、完全設定済みで、今日を待っていた。基本的なホームオートメーションにPi 5はオーバースペック。僕はオーバースペックが好きだ。Raspberry Pi OS Liteが動き、Dockerがインストールされ、Portainerが稼働中。あとは設置場所に繋ぐだけだ。
Argon ONE V3 M.2 NVME PCIE ケースバンドルを選んだ。組み立て済み:
- M.2 SSDにOSをフラッシュ済み(SDカード故障とはおさらば)
- Docker + Portainerインストール・テスト済み
- Home Assistantコンテナのデプロイ準備完了
- ネットワーク上に静的IP設定済み
飛行前チェックリスト - 完了
- ☑ Raspberry Pi OS LiteをSSDにフラッシュ済み
- ☑ SSH有効化、認証情報設定済み
- ☑ 静的IPでネットワーク設定済み
- ☑ Docker + Portainer稼働中
- ☑ Home Assistant設定ファイル準備済み
センサー:ESP32ボード - フラッシュ・テスト済み
この小さなESP32ボードが一番楽しい部分だった。先週末、息子と一緒にフラッシュして、WiFi信号データが流れてくるのを見ていた。動作確認済み。
- WiFiセンシングユニット - WiFi信号の乱れを測定して動きを検知する。リビングルームを歩き回ってテスト済み。壁越しの動きも検知でき、範囲は約4.5~6メートルだ。
- WiFiフォグユニット - 外部のWiFiセンシングを妨害するノイズを生成する。隔離環境で稼働させ、信号空間に見事なカオスを作り出している。
今日はこれらをHome Assistantに統合して、オートメーションが正しく発動するか確認する。テスト環境ではコードは動く。問題は:全部を接続した時に動くかどうか?
(なぜこれが重要なのか、背景を知りたければWiFiセンシングとWiFi対策の記事を読んでほしい。)
既存インフラ - 設置済み
ゼロからのスタートではない。家にはすでにスマートデバイスがある。ただ別々のアプリで動いていて、バラバラの離島みたいな状態だ。今日、王国を統一する:
- Philips Hue電球 - 家中に設置済み。現在はHueアプリで制御中。今日:Home Assistantが引き継ぐ。
- Ecobeeサーモスタット - センサーでどの部屋に人がいるか把握済み。今日:そのデータを統合する。
- Eight Sleepベッド - 僕がいつ寝ているか追跡済み。今日:ロックダウンオートメーションのトリガーになる。
- Kwiksetロック(Z-Wave) - ドアに設置済み。今日:自動ロックを覚えさせる。
- MyQガレージ - 設置済み。今日:閉め忘れて家に戻ることはもうない。
ポイント: 思っている以上にスマートホーム機器が既にあるかもしれない。ただまだお互いに連携していないだけだ。
フェーズ1:インフラ(完了)
これは先週末の作業だ。後から追いかける人のために、やったことを記しておく。Dockerの記事を読んだなら、なぜすべてをコンテナ化したか分かるだろう。
bash# Docker + Portainer - Already running
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
docker volume create portainer_data
docker run -d -p 9000:9000 --name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-cePortainerはhttp://raspberrypi.local:9000で稼働中。コンテナ管理用の美しいGUI。確認済み。
フェーズ2:Home Assistant(今日の最初のタスク)
docker-composeファイルは書いた。設定ディレクトリは準備済み。今日はこれを本番で起動して、デバイスを接続していく。
yaml# docker-compose.yml - ready to deploy
version: '3'
services:
homeassistant:
container_name: homeassistant
image: ghcr.io/home-assistant/home-assistant:stable
volumes:
- /home/pi/homeassistant:/config
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
privileged: true
network_mode: host計画: docker-compose up -dを実行し、セットアップウィザードを開き、これらの連携を一つずつ接続する:
- Philips Hue - ネットワーク上で自動検出されるはず
- Ecobee - OAuthフロー、アプリを手元に準備
- Eight Sleep - API連携、認証情報準備済み
- Z-Wave - これはスパイシーになるかも、ロックは気まぐれだ
- MyQ - 簡単、前にやったことがある
- ESPHome - 先週末フラッシュしたESP32デバイス用
予想される課題: Z-Wave。ロックはいつも態度がでかい。見てみよう。
フェーズ3:WiFiセンシング統合(今日の楽しいパート)
センシングユニット - 接続準備完了
先週末、息子がシリアルモニターを見ている時、こいつがリビングルームを歩く僕を検知した。息子の正確な言葉:「パパ、これ不気味でカッコいい。」
ESP32にはすでにESPHomeがフラッシュ済み。WiFi CSI(チャネル状態情報)による動体検知も動作中。今日はこれをHome Assistantに接続して名前をつける:binary_sensor.living_room_occupied
テスト: リビングルームに入る。Home Assistantがそれを検知するか?検知できれば、本番だ。
フォグユニット - プライバシーレイヤー準備完了
2台目のESP32は対策記事のノイズジェネレーターを動かしている。1週間ベンチで稼働させ、WiFiスペクトラムに見事なカオスを生み出している。
そう、自分たちのオートメーションにはWiFiセンシングを使いながら、同時に他人が同じことをするのを防いでいる。偽善じゃない。これは運用セキュリティだ。そして息子はこれが最高にクールだと思っている。
将来の拡張:3+3
今日の目標は、センサー1台とフォグデバイス1台でコンセプトを実証すること。確信が持てたら:
- センシングデバイス3台: リビング、キッチン、寝室
- フォグデバイス3台: 家全体をカバーするよう分散配置
ESP32ボード約50ドルで家全体をアップグレードできる。でもまず、今日うまくいくか確認しよう。
フェーズ4:オートメーション(本当の目的)
すべてはここに向かって積み上げてきた。これらのYAMLファイルは書き上げ、頭の中で百回テストし、ペーストする準備ができている。一発で動くか?やってみよう。
オートメーション1:フォローミーライティング(目玉機能)
ビジョン: 部屋に入ると、照明が迎えるように灯る。出ると、礼儀正しい執事のように背後でフェードする。トニー・スタークの家。それが目標だ。
ニュアンス: 手動でライトを点けた場合、システムはそのままにする。あなたの選択は尊重される。input_booleanヘルパーでこれを追跡する。自動化と闘うほど最悪なものはないからだ。
yaml# configuration.yaml additions
input_text:
last_occupied_room:
name: "Last Occupied Room"
initial: "none"
input_boolean:
living_room_auto_triggered:
name: "Living Room Auto Triggered"
kitchen_auto_triggered:
name: "Kitchen Auto Triggered"
bedroom_auto_triggered:
name: "Bedroom Auto Triggered"次にオートメーション:
yaml# automations.yaml
- alias: "Follow Me - Living Room Entry"
trigger:
- platform: state
entity_id: binary_sensor.living_room_occupied
to: "on"
condition:
- condition: state
entity_id: light.living_room
state: "off"
action:
# Dim the previous room if it was auto-triggered
- choose:
- conditions:
- condition: template
value_template: "{{ states('input_text.last_occupied_room') == 'kitchen' }}"
- condition: state
entity_id: input_boolean.kitchen_auto_triggered
state: "on"
sequence:
- service: light.turn_on
target:
entity_id: light.kitchen
data:
brightness_pct: 20
transition: 3
# Turn on current room
- service: light.turn_on
target:
entity_id: light.living_room
data:
brightness_pct: 100
- service: input_boolean.turn_on
target:
entity_id: input_boolean.living_room_auto_triggered
- service: input_text.set_value
target:
entity_id: input_text.last_occupied_room
data:
value: "living_room"
- alias: "Follow Me - Living Room Vacancy"
trigger:
- platform: state
entity_id: binary_sensor.living_room_occupied
to: "off"
for:
minutes: 2
condition:
- condition: state
entity_id: input_boolean.living_room_auto_triggered
state: "on"
action:
- service: light.turn_off
target:
entity_id: light.living_room
data:
transition: 5
- service: input_boolean.turn_off
target:
entity_id: input_boolean.living_room_auto_triggeredテスト: デプロイしたら、息子と一緒に家の中を歩いて、照明がついてくるか確認する。うまくいけば映画の中にいるみたいな気分になる。ダメなら、ピザを食べながらデバッグだ。
オートメーション2:就寝ロックダウン(安心感)
シナリオ: 夜10時。ベッドに入る。5分後、Eight Sleepが実際に寝ていることを確認する(ただ横になってスクロールしているのではなく)。家が応答する:すべてのドアがロックされ、閉め忘れたガレージが閉まり(また)、サーモスタットがスリープモードに切り替わり、自動で点いたライトがフェードアウトする。
yaml- alias: "Bedtime - Eight Sleep Triggered Lockdown"
trigger:
- platform: state
entity_id: binary_sensor.eight_sleep_bed_presence
to: "on"
for:
minutes: 5
condition:
- condition: time
after: "21:00:00"
before: "06:00:00"
action:
# Lock all doors
- service: lock.lock
target:
entity_id:
- lock.front_door
- lock.back_door
# Close garage if open
- service: cover.close_cover
target:
entity_id: cover.garage_door
# Set Ecobee to sleep mode
- service: climate.set_preset_mode
target:
entity_id: climate.ecobee
data:
preset_mode: "Sleep"
# Turn off auto-triggered lights
- service: light.turn_off
target:
entity_id:
- light.living_room
- light.kitchen
data:
transition: 5Eight Sleepを持っていない? 時間ベースのトリガー(22:30)やスマホの充電検知で代用できる。ロジックは同じだ。
オートメーション3:ガレージ自動閉鎖(夫婦の救世主)
問題:「ガレージ閉めた?」。この家で週3回聞かれる質問。もう終わり。10分間開いていたら自動で閉まって、通知が届く。
yaml- alias: "Garage - Auto Close After 10 Minutes"
trigger:
- platform: state
entity_id: cover.garage_door
to: "open"
for:
minutes: 10
action:
- service: cover.close_cover
target:
entity_id: cover.garage_door
- service: notify.mobile_app_your_phone
data:
title: "Garage Secured"
message: "Garage was open for 10 minutes. Auto-closed."
data:
tag: "garage-closed"オートメーション4:スマート空調(省エネ)
ロジック: 空の家を暖房する意味は?WiFiセンサーが30分間誰もいないと言えば、Ecobeeが外出モードに切り替わる。誰かが帰ってきたら、復帰する。
yaml- alias: "Ecobee - Away When House Empty"
trigger:
- platform: state
entity_id: binary_sensor.home_occupied
to: "off"
for:
minutes: 30
action:
- service: climate.set_preset_mode
target:
entity_id: climate.ecobee
data:
preset_mode: "Away"
- alias: "Ecobee - Home When Occupied"
trigger:
- platform: state
entity_id: binary_sensor.home_occupied
to: "on"
condition:
- condition: state
entity_id: climate.ecobee
attribute: preset_mode
state: "Away"
action:
- service: climate.set_preset_mode
target:
entity_id: climate.ecobee
data:
preset_mode: "Home"統合センサーの作成
binary_sensor.home_occupiedは全部屋のセンサーを統合するテンプレートセンサーだ:
yamltemplate:
- binary_sensor:
- name: "Home Occupied"
state: >
{{ is_state('binary_sensor.living_room_occupied', 'on')
or is_state('binary_sensor.kitchen_occupied', 'on')
or is_state('binary_sensor.bedroom_occupied', 'on') }}何がうまくいかないか?(楽しいパート)
こういうことだ:今日、何かは必ずうまくいかない。悲観じゃない。現実だ。それでいい。それが核心だ。
今日の冒険で起きそうなこと:
- Z-Waveロック - こいつらは態度がでかい。ペアリングに何度か試行が必要かもしれない。
- WiFiセンサーのキャリブレーション - ベンチでは動くが、設置場所ではどうか?
- オートメーションのエッジケース - 2秒で部屋を通り過ぎたらどうなる?
- 「昨日は動いてた」問題 - テクノロジーのお気に入りのジョーク。
だからこそ一緒にやるんだ。父と息子で、トラブルシューティングして、学んで、YAMLがパースできない理由でおそらく言い合う。これが本当の学び方だ。実際に何かを作って、壊れるのを見て、直す。
ゾルバの鉱山は崩壊した。彼の反応は?浜辺で踊ること。今日何が壊れても、なんとかする。なんとかならなくても、夕食のいいネタになる。
哲学
実行する人と夢見る人を分けるのはここだ:
夢見る人は何ヶ月もリサーチする。すべての記事を読む。「正しい」ハードウェアを待つ。完璧になるまで計画を最適化する。永遠に始めない。
実行する人は計画を書き、必要なものを集め、実行する。課題を予想する。臨機応変に対応する。前に向かって失敗する。
計画なくして道はない。自分の声を聞きたいだけの人々がいるだけだ。でも実行のない計画は、ステップが多い夢でしかない。
今日の成功基準
- ☐ 全デバイス接続済みのHome Assistantが稼働
- ☐ WiFiセンサーがリビングの動きを検知
- ☐ フォローミーライティングが少なくとも1部屋で動作
- ☐ 就寝ロックダウンオートメーションが有効
- ☐ 息子が「トニー・スタークの家みたいだ」と言う
次のステップ(今日が成功したら)
成功すると仮定して。そしてきっと成功する。予想より時間がかかっても:
- ESP32フル3+3デプロイ - 主要な部屋すべてにセンシング、フォグカバレッジを全体に
- 壁掛けタブレットダッシュボード - 廊下の常時オンコントロールパネル
- ローカル音声制御 - Wyoming/Piperで家から出ない音声コマンド
- 漏水センサー - すべてのシンク下と給湯器の近くに
でもまず:今日。まず:実行。まず:この計画が本当に機能するか証明すること。
「人生とは、他の計画を立てるのに忙しい間に起きるものだ。」ジョン・レノン
違う。人生は、計画をやめて行動を始めた時に起きるものだ。向こう側で会おう。 さあ、何かを作りに行こう。