初めに
この記事はMicro Mouse Advent Calendar 2020 の21日目の記事です。 20日目はもすさんのEAGLEのuloで苦労したとこという記事でした。特定のアプリに内包されている謎言語は便利ですが、微妙にクセが強いことが多い気がします。
アドベントカレンダーは色々な話題が読めて楽しいですね。ぷーちんさんの記事でハードルを上げられて困ってますが、頑張って記事を書こうと思います。複数のグラフのうち一つを動かすと他のすべてが動くやつカッコいいです。いつもやろうと思ってその大変さにくじけて実現したことはないです。
解決したい課題
ロボットが出力する時系列データをエクセルに張り付けてグラフ表示という一連の作業を楽にしたい。
こんな感じのteratermに出力されるcsv形式のデータ pic.twitter.com/hYry3M856B
— R.Ganon (@qtfdl94q) December 21, 2020
できたもの
こんなものを作った pic.twitter.com/QFuMJewnm9
— R.Ganon (@qtfdl94q) December 21, 2020
なぜ雑につくるべきか
凝ったものを作っても結局めんどくさくなって使わなくなるからです。
私の好きなyoutuberにPrimitive Technologyという山奥でひたすら火をおこしたり、泥をこねたりしている人がいます。彼は火起こしを原始的な道具で行います。初期の動画では投稿の度に火起こしのテクノロジーが進化していました。しかし、後の動画では初期装備の火起こしセットに戻ってしまうのです。しかも初期装備の方が手早く火が付くという。
何が言いたいのかというと、結局人は慣れると最後は一周回ってシンプルまたは汎用性が高い道具に戻ってくるということです。
シンプル: teraterm
汎用性が高い : エクセル
以下みたいなログビュワーを何度か作ってますが、結局メンテされなくなってteratermとエクセルに戻ったりしているのが現実です。
そのため、自分が楽をするためのツールに関しては考え方を変えることにしました。
- 使い捨てることを前提として作る
- 一から作っても半日で作れる規模と仕様にする
- 既存のベースを使いまわせば60分で作れる規模と仕様にする
- 小規模な変更をすぐに反映できる ≒ コンパイルがいらないスクリプト言語を使う
- メイン処理の記述を目標250行以下、多くても500行以下を目指す
良い例えではないかもしれませんが、毎日が外食やコンビニ弁当にならない程度に自炊を頑張るくらいの塩梅ででツールを作るという感じです。
— R.Ganon (@qtfdl94q) October 21, 2018
— R.Ganon (@qtfdl94q) June 21, 2017
— R.Ganon (@qtfdl94q) June 5, 2017
— R.Ganon (@qtfdl94q) May 22, 2016
Electronの紹介
ここではElectronについて簡単に紹介します。
nodejsに関する基本的な内容もかければよいのですが、紙面の関係で割愛します。
Electronって何
web技術を使ってネイティブアプリが作れるフレームワークです。
vscode等のアプリのベースになっています。
いいところ
- クロスプラットフォームで動くアプリが作れる
- オープンソース
- きれいな画面のUIを作りやすい
- 既存のwebアプリをネイティブアプリに改造するときに使える
- フロントエンドでnodejsのモジュールを呼べる
- javascriptとhtmlが書ければ簡単なネイティブアプリを比較的少ない手数で書ける
- 配布用の実行ファイルを生成できる
わるいところ
- 作ったアプリのイメージがでかい
- 作ったアプリのCPU負荷が高くなりがち
Electronアプリの典型的な構成
以下のうち必要最小限なのはindex.htmlとindex.jsです。gitで管理するときは.gitignoreにnode_modulesのフォルダを指定しましょう。
css <- .cssファイルを格納
js <- .jsファイルを格納
node_modules <- npmでインストールしたものが格納される
index.html <- アプリの画面、メイン処理を記述(ウェブアプリだとフロントエンド部分)
index.js <- index.htmlの立ち上げ等を記述(ウェブアプリだとサーバーサイド部分)
package.json <- 追加するモジュールや独自コマンドの定義
package.jsonの記述例
package.jsonのscriptに”run”、”build”、”rebuild”等のコマンドを登録することをおすすめします。コンソールで以下のように打つと定義したコマンドを実行できて便利です。
npm run 定義したコマンド
npm run run とrunが二つ続くのはちょっと微妙ですが気にしないでください。
雑に作ったログビュワー解説
コンセプト
- できるだけ少ない労力でグラフを拡大、縮小、移動ができるログビュワーを開発する
- 受信するデータが変わっても一度作った部分を流用して対応しやすいものを目指す
動作環境
OS: Windows
nodejs: v14.15.1 ( https://nodejs.org/ja/からwindows用のリリースをダウンロードして使用)
要求仕様
完成物に実装されていた仕様を説明用に列挙しました。仕様を決める人とコードを書く人とアプリを使う人が同一の場合は要求を明確に書き出す必要はないと思います。GitHubのREADME.mdに書く程度の粒度で書いてみました。
機能要求
データの受信
- csv形式データをシリアルポート経由で受け取ること
- 接続先シリアルポートの設定用GUIを設けること
- シリアルポートの接続ボタンと断接続ボタンを設けること
- 接続先のシリアルポート情報はアプリ内で記憶すること
- 保存済みのcsv形式データを読み込み可能とすること
データの表示
- csv形式のデータを時系列順にグラフ表示可能とすること
- グラフは拡大、縮小、移動が快適に行えること
- 保存済みcsvファイルをグラフ表示可能とすること
データの保存
- 受信したデータはcsvファイルとして保存すること
- csvファイルへの保存は自動で行うこと
- 保存するファイル名はそのときの日時、時刻が入ったものとすること
非機能要求
- アプリのイメージサイズは問わない (electronなので…)
- CPU負荷は問わない (electronなので…)
- データ読み込み時のエラー処理は実装しなくてもよい (自分しか使わんし)
- セキュリティは気にしない(業務で使うアプリの場合XSS対策とか必要)
ログ形式
「timestamp, hoge2, hoge3, hoge4\n」のような一列目にタイムスタンプのヘッダを持ったcsvファイルとする。
ソースコード
GitHubに一式おいておきました。
もう少しでアドベントカレンダーの納期が来そうなので、あとでREADME.mdにもう少し情報を追記しようかと思っています。
https://github.com/GanonKuppa/lazy_log_viewer
使われている技術
グラフの描画
plotlyというモジュールを使っています。適当なdiv要素を指定しリストに時系列データを入れるといい感じのグラフを描画できます。
シリアルポートの読み込み
nodejsのSerialPortというモジュールを使っています。electronではindex.jsで少しおまじないを書くとフロントエンド側でnodejsのモジュールが呼び出せてしまいます。
SerialPortをelectronで使う際には少しハマりポイントがあり、npm i serialportをしただけだとうまくいきません。このサイトを参考にして解決しました。
CSVの保存
ファイルを保存するためにnodejsのfsモジュールを使っています。フロントエンド側でnodejsのモジュールを呼び出せると本当に楽です。
終わりに
目標の250行は15行超えてしまいましたが265行でindex.htmlを書けました。スリムでいいですね。
最後にブログを更新したのが2年前のアドベントカレンダーだったという悲しい現実はありますが、久しぶりにブログを更新できてよかったです。
明日のMicro Mouse Advent Calendar 2020 21日目の記事はみんなのアイドル
? Aniki Hiraiさんの投稿です。どんな記事か楽しみですね。