普段使っているスマートディスプレイ「Google Nest Hub」ですが、結局のところお気に入り画像と時計表示にしか使っていない。。。
それぐらいのことであれば、自作もできるだろうと思い、CordovaとAndroidを使って、自分カスタムのスマートディスプレイを作成しました。以降、カスタムスマートディスプレイ(CSD)と呼びます。
まずは、簡単に構成を説明した後、その中で利用している要素技術を説明します。
機能としては、まずは以下の3つの機能を付けますが、今後拡張していければと思います。
・時刻表示
・お気に入り画像の背景表示
・音楽のバックグラウンド再生
システム構成
以下のような構成になります。
・Androidタブレット
これが今回作成するCordovaアプリが動作するAndroidタブレットです。スマートディスプレイとして設置するので、大きめがよいかと思います。私の場合は、AndroidタブレットであるAmazon Fire 8インチを使いました。
・BLEスピーカ
これは、必須ではありません。Androidタブレットで音楽再生しますが、音質が気になるようであれば、外付けでBLE/Bluetoothで接続できるスピーカを用意するのがよいです。また、GoogleのスマートスピーカであるGoogle Nest Miniもスピーカにすることができます。
・ラズパイ
音楽再生や背景画像のコンテンツファイルを配置し、Node.jsサーバを立ち上げて、AndroidタブレットやESP32と通信します。常時起動させることになります。ラズパイである必要はなく、通常のPCでも問題ありません。
・ESP32
Androidタブレットのタッチパネルで操作するのでもよいのですが、せっかくなので、赤外線リモコンを使って操作できるようにしました。赤外線を扱うために、赤外線送受信ユニットが必要であり、それを制御するためにESP32を採用しました。私の場合は、M5StickCを使いました。
・赤外線送受信ユニット
赤外線の送受信のためのデバイスです。ESP32とはGroveケーブルで接続します。
・赤外線リモコン
赤外線を送信するためのリモコンです。よく一般に「国内外メーカ〇〇社対応のテレビリモコン」などの名前で売られているものです。赤外線コードは何でもよいので、選ぶとしたら、ボタンが大きめで机に置いたままでも使えるものがよいかと思います。
画面構成
通常は、背景画像にお気に入りの画像が表示され、定期的に更新されます。また、時刻と日付が左下に表示されます。
Androidには照度センサがついていますので、照度を定期的に計測し、周りが暗くなった時には、背景画像の表示をやめて黒い背景にし、時刻と日付を画面の真ん中に表示します。
バックグラウンドで音楽を再生するようにしますので、画面タップまたは赤外線リモコンからの赤外線送信で、再生する音楽ファイルの選択時のための画面が表示されるようにします。
利用した技術
・Cordovaを採用
・フロントエンドとして、Vue、Vuex、Bootstrapを採用
・常時表示
・最大画面表示
・照度計測
・UDP送受信
・アプリ固定起動
・音量操作
・音楽再生
・赤外線送受信
Cordovaを採用
CSDのアプリとして、ブラウザを使う手もありましたが、後述するように、リジュームさせず常時表示させたり、アプリ固定起動させたり、と考えると、ブラウザでは実現できず、ネイティブアプリが適していました。また、Android Studioを使って、完全ネイティブアプリとして作成するものありますが、Cordovaであれば、表現力豊かなHTMLやJavascriptで手軽に実装できました。
常時表示
Androidは、何もしないとディスプレイがOffとなってしまいます。便利な機能ではあるのですが、スマートディスプレイとして常時表示させたい場合には対策が必要です。
そのためのCordovaプラグインがありますので、利用させていただきました。
// 画面常時On
window.powermanagement.acquire();
上記を呼ぶだけです。。。
最大画面表示
ブラウザの場合は、上下にアドレスバーなどが表示され、スマートディスプレイとしては少々邪魔です。
Cordovaアプリであれば、特に何も設定しなくても、ディスプレイ全面で表示してくれます。
照度計測
Androidには、加速度センサなど様々なセンサがついていますので、使わない手はないです。今回はその中で照度センサを使います。android.sensor.lightと呼ばれます。
照度センサを使うために、Cordovaプラグインを作成しました。
// 照度取得開始
const light_type = "android.sensor.light";
samplesensor.addDevice(light_type);
// 定期的に照度を取得し、背景表示変更
setInterval(async () =>{
const values = await samplesensor.getValue(light_type);
this.background_change_dark(values[0] < BRIGHTNESS_THRESHOLD);
}, BRIGHTNESS_UPDATE_INTERVAL);
UDP送受信
Node.jsサーバとPullとPushの双方向通信をしたく、PullはHTTP Post(Json)を利用しますが、Pushにはサーバとして立ち上げる必要があり、お手軽にUDP受信を利用しました。
こちらも、Cordovaプラグインを作成しました。
こんな感じで使います。
// UDPパケット受信開始
sampleudp.initialize(UDP_LOCAL_PORT);
sampleudp.registerReceiveListener(this.onUdpReceived);
console.log("SampleUdp initialized");
// ・・・
onUdpReceived: async function(data){
console.log("udp received: ", data);
// ・・・
}
アプリ固定起動
最近のAndroidでは、たいていアプリの固定起動ができます。今回作成したCordovaアプリを固定起動に指定すると、戻るボタンを押してもホーム画面に戻ることはなく、常にCordovaアプリが起動した状態になるので、非常に都合がよいです。
AndoidOSの標準機能なので、特に開発は不要です。
音量操作
AndroidOSのメディア音量をCordovaアプリから操作します。そのためのプラグインを利用させていただきました。
こんな感じで使います。
// 音量を上げる
volume_up: function(){
console.log("volume up");
cordova.plugins.VolumeControl.getVolume(volume =>{
volume = parseFloat(volume);
if( volume >= 1.0 - VOLUME_STEP )
volume = 1.0;
else
volume += VOLUME_STEP;
cordova.plugins.VolumeControl.setVolume(volume);
this.volume = volume;
});
},
// 音量を下げる
volume_down: function(){
console.log("volume down");
cordova.plugins.VolumeControl.getVolume(volume =>{
volume = parseFloat(volume);
if( volume <= VOLUME_STEP )
volume = 0.0;
else
volume -= VOLUME_STEP;
cordova.plugins.VolumeControl.setVolume(volume);
this.volume = volume;
});
音楽再生
Cordovaではお決まりの機能ですね。以下のプラグインを利用します。
こんな感じで使います。
this.media = new Media(this.play_item, () =>{
// 再生完了
}, (err) =>{
// エラー発生
});
this.media.play();
赤外線送受信
赤外線の送受信には、ESP32に助けを借ります。
Node.jsサーバとUDPで双方向通信できるようにし、ESP32に取り付けた赤外線送受信ユニットで赤外線信号を検出すると、Node.jsサーバにUDPパケットで知らせます。また、赤外線信号を送信したい場合には、Node.jsサーバからESP32にUDPパケットを送信することで知らせます。
利用しているCordovaプラグイン一覧
・cordova-plugin-device
・cordova-plugin-media
・cordova-plugin-networkinterface
・cordova-plugin-powermanagement
・cordova-plugin-samplesensor(自作)
・cordova-plugin-sampleudp(自作)
・cordova-plugin-volume-control
終わりに
現在、このカスタムスマートディスプレイ(CSD)の紹介資料やカスタム方法を記述した書籍を作成しました。
「AndroidとCordovaで自分カスタムスマートディスプレイ」
https://poruruba.booth.pm/items/4330100
とりあえず、ソースコード一式は以下のGitHubに上げておきます。
以上