3
0

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.

enebular_uhuruAdvent Calendar 2019

Day 5

enebularで値の見えるWebページを作る ~デバイス側~

Last updated at Posted at 2019-12-11

enebularで値の見えるWebページを作る(http post版)enebularで値の見えるWebページを作る ~enebularからherokuへのデプロイ~の続きの記事になります。

今回、デバイス側はMbedプラットフォームであるFRDM-K64FMulti IoT Boardを使用しました。
enebularで値の見えるWebページを作る(http post版))で書いたプラットフォームと変わってますが、同じプログラムが動作するはずです。)

image.png

#デバイスのプログラムの準備
K64FはMbedプラットフォームの為、Mbedのオンラインコンパイラ環境でプログラムを作りました。
Web側はhttp postでセンサーの値をアップロードできるようにしたので、http通信が行えるライブラリやJSON型を扱うライブラリ、Multi IoT Boardに搭載されている温度、湿度、気圧センサーのBME280のライブラリを使用します。

mbed-http
picojson
BME280

ここで、問題となるのが、httpsの通信です。
https通信にはルート証明書が必要になります。mbed-httpのライブラリにはルート証明書を取得する処理が無いため、手動で設定する必要があります。

herokuのルート証明書を調べる

センサーの値はenebularで値の見えるWebページを作る ~enebularからherokuへのデプロイ~で行った、heroku上で動作しているフローに対してアップロードします。
そのため、ルート証明書はherokuで使用しているものを調べます。
ルート証明書はブラウザで調べられます。ここでは普段使っているChromeでの調べ方を説明します。
まず、heroku上で動作しているページを開いて、以下の部分をクリックし、証明書を選択します。
image.png

image.png

ダイアログが表示されるので、証明書のパスのタブを選んで、証明書を選択し、証明書の表示をクリックします。

image.png

表示された証明書のダイアログで、詳細のタブからファイルにコピーをクリックします。

image.png

証明書のエクスポートウィザードが表示されるので、Base64形式を選び、ダウンロードします。

image.png

ダウンロードした証明書をテキストエディタで開き、ちょっと編集をして、ソースコードに貼り付けます。

# デバイスのプログラム
デバイスのプログラムの構成は以下の様にしています。
image.png

main_app.jsonはmbed-osの設定項目を定義するファイルになっています。今回のプログラムでは、Wi-Fiの設定を記述しています。


{
    "config": {
        "wifi-ssid": {
            "help": "WiFi SSID",
            "value": "\"SSID\""
        },
        "wifi-password": {
            "help": "WiFi Password",
            "value": "\"PASS\""
        }
    },
    "target_overrides": {
        "*": {
            "platform.stdio-convert-newlines": true,
            "esp8266.provide-default" : true
        }
    }
}

main.cppの内容は以下の様になっています。

#include "mbed.h"
#include "platform/mbed_thread.h"
#include "https_request.h"
#include "BME280.h"
#include "picojson.h"

#define SENSOR_UPDATE_RATE_MS   60000 // 1分おきにセンサーの値をアップロード
#define ID                      1

BME280 sensor(I2C_SDA, I2C_SCL);

const char SSL_CA_PEM[] = "-----BEGIN CERTIFICATE-----\n"
"MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs\n"
"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"
"d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\n"
"ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDEL\n"
"MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\n"
"LmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3Vy\n"
"YW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2\n"
"4C/CJAbIbQRf1+8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU+UDlqUH1VWtMIC\n"
"Kq/QmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK/IHe1NnF9Xt4ZQaJn1\n"
"itrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j/018QsIJzJa9buLnqS9UdAn\n"
"4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I+4G3FhahnSMSTeXXkgisdaScus0X\n"
"sh5ENWV/UyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcft\n"
"bZvySC/zA/WiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH/AgEA\n"
"MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw\n"
"NAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy\n"
"dC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29t\n"
"L0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIG\n"
"BFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQ\n"
"UzAdBgNVHQ4EFgQUUWj/kK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7D\n"
"aQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwd\n"
"aOpKj4PWUS+Na0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk/gNH\n"
"E+r1hspZcX30BJZr01lYPf7TMSVcGDiEo+afgv2MW5gxTs14nhr9hctJqvIni5ly\n"
"/D6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zu\n"
"xICaEnL6VpPX/78whQYwvwt/Tv9XBZ0k7YXDK/umdaisLRbvfXknsuvCnQsH6qqF\n"
"0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY+3sAzm2fTYS5yh+Rp/BIAV0Ae\n"
"cPUeybQ=\n"
"-----END CERTIFICATE-----\n";


int main()
{
    WiFiInterface *wifi = WiFiInterface::get_default_instance();
    if (!wifi) {
        printf("ERROR: No WiFiInterface found.\n");
        return -1;
    }

    int ret = wifi->connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
    if (ret != 0) {
        printf("\nConnection error: %d\n", ret);
        return -1;
    }
    
    while (true) {
        picojson::object body_json;
        body_json["id"] = picojson::value((double)ID);
        body_json["temperature"] = picojson::value(sensor.getTemperature());
        body_json["pressure"] = picojson::value(sensor.getPressure());
        body_json["humidity"] = picojson::value(sensor.getHumidity());
        string body = picojson::value(body_json).serialize();
        HttpsRequest* request = new HttpsRequest(wifi, SSL_CA_PEM, HTTP_POST, "https://{herokuのアプリケーション名}.herokuapp.com/push");
        request->set_header("Content-Type", "application/json");
        HttpResponse* http_res = request->send(body.c_str(), body.length());
        delete request;
        thread_sleep_for(SENSOR_UPDATE_RATE_MS);
    }
}

プログラムについて

今回は、Mbed OSのプログラムで書きました。
がっつり宣伝ですが、Mbed OSのプログラミング入門は著書を参照ください。

はじめてのMbed OS 5【前編】: Mbed OS 5で始めるIoTプロトタイピング
image.png

とはいえ、プログラミングしないでデバイス側のプログラムを作る方法もあります。
enebularは、デバイスにもフローをデプロイする機能があるので、次回の記事では、enebularで作ったフローがデプロイできるマイコンボード「RAVEN」で紹介したRAVENでデバイス側のプログラムを作ってみたいと思います。

3
0
0

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
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?