Cisco Webex Devices 新機能 USB 入力デバイスを試す

# はじめに

Cisco Webex Devices の新機能を確認しようと年末に[What's New in Cisco Webex Room and Desk Devices](https://collaborationhelp.cisco.com/article/en-us/n4lhv2s) を読んでいると、1. USB 入力デバイスのサポート、 2. HTTP POST のサポート、 3. デフォルトボタン非表示機能の3つの新機能がリリースされたことを知りました。この記事では、 USB 入力デバイスを確認します。

# 概要
Cisco Webex Devices には USB ポートを持つものがあります。このポートに USB キーボードなどのいわゆる入力デバイスを接続することでそのアクションをマクロに記載することができます。詳細のドキュメントは[Support for Third Party USB Controllers](https://collaborationhelp.cisco.com/article/en-us/ntixxg2)にあります。
用途ですが、USB テンキーを接続し、数字の入力をアシストしたり、キーボードのキーボードの 1 を押したら決められた場所に発信や、設定変更、 USB キー入力に変換してくれる赤外線受光器を利用して赤外線リモコンを接続などさまざまな利用シーンが考えられます。

サポートデバイスは下記の一覧になります。

- Codec Plus
- Codec Pro
- DX70 and DX80
- Room 55 and 55 Dual
- Room 70 and 70 G2
- Room Kit


# DX80 と USB キーボードで実験

DX80 を Cisco Webex Control Hub に登録し、[高度な設定](https://collaborationhelp.cisco.com/article/ja-jp/n5pqqcm)からローカルの管理者 localadmin を事前に作成しました。

Setup > Peripherals から InputDevice Mode を On にします。

<img width="808" alt="スクリーンショット 2019-01-02 1.15.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/216119/b7ef52c0-257c-1331-63fc-a2e850eb20b1.png">

USB キーボードを差し込みます。 Status > Peripherals で確認します。

<img width="831" alt="スクリーンショット 2019-01-02 1.18.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/216119/f84c0abd-922c-e199-1919-2ba777d6a9e2.png">

Dell キーボードの場合 2 つ ID が見えますね。 念の為、PFU のキーボードを接続してみました。こちらは ID が一つとなります。

<img width="849" alt="スクリーンショット 2019-01-02 1.20.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/216119/b24c2d29-f242-b9e9-4919-c339b8ffc3a3.png">

マウスも認識します。

<img width="861" alt="スクリーンショット 2019-01-02 1.23.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/216119/11b74525-b76e-8c92-c153-452a5d1dae58.png">

ただ、これだけではキーボードは動作しません。あくまで認識し、入力を受け付けるようになっただけで、その入力に応じて何をするかは定義してあげる必要があります。

SSH で端末にログインします。

```
$ ssh -l localadmin 10.65.74.37
Password: 

*r Login successful
OK
```

入力に応じてどのようなイベントが発生するかモニタするため、下記のコマンドを入力します。

```
xFeedback Register /event/UserInterface/InputDevice 
```

ちなみに終了するときは下記のコマンドです。

```
xFeedback Deregister /event/UserInterface/InputDevice 
```

マウスの左クリックイベントを拾ってみました。

```
*e UserInterface InputDevice Key Action Key: CODE_273
*e UserInterface InputDevice Key Action Code: 273
*e UserInterface InputDevice Key Action Type: Pressed
** end
*e UserInterface InputDevice Key Action Key: CODE_273
*e UserInterface InputDevice Key Action Code: 273
*e UserInterface InputDevice Key Action Type: Released
** end
```
キーボードだとこんな感じです。

```
*e UserInterface InputDevice Key Action Key: KEY_6
*e UserInterface InputDevice Key Action Code: 7
*e UserInterface InputDevice Key Action Type: Released
** end
*e UserInterface InputDevice Key Action Key: KEY_BACKSPACE
*e UserInterface InputDevice Key Action Code: 14
*e UserInterface InputDevice Key Action Type: Pressed
** end
*e UserInterface InputDevice Key Action Key: KEY_BACKSPACE
*e UserInterface InputDevice Key Action Code: 14
*e UserInterface InputDevice Key Action Type: Released
** end
*e UserInterface InputDevice Key Action Key: KEY_ENTER
*e UserInterface InputDevice Key Action Code: 28
*e UserInterface InputDevice Key Action Type: Pressed
** end
*e UserInterface InputDevice Key Action Key: KEY_ENTER
*e UserInterface InputDevice Key Action Code: 28
*e UserInterface InputDevice Key Action Type: Released
** end
```

この Action Type と Action Key をマクロなどで拾ってあげてそのアクションを定義づけしてあげる必要があります。

```Javascript
/**
 * Mouse Click to Call
 * 
 */


// library for communicating with video system
const xapi = require('xapi');
// Dial Destination
const number1 = 'example1@example.com';
const number2 = 'example2@example.com';

function dial(number) {
  console.log('dial', number);
  xapi.command('dial', { Number: number });
}

function listenToGui(event) {
  if (event.Type === 'Pressed') {
    switch (event.Key) {
    case 'CODE_273': 
      // Left-Click
      dial(number1); 
      break;
    case 'CODE_272':
      // Right-Click
      dial(number2); 
      break;
    }
  }
}

xapi.event.on('UserInterface InputDevice Key Action', listenToGui);
```

# キーボードの入力と数字入力をマッピング

キーボードの入力をそのまま端末の入力に伝えるにはどうしたらよいでしょうか？  DX には画面上のキーボード画面の一部のキーを代替してくれる xcommand UserInterface OSD Key Click Key:  コマンドがあります。こちらを利用します。なお、キーの一部は動作しないので、コマンドで実際に入力して確認する必要があります。

```
xcommand UserInterface OSD Key Click Key: 
+             7             F3            Ok            SrcPc
-             8             F4            PhoneBook     SrcVcr
0             9             F5            Presentation  Star
1             C             Grab          Right         Up
2             Call          Home          Selfview      VolumeDown
3             Disconnect    Layout        Square        VolumeUp
4             Down          Left          SrcAux        ZoomIn
5             F1            Mute          SrcCamera     ZoomOut
6             F2            MuteMic       SrcDocCam     
xcommand UserInterface OSD Key Click Key: 1

OK
```

これを利用して、 Dell のキーボードの 10 キーからの入力を受け付けるようにしました。 なお、 Qwerty キーボード側の数字入力と右側の 10 キーとでは Key Action が違い、ここでは 10 キーだけの受付にしています。

```Javascript
const xapi = require('xapi');

function listenToGui(event) {
  let inputChar;
  if (event.Type === 'Pressed') {
    switch (event.Key) {
    case 'KEY_KP0':
      inputChar = '0';
      break;
    case 'KEY_KP1':
      inputChar = '1';
      break;
    case 'KEY_KP2':
      inputChar = '2';
      break;
    case 'KEY_KP3':
      inputChar = '3';
      break;
    case 'KEY_KP4':
      inputChar = '4';
      break;
    case 'KEY_KP5':
      inputChar = '5';
      break;
    case 'KEY_KP6':
      inputChar = '6';
      break;
     case 'KEY_KP7':
      inputChar = '7';
      break;     
    case 'KEY_KP8':
      inputChar = '8';
      break;
    case 'KEY_KP9':
      inputChar = '9';
      break;
    case 'KEY_BACKSPACE':
      inputChar = 'C';
      break;
    case 'KEY_RIGHT':
      inputChar = 'Right';
      break;
    case 'KEY_LEFT':
      inputChar = 'Left';
      break;
    case 'KEY_DOWN':
      inputChar = 'Down';
      break;  
    case 'KEY_UP':
      inputChar = 'Up';
      break;   
    case 'KEY_KPPLUS':
        inputChar = '+';
      break;
    case 'KEY_KPMINUS':
        inputChar = '-';
      break;    
    case 'KEY_KPASTERISK':
        inputChar = 'Star';
      break;    
      
    }
    if (inputChar !== undefined ){
      xapi.command('UserInterface OSD Key Click',{Key: inputChar});
    }
  }
}

xapi.event.on('UserInterface InputDevice Key Action', listenToGui);
```

[ドキュメントの例](https://collaborationhelp.cisco.com/article/en-us/nhqh1mf)では、 PTZ カメラのコントロールを矢印キーで受け付けるようにしています。機能とマッピングすることで、さまざまな使い方が生まれるかもしれませんね。