在物聯網平臺的建構過程中,資料的有效管理和根據規則的自動化控制至關重要。本文將深入探討資料刪除策略的 API 設計以及規則引擎的建置方法,並輔以程式碼範例和圖表說明。首先,我們將介紹如何使用 Python 實現 Purge API,用於清除已刪除的資料。接著,我們將探討如何建立時間戳微服務,並結合 Rust 和 Hugging Face Transformers 強化其功能。此外,我們將使用 JavaScript 實現隨機程式碼產生器和 UUID 生成器,提供實用的工具函式。最後,我們將著重於根據 Node-RED 的規則引擎設計,並探討如何使用 Python 實現身份驗證邏輯,確保平臺的安全性。

刪除資料

刪除資料的過程涉及到更新資料的狀態為已刪除。這可以透過一個刪除 API 來實現。刪除 API 可以接受資料的 ID 和主題作為引數,並更新相應的資料狀態。

清除資料

清除資料的過程涉及到完全從儲存中移除已刪除的資料。這可以透過一個清除 API 來實現。清除 API 可以接受資料的 ID 和主題作為引數,並從儲存中移除相應的資料。

Purge API

Purge API 是一個用於清除資料的 API。它可以接受資料的 ID 和主題作為引數,並從儲存中移除相應的資料。Purge API 的實現涉及到使用 DELETE 查詢來移除資料。

# Purge API 實現
def purge_data(topic, id):
    # 如果沒有身份驗證過濾器,設定預設值為 1
    if not msg.req.authFilter:
        msg.req.authFilter = 1
    
    # 建立 DELETE 查詢
    msg.topic = "DELETE thingData" + \
                " WHERE deleted=1" + \
                " AND" + \
                " topic='" + msg.req.params.topic + "'" + \
                " AND (" + msg.req.authFilter + ")" + \
                " AND id=" + msg.req.params.id + ";"
    
    # 執行 DELETE 查詢
    return msg

Purge 幾條記錄

Purge 幾條記錄的過程涉及到使用 Purge API 來清除多條資料。這可以透過傳遞資料的 ID 和主題作為引數來實現。

# Purge 幾條記錄
def purge_several_records(topic, ids):
    # 如果沒有身份驗證過濾器,設定預設值為 1
    if not msg.req.authFilter:
        msg.req.authFilter = 1
    
    # 建立 DELETE 查詢
    msg.topic = "DELETE thingData" + \
                " WHERE deleted=1" + \
                " AND" + \
                " topic='" + msg.req.params.topic + "'" + \
                " AND (" + msg.req.authFilter + ");"
    
    # 執行 DELETE 查詢
    return msg

Purge 第一幾條記錄

Purge 第一幾條記錄的過程涉及到使用 Purge API 來清除前幾條資料。這可以透過傳遞資料的 ID 和主題作為引數來實現。

# Purge 第一幾條記錄
def purge_first_few_records(topic, count):
    # 如果沒有身份驗證過濾器,設定預設值為 1
    if not msg.req.authFilter:
        msg.req.authFilter = 1
    
    # 建立 DELETE 查詢
    msg.topic = "DELETE thingData" + \
                " WHERE deleted=1" + \
                " AND" + \
                " topic='" + msg.req.params.topic + "'" + \
                " AND (" + msg.req.authFilter + ");"
    
    # 執行 DELETE 查詢
    return msg

建立時間戳微服務

時間戳微服務是一種非結構化功能,為玄貓提供時間戳的取得。在之前的章節中,我們已經建立了一個根據廣播的時間戳服務,現在我們將新增一個根據輪詢的時間戳服務。

獲取當前時間戳

我們可以使用以下程式碼建立一個簡單的時間戳服務:

import datetime

def get_current_timestamp():
    timestamp = int(datetime.datetime.now().timestamp() * 1000)
    return timestamp

# 使用Mojo框架建立API
from mojo import app

@app.route('/timestamp', methods=['GET'])
def get_timestamp():
    timestamp = get_current_timestamp()
    return {'timestamp': timestamp}

if __name__ == '__main__':
    app.run()

這個服務可以透過 /timestamp 端點訪問,傳回一個UNIX風格的時間戳。

測試時間戳服務

我們可以使用cURL命令進行快速測試:

curl http://localhost:5000/timestamp

輸出結果為:

{"timestamp": 1643723900375}

這個時間戳是以UNIX風格的微秒時間戳表示。

結合Rust和Hugging Face Transformers

為了增強時間戳服務的功能,我們可以使用Rust和Hugging Face Transformers進行時間戳的分析和處理。以下是一個簡單的例子:

use chrono::{DateTime, Utc};
use hugging_face::{Transformers, Tokenizer};

fn analyze_timestamp(timestamp: i64) -> String {
    let dt = DateTime::<Utc>::from_utc(
        chrono::NaiveDateTime::from_timestamp_opt(timestamp / 1000, 0),
        Utc,
    );
    let tokenizer = Tokenizer::new("bert-base-uncased");
    let input = tokenizer.encode(dt.format("%Y-%m-%d %H:%M:%S").to_string(), true);
    let output = Transformers::new("bert-base-uncased").generate(input);
    output
}

fn main() {
    let timestamp = 1643723900375;
    let result = analyze_timestamp(timestamp);
    println!("{}", result);
}

這個例子使用Rust和Hugging Face Transformers對時間戳進行分析和處理,傳回一個字串結果。

圖表視覺化

以下是時間戳服務的Mermaid圖表:

  flowchart TD
    A[時間戳請求] --> B[時間戳服務]
    B --> C[時間戳處理]
    C --> D[傳回時間戳]
    D --> E[客戶端接收]

這個圖表展示了時間戳服務的流程,從時間戳請求到客戶端接收。

隨機程式碼產生器

為了建立一個隨機程式碼產生器,我們可以使用 Node-RED 的功能來實現。這個產生器可以生成一個指定長度的隨機字串,非常適合用於建立令牌、預設密碼或 API 金鑰。

隨機程式碼產生器的實現

首先,我們需要定義一個函式來生成隨機字串。這個函式可以根據指定的長度生成一個隨機的字串。然後,我們可以使用這個函式來生成隨機程式碼,並將其作為輸出傳遞給使用者。

var randomString = function(length) {
  var text = "";
  var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  for (var i = 0; i < length; i++) {
    text += possible.charAt(Math.floor(Math.random() * possible.length));
  }
  return text;
}

接下來,我們可以使用這個函式來生成隨機程式碼,並將其作為輸出傳遞給使用者。

msg.payload = {
  code: randomString(msg.req.params.len)
}
return msg;

測試隨機程式碼產生器

我們可以使用 cURL 來測試這個隨機程式碼產生器。下面是測試的輸出結果:

{"code":"ASQ6t9PidHZ0BKxIsQfguD72fp0DcErq"}
{"code":"rU5rB3Db"}
{"code":"bydGpfpth9xE4vy9HcM97s1Jm3dmMipB0UuJB2Lqn95pkPrMM4IdxtaxUEBLvR1A"}

安裝額外的 Node-RED 節點

為了建立其他微服務,我們需要安裝額外的 Node-RED 節點,包括 UUID、Sendgrid 和 Twilio。這些節點可以幫助我們實現 UUID 生成、電子郵件傳送和簡訊傳送等功能。

UUID 生成器

UUID 生成器可以根據指定的名稱空間或時間戳生成 UUID。下面是 UUID 生成器的實現:

// Prepare response
msg.payload = {
  uuid: msg.payload
}
return msg;

測試 UUID 生成器

我們可以使用 cURL 來測試這個 UUID 生成器。下面是測試的輸出結果:

{"uuid":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}

圖表翻譯:

  flowchart TD
    A[開始] --> B[定義隨機字串函式]
    B --> C[生成隨機程式碼]
    C --> D[傳遞輸出]
    D --> E[測試隨機程式碼產生器]
    E --> F[安裝額外的 Node-RED 節點]
    F --> G[建立 UUID 生成器]
    G --> H[測試 UUID 生成器]

這個圖表展示了隨機程式碼產生器和 UUID 生成器的實現流程。

建立簡訊和電子郵件微服務API

在本章中,我們將探討如何使用Twilio和Sendgrid建立簡訊和電子郵件微服務API。為了使用這些服務,您需要在Twilio和Sendgrid上註冊帳戶,並取得API金鑰。

設定節點

首先,將Twilio和Sendgrid節點從節點面板拖放到工作區。然後,雙擊Sendgrid節點並在設定視窗中輸入API金鑰。這樣就完成了Sendgrid節點的設定。

接下來,雙擊Twilio節點並點選鉛筆圖示建立Twilio配置。這將開啟另一個對話方塊,需要輸入三個重要的輸入:Account SID、Twilio號碼和驗證令牌。這些資訊可以在您的Twilio帳戶頁面上找到。

簡訊傳送公用程式

有了配置設定後,我們可以建立一個簡訊API。定義端點為 /sms/to/:to/message/:message,其中 to 是目標手機號碼,message 是簡訊內容。

注意,Twilio節點沒有輸出,因此無法直接知道簡訊傳送請求是否成功。Twilio提供了回撥功能,可以在簡訊傳送成功或失敗時呼叫指定的URL。

以下是簡訊傳送公用程式的程式碼:

// 準備簡訊
msg.topic = msg.req.params.to;
msg.payload = msg.req.params.message;
return msg;

// 準備回應
msg.payload = {
  "smsTo": msg.topic,
  "message": msg.payload,
  "status": "queued"
};
return msg;

Twilio節點需要在簡訊物件中指定目標號碼和簡訊內容。prepare message函式節點負責準備這個簡訊包。

prepare response節點簡單地響應API呼叫者,狀態為queued,並回顯傳送的內容。

電子郵件傳送公用程式

現在,讓我們建立一個電子郵件傳送公用程式。定義端點為 /email/to/:to/subject/:subject/message/:message,其中 to 是目標電子郵件地址,subject 是電子郵件主題,message 是電子郵件內容。

Sendgrid節點需要在簡訊物件中指定傳送者、收件者、主題和內容。以下是電子郵件傳送公用程式的程式碼:

// 準備電子郵件
msg.from = "in24hrs <the.author@in24hrs.the.book>";
msg.to = msg.req.params.to;
msg.topic = msg.req.params.subject;
msg.payload = msg.req.params.message;
return msg;

// 準備回應

這個程式碼準備電子郵件內容,並將其傳送給Sendgrid節點。

建立規則引擎和身份驗證

規則引擎是IoT平臺中最強大的模組之一。它可以根據連線環境中的事件觸發其他事件,從而實現智慧化控制。在本章中,我們將建立規則引擎的工作邏輯,建立規則引擎流程,開發規則管理API,並實現身份驗證邏輯。

規則引擎邏輯

規則引擎可以透過多種方式實現。其中一種方式是使用Node-RED流程基礎的方法,新增訊息流監聽器,根據預先程式設計的標準分發訊息到其他節點,並執行進一步的動作。然而,這種方法有一定的侷限性,因為它需要手動預先程式設計規則。

另一種方法是使用查詢基礎的規則引擎。這種方法可以根據查詢結果動態新增或刪除規則。為了實現這種方法,我們需要建立一個資料表來儲存規則。

建立資料表

建立規則引擎的第一步是定義資料結構並新增一個資料表到時間序列資料儲存中。這個資料表被稱為規則引擎表(ruleEngine)。這個表中包含了規則的基本資訊,例如規則名稱、規則狀態、主題模式、有效負載模式等。

CREATE TABLE ruleEngine (
  id INT PRIMARY KEY AUTO_INCREMENT,
  ruleName VARCHAR(255),
  active BOOLEAN,
  topicPattern VARCHAR(255),
  payloadPattern VARCHAR(255),
  webHook VARCHAR(255),
  method VARCHAR(255)
);

規則引擎流程

規則引擎流程是根據規則表中的資料生成的。這個流程可以透過查詢規則表中的資料來動態生成規則。

  flowchart TD
    A[規則引擎] --> B[查詢規則表]
    B --> C[生成規則]
    C --> D[執行規則]
    D --> E[傳回結果]

圖表翻譯:

這個流程圖展示了規則引擎的工作流程。首先,規則引擎查詢規則表中的資料。然後,根據查詢結果生成規則。接下來,執行生成的規則。最後,傳回執行結果。

身份驗證邏輯

身份驗證是IoT平臺中的一個重要組成部分。它可以確保只有授權的使用者才能訪問平臺的資源。

import hashlib

def authenticate(username, password):
    # 查詢使用者資料
    user_data = query_user_data(username)
    if user_data:
        # 驗證密碼
        if hashlib.sha256(password.encode()).hexdigest() == user_data['password']:
            return True
    return False

內容解密:

這個程式碼展示了身份驗證的邏輯。首先,查詢使用者資料。如果使用者資料存在,則驗證密碼。如果密碼正確,則傳回True,否則傳回False。

規則引擎和身份驗證

在本章中,我們將討論規則引擎和身份驗證的概念。規則引擎是一種軟體元件,它允許您定義和執行業務規則。這些規則可以用於各種目的,例如資料驗證、業務流程自動化和決策支援。

規則引擎表設計

下面是一個典型的規則引擎表設計:

| 規則名稱 | 活動 | 主題模式 | 負載模式 | 方法 | WebHook |
| --- | --- | --- | --- | --- | --- |
| 時間戳規則 | 1 | timestamp% | % | POST | https://example.com/webhook |

在這個表中,我們定義了一個規則,名為“時間戳規則”。該規則活動且主題模式為“timestamp%”,負載模式為“%”。當訊息主題匹配該模式時,規則將被執行。方法為“POST”,WebHook URL為“https://example.com/webhook”。

流程式列構建

下面是一個流程式列示例:

  graph LR
    A[MQTT監聽器] --> B[搜尋規則]
    B --> C[MySQL節點]
    C --> D[呼叫WebHook]
    D --> E[除錯節點]

在這個流程式列中,我們首先使用MQTT監聽器監聽訊息。然後,我們使用搜索規則節點搜尋匹配的規則。MySQL節點用於從規則引擎表中檢索規則。呼叫WebHook節點用於執行WebHook請求。最後,除錯節點用於顯示輸出。

搜尋規則程式碼

msg.topic = "SELECT * FROM ruleEngine" +
" WHERE" +
" ('" + msg.topic + "' LIKE topicPattern)" +
" AND" +
" ('" + msg.payload + "' LIKE payloadPattern)" +
" AND active=1";
return msg;

這個程式碼片段實現了反向搜尋技術。它搜尋匹配主題模式和負載模式的規則,並且僅檢索活動規則(即active=1)。

呼叫WebHook程式碼

if(msg.payload.length !== 0) {
    for(var i = 0; i < msg.payload.length; i++) {
        msg.method = msg.payload[i].method;
        msg.url = msg.payload[i].webHook;
        node.send([msg]);
    }
}

這個程式碼片段檢查payload長度是否非零。如果長度非零,則執行一個迴圈,遍歷規則陣列。對於每個規則,分配HTTP呼叫方法和URL,然後傳送訊息包。

HTTP請求節點配置

HTTP請求節點配置如下:

| 方法 | URL |
| --- | --- |
| POST | https://example.com/webhook |

這個配置指定了HTTP呼叫方法和URL。

測試規則引擎

我們可以使用Paho MQTT工具測試規則引擎。首先,釋出一個時間戳訊息到MQTT主題。規則引擎將搜尋匹配的規則並執行它。然後,規則引擎將釋出另一個訊息到MQTT主題。我們可以在Paho頁面上看到這個過程的即時輸出。

圖表翻譯:

此圖示為流程式列的Mermaid圖表,展示了規則引擎的執行流程。圖表由多個節點組成,每個節點代表一個流程步驟。節點之間的箭頭表示流程的執行順序。

規則引擎的強大功能

要體驗規則引擎的強大功能,我們可以更新規則引擎表以新增更多規則,如圖10-5所示。

圖10-5. 兩個規則匹配同一標準和一個匹配後續標準 在這裡,我們有兩個規則匹配標準(即規則ID 1和ID 2)。相比之下,當我們執行規則2時,它釋出一條訊息,規則引擎再次工作。我們配置了第三個規則,不檢查主題模式,而是檢查有效負載模式,用於以“again”結尾的訊息。這意味著我們的第二個規則觸發了第三個規則。再次檢查Paho工具。在釋出時間戳主題上的內容後,應該會有三個額外的訊息跟隨。

注意:請仔細編寫規則並檢查迴圈參照。如果處理不當,這些參照可能會導致迴圈,從而迅速鎖定訪問。

規則管理API

為了輕鬆管理規則,我們將建立三個API:

  • 啟用或停用指定規則
  • 啟用或停用所有規則(當您想要停止所有規則時很方便)
  • 建立一個新規則帶有回撥(滿足M7要求)

啟用和停用特定規則

第一個API流程式列由玄貓遵循,如圖10-6所示。

圖10-6. 啟用或停用規則流程式列 我們建立了兩個API:/rules/enable/:id和/rules/disable/:id,用於啟用和停用規則。這些兩個類似的函式塊用於建立查詢,區別在於一個設定活動值為1,另一個設定活動值為0。

# 建立查詢 - /rules/enable/:id
msg.action = "enable"
msg.topic = "UPDATE ruleEngine" + " SET active=1" + " WHERE" + " id=" + msg.req.params.id + ";"
return msg

上面的程式碼片段是用於啟用查詢的。我們建立這個查詢並將一個變數新增到msg物件中作為action =“enable”。這使我們能夠在準備響應功能塊中正確響應。相應地,準備響應函式具有以下程式碼:

# 準備響應
msg.payload = {
    "status": msg.action + " success"
}
return msg

我們使用上游塊中的action變數來建立一個有意義的響應。由於我們已經在表中有一個規則ID = 1,我們可以使用以下cURL啟用或停用它:

curl -X PUT \
  http://localhost:8080/rules/enable/1 \
  -H 'Content-Type: application/json' \
  -d '{}'

輸出:

{
    "status": "enable success"
}

現在,如果您檢查資料庫,規則將具有active = 1的值。

覯規引擎和驗證

在本章中,我們將探討規則引擎和驗證的實現。規則引擎是一個強大的工具,允許我們定義和管理複雜的規則和條件。

啟用和停用所有規則

首先,我們將建立一個 API,用於啟用或停用所有規則。這個 API 的實現相對簡單,主要是更新規則引擎中的 active 欄位。

# 啟用所有規則
msg.action = "enable all"
msg.topic = "UPDATE ruleEngine SET active=1;"
return msg

建立新規則

接下來,我們將建立一個 API,用於新增新規則。這個 API 的實現涉及插入新規則記錄到規則引擎表中。

# 建立新規則
var ruleName = msg.req.params.rulename;
var topicPattern = msg.req.body.topicPattern;
var payloadPattern = msg.req.body.payloadPattern;
var method = msg.req.body.method;
var webHook = msg.req.body.webHook;
msg.topic = "INSERT INTO ruleEngine (ruleName, topicPAttern, payloadPattern, method, webHook)" + " VALUES" + " ('" + ruleName + "', '" + topicPattern + "', '" + payloadPattern + "', '" + method + "', '" + webHook + "');";
return msg;

刪除規則

雖然在本章中沒有詳細介紹刪除規則的 API,但您可以按照 /purge API 的邏輯建立一個刪除規則的 API。

使用 Node-RED 建立規則引擎

除了使用時間序列資料庫外,我們還可以使用 Node-RED 介面建立規則引擎。然而,這種方法有一些限制,例如不能動態地檢查多個輸入引數。

  flowchart TD
    A[規則引擎] --> B[時間序列資料庫]
    B --> C[規則管理]
    C --> D[條件檢查]
    D --> E[動作觸發]

圖表翻譯:

上述 Mermaid 圖表展示了規則引擎的基本流程。規則引擎從時間序列資料庫中讀取資料,然後進行規則管理和條件檢查。如果條件滿足,則觸發相應的動作。

在本章中,我們探討了規則引擎和驗證的實現,包括啟用和停用所有規則、建立新規則和使用 Node-RED 介面建立規則引擎。規則引擎是一個強大的工具,允許我們定義和管理複雜的規則和條件。

從系統架構的視角來看,本文深入探討了刪除、清除資料的 API 設計,時間戳微服務的構建,隨機程式碼產生器和簡訊/電子郵件微服務的開發,以及規則引擎和身份驗證的實現。透過結合 Python、JavaScript、Rust 等多種程式語言,以及 Mojo、Node-RED 等框架,文章展示了建構完整 IoT 平臺的關鍵模組。然而,目前系統的規則引擎功能仍受限於 Node-RED 的能力,無法完全實現動態多引數檢查。此外,簡訊傳送的成功與否缺乏完善的回饋機制,僅依靠 Twilio 的回撥功能,可能存在一定的可靠性風險。展望未來,整合更強大的規則引擎,例如 Drools 或 Nools,並引入更完善的非同步任務管理機制,將能提升系統的彈性與擴充套件性。同時,匯入更嚴謹的錯誤處理和日誌記錄機制,對於提升系統的穩定性和可維護性至關重要。對於追求高效能和高可靠性的 IoT 平臺而言,持續最佳化這些關鍵環節將是未來的發展方向。