趣味のログ

自分用の作業ログ。。

RaspberryPi3からAWS IoTへセンサデータの送信

AWS IoT SDK for JavaScriptのインストール

githubのREADMEを参考に、AWS IoT SDKをインストール
nodejsのバージョンは

node -v
v4.4.4

AWS IoT SDKインストール

npm install aws-iot-device-sdk
cd /home/pi (任意のディレクトリでOK)
git clone https://github.com/aws/aws-iot-device-sdk-js.git
cd aws-iot-device-sdk-js
npm install

センサー情報の取得

センサー情報はGrove+を使って取得する
AWS IoT SDKはnode.jsを使っているけれど、センサーデータはpythonで取得する
まずはpythonのコードを作成する

#!/usr/bin/env python
import sys
sys.path.append('/home/pi/Desktop/GrovePi/Software/Python/')
import time
import datetime
from grovepi import *
import serial

# for GPS
ser = serial.Serial('/dev/ttyAMA0',  9600, timeout = 0) #Open the serial port at 9600 baud
ser.flush()

class GPS:
        inp=[]
        GGA=[]
        def read(self):
                while True:
                        GPS.inp=ser.readline()
                        if GPS.inp[:6] =='$GPGGA': # GGA data , packet 1, has all the data we need
                                break
                        time.sleep(0.1)
                try:
                        ind=GPS.inp.index('$GPGGA',5,len(GPS.inp))
                        GPS.inp=GPS.inp[ind:]
                except ValueError:
                        hoge="fuga"
                GPS.GGA=GPS.inp.split(",")
                return [GPS.GGA]

        def vals(self):
                time=GPS.GGA[1]
                lat=GPS.GGA[2]
                lat_ns=GPS.GGA[3]
                long=GPS.GGA[4]
                long_ew=GPS.GGA[5]
                fix=GPS.GGA[6]
                sats=GPS.GGA[7]
                alt=GPS.GGA[9]
                return [time,fix,sats,alt,lat,lat_ns,long,long_ew]

# for Japan Timestamp
class JapanTZ(datetime.tzinfo):
    def tzname(self, dt):
        return "JST"
    def utcoffset(self, dt):
        return datetime.timedelta(hours=9)
    def dst(self, dt):
        return datetime.timedelta(0)


ptemperature = 3
pmoisture = 0
plight = 1

gps = GPS()

pinMode(ptemperature,"INPUT")
pinMode(pmoisture,"INPUT")
pinMode(plight,"INPUT")
time.sleep(1)

[temperature, humidity] = dht(ptemperature, 1)
moisture = analogRead(pmoisture)

light = analogRead(plight)

gps.read()

[t,fix,sats,alt,lat,lat_ns,long,long_ew] = gps.vals()

try:
  latitude = str(float(lat)/100)
  longitude = str(float(long)/100)
except ValueError:
  latitude = 0
  longitude = 0

time.sleep(.5)

print("{0},{1},{2},{3},{4},{5},{6}".format(datetime.datetime.now(JapanTZ()).strftime('%Y-%m-%dT%H:%M:%S+09:00'), temperature, humidity, moisture, light, latitude, longitude))

ser.close()

次にnode.jsのコード
5分間隔でセンサーデータを取得し、AWS IoTクラウドへ送信する
private.pem.key、certificate.pem.crt、root-CA.crtは、AWS IoTのクラウドコンソールからダウンロードしておき、任意のディレクトリに配置しておく
pythonコードの実行は、child_processのexecファンクションを使用する(pythonの標準出力を、execファンクションに設定したコールバック関数の引数として受け取れる)

var awsIot = require('aws-iot-device-sdk');
var sys = require('sys')
var exec = require('child_process').exec;

var device = awsIot.device({
    privateKey: './certs/private.pem.key',
    clientCert: './certs/certificate.pem.crt',
    caCert: './certs/root-CA.crt',
    clientId: 'test_client',
    region: 'ap-northeast-1'
});

device.on('connect', function() {
  console.log('Connect!!');
  setInterval(function() {
    exec("python /path to python code", function(error, stdout, stderr) {
      if (error !== null) {
        console.log('exec error: ' + error);
        return
      }
      var data = stdout.replace(/\r?\n/g,"");
      var datas = data.split(",")
      var record = {
        deviceid: "pi_01",
        timestamp: datas[0],
        temperature: Number(datas[1]),
        humidity: Number(datas[2]),
        moisture: Number(datas[3]),
        light: Number(datas[4]),
        location: datas[5] + "," + datas[6]
      };
      var message = JSON.stringify(record);
      console.log("Publish: " + message);
      device.publish('pi_test', message);
    });
    return;
  }, 300000);
});