

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# AWS Lambda 与 MQTT 一起使用
<a name="tracking-using-mqtt-with-lambda"></a>

虽然在将设备位置数据发送到 Amazon Location 进行跟踪时不再需要使用 AWS Lambda ，但在某些情况下，您可能仍想使用 Lambda。例如，如果您想在将设备位置数据发送到 Amazon Location 之前自己处理设备位置数据。以下主题介绍如何在消息发送到您的跟踪器之前使用 Lambda 处理消息。有关此模式的更多信息，请参阅[参考架构](https://d1.awsstatic.com/architecture-diagrams/ArchitectureDiagrams/amazon-location-service-ra.pdf)。

**Topics**
+ [先决条件](#mqtt-prerequisite-with-lambda)
+ [创建 Lambda 函数](#mqtt-with-lambda-create-lambda)
+ [创建 AWS IoT Core 规则](#mqtt-create-iot-rule-with-lambda)
+ [在控制台中测试你的 AWS IoT Core 规则](#mqtt-test-iot-rule-with-lambda)

## 先决条件
<a name="mqtt-prerequisite-with-lambda"></a>

在开始追踪之前，必须先[创建跟踪器资源](start-tracking.md)。要创建追踪器资源，您可以使用亚马逊定位控制台 AWS CLI、或亚马逊位置 APIs。

以下示例使用 Amazon Location Service 控制台创建跟踪器资源：

1. 打开 Amazon Location Service 控制台，网址为[https://console.aws.amazon.com/location/](https://console.aws.amazon.com/location/home)。

1. 在左侧导航窗格中，选择**跟踪器**。

1.  选择**创建跟踪器**。

1. 填写以下选框：
   + **名称** – 输入一个最多包含 100 个字符的唯一名称。有效条目包括：字母数字字符、连字符和下划线。例如 *MyTracker*。
   + **描述** – 输入可选描述。例如 *Tracker for storing AWS IoT Core device positions*。
   + **位置筛选** – 选择要用于位置更新的筛选。例如，**基于精度的筛选**。

1. 选择**创建跟踪器**。

## 创建 Lambda 函数
<a name="mqtt-with-lambda-create-lambda"></a>

要在 AWS IoT Core 和 Amazon Location Service 之间建立连接，您需要一个 AWS Lambda 函数来处理由转发的消息 AWS IoT Core。此函数将提取所有位置数据，将其格式化为 Amazon Location Service，然后通过 Amazon Location 跟踪器 API 提交。您可以通过 AWS Lambda 控制台创建此函数，也可以使用 AWS Command Line Interface (AWS CLI) 或 AWS Lambda APIs。

要使用控制台创建 Lambda 函数，将位置更新发布到 Amazon Location，请执行以下操作：

1. 打开 AWS Lambda 控制台，网址为[https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/home)。

1. 从左侧导航窗格中，选择**函数**。

1.  选择**创建函数**，并确保选择**从头开始创作**。

1. 填写以下选框：
   + **函数名称** – 输入您的函数的唯一名称。有效条目包括字母数字字符、连字符和下划线，不带空格。例如 *MyLambda*。
   + **运行时间**-选择*Python 3.8*。

1. 选择**创建函数**。

1. 选择 **代码** 选项卡以打开编辑器。

1. 用以下代码替换 `lambda_function.py` 中的占位符代码，将分配给 `TRACKER_NAME` 的值替换为您作为[先决条件](#mqtt-prerequisite-with-lambda)创建的跟踪器的名称。

   ```
   from datetime import datetime
   import json
   import os
   
   import boto3
   
   # Update this to match the name of your Tracker resource
   TRACKER_NAME = "MyTracker"
   
   """
   This Lambda function receives a payload from AWS IoT Core and publishes device updates to 
   Amazon Location Service via the BatchUpdateDevicePosition API.
   
   Parameter 'event' is the payload delivered from AWS IoT Core.
   
   In this sample, we assume that the payload has a single top-level key 'payload' and a nested key
   'location' with keys 'lat' and 'long'. We also assume that the name of the device is nested in
   the payload as 'deviceid'. Finally, the timestamp of the payload is present as 'timestamp'. For
   example:
   
   >>> event
   { 'payload': { 'deviceid': 'thing123', 'timestamp': 1604940328,
     'location': { 'lat': 49.2819, 'long': -123.1187 },
     'accuracy': {'Horizontal': 20.5 },
     'positionProperties': {'field1':'value1','field2':'value2'} }
   }
   
   If your data doesn't match this schema, you can either use the AWS IoT Core rules engine to
   format the data before delivering it to this Lambda function, or you can modify the code below to
   match it.
   """
   def lambda_handler(event, context):
     update = {
         "DeviceId": event["payload"]["deviceid"],
         "SampleTime": datetime.fromtimestamp(event["payload"]["timestamp"]).strftime("%Y-%m-%dT%H:%M:%SZ"),
         "Position": [
           event["payload"]["location"]["long"],
           event["payload"]["location"]["lat"]
           ]
       }
     if "accuracy" in event["payload"]:
         update["Accuracy"] = event["payload"]['accuracy']
     if "positionProperties" in event["payload"]:
         update["PositionProperties"] = event["payload"]['positionProperties']
    
     client = boto3.client("location")
     response = client.batch_update_device_position(TrackerName=TRACKER_NAME, Updates=[update])
   
     return {
       "statusCode": 200,
       "body": json.dumps(response)
     }
   ```

1. 选择**部署**以保存您更新的函数。

1. 选择**配置**选项卡。

1. 在**权限**部分，选择超链接的角色名称以授予 Amazon Location Service 对您的 Lambda 函数的权限。

1. 在角色的**摘要**页面中，选择**添加权限**，然后从下拉列表中选择**创建内联策略**。

1. 选择 **JSON** 选项卡，并用以下文档覆盖策略。这允许您的 Lambda 函数更新由所有区域的所有跟踪器资源管理的设备位置。

   ```
   {
     "Version": "2012-10-17",		 	 	 
     "Statement": [
       {
         "Sid": "WriteDevicePosition",
         "Effect": "Allow",
         "Action": "geo:BatchUpdateDevicePosition",
         "Resource": "arn:aws:geo:*:*:tracker/*"
       }
     ]
   }
   ```

1. 选择**查看策略**。

1. 输入策略名称。例如 *AmazonLocationTrackerWriteOnly*。

1. 选择**创建策略**。

您可以根据需要修改此函数代码，以适应您自己的设备消息架构。

## 创建 AWS IoT Core 规则
<a name="mqtt-create-iot-rule-with-lambda"></a>

接下来，创建一条 AWS IoT Core 规则，将设备的位置遥测数据转发给该 AWS Lambda 函数，以便转换并发布到 Amazon Location Service。提供的示例规则假设设备有效负载的任何必要转换均由您的 Lambda 函数处理。您可以通过 AWS IoT Core 控制台、 AWS Command Line Interface (AWS CLI) 或创建此规则 AWS IoT Core APIs。

**注意**  
虽然 AWS IoT 控制台处理 AWS IoT Core 允许调用您的 Lambda 函数所需的权限，但如果您从 AWS CLI 或 SDK 创建规则，则必须[配置策略以授予权限](https://docs.aws.amazon.com/iot/latest/developerguide/lambda-rule-action.html#lambda-rule-action-requirements)。 AWS IoT

** AWS IoT Core 使用控制台创建**

1. 登录 AWS IoT Core 控制台，网址为[https://console.aws.amazon.com/iot/](https://console.aws.amazon.com/iot/home)。

1. 在左侧导航窗格中，展开**行动**，并选择**规则**。

1. 选择**创建规则**以启动新规则向导。

1. 为您的规则输入名称和描述。

1. 对于**规则查询语句**，请更新 `FROM` 属性，以引用至少一台设备正在发布包含位置的遥测的主题。如果您正在测试解决方案，则无需进行任何修改。

   ```
   SELECT * FROM 'iot/topic'
   ```

1. 在**设置一个或多个操作**下，选择**添加操作**。

1. 选择**向 Lambda 函数发送消息**。

1. 选择 **Configure action**。

1. 从列表中选择您的 Lambda 函数。

1. 选择**添加操作**。

1. 选择 **Create rule**（创建规则）。

## 在控制台中测试你的 AWS IoT Core 规则
<a name="mqtt-test-iot-rule-with-lambda"></a>

如果当前没有设备发布包含位置信息的遥测数据，则可以使用 AWS IoT Core 控制台测试您的规则和此解决方案。控制台有一个测试客户端，您可以在其中发布一条示例消息来验证解决方案的结果。

1. 登录 AWS IoT Core 控制台，网址为[https://console.aws.amazon.com/iot/](https://console.aws.amazon.com/iot/home)。

1. 在左侧导航窗格中，展开**测试**，然后选择 **MQTT 测试客户端**。

1. 在 “**发布到主题**” 下，将**主题名称**设置为*iot/topic*（或您在 AWS IoT Core 规则中设置的主题的名称，如果不同），然后为**消息负载**提供以下内容。将时间戳*1604940328*替换为最近 30 天内的有效时间戳（任何超过 30 天的时间戳都将被忽略）。

   ```
   {
     "payload": {
       "deviceid": "thing123",
       "timestamp": 1604940328,
       "location": { "lat": 49.2819, "long": -123.1187 },
       "accuracy": { "Horizontal": 20.5 },
       "positionProperties": { "field1": "value1", "field2": "value2" }
     }
   }
   ```

1. 选择**发布**到主题来发送测试消息。

1. 要验证 Amazon Location Service 是否已收到该消息，请使用以下 AWS CLI 命令。如果您在设置过程中对其进行了修改，请将跟踪器名称和设备 ID 替换为您使用的跟踪器名称和设备 ID。

   ```
   aws location batch-get-device-position --tracker-name MyTracker --device-ids thing123
   ```