子育てしながらエンジニアしたい

現在 4 歳 女の子の子育て中エンジニアによる、技術系 + 日常系ブログ。

Emacs org-mode から見栄えの良い HTML を出力する

Emacs org-mode は、メモや TODO リストにとどまらず、いろんなことに使える Emacs のモードです。

orgmode.org

数年前から
「org-mode で書いたメモを HTML にエクスポートして報告書代わりにする」
ことをしていたのですが、久しぶりにやってみたら、昔よりも簡単に見栄えの良い HTML ができるようになってました。

たかが見栄え、されど見栄え。
中身は変わらなくても見栄えが良いと、良い仕事をした感じがあります。(錯覚?)
簡単ですがまとめておくことにしました。

emacs-htmlize の導入

これは見栄えと関係ないですが、そもそも html へのエクスポートでこけたのでメモ。

PC を入れ替えたときに、新しく Emacs 26.2 を入れました。
org-to-html (C-c C-e h h) しようとしたら、以下のエラーメッセージが出ました。

Please install htmlize from https://github.com/hniksic/emacs-htmlize

このお達しに従って、上記の GitHub から htmlize.el を lisp の入っているディレクトリにダウンロード。
そして init.el に以下を追加しました。

;; htmlize
(require 'htmlize)

見栄えを良くする

org ファイルの一番上に一行書くだけで、見栄えの良い HTML が出力できます。

#+SETUPFILE: https://fniessen.github.io/org-html-themes/setup/theme-readtheorg.setup

これだけ。
こんな素敵なものを用意してくれたのは以下の GitHub

github.com

今の所、Bigblow と ReadTheOrg の 2 テーマがあるようです。
上記の例は ReadTheOrg のテーマを使ったものです。
Bigblow にしたければ、

#+SETUPFILE: https://fniessen.github.io/org-html-themes/setup/theme-bigblow.setup

と書くだけ。
とても簡単!!

さらにテーマのカスタマイズもできるようです。
デフォルトだとコードブロックが見づらかったので、GitHub のカスタマイズ例に従って下記の一文を追加しました。

#+HTML_HEAD: <style>pre.src{background:#343131;color:white;} </style>

結果例

1 つ前にデータベース関連の記事を書きました。

edosha.hatenablog.jp

これのメモを報告書っぽくエクスポートした例です。

元の org ファイル

#+SETUPFILE: https://fniessen.github.io/org-html-themes/setup/theme-readtheorg.setup
#+HTML_HEAD: <style>pre.src{background:#343131;color:white;} </style>

#+TITLE: DB Performance Improvement
#+AUTHOR: edosha

* 現状調査
** レコード数と処理時間
  各テーブルのレコード数を調べ、それぞれ同じ SQL Query に対してどのくらい時間がかかるか調べた。

*** SQL Query
    #+BEGIN_SRC sql
    select count(*) from テーブル名;
    #+END_SRC

*** 結果
    | Table | Count | Time |
    |-------+-------+------|
    | A     |       |      |
    | B     |       |      |
    | C     |       |      |
    |       |       |      |
    |       |       |      |
    |       |       |      |
    |       |       |      |
    |       |       |      |
    |       |       |      |
    |       |       |      |

出力された HTML

出力された HTML
出力された HTML

素敵な Read The Docs 風の HTML がこれだけで出ました!
これはもう報告書は org-mode で決まりだ...

PostgreSQL - 最後に追加したレコードの抽出、レコード数のカウント、同一データを含むレコード数のカウント、SQL 実行時間の計測

様々な工作機械から吸い上げたデータを PostgreSQL にためて、表示や分析をするシステムを運用しています。
最近、やけにデータベースへのアクセスが遅くなってきたので原因を分析することにしました。
その中で、今まで使ったことがなかった SQL がいろいろあったのでメモ代わりに記録を残すことにしました。

データベースの構造

非常にシンプルなもので、工作機械ごとに以下のようなテーブルが作られています。
int フィールド以下に機械の稼働データが溜め込まれています。
IoT の例としてよく言われる、
「表示灯に光センサーをつけてその光量値をもとに稼働状況を見える化する」
の、光量値が int フィールドに入っていると思ってもらえれば良いかと。
実際はそれだけではなく、いろいろな種類がありますが...

Column Type Collation Nullable Default
date date
time time without time zone
int1 integer
int2 integer
int3 integer
: :

遅い...

このデータベースからレコードを取得して、リアルタイムに可視化したり稼働状況の分析をしていますが、この頃やけにアクセスが遅くなってきました。
体感速度的には、select 文一度につき 10 秒以上かかっているような工作機械もありました。
そこでまずは何に時間がかかっているのか、原因の分析をすることにしました。
その過程でいろいろ知らなかった SQL を使う機会があったので、メモとして残しておきます。

最後に追加したレコードの抽出

工作機械が稼働しているときはレコードを書き込み、そうでないときはレコードは書き込みません。
そのため、最後に追加したレコードは、最も直近に工作機械が稼働していたときということになります。
というわけで「最後の日付を取得する」目的のために、MAX を使用しました。

SELECT MAX(date) FROM テーブル名;

こうすると、こんな感じの出力が取得できます。

    max
------------
 2019-06-10
(1 row)

逆に最初のレコードであれば MIN を使えます。

SELECT MIN(date) FROM テーブル名;

あるテーブルに含まれるレコード数のカウント

あるテーブルに含まれているレコード数がどれほどパフォーマンスに影響するのかを知るために、レコード数のカウントをしました。

SELECT COUNT(*) FROM テーブル名;

こんな感じの出力が得られます。

  count
---------
 1544613
(1 row)

このテーブルには 1,544,613個のレコードがありました。
しかしテーブルによっては...

  count
----------
 38989285
(1 row)

38,989,285 レコード...
この count を出力するだけでも非常に重いので、レコード数が多すぎるようです。

同一データを含むレコード数のカウント

言い回しが難しいですが、たとえば日付でいえば、何月何日にいくつのレコードがあるのかをカウントする方法です。
たくさんのレコードがある日が重くなるのかを調査するためにやってみました。
これは COUNT と GROUP BY を使うことでできます。

SELECT date, COUNT(date) FROM テーブル名 GROUP BY date;

これで以下のような出力が得られます。

    date    | count
------------+--------
 2018-11-12 |     66
 2018-11-14 | 104135
 2018-11-16 |  29900
 2018-11-28 |  80500
 2018-12-03 |  39400
 2018-12-21 |  23800
 2018-12-28 |  33350

SQL 実行時間の計測

SQL の実行にどれくらいの時間がかかるのか計測が必要です。
PostgreSQL だけかもしれないですが、psql のシェルで以下のコマンドを入れれば、それ以降の SQL 実行時間を計測してくれるというありがたい機能がありました。

\timing

こうすると、たとえば上記の COUNT でどのくらい時間がかかったかを出力してくれます。

SELECT COUNT(*) FROM テーブル名;
  count
---------
 1544613
(1 row)

Time: 65.050 ms

こちらは 65 ms 程度のようです。

  count
----------
 38989285
(1 row)

Time: 13115.412 ms (00:13.115)

レコード数が多い方は約13秒もかかっていました...
今回問題になったのは、レコード数が多すぎるみたいですね...
間引くとか、いろんな方法を考えねば...

ESP32 (Arduino) でアナログ距離センサー GP2Y0E02A を使う

ESP32 を仕事でいろいろ使っています。
といってもこれまでは I2C をはじめとしたデジタル信号しか使っていませんでした。
今回、アナログ信号による距離センサーを使うことになったので記録しておきます。

アナログ距離センサー GP2Y0E02A (Sharp)

akizukidenshi.com

秋月電子で購入。
電源電圧は 3.3V なので、ESP32 で使えます。
距離を電圧に変換してくれます。

測距範囲は 4cm ~ 50cm。
アプリケーションノートによると、距離に応じて以下の電圧が出力されます。

距離 電圧 (Min) 電圧 (Typ) 電圧 (Max)
50cm 0.3V 0.55V 0.8V
10cm 1.9V 2V 2.1V
4cm 2.1V 2.2V 2.3V

ESP32 との接続

f:id:edosha:20190514140126j:plain
ESP32 と GP2Y0E02A の接続

GP2Y0E02A の端子は以下のようになっています。

f:id:edosha:20190514140534p:plain
GP2Y0E02A の端子

これを ESP32 と次のように接続します。

ESP32 GP2Y0E02A
3v3 VDD
GND GND
IO35 Vout(A)
3v3 GPIO1

なお今回は Vout(A) を ESP32 の IO35 に接続しましたが、別のピンでも大丈夫です。
以下のサイトでアナログに使えるピンを解説してくれています。

ht-deko.com

距離センサーを常に使用する場合は GPIO1 と 3v3 を直結で良いようですが、
スタンバイなどを実装したい場合は IO ピンと接続するみたいです。
詳しくはアプリケーションノートで...

Arduino スケッチ

取得した距離をシリアルで送信します。

void setup() {
    // put your setup code here, to run once:
    Serial.begin(115200);
}

void loop() {
    // put your main code here, to run repeatedly:
    delay(100);

    long distA = 0;
    int i;

    // 100 回取得した結果を平均化
    for (i = 0; i < 100; i++)
    {
        distA += analogRead(35);
    }
    distA /= 100;

    long distAns1 = map(distA, 0, 4095, 0, 330);
    long distAns2 = map(distAns1, 55, 220, 50, 4);
    int distResult = distAns2;

    Serial.printf("Dist: %d cm\n", distResult);
}

こんな感じで出力されます。

f:id:edosha:20190514141512p:plain
GP2Y0E02A の出力

やってみて気づいたのですが、最小距離の 4cm を下回ると 65 cm が出力されるようです。
このへんは要注意ですね。

まとめ

ESP32 でアナログ距離センサー GP2Y0E02A を使いました。
Arduino と同様に ESP32 でも analogRead が簡単に使えました。