Junpei Qawasaki

テクノロジーをベースに新規事業とかインタラクティブなものとかを色々とやっております

【Python×Unity】パーソナルウェザーステーション「netatmo」からAPI経由でデータを取得する

f:id:jkawasaki:20181007110055j:plain
屋外&屋内の気象観測が出来る「netatmo」というセンサーを入手しまして。
写真左から屋内モジュール、屋外モジュール、風速計、雨量計です。数万円で精密な環境センサが手に入る時代。
とはいえ、製品自体は数年前に発売されたものなのだけど、農業とかアウトドア関連のものだと使い勝手良いと思っていて。
例えば「幕張メッセの今の二酸化炭素量」とか「港区のビル屋上の風速」みたいなのって、フツーはピンポイントで分からないのだけど、コレ置くだけで把握出来ます。なので、任意の地点の雨量を計測して、雨量が一定量超えたらXXする、みたいな事も出来るし、高機密性の家とかだと二酸化炭素濃度が上がりやすかったりとかするので、一定のCO2濃度超えたら換気するみたいなスマートホーム的な物にも使えそう。

パーソナルウェザーステーションといえど、精度は高いので台風とかそういう時にもピンポイント雨量がわかるだけでも中々便利でありまして、日本の各自治体で1台ずつ導入して頂いてなんか作らせてほしい。

それはさておき、コレをとりあえず触って行きます。「こんな段取りでセンサーの特徴理解していくよ」って話なので、馴染みが無い人にはくそつまらない記事だと思います。のでご了承くださいませ。

○netatmoについて

屋内センサ(親)はWiFiクラウドに繋がってて気温、湿度、騒音、二酸化炭素量なんかが収集されます。
別売りの屋外・風速・雨量モジュール(子)は電池駆動。屋内と無線で繋がってて風速とか雨量とか気圧とか取れます。
風速や雨量のデータを集めたい場合、通常だと専用のモジュールとシールド買ってArduinoやラズパイと繋げるという以下みたいな選択になりますが↓↓
ウェザーメーター(風向・風速・雨量) - Weather Meters/SEN-08942 - ネット販売
ざっくり考えても以下3点の理由で効率悪い。

・個々のモジュール制作にコストがかかる
・収集されるデータが生データなので成型するのが大変
・苦労して完成したとして、果たしてそのデータにどれだけ信頼おけるのか

風速についても超音波モジュールの組み合わせで安価出来る、みたいな記事もあるのだけど、実務で使うには信頼性が怪しい。
そんな訳で、辿り着いたのがnetatmoです。公式のアプリもあってちょっと設定するだけで以下のような管理画面でグラフ見れる、すごい。
f:id:jkawasaki:20181008180645p:plain

で、肝心のデータの正確さはどうなんだって話なんですが、家の外に置いてたらちょうど良く台風来まして。そのデータがこちら。
f:id:jkawasaki:20181008181023p:plain
大型台風で道路の木とか倒れてしまう時で相当な風速だったのだけど、壊れることもなく取得に成功。気圧も良い感じのカーブを描いてた。
ただ、風速がkm表記なんすよね。日本の場合はm/s表記がスタンダードなので、変換をかませないといけなくて、変換してみるとこの値が正しいのかどうなのかはまだちょっと微妙。

とはいえ、センサーとしての信頼度は高く使い勝手が良いのは分かったのでAPIから色々取得出来るようになりましょう。と。

○netatmo APIをターミナルから触ってみる


※基本的な部分は以下記事を参考にしてもらう前提で割愛※
NetatmoウェザーステーションAPIをさくっと呼び出す

netatmoの管理画面でアプリ登録をするとIDとsecret keyとか発行されるので、それを使います。
疎通確認するくらいなら以下のコマンドを打てばok。

curl -X POST https://api.netatmo.com/oauth2/token -d "grant_type=password&client_id=[自分のID]&client_secret=[自分のシークレットキー]&username=[メアド]&password=[パスワード]"

f:id:jkawasaki:20181008213934p:plain
こんな感じのaccess_tokenが返ってくるので、それが返って来るなら、少なくとも使える状態にはあるはず。
とはいえ、これでは何もデータが見れないので、まずはAPIから各種データを取得したい。
が、ちょっとSDKは個人的に好きな言語のが無かったのです。なのでまずはPythonで取得する事から始める。

Pythonでデータを取得する


今回はlnetatmoというライブラリを拝借。
github.comどうでもいいけどサムネの画像の主張がすごい。
2日くらい色んな手法を探したのですが、Netatmoを掘り下げて行くとネットの海を2周遊くらいして、最終的にこいつに行き着きます。一応、他にも2つくらいはやり方あります。

ex.py

#!/usr/bin/python3
# encoding=utf-8
import lnetatmo
#tokenを取得
authorization = lnetatmo.ClientAuth(
                clientId = "自分のID",
                clientSecret = "自分のシークレットキー",
                username = "メアド",
                password = "パスワード",
                scope = "read_station"
)
#天気情報の取得
weather_station = lnetatmo.WeatherStationData(authorization)
#天気情報の表示
print(weather_station.lastData())

で、こいつを実行すると、こうです。
f:id:jkawasaki:20181008183026p:plain

無事に各種、センサー値が返って来ました。
さて、これで色々出来るようになったのだけど、今回の目的としてはUnityでこのデータを触りたいという思いがあるので、UnityからPython経由で取得する方法を探ります(2018.10.8現在未完成)

○Unityでデータを取得する


今回参考にさせて頂いたのは以下のブログです。
【Unity】「IronPython」で Python から Unity API を呼び出す方法 - コガネブログ
Unity上でPythonを使う①【アセット組み込み編】 - kitao's blog
Unity上でPythonを使う②【外部ファイル読み込み編】 - kitao's blog

Python連携するにはIronPythonが良いらしいのだけど、ライブラリ自体が汎用的で複雑なので調べ方を間違えると把握するのむずい。
やりたかったのは後者のブログの内容なのだけど、これの通りだと残念ながら動作しなかったです。
前者の方がコードもシンプルだったので割と楽に動いた。
■exsample.cs

using IronPython.Hosting;
using UnityEngine;

public class Example : MonoBehaviour
{
    public TextAsset m_textAsset;

    private void Awake()
    {
        var text = m_textAsset.text;
        var engine = Python.CreateEngine();
        engine.Runtime.LoadAssembly(typeof(GameObject).Assembly);
        var scope = engine.CreateScope();
        var source = engine.CreateScriptSourceFromString(text);
        source.Execute(scope);
    }
}

で、Assetsの下に配置したPythonのコード(.txt)側でログ出力をしてるのだけど上記csコードが動かしてくれます。
f:id:jkawasaki:20181008183957p:plain

こんな感じに。
Pythonの中に書いたDebug.Logが出力されただけ。
て、よく考えたらこれ「UnityでPythonコード実行」じゃなくて「PythonでUnityのAPIが叩ける」なので、そもそも違う。

netatmoデータ持ってくるにはlnetatmoのライブラリを経由する必要があるので、このままでは叩けない。
そんで、ここまで来て一旦時間切れということもあるので本調査は終了。

本当は、UnityからnodeとPythonを自由に使えるようになったら色んなこういうAPI解放してる外部製品を触り放題だから、そういう所を目指してるのですが、まだいくつか触っていかないと見えんすね。

では。