じーろぐ

日々の記録。コンピュータやプログラミングの話題が多め。

Nature Remoの人感センサーの値を集計して可視化する

Nature Remoに内蔵されているセンサーの値は、公式のアプリで見ることができる他、Nature Remo Cloud APIの値を通じて取得することができます。 これまで取得できたのは温度、湿度、照度センサーの値でしたが、2019年6月20日あたりから人感センサーの値も取得できるようになりました。これで、Nature Remo搭載の内蔵センサーの値が全部API経由で取得できるようになったようです。

以下は、実際にNature Remo Cloud API経由で取得したJSONデータ例です。

"newest_events": {
    "hu": {
        "val": 70,
        "created_at": "2019-06-27T15:12:45Z"
    },
    "il": {
        "val": 10.6,
        "created_at": "2019-06-27T14:27:47Z"
    },
    "mo": {
        "val": 1,
        "created_at": "2019-06-27T15:01:45Z"
    },
    "te": {
        "val": 27,
        "created_at": "2019-06-27T15:01:17Z"
    }
}

センサーごとに値(val)とその取得日時(created_at)のペアが得られるようになっていて、moが新たに取得できるようになった人感センサーの値です。(ちなみに、hu, il, teはそれぞれ湿度、照度、温度センサーに対応します) Nature Remo Cloud APIのドキュメントには、取得できる値について詳しい説明がないのですが、定期的に取得したデータを見てみたところ、値(val)は1固定で、センサーに反応があったときに更新日時(created_at)が更新されるようでした。(ちなみにこの人感センサーですが、一般的なセンサーライトなどと同じく動く熱源に反応するみたいです。)

以前、温度、湿度、照度センサーの値を取得して時系列でグラフ化する方法を紹介しましたが、人感センサーの場合、値は実質ないので同じ方法では可視化できず、ちょっと悩みました。今回は、とりあえず今回はGithubのContribution Graph風に可視化してみました。

f:id:z_logger:20190707022621p:plain

ちなみに、ここで紹介したグラフを作るのに使ったツールはGithubで公開しています。

github.com

データの収集と可視化方法

以下、人感センサーの値をPython+matplotlib+pandasをつかって、GithubのContribution Graph風に可視化する方法をざっくり解説します。

データ

まず、Nature Remo Cloud APIに定期的にアクセスして人感センサーのcreated_atが変化したとき、その日付をcsvで記録します。

2019-06-22T13:17:18Z, 1
2019-06-22T13:30:01Z, 1
2019-06-22T13:43:15Z, 1
2019-06-22T13:56:05Z, 1
2019-06-22T14:32:31Z, 1
2019-06-22T14:58:55Z, 1
2019-06-22T15:04:18Z, 1
.
.

詳しくはgetRemoSensorData.shを参照してください。 (このシェルスクリプトをcron等で定期的に実行するとmo.txtとして記録されていきます。あとで、dataframeに変換できるならCSVでなくても良いです。)

Python+matplotlibで可視化

グラフ化にはmatplotlibを使いました。まずデータをpandasのdataframeとして読み込みます。 Nature remoのAPIで取得できる日時はUTCですので、datetime型に変換したのち日本時間にします。

df_mo = pd.read_csv('mo.txt', names=['time', 'motion'])
df_mo.time = pd.to_datetime(df_mo.time,format='%Y-%m-%dT%H:%M:%SZ')
df_mo.time = df_mo.time + dt.timedelta(hours=9)
df_mo = df_mo.set_index('time')

次に、それぞれの曜日と時間を取得してdataframeに追加します。

df_mo["weekday"] = df_mo.index.weekday
df_mo["hour"] = df_mo.index.hour

縦が曜日、横が時刻(hour)にしてセンサー反応回数を集計します。 pandasのピボットテーブルを使うと便利です。

df_mo_pivot = df_mo.pivot_table(index=["weekday"], columns=["hour"], values="motion", aggfunc=sum)
df_mo_pivot.fillna(0, inplace=True)

最終的には以下のような7x24(曜日x時刻)のテーブルができます。

hour       0    1     2    3     4   ...  19    20    21    22   23
weekday                                                   ...
0         9.0  8.0   0.0  7.0   0.0  ...  7.0   6.0  11.0  10.0  8.0
1        11.0  9.0   4.0  0.0   1.0  ...  6.0   7.0   5.0  12.0  8.0
2        11.0  6.0   4.0  6.0   0.0  ...  6.0   6.0   7.0   8.0  8.0
3         7.0  9.0  10.0  5.0   0.0  ...  7.0   9.0   7.0  11.0  8.0
4         4.0  2.0   7.0  1.0   9.0  ...  9.0   3.0   4.0   4.0  4.0
5         4.0  8.0   0.0  7.0  10.0  ...  7.0   3.0   2.0  11.0  5.0
6        11.0  5.0   4.0  0.0   8.0  ...  5.0  13.0  12.0   6.0  7.0
[7 rows x 24 columns]

あとは、matplotlibのimshowでグラフ化。以下の2行で可視化できますが、GithubのContribution Graphに似せようとして実際はいろいろスタイルいじってます。

plt.imshow(df_mo_pivot, cmap="YlGn")
plt.show()

青系のカラースキームを使うと以下のような感じになります(涼しげ)。 以下の可視化結果は、ダミーのデータを使っているのでわからないですが、生活パターンとかがわかって面白いです。

f:id:z_logger:20190707152858p:plain

ソースコード全体は、visualizer/remo_motion_graph.pyにあります。

参考サイト

温度、湿度、照度センサーの値を同じように可視化する方法は以下のエントリで紹介しています。 zlog.hateblo.jp