{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"オリジナルの作成:2015/11/01"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 0P-WiFiからIFTTTを使ってみる\n",
"## IFTTTについて\n",
"Makerが提供するIFTTT(イフトと発音するらしい)サービスを使うと ESP-WROOM-02モジュールからのデータを簡単にサーバに送り、 様々な処理を施すことができます。\n",
"\n",
"詳しくは、スイッチサイエンスさんの \n",
"[IFTTTにMaker Channelができました](http://mag.switch-science.com/2015/06/25/ifttt-maker-channel/)\n",
"を参照してください。\n",
"\n",
"MakerのIFTTTに登録するとユーザIDにシークレットKEYが割り当てられます。 このKEYとイベントでIFTTTに情報を送ります。\n",
"\n",
"### iPhoneアプリIF by IFTTT\n",
"iPhoneでMakerのIFTTTで作ったイベントを受け取るには、iPhoneアプリIF by IFTTTをインストールします。 詳しくは以下を参照してください。\n",
"\n",
"- [IF by IFTTT](https://itunes.apple.com/jp/app/if-by-ifttt/id660944635?mt=8)\n",
"\n",
"### Maker Channel画面\n",
"登録が終わり、http://ifttt.com/makerに行くと以下の様な画面になります。 Reconnect Channelを押すとKeyが再割り当てされますので、注意しましょう。\n",
"\n",
"\n",
"\n",
"### トリガーイベントの作成\n",
"新しくイベントを作るには、Receive a web requestをクリックし、 Receive a web requestの「Create a new Recipe」ボタンを押すとレシピの作成画面に移動します。\n",
"\n",
"\n",
"\n",
"「this」をクリックし、Search ChannelsでMakerと入力し、 Makerのアイコンを選択します。\n",
"\n",
"\n",
"\n",
"Choose a Trigger画面が表示され、Receive a web requestをクリックします。\n",
"\n",
"以下の様なComplete Trigger Fields画面になりますので、ここでEvent Name を入力します。ここではLM35と入力しました。\n",
"\n",
"\n",
"\n",
"以下の画面でthatを選択します。\n",
"\n",
"\n",
"\n",
"Choose Action Channelが表示されるので、iPhoneと入力し、iPhoneのIF Notificationを選択します。\n",
"\n",
"\n",
"\n",
"Choose an Action画面がでるので、Send a notificationをクリックします。\n",
"\n",
"Complete Action Fields画面がでるので、Notificationに出すメッセージを入力します。 以下の様にキーワードを{{ }}で括って入力し、Create Actionボタンを押します。\n",
"\n",
"```\n",
"温度センサLM35からイベント{{EventName}}と値{{Value1}}を受け取りました。 \n",
"```\n",
"\n",
"\n",
"\n",
"以下の最終確認でますので、Create Recipeボタンをクリックします。\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## レシピの確認\n",
"MakerのIFTTTで作ったイベントは、普通のHTTPプロトコルで送ることができるので、 ブラウザーからイベントのテストができます。\n",
"\n",
"先ほど作ったLM35レシピを確認してみましょう。\n",
"\n",
"ここではシークレットキーをSECRET_KEYで説明しますので、適宜置き替えてください。\n",
"\n",
"- イベント名: LM35\n",
"- KEY: SECRET_KEY\n",
"\n",
"ブラウザーから以下の様に入力します。\n",
"\n",
"```\n",
"http://maker.ifttt.com/trigger/LM35/with/key/SECRET_KEY?value1=21.0\n",
"```\n",
"\n",
"iPhoneに以下の様なNotificationが表示されます。\n",
"\n",
"\n",
"\n",
"\n",
"### IFTTTの受け付けるHTTP GET要求\n",
"MakerのIFTTTサーバは、\n",
"Arduino勉強会/0N-WiFiモジュールその1\n",
"で試したようなGET要求だけではエラーになることが分かりました。\n",
"\n",
"調べたところ、以下の様にHTTPヘッダにHostとAcceptを追加すると上手くいきました。 \n",
"\n",
"```bash\n",
"$ telnet 54.235.148.87 80\n",
"GET /trigger/test/with/key/SECRET_KEY HTTP/1.1\n",
"Host: maker.ifttt.com\n",
"Accept: */*\n",
"```\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## ArduinoからLM35イベントを送る\n",
"スイッチサイエンスからESP-WROOM-02ピッチ変換済みモジュール《シンプル版》 が届いたので、 これを使って温度センサLM35から取得した温度をIFTTTイベントとして送ってみます。\n",
"\n",
"\n",
"\n",
"### ピッチ変換モジュールのハンダ付け\n",
"ESP-WROOM-02をピッチ変換モジュールにハンダ付けします。 裏面のジャンパーは、SJ1とSJ2をハンダでショートします。\n",
"\n",
"\n",
"\n",
"### ブレッドボードの組み立て\n",
"ブレッドボードにESP-WROOM-02とArduino Pro Mini(3.3V)とLM35を以下の様に配置します。 抵抗は10KΩを使いました。\n",
"\n",
"\n",
"\n",
"\n",
"### スケッチ\n",
"Arduino勉強会/0O-WiFiモジュールその2\n",
"で作ったEspClientのatCipSendを 以下の様に修正し、シリアルもSoftwareシリアルでESP-WROOM-02で接続することに しました。この結果シリアルモニタの出力は文字化けしますが、この方が開発が簡単になります。\n",
"\n",
"```C++\n",
"int EspClient::atCipSend(char *uri, char *host) {\n",
" sprintf(buf, \"GET %s HTTP/1.1\\r\\nHost: %s\\r\\nAccept: */*\\r\\n%s\", uri, host, CRLF2);\n",
" int len = strlen(buf);\n",
" char tmp[32];\n",
" sprintf(tmp, \"AT+CIPSEND=%d%s\", len, CRLF);\n",
" // uriを送る\n",
" atCommand(tmp, 1000);\n",
" esp.print(buf);\n",
" // 応答を待つ\n",
" waitForResponse();\n",
"}\n",
"```\n",
"\n",
"LM35の温度を送るテスト用スケッチは、以下の通りです。\n",
"```C++\n",
"#include \"EspClient.h\"\n",
"#include \n",
"\n",
"#define ST_SSID \"take-iPhone5s\"\n",
"#define ST_PASSWD \"jpb67k42hgq5z\"\n",
"\n",
"#define SERVER_ADDR \"54.235.148.87\" // maker.ifttt.comのIPアドレス\n",
"#define SERVER_PORT 80\n",
"\n",
"#define EVENT \"LM35\"\n",
"#define SECRET_KEY \"ここにSECRET_KEYを入れてください\"\n",
"\n",
"int sw_pin = 10;\n",
"int sTx_pin = 12;\n",
"int sRx_pin = 11;\n",
"int lm35_pin = A0;\n",
"int lm35_value;\n",
"\n",
"char buf[128];\n",
"EspClient esp(sRx_pin, sTx_pin);\n",
"\n",
"void setup() {\n",
" pinMode(sw_pin, INPUT);\n",
" esp.begin(9600);\n",
" esp.println(\"ESP8266IF3tTest\");\n",
" esp.atCwMode(STATION_MODE);\n",
" esp.atCwJap(ST_SSID, ST_PASSWD);\n",
"}\n",
"\n",
"void loop() {\n",
" if (digitalRead(sw_pin) == LOW) {\n",
" esp.println(\"SW pressed\");\n",
" // チャタリング防止\n",
" delay(500);\n",
" lm35_value = analogRead(lm35_pin); // LM35から値を読み取る\n",
" int temp10 = (int)((lm35_value*3.3)/1023.0*1000); // 温度を0.1度までの整数に変換\n",
" sprintf(buf, \"temp=%d.%df\", temp10/10, temp10%10);\n",
" esp.println(buf); \n",
" esp.atCipStart(SERVER_ADDR, SERVER_PORT);\n",
" sprintf(buf, \"/trigger/%s/with/key/%s?value1=%d.%d\", EVENT, SECRET_KEY, temp10/10, temp10%10);\n",
" esp.atCipSend(buf, \"maker.ifttt.com\"); \n",
" }\n",
"}\n",
"```\n",
"\n",
"### 動作確認\n",
"起動後に、ボタンを押してイベントをIFTTTサーバに送ります。 シリアルモニタは以下の様に文字化けしますが、イベントはきちんと送られています。\n",
"\n",
"```\n",
"ESP8266IF3tTest\n",
"AT+CWMODE=1\n",
"\n",
"OK\n",
"AT+CWJAP=\"take-iPhone5s\",\"jpb67k42hgq5z\"\n",
"\n",
"WIFI DISCONNECT\n",
"WIFDo wait onece\n",
"WIFI GOT IP\n",
"\n",
"OK\n",
"SW pressed\n",
"temp=25.4f\n",
"AT+CIPSTART=\"TCP\",\"54.235.148.87\",80CONNECT\n",
"\n",
"OK\n",
"AT+CIPSEND=112\n",
"\n",
"busy p...\n",
"\n",
"OK\n",
"> GE@½ÑÉ¥½cªz½[½¹©Q]©Íå¥aY©-Ùµ±ý±\n",
"±ÕÅëªr¢BBEõ(rjõkÑéj\n",
"ɹKÑÑѹ½µ5\n",
"ÁÑéRzRjÔÔ¨HHTÖ,¤¦L&H¬_]Y®Cá\n",
"SEND OK\n",
"```\n",
"\n",
"\n",
"\n",
"### スケッチのダウンロード\n",
"スケッチを以下からダウンロードできます。\n",
"\n",
"- [ESPClientスケッチ EspIFTClient.zip](data/EspIFTClient.zip)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 温度を記録する\n",
"つぎにGoogleのスプレッドシートに温度とイベントが発生時刻を記録してみましょう。\n",
"\n",
"### IFTTTの定義\n",
"以下の様にActionでspreadsheetに行を追加するRecordLM35イベントを作成します。\n",
"\n",
"\n",
"\n",
"### ブラウザーでテスト\n",
"以下のURLをブラウザー入力します。\n",
"\n",
"```\n",
"http://maker.ifttt.com/trigger/RecordLM35/with/key/<<ここにSECRET_KEYを入れる>>?value1=18.0\n",
"```\n",
"\n",
"Googleドライブにアクセスすると、IFTTT/Maker/RecordLM35のディレクトリが作られ\n",
"IFTTT_MakerRecordLM35スプレッドシートに以下のような記録が作成されます。\n",
"\n",
""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.13"
}
},
"nbformat": 4,
"nbformat_minor": 0
}