Article information
RevisionsShow article in Markdown
Report article
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

This post is Private. Only a writer or those who know its URL can access this post.

posted at

updated at

FlashAirに書き込まれたcsvファイルをAmazon S3に転送し、さらにデータをDynamoDBに書き込む

IoT.kyoto IoTスターターパック

IoT.kyotoではFlashAirを使用したスターターパックをご用意しております。FlashAirにファイルとしてデータを書き込むと、そのファイルはLTEルーターを経由してAmazon S3に保存され、自由なデータの取り出しが可能になります。
スクリーンショット 2018-11-26 11.04.47.png

概要

スクリーンショット 2018-11-26 11.10.09.png

このチュートリアル記事では、上記スターターパックのアーキテクチャをもとに、FlashAirにcsvファイルを書き込むとS3にcsvファイルが転送され、さらにNoSQL DBであるDynamoDBに書き込まれるアーキテクチャの構築手順を説明します。

事前準備

  • パソコン
    • OS: macOSまたはWindows(macOSだとデータの送信に失敗する場合があります。その場合はWindowsでお試しください)
    • ブラウザ: Google Chrome
    • SDカードを接続できること(なければUSBのSD CARD READER等が必要)
    • LTEルーターに接続可能であること
  • LTEルーター
    • SORACOM Air SIM が接続可能なこと
    • Wi-Fiで接続可能なこと
    • 予めSSIDとパスワードをメモしておくこと
  • 有効な AWS アカウント
    • AWSコンソールのIAMから自分のアカウントを選択し、AdministratorAccessの権限が付与されていることを確認してください
  • 有効な SORACOM アカウント
  • SORACOM アカウントに登録済みの SORACOM Air SIM (LTEルーターに接続できるサイズであること)

料金

今回使用するサービスの料金体制については、それぞれのリンク先をご参照ください。

SORACOM Air SIM
https://soracom.jp/services/air/cellular/price/

SORACOM Beam
https://soracom.jp/services/beam/price/

Amazon API Gateway
https://aws.amazon.com/jp/api-gateway/pricing/

AWS Lambda
https://aws.amazon.com/jp/lambda/pricing/

Amazon S3
https://aws.amazon.com/jp/s3/pricing/

AWS DynamoDB
https://aws.amazon.com/jp/dynamodb/pricing/

AWS Cloud9
https://aws.amazon.com/jp/cloud9/pricing/

[1]FlashAirの設定

まずはFlashAirの設定を行います。
FlashAirをLTEルーターに紐付け、特定のフォルダのファイルをAWSに送信できるようにLuaファイルを作成します。

図で表すと、こちらの部分です。
FlashAirのみ.png

初期設定

FlashAir設定ソフトウェア

FlashAirの初期設定を行うため、FlashAir設定ソフトウェアをインストールして、ネットワークの設定を行います。
1. 下記のURLから、パソコンのOSに合わせて、ダウンロードします
https://jp.toshiba-memory.com/support/download/flashair/software/we/software02.htm
2. FlashAirのSDカードをパソコンと接続した状態で設定ソフトウェアを開くと、下図のような画面が表示されます
スクリーンショット 2018-11-09 13.52.25.png
3. 表示されたら、一番上の「ネットワークの設定」をクリック
ネットワーク設定が表示されるので、LTEルーターのSSIDとパスワードを記載し、リダイレクト機能をONにして、適用ボタンをクリックします。
スクリーンショット 2018-11-09 13.52.50.png

Configの設定

FlashAirには、ネットワーク設定やバージョン情報などを保持するファイルが予め用意されています。
Configファイルは、SDカード内部のSD_WLANフォルダに保存されています(SD_WLANフォルダは隠しフォルダになっています)。
上記のネットワーク設定を行った後、下記のような内容になっています(FlashAirによって設定値は異なります)。

/SD_WLAN/config.CONFIG
[Vendor]

CIPATH=/DCIM/100__TSB/FA000001.JPG
VERSION=F15DBW3BW4.00.03
CID=<CIDが表示されます>
PRODUCT=FlashAir
VENDOR=TOSHIBA
APPSSID=<SSID名>
APPNETWORKKEY=<SSIDのパスワード>
APPMODE=4
APPAUTOTIME=300000
DNSMODE=1
LOCK=1

設定値の詳細については、下記のURLから確認できます。
https://www.flashair-developers.com/ja/documents/api/config/

/SD_WLAN/config.CONFIG を以下の通り加筆、修正します。

※ <>には、<>を抜いたユニークな値が入ります。ご自分の環境に合わせて入力してください
※ 下記の例に記述されているコメントは、実際には記入しないでください

  1. APPMODEの値を、5に変更
  2. STA_RETRY_CT=5を追記
  3. LUA_SD_EVENT=/lua/sendData.luaを追記

全て記載すると、下記のようなファイルになります。

/SD_WLAN/config.CONFIG
[Vendor]

CIPATH=/DCIM/100__TSB/FA000001.JPG
VERSION=F15DBW3BW4.00.03
CID=<CIDが表示されます>
PRODUCT=FlashAir
VENDOR=TOSHIBA
APPSSID=<SSID名>
APPNETWORKKEY=<SSIDのパスワード>
APPMODE=5 //変更
APPAUTOTIME=300000
DNSMODE=1
LOCK=1
LUA_SD_EVENT=/lua/sendData.lua //追記
STA_RETRY_CT=5 //追記

FlashAir設定ソフトウェアとCONFIG設定後

設定を反映させるために、FlashAirを再起動する必要があります。
一度FlashAirのマウントを解除し、FlashAirをパソコンから取り外します。
その後、FlashAirを再度パソコンに接続します。

Luaファイル

Luaファイルの作成

Luaファイルとは、FlashAirで使用することができる汎用スクリプト言語で作成されたもので、
データの転送やファイル操作などを行うことができます。
FlashAirが起動された時やファイルの更新があった場合に、
CONFIGファイルのLUA_SD_EVENTに設定されたファイルのスクリプトが起動されます。

今回はFlashAir直下にLuaフォルダを作成し、そこにsendData.luaという名前で保存します(/lua/sendData.lua)。
Luaファイルにも、SSIDの設定を記載します。

  1. 以下のソースコードを環境に合わせて変更し、貼り付けてください
sendData.lua
local TARGET_PATH = "/Send" -- データ送信するフォルダ
local GW_SSID = <SSID> -- SSIDを記載する
local DB_CONNECTION = <SSIDのパスワード> -- SSIDのパスワードを記載する

-- 更新されたファイルを探す
function find_latest_path()
  r, fl, t = fa.search("file", TARGET_PATH, -1)
  if r == 1 then
    return string.match(fl, '(.-),')
  end
end

-- 保存されたファイルをSORACOM経由でAWSに送信する
function request_api(path)
  endpoint = "http://beam.soracom.io:18080/dev/puts3"
  boundary = "--61141483716826"
  contenttype = "multipart/form-data; boundary=" .. boundary
  mes = "<!--WLANSDFILE-->\r\n"
  blen = lfs.attributes(path, "size")
  b, c, h = fa.request{
    url = endpoint,
    method = "POST",
    headers = {
      ["Content-Length"] = tostring(blen),
      ["Content-Type"] = contenttype
    },
    file = path,
    body = mes
  }
end

-- LTEルーターと再接続する
function connect()
  fa.Disconnect()
  sleep(5000)
  fa.Connect(GW_SSID, DB_CONNECTION)
  sleep(5000)
end

-- SDカード更新時に起動して処理が実施される
local latest = find_latest_path()
connect()
request_api(latest)

以上でFlashAirの設定は完了です。

[2]AWSの設定

FlashAir側の設定が終わりましたので、次はクラウド側の設定を行います。
APIGatewayで受け口を作成し、Lambdaで処理を行い、S3やDynamoDBに保存します。

図で表すと、こちらの部分です。
スクリーンショット 2018-11-26 11.10.36.png

AWS Cloud9を使用してServerless Frameworkを実行する

Serverless Frameworkとは

Lambda、API Gateway、DynamoDBなどのAWSサービスを作成、管理、デプロイできるツールです。
本来であればAWSのサービスごとにコンソールやコマンドから一つ一つ作る必要がありますが、
Serverless Frameworkを使用すると、複数のサービスを一括で作成・削除できます。

AWS Cloud9とは

AWS Cloud9とは、ブラウザから使えるクラウド型のIDEです。
Serverless Frameworkをdeployするにあたり、OS等の開発環境に依存した準備をするのは手間がかかります。
そこで、今回はAWS Cloud9を使うことで、どのOSでも同じIDEを用意し、Serverless Frameworkを実行します。

AWS Cloud9の作成

  1. AWSコンソールを開き、AWS Cloud9を選択
  2. 2018年11月現在、東京リージョンにサービスはないので、アジアパシフィック(シンガポール)で作成
  3. Create environmentから、environmentを作成
  4. 名前は任意に入力。Environment settingsは初期設定のままで問題ありません

ファイルの設置

AWS Cloud9のenvironmentの作成が完了すると、コンソールが表示されます。
AWS Cloud9コンソールの上部メニューからFile→New Fileで新規ファイルが作成されるので、下記の3ファイルを作成し、保存します。
S3のバケット名は、各自で分かりやすいものを代入してください。
また、S3バケットは全てのファイルで同じ名称にしてください。

handler.js
"use strict";

const AWS = require("aws-sdk");
const s3 = new AWS.S3()
const DYNAMO_DB = new AWS.DynamoDB.DocumentClient({
  region: "ap-northeast-1"
});
const CSV = require("comma-separated-values");
const TABLE_NAME = "FlashAirData";

// S3に保存されたCSVファイルを元に、DynamoDBにデータを挿入する
exports.sendData = (event, context) => {
  const bucket = event.Records[0].s3.bucket.name;
  const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
  const params = {
    Bucket: bucket,
    Key: key,
  };
  s3.getObject(params, (err, data) => {
    if (err) {
      console.log(err);
      return
    } else {
      const csv = new CSV(data.Body.toString("utf-8"), {header: true}).parse();
      console.log(csv);
      for(let num = 0 ; num < csv.length ; num++) {
        let dynamoDBParam = {
          TableName: TABLE_NAME,
          Item: csv[num]
        };
        DYNAMO_DB.put(dynamoDBParam).promise().then(data => {
          console.log(data);
        }).catch(err => {
          console.log(err);
          throw new Error(err);
      });
      }
    }
  });
};

// FlashAirから送信されたCSVファイルをS3に保存する
exports.putS3 = (event, context) => {
  console.log(event);
  s3.putObject({
    Body: event.body,
    Bucket: バケット名, // serverless.ymlと同じバケット名にする
    ContentType: 'text/csv',
    Key: 'data.csv'
  }).promise()
    .then((result) => {
      console.log("result!");
      return {
        statusCode: 200,
        body: JSON.stringify({
        message: "Success!! insert data to DynamoDB",
        input: event
    })
  };
    })
    .catch((err) => {
      return {
        statusCode: 400,
        body: JSON.stringify({
          message: err,
          input: event
      })
    };
    })
}
package.json
{
  "dependencies": {
    "comma-separated-values": "^3.6.4"
  }
}
serverless.yml
service: flashair-handson

# handler.jsと同じバケット名にする
custom:
  defaultStage: dev
  defaultProfile: default
  defaultRegion: ap-northeast-1
  defaultTableName: FlashAirData
  defaultBucket: <バケット名>

# サービスの設定やIAMの作成を行う
provider:
  name: aws
  runtime: nodejs8.10
  stage: ${opt:stage, self:custom.defaultStage}
  region: ${opt:region, self:custom.defaultRegion}
  apiKeys:
    - flashAirKey
  iamRoleStatements:
    -  Effect: "Allow"
       Action:
        - "dynamodb:PutItem"
        - "s3:getObject"
        - "s3:putObject"
       Resource: 
        - "arn:aws:dynamodb:${self:provider.region}:*:table/${self:custom.defaultTableName}"
        - "arn:aws:s3:::${self:custom.defaultBucket}/*"

# LambdaやS3、API Gatewayを作成する
functions:
  putS3:
    handler: handler.putS3
    events:
      - http:
          path: /puts3
          method: post
          private: true
  sendData:
    handler: handler.sendData
    events:
      - s3: ${self:custom.defaultBucket}

# DynamoDBを作成する
resources:
  Resources:
    usersTable:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: ${self:custom.defaultTableName}
        AttributeDefinitions:
          - AttributeName: deviceID
            AttributeType: S
          - AttributeName: record_time
            AttributeType: S
        KeySchema:
          - AttributeName: deviceID
            KeyType: HASH
          - AttributeName: record_time
            KeyType: RANGE
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1

コンソールからslsの実行

Lambda起動に必要なライブラリの準備や、Serverless Frameworkコマンドの準備を行います。
AWS Cloud9の右下にあるコンソールから、下記のコマンドを入力します。

AWSCloud9コンソール
$ sudo yum -y update
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
$ . ~/.bashrc
$ nvm install --lts=carbon
$ nvm use lts/carbon
$ node -v
$ npm update -g npm
$ npm install -g serverless
$ npm install
$ sls deploy

APIの確認

この後に行うSORACOMの設定のため、APIのエンドポイントとAPIキーを確認します。
sls deploy実施後、コンソールに以下のようにapi keysとendpointsが出力されますので、
メモしておきます。

AWSCloud9コンソール
api keys:
  flashAirKey: JQDRwWYCQ1V4Ly9DsLjw5Tn3MlazodH4UG9N5kEa
endpoints:
  POST - https://hoge.execute-api.ap-northeast-1.amazonaws.com/dev/puts3

上記内容はAWSコンソールからも確認できます。
東京リージョンにて、API Gatewayサービスを選択し、Serverless Frameworkで作成されたAPIを選択します。

エンドポイント:

  • dev-flashair-handsonを選択し、ステージ→devとクリックして表示されるURL

(例)https://hoge.execute-api.ap-northeast-1.amazonaws.com/dev

APIキー:

  • APIキーを選択し、flashAirKey→APIキーの表示をクリックした際に表示される文字列

(例)JQDRwWYCQ1V4Ly9DsLjw5Tn3MlazodH4UG9N5kEa

[3]SORACOMの設定

FlashAirとAWSの設定が完了したら、その間を通信するSORACOMの設定を行います。
今回はSORACOM Air SIM を使用し、SORACOM Beamというサービスを使い、AWSへの通信を行います。

図で表すと、こちらの部分です。
ソラコムのみ.png

グループの作成

SORACOMコンソールを開き、メニューからSIMグループをクリックする。
SIMグループ画面で追加ボタンを押す。
スクリーンショット 2018-11-09 16.58.44.png
ダイアログが表示されるので、グループ名にFlashAir_demoと入力し、グループ作成をクリックします。
スクリーンショット 2018-11-09 17.01.01.png
作成したSIMグループを選択し、基本設定から、SORACOM Beam設定を選択し、+ボタンをクリックします。
エントリポイントの選択が出てくるので、Webサイトエンドポイントをクリックします。
スクリーンショット 2018-11-09 17.08.59.png
SORACOM Beamの設定画面が表示されるので、以下の内容を入力して、保存します。

  • 設定名に任意の文字列を設定する
  • ホスト名に、API GatewayでメモしたURLの頭のhttps://と末尾の/devを削除して入力する
  • IMSIヘッダをONにする
  • IMEIヘッダをONにする
  • カスタムヘッダのヘッダ名にX-API-KEY、値にAPI GatewayでメモしたAPIキーを入力する

webサイト転送設定.png

ヘッダ操作.png

SIMグループができれば、SORACOMコンソールのSIMカード一覧から、LTEルーターに接続しているSIMを選択し、所属グループの変更をクリックします。
ダイアログが表示されるので、作成した所属グループを紐付けます。
これでSORACOMの設定は完了です。
スクリーンショット 2018-11-09 17.25.04.png
simの所属グループ変更.png

[4]動作チェック

準備ができたら、実際に動かしてみましょう。

CSVファイルの設置

FlashAirにSendフォルダを作成し、下記のファイルをUTF-8の文字コードで保存します。
動作に問題がなければ、CSVがアーキテクチャ図の通りに流れ、DynamoDBに保存されます。

sample.csv
record_time,deviceID,temp
2018-11-07T00:00:00.000+0900,Device1,14
2018-11-07T01:00:00.000+0900,Device1,14
2018-11-07T02:00:00.000+0900,Device1,13
2018-11-07T03:00:00.000+0900,Device1,12
2018-11-07T04:00:00.000+0900,Device1,13
2018-11-07T05:00:00.000+0900,Device1,14
2018-11-07T06:00:00.000+0900,Device1,14
2018-11-07T07:00:00.000+0900,Device1,15
2018-11-07T08:00:00.000+0900,Device1,16
2018-11-07T09:00:00.000+0900,Device1,17
2018-11-07T10:00:00.000+0900,Device1,19
2018-11-07T11:00:00.000+0900,Device1,20
2018-11-07T12:00:00.000+0900,Device1,22
2018-11-07T13:00:00.000+0900,Device1,23
2018-11-07T14:00:00.000+0900,Device1,22
2018-11-07T15:00:00.000+0900,Device1,22
2018-11-07T16:00:00.000+0900,Device1,20
2018-11-07T17:00:00.000+0900,Device1,18
2018-11-07T18:00:00.000+0900,Device1,17
2018-11-07T19:00:00.000+0900,Device1,17
2018-11-07T20:00:00.000+0900,Device1,16
2018-11-07T21:00:00.000+0900,Device1,16
2018-11-07T22:00:00.000+0900,Device1,15
2018-11-07T23:00:00.000+0900,Device1,14
2018-11-07T24:00:00.000+0900,Device1,14

FlashAirをmacOSに接続して動作確認する場合、うまく動作しないことがあります。
その場合は、FlashAirをWindowsに接続して動作確認をお願いします。

データの確認(AWSコンソールから確認)

AWSコンソールからDynamoDBを選択し、FlashAirDataテーブルを確認します。
問題なく処理された場合、CSVの内容がDynamoDBに保存されています。

データの確認(IoT.kyoto VISで確認)

DynamoDBに保存されたデータは、IoT.kyoto VISで可視化することもできます。

IoT.kyoto VISは、IoT.kyotoが提供する無料でご利用いただけるIoTデータ可視化アプリです。
操作方法についてはこちらからご確認ください。

こちらのアプリはリアルタイムでのグラフ描画が可能です。どのような動きをするかは下記の動画をご覧ください。画像をクリックするとYouTubeのページに遷移します。

IMAGE ALT TEXT HERE

[5]各種アカウントの環境を削除

AWSやSORACOMは、上記の料金の項目に記載されている通り、課金が発生します。
そのため、今回ハンズオンで作成した環境が不要になった場合は、下記の手順で環境を削除してください。

AWS

  1. 予め作成したS3バケットの中身を全て削除します。
  2. AWS Cloud9のコンソールで、下記のコマンドを入力すると、AWSで作成したハンズオンの内容は全て削除されます。
  3. AWSのサービス一覧からAWS Cloud9を選択し、deleteボタンで作成したenvironmentsを削除します。
AWSCloud9コンソール
$ sls remove

sls removeする前に必ずS3バケットが空になっているかを確認してください
もしファイルが残っていると、削除がエラーとなってしまいます。

SORACOM

SORACOMコンソールから今回使用したSIMを選択し、今後のご利用予定に合わせてSIMの状態を変更することができます。
今回使用したSORACOM Air SIMを長期間(二ヶ月以上)利用しない場合は、利用中断に、
今後も利用する予定がある場合は、休止にしてください。

FlashAir

もし初期化する必要があるのであれば、FlashAir設定ソフトウェアから実施できます。
スクリーンショット 削除.png

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Article information
RevisionsShow article in Markdown
Report article
Help us understand the problem. What are the problem?