設計書 · 2026-09-29
Launch
靴・ベルト・Smart Ring に入れる「アプリ」のしくみです。アプリは開いて使うものではありません。入っていれば、それだけで常に働いています (プラグインに近い考え方)。当てる・通る・届く、という出来事に、入っているアプリが自動で応えます。
公開した画面: Launch (本人のスマホ) ・ 読み取り機 (入り口に置く)
1. しくみ
- 入れる: 本人のスマホの Launch で、アプリの横のスイッチを入れる (顔・指紋で確かめる)。
- 働く: 入り口の読み取り機に靴・ベルト・Smart Ring を当てる → サーバーが「本物のタグか・使い回しでないか・そのアプリが入っているか」を確かめて処理する。
- 知らせる: 結果を本人 (と家族) の iPhone に通知。SIM ありの本体には、光や振動の指示が LTE で届く。
- 本体の決まり: 入れたアプリに合わせた「出来事 → 動作」の表 (最大 12 個・26 バイト) を本体に入れる。SIM なしの本体には画面の点滅で送る (約 40 秒)。
| 部分 | どこ |
|---|---|
| サーバー | ~/work/kutsu-belt/site/functions/api/launch/[[route]].js, アプリの一覧 _lib/apps.js |
| 本人のスマホの画面 | /launch/ (ホーム画面に追加して使う) |
| 読み取り機 | /launch/reader.html — Android の Chrome (Web NFC)。iPhone のブラウザは NFC を読めないので読み取り機にはなれない |
| 先生の画面 | /launch/room.html#rid=…&secret=… (合言葉は # の後ろ = サーバーの記録に残らない) |
| 本体のプログラム | firmware/launch_rules.c (決まりの表), pass_id.c (すれ違いの ID), optical_rx.c (点滅の長い形式) |
2. アプリ
| アプリ | 使う本体 | できること | 今の状態 |
|---|---|---|---|
| 🚪 入退室 | 靴 (主) ・ Smart Ring ・ ベルト | 教室の入り口の読み取り機に当てると入室・退室が交互に記録され、本人と家族のスマホに届く。先生の画面に在室の一覧。生徒は「参加の番号」で教室に参加した時だけ記録される (本人の同意) | 動く (本番で確認) |
| ♨️ 温泉 | Smart Ring ・ 靴 (下足) | 受付でチェックイン → ロッカー番号。下足箱で靴を当てて下足番号。売店でつけ払い。帰りの受付で精算 (合計と下足番号を知らせる)。財布もスマホも持たずに入れる | 動く (手元の試験) |
| 👋 すれ違い | Smart Ring ・ 靴 | 同じアプリを入れた人と近くを通ると、お互いの名刺 (呼び名とひとこと) を交換 | サーバーと ID の計算は動く。Bluetooth の部品が要る (次の版) |
| 💬 S2S | Smart Ring ・ ベルト | S2S にメッセージが届くと Smart Ring が光ってそっと震える | 受け口は動く。S2S 側からの送信はまだつないでいない |
| 🔊 音 | ベルト ・ 靴 | 知らせの音と、体に伝える低音 (7 章) | 部品が要る (次の版) |
3. 代わりに当てられないこと (代返の防止)
タグは当てるたびに暗号の数字が変わる URL を出します (NTAG 424 DNA の SUN)。サーバーは「前より新しい回数か」を確かめるので、URL を写してほかの人のスマホで開いても「使い回しの URL」として記録されません。本番でも、同じ URL を 2 回送ると 2 回目は断られることを確かめました。ただし、本人の靴そのものを借りて当てることは防げません。
4. すれ違いの ID
- 本体は 10 分ごとに変わる 16 バイトの ID を Bluetooth で流し、近くで聞いた ID を記録する。
- ID = HMAC-SHA256(日の鍵, "eph:" + 区切り) の先頭 16 バイト。日の鍵は本体とサーバーだけが知る。ID から持ち主はわからない。
- 本体が上げた「聞いた ID」を、サーバーが参加者全員のその日の ID と照らす。お互いに聞こえた時だけ名刺を交換 (片方だけでは交換しない)。同じ日の同じ相手は 1 回だけ。
- 上げる時は本体の鍵で署名する (偽の上げ方は断る)。
- 照らし合わせはサーバーで行うので、サーバーは「誰と誰がすれ違ったか」を知ります。Bluetooth はこのアプリを入れた時だけ動かす設計です。
5. 本体の決まりの表
1 つの決まり = 2 バイト [出来事 (上 4 ビット) | 動作 (下 4 ビット), 引数]。最大 12 個。光の引数は「色 (上 4 ビット) | 秒 (下 4 ビット)」。転倒の振動は表になくても必ず出る (アプリで消せない)。4 アプリ (入退室・温泉・すれ違い・S2S) を入れた Smart Ring で 10 個・22 バイト。
| 出来事 | 番号 |
|---|---|
| 2 回叩く / 転倒 / すれ違い / 入室 / 退室 / 温泉チェックイン / 温泉チェックアウト / S2S / タイマー / 電池が少ない | 1〜10 |
| 動作 | 番号 |
| 光 / 振動 / 電子ペーパーを次へ / タイマー / 音 | 1〜5 |
6. 確かめたこと
- サーバー: 手元の試験 45 項目 (入退室・温泉・すれ違い・本体への指示・S2S の受け口・Launch の中でのパスキー) がすべて通った。
- 本番: ブラウザで「ベルト → パスキー → このスマホに Launch → 入退室アプリを入れる → 教室に参加 → 靴のタグで入室 → 同じ URL は拒否 → 先生の画面に在室 1 人」が通った (パスキーは開発用の仮想の装置, 通知の購読だけは API を直接呼んで代えた)。
- 本体: 決まりの表の読み込み・壊れた表の拒否、すれ違いの ID が C とサーバーで一致、画面の点滅の長い形式 (18 バイト) が 60 Hz と 120 Hz で 100 回中 100 回受け取れた (模擬)。
7. 音 (ベルト・靴)
Vision Pro は耳のすぐ横に小さなスピーカー (オーディオポッド) を置いて音を届けます。ベルトや靴は耳から 1 m 近く離れているので、同じ置き方はできません。そこで役割を分けます。
- 低音は体で感じる: 振動子 (音の帯域まで動くボイスコイル型) を、ベルトはお腹側・靴は靴底に当てる。音量を上げずに低音を体に伝える (まわりに漏れにくい)。
- 知らせの音は小さなスピーカー: ベルトのベルト通し (金属をやめ樹脂にする) に直径 10 mm 前後のスピーカーを上向きに。声や短い音だけ。
- どの程度聞こえるか・感じるかは試していません。音楽を流すには Bluetooth の部品 (LE Audio) も要ります。
8. S2S を本当につなぐには
Launch 側の受け口 (/api/launch/s2s, 署名つき) はできています。S2S の側で「メッセージが届いた時、つないだ人の番号 (S2S-XXXXXXXX) へ知らせる」処理を足せば、Smart Ring が光ります。s2s.day 本体の変更になるので、まだ手を付けていません。
9. まだのこと
- すれ違いと音の部品 (Bluetooth・振動子・スピーカー) を本体に足す設計と基板。
- 温泉の入浴タイマー (浴室の入口で当てたら N 分後に振動) は、決まりの表には入れたが、サーバーから時間で知らせる仕組みはまだ。
- iPhone の実機で通知が届くか。
- 学校や施設で使う時の、名簿の管理・記録の保存期間・消し方の決まり。