家じゅうの機器を、1台のマシンから叩けるコマンドで動かしています。照明も、電動シャッターも、エアコンも、電力の実測値も。市販の統合ソフトは使っていません。プロトコルごとに専用のCLIを自作し、その上に統合レイヤを重ねて、家全体を1つのシステムとして扱えるようにしています。

この記事は、その全体像をまとめたハブです。個々のツールの深掘りは別記事に譲り、ここでは「何が」「どの層で」「どうつながっているか」を一望できるようにします。同じようにスマートホームを自前で組みたい人が、構成の見取り図として使えることを狙っています。

前提:なぜ市販の統合ソフトではないのか

スマートホーム前提で家を建て、最初は Home Assistant(HA)を「家のOS」に選びました。ベンダー非依存でMatterもECHONET Liteも一括で扱える、デファクトだったからです。しかし新居で構成が大きくなると、グループ照明が毎回きれいに動かない、状態が素直に取れない、何が起きているのか分からない——といった問題にぶつかりました。

そこで方針を変え、UNIX哲学に沿った軽量ツールを自作する道に切り替えました。その経緯は別記事にまとめてあるので、ここでは繰り返しません。

この記事で押さえておきたいのは、その結果として全ツールが共有している設計方針だけです。

  • 1ツール1仕事 — 1つのプロトコル、1つの関心事に絞る
  • stateless / one-shot — 常駐しない。開いて、送って、待って、終わる
  • stdoutは純粋なJSONのみ — 診断ログやエラーはstderrへ。そのまま jq やLLMのfunction callingに流せる
  • 最小依存・composable — スケジューリングや横断は外側(cronや、ワークフローエンジンのdagu)に委ねる

この方針が、以下すべてのツールに一貫して現れます。

全体アーキテクチャ

家を動かしている自作Rust製ツールは6本です。役割で層に分けると、こうなります。

                 [ 人 ]              [ AI ]
                   │                   │
              mando (Web UI)      CLIを直接たたく
                   │                   │
                   └─────────┬─────────┘

          ┌─────────────────────────────────────┐
          │        casa (統合CLI / 横断UX)          │  ← オーケストレーション層
          └─────────────────────────────────────┘
              │         │         │         │
           ┌─────┐   ┌─────┐   ┌─────┐   ┌─────┐
           │ enl │   │ mat │   │ ais │   │ swb │    ← プロトコルCLI層
           └─────┘   └─────┘   └─────┘   └─────┘
              │         │         │         │
       ECHONET Lite   Matter    AiSEG2   SwitchBot    ← 機器層
      (シャッター/エアコン (照明/プラグ (電力モニタ)  (センサー類
        /給湯器 …)       …)                    …)

下から順に読むと分かりやすいです。

  • 機器層 — 家の実物。電動シャッターやエアコンはECHONET Lite、後付けのスマートプラグや照明はMatter、分電盤まわりの電力はPanasonic AiSEG2、温湿度やCO2のセンサー類はSwitchBot、というふうにプロトコルが分かれています。
  • プロトコルCLI層(enl / mat / ais / swb — 各プロトコルを「うまくやる」ことだけに専念するCLI。ここより下の事情(バイト列やソケット、HTTPの認証)を、この層に閉じ込めます。厚みはプロトコル次第で、ECHONET Liteのように小さく済むものもあれば、Matterのように本格的な実装になるものもあります。
  • オーケストレーション層(casa / mando — 人に優しい名前で機器を呼べる統合CLI casa と、家族がスマホから触るWebフロント mando。プロトコルは喋らず、下の層を呼ぶだけです。AIには専用の入口を作っていません。全ツールが構造化JSONを吐くので、CLIをそのまま直接叩けるからです。

重要なのは、各層が下を「呼ぶだけ」で、自分より下の実装を知らないことです。だから1か所を差し替えても上は壊れません。

各ツールの役割

enl — ECHONET Lite を喋るCLI

日本の据え付け設備(電動シャッター、エアコン、給湯器、スマートメーターなど)が共通で使うECHONET Liteを扱う、one-shotなCLIです。ソケットを開いてUDPフレームを送り、タイムアウトまで応答を集めて終了する。機器側からの自発通知(INF)を待ち受ける listen サブコマンドもありますが、これも指定した件数を受け取るかタイムアウトで終了するone-shotで、デーモン化はしません。常駐で待ち受けたいときは、外側のループ(後述の casad など)から叩く設計です。

UNIX哲学がそのまま形になっていて、stdout は1コマンド=1つのJSONオブジェクト、診断は stderr、成功・タイムアウト・拒否を終了コードで区別できます。未知の機器やプロパティも生のhexとしてロスレスに返し、コマンド自体は成功する——デコード辞書は「あれば嬉しい」加算的なものに徹しています。

mat — Matter を喋るCLI

新しく売り出されるスマート機器の側で採用が進むMatterを扱うCLIです。当初はMatterコントローラ(chip-tool)をサブプロセスとして呼ぶ作りでしたが、いまはTLVやCASEを含めてプロトコルを自前実装しています。chip-tool はあくまでテストツールで、本番の実装に組み込むべきものではないうえ、常駐させるとCPUの1コアを100%使い続けることも分かり、脱 chip-tool に踏み切りました。

Matterはセッション確立(CASE)や証明書まわりが重く、毎回one-shotで払うには高くつきます。そこでwarmなセッションを保つ常駐デーモン matd を別バイナリとして持ち、mat 本体はあくまでone-shot。commission(機器の追加)、read / write / invoke、複数管理者での共有、グループ制御まで実装済みです。6本の中ではいちばん「薄くない」CLIで、実体はMatterコントローラの自前実装です。

ais — Panasonic AiSEG2 を叩くCLI

分電盤まわりの電力を可視化するPanasonic AiSEG2専用のCLIです。AiSEG2は「製品」で、操作面がWeb UIしかないため、ais はそのWeb UIをHTTP(Digest認証)で叩いて電力データを読み取ります。ちなみにリンクプラス照明は、結局無線アダプタを付けてECHONET Liteで喋れる形にしたので、ais ではなく enl の担当です。

ここでもstdoutは純粋なJSON、診断はstderr、stateless / one-shot。ECHONET LiteやMatterのように機器プロトコルを直接喋る経路とは毛色が違いますが、「薄く、透明に、composableに」という規約は共通です。対象ファームウェアを固定し、解釈層の契約を凍結して壊れにくくしている点も現実的な工夫です。

swb — SwitchBot を扱うCLI

後付けのSwitchBot機器を扱うCLIです。温湿度計やCO2センサーの値はBLEのパッシブスキャンで直接読み取ります。ハブもクラウドも介さないので、レート制限を気にせず流しっぱなしにできる。一方、機器の操作はSwitchBot Cloud APIを叩きます。読み取りはBLE、操作はクラウド——と経路を割り切っているのが特徴です。

ここでも規約は同じで、stdoutは純粋なJSON(スキャン時は1行1JSONのストリーム)、診断はstderr、未知の機器も生のhexでロスレスに流します。集計や保存は jq や下流の道具の仕事です。

casa — 横断オーケストレーションCLI

enl / mat / ais を束ねる統合CLIです。プロトコルは一切喋らず、バイト列もソケットも持たず、すべて兄弟CLIにサブプロセスとして委譲します。casa の仕事は3つ——人に優しい名前から(プロトコル, アドレス, オブジェクト)への解決、設定ファイルの読み込みとバリデーション、そして各CLIへの一貫したラッパUXです。

たとえば casa set living_aircon ... と書けば、裏で適切なプロトコルCLIが選ばれて実機に届きます。子CLIの出力を casa のスキーマに正規化して再出力するので、上の層は個々のプロトコルの差を意識せずに済みます。キャッシュDBもデーモンも内部スケジューラも持たず、状態は設定ファイルだけ——という禁欲もそのままです。

横断ならではの仕事もここに集まります。設定でグループを定義すると、プロトコルをまたいだシーンを1コマンドで叩けます(casa on living で、ECHONET Liteの照明もMatterのプラグもまとめてon)。さらに定期実行やルール実行——「enl がINF通知を受けたら mat で照明を動かす」のような自動化——は、同じワークスペースの別バイナリ casad が担います。casad はTOMLで書いたルールを常駐して評価し、発火したら casa を子プロセスで呼ぶだけ。casa 本体のステートレスは崩しません。

mando — 家族が使うWebフロント

家族が日常的に触るWebフロントの常駐サービスです。技術者でない家族が、スマホからシャッターなどを「確実に」開け閉めできる最小UIを配ります。プロトコルは喋らず、casa(ブートストラップ期は enl)をサブプロセスで呼ぶだけ。成果物はバイナリ1個+設定ファイルで、UIは焼き込み済みです。

設計で徹底しているのは「正直さ」です。set後に必ずstateを取り直し、実際の開閉を確認してから表示する。「閉じました」を楽観表示しない。いまはUIが数秒間隔のポーリングでも状態を引いていますが、これはさすがにやりすぎなので、やめる予定です。派手さより、軽さと「壊れない・嘘をつかない」を優先した——家族が毎日触る操作面だからこその割り切りです。

この構成の勘所

改めて眺めると、効いているのは「モノリスにしない」という一点です。

市販の統合ソフトは、1つの大きなアプリにすべてを取り込みます。それが便利な場面もありますが、中身が不透明になり、一部が不調でも全体を疑うことになりがちです。対して、プロトコルごとにCLIを分け、横断UXをその上に薄く乗せるこの構成は、こうふるまいます。

  • 境界が明確 — Matterの不調は mat の中で完結し、enl にも casa にも波及しない
  • 差し替えが局所的mando のバックエンドを enl から casa に移すのは、コード変更ではなく設定の差し替えで済む
  • composable — どのCLIも jq やcron、daguのようなワークフローエンジンから素直に叩けるので、自動化は外側で自由に組める
  • AIネイティブ — 全ツールが構造化JSONを吐くので、GUIを経由せずAIが家を操作できる

小さく分けて、上で束ねる。UNIX哲学をそのまま家に持ち込んだ、というのが全体像です。

これから深掘りしていくもの

各ツールの中身や、実際に家がどう動いているかは、1本ずつ記事にしていきます。第1弾のECHONET Lite編はすでに公開済みで、コマンド1つで電動シャッターが降りるまでを実際のコマンドと出力付きで書いています。

紹介したツールはすべて公開しているので、動くものをその場で確認できます。READMEには実行例と設計背景を書いてあり、そのまま手を動かせるはずです。

次は mat(Matter側)や casa の中身を、同じように手を動かしながら書いていきます。自分の家が自分の書いたコードで動いていく記録として、また覗きに来てもらえたら嬉しいです。