株式会社インデペンデンスシステムズ横浜

システム開発エンジニアの西田五郎が運営しております。Raspberry Pi や Arduino その他新規開発案件のご依頼をお待ちしております。

IoT Raspberry Pi

Raspberry PiでIoT(温度・湿度・気圧データ編 その2)Webサーバ側構築とデータ送信

投稿日:2017年4月2日 更新日:

Raspberry PiでIoT 温度・湿度・気圧データ編の2回目です。前回はRaspberry Piに温度・湿度・気圧データが測定出来るセンサモジュールのBME280を接続して値を取得しました。

以下が、Raspberry PiでIoT(温度・湿度・気圧データ編)の記事一覧です。
Raspberry PiでIoT(温度・湿度・気圧データ編 その1)BME280でデータ取得
Raspberry PiでIoT(温度・湿度・気圧データ編 その2)Webサーバ側構築とデータ送信
Raspberry PiでIoT(温度・湿度・気圧データ編 その3)データ表示とグラフ表示”
Raspberry PiでIoT(温度・湿度・気圧データ編 その4)アラートメール送信

今回は以下のデータ保存の流れで、右側のWebサーバ(データベース)の部分を構築します。そして、構築したサーバにセンサーデータを送信します。送信処理は以下のデータ保存の流れで左側です。ここでの私のサーバ環境は、レンタルサーバ上で、ウェブサーバ:Apache、データベース:MYSQL、開発言語:PHPです。今時であれば他にもいろいろと選択肢があるとは思いますがこれでやってみました。

データ保存の流れ
Raspberry Pi + センサー => インターネット => Webサーバ(データベース)

今回の作業手順は以下です。
1.データベースの構築(Webサーバ上)
2.PHPプログラムの作成(Webサーバ上)
3.Raspberry PiからPython単体テスト送信
4.Raspberry PiからセンサーデータをPythonで送信
5.ブラウザでデータ確認
6.cronでの自動実行

早速順番に書きます。但しですが、詳細の環境構築方法や、詳細のツールの使用法等は必ずしも書きませんので、実際に作業する場合はマニュアルサイト等を探してみて下さい。また、各プログラムは単なるテストプログラムです。動作保証は一切しておりません。

1.データベースの構築(Webサーバ上)
ここではMYSQLを使うので管理ツールは phpMyAdminです。以下のCreate文のテーブルを作成しました。

-- 
-- データベース: `indpsys_iot`
-- テーブルの構造 `sensorvalues`
-- 
CREATE TABLE `sensorvalues` (
  `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`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=316 ;

以下のように出来ました。

2.PHPプログラムの作成(Webサーバ上)
以下のプログラムを作成しました。

<?php
$pdo = new PDO('mysql:host=localhost;dbname=dbname;charset=utf8','tablename','mypassword');

switch ($_SERVER['REQUEST_METHOD']) {
	case 'GET':
		$st = $pdo->query("SELECT * FROM sensorvalues");
  		echo json_encode($st->fetchAll(PDO::FETCH_ASSOC));
		break;
		
	case 'POST':
		$in = json_decode(file_get_contents('php://input'), true);
  		if (!isset($in['id']))
  		{
    		    $st = $pdo->prepare("INSERT INTO sensorvalues(datetime,temp,hum,press)                                  VALUES(:datetime,:temp,:hum,:press)");
  		}
  		$st->execute($in);
  		
  		echo json_encode("normal end");
  		
  		break;
}
?>

このプログラムをインターネット上でもローカル環境でもいいですが、Webサーバ上にアクセス出来るように配置します。処理としては、HTTPのGETとPOSTの処理を実装しています。
GETの場合は全レコードをJSON形式で返しています。POSTの場合は念のためidという項目が設定されていなかったら、追加レコードとしてINSERT文を実行します。

3.Raspberry PiからPython単体テスト送信
ここでの作業、処理は以下の太字の部分です。
データ保存の流れ
Raspberry Pi + センサー => インターネット => Webサーバ(データベース)
上記のPHPプログラムにRaspberry PiのPythonのプログラムからまずは単体テスト的にPOSTします。以下のPythonプログラムを使用します。

import requests
import json

from datetime import datetime

def uploadSensorValues(temp, hum, press):

    url = 'http://yourdomain/subsub/sensvalues.php'

    sensorsdata = {'datetime':datetime.now().strftime("%Y/%m/%d %H:%M:%S"),'temp':temp,'hum':hum,'press':press}

    print json.dumps(sensorsdata)

    headers = {'content-type': 'application/json'}

    res = requests.post(url, data=json.dumps(sensorsdata), headers=headers, verify=False)

    print res.json()
    pass

def main():

    uploadSensorValues(21.8, 39.1, 1020)

if __name__ == '__main__':
    main()

以下のように実行します。ここではweb.pyというファイル名で作成しています。

この場合は、main()が呼ばれるので、温度:21.8、湿度:39.1、気圧:1020というテストデータをjsonデータでPOSTしています。作成したjsonデータとレスポンスを画面に表示しています。

正常に終了すると、PHPからのレスポンスの normal end が表示されます。
データベース側を、phpMyAdminで確認します。以下のように確認出来ました。

4.Raspberry PiからセンサーデータをPythonで送信
いよいよ実際のセンサーデータを送信します。

まずは、前回のようにしっかりとbme280センサーモジュールを接続します。

前回のフォルダに上記のweb.pyを追加して、bme280Main.pyをbme280MyMain.pyに名称変更して、以下のファイル構成にします。(※すいません別にメインのファイル名は任意でいいです。好きなファイル名にして下さい。)
bme280MyMain.py
bme280_custom.py
web.py

以下のようになります。

ここでbme280MyMain.py(メイン)を以下のように編集します。

#coding: utf-8

import bme280_custom
import datetime
from web import uploadSensorValues

#センサー値をカンマ区切りで取得
csv = bme280_custom.readData()
list = csv.split(",")

#カンマ区切りを別々の変数に格納
press = list[0]
temp = list[1]
hum = list[2]

#それぞれを表示
print temp
print hum
print press

#webへPOST
uploadSensorValues(temp,hum,press);

以下のようにメインを実行します。sudo を忘れないで下さい。正常に処理出来れば、センサーの各値、normal endのレスポンスが確認出来ると思います。

5.ブラウザでデータ確認
実際に保存したデータをブラウザでも確認します。ブラウザで以下のようにPHPのURLを指定します。
http://youdomainOrIPAdress/subsub/sensvalues.php

確かに、値が確認出来ますが、JSON形式のテキストで表示されただけです。この表示の続き等は次回に書きます。

6.cronでの自動実行
センサーデータを送信するプログラムをcronを使って自動実行します。以下で自動実行を設定します。
$ sudo crontab -e
編集状態で以下を追記します。これでセンサー送信プログラムが1分おきに実行されます。
0-59/1 * * * * sudo python /home/pi/bme280/bme280MyMain.py

前項の方法でブラウザで結果を確認します。ここではデータが増えているなという程度に分かればいいです。次回にデータの一覧表示、グラフ表示を作成します。

技術要素についての補足と雑感等
今回のWebサーバ側構築とデータ送信では以下のような技術要素が出てきました。
Webプラットフォーム
LAMPと呼ばれている環境を使いました。Linux(OS)、Apache(Webサーバ)、MYSQL(RDBMS)、PHP(プログラミング言語)の組み合わせです。どうやら最近は、MYSQLの後継としてMariaDBが出てきているようです。この環境をとりあずローカル環境で構築するのであれば、XAMPPも選択肢の一つだと思います。

HTTP通信(TCP/IP)
まずは、TCP/IPとはインターネットの通信プロトコル(通信規約)のことです。以下の記事で少し書きましたが、大きな特徴として他の類似の通信プロトコル(osi参照モデルとよく比較されます)と同様に「階層構造」になっていることです。
Arduino Ethernetシールド(旧製品)を使ってみた

TCP/IPの階層構造は以下です。

アプリケーション層 – アプリケーションプロトコル(HTTP、FTP、SMTP等)
トランスポート層 – プログラム間通信、制御(TCP、UDP等)
ネットワーク層 – ネットワーク層(IP4、IP6等)
リンク層 – Ethernet、Wifi等

HTTPはWebブラウザでも利用されていますが、アプリケーションプロトコルの一つです。Raspberry PiからPythonプログラムでこのHTTPのPOSTメソッドを使ってセンサーデータを送信しました。

今回では使用していませんが、IoTでよく利用されるプロトコルにMQTTがあります。MQTTの特徴としてはシンプルで軽量なことです。どこかで取り上げたいと思っています。

AdSense

AdSense

-IoT, Raspberry Pi

執筆者:

関連記事

Raspberry Piをモニターとキーボードなしで導入する(2021年5月版 その3)リモートデスクトップの導入から初期設定まで

今現在(2021年5月)の方法でRaspberry Piをヘッドレス(モニターとキーボードなしの状態)で導入する方法について書いています。前回まででSSH経由でログインするところまで書きました。今回で …

Raspberry Piでタッチアプリ開発(その4)ボタンとGPIOの連動

Raspberry Piでタッチアプリ開発の4回目です。前回作成したレイアウトとボタンのコールバックにGPIOの処理を組み込みます。そして、このアプリを自動起動するように設定します。 (※2021/0 …

Raspberry PiでAC100V(ソリッド・ステート・リレー)制御

Raspberry PiでAC100VのON/OFF制御を試してみました。今回そのために以下のソリッド・ステート・リレーキットを利用しました。この製品を選んだ理由としては「扱いが簡単」かなと思ったから …

Raspberry Pi 3でのコンソールケーブル利用と初期設定

Raspberry Pi 3 でコンソールケーブルを利用する方法と初期設定についてです。 以下のページ等で今までこのテーマについて書きました。 Raspberry Piをモニターとキーボードなしで導入 …

Raspberry Pi Imager でSDカード書き込み時にWifiやSSH接続を設定する方法

Raspberry Pi Imager のV1.6からは、Raspberry Pi ImagerのOSや書き込み先を選択する画面からオプションでWifiやSSH接続が設定出来るようになっていました。 …