Raspberry PiとテレビをHDMI接続してテレビのON/OFFを確認する

以前に[Raspberry PiとMac or Windows PCを有線で直接繋いでさくっとSSH接続する](http://qiita.com/mascii/items/7d955395158d4231aef6)という記事を書いていて、HDMI対応ディスプレイとキーボードをセットしなくてもさくっとSSH接続してRaspberry Piで遊べることをアピールしていたのですが、今回は逆にあまり使うことのなかったRaspberry PiのHDMI端子を活用し、テレビのON/OFF(STANDBY)状況をRaspberry Piから確認してみたいと思います。

今回はHDMIの**CEC**(Consumer Electronics Control)という、機器間を制御するリンク機能を活用します。
SONYだとブラビアリンク、東芝だとレグザリンク、パナソニックだとビエラリンク、SHARPだとAQUOSファミリンク、などと呼ばれています。

# 動作環境
## Raspberry Pi側
- Raspberry Pi 2 Model B
    - Raspbian Jessie Lite 2016-09-23
        - イメージをMicroSDに書き込んだ直後の状態
- Raspberry Pi 3 Model B, Raspberry Pi Zero W
    - Raspbian Jessie Lite 2017-07-05
        - こちらの記事で検証をしています: [Raspberry Pi Zero WはPi 3と同じように使える？IoTなnpmパッケージを試してみた！](https://qiita.com/mascii/items/1131a08ed02dc112b765)

## テレビ側
- SONY BRAVIA KDL-46HX850

# インストール
## GitやVimのインストールと`cec-client`のインストール
```
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install git vim cec-utils -y
```

## Node.jsのインストール
Node.jsとnpmの最新版を[Raspberry PiにNode.jsとnpmの最新版をインストールする](http://qiita.com/mascii/items/77c685df65c4cbca9315)を参照してインストールします

## リポジトリのクローンと`npm install`
こちらのリポジトリにサンプルを公開していますので、cloneしてお使いください:
https://github.com/mascii/raspberrypi-hdmi-cec

`npm install`で`node-cec`と`onoff`(LEDを制御して動作確認に使用) が入ります。

```
git clone https://github.com/mascii/raspberrypi-hdmi-cec.git
cd raspberrypi-hdmi-cec
npm install
```

## Raspberry Pi起動時にTVの入力切替しない・電源を入れないための設定
`/boot/config.txt`に`hdmi_ignore_cec_init=1`を追記することで、Raspberry Pi起動時にTVの入力が切り替わったり、TVの電源が入ったりしなくなります。
突然、Raspbianの黒い画面出るとびっくりしちゃいますので、設定しておきます。

```
echo hdmi_ignore_cec_init=1 | sudo tee -a /boot/config.txt
```

# テレビのON/OFF状況を取得してみる
## `cec-client` で信号を調べる
`cec-client -m -d 8 -b -r` でテレビからどんな信号が来ているか確認できます。

```text:Raspbian
pi@raspberrypi:~/raspberrypi-hdmi-cec $ cec-client -m -d 8 -b -r
starting a monitor-only client. use 'mon 0' to switch to normal mode
log level set to 8
using base device '0'
No device type given. Using 'recording device'
CEC Parser created - libCEC version 3.0.1
no serial port given. trying autodetect: 
 path:     Raspberry Pi
 com port: RPI

opening a connection to the CEC adapter...
waiting for input
TRAFFIC: [             218]	>> 0e:90:00
TRAFFIC: [            2947]	>> 0e:83
TRAFFIC: [           17947]	>> 0e:83
TRAFFIC: [           32947]	>> 0e:83
TRAFFIC: [           47948]	>> 0e:83
TRAFFIC: [           62948]	>> 0e:83
TRAFFIC: [           77951]	>> 0e:83
TRAFFIC: [           92949]	>> 0e:83
TRAFFIC: [           94908]	>> 0f:36
```

どうやらテレビがONの時は `0x83`([`cectypes.coffee`](https://github.com/patlux/node-cec/blob/master/src/lib/cectypes.coffee)を調べると `GIVE_PHYSICAL_ADDRESS`)が定期的に来て、テレビがOFFにする時に `0x36`(`STANDBY`)が来るようです。
この辺は機種依存の可能性がありますので、適宜調べて変更してください。もしよろしければ、調査結果をコメントで投稿してください！

`cec-client` で表示された `0e:90:00` のような信号は、**[CEC-O-MATIC](http://www.cec-o-matic.com/)**というサービスでどのような内容なのか調べられそうです。
<img width="480" alt="CEC-O-MATIC.png" src="https://qiita-image-store.s3.amazonaws.com/0/137045/7fa8c66a-887d-0224-4d79-c97865fe8c24.png">


## Node.jsでテレビのON/OFF状況を取得
先ほどクローンしたリポジトリ内にある `hdmi.js` は、`0x83`(`GIVE_PHYSICAL_ADDRESS`)が来るとテレビがONになった可能性があるので、ON/OFF状況を確認するコマンドを送ってテレビのON/OFF状況を確認します(OFF時であってもスタンバイ状態なので確認できる)。

`0x36`(`STANDBY`)が来るとテレビがOFFになったと判定します。

また、起動時の１回だけON/OFF状況を確認するコマンドを送ります。

`0x83`と`0x36`が稀に前後して到着することがあるようなので、このような処理にしています。

![hdmi-led.gif](https://qiita-image-store.s3.amazonaws.com/0/137045/a3802eeb-9290-338c-bd1b-9e2066b1678f.gif)
`hdmi-led.js`では、`hdmi.js`の動作をベースに、TVがオンになると`GPIO 22`ピンのLED(青)が、TVがオフになると `GPIO 24`ピンのLED(赤)が点灯します。

# IoTとして活用
象印が[みまもりほっとライン](http://www.mimamori.net/)という、電気ポットの使用状況による高齢者安否確認サービスを提供していますが、今回紹介したHDMIのCEC機能を用いることで電気ポットではなくテレビを用いた安否確認システムを構築できそうです。
通信に[SORACOM Air](https://soracom.jp/)、サーバーに[Milkcocoa](https://mlkcca.com/)を用いた構成例が考えられると思います。

![mimamori2.png](https://qiita-image-store.s3.amazonaws.com/0/137045/fa82ddd4-bc0c-1856-aae4-965a2c65e561.png)

上図の構成であれば、テレビとのHDMI接続とモデムのUSB接続のみで済んでしまうので、**電子工作不要で**高齢者見守りデバイスを製作できるかと思います。

通信に必要なモデムですが、L-05Aといった３G対応の中古のものであればヤフオクやメルカリで1000円〜2000円程度で手に入る感じです。SORACOM Airの通信料は、テレビのON/OFF時の通知のみであれば他の案件での経験から月額350円程度だと推測します。

# 参考サイト
[Raspberry Pi のcec 制御とHDMIのオンオフ - それマグで！](http://takuya-1st.hatenablog.jp/entry/2015/11/10/110558)