M5Stack でMilkcocoa のデータストアに登録されるデータを監視する

# これは何？

M5Stack をMilkcocoa 連携させたときのメモです。

# 対象読者
こんな方を想定しています

* M5Stack をサーバーや外部デバイスなどと連携させたい
* M5Stack でMilkcocoa に登録されたデータを読み取りたい

# 環境

* [M5Stack](http://www.m5stack.com/)
* [Milkcocoa](https://mlkcca.com/)
* [Arduino IDE](https://www.arduino.cc/)

# M5Stack 開発環境のセットアップ

M5Stack [公式のGithubページ](https://github.com/m5stack/M5Stack)を確認して開発環境をセットアップしてください。

# Arduino IDE へのライブラリのインストール

## M5Stack Core Development kit のインストール
Arduino IDE のメニューから
スケッチ→ライブラリをインクルード→ライブラリを管理 を選択してライブラリマネージャを開きます。
画面右上のフィルタで”M5Stack" と入力すると「M5Stack Core Development kit」が表示されるので最新版をインストールしてください。

<img width="912" alt="M5Stack Core Development kit のインストール" src="https://qiita-image-store.s3.amazonaws.com/0/154381/28e4f179-3b42-f98d-6373-9fcdeeaaced0.png">

## Milkcocoa Arduino SDK のインストール

### ライブラリのダウンロード
こちらからコードをダウンロードしてください。
https://github.com/milk-cocoa/Milkcocoa_Arduino_SDK

### Arduino IDE でインストール
Arduino IDE のメニューから
スケッチ→ライブラリをインクルード→.ZIP形式のライブラリをインストール を選択し、ダウンロードしたライブラリのファイル（Milkcocoa_Arduino_SDK-master.zip）をしてインストールします。


### ライブラリのソースに手を加える
Milkcocoa Arduino SDK はESP8266 用に開発されていますが、M5Stack はESP32 を使用しているので少しだけ手を加える必要があります。

Arduino IDE のライブラリディレクトリから「Adafruit_MQTT.cpp」を探してください。
MacOS の場合は下記のディレクトリにあります。
※ ${user_name} は環境に応じて読み替えてください

```Bash
/Users/${user_name}/Documents/Arduino/libraries/Milkcocoa_Arduino_SDK-master/Adafruit_MQTT.cpp
```

「Adafruit_MQTT.cpp」内にある下記の行をコメントアウトしてArduino IDE を再起動します。

```cpp:Adafruit_MQTT.cpp（抜粋）
（前略）
#include "include/Adafruit/Adafruit_MQTT.h"

#if defined(ARDUINO_ARCH_AVR)
#define strncasecmp strncasecmp_P
#define strncpy strncpy_P
#else
// #include "avr/dtostrf.h"  ← この行をコメントアウト
#endif

void printBuffer(uint8_t *buffer, uint8_t len) {
（後略）
```

こちらの記事をそのまま行っています
[ESP32(ESP-WROOM-32)でMilkcocoaSDKを使う](https://qiita.com/306_san/items/d074199e6fb4c3d637ed)

# コーディング
Arduino IDE で以下をコーディングしてください。

Milkcocoa のアプリケーションIDやデータストア名、Wi-FiのSSID/Password は環境に応じて書き換えてください。

```cpp:m5stack_milkcocoa.ino
#include <Milkcocoa.h>
#include <M5Stack.h>
#include <WiFi.h>

#define WIFI_SSID "Wi-Fi のSSID"
#define WIFI_PASSWORD "SSID のパスワード"

#define MILKCOCOA_APP_ID      "Milkcocoa のアプリケーションID"
#define MILKCOCOA_SERVERPORT  1883
#define MILKCOCOA_DATASTORE   "Milkcocoa のデータストア名"

const char MQTT_SERVER[] PROGMEM    = MILKCOCOA_APP_ID ".mlkcca.com";
const char MQTT_CLIENTID[] PROGMEM  = __TIME__ MILKCOCOA_APP_ID;

WiFiClient client;
Milkcocoa milkcocoa = Milkcocoa(&client, MQTT_SERVER, MILKCOCOA_SERVERPORT, MILKCOCOA_APP_ID, MQTT_CLIENTID);

// Init M5Stack screen
void clearScreen(){
    uint8_t font_buf[20][16];
    uint16_t sj_length;
    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.print("========== Milkcocoa subscriber ==========\n\n");
}

void setup() {
  Serial.begin(115200);
  // Connect to Wi-Fi
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("connecting");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("connected: ");
  Serial.println(WiFi.localIP());
  delay(500);

  // Subscribe Milkcocoa datastore
  milkcocoa.on(MILKCOCOA_DATASTORE, "push", on_push);

  M5.begin();
  clearScreen();
}

void loop() {
  milkcocoa.loop();
  milkcocoa.ping();
  delay(5000);
}

// Callback for subscribe
void on_push(DataElement *elem) {
  // 登録されたデータを画面に表示する（データ項目名[type, message]は適宜変更してください）
  M5.Lcd.print(elem->getString("type"));
  M5.Lcd.print(": ");
  M5.Lcd.print(elem->getString("message"));
  M5.Lcd.print("\n");
};
```

※[こちらのGithubページ](https://github.com/sumihiro3/M5StackMilkcocoa)にも同じものを置いておきます

あとはArduino IDE からM5Stack へ書き込んで再起動するだけです。

# デモ動画

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/M5Stack?src=hash&amp;ref_src=twsrc%5Etfw">#M5Stack</a> でMilkcocoa のデータストアに登録されるデータを監視する（デモ動画）<a href="https://t.co/3xxcdJB3Ly">https://t.co/3xxcdJB3Ly</a></p>&mdash; Sumihiro Kagawa (@sumihiro3) <a href="https://twitter.com/sumihiro3/status/999572937249189888?ref_src=twsrc%5Etfw">2018年5月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 参考ページなど

* [ESP32(ESP-WROOM-32)でMilkcocoaSDKを使う](https://qiita.com/306_san/items/d074199e6fb4c3d637ed)
* [ESP8266やArduinoでMilkcocoaを使う方法(Milkcocoa Arduino SDK)](http://blog.mlkcca.com/iot/milkcocoa-arduino/)
* [Getting Started(Arduino, ESP8266, mbed)](https://mlkcca.com/document/start-arduino.html)
* [M5StackMilkcocoa](https://github.com/sumihiro3/M5StackMilkcocoa)