ProEye-X API

Cách đọc và ghi dữ liệu phân tích công việc trong phiên bản riêng của công ty (https://congty.proeye-x.com) từ hệ thống bên ngoài như MES, ERP, BI. Mọi lệnh gọi dùng JSON-RPC 2.0, gửi POST đến một địa chỉ duy nhất: /jsonrpc.

Bắt đầu

Địa chỉ gọi

Địa chỉ khác nhau cho mỗi phiên bản công ty. Tên cơ sở dữ liệu là phần đầu của địa chỉ công ty (congty).

POST https://company.proeye-x.com/jsonrpc

Tạo khóa API

Đăng nhập phiên bản → menu người dùng (góc trên phải) › Hồ sơ của tôi (Tùy chọn) › Bảo mật tài khoản › “Khóa API mới”. Dùng khóa thay cho mật khẩu; khóa chỉ hiển thị một lần. Chỉ lưu khóa trong chương trình phía máy chủ, không đặt trong mã trình duyệt.

Xác thực (lấy uid)

Đổi email đăng nhập và khóa API lấy mã người dùng (uid), sau đó gửi kèm cơ sở dữ liệu, uid và khóa API trong mọi lệnh gọi.

curl
curl -s https://company.proeye-x.com/jsonrpc \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "method": "call", "params": {
        "service": "common", "method": "authenticate",
        "args": ["company", "you@company.com", "YOUR_API_KEY", {}]}}'

# → {"jsonrpc": "2.0", "id": null, "result": 7}      (7 = uid)

Hàm hỗ trợ Python

Các ví dụ bên dưới dùng hàm hỗ trợ model() này.

Python
import requests

URL = "https://company.proeye-x.com/jsonrpc"
DB, LOGIN, KEY = "company", "you@company.com", "YOUR_API_KEY"

def call(service, method, *args):
    r = requests.post(URL, json={"jsonrpc": "2.0", "method": "call",
                                 "params": {"service": service, "method": method, "args": args}}, timeout=30)
    r.raise_for_status()
    body = r.json()
    if body.get("error"):
        raise RuntimeError(body["error"]["data"]["message"])
    return body.get("result")          # no "result" key when the method returns nothing

UID = call("common", "authenticate", DB, LOGIN, KEY, {})

def model(name, method, args, kw=None):
    return call("object", "execute_kw", DB, UID, KEY, name, method, args, kw or {})

Ngôn ngữ

Truyền lang trong context để nhận tên công việc và tên phần tử bằng ngôn ngữ đó (khi có bản dịch). Ví dụ: {"context": {"lang": "vi_VN"}} · en_US · ja_JP · zh_CN · zh_TW · th_TH · id_ID · es_ES · de_DE · ko_KR.

Lỗi

Khi thất bại, bạn nhận HTTP 200 kèm đối tượng "error"; error.data.message cho biết lý do (không có quyền, thiếu trường bắt buộc, …).

Danh sách API

element_type là khóa của ô loại công việc (va = ô 1, nva = ô 2, wait = ô 3, ô tự định nghĩa c4 …). Thời gian VA/NVA được tính từ các khoảng segment_data.

1. Danh sách phân tích

Mô hình · wa.sessionPhương thức · search_read

Lấy danh sách phân tích công việc (phiên) cùng thời gian chu kỳ trung bình, tỷ lệ VA và số phần tử.

Python
rows = model("wa.session", "search_read", [[]], {
    "fields": ["o_no", "name", "process_name", "cycle_time_avg", "va_ratio", "element_count"],
    "order": "date desc", "limit": 20,
    "context": {"lang": "en_US"},       # names in English (optional)
})
curl
curl -s https://company.proeye-x.com/jsonrpc -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0", "method": "call", "params": {"service": "object", "method": "execute_kw",
  "args": ["company", 7, "YOUR_API_KEY", "wa.session", "search_read", [[]],
           {"fields": ["o_no", "name", "cycle_time_avg", "va_ratio"], "limit": 20}]}}'
Phản hồi mẫu
[{"id": 6, "o_no": "O-ENG-NOVICE-01", "name": "Engine Assembly - Novice",
  "process_name": "Engine Assembly Work", "cycle_time_avg": 165.33, "va_ratio": 63.7, "element_count": 14}]

2. Lấy phần tử công việc

Mô hình · wa.elementPhương thức · search_read

Lấy các phần tử công việc của một phân tích theo chu kỳ: thời gian bắt đầu/kết thúc (giây), thời gian tiêu chuẩn, thời gian VA và NVA. cycle_no là chu kỳ chứa phần tử đó (1, 2, 3 …).

Python
elements = model("wa.element", "search_read",
    [[["session_id", "=", 6], ["cycle_no", "=", 1]]],
    {"fields": ["cycle_no", "sequence", "name", "element_type", "video_start_time", "video_end_time",
                "standard_time", "va_time", "nva_time"], "order": "cycle_no, sequence"})
# every cycle: drop the ["cycle_no", "=", 1] condition — cycle_no tells which cycle each element belongs to
Phản hồi mẫu
[{"id": 70, "cycle_no": 1, "sequence": 1, "name": "Fetch the tools and prepare.", "element_type": "wait",
  "video_start_time": 189.656, "video_end_time": 198.398, "standard_time": 8.742,
  "va_time": 4.104, "nva_time": 4.638}, ...]

3. Lấy LOSS

Mô hình · wa.elementPhương thức · search_read (LOSS)

Lấy nội dung đã nhập ở tab LOSS. Với mỗi đoạn NVA của phần tử (mục segment_data có type = nva), nội dung LOSS (loss_data) và mã loại lãng phí (loss_type_data) được lưu thành mảng JSON cùng thứ tự — ghép như bên dưới để có các dòng chu kỳ · phần tử · thời gian đoạn · loại lãng phí · nội dung LOSS.

Python
import json

rows = model("wa.element", "search_read", [[["session_id", "=", session_id]]],
             {"fields": ["cycle_no", "sequence", "name", "segment_data", "loss_data", "loss_type_data"],
              "order": "cycle_no, sequence"})
losses = []
for e in rows:
    nva = [s for s in json.loads(e["segment_data"] or "[]") if s["type"] == "nva"]
    notes = json.loads(e["loss_data"] or "[]")          # LOSS text, one per NVA segment
    types = json.loads(e["loss_type_data"] or "[]")     # waste type code, one per NVA segment
    for i, seg in enumerate(nva):
        losses.append({"cycle_no": e["cycle_no"], "element": e["name"],
                       "start": seg["start"], "end": seg["end"], "dur": seg["dur"],
                       "loss_type": types[i] if i < len(types) else "",
                       "loss": notes[i] if i < len(notes) else ""})
Phản hồi mẫu
# rows (raw)
[{"id": 207, "cycle_no": 1, "sequence": 1, "name": "Fasten bolt",
  "segment_data": "[{\"type\": \"va\", \"start\": 4.2, \"end\": 7.0, \"dur\": 2.8}, {\"type\": \"nva\", \"start\": 7.0, ...}]",
  "loss_data": "[\"Searching for the wrench\", \"Waiting for the jig\"]",
  "loss_type_data": "[\"w6\", \"w2\"]"}]

# losses
[{"cycle_no": 1, "element": "Fasten bolt", "start": 7.0, "end": 9.1, "dur": 2.1, "loss_type": "w6", "loss": "Searching for the wrench"},
 {"cycle_no": 1, "element": "Fasten bolt", "start": 11.0, "end": 12.6, "dur": 1.6, "loss_type": "w2", "loss": "Waiting for the jig"}]

# loss_type: w1 overproduction · w2 waiting · w3 transport · w4 over-processing · w5 inventory · w6 motion · w7 defects

4. Tạo phân tích

Mô hình · wa.sessionPhương thức · create

Tạo phân tích công việc mới. O-No (mã duy nhất) là bắt buộc và không được trùng. Trả về ID mới.

Python
session_id = model("wa.session", "create", [{
    "o_no": "O-2026-LINE3-01",          # required, unique
    "name": "Line 3 sub-assembly",
    "process_name": "Sub-assembly",
}])
Phản hồi mẫu
21

5. Thêm phần tử công việc

Mô hình · wa.elementPhương thức · create

Thêm nhiều phần tử cùng lúc theo khoảng thời gian video. Các tổng như thời gian chu kỳ, tỷ lệ VA được tính lại tự động.

Python
ids = model("wa.element", "create", [[
    {"session_id": session_id, "cycle_no": 1, "sequence": 1, "name": "Pick part",
     "element_type": "va", "video_start_time": 0.0, "video_end_time": 4.2},
    {"session_id": session_id, "cycle_no": 1, "sequence": 2, "name": "Fasten bolt",
     "element_type": "va", "video_start_time": 4.2, "video_end_time": 9.8},
]])
summary = model("wa.session", "read", [[session_id]],
                {"fields": ["element_count", "cycle_time_avg", "va_ratio"]})
Phản hồi mẫu
[205, 206]
[{"id": 18, "element_count": 2, "cycle_time_avg": 9.8, "va_ratio": 100.0}]

6. Sửa / xóa phần tử

Mô hình · wa.elementPhương thức · write / unlink

Đổi tên, thời gian hoặc loại công việc (write), hoặc xóa (unlink).

Python
model("wa.element", "write", [[205], {"name": "Pick and place", "video_end_time": 4.6}])
model("wa.element", "unlink", [[206]])
Phản hồi mẫu
true
true

7. Ghi LOSS

Mô hình · wa.elementPhương thức · write (LOSS)

Ghi nội dung LOSS và mã loại lãng phí cho từng đoạn NVA dưới dạng mảng JSON theo thứ tự thời gian. Giá trị thứ n thuộc đoạn NVA thứ n. Mã: w1 sản xuất thừa · w2 chờ đợi · w3 vận chuyển · w4 gia công thừa · w5 tồn kho · w6 thao tác · w7 lỗi.

Python
import json

# element with NVA segments 7.0–9.1 s and 11.0–12.6 s → one entry per NVA segment, in time order
model("wa.element", "write", [[207], {
    "loss_data": json.dumps(["Searching for the wrench", "Waiting for the jig"]),
    "loss_type_data": json.dumps(["w6", "w2"]),
}])
Phản hồi mẫu
true

8. Lấy chu kỳ

Mô hình · wa.cyclePhương thức · search_read

Lấy các chu kỳ đã đo với thời điểm bắt đầu, kết thúc và thời gian chu kỳ.

Python
cycles = model("wa.cycle", "search_read", [[["session_id", "=", 4]]],
               {"fields": ["sequence", "video_start", "video_end", "cycle_time"], "order": "sequence"})
Phản hồi mẫu
[{"id": 4, "sequence": 1, "video_start": 0.767, "video_end": 17.15, "cycle_time": 16.383}, ...]

9. So sánh (trước / sau)

Mô hình · wa.comparisonPhương thức · create · action_build_lines · read

Ghép hai phân tích thành một so sánh, tạo các dòng so sánh và lấy mức giảm thời gian chu kỳ, cải thiện VA và chênh lệch từng phần tử.

Python
cid = model("wa.comparison", "create", [{
    "name": "Line 1 before / after", "session_a_id": 7, "session_b_id": 11}])
model("wa.comparison", "action_build_lines", [[cid]])
result = model("wa.comparison", "read", [[cid]],
               {"fields": ["ct_a", "ct_b", "ct_reduction", "ct_reduction_pct", "va_improvement"]})
lines = model("wa.comparison.line", "search_read", [[["comparison_id", "=", cid]]],
              {"fields": ["sequence", "step_name", "time_a", "time_b", "time_diff"], "order": "sequence"})
Phản hồi mẫu
[{"id": 3, "ct_a": 22.72, "ct_b": 23.39, "ct_reduction": -0.67, "ct_reduction_pct": -2.9, "va_improvement": -6.4}]
[{"id": 49, "sequence": 1, "step_name": "UP", "time_a": 2.85, "time_b": 2.723, "time_diff": -0.127}, ...]

10. Cân bằng chuyền

Mô hình · wa.linebalance · wa.lb.processPhương thức · search_read

Lấy takt time, hiệu suất chuyền, công đoạn nút thắt cùng thời gian chu kỳ và tải của từng công đoạn.

Python
lines = model("wa.linebalance", "search_read", [[]],
              {"fields": ["name", "takt_time", "lb_efficiency", "bottleneck_name", "max_ct"]})
processes = model("wa.lb.process", "search_read", [[["lb_id", "=", lines[0]["id"]]]],
                  {"fields": ["sequence", "process_name", "cycle_time", "load_ratio", "over_takt"],
                   "order": "sequence"})
Phản hồi mẫu
[{"id": 1, "name": "LB_Robot Assembly Line MAC Analysis", "takt_time": 27.74,
  "lb_efficiency": 90.0, "bottleneck_name": "Robot Assembly Line (After Improvement)", "max_ct": 27.74}]
[{"id": 1, "sequence": 10, "process_name": "Robot Assembly Line (After Improvement)",
  "cycle_time": 23.39, "load_ratio": 84.3, "over_takt": false}, ...]

11. MMC · MAC

Mô hình · wa.mmc · wa.macPhương thức · search_read

Lấy biểu đồ người-máy (MMC) và biểu đồ đa hoạt động (MAC) với cơ cấu thời gian và hiệu suất sử dụng.

Python
mmc = model("wa.mmc", "search_read", [[]],
            {"fields": ["name", "total_time", "machine_time", "walk_time", "wait_time", "load_ratio"]})
mac = model("wa.mac", "search_read", [[]],
            {"fields": ["name", "process_count", "takt_time", "avg_ct", "utilization", "balance_eff"]})
Phản hồi mẫu
[{"id": 1, "name": "Engine Assembly Line", "total_time": 165.33, "machine_time": 0.0,
  "walk_time": 0.0, "wait_time": 0.0, "load_ratio": 100.0}]
[{"id": 1, "name": "Robot Assembly Line MAC Analysis", "process_count": 4, "takt_time": 0.0,
  "avg_ct": 24.97, "utilization": 0.0, "balance_eff": 90.0}]

Xem mọi trường bằng fields_get: model("wa.session", "fields_get", [], {"attributes": ["string", "type"]})