JAWS-Festa 2015登壇資料 URL の訂正

JAWS Festa 2015 「Raspberry Pi と AWS でIoT」資料ダウンロード先の訂正

http://jft2015.jaws-ug.jp/speaker/yukihito-kataoka/
JAWS Festa 2015 IoTトラック 「Raspberry Pi と AWS でIoT」資料ダウンロード先のURLが間違っていました。
誠に申し訳けございません。

お詫びと同時に、以下URLに訂正させて頂きます。
http://goo.gl/forms/41oaevDrAA

広告

6.S3静的htmlのJavaScriptでグラフ表示

jPlot

s3の静的サイトにグラフを表示するJavaSciptプログラムを含んだhtmlをアップします。

S3に保管したJSONのデータは、S3の静的サイト内からAJAXで利用できます。
上の画像は html 内の javascript プログラムで以下の処理を行って表示しています。
・JSONの1日のセンサ生データGET
・1分毎のJSONデータを1時間平均に計算
・グラフで表示

グラフには jqPlot を利用しています。

jqPlot
http://www.jqplot.com/

実際のhtml5内の javascript プログラムは以下で確認できます。
https://github.com/yukataoka/IoT_Raspi_AWS_Demo/tree/master/S3WebSite

実際にRaspberry Pi から AWS S3 にアップされたJSONデータのサンプルは以下で確認できます。
https://github.com/yukataoka/IoT_Raspi_AWS_Demo/tree/master/S3WebSite/Hub01

実際の動きは、以下のサイトで確認できます。
http://s.ykata.net/

こちらのjavascriptプログラムの詳細は上記サイトをご参照ください。

最初のページに 戻る

5.センサ値をクラウドに保管・表示

5.1.node.js の設定

参考情報

m_shige1979のささやかな抵抗と欲望の日々(id:m_shige1979さん )
http://m-shige1979.hatenablog.com/entry/2014/06/17/211645

以下の手順で、開発言語 node.js (Javascript) と、Amazon AWS にデータをアップするためのモジュールを設定します。

$ wget http://node-arm.herokuapp.com/node_latest_armhf.deb
$ sudo dpkg -i node_latest_armhf.deb
$ npm install aws-sdk
aws-sdk@2.1.34 node_modules/aws-sdk
├── xml2js@0.2.8
├── sax@0.5.3
└── xmlbuilder@0.4.2

$ npm install sax@0.5.8
$ npm install xml2js@0.2.8
$ npm install xmlbuilder@0.4.2
$ npm install sax@0.5.3

$ npm install aws-sdk

5.2.AWSコンソールの設定

AWSのコンソールにログインします。
今回は
Cognito => アクセスID認証
Identity and Access Management => アクセスIDの利用権限設定
S3 => 静的Webサイト sensor.ykata.net で公開する設定例
を利用します。

Cognito は現時点で日本のリージョンでは使えません。(夏頃 東京リージョン でも使えるらしいです。)
「バージニア北部」を選択します。
AWS-01

詳細はそれぞれ以下で確認してください。
http://aws.amazon.com/jp/cognito/
http://aws.amazon.com/jp/iam/
http://aws.amazon.com/jp/s3/

先ず Cognito を設定します。
Create new identity pool を行います。
AWS-02

以下 identity pool name が SensorHUB2 の例です。
Create Pool します。
AWS-03


以下自動作成してくれた権限設定はそのままで、許可 します。
Unauthのロール名は設定で使いますので控えておきます。
AWS-04

この画面に来ると設定は完了です。
Get AWS Credentials の赤字部分は設定で使いますので控えておきます。
Go to Dashboad します。

AWS-05

ダッシュボード画面が表示され、以上でCognitoの設定完了です。
AWS-06

Identity and Access Management (IAM)で、先に設定した Cognito で発行される アクセスID の利用権限を設定します。
ロールを選択します。
AWS-07

Cognito の Unauthのロール名 を選択します。
AWS-08

S3をデータ保管先として利用しますので、ポリシーのアタッチ を行います。
AWS-09

Amazon S3 Full Access を選択し、 ポリシーのアタッチ を行います。
AWS-10

以上で IAM の設定は完了しました。
AWS-11

S3にデータを保管する バケット を作成します。
このバケットは JSON でデータを保管するとともに、グラフなどで情報を閲覧するWebサイトとして利用する設定も行います。
AWS-12

バケット名を公開するドメインと同じにすると、公開Webとしても使えます。
リージョンは Cognito と同じになるよう注意して、作成 してください。
AWS-13

バケットができたら、公開Webとして使うための バケットポリシーを追加 します。
AWS-14

ポリシーエディタが起動します。
最初から作成するのは難しいので、AWS Policy Generator を利用します。
AWS-15

以下の例のように入力します。
AWS-16

ARNは arn:aws:s3:::バケット名/* を入力します。
今回の例では arn:aws:s3:::sensor.ykata.net/* となります。
Add Statement します。
AWS-17

以下のように追加されたら、Generate Policy します。
AWS-18

以上、完成したポリシーをコピーして、ページを閉じます。
AWS-19

最初の画面で、ペースト し、保存 します。
AWS-20

保存 して、静的ウエッブサイトホスティング の設定をします。
AWS-21

ウエッブサイトホスティングを有効にします。
インデックスドキュメントを index.html に設定して 保存 します。
AWS-22

以上で設定は完了しました。

S3のバケット内で右クリックすると、アップロードというメニューがあります。
そちらを開いて、htmlなどのファイルをアップすると、Webとして利用できます。

5.3.CognitoによるアクセスIDの発行

Cognitoで実際に アクセスID が node.js のプログラムで発行されるか、確認してみます。
https://github.com/yukataoka/IoT_Raspi_AWS_Demo/blob/master/cognito.js

$ nano cognito.js
var AWS = require(‘aws-sdk’);
var awsRegion = “us-east-1”;
var cognitoParams = {
AccountId: “AWSのアカウントID”,
RoleArn: “arn:aws:iam::AWSのアカウントID:role/Cognito_SensorHUBUnauth_Role”,
IdentityPoolId: “us-east-1:AWSのIdentityPoolId”
};

AWS.config.region = awsRegion;
AWS.config.credentials = new AWS.CognitoIdentityCredentials(cognitoParams);
AWS.config.credentials.get(function(err) {
if (!err) {
console.log(“Cognito Identity Id: ” + AWS.config.credentials.identityId);
}
});

実行してみると、実際にIdを獲得している様子が分かります。

$ node cognito.js
Cognito Identity Id: us-east-1:7a465491-dc91-44e7-9d8c-f08dd674c532

5.4.センサ値をS3へ発行

実際にCognitoで発行、取得したIdにS3にアクセスし、データを保管します。

先ずは、センサ値をCSV形式で出力しLCDに表示する Python プログラムを作成します。
ブロッグではインデントが表示されないので、動くコードは以下を参照してください。
https://github.com/yukataoka/IoT_Raspi_AWS_Demo/blob/master/getSensor.py

$ nano getSensor.py
#!/usr/bin/python
import time
import wiringpi2
import os
import sys
import struct
import subprocess
from time import sleep
from notsmb import notSMB
#from TSL2561 import TSL2561
from tsl2561_lux import Luxmeter

tmpVal = -999
humVal = -999
co2Val = -999
luxVal = -999

“”” LUX Setting “””
##tsl = TSL2561()
tsl=Luxmeter()

i = 0
while True:
try:
# luxVal = int(tsl.readLux())
luxVal = int(tsl.getLux())
if luxVal <= 200000 and luxVal > 100:
break
i = i + 1
if i > 5:
break
sleep(0.5)
except:
blank =0;
sleep(0.5)

“”” CO2 Setting “””
I2CBUS = 1
CO2_ADDR = 0x68
READ = 0x22
readBytes = [0x00, 0x08, 0x2A]
bus = notSMB(I2CBUS)

i = 0
while True:
try:
resp = bus.i2c(CO2_ADDR,[0x22,0x00,0x08,0x2A],4)
time.sleep(0.1)
co2Val = (resp[1]*256) + resp[2]

if co2Val < 8000:
break

i = i + 1
if i > 5:
break
except:
blank =0;
sleep(0.5)

“”” Temperature Humidity Setting “””
wiringpi2.wiringPiSetup()
i2c = wiringpi2.I2C()
dev = i2c.setup(0x40)

i2c.writeReg16(dev,0x02,0x10)
i2c.writeReg8(dev,0x00,0x00)
sleep((6350.0 + 6500.0 + 500.0)/1000000.0)
tmpVal = ((struct.unpack(‘4B’, os.read(dev,4)))[0] << 8 | (struct.unpack(‘4B’, os.read(dev,4)))[1])
humVal = ((struct.unpack(‘4B’, os.read(dev,4)))[2] << 8 | (struct.unpack(‘4B’, os.read(dev,4)))[3])
os.close(dev)
tmpVal = round(((tmpVal / 65535.0) * 165 – 40), 1)
humVal = round(((humVal / 65535.0) * 100), 1)

sleep(0.5)

line = time.strftime(‘%Y/%m/%d,’) + time.strftime(‘%H:%M:%S,’)
line = line + str(tmpVal) + “,” + str(humVal) + “,” + str(co2Val) + “,” + str(luxVal)
print line

parm1 = time.strftime(‘%m/%d_%H:%M’)
parm2 = “T:” + str(tmpVal) + “*c_H:” + str(humVal) + “%”
parm3 = “CO2:” + str(co2Val) + “ppm”
parm4 = “Lig:” + str(luxVal) + “LUX”
cmd = “/var/www/bin/oled %s %s %s %s” % (parm1, parm2, parm3, parm4)
subprocess.Popen( cmd.strip().split(” “) )

この python プログラムで得たセンサの計測値を AWS の S3 にJSONで保管する node.js のプログラムを作成します。
https://github.com/yukataoka/IoT_Raspi_AWS_Demo/blob/master/sensor.js

$ nano  sensor.js
var execSync = require(‘child_process’).execSync;
var id = “Hub01”;

var AWS = require(‘aws-sdk’);
var awsRegion = “us-east-1”;

// 1タイムアクセスID作成
var cognitoParams = {
AccountId: “AWSのアカウントID”,
RoleArn: “arn:aws:iam::AWSのアカウントID:role/Cognito_SensorHUBUnauth_Role”,
IdentityPoolId: “us-east-1:AWSのIdentityPoolId”
};
AWS.config.region = awsRegion;
AWS.config.credentials = new AWS.CognitoIdentityCredentials(cognitoParams);
AWS.config.credentials.get(function(err) {
if (!err) {
// console.log(“Cognito Identity Id: ” + AWS.config.credentials.identityId);
}
});

// S3
var s3 = new AWS.S3();
var bucket = ‘s.ykata.net’;
// センサ値取得
var result = “” + execSync(‘sudo /pi/home/getSensor.py’);

// 現在値をJSONでS3にアップ
var vRes = result.replace(/[\n\r]/g,””).split(“,”);
var vKeyN = id + “/now.json”;
var vKeyF = vRes[0].replace(/\//g,”_”);
var vKeyD = id + “/” + vKeyF + “.json”;
var vJson = ‘{“Date”:”‘+vRes[0]+'”,”Time”:”‘+vRes[1]+'”,”Temperature”:’+vRes[2]+’,’;
vJson = vJson + ‘”Humidity”:’+vRes[3]+’,”CO2″:’+vRes[4]+’,”Illuminance”:’+vRes[5]+’}’;
var params1 = {
Bucket: bucket,
Key: vKeyN,
ContentType: ‘application/json’,
Body: vJson
};
s3.upload(params1, function(err) {
if(err) {
console.log(“Error uploading data 01 : “, err);
}
});

// 1日のデータをファイルに保管し、JSONでS3にアップ
var fs = require(‘fs’);
var path = ‘./’+vKeyF;
var fsData = “”;
var fsUPData = “”;
try {
fs.statSync(path);
fsData = fs.readFileSync(path, ‘utf8’);
fsUPData = fsData + “,” + vJson;
} catch (e) {
execSync(‘echo “” >> ‘ + path);
execSync(‘chmod 666 ‘ + path);
fsUPData = vJson;
}
fs.writeFileSync(path, fsUPData,’utf8′);
var params2 = {
Bucket: bucket,
Key: vKeyD,
ContentType: ‘application/json’,
Body: ‘[‘ + fsUPData + ‘]’
};
s3.upload(params2, function(err) {
if(err) {
console.log(“Error uploading data 02 : “, err);
}
});

このプログラムを cron に登録すると、毎分のデータをJSONで AWS S3 にアップするようになります。
cron の記載はフルパスで記載します。

$ crontab -e
* * * * *  /usr/local/bin/node /home/pi/sensor.js 2>> /home/pi/cron.log

続きは 6.S3静的htmlのJavaScriptでグラフ表示 へ

 

4.センサの設定とプログラミング

20150617_231446
実際の配線の様子ですが、配線の色を揃えれなくて見苦しい所はご容赦を。

以下、ブロッグの構造上Pythonのプログラムの前スペースが消えてます。
そのままでは動きませ。参照サイトからダウンロードのうえ、お試しください。

4.1.今回準備したもの

温湿度センサ HDC1000(秋月電子)
http://akizukidenshi.com/catalog/g/gM-08775/

CO2センサ K30 (co2meter)
http://www.co2meter.com/products/k-30-co2-sensor-module

Grove OLED Display (スイッチサイエンス)
https://www.switch-science.com/catalog/829/

光センサ TSL2561 (スイッチサイエンス)
https://www.switch-science.com/catalog/1174/

Raspberry Pi2 B+
http://jp.rs-online.com/web/p/processor-microcontroller-development-kits/8326274/

Raspberry Pi2 B+ ケース
http://jp.rs-online.com/web/p/development-board-enclosures/8787594/

その他
2000mA 5V 1ポート 2A高出力 USB AC アダプタ USB(Amazon)
USB電源ケーブル(ダイソー 100均)
屋内・屋外兼用ケース P10-22CA (Amazon)
小さいブレットボード(白)(秋月電子)
LTE通信USBモデムカード docomo L-03D (Amazon)
Transcend microSDHCカード 16GB Class10(Amazon)
普通のジャンパワイヤ(オス~オス)(スイッチサイエンス)
普通のジャンパワイヤ(オス~メス)(スイッチサイエンス)
普通のジャンパワイヤ(メス~メス)(スイッチサイエンス)

開発言語は、可能な限り C,C++ の入門者に敷居が高い言語を使わず、Python、node.js(Java Script) を用いる方針です。

4.2.センサ値獲得用プログラム言語Python環境確認

センサ値取得に利用する開発言語 Python のバージョンを確認します。
最新の3にはまだ未対応のライブラリィなどが多く、2.7 を用います。

$ python -V
Python 2.7.3

Pythonのセンサ用開発環境を追加インストールします。

$ sudo apt-get install python-dev

4.3.CO2センサ K30 I2Cプログラム計測

参考情報

K-30 10,000ppm CO2 Sensor
http://www.co2meter.com/products/k-30-co2-sensor-module

メーカPDF資料
http://co2meters.com/Documentation/AppNotes/AN142-RaspberryPi-K_series.pdf

説明は難しくなるので、以下の手順をこなしてみてください。

$ mkdir notsmb
$ cd notsmb
$ wget http://www.byvac.com/downloads/sws/notsmb_1_3.zip
$ unzip notsmb_1_3.zip
$ sudo python setup.py install

以下インデントが表示されていません。
実際に解答したファイルの内容をご参照ください。

$ nano CO2meter.py
import time
from notsmb import notSMB
I2CBUS = 1
CO2_ADDR = 0x68
READ = 0x22
readBytes = [0x00, 0x08, 0x2A]
bus = notSMB(I2CBUS)
while True:
try:
resp = bus.i2c(CO2_ADDR,[0x22,0x00,0x08,0x2A],4)
time.sleep(0.1)
co2Val = (resp[1]*256) + resp[2]
print(resp)
print(co2Val);
break
except:
blank =0;

$ sudo python ./CO2meter.py
[33, 11, 116, 160]
2932

4.3.温湿度センサHDC1000 I2C プログラム計測

参考情報

秋月電子 HDC100使用 温湿度センサーモジュール
http://akizukidenshi.com/catalog/g/gM-08775/

RaspberryPi + wiringPi-Python + HDC1000 で温湿度を取る(femmnomenaさん)
http://d.hatena.ne.jp/femm/20150426/1430033839

説明は難しくなるので、以下の手順をこなしてみてください。

$ sudo apt-get install python-pip
$ sudo pip install wiringpi2

$ nano HDC1000.py
import wiringpi2
import os
import struct
from time import sleep

wiringpi2.wiringPiSetup()
i2c = wiringpi2.I2C()
dev = i2c.setup(0x40)
i2c.writeReg16(dev,0x02,0x10)
i2c.writeReg8(dev,0x00,0x00) #start conversion.
sleep((6350.0 + 6500.0 + 500.0)/1000000.0)

temp = ((struct.unpack(‘4B’, os.read(dev,4)))[0] << 8 | (struct.unpack(‘4B’, os.read(dev,4)))[1])
hudi = ((struct.unpack(‘4B’, os.read(dev,4)))[2] << 8 | (struct.unpack(‘4B’, os.read(dev,4)))[3])
os.close(dev)

print “Humidity %.2f” % (( hudi / 65535.0 ) * 100)
print “Temperature %.2f” % (( temp / 65535.0) * 165 – 40 )

$ sudo python ./HDC1000.py
Temperature 28.0
Humidity 74.3

4.4.OLED ディスプレイ 128×64 表示プログラム

参考情報

GROVE – I2C OLEDディスプレイ128×64
https://www.switch-science.com/catalog/829/

Seeed-Studio/Grove-RaspberryPi
https://github.com/Seeed-Studio/Grove-RaspberryPi/tree/master/Grove%20-%20OLED%20Display%20128×64

こちらだけC++でコンパイルします。
説明は難しくなるので、以下の手順をこなしてみてください。

$ git clone https://github.com/Seeed-Studio/Grove-RaspberryPi
$ cd “Grove-RaspberryPi\Grove – OLED Display 128×64”
$ nano main.cpp
#include <sstream>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include “SeeedOLED.h”

using namespace std;

SeeedOLED oled = SeeedOLED(0x3c);

string GetStdoutFromCommand(string cmd) {
int len;
string data;
FILE * stream;
const int max_buffer = 256;
char buffer[max_buffer];
cmd.append(” 2>&1″);

stream = popen(cmd.c_str(), “r”);
if (stream) {
while (!feof(stream)) {
if (fgets(buffer, max_buffer, stream) != NULL) {
data.append(buffer);
}
}
pclose(stream);
}
len = data.size() – 1;
data = data.substr(0, len);
return data;
}

int main (int argc, char *argv[])
{

string line0 = ” “;

string argv1 = line0;
string argv2 = line0;
string argv3 = line0;
string argv4 = line0;
if(argc > 1) argv1 = argv[1];
if(argc > 2) argv2 = argv[2];
if(argc > 3) argv3 = argv[3];
if(argc > 4) argv4 = argv[4];

oled.writeString(0, 0, (char*)line0.c_str());
oled.writeString(1, 0, (char*)line0.c_str());
oled.writeString(2, 0, (char*)line0.c_str());
oled.writeString(3, 0, (char*)line0.c_str());

oled.writeString(0, 0, (char*)argv1.c_str());
oled.writeString(1, 0, (char*)argv2.c_str());
oled.writeString(2, 0, (char*)argv3.c_str());
oled.writeString(3, 0, (char*)argv4.c_str());
return 0;
}

$ make clean
$ make
$ OLED 1111 2222 3333 4444

4.5.照度センサ TSL2561 I2C プログラム計測

参考情報

GROVE – I2C デジタル光センサ
https://www.switch-science.com/catalog/1174/

seanbechhofer/raspberrypi
https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/tree/master/Adafruit_I2C
https://github.com/seanbechhofer/raspberrypi/blob/master/python/TSL2561.py

説明は難しくなるので、以下の手順をこなしてみてください。

$ git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code
$ git clone https://github.com/seanbechhofer/raspberrypi

以下、インデントが分からないので以下を参照してください。
https://github.com/yukataoka/IoT_Raspi_AWS_Demo/blob/master/TSL2561.py

$ nano TSL2561.py
#!/usr/bin/python

import sys
import time
from Adafruit_I2C import Adafruit_I2C

class TSL2561:
i2c = None

def __init__(self, address=0x29, debug=0, pause=0.8):
self.i2c = Adafruit_I2C(address)
self.address = address
self.pause = pause
self.debug = debug
self.gain = 0 # no gain preselected
self.i2c.write8(0x80, 0x03) # enable the device

def setGain(self,gain=1):
“”” Set the gain “””
if (gain != self.gain):
if (gain==1):
self.i2c.write8(0x81, 0x02) # set gain = 1X and timing = 402 mSec
else:
self.i2c.write8(0x81, 0x12) # set gain = 16X and timing = 402 mSec
self.gain=gain; # safe gain for calculation
time.sleep(self.pause) # pause for integration (self.pause must be bigger than integration time)
def readWord(self, reg):

“””Reads a word from the I2C device”””
try:
wordval = self.i2c.readU16(reg)
newval = self.i2c.reverseByteOrder(wordval)
if (self.debug):
print(“I2C: Device 0x%02X returned 0x%04X from reg 0x%02X” % (self.address, wordval & 0xFFFF, reg))
return newval
except IOError:
print(“Error accessing 0x%02X: Check your I2C address” % self.address)
return -1
def readFull(self, reg=0x8C):

“””Reads visible+IR diode from the I2C device”””
return self.readWord(reg);
def readIR(self, reg=0x8E):

“””Reads IR only diode from the I2C device”””
return self.readWord(reg);
def readLux(self, gain = 0):

“””Grabs a lux reading either with autoranging (gain=0) or with a specified gain (1, 16)”””
if (gain == 1 or gain == 16):
self.setGain(gain) # low/highGain
ambient = self.readFull()
IR = self.readIR()
elif (gain==0): # auto gain
self.setGain(16) # first try highGain
ambient = self.readFull()
if (ambient < 65535):
IR = self.readIR()
if (ambient >= 65535 or IR >= 65535): # value(s) exeed(s) datarange
self.setGain(1) # set lowGain
ambient = self.readFull()
IR = self.readIR()

if (self.gain==1):
ambient *= 16 # scale 1x to 16x
IR *= 16 # scale 1x to 16x

ratio = 0
if (ambient != 0):
ratio = (IR / float(ambient)) # changed to make it run under python 2

if ((ratio >= 0) & (ratio <= 0.52)):
lux = (0.0315 * ambient) – (0.0593 * ambient * (ratio**1.4))
elif (ratio <= 0.65):
lux = (0.0229 * ambient) – (0.0291 * IR)
elif (ratio <= 0.80):
lux = (0.0157 * ambient) – (0.018 * IR)
elif (ratio <= 1.3):
lux = (0.00338 * ambient) – (0.0026 * IR)
elif (ratio > 1.3):
lux = 0

return lux

if __name__ == “__main__”:
while True:
tsl=TSL2561()
print “LUX HIGH GAIN “, tsl.readLux(16)
print “LUX LOW GAIN “, tsl.readLux(1)
print “LUX AUTO GAIN “, tsl.readLux()

$ sudo python TSL2561.py
LUX HIGH GAIN 0
LUX LOW GAIN 2318.77744967
LUX AUTO GAIN 0.45162

続きは 5.センサ値をクラウドに保管・表示 へ

AWSとRaspberry Pi でIoT入門 (第9回JAWS-UG佐賀)

- Raspberry Pi で農業(施設園芸)用センサ、クラウド環境分析システム構築入門 -

JAWS-UG佐賀で上記内容で話をさせて頂きました。
理論中心の座学だけでなく、実践を見て頂きたくも仕事の本番環境は全て公開できません。
そこで、新しいセンサを評価がてら、実際の機器、作業で、センサによる値の計測から、クラウドAWSでのデータ保管、グラフによるデータ解析を行う一連のデモシステムを作成しました。

折角のご縁で、時間を頂いて話を聞きに来られた訳ですので、少しでもお役に立ちたく思います。
そこで、興味のある方に是非「ダイブ」(実際に試)して頂くための、デモシステムを構築した記録を以下にまとめました。
是非、ご参照ください。

以下で紹介するプログラムのソースコードは以下に公開しています。
https://github.com/yukataoka/IoT_Raspi_AWS_Demo

1.Raspberry Pi 初期設定
https://yukataoka.wordpress.com/2015/06/20/raspi01/

2.OSインストール後の設定
https://yukataoka.wordpress.com/2015/06/20/raspi02/

3.センサなどを使うための詳細設定
https://yukataoka.wordpress.com/2015/06/20/raspi03/

4.センサの設定とプログラミング
https://yukataoka.wordpress.com/2015/06/20/raspi04/

5.センサ値をクラウドに保管・表示
https://yukataoka.wordpress.com/2015/06/20/raspi05/

6.S3静的htmlのJavaScriptでグラフ表示
https://yukataoka.wordpress.com/2015/06/20/raspi06/

当日のスライド。
(後日公開予定)

実際のWebコンテンツ
http://s.ykata.net/

AWS麻雀のCDP:Stack Deploymentパターン

JAWS-DAYS 2015 AWS麻雀体験企画
– AWS麻雀のCDP役を理解する –

7.Stack Deploymentパターンを実践理解する

AWS麻雀CDP役(AWS OpsWorks Or Elastic Beanstalk Or AWS CloudFormation Or AWS CodeDeploy{発 扱い}+ コンピュート、データベース、ネットワークのいずれか2牌)
00

今回のStack Deploymentパターンは、AWSの利用環境を、予め設定した内容で自動構築し、簡単にコンテンツ更新を行えるパターンです。

システム開発や運用保守の段階では、試験環境を準備して、結果が問題ないと確認したうえで本番環境に適用します。
しかしながら、試験環境の設定、コンテンツを本番に適用する作業を手で行うと、ヒューマンエラーなどのトラブルが懸念されます。

そこで、あらかじめ試験環境構築を設定ファイル(テンプレート)で定義し、その通り実施する事で、本番環境構築を安全かつ容易に行えるようにします。
また、コンテンツを簡単にデプロィ(本番環境に展開)可能なうえ、バージョン管理を実施できる手法を試してみます。

具体的には Elastic Beanstalk を利用して、簡単にWebサービス用PHP開発環境を構築します。
続いて、自動で作成された構成である、EC2(Webサーバ)や、ロードバランサー、AutoScallingの設定を確認してみます。
そして、このような Elastic Beanstalk で指定した自動構成を実施する定義情報がある AWS CloudFormation の中身を少し紹介します。

参考情報は以下です。

AWS Elastic Beanstalkで環境構築自動化(supertaihei02 さん)
http://qiita.com/supertaihei02/items/b2373890b7e739ded318

Elastic Beanstalk 開発、テスト、デプロイ
http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create_deploy_PHP_eb.sdlc.html

AWS Elastic BeanstalkへGitでデプロイする方法(YoshikiNakamura さん)
http://qiita.com/YoshikiNakamura/items/55525fa0b17e74c25ceb

ZipファイルでElastic Beanstalkにデプロイ(サーバワークス CSチーム かわむら さん)
http://blog.serverworks.co.jp/tech/2012/09/28/elastic-beanstalk_deploy_zip/

 1. Elastic Beanstalk でWebサービス用PHP開発環境を構築

先ずは Elastic Beanstalk でWeb サービス用PHP開発環境を構築します。

管理コンソールで Elastic Beanstalk の画面を開きます。
02

実は最初の画面で、PHPを選択して 「Lunch Now」だけでも基本的な環境は作れてしまいます!
急いでいる方は、 「Lunch Now」が終わるのを待って、 2.コンテンツのデプロイ から参照ください。
さすがにこちらでは少し解説しないと内容を知る事にはなりませんので、 「create a new application」 で内容を確認しながら進めます。
03
残念ながら Elastic Beanstalk の画面は日本語化が間に合っていませんね。

Application name と Discription を入力し、次に進みます。
04

Web Server Environment を選びます。
05

今回は Permissions (権限)はそのまま次へ。
06
詳細が気になる方は、以下を参照ください。
http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/AWSHowTo.iam.roles.aeb.tiers.web.html

platform は PHP、Environment(環境) Type は折角なので、Single instance(単独サーバ環境)より、Load Balancing, Auto Scaling で、インスタンス(サーバ)がダウンしても自動で復旧し、過負荷時にサーバ自動で追加起動する設定にしてみます。
07

最初の application version はサンプルを利用します。
Deployment Limits はどれだけのサーバ数を確保するというような設定と考えると良いでしょう。
今回は試験なので、Fixed でとりあえずインスタンス(サーバ)1台以上をキープの設定に変更してみます。
08
詳細が気になる方は、以下を参照ください。
http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.rolling-version-deploy.html

Environment(環境)名と、URLを入力します。

すでにある名前は使えないので、Check availability で確認しましょう!
09

MySQLなどのRDMSを利用する場合は、RDSの設定をチェックします。
VPC( Virtual Private Cloud)の環境を使う場合は、VPCの設定をチェックします。
今回は使う予定がないので、そのまま次に進みます。
10

詳細の設定で、Instance type は無償試用対応インスタンスでパフォーマンスの良い t2.micro を選択し、EC2 key pair は既存のものがあれば選択します。
その他は初期値のままで良いでしょう。(後から変更も可能です。)
10-1
11

Environment(環境) Tag も設定できますが、今回は試すだけなのでパスします。
12

最後に設定の確認画面が表示されますので、Launch (構築)します。
13

14

構築中は半円の矢印がくるくる回っています。
しばらくコーヒーを味わえるぐらいの時間がかかります。
15

無事環境が構築されたら、緑丸の表示がでます。
Recent event でも確認できます。
さらに Show All で詳細を確認できます。
16

詳細を確認したら、URLのリンクをクリックしてみます。
17

初期コンテンツとして用意されているのはこのページです。
18

以上で、環境構築は完了です。

2.新しいコンテンツをデプロイ(展開)してみる

環境を構築しましたが、まだ実際のコンテンツが表示されている訳ではありません。
とりあえず、以下のサイトの無料テンプレートでコンテンツのデプロイ(展開)を試してみます。

Cafi Net カフィネット 無料テンプレート 73/5ページ/スライドショー
http://japanism.info/free-template.html

先ずは以下のような構成でコンテンツを圧縮したZipファイルを作成します。
20-1

Upload and Deploy で作業を開始します。
19

先ほどのZipファイルを選択し、デプロイします。
20

以下のように、再度作業中の画面が表示されます。
21

Running Version が変わり、Recent Events に Deploying new version の記述が追加されます。
22

再表示すると、入れ替わったコンテンツが確認できます。
23

ただ、これではPHPが動くかどうか確認できません。
そこで、livedoor天気予報のAPIを利用したコンテンツと、定番の phpinfo() を確認するファイルを追加して、デプロイしてみます。

livedoor天気予報 Weather Hacks
http://weather.livedoor.com/weather_hacks/

test.php

<?php
    $point = "390010";
    $url   = "http://weather.livedoor.com/forecast/webservice/json/v1?city=".$point;
    $json  = file_get_contents($url, true);
    $json  = json_decode($json, true);
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Stack Deploymentパターン</title>
</head>

<body>
<h2>Stack Deploymentパターン</h2>
<p>Elastic Beanstalk に デプロイするコンテンツ試験!</p>
<p>今回は livedoor天気情報 Wether Hacks <a href="http://weather.livedoor.com/weather_hacks/" target="_blank">http://weather.livedoor.com/weather_hacks/</a> のAPIをPHPで使った例にしてみました。</p>

<table border="1">

<tr><th colspan="2">
<a href="<?php echo $json['description']['text']; ?>" target="_blank"><?php echo $json['title']; ?></a>
</th></tr>
<tr><td colspan="2">
<?php echo $json['description']['text']; ?><br />
<a href="<?php echo $json['description']['text']; ?>" target="_blank"></a>
</td></tr>

<?php
foreach($json['forecasts'] as $value){
    echo "<tr>";
    echo "<td>".$value['dateLabel']."(".$value['date'].")</td>";
    echo "<td>";
    echo "<image src=\"".$value['image']['url']."\" />".$value['image']['title']."<br />";
    if($value['temperature']['min'] != "NULL") echo "最低気温".$value['temperature']['min']['celsius']."度 ";
    if($value['temperature']['max'] != "NULL") echo "最低気温".$value['temperature']['max']['celsius']."度 ";
    echo "</td>";
    echo "</tr>\n";
}
?>

<tr>
<td>高知その他のポイント</td>
<td>
<?php
foreach($json['pinpointLocations'] as $value){
    echo "<a href=\"".$value['link']."\" target=\"_blank\">".$value['name']."</a><br />";
}
?>
</td>
</tr>

<tr>
<td>提供時点</td>
<td><?php echo str_replace("T"," ",$json['publicTime']); ?></td>
</tr>

<tr>
<td>API提供先</td>
<td><a href="<?php echo $json['copyright']['link']; ?>" target="_blank"><?php echo $json['copyright']['image']['title']; ?></a></td>
</tr>

</table>

</body>
</html>
?>

info.php

<?php
phpinfo();
?>

先のZipファイルに、このPHPプログラムの2ファイルを追加します。
24

Zipファイルを選択し、デプロイします。
25

デプロイが完了したら、表示してみます。

URL/info.php
26

URL/test.php
27
PHPのプログラムがしっかり動いてます!

 3.自動で設定された環境を確認する

自動で設定された環境を確認してみます。

先ずは、EC2関連の設定を確認します。
30

インスタンス(サーバ)が稼働しているのが確認できます。
31

セキュリティグループの設定が追加されています。
32

ロードバランサー(アクセスを複数サーバに振り分ける装置)も設定されています。
33

ロードバランサー(アクセスを複数サーバに振り分ける装置)も設定されています。
34

Auto Scalling 関連の設定もされています。
35
36

ボリューム(サーバのハードディスク)は以下です。
37

続いて、状況を監視する CloudWatch の設定を確認します。
40

アラームが設定されています。
この設定をもとにAuto Scalling などが実施されます。
41

続いて、ログ(記録)などが保管される、S3(ストレージ)を確認します。
45

バケット(保管容器)が追加されています。
46

バケットの中身を確認すると、デプロイしたZipファイルの各バージョンのファイルが保管されているのが確認できます。
47

最後に、AWSのリソース(利用環境)を構成する設定がある、CloudFormationを確認します。
50

Stackと呼ばれる定義が作成されています。
51

Resourcesで構成した内容を確認します。
52

Templateで実際作成された定義を確認してみます。
53
これだけ長い定義記述を自動で作成している事が確認できます。
解読するためインデントを整理するのも大変な量です。

 4.構築した環境の動作を確認する

本当に構成された環境がうまく動いているのか、確認してみます。

インスタンス(サーバ)を削除してみます。
61

62

しばらく待つと、自動で新しいインスタンス(サーバ)が構築されています。
63

Elastic Beanstalk の画面でも確認します。
64

Recent Events でも確認できます。
65

66

5.設定変更の注意

過去 Elastic Beanstalk で設定した内容の変更、削除は必ずElastic Beanstalkの画面で行いましょう。
無視すると、思わぬトラブルに見舞われます。(過去の経験談)

Applicationを選択します。
64

Configuration を選びます。
71

変更をしたい部分の歯車マークをクリックします。
今回、Instances をクリックしてみます。
72

 

以下の変更画面が表示されます。
73
以下のサイトなどを参考にして、変更します。
さすがに、設定変更は専門の知識がないと厳しいでしょう。

インスタンス
http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.managing.ec2.html

Elastic Beanstalk 全般
http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/Welcome.html

6.Gitによるデプロイなど

Gitによるデプロイや、PHPフレームワークのfuelphpを使う場合などは、私の過去の記事を覗いてみてください。

Windows環境で Elastic Beanstalk を使ってデプロイ(アプリ更新)
Elastic Beanstalk でFuel PHPをデプロイ
Elastic Beanstalk で RDS(MySQL)を使う
Elastic Beanstalk の RDS を FuelPHP から利用

さらに詳しい内容を知りたい方は以下が参考になるでしょう!

CloudFormationで環境構築を自動化する(竹永篤史 さん)
http://www.atmarkit.co.jp/ait/articles/1408/25/news014.html

AWS CloudFormation サービスサンプルテンプレート
http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/sample-templates-services-us-west-2.html

AWS Elastic Beanstalkの(多分)最速設定(soramugi さん)
http://qiita.com/soramugi/items/1258127d159703fe731d

ElasticBeanstalkのログ保存方法(今岡久敏 さん)
http://blog.cloudpack.jp/2015/01/28/how-to-store-log-of-elasticbeanstalk/

Elastic BeanstalkでWordPressをインストールしてみました(サーバワークス CSチーム かわむら さん)
http://blog.serverworks.co.jp/tech/2012/06/29/elastic-beanstalk_wordpress_install/

Elastic Beanstalk アプリケーションソースバンドルを作成する
http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.deployment.source.html

AWS麻雀のCDP:Job Observerパターン

JAWS-DAYS 2015 AWS麻雀体験企画
– AWS麻雀のCDP役を理解する –

5.Job Observerパターンを実践・理解する

AWS麻雀CDP役(1〜4ECU+7ECU+1〜SQS{中扱い})
01

今回のJob Observerパターンは、SQSのキュー(処理待ちリクエストなど、一時的な保管データ)と、CloudWatchというリソース情報管理する機能を利用します。
SQS内の処理待ちリクエストが一定量を超えてないかCloudWatchで監視し、超えた時点でAuto Scaling機能で、EC2のインスタンス(サーバ)を追加起動します。
これにより、バッチ処理(Webと違い、計算などの処理を黙々と行うこと)を行うサーバを自動で増減し効率良く処理する事ができます。

例えば、バックグラウンドで実施している動画のサムネイル画像作成処理などで、サムネイル作成指示用SQSのキューが増分した場合、自動で処理サーバを増やす事で一定の処理パフォーマンスを保つができるようになります。

今回はとりあえずt2.microEC2インスタンス(サーバ)と、AMI(サーバイメージ)を作成して、SQS内のキューをコンソールより追加して試してみます。
SQSのキューが5個を超えた時点でサーバの負荷大になると想定し、新しいインスタンス(サーバ)が追加されるよう設定し、処理が実施されるか試したいと思います。

参考情報は以下です。

Amazon SQS との組み合わせで素早く Auto Scaling
http://aws.typepad.com/aws_japan/2015/01/auto-scaling-with-sqs.html

“SQS”と”CloudWatch”と”Auto Scaling”(スズキさん)
http://blog.suz-lab.com/2011/06/sqscloudwatchauto-scaling.html

Amazon SQSとCloudWatchによる高速AutoScaling(横田あかりさん)
http://dev.classmethod.jp/cloud/amazon-sqs-cloudwatch-rapid-autoscaling/

Amazon SQS のディメンションおよびメトリックス
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/DeveloperGuide/sqs-metricscollected.html
先ずは好きなインスタンスで、サーバを立ち上げます。
今回は、Amazon Linux AMI 2015.03 (HVM) t2.micro を利用します。

余談ですが、今回から管理コンソールが日本語化表示です!
00

 

1.EC2のイメージ作成

今回は、バッチジョブと呼ばれる裏方作業のサーバをEC2で起動します。
但し、実際のバッチジョブのアプリ実装は大変ですので、あくまでサーバの起動までを試します。

管理コンソールでEC2の画面を表示します。
00A

インスタンスの作成を行います。
02

Amazon Linux AMI を選択します。
03

t2.micro を選択します。(試して課金はさけたいところ、くれぐれもお間違いなく!)
04

作成 します。
05

既存のキーペアーを選択するか、新しく指定して インスタンスを作成します。
06

以上で、新しいインスタンスが作成。
07

作成したインスタンスのイメージ(AMI)を作成します。
これはSQSの処理待ちキューが増えた場合に、サーバ(インスタンス)を増やす場合の元イメージになります。
本来はシステムを構築したインスタンスのイメージを使います。
が、今回は動きを確認するだけで、Amazon Linux AMI をそのまま使います。
08

インスタンス行の上で 右クリックで、イメージ、イメージの作成 を選択します。
09

イメージ名、説明を適当に設定し イメージの作成をします。
10

 

イメージ(AMI)が完成します。
11

作成したイメージ(AMI)を確認します。
12

 

2.SQSの設定

今回はSQSの処理待ちキューの数が一定量を超える事で、バッチ処理サーバを増やす想定です。
このSQSは、バッチ処理サーバとは別に、業務サーバや、Webサーバなどよりバックグラウンドで行う処理の指示と関連する情報を保管します。
バッチ処理サーバは、このSQSに蓄積されたキューの処理指示に従い、裏方処理を実施します。
SQSは複数のバッチ処理サーバからのアクセスを考慮した処理も実装可能です。

処理待ちを管理するのSQSのキューを作成します。
00B

 

新しいキューの作成 を行います。
13

キュー名、キューの設定 を行います。可視性、メッセージの消滅は短めに設定しました。
キューの作成 をします。
14

キューが出来上がりました。
キューの試験用データは他の設定完了後に行います。
15

 

3.AutoScallingの設定

SQSのキューが閾値を超えた際にバッチ処理サーバを増やします。
これはコンソールのEC2内にある、AutoScalling という機能を利用します。
AutoScalling は今回の例の他に、AWSのロードバランサーと組み合わせて、自動スケールアウト・無停止Webサーバの設定などによく用いられます。

Auto Scalling グループの作成 を行います。
16

起動設定の作成 を行います。
17

マイAMI を選択します。
18

先に作ったイメージ(AMI)を選択します。
19

t2.micro を選択します。(試して課金はさけたいところ、くれぐれもお間違いなく!)
次の手順 に進みます。
20

起動設定を作成します。
名前 を設定し、確認画面にスキップ します。
21

起動設定の作成 を行います。
22

先のEC2のインスタンス作成と同じ設定にします。
23

グループ名 の設定、サブネット を選択します。
次の手順 に進みます。
24

スケーリング範囲を 1 および 2 に設定します。
本来範囲は処理量に応じて設定しますが、今回は試験なので1台の増分で止めます。
名称 、アクションを設定します。
アクションは、今回は試験なので1インスタンス(サーバ)づつ追加にしています。
確認 します。
25

AutoScalling グループの作成 を行います。
26

作成されました。
27

以下のように表示されます。
28

 

4.CloudWatchの設定

CloudWatchはAWSの各サービスの状況を監視し、アラームによる通知・処理などを行います。
その他のサービスと連携し、今回のようなSQSのキュー数の閾値によるインスタンス(サーバ)起動なども行えます。

SQSのキュー数を監視するためのCloudWatchのアラームを作成します。
00C

アラームの作成 を行います。
29

SQSメトリックス を選択します。
30

ApproximateNumberOfMessagesVisible をチェックし、次へ 進みます。
ApproximateNumberOfMessagesVisible はSQS内の有効なキューの数です。
31

名前、説明 を設定します。
ApproximateNumberOfMessagesVisible の値が5以上でアクションを実施するよう設定します。
通知 アクションを削除し、Auto Scalling アクション を追加します。
32


追加した アクション に、アラーム 警告 を選択します。
グループ他には、先に設定した Auto Scalling の設定を選択し、アラームの作成 を行います。

33

作成されたばかりの状態です。
34
以上で設定は終わりです。

 

5.試験の実施

設定が完了しましたが、SQSにキューを登録しない限りインスタンス(サーバ)の数はそのままです。
SQSにデータを5件登録、そして削除した場合のインスタンス(サーバ)の数を確認してみます。

EC2のインスタンスの画面で、稼働しているのは先に作成したインスタンス(サーバ)1個のみです。
40

SQSの画面でキューのメッセージを追加(メッセージの送信)します。
41

5件ほど適当なメッセージを入れて、メッセージの送信 します。
42

43

メッセージの表示 で確認します。
44

メッセージのポーリングを開始します。
45

キュー内に5件のメッセージがあります。
46

CloudWatchの画面で、早速 アラーム が発生しています!
47

最初EC2のインスタンス(サーバ)画面に戻って、起動数が変わらず、、、。
先の赤書きの部分を間違えて設定して、、、最大数を2に変更しました。
48

EC2の画面で、もう1つ同じイメージ(AMI)のインスタンス(サーバ)が起動し始めました。
49

ステータスチェックも合格し、無事起動です!
50

では、意地悪くインスタンス(サーバ)のトラブルを想定し、起動したインスタンス(サーバ)を削除してみます。
51

52

terminatedとは削除された状態で、削除されています!
53

少し待つと、再度アラームの処理で、新しいインスタンス(サーバ)が起動を始めます!
54

これは サーバ管理者の眠れない夜! 撲滅に効果大ですね!(^^)v

では、SQSのキュー内のメッセージを削除してみます。
55

56

SQSキュー内のメッセージが4個になりました。
57

SQSのアラートが消えて正常になっています!
58

EC2のインスタンス(サーバ)が自動で削除(terminated)されています!
59

今回のCDPパターンは地味ですが、この機能は
・ソフト会社で基幹系システムのSI屋さん
・Webサービスでバックグランド処理をかかえるIT屋さん
などには必須の機能ですね!

このブロッグでは触りの部分のみ紹介しましたが、もっと突き詰めて設定すると素晴らしいパフォーマンスの停止しないシステムを構築可能でしょう!!

JAWS-DAYS 2015 AWS麻雀体験企画 に戻る