AI 驅動文件
您想了解什麼?
相機指令碼
相機指令碼是整個相機使用的一個指令碼。它對每次完成的檢測和傳入的訊息做出響應,可以:
- 釋出到任何 MQTT 主題,使用您自己的格式
- 設定變數,供程式指令碼讀取
- 觸發告警,顯示在診斷日誌中
- 執行定時器和保持狀態,例如計數器和最後看到的值
它絕不會更改判定:決定通過或失敗是程式指令碼的職責。它在程式切換期間持續執行。
開啟 Integration > Camera Script。在您開啟指令碼之前不會執行任何內容,因此您可以先編寫和測試它。

執行方式
指令碼匯出多個鉤子。每個鉤子都是可選的:一個指令碼可以只匯出 onResult,或只匯出 subscriptions 和 onMessage。
| 鉤子 | 執行時機 |
|---|---|
onStart() | 指令碼載入時:儲存後、開啟時以及相機啟動時。在此啟動定時器並初始化狀態 |
onResult(result) | 每次生產檢測之後。匯出 options = { setup_results: true } 也可以獲取設定模式的結果 |
onMessage(msg) | 當 subscriptions 中的主題收到訊息,或 PLC 的使用者資料發生變化時 |
onTimer(name) | 當定時器觸發時 |
onStop() | 新版本接管之前、關閉指令碼時以及關機時(斷電時不會觸發) |
export const subscriptions = ["plant/line3/cmd"]; // MQTT topics this script listens on
export function onStart() {
state.results = 0;
timers.set("heartbeat", 30 * 1000, { repeat: true });
}
export function onResult(result) {
state.results = Number(state.results ?? 0) + 1;
}
export async function onTimer(name) {
if (name !== "heartbeat" || mqtt.status() !== "connected") return;
await mqtt.publish("plant/line3/alive", { alive: true, results: state.results }, { qos: 0 });
}
**一次一個。**鉤子一次執行一個,因此狀態不會在鉤子執行期間改變。新事件在佇列中等待,最多可容納 64 個結果和 256 條訊息;當佇列已滿時,最舊的事件會被丟棄並計數。
**等待。**當某個鉤子在 await mqtt.publish 或 vars.set 時,下一個事件的鉤子可以執行。請在 await 之後再次讀取 state,而不是在它之前讀取。
**時間。**鉤子在第一次 await 之前有 1 秒時間,之後每段有 50 毫秒。執行超時的鉤子會被停止。
失敗。當鉤子丟擲異常或被停止時,錯誤會出現在指令碼的日誌中並作為告警出現,它啟動的呼叫會被取消,下一個事件照常執行。
可用內容
| 全域性物件 | 作用 |
|---|---|
mqtt.publish(topic, payload, opts?) | 釋出文字、位元組或物件(以 JSON 傳送)。選項:qos(0、1 或 2)、retain,以及 MQTT v5 屬性 content_type、response_topic、correlation_data、user_properties、message_expiry_s |
mqtt.status() | "disabled"、"connecting"、"connected" 或 "disconnected" |
subscriptions | 要監聽的主題列表,使用字串字面量。允許使用 + 和 # 萬用字元 |
vars.get(name) / vars.set(name, value) | 讀取任何變數;設定來源為相機指令碼的變數 |
timers.set(name, ms, { repeat }) / timers.clear(name) | 命名定時器,至少 100 毫秒 |
alert.raise(title, detail?) | 觸發告警。相同標題每分鐘最多觸發一次 |
state | 在事件之間保留的臨時記憶體,直到指令碼重新載入 |
csv(rows)、xml.build()、xml.parse() | 構建 CSV 文字,構建或解析 XML |
pack、unpack、crc、log | 與程式指令碼相同的輔助函式 |
onResult 中的 result 與結果訊息的結構相同:包括程式、觸發、最終 judgment 和 reason、每個工具的結果、vars、metadata、tags、image.url 等。詳見 MQTT。
相機指令碼不能做什麼
- 更改判定結果或寫入 PLC 使用者結果。只有程式指令碼可以執行此操作
- 訪問相機檔案,或通過 MQTT 之外的方式訪問網路
- 在重新載入或重啟後保留狀態:
state和定時器會重新開始 - 觸發檢測或切換程式。這些仍由 PLC 和 HTTP API 完成
其限制:包括 state 在內共 16 MiB 記憶體,最多 16 個進行中的呼叫、32 個定時器、每條接收的 MQTT 訊息 256 KiB、每秒 50 行日誌,以及每分鐘 10 個告警標題。
如果指令碼記憶體耗盡,它將被重置:state 和定時器會被清除,並且 onStart 會重新執行。請保持 state 儘可能小,例如使用計數而不是儲存每個結果的列表。
模板
| 分組 | 模板 |
|---|---|
| 釋出結果 | 將每個結果釋出到 MQTT 主題 · 定時釋出心跳 |
| 從產線接收資料 | 通過 MQTT 響應 JSON-RPC 請求 · 將供應商 JSON 訊息中的欄位複製到變數 |
| 監控生產 | 按班次統計通過和失敗數併發布 CSV · 連續拒絕後觸發告警 |

// Raise an alert after consecutive rejects
export function onResult(result) {
state.streak = result.judgment === "fail" ? Number(state.streak ?? 0) + 1 : 0;
if (state.streak === 3) {
alert.raise("Reject streak", {
streak: state.streak,
recipe: result.recipe.name,
reason: result.reason,
});
}
}
試執行
測試會以試執行方式執行您的草稿:它會通過 onStart、onResult 和 onStop 重放最近的結果,並記錄每一次釋出、變數寫入、定時器、告警和日誌行,但不會實際傳送任何內容。最近的結果儲存在記憶體中,因此重啟後該列表為空。
按照模板的做法,使用 mqtt.status() === "connected" 保護髮布操作,並對其使用 await 或新增 .catch()。釋出失敗且沒有任何等待處理時,會被記錄為錯誤。