ProEye-X API

Cara membaca dan menulis data analisis kerja di instans khusus perusahaan Anda (https://perusahaan.proeye-x.com) dari sistem eksternal seperti MES, ERP, atau BI. Semua panggilan memakai JSON-RPC 2.0, dikirim sebagai POST ke satu alamat: /jsonrpc.

Memulai

Alamat panggilan

Alamat berbeda untuk setiap instans perusahaan. Nama basis data sama dengan bagian depan alamat perusahaan (perusahaan).

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

Membuat kunci API

Masuk ke instans → menu pengguna (kanan atas) › Profil Saya (Preferensi) › Keamanan Akun › “Kunci API Baru”. Gunakan kunci sebagai pengganti kata sandi; kunci hanya ditampilkan sekali. Simpan kunci hanya di program sisi server, jangan di kode browser.

Autentikasi (mendapatkan uid)

Tukar email login dan kunci API dengan nomor pengguna (uid), lalu kirim basis data, uid, dan kunci API pada setiap panggilan.

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)

Fungsi bantu Python

Contoh di bawah memakai fungsi bantu model() ini.

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 {})

Bahasa

Berikan lang di context untuk menerima nama pekerjaan dan nama elemen dalam bahasa tersebut (jika ada terjemahan). Contoh: {"context": {"lang": "id_ID"}} · en_US · ja_JP · zh_CN · zh_TW · vi_VN · th_TH · es_ES · de_DE · ko_KR.

Galat

Jika gagal, Anda menerima HTTP 200 dengan objek "error"; error.data.message menjelaskan alasannya (tidak ada hak akses, kolom wajib kosong, …).

Daftar API

element_type adalah kunci slot jenis pekerjaan (va = slot 1, nva = slot 2, wait = slot 3, slot kustom c4 …). Waktu VA/NVA dihitung dari interval segment_data.

1. Daftar analisis

Model · wa.sessionMetode · search_read

Mengambil daftar analisis kerja (sesi) beserta rata-rata waktu siklus, rasio VA, dan jumlah elemen.

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}]}}'
Contoh respons
[{"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. Mengambil elemen kerja

Model · wa.elementMetode · search_read

Mengambil elemen kerja satu analisis per siklus: waktu mulai/selesai (detik), waktu standar, waktu VA dan NVA. cycle_no adalah siklus tempat elemen itu berada (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
Contoh respons
[{"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. Mengambil LOSS

Model · wa.elementMetode · search_read (LOSS)

Mengambil isi yang dimasukkan di tab LOSS. Untuk setiap segmen NVA sebuah elemen (item segment_data dengan type = nva), isi LOSS (loss_data) dan kode jenis pemborosan (loss_type_data) disimpan sebagai array JSON dengan urutan yang sama — pasangkan seperti di bawah untuk mendapat baris siklus · elemen · waktu segmen · jenis pemborosan · isi 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 ""})
Contoh respons
# 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. Membuat analisis

Model · wa.sessionMetode · create

Membuat analisis kerja baru. O-No (nomor unik) wajib diisi dan tidak boleh sama. Mengembalikan ID baru.

Python
session_id = model("wa.session", "create", [{
    "o_no": "O-2026-LINE3-01",          # required, unique
    "name": "Line 3 sub-assembly",
    "process_name": "Sub-assembly",
}])
Contoh respons
21

5. Menambah elemen kerja

Model · wa.elementMetode · create

Menambah beberapa elemen sekaligus berdasarkan rentang waktu video. Total seperti waktu siklus dan rasio VA dihitung ulang otomatis.

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"]})
Contoh respons
[205, 206]
[{"id": 18, "element_count": 2, "cycle_time_avg": 9.8, "va_ratio": 100.0}]

6. Mengubah / menghapus elemen

Model · wa.elementMetode · write / unlink

Ubah nama, waktu, atau jenis pekerjaan (write), atau hapus (unlink).

Python
model("wa.element", "write", [[205], {"name": "Pick and place", "video_end_time": 4.6}])
model("wa.element", "unlink", [[206]])
Contoh respons
true
true

7. Menulis LOSS

Model · wa.elementMetode · write (LOSS)

Menulis isi LOSS dan kode jenis pemborosan untuk setiap segmen NVA sebagai array JSON berurutan waktu. Nilai ke-n milik segmen NVA ke-n. Kode: w1 produksi berlebih · w2 menunggu · w3 transportasi · w4 proses berlebih · w5 persediaan · w6 gerakan · w7 cacat.

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"]),
}])
Contoh respons
true

8. Mengambil siklus

Model · wa.cycleMetode · search_read

Mengambil siklus yang diukur beserta waktu mulai, selesai, dan waktu siklus.

Python
cycles = model("wa.cycle", "search_read", [[["session_id", "=", 4]]],
               {"fields": ["sequence", "video_start", "video_end", "cycle_time"], "order": "sequence"})
Contoh respons
[{"id": 4, "sequence": 1, "video_start": 0.767, "video_end": 17.15, "cycle_time": 16.383}, ...]

9. Perbandingan (sebelum / sesudah)

Model · wa.comparisonMetode · create · action_build_lines · read

Memasangkan dua analisis sebagai perbandingan, membuat baris perbandingan, lalu mengambil pengurangan waktu siklus, peningkatan VA, dan selisih per elemen.

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"})
Contoh respons
[{"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. Penyeimbangan lini

Model · wa.linebalance · wa.lb.processMetode · search_read

Mengambil takt time, efisiensi lini, proses bottleneck, serta waktu siklus dan beban tiap proses.

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"})
Contoh respons
[{"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

Model · wa.mmc · wa.macMetode · search_read

Mengambil diagram manusia-mesin (MMC) dan diagram multi-aktivitas (MAC) dengan komposisi waktu dan utilisasi.

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"]})
Contoh respons
[{"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}]

Lihat semua kolom dengan fields_get: model("wa.session", "fields_get", [], {"attributes": ["string", "type"]})