製品正規の赤外線リモコンが使えなくなったのでIRKitを用いて自作した


新型コロナウィルスの影響で急遽帰国することになり実家に帰省していたら身体が鈍ってしまったので昔購入したフィットネスマシン SURF BOY を久々に使ってみようと思ったのだけれど、高温多湿な場所に長期間保管していたため、リモコンが反応しなくなっていた。この製品は既に製造中止になっており、正規のリモコンは中古以外で購入することはできなさそうだったのだが、幸い[ネット上で赤外線コードを入手することができた](http://tutujith.blog.fc2.com/blog-entry-145.html)ため、[IRKit](https://getirkit.com/)で操作することを試みた。
（IRKit はリモコンのコードを受信器で読み取ってそれをHTTP経由で再利用することが可能なデバイスなので、コピー元のリモコンが使用できない場合は自分でコピー元のコードを作る必要がある。）


## 対象の規格

まずは SURF BOY の赤外線コードを見てみると、ON/OFF と動作切替の2種類のコードがあり、それぞれ `5A0BF400FF` と `5A0BF4807F` だとわかる。一般的に赤外線通信ではこのようなデータを送る前後に予め決められたリーダー部とトレイラ部という合言葉のような信号を送る必要があり、この製品では以下のように規定されているようだ。

- リーダー部: ON 4.6ms -> OFF 4.4ms
- トレイラ部: ON 0.6ms

そしてこの製品ではリモコンから送られてくる信号をどのように 0/1 と判定するかという基準が以下のように規定されているようだ。

- 0: ON 0.6ms -> OFF 0.6ms
- 1: ON 0.6ms -> OFF 1.6ms

つまり、5 (0101) をデータとして送りたい場合には ON(0.6ms) -> OFF(0.6ms) -> ON(0.6ms) -> OFF(01.6ms) -> ON(0.6ms) -> OFF(0.6ms) -> ON(0.6ms) -> OFF(01.6ms) とすればよい（明確に書かれていないが通常 LSB first 形式らしい）。


次にIRKitに赤外線信号を指定する方法を見てみる。
[赤外線信号を表すJSONについて](https://getirkit.com/#toc_5)

Key | Description
--- | :--
format | "raw"のみ
freq | 赤外線信号のサブキャリア周波数を表します。38 または 40 のみ。単位 [kHz]
data | 赤外線信号は、サブキャリア周波数のオン・オフからなります。IRKitデバイスはオン→オフ間の時間、オフ→オン間の時間を 2MHz のカウンタで数えます。dataには、カウンタで数えた数をオン・オフの回数分ならびます。

大事なのがサブキャリアが 38 もしくは 40 kHz のみで、オン→オフ間の時間、オフ→オン間の時間を 2MHz のカウンタで数えるということの2点。
SURF BOY のサブキャリアは 38kHz らしいので問題なく操作できそう。

## IRKit にリクエストするための JSON の作成

`format` と `freq` は既に決まっているので、リーダー部とデータ部とトレイラ部をそれぞれIRKitの規格に合わせて JSON に指定する `data` を作成していく。2MHz ということは1秒間に 2,000,000 回振動するということなので、必要な秒数に 2,000,000 を乗算すればよい。サブキャリアの関係上上限値があるが、今回は問題ない。

**リーダー部**

```
0.0046 * (2,000,000/1) = 9200
0.0044 * (2,000,000/1) = 8800
```

**データ部**
上記の 0/1 の規定の通りに ON <-> OFF の指定時間になるように変換する。

```
// 0
0.0006 * (2,000,000/1) = 1200
0.0006 * (2,000,000/1) = 1200

// 1
0.0006 * (2,000,000/1) = 1200
0.0016 * (2,000,000/1) = 3200
```

これを ON/OFF と 動作切替 それぞれのコードに適用する。
`5A....` -> `0101 1010 ....` -> `1200,1200,1200,3200,1200,1200,1200,3200 1200,3200,1200,1200,1200,3200,1200,1200 ....`

**トレイラ部**

```
0.0006m * (2,000,000/1) = 1200
```

## リクエストしてみる

上記で作成した最終的な成果物をカンマ区切りで並べて data に含め、IRKit に post /messages で送信すればよい。（もしもBonjourの.localホスト名を解決できないクライアントだった場合はIPアドレスを調べてそれを指定する必要がある。詳しくは[こちら](IRKit-Device-API)。）

curl の例

```
curl -i "http://irkitxxxx.local/messages" \
     -H "X-Requested-With: curl" \
     -d '{ \
     		"format":"raw", \
     		"freq":38, \
     		"data":[9200,8800,1200,1200,1200,3200,1200,1200,1200,3200,1200,3200,1200,1200,1200,3200,1200,1200....,1200] \
     	 }'
```

## 家族にも使えるようにする

ここまでで IRKit を通して SURF BOY が操作できるようになったものの、このままでは多少知識のある人にしか使えないし、使い勝手も悪いのでスマートフォンから操作できるようにしたい。機能追加もあるだろうからできる限り共有の手間は省きたい。

### iOSアプリにする -> 配布の煩雑さで断念
まず考えたのが POST リクエストするだけのシンプルなiOSアプリ。家族に配布するので再配布の手間を減らすため、設定ファイルをWEB上に置いて起動時に読み込み、設定ファイルに従ってアプリ側で必要なだけボタンを作成しタップ時に IRKit にリクエストを送るというシンプルなものだった。作成段階では SURF BOY とシーリングライトのみ操作できるようにしていたがゆくゆくは気が向いた時にエアコンやテレビなど随時設定ファイルに追加していく予定だった。しかし、実機配布する段階になって僕の開発者証明書が切れていたり、登録端末の上限に達していてこれ以上追加できない（期限切れなので削除もできない）ことがわかり、尚且つ新規アカウントでは頻繁に再インストールが必要なことがわかったため断念。

### ショートカットを作成して共有

単にPOSTリクエストを送りたい & 共有したい だけだったので改めて調べてみたところアプリを自作しなくてもショートカットアプリで実現できることが判明し、ショートカットを作成してそれをAirDropで共有することにした。
ヘッダーの `X-Requested-With` については[値はなんでも良さそうだった](https://github.com/irkit/device/blob/f80e8374bb57c3db1eb42a5dc002524c0c031eae/firmware/src/IRKit/GSwifi.cpp#L560)ので区別する必要はなさそうだったけれど、`shortcut` とした。

![IMG_3882.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29186/74c7cf63-eb96-c573-b404-1285bfc89dd5.png "IMG_3882.PNG")