RICOH THETA Sをnode.jsから使ってみる

#はじめに
![theta s.png](https://qiita-image-store.s3.amazonaws.com/0/95484/6a59b9f3-b480-6918-94db-9201319d1677.png)

機能アップしたRICOH THETA Sをnode.jsから操作してみる。
[公式](https://developers.theta360.com/ja/docs/v2/api_reference/)によるとAPIがGoogleのOpen Spherical Camera API Version 1.0準拠になったということなので、OSCを使って制御してみる。

#準備
THETAはP2Pのwifi接続でアクセスするので、PC側にwifiアダプタをつなぎ、通信できるようにした。
ノートPC環境でwifi接続できる環境でも良いのだが、THETAと接続すると通常のインターネット環境が失われるため、既存のネット環境は維持しつつ、THETAをつなげるには２つのネットワークアダプタが最低限必要。
今回は有線で通常のネットワーク環境を維持しつつ、wifiはTHETAに繋げるという構成にした。

##curlで接続確認
[公式](https://developers.theta360.com/ja/docs/v2/api_reference/)のAPI ReferenceによるとTHETAのIPアドレスとポートは`192.168.1.1:80`なので、このアドレスに対してcurlでコマンドを投げてみる。

`curl http://192.168.1.1:80/osc/info`でinfoをとってみる。

レスポンス

```json
{
    "manufacturer": "RICOH",
    "model": "RICOH THETA S",
    "serialNumber": "00XXXXXX",
    "firmareVersion": "01.11",
    "supportUrl": "https://theta360.com/en/support/",
    "endpoints": {
        "httpPort": 80,
        "httpUpdatesPort": 80
    },
    "gps": false,
    "gyro": false,
    "uptime": 222,
    "api": [
        "/osc/info",
        "/osc/state",
        "/osc/checkForUpdates",
        "/osc/commands/execute",
        "/osc/commands/status"
    ]
}
```

`curl -X POST http://192.168.1.1:80/osc/state`でTHETAの状態を取得してみる。

レスポンス

```json
{
    "fingerprint": "FIG_0002",
    "state": {
        "sessionId": "SID_0000",
        "batteryLevel": 1,
        "storageChanged": false,
        "_captureStatus": "idle",
        "_recordedTime": 0,
        "_recordableTime": 0,
        "_latestFileUri": "",
        "_batteryState": "disconnect"
    }
}
```

#node.jsからのアクセス
Open Spherical Camera APIをラップした[osc-client](https://www.npmjs.com/package/osc-client)を使ってみる。
takePicture()で写真を撮り、jpegイメージを取得できるようにした。

```js:theta.js
var fs = require('fs');
var OscClientClass = require('osc-client').OscClient;
 
var domain = '192.168.1.1';
var port = '80';
var client = new OscClientClass(domain, port);
var sessionId;
var filename;
 
client.startSession().then(function(res){
  sessionId = res.body.results.sessionId;
  return client.takePicture(sessionId);
})
.then(function (res) {
  var pictureUri = res.body.results.fileUri;
  console.log('pictureUri :%s',pictureUri);
  
  var path = pictureUri.split('/');
  filename = path.pop();
  return client.getImage(pictureUri);
})
.then(function(res){
  var imgData = res.body;
  fs.writeFile(filename,imgData);
  return client.closeSession(sessionId);
});
```

`node theta.js`で実行すると撮影した後にfileUriを表示して、ファイルを取り込む。

```
node theta.js
pictureUri :100RICOH/R0010009.JPG
```
実行ディレクトリにファイルが作成される。
![theta.png](https://qiita-image-store.s3.amazonaws.com/0/95484/d51f1507-584e-b9f4-5368-9bfa859f7ef1.png)

IPアドレスとポートは[API Reference](https://developers.theta360.com/ja/docs/v2/api_reference/)に記載のものを使用する。
P2P接続、かつクライアントは1台しか繋がらないので別に晒してもOK。

処理の概要は以下のとおり。
1. startSession()でsessionIdを取得する
2. 取得したsessionIdを指定してtakePicture()で撮影。
3. takePicture()のレスポンス(fileUri)を指定して、getImage()でファイルイメージを取得。
4. closeSession()でセッションクローズ。

#さいごに
新しいtheta sはOpen Spherical Camera APIに準拠したため、より簡単にアプリの構築が可能になっている印象。
結構売れているみたいだし、これから面白い使い方が増えてくるのではないかな？

個人的にはwifiの切り替え、thetaアプリの起動など、一連の作業が面倒なのでNFCタグを利用して、自動化しようと考え中。
完成したら投稿予定。