PHY: LEDをキーのbooleanと汎用の部品ノードに分ける(P-10解消)

per-key LEDは位置に自由度がないため、キーが持つboolean 1つにする。
設計者が位置を決める部品はLED専用ノードにせず、変換と部品グループだけを持つ
部品ノードとして一般化する。表裏とチェーン順序はPHYに持たない。

Journal: journal/2026-09-20-led-node.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-20 10:53:57 +09:00
co-authored by Claude Opus 5
parent bbea89798d
commit 2ec3dd4a1a
2 changed files with 115 additions and 11 deletions
+50 -11
View File
@@ -68,6 +68,34 @@ PHYはスイッチの品種(MX-3pin、Choc V1 など)もソケット方式も持
キーごとの検出方式(接点マトリクス / アナログ / 光学)はELCが持ち、PHYは持たない。
ホールセンサのように端子数も配線トポロジも接点スイッチと異なるものがあり、これは電気的な性質のため。
### per-key LED
キーはper-key LEDの有無をbooleanで持つ。位置も向きも持たない。
per-key LEDの位置はスイッチのフットプリント内で決まり、向きはキーのorientationに従うため、
設計者が決められるのは載せるか載せないかだけ。
載せるキーと載せないキーが混在する構成を表せるよう、キーごとに持つ。キーごとの固定値であり、
条件によって有無が変わる構成は扱わない。
### 部品ノード
LED・OLED・ロータリーエンコーダ・ネジ穴のように、設計者が位置を決めるキー以外の部品は、
キーと同じ変換を持つノードとして木に置く。per-key LED以外のLEDもここに入る。
部品ノードが持つのは変換と部品グループだけ。品種・端子配置・フットプリント・表裏は持たない。
どの部品を実際に載せるかはPCB設計ツール側の選択であり、キーと同じ原則が適用される。
スイッチの向き(orientation)に当たる軸は持たない。キーが2軸を持つのはキーキャップとスイッチが
独立に回せるためで、部品ノードにその二重構造はない。向きは変換の回転角度で表す。
部品グループ名のうち `@` で始まるものは予約で、エディタ上の描画を変えるために使う。
フットプリントの選択には使わない。予約名以外および省略時は既定の形で描く。
ユーザーが付ける名前は `@` で始めない限り予約と衝突しない。
部品ノードはクラスターの子になれる。クラスターを動かせば配下の部品も追随する。
LEDの配線はPHYが持たない。デイジーチェーンの順序はELC、RGB効果が使う論理インデックスはIDXが持つ [推測:P-11]。
### デカールとゴースト
デカールとゴーストはキーとして扱い、フラグで区別する。KLEの d, g に対応する。
@@ -97,7 +125,7 @@ PHYはスイッチの品種(MX-3pin、Choc V1 など)もソケット方式も持
各ノードは親から見た変換を持つ。キーとクラスターを混在させた木構造として保持する。
`phase1-json-schema.md` のPHYスキーマは、この節の Key 型(x2〜h2, decal, ghost, labels, switchOffset, partGroup, orientation)にまだ追従していない。
`phase1-json-schema.md` のPHYスキーマは、この節の Key 型(x2〜h2, decal, ghost, labels, switchOffset, partGroup, orientation, perKeyLED)と Component 型にまだ追従していない。
```ts
type Transform = {
@@ -122,13 +150,18 @@ type Key = {
labels?: string[], // 参考情報
switchOffset?: { x: number, y: number }, // (w, h) 矩形の中心から。省略時は0
partGroup?: string, // 同じ部品を使うキーをまとめるラベル。中身は解釈しない
orientation?: 0 | 90 | 180 | 270 // スイッチの向き。キーのローカル座標系。省略時は0
orientation?: 0 | 90 | 180 | 270, // スイッチの向き。キーのローカル座標系。省略時は0
perKeyLED?: boolean // per-key LEDの有無。省略時はfalse
}
type Component = {
transform: Transform,
partGroup?: string // `@` 始まりは描画用の予約名
}
type Cluster = {
transform: Transform,
children: (Key | Cluster)[]
children: (Key | Cluster | Component)[]
}
const root: (Key | Cluster)[] = []
const root: (Key | Cluster | Component)[] = []
```
## 連携用出力形式
@@ -181,7 +214,7 @@ const kleData = (ConfigObject | KeyLabel)[][]
- 回転角度は正規化せずそのまま出力する。KLEのデータは任意の角度を受け付け、15度刻みはKLEのUI上の操作単位にすぎない
- rx, ry はPHYに持たないので、出力時に選ぶ
- ユニットサイズ(mm)、ビジュアルオフセット、クラスター構造はKLE JSONに出力されない
- ユニットサイズ(mm)、ビジュアルオフセット、クラスター構造、部品ノード、per-key LEDはKLE JSONに出力されない
- 部品グループ・スイッチの向きはKLE JSONに出力しない。sm, sb, st には取り込み時に保持した値をそのまま書き戻す
- KLEの `p` はキーキャップのプロファイル名(SA、DCSなど)であり、PHYのプロファイルとは対応させない
@@ -203,11 +236,11 @@ Beyond KLEはスイッチの品種を持たないため、対応づける先が
## 検討済み・非採用
- ノードごとの回転中心パラメータ (journal/2026-09-18-phy-coordinate-model.md)
- KLE JSONへの識別・構造情報の埋め込み(labelのID、`_beyondkle` メタデータ、ゴーストキー) (journal/2026-09-18-kle-roundtrip.md)
- KLEのデカール・ゴースト・見た目属性を取り込み時に捨てる (journal/2026-09-19-kle-key-attributes.md)
- スイッチのブランドをPHYで持つ (journal/2026-09-20-switch-terminal.md)
- スイッチの品種・ソケット方式をPHYで持つ (journal/2026-09-20-switch-terminal-reversal.md)
- LED専用ノード (journal/2026-09-20-led-node.md)
- per-key LEDに座標を持たせる (journal/2026-09-20-led-node.md)
## 未確認事項
@@ -242,8 +275,14 @@ Beyond KLEはスイッチの品種を持たないため、対応づける先が
- 現状の認識: どのラベルがMAPに適用できるかは、おそらく機械的には判断できない。自動で適用してユーザーが不要なものを落とす方式も考えられる
- 格上げ条件: 適用するか、する場合は自動適用とユーザーによる取捨の流れをユーザーが決める
### P-10 LEDを独立したノードとして持つか
### P-11 LEDのチェーン順序をELCが持つか
- 位置づけ: 未解決の問い。LED用の穴をどう表すか
- 現状の認識: LEDの配置は設計者が決め、色や実装するかは利用者が選ぶ。位置と向き(表裏を含む)を持つ要素なのでPHYに入りそうだが、独立ノードにするかは未検討
- 格上げ条件: LEDの配置がスイッチに従属するか独立するかをユーザーが決め、ノードにするかを決める
- 位置づけ: 本文「部品ノード」が前提にしている
- 現状の認識: 電気的な接続なのでELC、という切り分けで進めている。ただしデイジーチェーンの順序が接点マトリクスと同じ層に収まるかに確信がない。引っかかりを言語化できていない
- 格上げ条件: ELCの構造を具体化し、チェーン順序がその中に無理なく収まるか、別の持ち方が要るかを確認する
### P-12 部品の表裏を描画でどう扱うか
- 位置づけ: 本文「部品ノードは表裏を持たない」の残余
- 現状の認識: どちらの面に載るかはPCB設計ツールが決める情報なのでPHYには持たない。ただしエディタ上で裏面の部品を描き分けたくなる可能性があり、`@` 始まりの予約グループ名だけで表現できるかは未検証
- 格上げ条件: 予約グループ名による描画を実装し、表裏の描き分けが必要になるか、必要なら予約名で足りるかを確認する
+65
View File
@@ -0,0 +1,65 @@
# LEDの持ち方 / 部品ノードへの一般化
## 結論
- per-key LEDは、キーが持つboolean 1つ。位置も向きも持たない
- LED専用ノードは作らない。キー以外の部品を一般の「部品ノード」として持ち、LEDはその一例
- 部品ノードは transform と partGroup のみ。orientation は持たない
- 部品グループ名の `@` 始まりは予約。エディタ上の描画にのみ使う
- チェーン順序・論理インデックス・表裏はPHYに持たない
## 案の比較
### per-key LEDの表現
| 案 | 位置 | 採否 |
|---|---|---|
| キーのboolean | 持たない | ○ |
| キーに追随する自動生成ノード | ノードが座標を持つ | × 座標に自由度がない |
| ユーザーが1個ずつ置く | 持つ | × キー数ぶんの手作業 |
### 独立して置く部品
| 案 | 対象 | 採否 |
|---|---|---|
| 部品ノード(汎用) | LED / OLED / エンコーダ / ネジ穴 / MCU など | ○ |
| LEDノード専用 | LEDのみ | × 次の部品で同じ議論をやり直す |
## 根拠
per-key LEDの位置はスイッチのフットプリント内で決まっている(MXならスイッチ上側の窓)。
設計者が選べる自由度がないので、座標を持たせても常に導出可能な値を二重に持つだけになる。
スイッチの品種を持たないと決めた判断と同じ論法。
向きも同様で、per-key LEDはキーの orientation に従う。よってパラメータは有無だけ。
一方、アンダーグローやインジケータは設計者が位置を決めるのでノードが要る。
ここでLED専用ノードにすると、OLED・ロータリーエンコーダ・リセットスイッチ・TRRSジャック・
MCU・ネジ穴が来たときに毎回同じ議論になる。どれも「位置と向きを持つ非キー要素」で構造が同じ。
partGroup(中身を解釈しないラベル)をそのまま流用できるので、一般化するコストがほぼない。
部品ノードが orientation を持たない理由: キーが2軸(キャップの向き = transform.rotation /
スイッチの向き = orientation)を持つのは、キャップという外皮とスイッチが独立に回せるため。
部品ノードにはその二重構造がないので transform.rotation だけで足りる。
`@` 始まりの予約: 部品グループの中身を解釈しないという原則と、描画を変えたいという要求は、
「描画にのみ使う。フットプリントの選択には使わない」で両立する。
記号始まりにすればユーザーが自由に付けた名前(`led-left` など)と絶対に衝突しない。
未知のグループ名は既定の形で描く。
## キーごとのopt-outが要る理由
一部のキーだけLEDを載せない構成として挙がった例(いずれも未検証):
- スタビライザとの干渉
- ロータリーエンコーダに置き換わる位置
- USBの電流上限に収めるためにLED数を絞る
## 捨てた案・送った先
- ファイル単位の「per-key LEDがある」フラグ: キーごとのbooleanから導出できるので存在フラグとしては不要。
既定値を与える設定としては意味があるが、ファイル単位設定の置き場は他にも要求があり別トピックへ。
今回はキーごとのbooleanのみ決め、省略時は false とする
- レイアウトによって条件付きでLEDの有無が変わる構成: ANSI/ISO Enter のようなキー自体の排他と同じ問題で、
LED固有ではない。マルチレイアウト(未導入の概念)側へ送る
- 部品の表裏をPHYが持つ: PCB設計ツールが決める情報。ただし描画の描き分けとの絡みが残るので P-12
- チェーン順序をPHYが持つ: 電気的な接続なのでELC。ただし接点マトリクスと同じ層でよいかに確信がなく P-11