以device shadows與rules engine串聯實體世界
TRANSCRIPT
AWS Cloud Kata for Start-Ups and Developers
Hong Kong
Programming the Physical World with Device Shadows and Rules Engine Dickson Yue Solutions Architect, AWS
AWS Cloud Kata for Start-Ups and Developers
Interact with with unreliable connections thing Device Shadow
AWS Cloud Kata for Start-Ups and Developers
AWS IoT Device Shadows flow
Shadow
Thing 7. Device Shadow confirms state change
1. Device publishes current state
report {light: off}
3. App requests device’s current state
get {light : off}
4. App requests change the state desire {light : on} 5. Device Shadow syncs
updated state
delta {light : on}
6. Device publishes current state report {light : on}
2. Persist JSON data store
reported {light : off} desired{light : on}
reported {light : on}
App
AWS Cloud Kata for Start-Ups and Developers
AWS IoT Device Shadow - Simple Yet { "state" : { “desired" : { "light": “on” }, "reported" : { "light" : “off” }, "delta" : { "light" : “on” } }, "version" : 10 }
Device Report its current state to one or multiple shadows Retrieve its desired state from shadow
Mobile App
Set the desired state of a device Get the last reported state of the device Delete the shadow
Shadow Shadow reports delta, desired and reported states along with metadata and version
AWS Cloud Kata for Start-Ups and Developers
AWS IoT Device gateway
reported: {temp:27, humidity: 80%}
Light Amazon Alexa
Service AWS Lambda
Grove
Light Bulb Shadow
4. Update shadow desired: {light: off}
Environment Monitor
3. Switch off the light
2. Update shadow
Switch
1. Sensors update
MQTT MQTT over the WebSocket HTTP Alexa + Lambda
$$ charged by Prices are based on the number of messages published to AWS IoT (Publishing Cost), and the number of messages delivered by AWS IoT to devices or applications (Delivery Cost).
6. Update shadow reported: {light: off}
AWS Cloud Kata for Start-Ups and Developers
Create a thing AWSREGION='us-east-1’
THINGSNAME="lightbulb02”
POLICYNAME='smarthome-devices’
aws iot create-thing --thing-name $THINGSNAME --region $AWSREGION >things/thing-$THINGSNAME.json
CERTARN=$(aws iot create-keys-and-certificate --set-as-active --certificate-pem-outfile ./certs/$THINGSNAME-cert.pem --public-key-outfile ./certs/$THINGSNAME-publicKey.pem --private-key-outfile ./certs/$THINGSNAME-privateKey.pem --output text --query 'certificateArn' --region $AWSREGION)
aws iot attach-thing-principal --thing-name $THINGSNAME --principal $CERTARN --region $AWSREGION
aws iot attach-principal-policy --principal $CERTARN --policy-name $POLICYNAME --region $AWSREGION
aws iot list-thing-principals --thing-name $THINGSNAME --region $AWSREGION
1
2
3
4
AWS Cloud Kata for Start-Ups and Developers
AWS IoT Policy
{ "Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action":["iot:Publish"],
"Resource": ["arn:aws:iot:us-east-1:123456789012:topic/home/${iot:ClientId} "]
},
{
"Effect": "Allow",
"Action":["iot:Subscribe"],
"Resource": ["arn:aws:iot:us-east-1:123456789012:topic/home/*"]
},
{
"Effect": "Allow",
"Action": ["iot:Connect"],
"Resource": ["*"]
}
]
}
AWS Cloud Kata for Start-Ups and Developers
Load cert and private key Generate certivate with AWS IoT
certfile="../../certs/grove-cert.pem",
keyfile="../../certs/grove-privateKey.pem",
rootCA="../../certs/root.pem”
Copy the cert through SSH
JITR - Just In Time Certificate Registration
1. You will register and activate the CA certificate. 2. Use this certificate to create and sign the certificates you will use per device. 3. Let the device present the certificate to AWS and then activate it, i.e. through Lambda 4. Finally, use an AWS Lambda function to notify you when a new certificate is present to AWS.
It can also activate the certificate and handle any registration or initialization.
AWS Cloud Kata for Start-Ups and Developers
Connect through MQTT library import paho.mqtt.client as mqtt
def init():
global client
try:
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.clientid = clientid
client.tls_set( "../../certs/root.pem",
certfile="../../certs/grove-cert.pem",
keyfile="../../certs/grove-privateKey.pem", tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None )
client.connect("data.iot.us-east-1.amazonaws.com", 8883, 10)
client.loop_forever()
except:
print "Mqtt Unexpected error:", sys.exc_info()[0]
Do not duplicate your clientid
MQTT Event handler
Cert, Private key, Root CA
AWS Cloud Kata for Start-Ups and Developers
Connect through Python SDK from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
def init():
global client
try:
client = AWSIoTMQTTClient(clientid)
client.configureEndpoint(host, 8883)
client.configureCredentials(rootCAPath, privateKeyPath, certificatePath)
client.configureAutoReconnectBackoffTime(1, 32, 20)
client.configureDrainingFrequency(2) # Draining: 2 Hz
client.configureConnectDisconnectTimeout(10) # 10 sec
client.configureMQTTOperationTimeout(5) # 5 sec
client.connect()
thingLightbulb = client.createShadowHandlerWithName(thingLightbulbName, True) thingLightbulb.shadowRegisterDeltaCallback(lightbulbShadowCallback_Delta)
except:
print "Unexpected error at init:", sys.exc_info()[0]
Auto reconnection with progressive backoff Offline publish queue
AWS Cloud Kata for Start-Ups and Developers
Read sensor data from Grove try:
[ temp,hum ] = dht(dht_sensor_port,dht_sensor_type)
ppm = grovepi.analogRead(air_sensor)
aq = getairquality(ppm)
loudness = grovepi.analogRead(loudness_sensor)
light = grovepi.analogRead(light_sensor)
state = {
"temp" : temp,
"humidity" : hum,
"lightsensorvalue" : light,
"lightsensorresistance" : resistance,
"ppm" : ppm,
"airquality" : aq,
"loudness" : loudness,
"createdat" : nowstr
}
Extract sensor value
Prepare your message
AWS Cloud Kata for Start-Ups and Developers
Update shadow through MQTT state = {
"temp" : temp,
"humidity" : hum,
"lightsensorvalue" : light,
"lightsensorresistance" : resistance,
"ppm" : ppm,
"airquality" : aq,
"loudness" : loudness,
"createdat" : nowstr
}
msg = {
"state":{
"reported": state
}
}
topicshadow = "$aws/things/grove/shadow/update"
client.publish(topicshadow,json.dumps(msg),1)
Update shadow through publish a MQTT message
AWS Cloud Kata for Start-Ups and Developers AWS Cloud Kata for Start-Ups and Developers
Connect through JavaScript
AWS Cloud Kata for Start-Ups and Developers
Connect through JavaScript AWS.config.region = region;
AWS.config.credentials = new AWS.CognitoIdentityCredentials(
{ IdentityPoolId: identityPoolId }
);
credentials.get(
function(err) {
if(err) {var requestUrl = SigV4Utils.getSignedUrl(
'wss', c.AWS.iotEndpoint, '/mqtt', 'iotdata', c.AWS.iotRegion,
credentials.accessKeyId,
credentials.secretAccessKey,
credentials.sessionToken);
initClient(requestUrl);
});
Get credential through Cognito
With temp access token
Get signed url
AWS Cloud Kata for Start-Ups and Developers
Connect through JavaScript function initClient(requestUrl) {
var clientId = String(Math.random()).replace('.', '');
var client = new Paho.MQTT.Client(requestUrl, clientId);
mqttClient = client;
var connectOptions = {
onSuccess: function() {
client.subscribe(topiclightbulb);
client.subscribe(topicgrove);
},
useSSL: true, timeout: 3, mqttVersion: 4,
onFailure: function() { console.error('connect failed'); }
};
client.connect(connectOptions);
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
}
Signed url
MQTT Event handler
AWS Cloud Kata for Start-Ups and Developers
Update shadow through MQTT function updateLightShadow(state) {
lightstate = state;
msg = "{\"state\": {\"desired\" : { \"light\":\"" + lightstate + "\" }}}";
topicshadow = topiclightbulbUpdate;
console.log(msg);
mqttClient.send(topicshadow, msg);
}
AWS Cloud Kata for Start-Ups and Developers
Button Control
Click +
Publish a msg to a topic +
Rules +
Trigger Lambda
AWS Cloud Kata for Start-Ups and Developers
Update shadow through Lambda var AWS = require('aws-sdk'); var config = {iotendpoint: 'A1OMFFL4UASE1E.iot.us-east-1.amazonaws.com'};
var iotdata = new AWS.IotData({endpoint:config.iotendpoint});
var newstate = reported.light === "on"? "off" : "on";
var state = {
"state" : {
"desired" :{
"light" : newstate
}
}
}
var params = {
payload: JSON.stringify(state),
thingName: thingName
};
iotdata.updateThingShadow(params, function(err, data) {
callback(data);
});
Update shadow through publish a AWS SDK Flip the switch
Prepare your state
AWS Cloud Kata for Start-Ups and Developers AWS Cloud Kata for Start-Ups and Developers
Bind a Lambda function with your skill
AWS Cloud Kata for Start-Ups and Developers
Update shadow through Lambda if ("AskLightControlIntent" === intentName) {
handleLightControlIntent(intent, session, callback);
}
function handleLightControlIntent(intent, session, callback) {
var switchSlot = intent.slots.Switch;
var sw = "";
if(switchSlot)
sw = switchSlot.value;
speechOutput = "The light is now " + sw +".";
var data = sw=="on" ? LightblubShadow.on : LightblubShadow.off;
var next = function(){
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession)); }
updateShadow("lightbulb",JSON.stringify(data),next);
Handle the corresponding intent
AWS Cloud Kata for Start-Ups and Developers
Extracting the value from messages
• Filter messages with certain criteria • Move messages to other topics • Move messages to other systems • Transform the payload of messages • Predict messages based on trends • React based on messages
AWS Cloud Kata for Start-Ups and Developers
But how? Highly available?
Scalable?
Easy to operate?
Easy to change?
Easy to implement? instance database
AWS Cloud Kata for Start-Ups and Developers
AWS IoT rules engine
predict, republish
Amazon Machine Learning
index
archive, analyze
Amazon DynamoDB
AWS Lambda
Amazon Redshift
process
AWS Cloud Kata for Start-Ups and Developers
AWS IoT - SQL Reference
SELECT DATA FROM TOPIC WHERE FILTER
• Like scanning a database table • Default source is an MQTT topic EXAMPLES: • FROM mqtt(‘my/topic’) • FROM mqtt(‘my/wildcard/+/topic’) • FROM (‘my/topic’)
AWS Cloud Kata for Start-Ups and Developers
Rules Engine
• Familiar SQL syntax • SELECT * FROM topic WHERE filter
• Functions • String manipulation (regex support) • Mathematical operations • Context based helper functions • Crypto support • UUID, timestamp, rand, etc.
• Execute Simultaneous Actions
AWS Cloud Kata for Start-Ups and Developers
Secure Pub/Sub broker
Rules
Log {1,2,3,4}
Monitoring DB {1,2,3,4}
Alarm {4}
blue/1 {temp:15} blue/2 {temp:16} blue/3 {temp:12} blue/4 {temp:40}
temp = *
temp = select temp, lux
temp > 30
temp = * Search {1,2,3,4}
AWS Cloud Kata for Start-Ups and Developers
ES Index PUT awsiot-grove{
"mappings": {
"grove": {
"properties": {
"temp": { "type": "double" },
"humidity": { "type": "double“ },
"lightsensorvalue": { "type": "double“ },
"lightsensorresistance": { "type": "double“ },
"createdat": { "type": "date","format" : "yyyy-MM-dd HH:mm:ss" }, "time": { "type": "date" },
"timestamp": { "type": "date" }
}
}
}
}
AWS Cloud Kata for Start-Ups and Developers
Get Started with AWS IoT Device SDK
C-SDK (Ideal for embedded
OS)
JavaScript-SDK (Ideal for Embedded
Linux Platforms)
Arduino Library (Arduino Yun)
Mobile SDK (Android and iOS)
Java-SDK Python
AWS Cloud Kata for Start-Ups and Developers
Key take away
• Program with Shadows • Nodejs, Python, JavaScript • MQTT library vs AWS SDK • Cert vs Cognito • Message routing Rules Engine configuration • Elasticsearch integration