Raspberry PiのデータをGCPに送ってみた(無料)
Raspberry PiのデータをMySQLに格納し、Web上で確認できる仕組みを作りたかった。
VPSにサーバーを立てて、データのやり取りをしたい人向け。
※本記事は、Rasberry Pi上で気温データを取得し、送信することを目的としています。
開発環境
- Windows10 Pro
- Powershell
- Windows Subsystem for Linux(Ubuntu)
GCPについて
Google Cloud Platformの略称で、Googleが提供しているクラウドコンピューティングサービスである。
GCPの始め方はこちらを参考に
Windows Subsystem for Linux(WSL)について
- Ubuntu(バージョン明記なし)をMicrosoft Storeからインストール
- どうやら自動的に最新版になるらしい
- ホームディレクトリは
/home/[作成ユーザー名]/
になっている- Powershellは
/mnt/c/Users/[ユーザー名]/
- Powershellは
-
/mnt/c/Users/[ユーザー名]/
にcdコマンドで移動して作業開始
Webサーバを立てる
- GCPプロジェクトの作成
- 好きなOSのVMを立てる(筆者は、Ubuntu 18.04 LTS)
※無償枠で作成する場合はこちらを参考に作成してください。
- SSH認証を行う(Windowsからアクセスする用)
※補足:公開鍵をscpで送りたい場合
scp ~/.ssh/[公開鍵] [ユーザー名]@[転送先サーバのIP]:~/.ssh/
- apache2のインストール
sudo apt-get update
sudo apt-get install apache2 -y
curl http://[外部IP]
※外部IPはGoogle Cloud Platform -> Computer Engine -> VMインスタンス
- ファイアーフォールの設定 (ufwのインストールと設定)
#有効化
sudo ufw enable
#使っているTCP/UDPポートを調べる
sudo ufw status
#nmapでも可能
sudo nmap -sTU localhost
#ポートの解放(ルールの登録)
sudo ufw allow [許可したいポート番号]
#ルールの削除
sudo ufw status numbered
sudo ufw delete [number]
#無効化
sudo ufw disable
DBの構築(MySQL)
sudo apt install mysql-server mysql-client
#サービスの起動確認
sudo service mysql status
#MySQLの初期設定
sudo mysql_secure_installation
#コンソールからMySQLサーバへ接続
sudo mysql -u root -p
- MySQLのユーザー情報の確認等
#状態表示
mysql> status
#データベース一覧表示
mysql> show database;
#ユーザー一覧表示
mysql> select user, host from mysql.user;
#特定ユーザの権限確認(ex) ユーザー:root, ホスト名:localhost)
mysql> show grants for 'root'@'localhost';
#終了
mysql> exit
https://www.yokoweb.net/2018/05/13/ubuntu-18_04-server-mysql/
- 実際に構築をする
- 今回は、取得時間と気温データの2つのフィールドを作成する
sudo mysql
#データベースの作成
mysql> create database [db_name]
mysql> show databases;
#データベースの移動
mysql> use [db_name]
#テーブルの作成(シングルコートいらない)
mysql> create table [tbl_name] ( id int(11) NOT NULL AUTO_INCREMENT,
-> ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-> temp float NOT NULL,
-> PRIMARY KEY(id)) ENGINE=MyISAM
#確認
mysql> show tables from [db_name];
mysql> show columns from [tbl_name];
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| ts | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| temp | float | NO | | NULL | |
+-------+-----------+------+-----+-------------------+-----------------------------+
3 rows in set
※トランザクション処理は行わないので、MyISAM。上記コードは温度データのみ格納用。
- 外部から直接MySQLにアクセスするやり方もあるらしいです
プログラムの作成
PHPの環境設定
- PHPをインストール
#最新版でなければこれでOK(最新はver7.3、aptの場合ver7.2)
sudo apt install php
- ドキュメントルート(apacheがブラウザに送信するHTML)は
/var/www/html/
- パーミッションを変更
- PHPの動作確認はphpinfoで可能
<?php phpinfo(); ?>
PHPからDB(MySQL)へのアクセス確認
- PHP Data Objects(PDO) ※今回はPDOを使用
- PHPからデータベースのアクセスを抽象的にやってくれる
- mysqli
- MySQL改良版拡張モジュール
<?php
try{
// PDOクラスのオブジェクトを作成
$pdo = new PDO('mysql:host=localhost;dbname=[db_name];charset=utf8', '[ユーザー名]', '[パスワード]', array(PDO::ATTR_EMULATE_PREPARES => false));
}catch(PDOException $e){
exit('データベース接続失敗。'.$e->getMessage());
}
// DB処理
switch ($_SERVER['REQUEST_METHOD']) {
case 'GET':
$st = $pdo->query("select * from [テーブル名]");
echo json_encode($st->fetchAll(PDO::FETCH_ASSOC));
break;
case 'POST':
$data = json_decode(file_get_contents('php://input'), true);
$st = $pdo->prepare("insert into [テーブル名](ts, temp) values (:datetime,:temp)");
$st->execute($data);
header('Content-Type: application/json');
echo json_encode("end");
break;
}
?>
Raspberry PiからPHPへのデータ送信処理(Python)
# coding: utf-8
import requests
import json
from datetime import datetime
def main():
url = 'http://[外部IP]/[プログラム名].php'
#気温取得の処理
...
temp = #値
data = {'datetime':datetime.now().strftime("%Y/%m/%d %H:%M:%S"),'temp':temp}
#JSON形式にdataをエンコード
print(json.dumps(data))
#JSON形式でPOSTリクエストを送信する(json形式のレスポンスが欲しいため、Content-type指定)
response = requests.post(url, json.dumps(data), headers={'Content-type': 'application/json'}) #正しく返された場合にresponseに値が入る
print(response.json())
pass
if __name__ == '__main__':
main()
センサーデータをうまく利活用し、クラウドとの連携をしていきたい…