ころちゃん

木工・電子工作・IoT・作ったもの試したものを記事にして投稿してます

温度・湿度・気圧をBME280/Raspberry Pi/Azureで可視化 その1

time 更新日:  time 公開日:2020/04/30

温度・湿度・気圧をBME280/Raspberry Pi/Azureで可視化 その1

Raspberry Piに温度、湿度、気圧をとれるセンサーBME280を取り付けて、データをMicrosoftのクラウドAzureに送信し、グラフ描画してみました。

2年ほど前に同様の事をしたことがありました。その時の記録はこちら↓↓↓。

その際、Stream Analyticsという有料サービスを無料と思い込み、2ヵ月間動かし続けて2万円の請求が来てしまうという、大失敗をやらかしました。今回は別なアプローチで無料枠で動かせるように、試した手順の紹介です。

各ステップ毎に、3回に分けて書きます。

  1. 温度・湿度・気圧をBME280/Raspberry Pi/Azureで可視化 その1(AzureにWEBサーバとDBの準備編) ←本稿
  2. 温度・湿度・気圧をBME280/Raspberry Pi/Azureで可視化 その2(Raspberry Pi Zero WにBME280取り付け・データ送信編)
  3. 温度・湿度・気圧をBME280/Raspberry Pi/Azureで可視化 その3(チャート描画編)

構成概要

Raspberry Pi Zero Wに、温度・湿度・気圧の測定できるセンサーモジュールBME280を取り付ます。そして、読み取った値を一定間隔でWEBサーバにアップロードし、グラフで可視化する事を最終目標とします。

Raspberry Piでのデータ送信プログラムはPython、データを受け取るWebサーバはAzureのWebApps、データを格納するDBはMySQL、WEBサーバサイドのプログラムはPHP、ブラウザでのグラフ描画はJavaScriptを利用します。

最終的には、WEBブラウザ上でこのようなグラフを表示させます。

Azure Web Appsの準備

Azure Portalにログインします。アカウントは無料で作れます。

ログイン後、リソースの作成を選択します。

Webアプリを選択します。

作成するWebアプリの詳細を入力します。

  • サブスクリプション:料金支払いのお財布のようなイメージ。
  • リソースグループ:関連するサービスをグループ化します。
  • 名前:この名前がアクセスするURLになります(例:https://●●●.azurewebsites.net)。
  • 公開:コードを選択します。
  • ランタイムスタック:PHPを選択します。
  • オペレーティングシステム:Windowsを選択。後述しますが、Linuxを選択すると、MySQLが選択不可となります。
  • 地域:近くのサーバが良いでしょう。
  • SKUとサイズ:デフォルトではS1が選択されています。無料で動かせるF1に変更します。

開発/テストを選択>F1を選択します。

SKUとサイズがFreeF1になっている事を確認し、確認及び作成を選択します。

作成前の確認画面。作成を選択します。

おおよそ30秒ぐらいで、デプロイが完了します。ここまでの作業時間は、慣れてしまえばほんの数分。こんなに簡単な作業でWEBサーバが出来上がってしまいます。Azure凄い!

作成したAppsの概要を選択し、デプロイしたWEBサーバにアクセスしてみます。httpsがデフォルトで有効になっているのもありがたいですね。

デフォルト画面。このページは特に変更せずに、そのままにしておきます。

MySQLの準備

続いて、DBのMySQL in Appを設定します。MySQL in Appを選択>オンを選択>保存を選択>管理を選択します。この操作でDBが利用できるようになります。ホントに簡単です。

ちなみに、WebAppsを作成する際に、オペレーティングシステム:Linuxを選択すると、MySQL in Appが下記のようにグレーアウトして、「Linuxアプリでは、この機能はご利用いただけません。」と表示され選択できません。自社OSを使ってもらう為なんでしょうか。やりたいことができればどちらでもよいんですけどね。

MySQL in Appの管理を選択すると、DBの管理が出来るphpMyAdminが立ち上がります。しかし、場合によっては以下のようなエラー画面や、ユーザー名/パスワードを求められる画面が出る場合があります。

Error
MySQL said:
#2002 - An attempt was made to access a socket in a way forbidden by its access permissions.
— The server is not responding (or the local server's socket is not correctly configured).

ログインするIDやパスワードは設定してないし、どこにも書いてないのです。

このような画面が出たときの対処ですが、アプリの概要から、URLにアクセスし、再度MySQL in Appの管理を選択すると、phpMyAdminの画面に入れると思います。

デフォルトでデータベースlocaldbは作成済みのため、テーブルsensordataを下記内容で作成します。tempは温度を、humは湿度を、pressは気圧を格納します。

sensordataテーブルを設定します。localdbを選択>SQL>以下のCREATE文を貼り付け>Goを選択します。

CREATE TABLE `sensordata` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `temp` float NOT NULL,
  `hum` float NOT NULL,
  `press` float NOT NULL,
  PRIMARY KEY (`id`)
)DEFAULT CHARSET=utf8;

作成したテーブルを確認してみます。

データベースには、予めIDとパスワードが自動で設定されていたので、確認してみます。高度なツール>移動を選択します。

Kuduというツールを使います。クーズーと読むらしいです。呼び名に似つかわしくなく非常に優秀なツールで、そのギャップに思わず笑ってしまいました。Debug console>PowerShellを選択します。

MySQLのユーザー名やパスワードを確認してみます。ディレクトリ[D:\home\data\mysql]に移動し、[MYSQLCONNSTR_localdb.txt]の内容を確認します。データベース名、ホスト名、ポート番号、ユーザーID、パスワードが確認できます。

cat MYSQLCONNSTR_localdb.txt

プログラムのアップロード

WEBコンテンツが保存されるルートディレクトリは、[D:\home\site\wwwroot]となります。ルートディレクトリに直接ファイルを置きたくないので、[sensortest]というディレクトリを作成しました。

データベースにデータをインサートするのに、IDとパスワードが必要となります。今回利用するMySQLinAppの情報を調べてみると、上記のIDパスワードを直接設定してもDB接続できるらしいですが、ポート番号が不定期に変更され、接続できなくなることがあるとの事。

そのため、環境変数からその都度IDとパスワードをポートを取得する方が良いとの情報がありました。自分も環境変数から必要情報を取得しDB接続する方法をやってみました。環境変数は$_SERVER[“MYSQLCONNSTR_localdb”]で渡されます。参考にしたサイトはこちら。

DB接続で上手くいったコード[DbManager.php]と[Encode.php]。

<?php
function GetDb(){
$azure_mysql_connstr = $_SERVER["MYSQLCONNSTR_localdb"];

    $azure_mysql_connstr_match = preg_match(
      "/".
        "Database=(?<database> .+);".
        "Data Source=(?<datasource> .+):".
        "(?<port> .+);".
        "User Id=(?<userid> .+);".
        "Password=(?<password> .+)".
      "/u",
      $azure_mysql_connstr,
      $_);        

      $dsn = 'mysql:dbname='.$_['database'].'; host='.$_['datasource'].':'.$_['port'];
      $usr = $_['userid'];
      $passwd = $_['password'];

    try
    {
      $db = new PDO($dsn, $usr, $passwd);
      $db-> exec('SET NAMES utf8');
    }
    catch (PDOException $e)
    {
      die("connection failure: {$e-> getMessage()}");
    }
    return $db;
}

<?php
function e($str, $charset = 'UTF-8'){
print htmlspecialchars($str, ENT_QUOTES, $charset);
}

端末からデータをPOSTメソッドで受け取るプログラム[senserdatapost.php]はこちら。JSON形式で受け取り、データベースにインサートします。

<?php
require_once 'DbManager.php';
require_once 'Encode.php';
$db = GetDB();
$in = json_decode(file_get_contents('php://input'), true);
if (!isset($in['id']))
{
$st = $db->prepare("INSERT INTO sensordata(datetime,temp,hum,press) VALUES(:datetime,:temp,:hum,:press)");
}
$st->execute($in);
echo json_encode("normal end");

3つのファイルをアップロードします。ファイルのアップロードはKuduのWEB画面領域にドラッグ&ドロップで可能です。最近までKuduの存在を知らずにずっとFTPと利用していたのですが、こちらの方が圧倒的に便利です。全てブラウザ1つで完結します。

データベースへ書き込みテスト

温度等のセンサーデータをDBに書き込めるかのテストしてみます。クライアントからアップロードする想定で、以下のテストファイル[testpost.html]を作ってみました。これをサーバにアップロードして、値を適当に入力し送信を選択します。POSTメソッドでJSONデータを送信しています。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>データPOST送信テスト用</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script type="text/javascript">
    $(function(){
        $("#response").html("Response Values");
        $("#button").click( function(){
            var url = $("#url_post").val();
                var JSONdata = {
                    datetime: $("#datetime").val(),
                    temp: $("#temp").val(),
                    hum: $("#hum").val(),
                    press: $("#press").val()   
                };
            alert(JSON.stringify(JSONdata));
            $.ajax({
                type : 'post',
                url : url,
                data : JSON.stringify(JSONdata),
                contentType: 'application/JSON',
                dataType : 'JSON',
                scriptCharset: 'utf-8',
                success : function(data) {
                    // Success
                    alert("success");
                    alert(JSON.stringify(data));
                    $("#response").html(JSON.stringify(data));
                },
                error : function(data) {
                    // Error
                    alert("error");
                    alert(JSON.stringify(data));
                    $("#response").html(JSON.stringify(data));
                }
            });
        })
    })
</script>
</head>
<body>
    <h1>データPOST送信テスト</h1>
    <p>URL: <input type="text" id="url_post" name="url" size="60" value="https://●●●.azurewebsites.net/sensortest/sensordatapost.php"></p>
    <p>時刻: <input type="text" id="datetime" size="30" value="2020-04-18 20:30:12"></p>
    <p>温度(℃): <input type="text" id="temp" size="30" value="23"></p>
    <p>湿度(%): <input type="text" id="hum" size="30" value="56.3"></p>
    <p>気圧(hpa): <input type="text" id="press" size="30" value="1017.2"></p>
    <p><button id="button" type="button">送信</button></p>
    <textarea id="response" cols=60 rows=1 disabled></textarea>
</body>
</html>

エラーは出ず、データベースに値が登録されているのが確認できました。

Raspberry Piから同じ形式でのデータ送信されれば、データベースへ値が登録される状況になりました。この作業までで、その1(AzureにWEBサーバとDBの準備編)は終了です。

次回その2では、Raspberry Pi Zero Wに物理的にセンサーを取り付ける作業、センサーから値を読み取る設定、読み取った値をサーバにアップロードする設定を行います。

参考にさせていただいたURL

 

sponsored link

down

コメントする




CAPTCHA


管理人

ころちゃん

木工で日用品を作ったり、懐中電灯を改造したりしてます。まだまだ素人ですがどうぞよろしく。



sponsored link

アーカイブ