什麼是功能?
功能是執行節點可以執行的操作。每個功能定義:- 操作內容 (名稱和描述)
- 輸入參數 (JSON Schema)
- 輸出資料 (JSON Schema)
- 觸發的事件
功能結構
{
"action": "domain.action_name",
"name": "人類可讀的名稱",
"description": "為 AI 和使用者提供的詳細描述",
"params": {
"type": "object",
"properties": { ... },
"required": [ ... ]
},
"returns": {
"type": "object",
"properties": { ... }
},
"events": ["event.name1", "event.name2"]
}
必需欄位
| 欄位 | 型別 | 描述 |
|---|---|---|
action | string | 唯一的操作識別符 (domain.action) |
name | string | 簡短的人類可讀名稱 |
params | JSON Schema | 輸入參數定義 |
returns | JSON Schema | 輸出資料定義 |
可選欄位
| 欄位 | 型別 | 描述 |
|---|---|---|
description | string | 詳細描述 (由 AI 使用) |
events | string[] | 此操作可能觸發的事件 |
JSON Schema
功能使用 JSON Schema Draft 2020-12 來定義參數和傳回值。為什麼使用 JSON Schema?
- ✅ 自我文件化 - 描述資料結構
- ✅ 驗證 - Qaptly 在發送前驗證參數
- ✅ 型別安全 - 及早捕捉錯誤
- ✅ AI 友善 - AI 可以理解您的 API
基本型別
{
"type": "string" // 文字
}
{
"type": "number" // 數值 (整數或浮點數)
}
{
"type": "boolean" // true/false
}
{
"type": "array", // 列表
"items": { ... }
}
{
"type": "object", // 字典/對應
"properties": { ... }
}
功能範例
1. 簡單操作 (無參數)
獲取目前 WiFi 狀態且無輸入參數:{
"action": "wifi.status",
"name": "取得 WiFi 狀態",
"description": "傳回目前 WiFi 連接狀態,包括 SSID、訊號強度和 IP 位址",
"params": {
"type": "object",
"properties": {},
"required": []
},
"returns": {
"type": "object",
"properties": {
"connected": {
"type": "boolean",
"description": "WiFi 是否已連接"
},
"ssid": {
"type": "string",
"description": "網路名稱 (如已連接)"
},
"signal": {
"type": "number",
"description": "訊號強度 (dBm)"
},
"ip": {
"type": "string",
"description": "分配的 IP 位址"
}
}
},
"events": []
}
2. 具有必需參數的操作
使用必需 SSID 和可選密碼連接到 WiFi:{
"action": "wifi.connect",
"name": "連接到 WiFi",
"description": "連接到指定的 WiFi 網路。對於開放網路,密碼是可選的。",
"params": {
"type": "object",
"properties": {
"ssid": {
"type": "string",
"description": "要連接的 WiFi 網路的 SSID",
"minLength": 1,
"maxLength": 32
},
"password": {
"type": "string",
"description": "WiFi 密碼 (開放網路不需要)"
},
"timeout": {
"type": "number",
"description": "連接逾時時間 (秒)",
"default": 30,
"minimum": 5,
"maximum": 300
}
},
"required": ["ssid"]
},
"returns": {
"type": "object",
"properties": {
"connected": {
"type": "boolean"
},
"ip": {
"type": "string"
},
"gateway": {
"type": "string"
}
}
},
"events": ["wifi.connected", "wifi.connection_failed"]
}
3. 具有陣列參數的操作
同時控制多個 GPIO 腳位:{
"action": "gpio.set_multiple",
"name": "設定多個 GPIO 腳位",
"description": "同時將多個 GPIO 腳位設定為 HIGH 或 LOW 狀態",
"params": {
"type": "object",
"properties": {
"pins": {
"type": "array",
"description": "腳位設定的陣列",
"items": {
"type": "object",
"properties": {
"pin": {
"type": "number",
"description": "GPIO 腳位編號",
"minimum": 0,
"maximum": 40
},
"state": {
"type": "string",
"description": "腳位狀態",
"enum": ["HIGH", "LOW"]
}
},
"required": ["pin", "state"]
},
"minItems": 1
}
},
"required": ["pins"]
},
"returns": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"updated_pins": {
"type": "array",
"items": {
"type": "number"
}
}
}
},
"events": []
}
4. 具有列舉選項的操作
從預定義選項設定 LED 顏色:{
"action": "led.set_color",
"name": "設定 LED 顏色",
"description": "將 LED 變更為預定義顏色之一",
"params": {
"type": "object",
"properties": {
"color": {
"type": "string",
"description": "LED 顏色",
"enum": ["red", "green", "blue", "yellow", "white", "off"]
},
"brightness": {
"type": "number",
"description": "亮度等級 (0-100)",
"minimum": 0,
"maximum": 100,
"default": 100
}
},
"required": ["color"]
},
"returns": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"current_color": {
"type": "string"
}
}
},
"events": ["led.color_changed"]
}
JSON Schema 功能
驗證約束
{
"type": "string",
"minLength": 1,
"maxLength": 100,
"pattern": "^[a-zA-Z0-9_]+$"
}
{
"type": "number",
"minimum": 0,
"maximum": 100,
"multipleOf": 5
}
{
"type": "array",
"minItems": 1,
"maxItems": 10,
"uniqueItems": true
}
預設值
{
"properties": {
"timeout": {
"type": "number",
"default": 30,
"description": "請求逾時時間 (秒)"
}
}
}
列舉
{
"properties": {
"mode": {
"type": "string",
"enum": ["auto", "manual", "scheduled"],
"description": "操作模式"
}
}
}
巢狀物件
{
"properties": {
"config": {
"type": "object",
"properties": {
"host": {"type": "string"},
"port": {"type": "number"},
"ssl": {"type": "boolean"}
},
"required": ["host", "port"]
}
}
}
事件宣告
宣告一個功能可能觸發的事件:{
"action": "wifi.scan",
"events": [
"wifi.scan_complete",
"wifi.scan_failed",
"wifi.network_found"
]
}
最佳實踐: 只列出直接相關的事件。不要列出您的執行節點可能發出的所有可能事件。
操作命名慣例
格式
domain.action
標準網域
| 網域 | 用途 | 範例 |
|---|---|---|
wifi | WiFi 控制 | scan, connect, disconnect, status |
bluetooth | Bluetooth | scan, pair, unpair |
network | 網路診斷 | ping, traceroute, dns_lookup |
gpio | 硬體 GPIO | read, write, mode |
sensor | 感應器讀取 | temperature, humidity, pressure |
system | 系統操作 | reboot, shutdown, info |
file | 檔案操作 | read, write, list, delete |
自訂網域
對於廠商特定的操作,使用:vendor.domain.action
acme.motor.rotateacme.motor.stopacme.motor.set_speed
描述最佳實踐
良好的描述有助於 AI 理解您的執行節點:不好的描述
{
"description": "掃描 WiFi"
}
良好的描述
{
"description": "掃描範圍內可用的 WiFi 網路,並傳回其 SSID、dBm 中的訊號強度、MHz 中的頻率和安全型別 (開放、WEP、WPA、WPA2、WPA3)"
}
準則
- 具體化 - 確切地執行什麼操作?
- 提及關鍵資料 - 傳回的資訊是什麼?
- 包括單位 - dBm、MHz、秒等
- 注意副作用 - 它會改變狀態嗎?
- 為 AI 編寫 - 未來的 AI 整合將使用描述
完整範例
包含所有功能的綜合功能:{
"action": "sensor.read_temperature",
"name": "讀取溫度感應器",
"description": "從 DHT22 感應器讀取目前溫度,並以攝氏度或華氏度傳回該值。可選擇套用校準位移。如果溫度與上一次讀取的差異超過 0.5 度,則觸發 temperature_changed 事件。",
"params": {
"type": "object",
"properties": {
"unit": {
"type": "string",
"description": "溫度單位",
"enum": ["celsius", "fahrenheit"],
"default": "celsius"
},
"offset": {
"type": "number",
"description": "要套用的校準位移 (以選定的單位)",
"default": 0,
"minimum": -10,
"maximum": 10
},
"precision": {
"type": "number",
"description": "小數位數",
"enum": [0, 1, 2],
"default": 1
}
},
"required": []
},
"returns": {
"type": "object",
"properties": {
"temperature": {
"type": "number",
"description": "目前溫度讀取值"
},
"unit": {
"type": "string",
"description": "使用的測量單位"
},
"timestamp": {
"type": "string",
"description": "讀取的 ISO 8601 時間戳記",
"format": "date-time"
},
"sensor_id": {
"type": "string",
"description": "感應器硬體識別符"
}
}
},
"events": ["sensor.temperature_changed", "sensor.read_error"]
}
驗證
Qaptly 在發送命令前驗證參數:# 來自 Qaptly 的命令
{
"action": "wifi.connect",
"params": {
"ssid": "HomeWiFi",
"timeout": 45
}
}
# ✅ 有效: 所有必需參數都存在,型別正確
# ❌ 無效: 缺少必需參數
{
"action": "wifi.connect",
"params": {
"timeout": 45 // 缺少 "ssid"
}
}
# ❌ 無效: 型別錯誤
{
"action": "wifi.connect",
"params": {
"ssid": 12345, // 應為 string
"timeout": "45" // 應為 number
}
}
動態功能 (進階)
對於具有變化功能的執行節點 (例如,偵測到的感應器),您可以:- 初始註冊 - 使用基本功能進行註冊
- 發現 - 偵測可用硬體
- 重新連接 - 斷線並使用更新的功能重新連接
# 偵測到新感應器後
async def update_capabilities():
# 關閉目前連接
await websocket.close()
# 新增新功能
capabilities.append({
"action": "sensor.read_humidity",
"name": "讀取濕度感應器",
...
})
# 使用更新的功能重新連接
await connect_and_register()
功能更新需要斷線和重新註冊。相應地規劃執行節點架構。
測試功能
測試您的 JSON Schema 定義:import jsonschema
# 定義架構
schema = {
"type": "object",
"properties": {
"ssid": {"type": "string"},
"timeout": {"type": "number"}
},
"required": ["ssid"]
}
# 有效參數
params = {"ssid": "HomeWiFi", "timeout": 30}
jsonschema.validate(params, schema) # ✅ 無錯誤
# 無效參數
params = {"timeout": 30} # 缺少 ssid
jsonschema.validate(params, schema) # ❌ ValidationError
後續步驟
協議參考
訊息格式規格
示例
完整的工作實現
快速開始
建立您的首個執行節點
認證
安全性和金鑰管理