JSON API
Botnana Control 的 JSON API 採用 JSON-RPC 2.0 。
程式可以使用 JSON 格式和 Botnana Control 溝通。此一方法適用於各種支援 JSON 格式且具有 Websocket 函式庫的語言,例如:
- C#
- C++
- Python
公開 API 範圍
本章只涵蓋已發行 botnana-apis 用戶端函式庫所公開的客戶 API。Botnana
Control 另有供內建瀏覽器 HMI 與內部服務協調使用的方法;伺服器具有某個方法,
不代表它就是公開 API。方法必須先透過 botnana-apis 發行,本章才能將它記載為
客戶整合合約。
本章採用的相容性基準是 botnana-apis 標籤
customer-release-2025-02-21,其對應來源版本為 commit 1946d8d28759。
回傳資料格式
Botnana Control 若回傳資料,格式一律為
tag1|value1|tag2|value2...
注意回傳格式不是 JSON 格式。
自行開發 HMI 的 WebSocket 建議(1.14.3 版)
Botnana Control 1.14.3 提供兩個 rtForth 使用者工作供 WebSocket 用戶端使用。
伺服器接受 script.evaluate 請求後,不會回傳通用的成功或執行完成訊息。
因此,自行開發的 HMI 不可將 WebSocket 傳送成功或未收到錯誤,視為 script
已經執行的證明。
建議在用戶端採用以下限制,以減少請求累積,並讓運動命令較容易驗證:
- 每個 HMI 應用程式盡可能只維持一條 WebSocket 長連線。連線不用時應正常 關閉,重新連線時應加入有限的等待時間,並避免閒置的瀏覽器分頁或連續重連 占用兩個 rtForth 使用者工作。
- 將連線初始化、heartbeat、讀取及命令全部交由同一個送出額度管理。突發請求 不超過 5 個,持續速率不超過每秒 100 個請求。這是流量建議,不代表系統保證 每秒可執行 100 個長時間運行的 rtForth script。
- 操作命令及運動命令的優先順序應高於輪詢,但仍須使用相同的請求額度。較新的 輪詢可取代或取消尚未送出的舊輪詢;延遲或重新連線後不可補送累積的輪詢。
- 只輪詢目前畫面需要的即時數值。穩定不變的設定資料不應每 50 ms 重複讀取。
- 每個唯讀輪詢 script 應限制在 512 UTF-8 bytes 及 32 個 rtForth 操作以內。 運動命令及設定變更不可和可捨棄的輪詢放在同一批次。
- 必須處理伺服器傳回的每一則訊息,尤其是以
error|開頭的錯誤。 收到error|Scripts buffer is fulled.、逾時或斷線時,HMI 必須重新讀取並 核對控制器狀態,不可假設命令已經執行。 - 每條連線同一時間最多只能有一個尚待驗證的狀態變更 script。未收到回應時, 不可自動重送運動命令,因為原命令可能已經執行。
rtForth 使用者工作共用目前所選定的軸組。group! 以及依賴該軸組選擇的命令,
應放在同一個 script.evaluate 請求內。需要確認結果時,請在同一段 script
加入會輸出結果的讀回命令。例如:
{
"jsonrpc": "2.0",
"method": "script.evaluate",
"params": {
"script": "1 group! 100.0e mm/min vcmd! 1 .group"
}
}
回傳資料會包含第 1 軸組的 vcmd.1 欄位。這可以確認已儲存的命令值,但不能
單獨證明實際物理速度。vcmd! 對 Sine 軸組不產生作用;Sine 軸組所回報的
vcmd 是其設定的正弦速度振幅。
以上是 1.14.3 版的保守建議,可降低請求壓力造成問題的機會,但不能修復已停滯 的連線,也不提供命令恰好執行一次的保證。
Version API
程式可以使用 Version API 取得 Botnana Control 的版本。
{
"jsonrpc": "2.0",
"method": "version.get"
}
會回傳以下字串:
version|1.0.0
Configuration API
已發行的用戶端函式庫提供設定讀取、設定修改與 config.save。Botnana Control
1.14.4-21 與更新版本接受這些已發行的請求格式,不要求用戶端協商內建 HMI 使用
的版本感知設定協定。
同一時間只能使用一個設定編輯器。伺服器處理舊版 setter 請求時,會把修改套用至
當時的設定草稿;不帶參數的 config.save 會儲存當時的草稿。舊版請求無法偵測
另一個瀏覽器或用戶端是否在兩個請求之間修改草稿。請勿同時透過客戶 HMI 與內建
HMI 編輯設定。內建 HMI 的版本感知操作仍會執行過期修改檢查。
參數檔的設定,在重開機或重新讀取參數檔後生效。
修改設定參數
修改設定參數並不會立刻將設定值儲存至參數設定檔,也不會影響到各裝置目前使用的參數。
EtherCAT Position 與 Alias 說明:
EtherCAT Position: 依據 EtherCAT 網路佈局,最靠近主站的 Position 為 1, 依序遞增。
EtherCAT Alias: 每一個 EtherCAT 從站都可以設定一個站號的別名。一般設定此別名的方法有兩種:
- EtherCAT 從站內的 EEPROM,
- EtherCAT 從站的硬體旋鈕。
在設定參數時,如果 alias 不為 0,就會以 alias 選擇從站。當 alias 為 0,就以 position 選擇從站。
設定 EtherCAT Slave 參數 config.slave.set
方法:
"method": "config.slave.set"
必要參數:
"alias": Slave Alis。
"position": Slave Position。
"channel": Device Channel,從 1 開始計數。
每個已發行的 setter 請求只會送出一個數值欄位。已發行欄位如下:
homing_method、homing_speed_1、homing_speed_2與homing_acceleration;profile_velocity、profile_acceleration與profile_deceleration;以及pdo_velocity_offset、pdo_torque_offset、pdo_digital_inputs、pdo_demand_position、pdo_demand_velocity、pdo_demand_torque、pdo_real_velocity與pdo_real_torque。
Wire 範例:設定位置 1 從站之 channel 1 的回歸原點方法。
{
"jsonrpc": "2.0",
"method": "config.slave.set",
"params": {
"alias": 0,
"position": 1,
"channel": 1,
"homing_method": 33
}
}
設定運動控制參數 config.motion.set
方法:
"method": "config.motion.set"
必要參數:
None
已發行 setter 提供 period_us、group_capacity 與 axis_capacity,每個
請求只送出一個數值。
Wire 範例:
{
"jsonrpc": "2.0",
"method": "config.motion.set",
"params": {
"period_us": 2000
}
}
設定軸組參數 config.group.set
方法:
"method": "config.group.set"
必要參數:
"position": 指定軸組,從 1 開始計數。
已發行 setter 提供 name、必須搭配 mapping 的 gtype、vmax、
amax 與 jmax。除軸組型態與 mapping 必須成對送出外,每個用戶端 helper
只送出一個數值。
Wire 範例:將軸組 1 設為對應軸 1 與軸 2 的 2D 軸組。
{
"jsonrpc": "2.0",
"method": "config.group.set",
"params": {
"position": 1,
"gtype": "2D",
"mapping": [1, 2]
}
}
設定運動軸參數 config.axis.set
方法:
"method": "config.axis.set"
必要參數:
"position": 指定運動軸,從 1 開始計數。
每個已發行的 setter 請求只會送出一個數值欄位。已發行欄位如下:
name、home_offset、encoder_ppu、encoder_length_unit、encoder_direction、vmax與amax;ext_encoder_ppu、ext_encoder_direction、closed_loop_filter與max_position_deviation;drive_alias、drive_slave_position與drive_channel;以及ext_encoder_alias、ext_encoder_slave_position與ext_encoder_channel。
Wire 範例:
{
"jsonrpc": "2.0",
"method": "config.axis.set",
"params": {
"position": 1,
"name": "X"
}
}
取得設定參數
取得 EtherCAT slave 參數 config.slave.get
方法:
"method": "config.slave.get"
必要參數:
"alias": Slave Alias。
"position": Slave Position。
"channel": Device Channel,從 1 開始計數。
範例:
{
"jsonrpc": "2.0",
"method": "config.slave.get",
"params": {
"alias": 0,
"position": 1,
"channel": 1
}
}
回傳封包
config_slave_alias.1|0
|config_homing_method.1.1|33
|config_homing_speed_1.1.1|1000
|config_homing_speed_2.1.1|250
|config_homing_acceleration.1.1|500
|config_profile_velocity.1.1|1000000
|config_profile_acceleration.1.1|50000
|config_profile_deceleration.1.1|50000
|config_baud_rate.1.1|6
|config_data_frame.1.1|3
|config_half_duplex.1.1|1
|config_uart_p2p.1.1|0
|config_tx_optimization.1.1|1
取得運動參數 config.motion.get
方法:
"method": "config.motion.get"
必要參數:
None
範例: 取得 motion 設定
{
"jsonrpc": "2.0",
"method": "config.motion.get"
}
回傳封包:
config_period_us|2000
|config_group_capacity|7
|config_axis_capacity|10
取得軸組參數 config.group.get
方法:
"method": "config.group.get"
必要參數:
"position": 指定軸組,從 1 開始計數。
範例: 取得 Group 1 設定
{
"jsonrpc": "2.0",
"method": "config.group.get",
"params": {
"position": 1
}
}
回傳封包
config_group_name.1|BotnanaGo
|config_group_type.1|2D
|config_group_mapping.1|2,3
|config_group_vmax.1|0.200
|config_group_amax.1|5.000
|config_group_jmax.1|40.000
取得軸組參數 config.axis.get
方法:
"method": "config.axis.get"
必要參數:
"position": 指定運動軸,從 1 開始計數。
範例: 取得 Axis 1
{
"jsonrpc": "2.0",
"method": "config.axis.get",
"params": {
"position": 1
}
}
回傳封包
config_axis_name.1|Anonymous
|config_axis_home_offset.1|0.0000
|config_encoder_ppu.1|1000000.00000
|config_encoder_length_unit.1|Meter
|config_encoder_direction.1|1
|config_slave_position.1|2
|config_drive_channel.1|2
儲存設定參數
儲存設定參數會立刻將設定值儲存至參數設定檔,但不會影響到各裝置目前使用的參數。
關機再開後系統會使用新的設定。
範例:要求儲存 configuration:
{
"jsonrpc": "2.0",
"method": "config.save"
}
Real-time Scripting API
Botnana Control 在其 real-time event loop 提供 Real-time script 來滿足更複雜的程式需求。為此提供兩個 JSON-RPC:
- script.evaluate: 解譯 real-time script。注意不可以使用
script.evaluate來編譯 real-time script。 - script.deploy: 編譯 real-time script。
Real-time script 的指令集請見 Real-time scripting API
解譯 real-time script script.evaluate
方法:
"method": "script.evaluate"
必要參數:
"script":real-time script 。
範例:以下 RPC 呼叫設定 Drive channel 1 of Slave 1 回歸原點方法的 JSON 命令。
{
"jsonrpc": "2.0",
"method": "script.evaluate",
"params": {
"script": "33 1 1 homing-method!"
}
}
部署 real-time script script.deploy
此一命令將 script 轉交至背景執行的 Task 解譯或編譯,避免影響和使用者互動中的 Task。常用於大型 script 的解譯和執行。
方法:
"method": "script.deploy"
必要參數:
"script": real-time script 。
範例:以下 RPC 呼叫編譯了一名為 p1 的程式。當 p1 執行時會設定 Drive channel 1 of Slave 1 回歸原點方法。
{
"jsonrpc": "2.0",
"method": "script.deploy",
"params": {
"script": ": p1 33 1 1 homing-method! ;"
}
}