AWS re:Invent 2016: NEW LAUNCH! Lambda Everywhere (IOT309)

Post on 06-Jan-2017

246 views 0 download

Transcript of AWS re:Invent 2016: NEW LAUNCH! Lambda Everywhere (IOT309)

© 2016, Amazon Web Services, Inc. or its Affiliates. All rights reserved.

Marc Brooker, Principal Engineer, AWS

30 November 2016

IOT309

NEW LAUNCH! Lambda Everywhere

What to Expect from the Session

• Design a single architecture spanning devices and the cloud

• Build AWS Lambda functions for the cloud, and for AWS Greengrass

• Work through an example architecture

• Lots of Python Code

Part One: What We’re Building

Fleet of Sensors

OperatorAmazon

SNS

AWS

LambdaAWS

IoT

AWS

Greengrass

Core

Amazon

DynamoDB

Example: Combining Readings From Multiple Sensors

Temperature

Humidity

Example: Combining Readings From Multiple Sensors

Temperature

Humidity

Part Two: The Cloud

AWS Lambda lets you run code without provisioning

or managing servers.

Just upload your code and Lambda takes care of everything required to run and scale your code with high availability.

You can set up your code to automatically trigger from other AWS services or call it directly from any web or mobile app.

Fleet of Sensors

OperatorAmazon

SNS

AWS

LambdaAWS

IoT

AWS

Greengrass

Core

Amazon

DynamoDB

IoT Event Loading

# Extract the building ID, temp. and humidity from the IoT event

# Our GGC packs its data up in JSON form

building = event["building_id"]

new_temp = float(event["max_temp"])

new_humidity = float(event["max_humidity"])

Lambda Performance Tip

import boto3

print 'Runs Once On Container Start'

dynamodb = boto3.client('dynamodb')

def lambda_handler(event, context):

print 'Runs on every invoke’

This code runs once per container start.

This code runs every invoke.

Lambda Performance Tip

import boto3

print 'Runs Once On Container Start'

dynamodb = boto3.client('dynamodb')

def lambda_handler(event, context):

print 'Runs on every invoke’

Create Your Clients Here

Not Here

# Load the building configuration from DynamoDBdef load_building_config_from_dynamodb(building_id):

response = config_table.get_item(Key = { 'building' : building_id } )

if 'Item' in response:# The building configuration exists, use itreturn (float(response['Item']['min_temp']),

float(response['Item']['max_humidity']))

else:# Use default values if no config existsreturn (default_min_temp, default_max_humidity)

Loading Config and History with Amazon DynamoDB

# Apply the alarm threshold logicdef should_alarm(temp, humidity, config):

return temp < config[0] and humidity > config[1]

# Load configuration and previous values from DynamoDBlast_temp, last_humidity = load_previous_from_dynamodb(building)config = load_building_config_from_dynamodb(building)

# Send an SNS notification if the values move over the thresholdif should_alarm(new_temp, new_humidity, config)

and not should_alarm(last_temp, last_humidity, config):send_sns_notification(building, new_temp, last_temp,

new_humidity, last_humidity)

Apply the Latching Business Logic

# Send a notification to the SNS topic, formatted as JSONdef send_sns_notification(building, t, last_t, h, last_h):

notification = json.dumps({ "building" : building,"current_values" : { "temp" : t, "humidity" : h },"last_values" : { "temp" : last_t, "humidity" : last_h }

})

sns.publish(TopicArn = topic_arn,MessageStructure = 'json',Message = json.dumps({ 'default' : notification })

)

Sending a Notification with Amazon SNS

Fleet of Sensors

OperatorAmazon

SNS

AWS

LambdaAWS

IoT

AWS

Greengrass

Core

Amazon

DynamoDB

AWS

Lambda

Amazon

Redshift

Part Three: Local Filtering

Fleet of Sensors

OperatorAmazon

SNS

AWS

LambdaAWS

IoT

AWS

Greengrass

Core

Amazon

DynamoDB

Fleet of Sensors

OperatorAmazon

SNS

AWS

LambdaAWS

IoT

AWS

Greengrass

Core

Amazon

DynamoDB

Loading and Parsing A Shadow

def current_record_data(cls):

try:

# The get_thing_shadow API loads a shadow

shadow = iot_client.get_thing_shadow(thingName=cls.name)['payload']

record_shadow = json.loads(shadow)

version = record_shadow['state'].get('version', 0)

return record_value, last_push_time, version

except ShadowError as e:

# The shadow doesn't exist yet, so return some default values

if str(e).startswith('Request for shadow state'):

return None, None, 0

else:

raise e

Lambda

Function

MQTT

TopicIoT

Sensor

Shadow to Record

High Water Mark

Shadow to Record

Last Publish Time

MQTT Topic

Publish to AWS IoT

AWS

IoT

Updating a Shadow

def update_shadow(self):# Loop until shadow state update successfully occurswhile True:current_shadow, last_push, version = self.current_record_data()

if not self.should_update(self, current_shadow):return False

new_shadow = self.new_shadow(version)if self._update_shadow(new_shadow):return True

# Sleep with jittertime.sleep(random.random())

Publish an MQTT Message to the Cloud

def push_record(self):# Loop until shadow state update is successfulwhile True:record, last_push_time, version = self.current_record_data()

if not self._should_push_record(last_push_time):# Another Lambda has already posted. Job done!return False

# Try to update the thing shadowif self._try_update_shadow(version):# If that works, publish the messageiot_client.publish(topic=self.record_reporter_topic,

payload=str(record))return True

# Sleep for a short while, with jittertime.sleep(random.random())

Lambda

Function

MQTT

TopicIoT

Sensor

Shadow to Record

High Water Mark

Shadow to Record

Last Publish Time

MQTT Topic

Publish to AWS IoT

AWS

IoT

Shadow with

Configuration

Greengrass API Highlights

• Shadow API• Communication with devices

• Communication with AWS IoT

• Small local database

• Messaging API• Communication with devices

• Communication with AWS IoT

In the Cloud and in Greengrass: What’s The Same

• Python 2.7 support

• Event-based programming model

• Container lifecycle

What’s Different in Greengrass

• Local event sources (MQTT message routing)

• IoT-centric deployment and operational tools

• Authentication and authorization designed for devices

• ARM and x86 support

Thank you!

Remember to complete your evaluations!