Edited at

Soracomスターターキットで作るGPSなしの位置情報トラッカー ~その2 AWS IoT連携~

More than 1 year has passed since last update.

Soracomスターターキットで作るGPSなしの位置情報トラッカー ~その1~からの続きになります

ソースコードは以下になります

ymmtyuhei/GeoLogAWS: Google Geolocation APIを使い取得した位置情報をAmbientに送信する。


AWS IoTのセットアップ

AWS IoTへRaspberry PIからMQTTでメッセージをPublishするまでのRaspberry PiとAWSの環境を、チュートリアルの通り構築します。


Raspberry Pi の接続 - AWS IoT



  • Raspberry PIからメッセージをパブリッシュしたがAWSのウェブコンソールで確認できなかったとき、
    デバッグツールとしてMQTT.fxをつかってみるといいかもしれません。


AWS IoTを始めよう -MQTTの設定(MQTT.fx編)-

https://recipe.kc-cloud.jp/archives/9629


スクリーンショット 2018-04-18 17.05.00.png



  • 前回の手順でSoracom AirをセットアップしたRaspberry PIに有線LANのみ接続した状態だと、
    AWS IoTへのメッセージのパブリッシュができず、USBモデムを接続したときのみパブリッシュできました。


AWS Lambdaを設定

AWS IoTのカスタムルールを作成します。特定のトピックへのメッセージをフックし、Lambdaを実行する設定をします。


AWS IoT チュートリアル ラムダルールの作成



  • トピックフィルターとしてpisora/ssidsを設定しました。

  • MQTTfxを使いながらテストデータをパブリッシュし、Lambdaが実行されることを確認します。

  • Lambdaの実行ログは CloudWatch>ロググループで確認できます。

  • RasPi側でpisora/updateというトピックをフックして、SSIDの送信処理が実行されるようにしたので、AWS IoT側からそのトピックにメッセージを送信し、動作を確認できます。

スクリーンショット 2018-04-18 17.23.10.png

スクリーンショット 2018-04-18 17.23.22.png

const ambient = require('ambient-lib')

const axios = require('axios')
const geolocation_key = '***'
const ep_geolocation = 'https://www.googleapis.com/geolocation/v1/geolocate?key='+geolocation_key

//ambient.connect(チャネルId, ライトキー[, リードキー[, ユーザーキー]]);
ambient.connect(1234, "***", "***", "***");

function postAmbient(accuracy, lat, lng){
var ambientData = {
d5: accuracy,
lat: lat,
lng: lng
}
ambient.send(ambientData, function(err, res) {
if (err) {
console.error(err)
}
console.log('update to ambient success. :',res.statusCode)
})
}

function requestPosition(ssids){
console.log("got ssids")
console.dir(ssids)
axios.post(ep_geolocation, ssids)
.then(function (response) {
console.log("got geolocation from ssids")
console.dir(response.data)
postAmbient(
response.data.accuracy,
response.data.location.lat,
response.data.location.lng
)
})
.catch(function (error) {
console.log(error)
})
}

exports.handler = (event, context, callback) => {
var eventText = JSON.stringify(event, null, 2);
console.log("Received event:", eventText);
requestPosition(event)
}


Raspberry PiからSSIDをパブリッシュする


  • AWS IoTの鍵情報などが設定されたRaspberry Piから、定期的にSSIDを送信するスクリプトを展開します。

const piWifi = require('pi-wifi')

const cron = require('node-cron')
const axios = require('axios')
const geolocation_key = '***'
const ep_geolocation = 'https://www.googleapis.com/geolocation/v1/geolocate?key='+geolocation_key
let awsIot = require('aws-iot-device-sdk')
let device = awsIot.device({
keyPath: "/home/pi/deviceSDK/certs/private.pem.key",
certPath: "/home/pi/deviceSDK/certs/certificate.pem.crt",
caPath: "/home/pi/deviceSDK/certs/root-CA.crt",
clientId: "PISORA",
host: "xxx.iot.us-east-1.amazonaws.com"
})

function geolocationObject(piwifiResponse) {
var wifiAccessPoints = []
for (const network in piwifiResponse) {
if (piwifiResponse.hasOwnProperty(network)) {
const element = piwifiResponse[network]
let wifiAccessPoint = {
"macAddress":element.bssid,
"signalStrength":element.signalLevel
}
wifiAccessPoints.push(wifiAccessPoint)
}
}
let res = {
"considerIp": "false",
"wifiAccessPoints":wifiAccessPoints
}
return res
}

function scan(){
piWifi.scan(function(err, networks) {
if (err) {
return console.error(err.message)
}
if (networks === undefined ){
return console.error("networks undefined")
}
var res = geolocationObject(networks)
console.log("found ssids :")
console.dir(res)
device.publish('pisora/ssids', JSON.stringify(res))
})
}

device
.on('connect', function() {
console.log('connect')
device.subscribe('pisora/update')
scan()
/**
* 定期実行
* 1分に1回実行
*/

cron.schedule('*/1 * * * *', function(){
scan()
})
})

device
.on('message', function(topic, payload) {
console.log('message', topic, payload.toString())
scan()
})


永続化 (Raspberry Pi)

前回設定したpm2の自動起動の設定を削除したあと、pm2を再始動します

pm2 delete all

pm2 start {スクリプトのファイルパス}
pm2 save
pm2 startup


Ambidataで確認

位置情報がAmbidata上にプロットされていることを確認します。

SSIDから位置情報を推測しているので、GPSの電波を受信できない、地下鉄でも位置情報をプロットできました。

スクリーンショット 2018-04-18 17.38.14.png


運用にかかった費用(参考値)

1時間ほど動かしてみたところ、以下の転送量がSoracomコンソール上で確認されました

種別
1時間あたり転送量(その1)
1時間あたり転送量(その2)

上り
52.3KiB (0.05107 MiB)
113.7KiB(0.11104 MiB)

下り
188.2KiB (0.18379 MiB)
69.5KiB(0.06787 MiB)

* s1.standard 上り0.24 円/MB 下り0.8 円/MB

(なぜ上り転送量が増えたのか疑問が残る結果になりました...)

スクリーンショット 2018-04-18 16.51.07.png


1日稼働後のAWSの請求ダッシュボード

スクリーンショット 2018-04-18 17.41.37.png


(しばらく放置したの情報を追記)

** 条件が変わっています

*前回と条件が変わっています

送信間隔 1分→10分

バッテリは5000mAhの以下のもの

https://www.amazon.co.jp/gp/product/B01DEURI48

開始
終了
稼働時間

21:15
翌06:50
9:35

スクリーンショット 2018-04-20 12.33.56.png


1時間あたり転送量


  • UP 37.2kb/h

  • DL 39.2kb/h


上記の設定で一ヶ月稼働した場合


  • UP27.028125Mib = 6.48円

  • DL28.48125Mib = 22.4円

  • 想定される月額料金29円