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>

前へ 目次

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 で実行するだけです。

前へ 目次 次へ

8.DynamoDB (Key-Valueストア型DB)環境の構築

前へ 目次 次へ

データや、画像ファイル保管先情報を保管する DynamoDB (Key-Valueストア型DB)を構築します。

管理コンソール画面 DynamoDB

DynamoDB の画面で Create Table を実行します。

DynamoDB Create Table

一度設定した設定項目はレスポンス以外はほぼ変更できません。
DB設計は事前に、確実に行っておいてください。

以降、DynamoDBの詳細など不明な点は以下の資料をご参照ください。

Amazon DynamoDB ドキュメント(難しい)
http://aws.amazon.com/jp/documentation/dynamodb/

Developer Guide(日本語、英語)
http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Introduction.html
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html
日本語は更新が遅いので注意。

JAWS-UG大阪のしみずさん資料(分かりやすい)
http://www.slideshare.net/shimy_net/amazon-dynamodb-23315068

[AWSマイスターシリーズ] Amazon DynamoDB(分かりやすい)
http://www.slideshare.net/AmazonWebServicesJapan/aws-amazon-dynamodb

最初の画面でテーブル名とプライマリーキーを設定します。

DynamoDB Create Table

続いて、インデックスを作成します。

DynamoDB Create Table

RDBのインデックスとは違う事が多く、事前にドキュメントで意味を理解したうえで設定してください。
ローカル、クローバルインデックスの違いも理解しておいてください。
(今回時間がないので説明省略します)

今回は以下のように設定してみました。

DynamoDB Create Table

グローバルインデックスは、プライマリーキーのハッシュキーとレンジキーを逆にした索引用設定に便利です。

こちらでプロビジョンを設定します

DynamoDB Create Table

プロビジョンとは大まかに言うと、4KBまでのデータの1秒辺りの読込み、及び書き込み可能処理数です。

テーブルと、クローバルインデックスに割り当てます。
合計した設定が、読み込みで10、書き込みで5を超えると有償になりますので注意してください。

過去、本当にこの数値かあてになるかどうか試験した事がありますが、超えると確かにエラーで返ってきます。
対策としては、負荷を監視して自動で上げるか、特に書き込みの場合はエラーをSQSなどに退避し再処理する必要があります。

詳細はこちら
http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/ProvisionedThroughputIntro.html

必要な場合は、スループットのアラームを設定します。

DynamoDB Create Table

最後にCreateでしばらく(早ければ2分程度?)待つとテーブルが構築されています。

DynamoDB

前へ 目次 次へ