19
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Netatmo ウェザーステーションのAPIを使ってみる - Part1: Node.jsのサンプル

Last updated at Posted at 2015-08-31

Netatmo ウェザーステーションを使うと、屋内や屋外に設置したモジュールから簡単に環境データを計測して、スマホやデスクトップブラウザのダッシュボードから確認することができます。計測できるデータは気温、湿度、気圧、二酸化炭素濃度、騒音などです。myThingsにも対応しています。オフィシャルではAPIを使うためのSDKはPHP、Objective-C、Windows8、Android用が用意されています。コミュニティーベースですが、Node.js用のライブラリもGitHubにリポジトリがあったので、こちらを使ってみようと思います。

Netatmoのセットアップ

室内&屋外の気温・湿度・CO2等を計測して詳細な天気情報を出してくれる「netatmo ウェザーステーション&雨量計」レビューが写真入りで解説されているので参考にさせていただきます。また、スマホアプリのガイドも丁寧でわかりやすいので、アプリを操作していくだけでも簡単に設定していくことができます。

サインアップ

iPhoneの場合はWeather Station by Netatmo、Androidはステーション Netatmoをインストールして、Netatmoのセットアップetatmoにサインアップします。

屋外モジュールとステーションの設置

屋外モジュールに電池ををセットします。ステーションはMicro USBケーブルで電源プラグに接続します。ステーションの上部をタッチして側面が青色に点滅させます。

ステーションのWi-Fi設定

スマホアプリからステーションにBluetoothでペアリングしたあと、ステーションにWi-Fiのセットアップを行います。接続に成功するとステーションをNetatmoに登録して終了します。

デスクトップブラウザ

デスクトップブラウザからログインします。ウェザーステーションのページを開くと以下のように表示されます。

netatmo-station.png

APIを使う準備

APIを使ったサンプルは、Netatmo ウェザーステーションを買ってみたので Node.js でいじってみたを参考にさせていただきました。試してみたいNode.jsのライブラリの例なので助かりました。

アプリの登録

Netatmo Developersのページを開いてログインします。上メニューにDOCUMENTATIONCREATE AN APPLICATIONなどが表示されています。CREATE AN APPLICATIONのページを開き「Name」と「Description」に適当な名前をつけて登録すると、Client idとClient secretが発行されます。APIではこのidとsecretを使います。

netatmo-apikey.png

Node.jsのサンプル

Node.jsのnetatmoを利用してAPIを使ったサンプルを書いてみます。リポジトリはこちらです。今回もベースイメージにio.js3.2を利用してDocker Composeから構成管理します。

docker-compose.yml

docker-compose.yml.defaultファイルをdocker-compose.ymlにリネームしてから環境変数を編集します。

  • CLIENT_ID: 作成したアプリのClient id
  • CLIENT_SECRET: 作成したアプリのClient secret
  • USERNAME: netatmoにログインするユーザー名
  • PASSWORD: netatmoにログインするパスワード名
  • INTERVAL: 1800000(30分)、 netatmoからデータを取得する間隔
~/node_apps/docker-netatmo/docker-compose.yml.default
netatmo:
  build: .
  volumes:
    - .:/app
    - /etc/localtime:/etc/localtime:ro
  environment:
    - CLIENT_ID=
    - CLIENT_SECRET=
    - USERNAME=
    - PASSWORD=
    - INTERVAL=1800000
  ports:
    - 3033:3000

app.js

NetatmoにはGETMEASUREというAPIもありますが、デバイス(ステーション)とモジュール(屋外モジュール)のどちらかしかデータを取得できないようです。親子関係を紐付けるidをつかって一つのJSONオブジェクトにまとめてみました。

また、モジュールのtypeフィールドがNAModule4の場合は追加の屋内モジュールになります。こちらはCO2を検出できるので追加します。

~/node_apps/docker-netatmo/app.js
"use strict";

var netatmo = require('netatmo'),
    async = require('async'),
    _ = require('lodash'),
    moment = require('moment-timezone'),
    api = new netatmo({
        'client_id': process.env.CLIENT_ID,
        'client_secret': process.env.CLIENT_SECRET,
        'username': process.env.USERNAME,
        'password': process.env.PASSWORD,
    });

function getMyDevices(deviceIds, devices, modules, callback) {
    var myDevices = _.map(deviceIds, function(id) {
        return {
            device: _.find(devices, function(device) {
                return id == device._id;
            }),
            modules: _.filter(modules, function(module) {
                return id == module.main_device;
            })
        };
    });
    callback(null, myDevices);
}

function toJST(time_utc) {
  return moment(time_utc, 'X').tz("Asia/Tokyo").format();
}

function pluckDevice(device) {
    return {
        module_name: device.module_name,
        time_utc: toJST(device.dashboard_data.time_utc),
        noise: device.dashboard_data.Noise,
        temperature: device.dashboard_data.Temperature,
        humidity: device.dashboard_data.Humidity,
        pressure: device.dashboard_data.Pressure,
        co2: device.dashboard_data.CO2
    };
}

function pluckModule(module) {
    var retval = {
        module_name: module.module_name,
        time_utc: toJST(module.dashboard_data.time_utc),
        temperature: module.dashboard_data.Temperature,
        humidity: module.dashboard_data.Humidity
    };
    // for the additionnal indoor module
    // https://dev.netatmo.com/doc/methods/devicelist
    if (module.type == 'NAModule4'){
        retval[co2] = module.dashboard_data.CO2;
    }
    return retval;
}

function resultsOut(results) {
    _.forEach(results, function(result) {
        console.log(pluckDevice(result.device));
        _.forEach(result.modules, function(module) {
            console.log(pluckModule(module));
        });
    });
}

function measure(callback) {
    async.waterfall([
        function(callback) {
            api.getUser(callback);
        },
        function(user, callback) {
            api.getDevicelist(function(err, devices, modules) {
                if (err) return callback(err);
                getMyDevices(user.devices,
                             devices, modules,
                             callback);
            });
        }], function(err, results) {
            if (err) return console.log(err);
            resultsOut(results);
            console.log('----');
            setTimeout(callback, process.env.INTERVAL);
        });
}

async.forever( measure, function(err) {
    if(err) console.log(err);
});

実行

プログラムを実行すると環境変数INTERVALに定義した間隔(1800000ミリ秒=30分)でNetatmoからデータを取得して標準出力します。本体とモジュールのセンシング時間は完全に一致はしていないようです。

$ docker-compose up netatmo
...
netatmo_1 | npm info it worked if it ends with ok
netatmo_1 | npm info using npm@2.13.3
netatmo_1 | npm info using node@v3.2.0
netatmo_1 | npm info prestart netatmo-docker@0.0.1
netatmo_1 | npm info start netatmo-docker@0.0.1
netatmo_1 |
netatmo_1 | > netatmo-docker@0.0.1 start /app
netatmo_1 | > node app.js
netatmo_1 |
netatmo_1 | { module_name: 'リビング',
netatmo_1 |   time_jst: '2015-08-31T09:34:30+09:00',
netatmo_1 |   noise: 38,
netatmo_1 |   temperature: 24.5,
netatmo_1 |   humidity: 84,
netatmo_1 |   pressure: 1081.7,
netatmo_1 |   co2: 395 }
netatmo_1 | { module_name: 'ベランダ',
netatmo_1 |   time_jst: '2015-08-31T09:34:28+09:00',
netatmo_1 |   temperature: 22.9,
netatmo_1 |   humidity: 86 }
netatmo_1 | ----
19
22
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?