エアコンの消費電力をRaspberry Pi 3B+とBluetoothワットチェッカー REX-BTWATTCH1で常時モニタリング。電圧・電流・電力もグラフ化!

2019年7月15日

連日の猛暑でエアコンつけないと部屋にいられない!けど電気代は気になる。。。エアコンはつけっぱなしが良いとも聞くけど自宅環境でも同じかわからない、、、じゃぁ測ってしまおう!

ということで、先日の部屋の温湿度・気圧の監視に加え、ラズパイとラトックシステムのBluetoothワットチェッカー REX-BTWATTCH1を使って24時間常時モニタリング環境を構築しました!

こんな感じで電圧・電流・電力の使用量がモニタリングできます(^o^)

準備したモノ

  • Raspberry Pi 3B+、Raspbian Stretch 9.4(4.14.52-v7+ )
  • Bluetoothワットチェッカー REX-BTWATTCH1(ver. 1.20) ラトックシステムのサイト
  • エアコン(MITUBISHI、霧ヶ峰、2012年製、MSZ-GM222-W)
  • 古い扇風機(YAMAZEN、YBS-B250、15年前ぐらいに買ったやつ)

できたこと

  • ラズベリーパイのBluetooth機能でBluetoothワットチェッカーと通信し、2秒毎の電圧・電流・電力の情報を取得
  • 1時間分のデータ(約1800レコード)をCSVファイルとして出力
  • 過去1時間分のデータをHighchartsでグラフ化

Bluetoothワットチェッカーのセットアップ

Bluetoothワットチェッカーの説明書を見ながらセットアップしていきます。
※各種家電に接続する前に、Bluetoothワットチェッカーの定格内に収まっているか必ず確認してください!

定格の確認

Bluetoothワットチェッカーの定格を確認します。
「AC100V、50/60Hz、最大使用電流 15A」と記載されています。

エアコンの定格を確認します。
ラベルとみると「AC 100V、50/60Hz、運転電流 6.94A(冷房時)」と記載されており、Bluetoothワットチェッカーの定格内に収まっています。

コンセントに接続

コンセントに接続します(アースの接続も忘れずに!)

起動すると中央の緑色のLEDが点灯します。

専用アプリ「BTWATTCH」で動作確認

iOSのアプリ「BTWATTCH」で動作を確認します。

アプリを起動して「検索」すると、近くのBluetoothワットチェッカーが出てくるので接続をタップします。接続されたら「計測開始」をタップします。

「状態:計測中」と表示されたら、それをタップするとグラフが表示されます。

  • リアルタイムだと、秒単位で消費電力の他に、電圧・電流なども表示されます。
  • 1時間グラフだと、1分単位の消費電力が表示されます。

スマホアプリの接続を切る

動作していることが確認できたら、「切断」をタップしてBlueetoothの接続を切っておきます。

Raspberry Pi 3B+からBluetoothで接続する

ラズベリーパイの設定を進めて行きます。

古い情報だとBlueZをインストールして〜と紹介されていたりしますが、Raspbian Stretch では、標準のコマンド「bluetoothctl」が使えますので特に複雑な準備をする必要はありませんでした!

※コチラのサイトの情報を組み合わせて試してみました。

Bluetoothの設定

まず、Bluetooth設定用コマンドの存在を確認します。

$ bluetoothctl -v
5.43

bluetoothctlコマンドを実行して、内蔵Bluetoothの電源を入れます。

$ bluetoothctl
[NEW] Controller B8:27:EB:8D:C8:99 rpi3-03p [default]
[bluetooth]# power on
Changing power on succeeded

ペアリングコード管理のため、エージェントを起動します。

[bluetooth]# agent on
Agent registered

scanコマンドでデバイスを検出します。
WATT CHECKER と記載されたデバイスを探します。

[bluetooth]# scan on
Discovery started
[CHG] Controller B8:27:EB:8D:C8:99 Discovering: yes
[CHG] Device 00:E0:4C:8A:6C:1E RSSI: -43
[NEW] Device 00:0C:BF:20:1B:25 WATT CHECKER

ここでデバイスのアドレスを使用してペアリングを行います。
ペアリングのPINコードには"0000″を入力してください。

[bluetooth]# pair 00:0C:BF:20:1B:25
Attempting to pair with 00:0C:BF:20:1B:25
Request PIN code
[agent] Enter PIN code: 0000
[CHG] Device 00:0C:BF:20:1B:25 Connected: yes
[CHG] Device 00:0C:BF:20:1B:25 Modalias: bluetooth:v0039p5050d0120
[CHG] Device 00:0C:BF:20:1B:25 UUIDs: 00001101-0000-1000-8000-00805f9b34fb
[CHG] Device 00:0C:BF:20:1B:25 UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device 00:0C:BF:20:1B:25 ServicesResolved: yes
[CHG] Device 00:0C:BF:20:1B:25 Paired: yes
Pairing successful

trustします。

[bluetooth]# trust 00:0C:BF:20:1B:25
[CHG] Device 00:0C:BF:20:1B:25 Trusted: yes
Changing 00:0C:BF:20:1B:25 trust succeeded

接続したデバイスの詳細情報を確認してみます。

[bluetooth]# info 00:0C:BF:20:1B:25
Device 00:0C:BF:20:1B:25
Name: WATT CHECKER
Alias: WATT CHECKER
Paired: yes
Trusted: yes
Blocked: no
Connected: no
LegacyPairing: no
UUID: Serial Port (00001101-0000-1000-8000-00805f9b34fb)
UUID: PnP Information (00001200-0000-1000-8000-00805f9b34fb)
Modalias: bluetooth:v0039p5050d0120

ここまでできたらbluetoothctlを終了します。

[bluetooth]# exit
Agent unregistered
[DEL] Controller B8:27:EB:8D:C8:99 rpi3-03p [default]

sdptoolの設定

/lib/systemd/system/bluetooth.service を編集します。

sudo vim /lib/systemd/system/bluetooth.service

[Service]のbluetoothdに-Cを追加し、次の行にsdptoolの設定を新しく加えます。

#ExecStart=/usr/lib/bluetooth/bluetoothd
ExecStart=/usr/lib/bluetooth/bluetoothd -C
ExecStartPost=/usr/bin/sdptool add SP

書き換え後に、サービスを再起動します。

sudo systemctl daemon-reload
sudo systemctl restart bluetooth

先にペアリングしたワットチェッカーのアドレスを用いてシリアルポートのチャンネルを確認します。

sudo sdptool browse 00:0C:BF:20:1B:25 | grep -i channel
Channel: 6

rfcommのセットアップ

/etc/rc.local にrfcommの設定を追加します。

sudo vim /etc/rc.local
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi

# Setup rfcomm
sudo rfcomm bind /dev/rfcomm0 00:0C:BF:20:1B:25 6
sudo chmod 777 /var/run/sdp
sudo sdptool add --channel=22 SP

一度再起動します。

ここまでできたらシリアルポートができているか確認します。

sudo sdptool browse local|grep -i serial
Service Name: Serial Port
"Serial Port" (0x1101)
"Serial Port" (0x1101)

接続状態は以下のコマンドで確認できます。

rfcomm show 0
rfcomm0: B8:27:EB:8D:C8:99 -> 00:0C:BF:20:1B:25 channel 6 connected [reuse-dlc release-on-hup tty-attached]

※シリアルポートにアクセスしていないときは「connected」の代わりに「clean」と表示されます。実際にシリアルポートを開いて通信を開始すると上記のような表示になります。(2019-07-15追記)

計測データ(電圧、電流、電力)を取得する

Bluetoothによる通信準備ができたので、実際にデータを取得していきます。

データ取得にはいくつかのステップで特定のコマンドを送信する必要がありますが、これらを簡単に実現するために「atmark-techno社」が公開してくださっているサンプルプログラムをありがたく使わせていただきます。

サンプルプログラムの入手

atmark-techno社のサイトからサンプルプログラムを入手します。

適当なフォルダ(ここではsrc)を作って圧縮ファイルを展開し、makeします。

cd ~/src/
wget http://download.atmark-techno.com/misc/howto_armadillo_rex-btwattch1/wattchecker_20170911.tar.gz
tar xf wattchecker_20170911.tar.gz
cd wattchecker_20170911
make

makeが無事完了したら、スマートフォンアプリで接続している場合は一度切断して、./wattchecker /dev/rfcomm0を実行します。

sudo ./wattchecker /dev/rfcomm0
RTC timer set command success
start measure command success
2018/ 8/14 23:02:46
voltage = 100.64V , current = 3910.16mA , power = 302.38W
2018/ 8/14 23:02:48
voltage = 100.43V , current = 3947.33mA , power = 303.92W
^C
stop measure command success

いけた!

電圧・電流・電力の情報が2秒毎に表示されています。
Ctrl+c で停止します。

ただ、このままではデータとしてとても使いづらいので、出力を整形してCSV形式で出力します。

CSV形式で出力するための修正

後ほどデータ処理ができるようにCSV形式で出力するようにソースファイルを修正します。

wattchecker.c を以下のように書き換えます。
ソース

--- wattchecker.org.c   2018-08-14 23:25:20.370025269 +0900
+++ wattchecker.c       2018-08-16 23:03:51.589615907 +0900
@@ -27,6 +27,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <string.h>
 #include <errno.h>
 #include <time.h>
@@ -277,15 +278,22 @@
 static void disp_data_details(uint8_t *buf)
 {
        int voltage, current, power;
+       char datetime[20];
+       static bool flag = false;
 
-       printf("20%02d/%2d/%2d %2d:%02d:%02d\n",
+       if (!flag){
+               printf("datetime,Voltage (V), Current (mA) , Power(W)\n");
+               flag = true;
+       }
+
+       sprintf(datetime, "20%02d-%02d-%02dT%02d:%02d:%02d",
               buf[19], buf[18], buf[17], buf[16], buf[15], buf[14]);
 
        current = DATA( buf[7],  buf[6],  buf[5]);
        voltage = DATA(buf[10],  buf[9],  buf[8]);
        power   = DATA(buf[13], buf[12], buf[11]);
-       printf("voltage = %3.2fV , current = %4.2fmA , power = %4.2fW\n",
-              TO_V(voltage), TO_MA(current), TO_W(power));
+       printf("%s,%3.2f,%4.2f,%4.2f\n",
+               datetime, TO_V(voltage), TO_MA(current), TO_W(power));
 }
 
 /**
@@ -416,13 +424,13 @@
 
        /* ワットチェッカーの初期化を行う */
        init_wattchecker(fd);
-       printf("RTC timer set command success\n");
+       printf("# RTC timer set command success\n");
 
        /* ワットチェッカーの計測コマンド(計測開始コマンド) */
        ret = start_measure(fd);
        if (ret)
                goto err_restore_serial;
-       printf("start measure command success\n");
+       printf("# start measure command success\n");
 
        /* ワットチェッカーのリアルタイム計測データ転送要求コマンド */
        do {
@@ -443,7 +451,7 @@
        ret = stop_measure(fd);
        if (ret)
                goto err_restore_serial;
-       printf("stop measure command success\n");
+       printf("# stop measure command success\n");
 
 err_restore_serial:
        restore_serial(fd, &tio);

変更点

  • stdbool.h をインクルード
  • 「計測データ詳細表示関数」で、
    • 日時を入れる変数を追加
    • 日時の書式を変更
  • 標準出力に出すコメントの先頭に’#’を追加

書き換えたら make します。
これを実行すると、以下のように出力されるようになります。

# RTC timer set command success
# start measure command success
datetime,Voltage (V), Current (mA) , Power(W)
2018-08-17T01:00:01,100.46,261.34,0.77
2018-08-17T01:00:03,100.41,261.20,0.74
2018-08-17T01:00:05,100.42,261.44,0.80
...

定期実行スクリプトをcronに登録

1時間毎に分割したCSVファイルを作成できるように、データ取得開始・停止のスクリプトを作成して、cronに登録します。

データ取得「開始」スクリプト

適当なフォルダ(ここではscripts)に開始スクリプトを作成します。

vim ~/scripts/watt-log-start.sh
#!/bin/bash
sudo stdbuf -oL -eL /home/pi/bin/wattchecker /dev/rfcomm0 > /dev/shm/watt.$(date +\%Y\%m\%d-\%H).csv

wattcheckerの実行ファイルは、予め/home/pi/bin/にコピーしています。

最初のsudo stdbuf -oL -eLは、コマンドの出力結果をバッファにためずに1行ずつすぐに出力するために指定します。

watcheckerの出力結果をリダイレクトして日時を含んだファイル名を指定して保存します。

頻繁にデータ書き換えが起こるので、SDカードの寿命を縮めないよう「共有メモリ」領域(/dev/shm/)にファイルを作成しています。このままでは再起動すると消えてしまうので、停止スクリプトの中でSDカードの領域にコピーします。

データ取得「停止」スクリプト

次に、停止スクリプトを作成します。

vim watt-log-stop.sh
#!/bin/bash
sudo killall -SIGINT wattchecker
sleep 3
cp -f /dev/shm/watt*.csv /home/pi/log/watt/latest.csv
mv /dev/shm/watt*.csv /home/pi/log/watt/
  • killallコマンドを使って、wattcheckerのプロセスにSIGINT(Ctrl+c)を送って3秒ほど待ちます。
  • 共有メモリ上に置いたcsvファイルをコピー&移動します。
  • コピーしたファイルは最新データをグラフ化して表示する際に指定するものになります。

cronに登録する

cronの設定ファイル(ここでは、src/cron/cron-pi)を作成・編集します。
直接crontab -eで編集するより安全なので、コチラの方法をオススメします。

以下の設定を追加します。

LOG_CRON="/dev/shm/cron.log"
APP3="/home/pi/scripts/watt-log-start.sh"
APP4="/home/pi/scripts/watt-log-stop.sh"

0 * * * * ${APP3} >> ${LOG_CRON}
59 * * * * ${APP4} >> ${LOG_CRON}
  • 毎時0分に「watt-log-start.sh」を実行して、データの取得を開始します。
  • 毎時59分に、「watt-log-stop.sh」を実行して、データの保存(SDカードへの移動)を行います。

設定ファイルができたら、cronに登録します。

crontab cron-pi

これで、1時間毎に電圧・電流・電力の情報が記録されたCSVファイル(watt.YYYYmmdd-??.csv)を自動生成することができるようになります。

HighChartsを使ってデータをグラフ化する。

1時間毎のデータをCSVファイルで取得できるようになったので、これをグラフ化していきます。
Webサーバー(apache2)を動かしているという前提で、HighChartsを使ってグラフ化します。

HighChartsを用いたグラフ化を行うために、コチラのサイトを参考にしました。

グラフを表示するためのhtmlファイルを作成する

apacheのドキュメントフォルダに、htmlファイルを作成します。

vim watt.html
<!DOCTYPE html>
<html lang="ja">
        <head>
                <title>Watt Monitor</title>    
                <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
                <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
                <script src="//code.highcharts.com/highcharts.js"></script>
        </head>
        <body>
                <div id="chart" style="width:800px; height:400px"></div>
                <script type="text/javascript">

function draw() {
        options = {
            chart: {renderTo: 'chart',
                    zoomType:'xy'},
            title: {text: '電力モニター'},
            xAxis: {title: null,
                    type: 'datetime'},
            yAxis: [
                {title: {text: '電流 (mA)',
                        style: {
                                color: Highcharts.getOptions().colors[4]
                        }},
                        labels: {
                        style: { color: Highcharts.getOptions().colors[4] }
                }, 
                        min: 0
                },
                {title: {text: '電圧 (V)',
                        style: {
                                color: Highcharts.getOptions().colors[2]
                        }},
                        labels: {
                        style: { color: Highcharts.getOptions().colors[2] }
                },
                        opposite: false, min: 90, max: 110
                },
                {title: {text: '電力 (W)',
                        style: { color: Highcharts.getOptions().colors[3]}
                        },
                        labels: {
                                style: { color: Highcharts.getOptions().colors[3] }
                        },
                       opposite: true, min: 0, max: 1500
                }
            ]
        };
        var content = [];
        var result = [];
        var count1 = [];
        var count2 = [];
        var count3 = [];
        
        jQuery.get('./log/watt/latest.csv', function(content) {
            content = content.split('\n');
            for(i=0; i<content.length-1; i++) {
                count1[i] = [];
                count2[i] = [];
                count3[i] = [];
                result[i] = content[i].split(',');
                result[i] = [Date.parse(result[i][0]), Number(result[i][1]), Number(result[i][2]), Number(result[i][3])];
                count1[i][0] = result[i][0];
                count1[i][1] = result[i][2];    // 電流 (mA)
                count2[i][0] = result[i][0];
                count2[i][1] = result[i][3];    // 電力 (W)
                count3[i][0] = result[i][0];
                count3[i][1] = result[i][1];i   // 電圧 (V)
            }
            options['series'] = [
                {name: '電流 (mA)', type: 'line', data: count1}, 
                {name: '電力 (W)', type: 'line', yAxis: 2, data: count2}, 
                {name: '電圧 (V)', type: 'line',yAxis: 1, data: count3}
            ];
            chart = new Highcharts.Chart(options);
        });
    };
    document.body.onload = draw();
</script>
        </body>
</html>

グラフを確認する

Webブラウザでラズベリーパイにアクセスして、watt.htmlを表示してみましょう!

こんな感じで電圧・電流・電力の変動がグラフとして表示されます。
電力変化がわかりやすいよう、扇風機を弱・中・強・ルーバー作動を20秒ずつぐらいで切り替えています。
電圧も結構変動していますね。(※仕様によると精度は±3Vと書いてあるので、誤差の範囲内でしょうか。)

一部分を拡大することもできます。

まとめ: Raspberry Pi 3B+とBluetoothワットチェッカー REX-BTWATTCH1を使って電圧・電流・電力を常時モニタリングできるようになった!

今回のまとめです。
・Bluetoothワットチェッカー REX-BTWATTCH1を接続
・Raspberry Pi 3B+ のBluetooth機能を使って通信
・2秒毎の電圧・電流・電力変化を1時間毎に区切られたCSVファイルとして出力
・HighChartsを使ってデータをグラフ化

先の記事で実現した「室内の温湿度・気圧の常時監視」と併せて、エアコンの消費電力を常時監視できるようになりました。今後はこれらのデータに基づいて、エアコンの最適な稼働方法を探ってみたいと思います(^o^)

それではみなさん、良いラズパイ生活を!(・∀・)

Raspberry Pi

Posted by まーく