Upload
tsuchimon
View
1.480
Download
2
Embed Size (px)
Citation preview
AWS IoTで家庭内 IoTやってみた土持 昌志
自己紹介• 土持昌志• @pampitter
• 株式会社鈴木商店• JAWS-UG大阪• 好きな AWSサービス: Lambda、
S3
AWS IoTをやってみたきっかけ
AWS IoTをやってみたきっかけ• 2015年 10月に子供が生まれました• 2015年 10月の re:Inventで AWS IoT発表• 風邪・インフルエンザ対策に湿度データを収集してみよう
AWS IoTの概要
Device Gateway
DeviceGateway(Broker)
Publisher Subscriber
Publisher
Publisher Subscriber
Subscriber
MQTTHTTP
WebSocket
MQTTHTTP
WebSocket
Rule Engine
Action
SELECT humidityFROM '#'WHERE humidity <= 40
Rule Query
DeviceGateway
{"temp": 20.0}{"humidity": 40.0}{"temp": 22.0}
{"humidity": 70.0}{"temp": 21.0}
{"humidity": 20.0}
{"humidity": 40.0}{"humidity": 20.0}
Demo 1
湿度センサー
MQTT
Rule EngineTopic
センサーデータを収集# -*- coding: utf-8 -*-from __future__ import divisionfrom __future__ import absolute_importfrom __future__ import print_functionfrom __future__ import unicode_literals
from sense_hat import SenseHatimport datetimeimport json
sense = SenseHat()hum = sense.get_humidity()
now = datetime.datetime.now()
hum_json = { 'timestamp': now.strftime("%Y-%m-%d %H:%M:%S"), 'humidity': hum}
print(json.dumps(hum_json))
var execSync = require('child_process').execSync;
module.exports = { sensor: function() { var data = "" + execSync('python ' + __dirname + '/sensor.py'); return JSON.parse(data); }}
Nodeから Pythonへのブリッジ
var awsIot = require('aws-iot-device-sdk');var bridge = require('./bridge.js');
var device = awsIot.device({ keyPath: './certs/private.pem.key', certPath: './certs/certificate.pem.crt', caPath: './certs/root-CA.crt', clientId: 'pi2_01', region: 'ap-northeast-1'});
device .on('connect', function() { console.log('connect'); setInterval(function() { var humidity = bridge.sensor(); console.log(humidity) device.publish('pi2_01', JSON.stringify(humidity)); }, 1000); });
AWS IoTにパブリッシュ
Demo 1
Device Shadow
Device Device Shadow
App
• desired:管理アプリなどから指定されたあるべき状態• reported:デバイスが報告した現在の状態• delta:desiredと reportedの差分
Device Shadow{ "desired": { "color": "white" }, "reported": { "color": "white" }}
{ "desired": { "color": "red" }, "reported": { "color": "red" }}
{ "desired": { "color": "red" }, "reported": { "color": "white" }, "delta": { "color": "red" }}
Demo 2
LED
Device Shadow Console
LEDを点灯# -*- coding: utf-8 -*-from __future__ import divisionfrom __future__ import absolute_importfrom __future__ import print_functionfrom __future__ import unicode_literals
from sense_hat import SenseHatimport sys
sense = SenseHat()argv = sys.argv
colors = { "red": (255, 0, 0), "yellow": (255, 215, 0), "green": (50, 205, 50), "blue": (0, 0, 255), "light_blue": (91, 192, 222), "white": (255, 255, 255), "black": (0, 0, 0)}
if colors.has_key(argv[1]): color = colors[argv[1]]else: color = colors['black']
pixels = []for pix in range(0, 64) : pixels.append(color)
sense.set_pixels(pixels)
var execSync = require('child_process').execSync;
module.exports = { sensor: function() { var data = "" + execSync('python ' + __dirname + '/sensor.py'); return JSON.parse(data); }, led: function(color) { execSync('python ' + __dirname + '/led.py ' + color); return; }}
Nodeから Pythonへのブリッジ
var awsIot = require('aws-iot-device-sdk');var bridge = require('./bridge.js');
var thingShadows = awsIot.thingShadow({ keyPath: './certs/private.pem.key', certPath: './certs/certificate.pem.crt', caPath: './certs/root-CA.crt', clientId: 'pi2_01', region: 'ap-northeast-1'});
var clientTokenGet;var clientTokenUpdate;
thingShadows.on('connect', function() { thingShadows.register('pi2_01'); setTimeout(function() { clientTokenGet = thingShadows.get('pi2_01'); }, 2000);});
Device Shadowから LEDを操作thingShadows.on('status', function(thingName, stat, clientToken, stateObject) { console.log('received ' + stat + ' on ' + thingName + ': ' + JSON.stringify(stateObject)); if('delta' in stateObject.state && 'color' in stateObject.state.delta){ var delta_state = stateObject.state.delta.color; bridge.led(delta_state); console.log('received delta ' + ' on ' + thingName + ': ' + JSON.stringify(stateObject)); clientTokenUpdate = thingShadows.update('pi2_01', { "state": { "reported": { "color": delta_state } } }); }});
thingShadows.on('delta', function(thingName, stateObject) { var state = stateObject.state.color; bridge.led(state); console.log('received delta ' + ' on ' + thingName + ': ' + JSON.stringify(stateObject)); clientTokenUpdate = thingShadows.update('pi2_01', { "state": { "reported": { "color": state } } });});
thingShadows.on('timeout', function(thingName, clientToken) { console.log('received timeout ' + ' on ' + operation + ': ' + clientToken);});
Demo 2
Demo 3
湿度センサーRule EngineTopic
LED Device Shadow
var awsIot = require('aws-iot-device-sdk');var bridge = require('./bridge.js');
var thingShadows = awsIot.thingShadow({ keyPath: './certs/private.pem.key', certPath: './certs/certificate.pem.crt', caPath: './certs/root-CA.crt', clientId: 'pi2_01', region: 'ap-northeast-1'});
var clientTokenGet;var clientTokenUpdate;
thingShadows.on('connect', function() { thingShadows.register( 'pi2_01' ); setTimeout( function() { clientTokenGet = thingShadows.get('pi2_01'); }, 2000 ); setInterval(function() { var humidity = bridge.sensor(); console.log(humidity) thingShadows.publish('pi2_01', JSON.stringify(humidity)); }, 1000);});
センサーデータを収集/Device Shadowから LEDを操作
thingShadows.on('status', function(thingName, stat, clientToken, stateObject) { console.log('received ' + stat + ' on ' + thingName + ': ' + JSON.stringify(stateObject)); if('delta' in stateObject.state && 'color' in stateObject.state.delta){ var delta_state = stateObject.state.delta.color; bridge.led(delta_state); console.log('received delta ' + ' on ' + thingName + ': ' + JSON.stringify(stateObject)); clientTokenUpdate = thingShadows.update('pi2_01', { "state": { "reported": { "color": delta_state } } }); }});
thingShadows.on('delta', function(thingName, stateObject) { var state = stateObject.state.color; bridge.led(state); console.log('received delta ' + ' on ' + thingName + ': ' + JSON.stringify(stateObject)); clientTokenUpdate = thingShadows.update('pi2_01', { "state": { "reported": { "color": state } } });});
thingShadows.on('timeout', function(thingName, clientToken) { console.log('received timeout ' + ' on ' + operation + ': ' + clientToken);});
センサーデータを収集/Device Shadowから LEDを操作
// データの送受信のみの場合は device.publishdevice.publish('pi2_01', JSON.stringify(humidity));
// DeviceShadow使用時は thingShadows.publishthingShadows.publish('pi2_01', JSON.stringify(humidity));
# -*- coding: utf-8 -*-from __future__ import print_functionfrom __future__ import unicode_literalsfrom __future__ import absolute_importfrom __future__ import division
import jsonimport boto3
print('Loading function')
iot = boto3.client('iot-data')
def lambda_handler(event, context): print("Received event: " + json.dumps(event)) humidity = event['humidity'] if humidity < 40: color = 'blue' elif humidity >= 40 and humidity <= 70: color = 'green' else : color = 'red'
DeviceShadowを操作するLambda Function
try: shadow_stream = response = iot.get_thing_shadow( thingName='pi2_01' ) shadow_string = shadow_stream['payload'].read().decode('utf-8') shadow = json.loads(shadow_string) desired_color = shadow['state']['desired']['color'] if color != desired_color: payload = { "state": { "desired": { "color": color, } } } iot.update_thing_shadow( thingName='pi2_01', payload=json.dumps(payload) ) print('Update DeviceShadow delta: {}'.format(color)) else: print('DeviceShadow has been updated') return except Exception as e: print(e) print('Error') raise e
Demo 3
気をつけたいところ
• DynamoDBにデータが入らない!?• AWS SDKに IoT関連のものが 2つある
DynamoDBにデータが入らない!?
DynamoDBにデータが入らない!?
• Python
• Node.js
• Java
AWS SDKに IoT関連のものが 2つある
まとめ• AWS IoTで簡単にセンサーデータをアップできるようになった。• Device Shadowでリモートからのデバイス制御がやりやすくなった。• この冬は風邪を引かなかった!
まとめ
• 家庭の課題解決から IoTを始めよう!