スマホで見るホームラボ監視ダッシュボードの最小設計

スマートホームを描いたアイキャッチ画像

スマホでラボの状態を開いたとき、必要なのは「何でもできる管理画面」ではなく、今見るべきものが静かに並ぶ一画面でした。某所ラボでは、AI利用枠、警報、稼働中の仕事、月間利用量、PC電力を6枚のタイルにまとめた読み取り専用の「事務所」を作っています。

意外だったのは、完成に近づくほど表示する面が減ったことです。かつては9つの面を追加していましたが、今はすべて撤去しました。変更ボタンもありません。見るだけで済む画面にしたことで、短時間で状態を読み取るための余白が残りました。

この画面は、数値を飾るためのものではありません。値が来ていない口座は「計測待ち」と残し、取得できないデータをもっともらしい数字で埋めません。過去に扱った値と鮮度を組で扱う監視と同じく、値があることと、今読める値であることを分けて扱います。

目次

事務所は5つの面を6枚のタイルへ絞った

現在の事務所は、アラート、Quota、稼働中エージェント、Claude利用状況、Claude Codeの月間利用量、Main PCの電力という6枚で構成されています。用途の異なる数字を一か所へ寄せつつ、1画面で読める量に留めました。

図1は、現在残している面と役割を整理した構成図です。

図1: 構成図: 読み取り専用の事務所を構成する5面・6タイル
タイル画面で読むこと
アラートアラート未処理の異常・警告が残っていないか
利用状況Quota / Claude利用状況 / Claude Code月間利用量AI利用の残量と利用状況
稼働状況稼働中エージェント直近に動いた仕事があるか
電力Main PCの電力PC電力の状態

図1で重要なのは、タイルごとに操作を置かなかった点です。ここは作業を始める場所ではなく、作業が必要かどうかを読む場所です。

盛った9つの面を、最後には全部外した

最初から少なかったわけではありません。制作テーマや次のドロップ、反応シグナル、収益、板、商品の陳列、実行ボタン、専用セクション、クイックスタート、全体監視のダイジェストまで置いていました。

しかし、スマホで状態を読むたびに、それらは判断を速くするより視線を散らしました。残した6タイルは、今の状態を読むために必要なものです。制作や販売の段取り、始動用の導線、全体を説明するための表示は、ここでは役割が違いました。

比べる点以前の画面現在の事務所
面の数現在の6枚に加えて9面5面・6タイル
操作1件処理の実行、板の項目移動があった変更ボタンなし
目的見ることと進めることが混在状態を読むことに限定

変更系のAPIも、以前の2本を撤去しました。現在は読み取り専用です。操作を隠した管理画面ではなく、操作そのものを持たない表示へ切り替えています。

欠けたデータは、静かな空欄として残す

ダッシュボードは数字が多いほど安心に見えます。しかし、ソースにない数字まで並べると、読む側は何を信じればよいか分からなくなります。

データソースが見つからない場合は、エラー画面にせず穏やかな空状態を描きます。まだ値が来ていないAI口座も行を消さず、「計測待ち」と表示します。空欄は故障を演出するための空白ではなく、まだ数字を持っていないことをそのまま伝える場所です。

この扱いは、値だけでなく鮮度を見るための監視の考え方を画面にも持ち込んだものです。利用枠のように、行そのものが存在することに意味がある対象では、数字が来ていないからといって行まで消す必要はありません。

注意: 空欄をすべて異常として赤く染める設計にはしていません。データがない理由は画面だけでは区別できない場合があります。必要なら元のデータ経路を別途たどります。

アラートは成功を48時間で消し、異常は消さない

図解: 通知種別ごとの表示規則(完了・成功 / 48時間後に自然に退場 / 異常・警告 / 復帰通知または解決記録まで継続)
図解: 通知種別ごとの表示規則(AI生成)

アラートにも、同じ「読むための量」に合わせた時間の扱いがあります。完了・成功の通知は48時間で画面から自然に退場します。一方、異常・警告には時効を設けません。

復帰の通知が届くか、対応後に解決の記録を残すまで、異常は表示され続けます。古い異常を消すために時間だけを使うのではなく、未処理である事実を残します。

図2は、通知種別ごとの表示規則です。

図2: 構成図: 成功通知は48時間、異常・警告は解決まで表示
通知の種類表示の終わり読み取り方
完了・成功48時間後に自然に退場直近の完了だけを見る
異常・警告復帰通知または解決記録まで継続未処理なら画面に残る

図2の変化しない側、つまり異常・警告が残る側が設計の中心です。画面に出続けることは不具合ではありません。対処が要るという読み取りを、表示の寿命に反映しています。

稼働中の表示は「直近1時間に働いたか」で決める

稼働中エージェントの面は、常に存在するものを全部並べる画面にはしていません。直近1時間に活動したものだけを個別に出し、それより古いものは「待機中のセッションが何本あるか」という1行に畳みます。同じ条件の実行が複数ある場合も、件数をまとめて表示します。

これは、常駐しているかだけを見る監視から一歩離れる設計です。以前の「働いているか」を見る監視で扱った通り、存在確認だけでは今の仕事ぶりを読み取れません。

この面は、常時集計する仕組みを持ちません。画面を開くたびに、その時点のプロセス状態を読み取ります。履歴を網羅するためではなく、今の一時間を読むためのタイルです。

画面の版数は、手で管理しない

図解: 画面の版数を自動で導く(HTML、スクリプト、スタイル / 内容 / 版数表示 / 内容が変われば版数も変わり / 実際に描画されたタイル)
図解: 画面の版数を自動で導く(AI生成)

版数表示は、人が更新のたびに数字を書き換える方式ではありません。HTML、スクリプト、スタイルなど、画面を構成する部品の内容から自動的に導き出します。

内容が変われば版数も変わり、内容が変わらなければ版数も変わりません。表示を直したのに版数だけ古い、あるいは版数だけ進んでいて何が変わったか分からない、といった分離を避けるためです。

新しいタイルを足す手順の最後には、ブラウザで実際に描画されたタイルを目で見る工程も置いています。通信が成功しても、画面が読める状態で描画されたことまでは示しません。事務所はAPIの応答を見るためのものではなく、人が画面を読むためのものだからです。

自分のラボで試すなら、最初は3枚で足りる

同じ種類の画面を作るなら、最初から6枚を目指す必要はありません。スマホで毎日か週に数回見たい対象だけを選びます。

最小構成入れるもの入れないもの
警報未処理の異常・警告成功通知の長期保存
状態直近に動いた仕事古い活動の個別行
資源気にしている残量か電力のどちらか1つ取得できない数値の代替表示

この3枚で、開いた直後に次の行動が決まるなら十分です。決まらないなら、タイルを増やす前に、各タイルが答える問いを一つに絞るほうが効きます。

画面に操作を戻す予定は、今のところない

読み取り専用にしたことで、事務所だけで仕事を完結させることはできません。それは制限でもあります。何かを実行したり、項目を動かしたりする場所は別に必要です。

また、空欄が静かであることは、データ経路が正常であることを保証しません。計測待ちなのか、データソースが見つからないのか、画面だけでは判断できない場面も残ります。画面は入口として使い、必要なときだけ個別の運用画面へ戻る設計です。

工作展の最後に、事務所を置く

このお試しシーズンは、工作室を開けた回から始まりました。失敗の解剖だけでなく、AIと一緒に作ったものを見せる。その流れの最後に、個別の装置たちを一画面で見る装置を置きました。

表示ボタンより、表示しないと決めた判断のほうが多い事務所が、今はこの形で1画面に立っています。6枚のタイルは動き、変更ボタンはなく、欠けたデータは空欄のまま残ります。完成の宣言ではありませんが、今の仕事ぶりを読むには足りています。

次は、Main PCの電力タイルのように、一覧をデータ側から自動生成する設計をほかの面にも広げてみたいところです。この「失敗の解剖を少し休み、作った物を見せる」工作展の空気は、続きを読みたいと思えるでしょうか。

状態JSONから6枚の読み取り専用タイルを描く

検証した画面は、状態を返すJSONと、HTML・JavaScript・CSSだけで構成しています。変更系APIは持たず、ブラウザを開いた時点の状態を読みます。次の最小例は、JSONにある6項目をボタンなしのタイルへ描く部分です。

{
  "alerts": {"label": "アラート", "display": "未処理なし"},
  "quota": {"label": "Quota", "display": "計測待ち"},
  "agents": {"label": "稼働中エージェント", "display": "待機中"},
  "claude": {"label": "Claude利用状況", "display": "計測待ち"},
  "monthly": {"label": "Claude Code月間利用量", "display": "計測待ち"},
  "power": {"label": "Main PCの電力", "display": "計測待ち"}
}
const order = ["alerts", "quota", "agents", "claude", "monthly", "power"];
const state = await fetch("./status.json", {cache: "no-store"}).then(r => {
  if (!r.ok) throw new Error(`status HTTP ${r.status}`);
  return r.json();
});
document.querySelector("#tiles").replaceChildren(...order.map(key => {
  const tile = document.createElement("section");
  tile.className = "status-tile";
  const item = state[key] ?? {label: key, display: "計測待ち"};
  tile.textContent = `${item.label}: ${item.display}`;
  return tile;
}));

開発者ツールでstatus.jsonが200になり、#tiles直下に6要素が描画されれば成功です。JSONが欠けた項目は推測値で埋めず「計測待ち」にします。JSON自体を取得できない場合は、空の正常画面にせず通信エラーとして切り分けます。

成功: #tiles の子要素が6件 / 操作ボタンは0件
失敗: status HTTP 404 など / JSONの構文エラー

この検証を回している環境

この検証は、自宅の常設ラボ(使い捨てVM/LXCを回す母艦+GPU+VLAN分離ネットワーク)で動かしています。使っている機材と選定理由、全体構成は1本にまとめています。

ラボ構成のまとめを見る →
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次