
先日、NGK2022Sという名古屋合同懇親会という名のIT系コミュニティの合同新年会のLT大会が開催されました。
そのイベントの中で以下のような内容のLTを行いました。

一応、コロナ禍で名ばかりのSeeedJP UGのメンバーにはなっているのですが、SeeedさんのreTerminalのことについて紹介しました。
LTの中ではちょっと思いついたネタを紹介してみたのですが、折角なのでそのネタを実際に作ってみようかなと思い今回のエントリに至ります。
そのネタはこんなものになります。
Node-REDでのリアルタイムTweetのwordcloud画像作成し、reTerminalの画面に表示する

詳しくは以下に書いていきます。
最後にもまとめていますが、このデバイスは本当にNode-REDと相性のよいデバイスだなと思います。
今回の手順
作ろうとするものの大まかな手順としては以下の様になると思います。
Node-REDのインストールwordcloudモジュール(およびコマンド)のインストール- テスト用テキストのダウンロード(
alice.txt)(これはやらなくてもよい) alice.txtを使用してwordcloud画像を作成する(これはやらなくてもよい)- 日本語フォントを取得する
Node-REDの拡張機能をインストールする(Twitter、kuromoji、DashBorad、image-output、base64、cron)- フローを作成する
- 実行する
では順を追って簡単に説明していきたいと思います。細かくは別のエントリにしてもいいのかも。
Node-REDのインストール
これはNode-REDを使用している人からは見慣れた手順となります。このコマンドではNode-REDをインストールするためにNode.jsの比較的新しいバージョンがインストールされます。また、古いバージョンのNode-REDをインストールしている場合にはバージョンアップも行われるので、バージョンの縛りがある方は注意が必要です。
$ bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
あとは、Node-REDの起動はサービス化してもいいと思いますが、簡単にするならCLIでnode-redと起動すればOKです。デフォルトではセキュリティが問題ありですのでパスワードの設定は行うようにしてください。今回は説明は省略しています。
wordcloudモジュール(およびコマンド)のインストール
wordcloudモジュールはテキストから頻度に応じて文字を大きく表示してくれるという見える化のできる機能を提供するものになります。今回はNode-REDからこの機能を提供してくれるものを探していたのですが、簡単に作るものがなかなか見当たらなかったので今回はコマンドラインツール(wordclo_cli)をexecノードから使用することにしました。Node-REDから実行できるとなお良かったと思いますが、今回は手軽さを求めたのでこちらの方法にしています。
参考(wordcloudモジュールのインストール)
インストールに関しては以下のコマンドを実行すればよいのですが…
$ pip3 install wordcloud
上記コマンドの実行でインストール処理は完了するのですが、そのままではnumpyモジュールのバージョンに関するエラーが発生し、wordcloud_cliのコマンドも実行できません。そこで、関係ありそうなモジュールの再インストールを行おうと以下のように実行してみますが、それでもうまくいきません。
$ pip3 install numpy $ pip3 install pillow $ pip3 install wordcloud
これは、バージョンの問題になるようなので、そのままインストールしても、想定より古いモジュールが既にインストールされていますというメッセージが表示されます。
RuntimeError: module compiled against API version 0xe but this version of numpy is 0xd
そこで、以下のようにしてオプションスイッチを追加して、強制的にnumpyモジュールのバージョンアップを行います。
$ pip3 install numpy --upgrade --ignore-installed
これでモジュールのインストールもwordcloud_cliのコマンド実行できるようになります。ただ、インストール先のディレクトリはユーザのホームディレクトリにインストールされ、そのパスは~/.local/bin/wordcloud_cliとなっているのでこちらをパス指定して実行してください。解析用のテキストとしてalice.txtを使用したので、それを取得してからwordcloud画像を生成してみます。
$ wget https://raw.githubusercontent.com/amueller/word_cloud/master/examples/alice.txt $ ~/.local/bin/wordcloud_cli --text alice.txt --width 640 --height 480 --imagefile wordcloud.png
alice.txtのwordcloud画像

日本語フォントを取得する
先程はアルファベットの文章を使っていたので、システムフォントを使えばよかったのですが、今回はTwitterのツイートの文字情報を使用しているので、表示されるテキストも自ずと日本語になります。以前はWindows環境で開発をしていたのでフォントもメイリオなどのWindowsフォントで良かったのですが、これらフォントはWindowsでのみ使用を認めているので、そのままフォントファイルをコピーしてRaspberryPiなどで使用するのはちょっと問題ありかなと思います。なので、今回はフリーのフォントであるIBM/plexフォントを使用します。
過去記事参考
インストールするフォントのリポジトリは以下になります。
今回はIBMPlexSansJP-Bold.ttfというフォントを使用していくことにします。
リポジトリからフォントを取得して画像生成を行うパスに予めコピーしておきます。
取得は以下のようにします。
$ wget https://github.com/IBM/plex/raw/master/IBM-Plex-Sans-JP/fonts/complete/ttf/hinted/IBMPlexSansJP-Bold.ttf

Node-REDの拡張機能をインストールする(Twitter、kuromoji、DashBorad、image-output、base64、cron)
拡張ノードのインストールは、フローエディタの左上にある、【三】(ハンバーガーメニュー)をクリックして、プルダウンメニューから【パレットの管理】をクリックして選択します。

ユーザー設定のダイアログが開いたら【ノードを追加】タブをクリックし、

入力ボックスに追加する拡張ノードの名前を入れて検索し、リスト表示された結果の【ノードを追加】ボタンをクリックしてインストール作業をしていきます。

確認ダイアログが表示されたら、【追加】ボタンをクリックしてください。

今回はデフォルトのノード以外に拡張ノードとして以下のものを使用していきます。
- Twitter(
node-red-node-twitter) … Twitterのツイートを取得する機能 - kuromoji(
node-red-kuromoji) … 日本語の分かち書き(品詞分解)を行う機能 - DashBoard(
node-red-dashboard) … 情報表示を行うWebダッシュボードの機能 - image-output(
node-red-contrib-image-output) …Node-REDのフローエディタ内に画像を表示するデバッグ向け機能 - base64(
node-red-node-base64) … バイナリデータをBASE64形式に変換する機能(image-outputのために必要) - cron(
node-red-contrib-cron) … 定期実行の機能(cronの設定のように定期実行の設定ができる)
これらの拡張ノードのインストールに関しては、過去のエントリにも記載しているのでそちらを参照してください。
Twitter参考
すべての拡張ノードをインストールしたら次に進めます。
フローを作成する
拡張ノードのインストールが終われば、あとはフローの作成になります。 今回は処理を大きく3つに分けています。

- Twitterからツイートを取得し、正規表現で不要な情報を廃棄、分かち書きと品詞分解を行い必要なものだけを
log.txtに格納する - 定期的に
log.txtを使用してwordcloud画像を生成し、Webダッシュボードに表示する - 1時間毎に画像のバックアップと
log.txtの作り直し
1つ目をlog.txt生成フロー、2つ目をwordcloud画像表示フロー、3つ目をバックアップフローと呼ぶことにします。
フローは以下のように構成しています。
1)log.txt生成フロー

基本的な動作は以下のようになります。
- Twitterからハッシュタグ検索をし取得されたツイートを取得。(TwitterのAPIの認証に必要な情報は自身のアプリを作成し設定を行います)
- リツイートの情報でないものを取得。
- ツイートの本文のみを取得
- ツイート内のName、ハッシュタグ、URLなどを正規表現で削除
Kuromojiで分かち書きと品詞分解→リスト化されて出力- 品詞(動詞、形容詞、形容動詞、固有名詞、名詞)のみ抽出
- 活用形のある品詞に関しては語句基本形を抽出
- 単語の取得
- 不要語句を削除(あまり意味のない単語はないほうがよいので)
- ログファイル(log.txt)に書き込み
4の処理は正規表現の部分が冗長なのでサブフロー化しました。

正規表現での語句の入れ替えに関してはNode-REDのchangeノードを使うと視認性が悪くなるのでfunctionノードで記述するか迷ったのですがサブフローにしています。
wordcloud画像表示フロー

こちらのフローは以下の処理を行っています。
- 毎分毎トリガを生成
- 画像を生成(
wordcloud_cliを実行) - 画像をバイナリデータとして読み込み
- バイナリデータを
base64化 - デバック用にフローエディタに表示
- Webのダッシュボードに表示
Dashboardに表示するときには画像のバイナリデータをbase64化する必要があるようです。画像用のタグはないのでDashboardのtemplateノードにタグを直接記載しています。
バックアップフロー

こちらのフローは以下の処理を行っています。
- 1時間毎にトリガを生成(
cronで行っています) - 時刻情報からバックアップ画像ファイル名を生成
- 画像ファイルのアーカイブ保存
- ログファイル(
log.txt)の削除
基本的特に難しい点はありません。バックアップする画像のファイル名の生成でfunctionノードを使用している点がちょっと残念な印象です。
実行する
Node-REDのフローが実行状態であれば、reTerminal上のブラウザ(Chromium)でhttp://raspberrypi.local:1880/ui/を開けば、Webのダッシュボードで表示を観ることができるようになります。
そのままでは起動が面倒なので以下のようなシェルスクリプトを作成してみました。キオスクモードにしてもいいのかもしれませんが、今回は最大化とエラーの表示を制限するにとどめました。
start.sh
/usr/bin/chromium-browser --noerrdialogs --start-maximized --app=http://raspberrypi.local:1880/ui/
これで開発をしないというのであれば、chromium-autorun.serviceを使用するのも手かもしれません。
では実行の状態を確認してみます。
実行時のフローの様子

ダッシュボードの様子

reTerminalの実行の様子

完成したフローは以下のリポジトリに格納しますので、無保証ですがお使いください。※Twitterの認証に関してはダウンロードされたフローは空白になるので、その部分だけは入力を行ってください
おわりに
今回、reTerminalを使用してみてわかったのですが、Node-REDとの相性がいいように感じました。
- 開発してすぐに実行し設置デバイスとしても使える点(開発と実行デバイスの両立が即できる)
- デバイスに比較的大きなタッチパネル付き液晶があり情報の表示が
Node-REDのWebダッシュボードで表示しやすい
想像以上にいいデバイスですね。最近の半導体不足によるRaspberryPiの入手の悪さに比較して、reTerminalは入手しやすいのもいいですね。
値段は少し張りますが、上記の利点を考慮すればその値段差もありかなと思ってしまいました。あとミニ三脚との組み合わせで手軽に持ち運べる点もいいと思います。
RaspberryPiの入手性。つらい。

思った以上にNode-REDとreTerminalの相性がいいので、今後はこちらに開発環境をシフトしたいなと考えています。