3.センサなどを使うための詳細設定

3.1.開発言語・ライブラリィ環境の設定

C,C++,pythonなどの言語及びライブラリィをインストールしておきます。

$ sudo apt-get install cmake libtool doxygen graphviz
$ sudo apt-get install ttf-bitstream-vera ttf-dejavu unzip python-numpy

この作業はしばらく時間がかかります。

3.2.Webサーバの設定

Webサーバは必須ではありません。
設定をしておくと、センサ値をhttp経由でJSON、CSV、htmlで外部からGETできると、活用範囲が広がり便利です。

今回はApacheではなく、軽量でPHPが問題なく稼働する lighttpd を利用します。
PHPは fastcgi で割とサクサク動きます。

先ずインストール。

$ sudo apt-get install lighttpd php5 php5-cgi php5-gd php5-mcrypt

設定ファイルの設定。

$ sudo nano /etc/lighttpd/lighttpd.conf
(中略)
server.document-root = “/var/www/html”
(中略)
server.username = “pi”
server.groupname = “pi”
(中略)
#include_shell “/usr/share/lighttpd/use-ipv6.pl ” + server.port
(中略)
server.modules += ( “mod_cgi” )
cgi.assign = ( “.pl” => “/usr/bin/perl”,
“.cgi” => “/usr/bin/perl”,
“.py” => “/usr/bin/python” )

include “fastcgi.conf”

PHP fastcgi の設定。

$ sudo nano /etc/lighttpd/fastcgi.conf
server.modules += (“mod_fastcgi”)
index-file.names += (“index.php”)
fastcgi.server = (
“.php” => (
“localhost” => (
“bin-path” => “/usr/bin/php-cgi”,
“socket” => “/tmp/php-fastcgi.sock”,
“broken-scriptfilename” => “enable”,
“max-procs” => 4, # default value
“bin-environment” => (
“PHP_FCGI_CHILDREN” => “1” # default value
)
)
)
)

コンテンツフォルダの作成とパーミッション(利用権限など)設定。

$ sudo mkdir /var/www/html
$ sudo mkdir /var/www/etc
$ sudo chown -R pi.pi /var/www
$ sudo chown -R pi.pi /var/log/lighttpd

Webサーバを再起動します。

$ sudo service lighttpd restart

3.3.FTPサーバの設定

FTPサーバも必須ではありません。
設定しておくと、慣れたPCのエディタでプログラムを作成し、Raspberry Pi でデバックすると作業がはかどります。

FTPサーバのインストール。

$ sudo apt-get install vsftpd ftp

設定ファイルの設定

$ sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.back
$ sudo rm /etc/vsftpd.conf
$ sudo nano /etc/vsftpd.conf
listen=YES
listen_ipv6=NO
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/private/vsftpd.pem
tcp_wrappers=YES

FTPサーバを再起動します。

$ sudo service vsftpd restart

Raspberry Pi で稼働試験します。

$ ftp localhost
Connected to localhost.
220 (vsFTPd 2.3.5)
Name (localhost:pi): pi
331 Please specify the password.
Password:*******
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> pwd
257 “/home/pi”
ftp> by
221 Goodbye.

3.4.外部IO端子を活用するためのライブラリィ設定

今回利用するセンサは Raspberr Pi の I2C(データ転送方式) の外部端子を使います。

I2C用のライブラリィをインストールします。

$ sudo apt-get install libi2c-dev

Raspberry Pi でGPIOやIC2、SPIなどの外部端子に接続した機器のプログラムを容易に開発するためのライブラリィ Wiring Pi を導入します。

Wiring Pi
http://wiringpi.com/

Gitでソースコードを取得し、以下でコンパイル、インストールします。

$ git clone git://git.drogon.net/wiringPi
$ cd wiringPi
$ ./build
$ cd

インストールが完了したら、以下を実行し表示を確認します。

$ gpio -v
gpio version: 2.20
Copyright (c) 2012-2014 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

Raspberry Pi Details:
Type: Model B, Revision: 2, Memory: 512MB, Maker: Sony

今回、I2Cを利用しますので、モジュールをロードする設定をします。

$ sudo nano /etc/modules
#snd-bcm2835
i2c-dev

モジュールをロードするため、再起動します。

$ sudo reboot

I2Cのデバイスを外部端子と配線し、問題がなければ各センサの番地が表示されます。
照度センサ、LCD液晶、温湿度、CO2の各I2cセンサの番地 29,3c,40,68,69 が確認できます。

$ sudo /usr/sbin/i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: — — — — — — — — — — — — —
10: — — — — — — — — — — — — — — — —
20: — — — — — — — — — 29 — — — — — —
30: — — — — — — — — — — — — 3c — — —
40: 40 — — — — — — — — — — — — — — —
50: — — — — — — — — — — — — — — — —
60: — — — — — — — — 68 69 — — — — — —
70: — — — — — — — —

以上でI2Cセンサのプログラミングができる状態になりました。

続きは 4.センサの設定とプログラミング へ

15.AWS の DynamoDB、S3に保管したデータをEC2のWebサーバで表示

前へ 目次

AWS の DynamoDB に保管したデータを EC2 の Webサーバから表示するPHPプログラム例です。

普段は PHP MVC Framework を使って、Json での Rest full Web API で実装しますが、デモなのでこの辺りのサンプルで。。。

試作システム

</code>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>塩ケンピ試食者一覧</title>
<style type="text/css">

table {
border-collapse:collapse;
border-spacing:0;
background-color:#ffffff;
empty-cells:show;
}

th {
border-right:1px solid #663300;
border-bottom:1px solid #663300;
color:#ffffff;
background-color:#006400;
padding: 5px 4px;
text-align:center;
}

td {
border-right:1px solid #006400;
border-left:1px solid #006400;
border-top:1px solid #006400;
border-bottom:1px solid #006400;
padding:0.1em 0.3em;
}

.tdback {
background-color:#008000;
color:#ffffff;
}

h2 {
position: relative;
color: #ffffff;
background: #008000;
font-size: 16px;
line-height: 1;
margin: 0px 0px 5px 5px;
padding: 5px 5px 5px 10px;
border-radius: 5px 5px 5px 5px;
}

p {
margin:0 0 15px 5px;
}

a {
text-decoration:underline;
}
a:hover {
color: #ffffff;
background: #008000;
text-decoration:underline;
}

</style>

</head>
<body>

<h2>塩ケンピ試食者検索条件</h2>

<?php

ini_set( 'display_errors', 1 );
ini_set('error_reporting', E_ALL);

require_once('/usr/share/pear/AWSSDKforPHP/aws.phar');
use Aws\Common\Aws;
use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\Exception\DynamoDbException;
use Aws\Common\Enum\Region;
use Guzzle\Http\EntityBody;

$aws = Aws::factory("/usr/share/pear/AWSSDKforPHP/Aws/Common/Resources/aws-config.php");

$interval = "-1 hour";
if(isset($_REQUEST['r'])) $interval = $_REQUEST['r']."";

$r = array("","","","","","","","");
switch ($interval) {
case "-1 hour":
$r[0] = " selected";
break;
case "-2 hour":
$r[1] = " selected";
break;
case "-4 hour":
$r[2] = " selected";
break;
case "-6 hour":
$r[3] = " selected";
break;
case "-12 hour":
$r[4] = " selected";
break;
case "-1 day":
$r[5] = " selected";
break;
case "-2 day":
$r[6] = " selected";
break;
}

?>

<form name="frm01" action="splist.php" method="post" >
表示範囲:<select name="r">
<option value="-1 hour"<?php echo $r[0]; ?>>1時間</option>
<option value="-2 hour"<?php echo $r[1]; ?>>2時間</option>
<option value="-4 hour"<?php echo $r[2]; ?>>4時間</option>
<option value="-6 hour"<?php echo $r[3]; ?>>6時間</option>
<option value="-12 hour"<?php echo $r[4]; ?>>12時間</option>
<option value="-1 day"<?php echo $r[5]; ?>>1日</option>
<option value="-2 day"<?php echo $r[6]; ?>>2日</option>
</select>
<input type="submit" value="Do">
</form>

<?php

// Dynamo の処理
$dynamo     = $aws->get('dynamodb');
$dynamoTbl  = "demo-distance";            // TABLE NAME

$now        = new DateTime();
$eymdhims   = $now->format('YmdHis');
$now->modify($interval);
$symdhims   = $now->format('YmdHis');
//echo $symdhims."〜".$eymdhims."<br />\n";

?>

<br /><br />
<h2>塩ケンピ試食者一覧</h2>
<?php

// Image
try{
$iterator = $dynamo->getIterator('Query', array(
'TableName'     => $dynamoTbl,
'KeyConditions' => array(
'HashKey' => array(
'AttributeValueList' => array(
array('S' => 'D001-PIC-DIST')
),
'ComparisonOperator' => 'EQ'
),
'RangeKey' => array(
'AttributeValueList' => array(
array('S' => "".$symdhims),
array('S' => "".$eymdhims)
),
'ComparisonOperator' => 'BETWEEN'
)
),
'ScanIndexForward' => false,
)
);
$count = 1;
foreach ($iterator as $item) {
if($count == 1){
echo "<table>\n";
echo "<tr><th>No.</th><th>日付</th><th>距離</th><th>画像・情報</th>";
echo "<th>HashKey</th><th>RangeKey</th><th>HashKey01</th><th>RangeKey02</th><th>RangeKey03</th></tr>";
}
echo "<tr><td>".$count."</td><td>".$item['datetime']['S']."</td><td>".$item['distance']['S']." ".$item['unit']['S']."</td>";
echo "<td><a href=\"ImageData.php?b=".$item['s3backet']['S']."&k=".$item['s3key']['S']."\" target=\"_blank\">画像</a> ";
echo "<a href=\"DataGet.php?p=".$item['HashKey01']['S']."\" target=\"_blank\">情報</a></td>\n";
echo "<td>".$item['HashKey']['S']."</td><td>".$item['RangeKey']['S']."</td>";
echo "<td>".$item['HashKey01']['S']."</td><td>".$item['RangeKey02']['S']."</td><td>".$item['RangeKey03']['S']."</td></tr>";
$count++;
}
if($count > 1) echo "</table>\n";
if($count < 2) echo "<table><tr><td>該当するデータはありませんでした。</td></tr></table>\n";
} catch (DynamoDbException $exc) {
echo "<table><tr><td>エラーが発生しました : ".$exc->getMessage()."</td></tr></table>\n";
}
?>

<br /><br />
<h2>環境情報(温湿度情報)</h2>
<?php
// Data
try{
$iterator = $dynamo->getIterator('Query', array(
'TableName'     => $dynamoTbl,
'KeyConditions' => array(
'HashKey' => array(
'AttributeValueList' => array(
array('S' => 'D001-AIR-TEMP')
),
'ComparisonOperator' => 'EQ'
),
'RangeKey' => array(
'AttributeValueList' => array(
array('S' => "".$symdhims),
array('S' => "".$eymdhims)
),
'ComparisonOperator' => 'BETWEEN'
)
),
'ScanIndexForward' => false,
)
);
$count = 1;
foreach ($iterator as $item) {
if($count == 1){
echo "<table>\n";
echo "<tr><th>No.</th><th>日付</th><th>温度</th><th>湿度</th><th>情報</th>";
echo "<th>HashKey</th><th>RangeKey</th><th>HashKey01</th><th>RangeKey02</th><th>RangeKey03</th></tr>";
}
echo "<tr><td>".$count."</td><td>".$item['datetime']['S']."</td><td>".$item['air_temp']['S']." ".$item['temp_unit']['S']."</td>";
echo "<td>".$item['air_hum']['S']." ".$item['hum_unit']['S']."</td>";
echo "<td><a href=\"DataGet.php?p=".$item['HashKey01']['S']."\" target=\"_blank\">情報</a></td>\n";
echo "<td>".$item['HashKey']['S']."</td><td>".$item['RangeKey']['S']."</td>";
echo "<td>".$item['HashKey01']['S']."</td><td>".$item['RangeKey02']['S']."</td><td>".$item['RangeKey03']['S']."</td></tr>";
$count++;
}
if($count > 1) echo "</table>\n";
if($count < 2) echo "<table><tr><td>該当するデータはありませんでした。</td></tr></table>\n";
} catch (DynamoDbException $exc) {
echo "<table><tr><td>エラーが発生しました : ".$exc->getMessage()."</td></tr></table>\n";
}
?>

<br /><br />
<h2>環境情報(Raspberry Pi 情報)</h2>
<?php
// Data
try{
$iterator = $dynamo->getIterator('Query', array(
'TableName'        => $dynamoTbl,
'ScanIndexForward' => false,
'KeyConditions'    => array(
'HashKey' => array(
'AttributeValueList' => array(
array('S' => 'D001-CPU-TEMP')
),
'ComparisonOperator' => 'EQ'
),
'RangeKey' => array(
'AttributeValueList' => array(
array('S' => "".$symdhims),
array('S' => "".$eymdhims)
),
'ComparisonOperator' => 'BETWEEN'
)
),
'ScanIndexForward' => false,
)
);
$count = 1;
foreach ($iterator as $item) {
if($count == 1){
echo "<table>\n";
echo "<tr><th>No.</th><th>日付</th><th>CPU温度</th><th>CPU利用率</th><th>メモリ使用率</th><th>情報</th>";
echo "<th>HashKey</th><th>RangeKey</th><th>HashKey01</th><th>RangeKey02</th><th>RangeKey03</th></tr>";
}
echo "<tr><td>".$count."</td><td>".$item['datetime']['S']."</td><td>".$item['cpu_temp']['S']." ".$item['cpu_unit']['S']."</td>";
echo "<td>".$item['cpu_used']['S']." ".$item['cpu_unit2']['S']."</td><td>".$item['mem_used']['S']." ".$item['mem_unit']['S']."</td>";
echo "<td><a href=\"DataGet.php?p=".$item['HashKey01']['S']."\" target=\"_blank\">情報</a></td>\n";
echo "<td>".$item['HashKey']['S']."</td><td>".$item['RangeKey']['S']."</td>";
echo "<td>".$item['HashKey01']['S']."</td><td>".$item['RangeKey02']['S']."</td><td>".$item['RangeKey03']['S']."</td></tr>";
$count++;
}
if($count > 1) echo "</table>\n";
if($count < 2) echo "<table><tr><td>該当するデータはありませんでした。</td></tr></table>\n";
} catch (DynamoDbException $exc) {
echo "<table><tr><td>エラーが発生しました : ".$exc->getMessage()."</td></tr></table>\n";
}
?>
<br /><br />
<h2>定期画像一覧</h2>
<?php

// Image
try{
$iterator = $dynamo->getIterator('Query', array(
'TableName'     => $dynamoTbl,
'KeyConditions' => array(
'HashKey' => array(
'AttributeValueList' => array(
array('S' => 'D001-PIC-PERI')
),
'ComparisonOperator' => 'EQ'
),
'RangeKey' => array(
'AttributeValueList' => array(
array('S' => "".$symdhims),
array('S' => "".$eymdhims)
),
'ComparisonOperator' => 'BETWEEN'
)
),
'ScanIndexForward' => false,
)
);
$count = 1;
foreach ($iterator as $item) {
if($count == 1){
echo "<table>\n";
echo "<tr><th>No.</th><th>日付</th><th>画像・情報</th>";
echo "<th>HashKey</th><th>RangeKey</th><th>HashKey01</th><th>RangeKey02</th><th>RangeKey03</th></tr>";
}
echo "<tr><td>".$count."</td><td>".$item['datetime']['S']."</td>";
echo "<td><a href=\"ImageData.php?b=".$item['s3backet']['S']."&k=".$item['s3key']['S']."\" target=\"_blank\">画像</a> ";
echo "<a href=\"DataGet.php?p=".$item['HashKey01']['S']."\" target=\"_blank\">情報</a></td>\n";
echo "<td>".$item['HashKey']['S']."</td><td>".$item['RangeKey']['S']."</td>";
echo "<td>".$item['HashKey01']['S']."</td><td>".$item['RangeKey02']['S']."</td><td>".$item['RangeKey03']['S']."</td></tr>";
$count++;
}
if($count > 1) echo "</table>\n";
if($count < 2) echo "<table><tr><td>該当するデータはありませんでした。</td></tr></table>\n";
} catch (DynamoDbException $exc) {
echo "<table><tr><td>エラーが発生しました : ".$exc->getMessage()."</td></tr></table>\n";
}
?>
<br /><br />
<a href="#" onClick="window.close(); return false;">閉じる</a>
</body>
</html>
<code>

AWS の S3 に保管したデータを EC2 の Webサーバから表示するPHPプログラム例です。

試作システム

</code>
<html>
<head>
<title>S3の画像</title>
<style type="text/css">

table {
border-collapse:collapse;
border-spacing:0;
background-color:#ffffff;
empty-cells:show;
}

th {
border-right:1px solid #663300;
border-bottom:1px solid #663300;
color:#ffffff;
background-color:#006400;
padding: 5px 4px;
text-align:center;
}

td {
border-right:1px solid #006400;
border-left:1px solid #006400;
border-top:1px solid #006400;
border-bottom:1px solid #006400;
padding:0.1em 0.3em;
}

.tdback {
background-color:#008000;
color:#ffffff;
}

h2 {
position: relative;
color: #ffffff;
background: #008000;
font-size: 16px;
line-height: 1;
margin: 0px 0px 5px 5px;
padding: 5px 5px 5px 10px;
border-radius: 5px 5px 5px 5px;
}

p {
margin:0 0 15px 5px;
}

a {
text-decoration:underline;
}
a:hover {
color: #ffffff;
background: #008000;
text-decoration:underline;
}

</style>

</head>

<body>
<h2>S3の保管画像</h2>
<?php

ini_set( 'display_errors', 1 );
ini_set('error_reporting', E_ALL);

$bucket = "";
if(isset($_REQUEST['b'])) $bucket = $_REQUEST['b']."";
$key = "";
if(isset($_REQUEST['k'])) $key = $_REQUEST['k']."";

?>
<table>
<tr><th>S3保管先画像ファイル => <?php echo $key; ?></th></tr>
<tr><td>
<?php
echo "<image src=\"Image.php?b=".$bucket."&k=".$key."\" />"
?>
</td></tr>
</table>
<br />
<a href="#" onClick="window.close(); return false;">閉じる</a>
</body>
</html>
<code>

 

</code>
<?php

ini_set( 'display_errors', 1 );
ini_set('error_reporting', E_ALL);

require_once('/usr/share/pear/AWSSDKforPHP/aws.phar');

use Aws\Common\Aws;
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
use Aws\Common\Enum\Region;
use Guzzle\Http\EntityBody;

$aws    = Aws::factory("/usr/share/pear/AWSSDKforPHP/Aws/Common/Resources/aws-config.php");
$s3     = $aws->get('s3');
$bucket = "";
if(isset($_REQUEST['b'])) $bucket = $_REQUEST['b']."";

$key = "";
if(isset($_REQUEST['k'])) $key = $_REQUEST['k']."";

if($bucket != "" && $key != ""){
$result = $s3->getObject(array(
'Bucket' => $bucket,
'Key' => $key
));
header("Content-Type: {$result['ContentType']}");
echo $result['Body'];

/*
$length = $result['ContentLength'];
$result['Body']->rewind();
$data = $result['Body']->read($length);
$filename = end(explode('/', $key));

header('Content-Type: application/octet-stream');
$disposition = 'Content-Disposition: attachment; filename="' . $filename . '"';
header($disposition);
$contentlength = 'Content-Length: ' . $length;
header($contentlength);
echo $data;
*/
}else{
header('HTTP/1.0 404 Not Found');
}
?>
<code>

前へ 目次

14.EC2 に AWS PHP SDK 開発環境を構築

前へ 目次 次へ

EC2にAWS PHP SDK で開発環境を構築するのは Raspberry Pi ほとんどと変わりません。

EC2ではpearのインストールでもトラブルは発生しません。

$ sudo yum install php-pear
$ sudo pear config-set auto_discover 1
$ sudo pear channel-discover pear.amazonwebservices.com
$ sudo pear install aws/sdk
$ sudo nano /usr/share/pear/AWSSDKforPHP/Aws/Common/Resources/aws-config.php

 

</code>
return array(
'class' => 'Aws\Common\Aws',
'services' => array(

'default_settings' => array(
'params' => array(
'key' => 'アクセスキー',
'secret' => 'シークレットキー',
'region' => 'ap-northeast-1' // リージョン
)
),
(後略)
<code>


前へ 目次 次へ

13.Web用LinuxサーバをEC2に構築

前へ 目次 次へ

DynamoDB、S3に保管した Raspberry Pi からのデータを公開するWebサーバをEC2に立ち上げます。

EC2(仮想サーバ)に Amazon Linux サーバ環境を構築します。
といっても至って簡単。

コンソール画面からEC2を選びます。

管理コンソール EC2

Lunchi Instance で新しい仮想サーバを構築します。

EC2

Amazon Linux を選びます。

EC2

無償でお試しできる t2.micro を選びます。

EC2

EC2

Webサーバですので、http の 80 番ポートにアクセスできるよう設定します。

EC2 Security

EC2 Security

EC2の仮想サーバにはデータを保管しないので、Disk は最低の5GBで設定します。

EC2 HD Size

サーバの管理コンソールで表示される名前を設定します。

EC2 Name

ssh(暗号化リモート接続し、コマンドライン処理のためのソフト)用の鍵を作成します。
鍵は必ず保管します。(保管し忘れるとアクセスできなくなります。)

EC2 ssh access key

以上のように構築すると良いでしょう。

EC2

EC2

固定グルーバルIPアドレスを取得します。(必要な場合)

EC2 Global Address

EC2 Grobal Address

EC2 Grobal Address

その他は、以下のリンクを参照すると良いでしょう。

AWSのEC2でのウェブサーバーを簡単に構築する方法(株式会社LIG さん)
http://liginc.co.jp/web/programming/server/110507

【AWS】入門 EC2で10分でサーバ作成&ログイン(shade さん)
http://fanblogs.jp/kagayakibito/archive/126/0
EC2でWebサーバの用の環境を設定します。

$ sudo yum update
$ sudo yum upgrade

スワップの設定(推奨)

$ free
             total       used       free     shared    buffers     cached
Mem:       1020044     314672     705372          0      13520     234808
-/+ buffers/cache:      66344     953700
Swap:            0          0          0

$ sudo nano /root/swap.sh
#!/bin/sh
SWAPFILENAME=/swap.img
SIZE=1200000k
fallocate -l $SIZE $SWAPFILENAME && mkswap $SWAPFILENAME && swapon $SWAPFILENAME

$ sudo chown root.root /root/swap.sh
$ sudo chmod 755 /root/swap.sh
$ sudo /root/swap.sh
$ sudo nano /etc/rc.local
/root/swap.sh

$ free
             total       used       free     shared    buffers     cached
Mem:       1020044     355220     664824          0      31984      91440
-/+ buffers/cache:     231796     788248
Swap:      1199996          0    1199996

WebサーバとPHP環境の構築

$ sudo yum install httpd php php-mcrypt

$ sudo nano /etc/php.ini
(変更部分のみ記載)
default_charset = “UTF-8”
date.timezone = Asia/Tokyo

[mbstring]
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.http_input = auto
mbstring.http_output = UTF-8
mbstring.encoding_translation = Off
mbstring.detect_order = UTF-8,SJIS,EUC-JP,JIS,ASCII
mbstring.substitute_character = none

$ sudo service httpd start
$ sudo chkconfig httpd on

FTPでコンテンツを転送する環境を整備(必要な場合のみ)

$ sudo yum install vsftpd ftp

$ sudo cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.back
$ sudo nano /etc/vsftpd/vsftpd.conf
(変更部分のみ記載)
anonymous_enable=NO

ascii_upload_enable=YES
ascii_download_enable=YES

tcp_wrappers=NO

pasv_enable=YES
pasv_addr_resolve=YES
pasv_min_port=60001
pasv_max_port=60099
pasv_address=<グルーバルIP>
use_localtime=YES
force_dot_files=YES

$ sudo adduser <FTPアカウント>
$ sudo passwd <FTPアカウント>

$ sudo service vsftpd start
$ sudo chkconfig vsftpd on
$ ftp localhost
Connected to localhost (127.0.0.1).
220 (vsFTPd 2.2.2)
Name (localhost:ec2-user): <FTPアカウント>
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> by
221 Goodbye.

上記FTP環境に接続できるよう、EC2のセキュリティ設定に以下を追加します。

EC2 Security

EC2 Security

以上で、Webサーバの基本的な設定が完了します。

さらに細かな設定が必要な場合は、Apache、vsftp などのキーワードで検索すると良いでしょう。

前へ 目次 次へ

12.Amazon AWS S3に画像ファイルを保管

前へ 目次 次へ

Raspberry Pi から Amazon AWS S3 に画像ファイル、DynamoDB に保管場所と条件を記録するPHPプログラムを作成します。

先の距離センサプログラム /home/pi/pgm/awsphp/distance で、撮影した画像 /var/www/distance.jpg を S3 にアップし、DynamoDB に距離と保管時間、S3 のパスを記録します。
距離センサプログラムで画像保管後、このプログラムを実行すると一連の作業を自動化できます。

$ nano /home/pi/pgm/awsphp/ImageUp.php

 

</code>
#!/usr/bin/php
<?php
// SDK読込み
require_once('/home/pi/aws/vendor/autoload.php');

use Aws\Common\Aws;
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
use Aws\Sqs\SqsClient;
use Aws\Sqs\Exception\SqsException;
use Aws\Common\Enum\Region;
use Guzzle\Http\EntityBody;

// 距離
$distance = "0";
if(isset($argv[1])) $distance = $argv[1];

// 現在日時取得
$now        = new DateTime();
$datetime   = $now->format('Y/m/d H:i:s');
$y          = $now->format('Y');
$m          = $now->format('m');
$d          = $now->format('d');
$h          = $now->format('H');
$i          = $now->format('i');
$i2         = floor($i / 10) * 10;
$s          = $now->format('s');
$aws        = Aws::factory("/home/pi/aws/vendor/aws/aws-sdk-php/src/Aws/Common/Resources/aws-config.php");

// S3 の処理
$s3         = $aws->get('s3');
$s3backet   = "demo-distance";
$s3dir      = $now->format('Ymd');
$s3file     = "/var/www/distance.jpg";
$s3key      = $s3dir."/".$now->format('Ymd_His').".jpg";

// SQS の処理
$sqserr     = $aws->get('sqs');
$queueURL   = $sqserr->getQueueUrl(array('QueueName' => "test-hub_error"));

// Dynamo の処理
$dynamo     = $aws->get('dynamodb');
$dynamoTbl  = "demo-distance";            // TABLE NAME

$HashKey    = "D001-PIC-DIST";            // Hash Key(データID)
$RangeKey   = $y * 10000000000 + $m * 100000000 + $d * 1000000 + $h * 10000 + $i * 100 + $s;    // Range Key(日時)
$RangeKey01 = $h * 10000000000 + $i * 100000000 + $s * 1000000 + $y * 10000 + $m * 100 + $d;  // Range Key(時日)
$RangeKey02 = $now->format('Ymd_His').".jpg".$RangeKey;                                                                            // Range Key(結果値順)

$HashKey01  = $y * 100000000   + $m * 1000000   + $d * 10000 + $h * 100 + $i2;  // Hash Key(日時)
$RangeKey03 = $HashKey.strval($h * 10000 + $i * 100 + $s);                                         // Range Key(データID+時刻)

// カメラ画像?
if(file_exists($s3file)){

// Dynamo へのデータ保管処理
$data = array();
try{

// S3 の処理
if(!$s3->isValidBucketName($s3backet)){
$s3->createBucket(array( 'Bucket' => $s3backet, 'LocationConstraint' => 'ap-northeast-1' ));
}
$handle = fopen($s3file, "r");
$result = $s3->putObject(array(
'Bucket' => $s3backet,
'Key'    => $s3key,
'Body'   => EntityBody::factory($handle),
'ContentType' => image_type_to_mime_type(exif_imageType($s3file))
));

// Dynamo の処理
// Key
$data['HashKey']    = $HashKey;                           // Hash Key(データID)
$data['RangeKey']   = strval($RangeKey);           // Range Key(日時)
$data['RangeKey01'] = strval($RangeKey01);    // Range Key(時日)
$data['RangeKey02'] = strval($RangeKey02);   // Range Key(結果値順)

$data['HashKey01']  = strval($HashKey01);   // Hash Key(データID)
$data['RangeKey03'] = $RangeKey03;             // Range Key(日時)

// Data
$data['datetime']  = $datetime;
$data['s3backet']  = $s3backet;
$data['s3key']     = $s3key;
$data['localpath'] = $s3file;
$data['distance']  = $distance;
$data['unit']      = "cm";

// Save
$result = $dynamo->putItem(array(
'TableName'              => $dynamoTbl,
'Item'                   => $dynamo->formatAttributes($data),
'ReturnConsumedCapacity' => 'TOTAL'
));

// エラー発生時はSQSに保管
} catch (S3Exception $exc) {
$sqserr->sendMessage( array('QueueUrl' => $queueURL, 'MessageBody' => 'S3 => '.$exc->getMessage()) );
} catch (DynamoDbException $exc2) {
$sqserr->sendMessage( array('QueueUrl' => $queueURL, 'MessageBody' => 'Dynamo => '.$exc2->getMessage()) );
}

// 画像削除
//unlink($s3file);

}else{
$sqserr->sendMessage( array('QueueUrl' => $queueURL, 'MessageBody' => 'No Photography ! ( '.$s3file.' )') );
}
?>
<code>


続いて、以下は定期的に画像を撮影・保管し、そのファイルを S3  にアップし、DynamoDB に保管時間と S3 のパスを記録します。

$ nano /home/pi/pgm/awsphp/ImageUp.php

 

</code>
#!/usr/bin/php
<?php

// SDK読込み
require_once('/home/pi/aws/vendor/autoload.php');

use Aws\Common\Aws;
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
use Aws\Sqs\SqsClient;
use Aws\Sqs\Exception\SqsException;
use Aws\Common\Enum\Region;
use Guzzle\Http\EntityBody;

// 現在日時取得
$now        = new DateTime();
$datetime   = $now->format('Y/m/d H:i:s');
$y          = $now->format('Y');
$m          = $now->format('m');
$d          = $now->format('d');
$h          = $now->format('H');
$i          = $now->format('i');
$i2         = floor($i / 10) * 10;
$s          = $now->format('s');
$aws        = Aws::factory("/home/pi/aws/vendor/aws/aws-sdk-php/src/Aws/Common/Resources/aws-config.php");

// S3 の処理
$s3         = $aws->get('s3');
$s3backet   = "demo-distance";
$s3dir      = $now->format('Ymd');
$s3file     = "/home/pi/data/".$now->format('Ymd_Hi').".jpg";
$s3key      = $s3dir."/".$now->format('Ymd_Hi').".jpg";

// カメラ画像取得
$imagecom = "sudo /opt/vc/bin/raspistill -t 1 -w 640 -h 480 -n -o ".$s3file;
exec($imagecom, $res);

// SQS の処理
$sqserr     = $aws->get('sqs');
$queueURL   = $sqserr->getQueueUrl(array('QueueName' => "test-hub_error"));

// Dynamo の処理
$dynamo     = $aws->get('dynamodb');
$dynamoTbl  = "demo-distance";            // TABLE NAME

$HashKey    = "D001-PIC-PERI";            // Hash Key(データID)
$RangeKey   = $y * 10000000000 + $m * 100000000 + $d * 1000000 + $h * 10000 + $i * 100 + $s;    // Range Key(日時)
$RangeKey01 = $h * 10000000000 + $i * 100000000 + $s * 1000000 + $y * 10000 + $m * 100 + $d;  // Range Key(時日)
$RangeKey02 = $now->format('Ymd_Hi').".jpg".$RangeKey;                                                                              // Range Key(結果値順)

$HashKey01  = $y * 100000000   + $m * 1000000   + $d * 10000 + $h * 100 + $i2;  // Hash Key(日時)
$RangeKey03 = $HashKey.strval($h * 10000 + $i * 100 + $s);                                         // Range Key(データID+時刻)

// カメラ画像?
if(file_exists($s3file)){

// Dynamo へのデータ保管処理
$data = array();
try{

// S3 の処理
if(!$s3->isValidBucketName($s3backet)){
$s3->createBucket(array( 'Bucket' => $s3backet, 'LocationConstraint' => 'ap-northeast-1' ));
}
$handle = fopen($s3file, "r");
$result = $s3->putObject(array(
'Bucket' => $s3backet,
'Key'    => $s3key,
'Body'   => EntityBody::factory($handle),
'ContentType' => image_type_to_mime_type(exif_imageType($s3file))
));

// Dynamo の処理
// Key
$data['HashKey']    = $HashKey;                         // Hash Key(データID)
$data['RangeKey']   = strval($RangeKey);         // Range Key(日時)
$data['RangeKey01'] = strval($RangeKey01);  // Range Key(時日)
$data['RangeKey02'] = strval($RangeKey02);  // Range Key(結果値順)

$data['HashKey01']  = strval($HashKey01);     // Hash Key(データID)
$data['RangeKey03'] = $RangeKey03;               // Range Key(日時)

// Data
$data['datetime']  = $datetime;
$data['s3backet']  = $s3backet;
$data['s3key']     = $s3key;
$data['localpath'] = $s3file;
$data['command']   = $imagecom;

// Save
$result = $dynamo->putItem(array(
'TableName'              => $dynamoTbl,
'Item'                   => $dynamo->formatAttributes($data),
'ReturnConsumedCapacity' => 'TOTAL'
));

// エラー発生時はSQSに保管
} catch (S3Exception $exc) {
$sqserr->sendMessage( array('QueueUrl' => $queueURL, 'MessageBody' => 'S3 => '.$exc->getMessage()) );
} catch (DynamoDbException $exc2) {
$sqserr->sendMessage( array('QueueUrl' => $queueURL, 'MessageBody' => 'Dynamo => '.$exc2->getMessage()) );
}

// 画像削除
unlink($s3file);

}else{
$sqserr->sendMessage( array('QueueUrl' => $queueURL, 'MessageBody' => 'No Photography ! ( '.$s3file.' )') );
}
?>
<code>


前へ 目次 次へ

11.Amazon AWS DynamoDB にセンサの計測値を記録

前へ 目次 次へ

Raspberry Pi から Amazon AWS DynamoDB にセンサの計測値を記録するPHPプログラムを作成します。

今回はセンサの値にプラスして、Raspberry Pi 機器の稼働環境情報も一緒に記録します。

CPUの使用率を計算するシェルプログラムを作成します。

$ nano /home/pi/pgm/awsphp/cpu.sh

</code>
#!/bin/bash
CUR=/proc/stat
USER=$(whoami)
PRE=/tmp/${USER}-prestat
if [ ! -f $PRE ]; then
  head -1 $CUR > $PRE
  exit 1
fi
awk '
  /cpu /{
        if (match(FILENAME,"prestat")) {
                pretotal = $2+$3+$4+$5; preidle = $5;
        } else {
                ctotal = $2+$3+$4+$5; cidle = $5;
        }
  }
  END {
        dtotal = ctotal - pretotal
        didle = cidle - preidle
        printf("%d",(((dtotal - didle) * 100) / dtotal),37)
  }
' $PRE $CUR
head -1 $CUR > $PRE
<code>


データを DynamoDB にアップするPHPプログラムを作成します。

$ nano /home/pi/pgm/awsphp/DataUp.php

</code>
#!/usr/bin/php
<?php

// SDK読込み
require_once('/home/pi/aws/vendor/autoload.php');
use Aws\Common\Aws;
use Aws\Sqs\SqsClient;
use Aws\Sqs\Exception\SqsException;
use Aws\Common\Enum\Region;
use Guzzle\Http\EntityBody;

// 現在日時取得
$now        = new DateTime();
$datetime   = $now->format('Y/m/d H:i:s');
$y          = $now->format('Y');
$m          = $now->format('m');
$d          = $now->format('d');
$h          = $now->format('H');
$i          = $now->format('i');
$i2         = floor($i / 10) * 10;
$s          = $now->format('s');
$aws        = Aws::factory("/home/pi/aws/vendor/aws/aws-sdk-php/src/Aws/Common/Resources/aws-config.php");

// データ取得
$cputemp   = "999";        // CPU温度
$cputempky = "99999";
$com = "cat /sys/class/thermal/thermal_zone0/temp";
exec($com, $res1);
if(isset($res1[0])){
    $cputempky = trim($res1[0]);
    $cputemp = intval($cputempky) / 1000;
}

$cpuused = "0";        // CPU使用率
$com = "/home/pi/pgm/awsphp/cpu.sh";
exec($com, $res2);
if(isset($res2[0])) $cpuused = $res2[0];

$memused = "0";        // メモリ使用率
$com = "cat /proc/meminfo | awk '/MemTotal/ {printf($2)}'";
exec($com, $res3);
$com = "cat /proc/meminfo | awk '/MemFree/ {printf($2)}'";
exec($com, $res4);
if(isset($res3[0]) && isset($res4[0])) $memused = round((($res3[0] - $res4[0]) / $res3[0] * 100), 1);

$airtemp = "999";        // 温湿度
$airhum  = "999";
$res5    = array();
$com = "sudo /home/pi/pgm/awsphp/temp_hum2";
exec($com, $res5);
if(isset($res5[1])) $airhum  = trim($res5[1]);
if(isset($res5[3])) $airtemp = trim($res5[3]);

// SQS の処理
$sqserr     = $aws->get('sqs');
$queueURL   = $sqserr->getQueueUrl(array('QueueName' => "test-hub_error"));

// Dynamo の処理
$dynamo     = $aws->get('dynamodb');
$dynamoTbl  = "demo-distance";            // TABLE NAME

$HashKey    = "D001-CPU-TEMP";            // Hash Key(データID)
$RangeKey   = $y * 10000000000 + $m * 100000000 + $d * 1000000 + $h * 10000 + $i * 100 + $s;    // Range Key(日時)
$RangeKey01 = $h * 10000000000 + $i * 100000000 + $s * 1000000 + $y * 10000 + $m * 100 + $d;    // Range Key(時日)
$RangeKey02 = $cputempky.$RangeKey;                                                                // Range Key(結果値順)

$HashKey01  = $y * 100000000   + $m * 1000000   + $d * 10000 + $h * 100 + $i2;                    // Hash Key(日時)
$RangeKey03 = $HashKey.strval($h * 10000 + $i * 100 + $s);                                        // Range Key(データID+時刻)

// Dynamo へのデータ保管処理
$data = array();
try{
    
    // Key
    $data['HashKey']    = $HashKey;            // Hash Key(データID)
    $data['RangeKey']   = strval($RangeKey);   // Range Key(日時)
    $data['RangeKey01'] = strval($RangeKey01); // Range Key(時日)
    $data['RangeKey02'] = strval($RangeKey02); // Range Key(結果値順)
    
    $data['HashKey01']  = strval($HashKey01);  // Hash Key(データID)
    $data['RangeKey03'] = $RangeKey03;         // Range Key(日時)
    
    // Data
    $data['datetime']  = $datetime;
    $data['cpu_temp']  = "".$cputemp;
    $data['cpu_unit']  = "*C";
    $data['cpu_used']  = "".$cpuused;
    $data['cpu_unit2'] = "%";
    $data['mem_used']  = "".$memused;
    $data['mem_unit']  = "%";
    
    // Save
    $result = $dynamo->putItem(array(
        'TableName'              => $dynamoTbl,
        'Item'                   => $dynamo->formatAttributes($data),
        'ReturnConsumedCapacity' => 'TOTAL'
    ));
    
    if($airtemp != "999" || $airhum != "999"){
        $data = array();
        
        // Key
        $data['HashKey']    = "D001-AIR-TEMP";     // Hash Key(データID)
        $data['RangeKey']   = strval($RangeKey);   // Range Key(日時)
        $data['RangeKey01'] = strval($RangeKey01); // Range Key(時日)
        $data['RangeKey02'] = $airtemp.$RangeKey;  // Range Key(結果値順)
        
        $data['HashKey01']  = strval($HashKey01);                                  // Hash Key(データID)
        $data['RangeKey03'] = $data['HashKey'].strval($h * 10000 + $i * 100 + $s); // Range Key(日時)
        
        // Data
        $data['datetime']   = $datetime;
        $data['air_temp']   = "".$airtemp;
        $data['temp_unit']  = "*C";
        $data['air_hum']    = "".$airhum;
        $data['hum_unit']   = "%";
        
        // Save
        $result = $dynamo->putItem(array(
            'TableName'              => $dynamoTbl,
            'Item'                   => $dynamo->formatAttributes($data),
            'ReturnConsumedCapacity' => 'TOTAL'
        ));
    
    }
    
// エラー発生時はSQSに保管
} catch (DynamoDbException $exc2) {
    $sqserr->sendMessage( array('QueueUrl' => $queueURL, 'MessageBody' => 'Dynamo => '.$exc2->getMessage()) );
}
?>
<code>


後は cron で実行するだけです。

前へ 目次 次へ

10.Raspberr Pi に AWS PHP SDK 環境の構築

前へ 目次 次へ

Raspberr Pi に戻り、AWS PHP SDK を利用する環境を構築します。

$ sudo apt-get install php-pear php5-curl

curlを利用した環境構築

$ mkdir /home/pi/aws
$ cd /home/pi/aws
$ curl -sS https://getcomposer.org/installer | php
$ nano /home/pi/aws/composer.json
{
  “require”: {
    “aws/aws-sdk-php”: “2.*”
  }
}

$ php composer.phar install
$ sudo nano /home/pi/aws/vendor/aws/aws-sdk-php/src/Aws/Common/Resources/aws-config.php

return array(
    'class' => 'Aws\Common\Aws',
    'services' => array(

        'default_settings' => array(
            'params' => array(
                'key' => 'アクセスキー',
                'secret' => 'シークレットキー',
                'region' => 'ap-northeast-1' // リージョン(日本)
            )
        ),
(後略)

pear を利用した場合の環境構築です。
RaspberryPiではNGでした

(EC2では問題なしです。)

$ sudo pear config-set auto_discover 1
$ sudo pear channel-discover pear.amazonwebservices.com
$ sudo pear -D auto_discover=1 install pear.amazonwebservices.com/sdk-2.6.16
$ sudo nano /usr/share/php/AWSSDKforPHP/Aws/Common/Resources/aws-config.php

return array(
    'class' => 'Aws\Common\Aws',
    'services' => array(

        'default_settings' => array(
            'params' => array(
                'key' => 'アクセスキー',
                'secret' => 'シークレットキー',
                'region' => 'ap-northeast-1' // リージョン(日本)
            )
        ),
(後略)

一連の設定の流れは、以下などの情報を参考にされると良いでしょう。

AWS SDK for PHPでAmazon S3 にファイルをアップロードする(cloudpackエバンジェリストの吉田真吾さん)
http://yoshidashingo.hatenablog.com/entry/2014/08/31/170333

上記設定はデモなので簡易に対応していますが、別途 セキュリティ対策 をしっかりされる事をお勧めします。

以下のSTS対応まで実装できると良いのですが、今回は時間が。。。(汗)
http://docs.aws.amazon.com/STS/latest/UsingSTS/STSUseCases.html

前へ 目次 次へ