2019年 10月 08日

NiZ Keyboard PLUM のキーマップを macOS や Linux から書き換える

前回 に引き続き NiZ のキーマップをごにょごにょする。

とりあえず表題の通り、キーマップの書きかえまではできた。

#!/usr/bin/env ruby


require "./niz.rb"
require 'progress_bar'

override_mapping = lambda do |mapping|
	# mapping[level][key_id] = hwcode
	# level:
	#   0: normal
	#   1: Right Fn
	#   2: Left Fn
	# key_id: 1-66
	# hwcode: See ./niz.rb HWCODE constant

	mapping[0][61] = 68 # Set key_id 61 (right side of space) = 68 (super)
	mapping[0][62] = 71
	mapping[0][63] = 74
end

#################################################################

niz = NiZ.new
Timeout.timeout(1) do
	begin
		niz.open
	rescue => e
		$stderr.puts "#{e.inspect} retrying open device..."
		retry
	end
end

puts "Version: #{niz.version}"
puts "#{niz.keycount} keys"

puts "Reading key mapping..."
progress = ProgressBar.new(niz.keycount * 3)
read_all = niz.read_all do |count, keymap|
	progress.increment!
end

mapping = NiZ.mapping_from_array(read_all)

override_mapping[mapping]

puts "Writing key mapping..."
progress = ProgressBar.new(niz.keycount * 3)
niz.write_all(mapping) do |count|
	progress.increment!
end

ポイント

キーマップの書きかえコマンドを送ると、まず既存のキーマップが全てリセットされるみたい。つまり、プロトコル的には一部のキーだけを書きかえということはできない。常に全部のキーマップを送信する必要がある。

なので、一部の書きかえを実現したいのであれば、

  1. 全キーマップの読み出し
  2. キーマップの更新
  3. 全キーマップの書き出し

という手順になる。

HWCODE の定義

NiZ は内部的にキーに対応する数値を HWCODE という名前で持っている。このコードは USB HID の scan code や、multi media キーや、その他いろいろな機能キーを一意に特定するものになっている。HWCODE は ASCII や Usage とまったく別の規則で割り当てられているようで、マッピングは気合で作るしかない。

気合で作るしかないので、おおむね作った。https://github.com/cho45/niz-tools-ruby/blob/master/niz.rb#L13 ということで、ここを読んでいる良い子のみんなは気合を入れる必要がなくなった。

マクロは?

自分で使わないのでまったく調べてない。マクロ登録用のコマンドがあるっぽい。

Windows での SKK

CorvusSKK にしてみた。Ctrl-SPC で IME のオン・オフをしたいので、設定する。

「キー0」タブが IME の ON/OFF 用のキーを設定する画面になっている。スペースキーは 0x20 なので、0x20 と入力して修飾キーとして CTRL を選択し、ON と OFF それぞれについてキーを追加する。

順番にどういう意味があるかわかってないけど、一応一番上にしておいた。こういう感じに。

Android で外部キーボード使用時の日本語入力を快適にする (SKK)

https://play.google.com/store/apps/details?id=jp.kcm.thumbctrl.en.layout これを入れて、レイアウトから Caps Lock -> Ctrl 置き換えする。いろいろレイアウトが追加されるけど、とりあえずこれで良い。

http://ray-mizuki.la.coocan.jp/software/skk_jp.html SKK for Android を apk から入れて、設定する

  • 辞書ファイル解凍
  • ハードキーボードの設定
    • かなキーを Ctrl+Space に (Ctrl+Unknown と表示されるけど、設定できている模様) 内部的には Ctrl 単体で割り当てらているみたい。Ctrl-Space は Android が OS 側で予約しており、割り当てることができない……
    • かなキーをトグルに
  • 句読点のタイプを「。、」に

これでほぼ違和感なく入力できる。ただ、SKK for Android には RET したとき改行しない設定がないので、ちょっと気をつけて入力する必要がある。

Android Studio (IntelliJ IDEA) + AquaSKK で aiueo がそのまま入力されてしまうのを直す

JRE込みのPyCharmで日本語入力がおかしい · Issue #24 · codefirst/aquaskk · GitHub この問題と同じだと思う。

どうも JDK のバージョンによって変な挙動になるらしい。ので、Android Studio の bundled JDK を使うのをやめる。

Selecting the JDK version the IDE will run under – IDEs Support (IntelliJ Platform) | JetBrains この手順に従う

Choose Runtime プラグインをいれる

再起動後に

Shift 連打とかで Choose Runtime... のダイアログを出す。

適当に 1.8.0 の JDK を選んで Install ボタンを押すと勝手に再起動する。

これでおわり。

JDK11 を指定したら起動しなくなった……

なんとなく AdoptOpenJDK 11 を入れて指定したら、起動しなくなってしまった。起動しないので Choose Runtime も使えない。

macOS の場合 ~/Library/Preferences/AndroidStudio3.5 以下に設定ファイルがある。~/Library/Preferences/AndroidStudio3.5/studio.jdk というファイルがあるので、これを消せばデフォルトの JDK に戻すことができる。

2019年 10月 07日

関連エントリー (画像)

NanoVNA WebApp の Android アプリ化

Capacitor をつかって NanoVNA-Web-Client を Android アプリ化してみた。

あんまりハマりどころはなかったのでそれほど書くことはないけど、いくつかメモ。

node_modules

アプリサイズを減らすためにできるだけリソースを減らす必要がある。node_modules 以下を雑に入れると数十MBになってしまうので、気をつける。

Web 版のリソースを完全にそのまま入れるより、必要なリソースだけをコピーするようなビルドスクリプトを書いたほうが良さそう。今回は Makefile でなんとかした。

splash 画像の生成自動化

Ionic のブログに Photoshop template があるので、これを利用させてもらう。

が、ブログの通り cordova-res を使うとうまくいかなかったので、Makefile と ImageMagick でなんとかした。

res:
	convert images/splash.png -gravity center -resize 480x320^ -extent 480x320 ./android/app/src/main/res/drawable/splash.png
	convert images/splash.png -gravity center -resize 800x480^ -extent 800x480 ./android/app/src/main/res/drawable-land-hdpi/splash.png
	convert images/splash.png -gravity center -resize 480x320^ -extent 480x320 ./android/app/src/main/res/drawable-land-mdpi/splash.png
	convert images/splash.png -gravity center -resize 1280x720^ -extent 1280x720 ./android/app/src/main/res/drawable-land-xhdpi/splash.png
	convert images/splash.png -gravity center -resize 1600x960^ -extent 1600x960 ./android/app/src/main/res/drawable-land-xxhdpi/splash.png
	convert images/splash.png -gravity center -resize 1920x1280^ -extent 1920x1280 ./android/app/src/main/res/drawable-land-xxxhdpi/splash.png
	convert images/splash.png -gravity center -resize 480x800^ -extent 480x800 ./android/app/src/main/res/drawable-port-hdpi/splash.png
	convert images/splash.png -gravity center -resize 320x480^ -extent 320x480 ./android/app/src/main/res/drawable-port-mdpi/splash.png
	convert images/splash.png -gravity center -resize 720x1280^ -extent 720x1280 ./android/app/src/main/res/drawable-port-xhdpi/splash.png
	convert images/splash.png -gravity center -resize 960x1600^ -extent 960x1600 ./android/app/src/main/res/drawable-port-xxhdpi/splash.png
	convert images/splash.png -gravity center -resize 1280x1920^ -extent 1280x1920 ./android/app/src/main/res/drawable-port-xxxhdpi/splash.png
	optipng $(wildcard ./android/app/src/main/res/*/splash.png)

Play Store のメモ

リリースしたことある気がしていたが、よく考えたら前職で数回やっただけなので個人のアカウントではやったことがなかった。いろいろストアの使い勝手が変わっていた。

  • 初回の審査は結構時間がかかる。一週間ぐらい? 更新の審査は割とすぐ。
  • 要求される画像がいっぱいあってだるい。全部埋めないとベータ版すらリリースできない
  • adb という仕組みができていた。(端末にあわせて必要なリソースだけを含む apk を自動生成する)

無料アプリの開発者視点からすると、別に Play Store に出すメリットはぜんぜんない。他の端末にさくっと入れたいときに便利かな、と思う。けど、それも普通にウェブサイト経由で .apk ダウンロードして入れればいいだけなので、それほど致命的に面倒くさいわけではない。まぁ Play Store のショバ代は初回に $25 なので Apple (毎年$99もとる) よりは格段に優しいといえる。

2019年 10月 06日

関連エントリー (画像)

NiZ Keyboard PLUM からキーマップや打鍵回数を読み出す

NiZ のアプリケーションは Windows 向けしかない。プロトコルが気になったので、とりあえず打鍵回数を読み出すところをまでをやってみた。環境は macOS で hid_api gem を使い、Ruby で書いた。

できたもの

実行するとこういう出力をする。最後の数字がキーに対応するカウント。

key=  1 hwcode=   1             ESC: 35
key=  2 hwcode=  15               1: 66
key=  3 hwcode=  16               2: 92
key=  4 hwcode=  17               3: 114
key=  5 hwcode=  18               4: 119
key=  6 hwcode=  19               5: 53
key=  7 hwcode=  20               6: 99
key=  8 hwcode=  21               7: 18
key=  9 hwcode=  22               8: 115
key= 10 hwcode=  23               9: 76
key= 11 hwcode=  24               0: 171
key= 12 hwcode=  25               -: 307
key= 13 hwcode=  26               =: 78
key= 14 hwcode=  41               \: 38
key= 15 hwcode=  14               `: 33
key= 16 hwcode=  28             TAB: 575
key= 17 hwcode=  29               Q: 253
key= 18 hwcode=  30               W: 627
key= 19 hwcode=  31               E: 1461
key= 20 hwcode=  32               R: 911
key= 21 hwcode=  33               T: 1137
key= 22 hwcode=  34               Y: 616
key= 23 hwcode=  35               U: 1317
key= 24 hwcode=  36               I: 1662
key= 25 hwcode=  37               O: 1536
key= 26 hwcode=  38               P: 549
key= 27 hwcode=  39               [: 584
key= 28 hwcode=  40               ]: 41
key= 29 hwcode=  27              BS: 1662
key= 30 hwcode=  67          L-CTRL: 18
key= 31 hwcode=  43               A: 1794
key= 32 hwcode=  44               S: 914
key= 33 hwcode=  45               D: 853
key= 34 hwcode=  46               F: 249
key= 35 hwcode=  47               G: 520
key= 36 hwcode=  48               H: 828
key= 37 hwcode=  49               J: 671
key= 38 hwcode=  50               K: 1424
key= 39 hwcode=  51               L: 696
key= 40 hwcode=  52               ;: 452
key= 41 hwcode=  53               ': 155
key= 42 hwcode=  54             RET: 1281
key= 43 hwcode=  55         L-Shift: 1610
key= 44 hwcode=  56               Z: 177
key= 45 hwcode=  57               X: 128
key= 46 hwcode=  58               C: 459
key= 47 hwcode=  59               V: 253
key= 48 hwcode=  60               B: 384
key= 49 hwcode=  61               N: 1352
key= 50 hwcode=  62               M: 482
key= 51 hwcode=  63               ,: 383
key= 52 hwcode=  64               .: 255
key= 53 hwcode=  65               /: 161
key= 54 hwcode=  66         R-Shift: 850
key= 55 hwcode= 156            R-Fn: 135
key= 56 hwcode=  67          L-CTRL: 1653
key= 57 hwcode= 166            L-Fn: 6
key= 58 hwcode=  69           L-Alt: 35
key= 59 hwcode=  68           Super: 703
key= 60 hwcode=  70           Space: 2037
key= 61 hwcode=  68           Super: 7
key= 62 hwcode=  71           R-Alt: 5
key= 63 hwcode=  74          R-Ctrl: 5
key= 64 hwcode=  88      Left Arrow: 24
key= 65 hwcode=  89      Down Arrow: 19
key= 66 hwcode=  90     Right Arrow: 34
key= 67 hwcode=   0                : 0
key= 68 hwcode=   0                : 0
key= 69 hwcode=   0                : 0
key= 70 hwcode=   0                : 0
key= 71 hwcode=   0                : 0
key= 72 hwcode=   0                : 0
key= 73 hwcode=   0                : 0
key= 74 hwcode=   0                : 0
key= 75 hwcode=   0                : 0

プロトコルの概要

すべて HID 上で行われる。64bytes 固定で read/write する。

日本語で説明するよりソースコード読んだほうが早いので説明するのをやめる。

カウントを得るためにすること

キーマップを得る

NiZ キーボード側から、現在のキーマップを取得する。66キーのモデルなので、66キー × 3レイヤー (ノーマル・左Fn・右Fn) で 198 個の論理キー定義がある。

これによって、キーID (1〜66) と、割当られているキーコード (.pro ファイルの HWCODE) のマッピングを得られる。

カウント一覧を得る

カウントは66個の数値の配列のようなものが得られる。インデックスがそれぞれキーIDに対応していると思われる。

インデックスからキーマップを得てカウントと共に表示すればおわり。

備考

macOS だからか、実装が悪いのか、どこが悪いのかわからないが、挙動が不安定

  • HidApi.open がしばしば失敗する
  • read に失敗する (タイムアウト)

何回か繰替えすと成功する。

hid_api

hid_api は timeout のメソッドがあるにも関わらず timeout の処理が抜けているので、モンキーパッチを書いてる。PR 作ろうかと思ったけど結構放置されてそうでめんどい。

macOS でもキーマップを書きかえたいんだけど???

read した形式で書き戻せばいいだけだと思う。

どうやって解析したか?

Windows に USBPcap を入れて、公式のアプリケーションを操作しながらログをとった。

あとは気合

ソースコード

https://github.com/cho45/niz-tools-ruby github にうつしました

>

2019年 10月 05日

関連エントリー (画像)

NiZ Keyboard PLUM という静電容量無接点キーボード

(この写真のキー配列はデフォルトのものではなく、既にカスタマイズ済みです。mac 用のキーキャップが付属しており、HHKB を基準にできるだけキーキャップもあわせています)

3行で

  • 信頼性のあるキーボードがほしいなら買わないほうが良い
  • 打鍵感は十分に良い
  • これにしかない魅力はある

NiZ というキーボード

https://www.nizkeyboard.com/ が公式っぽい。中華製の静電容量無接点キーボード (HHKBやRealforceなどと同じ分類)。

HHKB と比べると以下のような特徴がある

  • 35g / 45g を選べる。35g モデルでも 10g 増やすバネで、特定のキー(ホームポジションとか)だけ荷重を増やせる
    • HHKB は 45g キーストローク 4mm
  • キー数のバリエーションが多い
  • 完全にキーマップをカスタマイズ可能 (ファームウェアレベルで行う)
  • Type-C コネクタ (mini-B よりも機械的に丈夫なコネクタ)
  • Bluetooth 接続対応・バッテリー内蔵
  • 価格は若干安い

価格が安いだけなら買うつもりはなかったけど、キーが HHKB よりも軽くて Bluetooth 接続が可能で、Type-C 接続な点で気になった。66キー(HHKBとほぼ同じ大きさ) 35g のモデルを買ってみた。スペック通りなら HHKB 信者を止めることになる。

初期設定とハマったところ

デフォルトだと「Office モード」というモードらしく、キーのリマップが効かないモードになっている。 Fn+M キーを同時に2秒押して Program モードというモードにしなくてはいけない。

専用アプリを使ってのキーカスタマイズはこのモードでしか適用されない。

キーが効きにくい……

試しうちしてすぐ気付いたが、左 Ctrl (というか位置的には Caps-Lock)、スペース、RET、Shift が叩くように入力しないと反応しない、または普通に使っていて入力をとりこぼすことがわかった。

https://www.nizkeyboard.com/2019/07/07/some-keys-doesnt-work-look-at-this/ 公式にこういうエントリがあるぐらいなので頻出問題みたい。手順では F2 F10 を押しながらキャリブレーションすると書いてあるけど、単に基準となるキーが変わるだけで、どのキーを押しながらでもキャリブレーションできる。自分の場合は左 Shift + スペースを軽く押しながらキャリブレーションすることで、気になる範囲の取りこぼしはなくなった気がする。

キーボードの信頼性

市販のキーボードは「普通に動く」けれど、それはもうそれだけですごいのだ、ということに気付く。キーボードの信頼性というのはそこで、普段意識するようなことはない。最低限ちゃんと思った通りに入力できなければならない。

NiZ は(自分の場合は)キャリブレーションなしには全く使いものにならないものだった。普通に考えたら初期不良だし、キーボードをキャリブレーションしたらなおるとか思いもしないだろう。そういう初期調整も含めての安価な値段だと思う。

NiZの良い点

良い点は冒頭でもほとんど記したけど

  • 打鍵が軽い
  • スコスコしたスムーズな打鍵感
  • 打鍵音が静か (HHKB と比べると雲泥の差)
  • カスタマイズ性
  • Bluetooth

とかいろいろある。このキーボードにしかない特徴があるので、うまくキャリブレーションするか、あたり個体を掴めれば良い選択かもしれない。

とりあえず普段遣いできる感じのキャリブレーションはすることができたので、しばらく使ってみるつもり。

細かいメモ

USB デバイスとしては `ID 0483:512a STMicroelectronics 66EC-S ` で認識されている。STM32 っぽい……と言いたいところだけど、中華デバイスは STM32 互換の MCU に STM32 のツールで作ったファームウェアを書いていたりするので、これだけでは判断できない。