2014/09/27

室温モニタ

結局こんな感じに落ち着いた。

image

グラフ表示部に Google Charts の Annotated Time Line、カレンダー部に jQuery UI の datepicker を使ってみた。

Daily モードにすると、選択した日の 1 分刻みのデータをプロットして、Monthly モードにすると、その月のデータを 1 時間刻みでプロットするかんじ。

Monthly のデータの取り出しには

$targetDateString = $date->format("Y-m");
$daysInTheMonth = $date->format("t");

$query = "select
            date_format(ts, '%Y/%m/%d %H:00:00') as ts,
            avg(temp) as temp
          from sensor_db.room_temperature
          where ts between str_to_date('$targetDateString-01 00-00-00', '%Y-%m-%d %H-%i-%s') and
                           str_to_date('$targetDateString-$daysInTheMonth 23-59-59', '%Y-%m-%d %H-%i-%s')
          group by date_format(ts, '%Y-%m-%d-%H');";

こんな感じのクエリを使ってみた。

なかなか楽しい。

2014/09/26

温度センサー

WLAN のアクセスポイントと化している Raspberry Pi で室温を記録してみようかと思って温度センサーを買ってみた。I2C で通信できるやつ。

スイッチサイセンスで 600 円くらい。MCP9808 というチップが乗ってるらしい。

とりあえず、ピンをはんだ付けして、3.3V、GND、SDA、SCL にそれぞれワイヤを接続し、 i2cdetect をしてみる。

pi@raspberrypi ~ $ sudo i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- 18 -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --

0x18 にいるらしい。データシートを見ると、A0、A1、A2 に 3.3V を接続することでアドレスを変更できるようなことが書いてあった。今回はどのピンも接続してないので、0b0011000 = 0x18。あってる。

偉い人が既に Python のライブラリを書いてくれているので、それを使ってさっそく温度を取得してみる。

pi@raspberrypi ~/repos/Adafruit_Python_MCP9808 $ sudo python
Python 2.7.3 (default, Mar 18 2014, 05:13:23) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import Adafruit_MCP9808.MCP9808 as MCP9808
>>> sensor = MCP9808.MCP9808()
>>> print "Temp: %f" % sensor.readTempC()
Temp: 24.125000
>>> quit()

良い感じに読み取れた。目的は部屋の温度を記録することだったので、MySQL のデータベースに記録してみることにした。適当にタイムスタンプと float のテーブルを作って、

import Adafruit_MCP9808.MCP9808 as MCP9808
import MySQLdb

sensor = MCP9808.MCP9808()
sensor.begin()

temp = sensor.readTempC()

connection = MySQLdb.connect(db="sensor_db", user="sensor", passwd="********")
cursor = connection.cursor()
cursor.execute("insert into room_temperature values(now(), %.3f);" % temp)
cursor.close()
connection.commit()
connection.close()

こんなコードを cron で毎分動かす感じにした。

表示は PHP から MySQL にアクセスしてテーブルを取得して json_encode で JSON 形式に変換し、Google Charts API の Annotation Chart で表示するようにしてみた。コードは長いので割愛。

つまずいたのは、タイムスタンプを PHP のテーブルに突っ込むところくらい。日付の文字列をそのまま突っ込んでも、DateTime 型のオブジェクトを突っ込んでもダメだった。

正解は、カラムのタイプを datetime にして、データは

$dt = new DateTime($row['ts']);
$ts_data = "Date" . $dt->format("(Y, m, d, H, i, s)");

こんな感じの文字列で突っ込んであげればおっけーでした。

完成図がこちら。

image

いいかんじで記録してくれてる。

毎分記録してるのでログ容量がすごいことになりそうとおもって調べてみたけど、データベースサイズは 9 時間で約 50 KB くらい。一日 135 KB。一年で 50 MB。余裕でござりました。