資料介紹
描述
大家好,我是 Ivan Fardin,我是羅馬 Sapienza 大學計算機科學工程碩士的學生,這個項目是作為物聯網 19-20課程的一部分而開發的。
在本文中,我將向您展示如何使用用戶設備的加速度傳感器根據人群感應技術收集的值來設置一個基于 IoT MQTT 的基于云的人類活動識別 Web 應用程序系統。
概述
該項目包括:
假設運動最多為 0.5 Hz(即每分鐘 30 步),理論上 1 Hz(即每秒 1 條消息)的采樣頻率足以識別用戶是否靜止不動。
所有代碼都可以在GitHub 存儲庫中找到。
建筑學
讓我們通過分析圖中的每個組件開始詳細介紹。
用戶可以通過以下網站上的瀏覽器訪問Web 應用程序,并且該應用程序獨立于操作系統,因此可以將手機、平板電腦、臺式機和筆記本電腦等不同設備連接到后端。它利用通用傳感器 API從移動設備的加速傳感器收集數據。通用傳感器 API 是一種傳感器框架,可在安全上下文(即 HTTPS)中將傳感器設備暴露給 Web 平臺。
傳感器值或由此產生的人類活動通過MQTT (一種輕量級且被廣泛采用的針對特定主題的受限設備設計的消息傳遞協議)使用與網站訪問相關聯的唯一 ID(身份)傳輸到云基礎設施。
MQTT 是使用Eclipse Paho JavaScript Client實現的,這是一個用Javascript編寫的基于瀏覽器的 MQTT 客戶端庫,它使用 WebSockets(一種通信協議,通過單個 TCP/IP 連接提供全雙工通信通道)連接到 MQTT 代理。
為什么使用 WebSocket 上的 MQTT ?由于該應用程序是 Web 應用程序,因此它存在于瀏覽器中,并且基于 WebSocket 的 MQTT 允許將 MQTT 數據直接發送和接收到 Web 瀏覽器中。
通過 Paho 發送的消息取決于用戶選擇的模式來識別活動,它們是:
- 如果人類活動識別模型由云端執行,則為原始數據
- 如果人類活動識別模型由用戶設備執行,則產生的人類活動
后端是使用AWS IoT實現的,它在 Internet 連接的設備和 AWS 云之間提供安全的雙向通信。設備與 AWS 云之間的通信由AWS IoT 消息代理根據發布-訂閱模式進行處理。
AWS IoT 消息代理為設備和 AWS IoT 應用程序提供了一種安全機制,可以通過將消息從發布客戶端發送到訂閱客戶端來相互發布和接收連接 AWS IoT 客戶端的消息。客戶端通過在主題上發布消息來發送數據,并通過訂閱主題來接收消息。當消息代理接收到來自發布客戶端的消息時,它會將消息轉發給所有訂閱該主題的客戶端。
此外,AWS IoT 提供了創建規則的可能性,這些規則定義了一個或多個要根據 MQTT 消息主題執行的操作。通過這種方式,我通過創建一個規則來實現云計算,在該規則中,代理將來自 Web 應用程序設備的所有傳入消息轉發到指定的AWS Lambda函數。這會詳細說明傳入的數據并將它們插入到代表架構持久層的AWS DynamoDB表中。
最后,Web 應用程序連接到 AWS DynamoDB 服務,以根據所選模式檢索和顯示設備數據和最后一小時的結果活動,并連接到代理發送數據,如果啟用了云計算, 從 Lambda 函數接收實時數據。
?
AWS 配置
首先,如果您沒有 AWS 賬戶,您需要創建一個。作為一名學生,我有一個AWS 教育,它免費提供對云資源的有限訪問。
如果您像我一樣擁有 AWS 教育賬戶,請確保所選區域是 us-east-1(北弗吉尼亞),這是此類賬戶唯一可用的區域,否則后端將無法工作。
注冊或登錄后,請轉到下一部分。
動態數據庫
后端實施的一個良好起點可能是創建AWS DynamoDB表。
因此,在 AWS 控制臺中找到 DynamoDB 服務并單擊它。然后點擊創建表并填寫如下表格,然后按創建。
為了與 web 應用部分中的代碼保持一致,我將使用Id和dateTime但當然您可以將任何屬性作為分區和排序鍵,以及決定不使用排序鍵。
創建表后,您可以滾動概覽選項卡獲取關聯的 ARN
通過單擊項目選項卡,您可以查看表中存在哪些元素。
由于加速度傳感器的采樣頻率為 1 Hz,并且值會立即傳輸以進行實時識別,因此表格的大小將隨著使用而大幅增加。這可能是一個性能問題,但要記住 Web 應用程序的功能,我只需要持久性來顯示最后一小時的數據,因此我可以在這段時間間隔后刪除它們以提高性能。為此,DynamoDB 提供了生存時間(TTL) 功能,該功能允許定義表中的項目何時過期,以便可以自動從數據庫中刪除它們。
因此,在項目選項卡中單擊操作和管理 TTL。
在這里放置您決定用作 TTL 的屬性,然后單擊Continue
沒有什么比這更簡單了,您的數據庫已準備就緒。
?
拉姆達
既然你的數據庫已經準備好了,讓我們看看如何填充它。請記住,當 MQTT 消息到達AWS IoT Broker時,它會檢查主題是否與您選擇調用 Lambda 函數的主題匹配。AWS Lambda是一項計算服務,讓您無需預置或管理服務器即可運行代碼,并且僅在需要時執行您的代碼并自動擴展。
創建 Lambda 函數搜索并在 AWS 控制臺中選擇 Lambda 服務。
在其主頁中單擊創建功能
然后為它選擇一個名稱,作者從頭開始選項,因為我的實現非常簡單,以及編程語言(在我的例子中我選擇了Python 3.7 )。最后點擊創建函數
好的,現在您必須在編輯器中輸入以下代碼:
- 在邊緣計算的情況下,將在 DB 中插入與傳入 MQTT 消息對應的項目
- 在云計算的情況下,將根據傳入的MQTT消息中的值執行Human Activity Recognition的模型,在DB中插入相應的項目并將MQTT消息發送回客戶端以獲得實時結果
import json
import boto3
import time
dynamodb = boto3.resource('dynamodb', region_name='')
table = dynamodb.Table('')
def lambda_handler(event, context):
# Data expires after 1 hour (3600 s) and few minutes (400 s)
# Time in Unix epoch
ttl = int(time.time()) + 4000
# Check if edge computation
if "isStanding" in event:
table.put_item(
Item={
"Id": event["clientID"],
"dateTime": event["dateTime"],
"isStanding": event["isStanding"],
"computation": "edge",
"TTL": ttl
}
);
# Else cloud computation
else:
isStanding = True
x2 = event["x2"]
y2 = event["y2"]
z2 = event["z2"]
if((abs(x2 - event["x1"])*0.67 > 0.292) or
(abs(y2 - event["y1"])*0.7 > 0.145) or
(abs(z2 - event["z1"])*0.67 > 0.45)):
isStanding = False
clientID = event["clientID"]
table.put_item(
Item={
"Id": clientID,
"dateTime": event["dateTime"],
"x": str(x2), # DynamoDB does not support float type
"y": str(y2),
"z": str(z2),
"isStanding": isStanding,
"computation": "cloud",
"TTL": ttl
}
);
client = boto3.client('iot-data', region_name='')
# Change topic, qos and payload
response = client.publish(
topic = "" + clientID,
qos = 1,
payload = json.dumps({
"x": x2,
"y": y2,
"z": z2,
"isStanding": isStanding
})
)
?
認知和 IAM
現在,您需要創建一個AWS Cognito Identity Poll,授予用戶訪問 DynamoDB 服務和使用 AWS IoT 的 MQTT 操作的權限。
在 AWS 控制臺中搜索并選擇 Cognito 服務。
在其主頁中,按Create Identity Poll按鈕并填寫如下表格,然后單擊Create Pool ,然后單擊Allow 。
因此,單擊示例代碼選項卡以查看您的池 ID。
現在移動到IAM 服務頁面并單擊角色
在這里搜索剛剛創建的新的未經授權的 Cognito 角色并單擊它。
然后按附加策略按鈕
并搜索DynamoDBFullAccess ,選擇它并按下附加策略按鈕。
您的Cognito 身份投票現已準備好用于訪問您的 DynamoDB。
要完成,您必須創建并附加 IoT 策略,以執行 MQTT 消息的連接、訂閱、發布等操作。
要創建策略,請再次單擊附加策略按鈕,然后單擊創建策略( IAM步驟 3 和 4 的圖片可能很有用)。
在這里移動JSON選項卡
并在編輯器中粘貼以下 JSON,將區域、帳戶 ID 和主題字段替換為您的
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:Connect"
],
"Resource": [
"arn:aws:iot:::client/${iot:ClientId}"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Publish",
"iot:Receive"
],
"Resource": [
"arn:aws:iot:::topic/"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Subscribe"
],
"Resource": [
"arn:aws:iot:::topicfilter/"
]
}
]
}
然后,按Review policy并插入策略名稱和描述,然后單擊Create policy 。
最終重復 IAM 步驟 3 和 4 以將此新策略附加到未經授權的角色。
大功告成,您的 Cognito Identity Poll 已準備好用于訪問您的 DynamoDB 和 IoT Core。
?
物聯網核心
您幾乎已經完成了后端的設置,只是錯過了使用AWS IoT Core創建事物對象的過程。
在 AWS 控制臺中找到 IoT Core 服務并單擊它。
在這里,您必須將您的設備連接到平臺,因此請轉到Onboard并單擊Onboard a device中的Get started 。
然后選擇您連接到 AWS IoT 的方式,在本例中,我使用Linux平臺和Java編程語言,然后按 N ext 。
輸入你的東西的名字,然后繼續
然后下載證書和私鑰和公鑰,然后進行下一步。
您將在此處顯示配置和測試設備的教程,因此請按完成。你的東西已經創建了:)
之后,記下唯一標識您的事物的Amazon 資源名稱(ARN) 中的區域和賬戶 ID 。
ARN 具有以下一般格式:
- arn:partition:service:region:account-id:resource-id
- arn:partition:service:region:account-id:resource-type/resource-id
- arn:partition:service:region:account-id:resource-type:resource-id
因此,從 IoT Core 初始頁面轉到Things ,選擇新創建的并單擊它。
單擊設置并記下您的自定義端點,該端點允許您通過 REST API 連接到 AWS IoT(稍后將非常有用)。
現在您需要編輯在創建事物時生成的策略,以允許您的客戶端通過 MQTT 連接并與代理通信。
因此,從 IoT Core 初始頁面轉到Secure ,然后轉到Policies ,然后單擊與您的事物關聯的策略
在此處單擊Edit policydocument 并重用 IAM 控制臺中使用的 JSON 將區域和賬戶 ID 字段替換為您之前使用的字段
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:Connect"
],
"Resource": [
"arn:aws:iot:::client/${iot:ClientId}"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Publish",
"iot:Receive"
],
"Resource": [
"arn:aws:iot:::topic/"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Subscribe"
],
"Resource": [
"arn:aws:iot:::topicfilter/"
]
}
]
}
在哪里:
- ${iot:ClientId}變量表示用于連接到 AWS IoT Core 消息代理的客戶端ID
- *是主題名稱的通配符,相當于 MQTT 協議中的 # 通配符
現在,您必須向代理添加一條規則,以在傳入消息發布到指定主題時調用之前定義的 Lambda 函數。記下主題,稍后您將使用它。
為此,請轉到Act并按Create a rule按鈕。然后使用規則名稱和描述以及將過濾有關主題的傳入消息的 SQL 查詢填寫表格
滾動頁面并按添加操作按鈕為規則設置操作
并選擇向 Lambda 函數發送消息。
然后點擊頁面底部的Configure action ,選擇之前創建的函數
最后,單擊添加操作,然后單擊創建規則以得出結論:您的后端終于準備好了 :)
?
加速度計網絡應用程序
一旦您設置了基于云的后端,就該進行具有雙重作用的 Web 應用程序開發:生成和顯示數據。如果選擇邊緣計算,它還必須在本地處理數據。
要實現這一點,您需要一些HTML5和Javascript的基礎知識(也可以選擇CSS )。
讓我們從index.html文件開始,該文件包含 Javascript 可以使用的元素。
首先,您必須導入可選的 CSS 文件styles.css以及必要的SDK和腳本,包括AWS和Paho MQTT的那些。
html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pixeden-stroke-7-icon@1.2.3/pe-icon-7-stroke/dist/pe-icon-7-stroke.min.css">
<link rel="stylesheet" href="css/styles.css">
<script src="js/main.js">script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js">script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.1">script>
<script src="https://cdn.jsdelivr.net/npm/hammerjs@2.0.8">script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom@0.7.7">script>
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.7.16.min.js">script>
<script src="js/aws.js">script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript">script>
<script src="js/pahoMQTTClient.js">script>
head>
然后,在我的實現的主體部分,我使用了兩個按鈕允許用戶在Cloud 和 Edge Computing之間進行選擇,另一個用于檢索最后一小時的數據
id="btns" class="buttonsAnimation"> id="cloudBtn" class="btn btn-primary btn-lg btn-custom">Cloud Computing id="edgeBtn" class="btn btn-primary btn-lg btn-custom">Edge Computing
id="historyBtn" class="hide"> class="btn btn-secondary btn-lg btn-custom">Show last hour values
在云計算的情況下顯示人類活動識別結果和加速度計值的段落
id="measure" class="measure hide">
和四張卡片,以顯示以下形式的最后一小時值和活動(當然具有不同的 ID)
"historyChart" class="chart hide"> <div class="card"> <div class="card-body"> <div class="stat-widget-five"> <div class="stat-icon dib green-color"> <i class="pe-7s-graph2">i> div> <div class="stat-content"> <div class="dib"> <div class="stat-text">History Chartdiv> div> div> div> <canvas id="historyCanvas">canvas> div> div> </div> ... html>
我省略了一些不是成功完成任務的基本元素,但如果您有興趣,可以在我的GitHub 存儲庫中找到這些元素。
好吧,現在是時候討論由三個 Javascript 文件組成的 Web 應用程序的邏輯了:
- aws.js
- pahoMQTTClient.js
- main.js
第一個包含兩個函數,用于在具有 AWS IoT Core 的 Web 應用程序中通過 WebSocket 協議使用 MQTT,以便使用AWS Signature Version 4指定憑證。
第二個是一個 Javascript 類,它使用 WebSockets 執行與服務器的連接。此外,它還提供訂閱或取消訂閱 MQTT 主題、發布和接收 MQTT 消息以及與服務器斷開連接的功能。實現非常簡單,有關 Paho MQTT 的更多信息可以在官方頁面上閱讀。
類構造函數在輸入中有兩個參數:
- 執行 WebSocket 連接的請求 URL
- 在 MQTT 通道中唯一標識客戶端的客戶端 ID。
class PahoMQTTClient {
constructor(requestUrl, clientId) {
this.requestUrl = requestUrl;
this.clientId = clientId;
this.client = null;
this.isConnected = false;
}
...
}
為了將客戶端連接到服務器,我編寫了以下函數,它接收兩個回調作為參數,當連接成功或失敗時以及訂閱主題后收到 MQTT 消息時將調用它們。連接是使用SSL和可用于 AWS IoT 的更新版本的 MQTT 執行的。請注意,在連接選項中還指定了訂閱后傳入消息的回調,我添加了接收回調。
// Connect to the server
conn(callbackConnection, callbackReceive) {
this.client = new Paho.MQTT.Client(this.requestUrl, this.clientId);
var connectOptions = {
onSuccess: () => {
// Connect succeeded
console.log("onConnect: connect succeeded");
// In an arrow function "this" represents the owner of the function
// while in a regular function "this" represents the object that calls the function
this.isConnected = true;
callbackConnection();
},
useSSL: true,
timeout: 3,
mqttVersion: 4,
onFailure: function() {
// Connect failed
console.log("onFailure: connect failed");
callbackConnection();
}
};
// Set callback handlers
this.client.onConnectionLost = onConnectionLost;
this.client.onMessageArrived = onMessageArrived;
// Connect the client
this.client.connect(connectOptions);
// Called when the client loses its connection
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0)
console.log("onConnectionLost:" + responseObject.errorMessage);
}
// Called when a message arrives
function onMessageArrived(message) {
console.log("onMessageArrived:" + message.payloadString);
callbackReceive(message.payloadString);
}
}
訂閱和取消訂閱是很瑣碎的函數
// Subscribe to a topic
sub(topic) {
console.log("Subscribing on topic " + topic);
this.client.subscribe(topic);
}
// Unsubscribe to a topic
unsub(topic) {
console.log("Unsubscribing on topic " + topic);
this.client.unsubscribe(topic);
}
以及發布的
// Publish a message on a topic
pub(message, topic) {
console.log("Publishing message on topic " + topic);
// QOS = 0 => Best effort, retained = false => Message delivered only to current subscriptions
this.client.send(topic, message, 0, false);
}
我們錯過與 AWS 后端連接的最后一步是提供憑證。我們可以直接使用IAM的
var host = "", region = "";
var credentials = new AWS.Credentials("", "", "");
var requestUrl = SigV4Utils.getSignedUrl(host, region, credentials);
或認知
// Initialize Amazon Cognito credentials provider
AWS.config.region = '';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: '',
});
// Obtain credentials
AWS.config.credentials.get(function(){
// Credentials will be available when this function is called
var host = "";
var requestUrl = SigV4Utils.getSignedUrl(host, AWS.config.region, AWS.config.credentials);
...
});
選擇哪一個?Cognito 當然是因為我不想公開我的憑據。
因此在main.js文件中,當獲取憑證時,使用上述 Javascript 文件的功能執行 WebSocket 上的 MQTT 連接
var uuid = createUUID();
var mqttClient = null;
// Initialize Amazon Cognito credentials provider
AWS.config.region = '';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: '',
});
// Obtain credentials
AWS.config.credentials.get(function(){
// Credentials will be available when this function is called
var host = "";
var requestUrl = SigV4Utils.getSignedUrl(host, AWS.config.region, AWS.config.credentials);
mqttClient = new PahoMQTTClient(requestUrl, uuid);
mqttClient.conn(callbackConnection, callbackReceive);
});
這兩個回調函數非常簡單,但由于操作是異步的,所以是必要的。第一個通知全局環境連接嘗試已結束,第二個用于在啟用云計算時接收 MQTT 數據實時顯示給用戶。
// Callback for the MQTT client connection
function callbackConnection() {
fired = true;
// Check if the callback is invoked after that a button is pressed (slow connection)
if(cloudBtnActivated || edgeBtnActivated)
main();
}
// Callback for the MQTT client when a message is received after subscription
function callbackReceive(msg) {
if(!cloudBtnActivated) return;
msg = JSON.parse(msg);
setMeasureText('x: ' + msg.x + '
y: ' + msg.y + '
z: ' + msg.z + "
" + (msg.isStanding ? "You're standing" : "You're moving"));
}
其中cloudBtnActivated和edgeBtnActivated是兩個全局標志,分別表示是否激活了云計算按鈕或邊緣計算按鈕。
Web 應用程序的一個關鍵軟件組件由通用傳感器 API構成,它允許在上下文安全 (HTTPS) 時從用戶移動設備的加速度計傳感器收集數據。
用法很簡單,但是要讀取傳感器我們需要用戶的權限,所以首先檢查它是否被授予
navigator.permissions.query({ name: "accelerometer" }).then(result => {
if (result.state != 'granted') {
setMeasureText("Sorry, we're not allowed to access sensors on your device");
return;
}
start();
}).catch(err => {
setMeasureText("Integration with Permissions API is not enabled");
});
如果成功,調用 start 函數,該函數將創建讀取數據的 Javascript 對象
var accelerometer = null;
var topic = "" + uuid;
function start() {
if(accelerometer != null) {
accelerometer.start();
return;
}
try {
// For cloud computing
mqttClient.sub("" + uuid);
// Read once per second
accelerometer = new Accelerometer({ frequency: 1 });
accelerometer.addEventListener('error', errorListener);
accelerometer.addEventListener('reading', readListener);
accelerometer.start();
} catch (error) {
// Handle construction errors
setMeasureText(error.message);
}
}
如架構部分所述,我以 1 Hz 的頻率采樣并立即訂閱該主題以接收云計算結果消息。請注意,try代碼塊在應用程序的整個生命周期中執行一次,以避免多次創建。
錯誤監聽器非常簡單;它只是在應顯示 HAR 結果的區域顯示錯誤消息
function errorListener(event) {
// Handle runtime errors
setMeasureText(event.error.message);
}
相反,讀取偵聽器更有趣,因為除了在兩種模式下發送 MQTT 消息之外,它還包含傳感器值的處理和 HAR 結果的后續顯示(在邊緣計算的情況下)。
function readListener(event) {
var now = { x:event.target.x, y:event.target.y, z:event.target.z };
values.push(now);
// Cloud-based Deployment
if(cloudBtnActivated && values.length > 1) {
mqttClient.pub(createJsonString(values), topic);
values.shift();
}
// Edge-based Deployment
else if(edgeBtnActivated && values.length > 1) {
var check = isStanding(now);
if(check)
setMeasureText('x: ' + event.target.x + '
y: ' + event.target.y + '
z: ' + event.target.z + "
You're standing");
else
setMeasureText('x: ' + event.target.x + '
y: ' + event.target.y + '
z: ' + event.target.z + "
You're moving");
mqttClient.pub(createJsonString(check), topic);
}
}
為了停止讀取,我編寫了一個簡單的函數,它不會消除傳感器對象(請記住 start 函數),但會清理專用于顯示 HAR 結果的區域。
function stop() {
if(accelerometer != null)
accelerometer.stop();
setMeasureText("");
}
好吧,讓我們看看HAR 模型中最期待的部分代碼。實際上,您在編寫 Lambda 函數時已經看到了它,但我沒有說任何關于它的內容。它是如何工作的?它對兩個連續的措施進行簡單檢查,以檢測用戶是否在移動。如果移動超過指定閾值,則結果是移動,否則不是。閾值和歸一化因子是根據經驗計算的,以盡量減少噪聲,結果非常好。
// Check if the user is standing (do side effect on values array removing the old element)
function isStanding(now) {
var before = values.shift();
// One decides for all
if((Math.abs(now.x - before.x)*0.67 > 0.292)
|| (Math.abs(now.y - before.y)*0.7 > 0.145)
|| (Math.abs(now.z - before.z)*0.67 > 0.45))
return false;
return true;
}
最后但同樣重要的是,要查看最后一小時的活動(如果啟用了云計算,還有傳感器值),您可以單擊顯示最后一小時的值,該值將對數據庫執行查詢以檢索數據,然后通過可縮放和可平移的圖表正確顯示它們。這些是使用Chart.js庫實現的,Hammer.js用于手勢識別,chartjs-plugin-zoom用于縮放和平移。
與 DynamoDB的連接是通過如下修改之前的憑證塊來執行的
var uuid = createUUID();
var mqttClient = null;
// Initialize Amazon Cognito credentials provider
AWS.config.region = '';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: '',
});
// Obtain credentials
AWS.config.credentials.get(function(){
// Credentials will be available when this function is called
var host = "";
var requestUrl = SigV4Utils.getSignedUrl(host, AWS.config.region, AWS.config.credentials);
mqttClient = new PahoMQTTClient(requestUrl, uuid);
mqttClient.conn(callbackConnection, callbackReceive);
});
var docClient = new AWS.DynamoDB.DocumentClient();
由于 DynamoDB 是NoSQL數據庫,因此您必須使用以下語法
var params = {
TableName : "",
ProjectionExpression: ", ..., ",
KeyConditionExpression: "",
FilterExpression: "",
ExpressionAttributeNames:{
"": "",
...,
"": ""
},
ExpressionAttributeValues: {
"": "",
...,
"": ""
}
};
在哪里:
- KeyConditionExpression指定搜索條件:確定要從表或索引中讀取的項目的字符串。您必須將分區鍵名稱和值指定為相等條件
- FilterExpression確定應將查詢結果中的哪些項目返回給您
- ExpressionAttributeNames提供名稱替換。這是因為在 Amazon DynamoDB 中保留了一些單詞
- ExpressionAttributeValues提供值替換。這是因為你不能在任何表達式中使用文字,包括 KeyConditionExpression
- N >= M 和 N >= L
有關更多詳細信息,請參閱AWS DynamoDB 文檔。
因此,為了滿足該特征,查詢如下
var params = {
TableName : "",
ProjectionExpression: cloudBtnActivated ? "Id, #dt, x, y, z, isStanding" : "Id, #dt, isStanding",
KeyConditionExpression: "Id = :clientID and #dt between :start_h and :end_h",
FilterExpression: "computation = :computation",
ExpressionAttributeNames:{
"#dt": "dateTime"
},
ExpressionAttributeValues: {
":clientID": uuid,
":start_h": dateTime[1],
":end_h": dateTime[0],
":computation": cloudBtnActivated ? "cloud" : "edge"
}
};
docClient.query(params, function(err, data) {
if (err) {
// Error
} else {
// Success, do stuff
}
});
其中cloudBtnActivated是一個全局標志,用于表示云計算按鈕是否被激活。將功能分開就足夠了,因為它們是互斥的(即您不能同時使用兩者)。
警告:我使用Id作為分區鍵,而作為排序鍵dateTime ,它們必須與您在 DynamoDB 表中定義的一致。因此,如果您使用不同的密鑰,請在代碼中將我的密鑰替換為您的密鑰。
如果成功,您必須迭代響應對象以檢索數據并顯示它們
var sensorValues = [];
var dateTimes = [];
// Additional arrays for cloud computing
var xValues = [];
var yValues = [];
var zValues = [];
// Check if cloud computing
if(cloudBtnActivated)
data.Items.forEach(function(data) {
sensorValues.push(data.isStanding ? 0 : 1);
// DynamoDB does not support float type so, in the table, the value is stored as string
xValues.push(parseFloat(data.x));
yValues.push(parseFloat(data.y));
zValues.push(parseFloat(data.z));
dateTimes.push(data.dateTime);
});
else
data.Items.forEach(function(data) {
sensorValues.push(data.isStanding ? 0 : 1);
dateTimes.push(data.dateTime);
});
// Continue scanning if we have more data (per scan 1MB limitation)
if (typeof data.LastEvaluatedKey != "undefined") {
params.ExclusiveStartKey = data.LastEvaluatedKey;
docClient.scan(params, onScan);
}
if (sensorValues.length == 0)
setTimeout(function() {
alert("No data sent in the past hour");
}, 100);
else {
if(cloudBtnActivated) {
drawLineChart(dateTimes, sensorValues, "historyCanvas", "Activity Cloud Computing");
drawLineChart(dateTimes, xValues, "historyXCanvas", "x Cloud Computing");
drawLineChart(dateTimes, yValues, "historyYCanvas", "y Cloud Computing");
drawLineChart(dateTimes, zValues, "historyZCanvas", "z Cloud Computing");
}
else
drawLineChart(dateTimes, sensorValues, "historyCanvas", "Activity Edge Computing");
}
有關非重點代碼的更多詳細信息,請參閱我的GitHub 存儲庫。
就是這樣,享受它,如果您欣賞我的工作,請通過喜歡或評論告訴我。謝謝!
- 使用通用傳感器API的人類活動識別
- 基于谷歌云的物聯網系統——用戶活動識別
- 基于流量指紋的物聯網設備識別方法 13次下載
- 基于人類學習的網絡咨詢閱讀個性化模型 4次下載
- 物聯網工程概述課件下載 0次下載
- 基于深度信念網絡的實體識別算法 16次下載
- 2G網絡在物聯網中有怎么樣的應用 14次下載
- 物聯網到底是什么物聯網的簡介和三項關鍵技術詳細說明 16次下載
- 物聯網的體系架構的詳細資料概述 16次下載
- 物聯網實現的步驟有哪些 11次下載
- 《STM32物聯網實戰教程》單片機教學計算機網絡以及物聯網實戰概述 274次下載
- 物聯網的真正價值是什么?
- 物聯網應用與展望 115次下載
- 高校物聯網專業課程及實驗室建設初探 141次下載
- 高校物聯網人才培養探索 60次下載
- 物聯網的體系架構 989次閱讀
- 什么是車間物聯網技術? 1251次閱讀
- 如何使用移動傳感器產生的原始數據來識別人類活動 1074次閱讀
- 城市物聯網的發展情況分析 2014次閱讀
- 物聯網設備經常遇到怎樣的網絡問題 1225次閱讀
- 物聯網市場引發智能傳感技術新需求 665次閱讀
- 物聯網有哪些操作系統?物聯網操作系統匯總 5.4w次閱讀
- 一文解析物聯網協議 4522次閱讀
- 采用物聯網技術,對藥品進行有效的跟蹤識別 1625次閱讀
- 物聯網原理和它的應用與技術的資料概述 6890次閱讀
- 物聯網應用的支撐是5G網絡建設的主要目標之一 3594次閱讀
- 物聯網關鍵技術有哪些_物聯網關鍵技術相關介紹 2.5w次閱讀
- 物聯網與農業生產結合的3大發展趨勢和6個特征 6784次閱讀
- 為何LPWA對物聯網是顛覆性的新網絡? 4171次閱讀
- 農業物聯網中關鍵技術研究與探討 4787次閱讀
下載排行
本周
- 1普中科技HC6800-EM3使用操作手冊
- 21.69 MB | 3次下載 | 2 積分
- 2PL4807單節鋰離子電池充電器中文手冊
- 1.36 MB | 2次下載 | 免費
- 3智能小車proteus仿真+C源程序
- 0.02 MB | 1次下載 | 免費
- 4TMR技術在電流傳感器中的應用
- 616.47 KB | 1次下載 | 免費
- 5開關電源設計原理手冊
- 1.83 MB | 1次下載 | 免費
- 6BQ769142技術參考手冊
- 2.99MB | 1次下載 | 免費
- 7CBM8605_8606_8608-運算放大器【中文排版】-202406271735
- 2.70 MB | 1次下載 | 免費
- 801-07-06-CBM8655_CBM8656精密運算放大器
- 4.49 MB | 1次下載 | 免費
本月
- 1XL4015+LM358恒壓恒流電路圖
- 0.38 MB | 154次下載 | 1 積分
- 2PCB布線和布局電路設計規則
- 0.40 MB | 35次下載 | 免費
- 3智能門鎖原理圖
- 0.39 MB | 13次下載 | 免費
- 4GB/T4706.1-2024 家用和類似用途電器的安全第1部分:通用要求
- 7.43 MB | 11次下載 | 1 積分
- 5JESD79-5C_v1.30-2024 內存技術規范
- 2.71 MB | 10次下載 | 免費
- 6elmo直線電機驅動調試細則
- 4.76 MB | 9次下載 | 6 積分
- 7WIFI智能音箱原理圖完整版
- 0.09 MB | 7次下載 | 10 積分
- 8PC1013三合一快充數據線充電芯片介紹
- 1.03 MB | 7次下載 | 免費
總榜
- 1matlab軟件下載入口
- 未知 | 935115次下載 | 10 積分
- 2開源硬件-PMP21529.1-4 開關降壓/升壓雙向直流/直流轉換器 PCB layout 設計
- 1.48MB | 420061次下載 | 10 積分
- 3Altium DXP2002下載入口
- 未知 | 233084次下載 | 10 積分
- 4電路仿真軟件multisim 10.0免費下載
- 340992 | 191367次下載 | 10 積分
- 5十天學會AVR單片機與C語言視頻教程 下載
- 158M | 183333次下載 | 10 積分
- 6labview8.5下載
- 未知 | 81581次下載 | 10 積分
- 7Keil工具MDK-Arm免費下載
- 0.02 MB | 73806次下載 | 10 積分
- 8LabVIEW 8.6下載
- 未知 | 65985次下載 | 10 積分
評論
查看更多