家の温度・湿度をLCD表示＆サーバで記録・可視化＆通知する（ESP32）

##やったこと
ESP32を使ったIoT入門として、家の温度・湿度を
①液晶に表示
②サーバーに記録・可視化
③一定値を超えたら通知
するようなシステムを組んでみた。

一度にやると面倒だけど、1つ1つ機能を作れば誰でもできるのでやってみてください！

##使ったもの
・ESP32(DevKitC)
・温度湿度センサー(DHT11)
・液晶画面OLED(SSD1306)
・ブレッドボード(サンハヤト製)

サービス
・データ記録可視化サービス Ambient
・連携サービスIFTTT

##結線イメージ
雑ですがイメージです。解説は後ほど。
![IMG_0975.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342722/719aa2cb-25af-3700-d07d-b07703cab90c.jpeg)

##コード
解説は後ほど。まずは全体コード
この場合は湿度が50%超えると通知がいくようになってます。

```java
#include <WiFi.h>
#include <Ambient.h>
#include <DHT.h>
#include <HTTPClient.h>
#include "SSD1306.h"//ディスプレイ用ライブラリを読み込み

#define channelId 00000  // 生成したAmbientチャネルID
#define writeKey "hogehoge"  // Ambient のライトキーをセット

//DHT
const int PIN_DHT = 4;
DHT dht(PIN_DHT,DHT11);

//Ambient
Ambient ambient;
WiFiClient client;

//WiFiのIDとPASS
const char *ssid = "XXXXXXX";  //wifiのssid
const char *password = "XXXXXX";  //wifiのパスワード

//IFTTT
const String maker_Event = "XXXXX"; // Maker Webhooks
const String maker_Key   = "hogehoge"; // Maker Webhooks
const char* host = "maker.ifttt.com"; //host名

//LCD設定
SSD1306  display(0x3c, 21, 22); //SSD1306インスタンスの作成（I2Cアドレス,SDA,SCL）

//セットアップ
void setup() {
  Serial.begin(115200);
  
  // WiFiに接続
  Serial.println(ssid);
  Serial.print("Waiting for Wi-Fi connection");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  //Ambientに接続
  ambient.begin(channelId, writeKey, &client);  //  チャネルIDとライトキーを指定してAmbientの初期化
  
  //DHT 設定
  dht.begin();
}

//main
void loop() {
  // put your main code here, to run repeatedly:
    // DHT11から読み込み
    float t = dht.readTemperature();
    float h = dht.readHumidity();
    delay(200);
    if (isnan(t) || isnan(h)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }
    //シリアルモニターに温度・湿度の表示
    Serial.println("Temperature: " + String(t) + "C   Humidity: " + String(h) + "%");

    if(h > 50){  //湿度が閾値を超えたら
      //IFTTTに送信
      sendToIFTTT(t,h);
      }
    
    //Ambientに温度と湿度を送る
    ambient.set(1, t);   //データセット          
    ambient.set(2, h); 
    ambient.send();   //  Ambientにデータを送信  

    //LCD設定
    display.init();    //ディスプレイを初期化
    display.setFont(ArialMT_Plain_16);    //フォントを設定
    display.drawString(0, 0,"t = " + String(t));    //(0,0)の位置にHello Worldを表示
    display.drawString(0, 16,"h =" + String(h));    //(0,0)の位置にHello Worldを表示
    display.display();   //指定された情報を描画
    
    //データ取得頻度
    delay(1000*60);  //1000ミリ秒＝1秒
}

//IFTTTにパラメータを送信
void sendToIFTTT(float value1, float value2 )
{

  //IFTTT用
    // Use WiFiClient class to create TCP connections
    WiFiClient client;
    const int httpPort = 80;
    if (!client.connect(host, httpPort)) {
      Serial.println("connection failed");
      return;
      }

  // We now create a URI for the request
    String url = "/trigger/";
    url += maker_Event;
    url += "/with/key/";
    url += maker_Key;
    url += "?value1=";
    url += String(value1);
    url += "&value2=";
    url += String(value2);

    
    Serial.print("Requesting URL: ");
    Serial.println(url);
    
    // This will send the request to the server
    client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
    // Read all the lines of the reply from server and print them to Serial
    while (client.available()) {
      String line = client.readStringUntil('\r');
      Serial.print(line);
      }

  return; 
}
```

##⓪温度・湿度センサーを使用
準備
・DHT11のライブラリをインストール
・3.3vとGND,4pinに接続

コード該当部


```java
//DHT
const int PIN_DHT = 4;
DHT dht(PIN_DHT,DHT11);

//setup内
//DHT 設定
  dht.begin();

//loop内
    float t = dht.readTemperature();
    float h = dht.readHumidity();
    delay(200);
    if (isnan(t) || isnan(h)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }
    //シリアルモニターに温度・湿度の表示
    Serial.println("Temperature: " + String(t) + "C   Humidity: " + String(h) + "%");
```

##①液晶に表示
hello-worldは私の別記事参照ください
[OLED LCDディスプレイ(SSD1306)をESP32でHello-worldしてみる！](https://qiita.com/taiyyytai/items/6b2a90a3fe9e2a10fd04)
**SDA:IO21**
**SCL:IO22**

コード該当部

```java
//LCD設定
SSD1306  display(0x3c, 21, 22); //SSD1306インスタンスの作成（I2Cアドレス,SDA,SCL）

//setup内

//loop内
//LCD設定
    display.init();    //ディスプレイを初期化
    display.setFont(ArialMT_Plain_16);    //フォントを設定
    display.drawString(0, 0,"t = " + String(t));    //(0,0)の位置にHello Worldを表示
    display.drawString(0, 16,"h =" + String(h));    //(0,0)の位置にHello Worldを表示
    display.display();   //指定された情報を描画
```


##②サーバ記録・可視化
Ambientというサービスを使います。とても簡単でまず、登録してチャンネルIDとライトキーを取得してください。
[Ambient](https://ambidata.io/)

次にAmbientのライブラリをインストールしてwifi接続すればOKです。

コード該当部


```java
#define channelId 00000  // 生成したAmbientチャネルID
#define writeKey "hogehoge"  // Ambient のライトキーをセット

//setup内
//Ambientに接続
  ambient.begin(channelId, writeKey, &client);  //  チャネルIDとライトキーを指定してAmbientの初期化

//loop内  
//Ambientに温度と湿度を送る
    ambient.set(1, t);   //データセット          
    ambient.set(2, h); 
    ambient.send();   //  Ambientにデータを送信  

```

![FADD40D1-748E-4841-9BE8-B79725743842.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342722/f1c95d94-13c7-2d72-3521-299396ab904e.png)


##③Slackに通知
IFTTTという連携サービスを使います。
イベント名とキーを取得してください。

```java
//IFTTT
const String maker_Event = "XXXXX"; // Maker Webhooks
const String maker_Key   = "hogehoge"; // Maker Webhooks
const char* host = "maker.ifttt.com"; //host名
```

[IFTTT]()
[IFTTTを使ってESP32からSlackに通知する(入門)](https://magazine.halake.com/entry/esp32_ifttt?utm_source=feed)

IFTTTとはhttp通信を行います。送信用の関数を作りました。

```java
//IFTTTにパラメータを送信
void sendToIFTTT(float value1, float value2 )
{

  //IFTTT用
    // Use WiFiClient class to create TCP connections
    WiFiClient client;
    const int httpPort = 80;
    if (!client.connect(host, httpPort)) {
      Serial.println("connection failed");
      return;
      }

  // We now create a URI for the request
    String url = "/trigger/";
    url += maker_Event;
    url += "/with/key/";
    url += maker_Key;
    url += "?value1=";
    url += String(value1);
    url += "&value2=";
    url += String(value2);

    
    Serial.print("Requesting URL: ");
    Serial.println(url);
    
    // This will send the request to the server
    client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
    // Read all the lines of the reply from server and print them to Serial
    while (client.available()) {
      String line = client.readStringUntil('\r');
      Serial.print(line);
      }

  return; 
}
```


##終わりに
思い通りに通信までできるようになれば、工作の幅が広がると思います。
私もどんどん勉強します。