もう、半年以上も前のことになりますが、ESPr Developerを使って、当社のベランダの温度を測定するIoTデバイスを作りました(作成したときの記事は こちら、改良版の記事は こちら)。
リンク
5分毎に気温を測定して、Wi-FiでWebサーバに送信、それ以外の時間はdeep sleepする仕組みです。
実は、このデバイスで電池がどのぐらいもつのか確かめたいと考え、作成した後も、ずっと現在まで稼働させています。
作成した半年前には、最高気温が50℃ちかくになることもあったのですが、現在では逆に、最低気温がマイナスになることもあります。
せっかくデータがたまってきたので、これまでの気温の推移を見てみたくなり、PHPで集計プログラムを作ってみることにしました。
以下のような仕様です。
- データ採取期間(2018年7月〜2019年2月)すべてにわたり、日次の最低気温と最高気温をグラフ化
- データがおかしい期間やデータがない期間は電池が消耗している期間と考え、グレーの折れ線で表示
- グラフ表示には「Chart.js」を使用
プログラムは以下のようになりました(やっつけで作ったので結構汚いです)。
<?php $dbname = 'db_temp'; $db = new SQLite3($dbname); $sql = "SELECT * FROM temp"; $result = $db->query($sql); // 測定期間を取得 $bdate = ""; $edate = ""; while($info = $result->fetchArray(SQLITE3_ASSOC)){ $date = (int)($info['event_time']/86400); if($bdate=="" || $bdate>$date) $bdate = $date; if($edate=="" || $edate<$date) $edate = $date; } // 日次の最低,最高気温を取得 for($i=$bdate ; $i<=$edate ; $i++){ $min[$i] = ""; $max[$i] = ""; $flag[$i] = ""; } $prev = 0; while($info = $result->fetchArray(SQLITE3_ASSOC)){ $event_time = $info['event_time']; $date = (int)($event_time/86400); $val0 = $info['val0']*100/1024; if($min[$date]=="" || $min[$date]>$val0) $min[$date] = $val0; if($max[$date]=="" || $max[$date]<$val0) $max[$date] = $val0; if($event_time-$prev>480){ $flag[(int)($prev/86400)] = 1; $flag[$date] = 1; } if($val0>50) $flag[$date] = 1; $prev = $event_time; } for($i=$bdate ; $i<$edate ; $i++){ if($max[$i]=="" || $min[$i]=="") $flag[$i] = 1; } // グラフ表示用データを生成 $res_max = ""; $res_min = ""; $res_flag = ""; for($i=$bdate ; $i<$edate ; $i++){ $time = $i*86400*1000; if($flag[$i]!=1){ $res_max .= "{ x: " .$time .", y: " .$max[$i] ." },"; $res_min .= "{ x: " .$time .", y: " .$min[$i] ." },"; $res_flag .= "{ x: " .$time .", y: 0 },"; } else{ $res_flag .= "{ x: " .$time .", y: 50 },"; } } $db->close(); ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>温度計</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script> <style> body { font-family: sans-serif; } </style> </head> <body> <h1>兵庫県川西市の温度</h1> <canvas id="temp" width="300" height="100"></canvas> <script> var ctx = document.getElementById('temp').getContext('2d'); var temp = new Chart(ctx, { type: 'line', data: { datasets: [{ label: '最高気温', fill: false, borderColor: 'red', backgroundColor: 'red', pointRadius: 0, data: [ <?php echo $res_max; ?> ] },{ label: '最低気温', fill: false, borderColor: 'blue', backgroundColor: 'blue', pointRadius: 0, data: [ <?php echo $res_min; ?> ] },{ label: 'データなし', fill: true, borderColor: 'lightgray', backgroundColor: 'lightgray', pointRadius: 0, data: [ <?php echo $res_flag; ?> ] }] }, options: { scales: { xAxes: [{ type: 'time' }], yAxes: [{ ticks: { min: 0, max: 50, stepsize: 10 } }] } } }); </script> </body> </html>
表示結果は以下のとおりです。
電池は単三を3本使っていますが、おおむね当初の想定どおり、20日〜25日程度もっているようです。
設置場所を時々変えたり、台風が来た時にはデバイスを室内に退避させたり、たまには直射日光もあたったりと、気温の測定環境としては適切ではありませんが、データとしてはなかなかおもしろいものが取れたと思います。
リンク