Nodeflux Central
People Analytics

API Reference — People Analytics

Endpoint REST API untuk membuat, mengelola, dan memantau pipeline People Analytics pada stream Visionaire4, event streaming via WebSocket, dan struktur event JSON.

Endpoint pipeline (/pipeline/...) memanggil Visionaire API — basis URL dikonfigurasi melalui variabel VISIONAIRE_API_URL (default: http://localhost:4004). Autentikasi mengikuti konfigurasi deployment Visionaire Anda.


Manajemen Pipeline — Multi-Logics

Endpoint untuk membuat, mengubah, membaca, dan menghapus pipeline Multi-Logics (NFV4-MPA, NFV4-MPAA, NFV4-MPA2). Satu pipeline dapat menjalankan counting, roi_counting, dwelling, dan density sekaligus lewat array sub_analytics pada body request — lihat Konfigurasi untuk bentuk lengkap body-nya.

POST
/pipeline/{node_num}/{stream_id}/NFV4-MPA

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

node_num*integer

Nomor node (0 untuk single-node deployment).

stream_id*string

ID stream video yang akan diproses.

analytic_id*string

ID analitik Multi-Logics: NFV4-MPA (tanpa atribut), NFV4-MPAA (atribut generasi 1), atau NFV4-MPA2 (atribut generasi 2).

Value in"NFV4-MPA" | "NFV4-MPAA" | "NFV4-MPA2"

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

curl -X POST "http://localhost:4004/pipeline/0/stream_001/NFV4-MPA" \  -H "Content-Type: application/json" \  -d '{}'
{  "code": 200,  "message": "pipeline successfully created",  "node_num": 0,  "stream_id": "stream_001",  "analytic_id": "NFV4-MPA"}
{  "code": 400,  "message": "analytic_id=NFV4-MPA is already exists in stream=stream_001 !"}
PUT
/pipeline/{node_num}/{stream_id}/NFV4-MPA

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

node_num*integer

Nomor node (0 untuk single-node deployment).

stream_id*string

ID stream video yang akan diproses.

analytic_id*string

ID analitik Multi-Logics: NFV4-MPA (tanpa atribut), NFV4-MPAA (atribut generasi 1), atau NFV4-MPA2 (atribut generasi 2).

Value in"NFV4-MPA" | "NFV4-MPAA" | "NFV4-MPA2"

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

curl -X PUT "http://localhost:4004/pipeline/0/stream_001/NFV4-MPA" \  -H "Content-Type: application/json" \  -d '{}'
{  "code": 200,  "message": "pipeline successfully updated",  "node_num": 0,  "stream_id": "stream_001",  "analytic_id": "NFV4-MPA"}
{  "code": 400,  "message": "analytic_id=NFV4-MPA is already exists in stream=stream_001 !"}
GET
/pipeline/{node_num}/{stream_id}/NFV4-MPA

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

node_num*integer

Nomor node (0 untuk single-node deployment).

stream_id*string

ID stream video yang akan diproses.

analytic_id*string

ID analitik Multi-Logics: NFV4-MPA (tanpa atribut), NFV4-MPAA (atribut generasi 1), atau NFV4-MPA2 (atribut generasi 2).

Value in"NFV4-MPA" | "NFV4-MPAA" | "NFV4-MPA2"

Response Body

application/json

application/json

curl -X GET "http://localhost:4004/pipeline/0/stream_001/NFV4-MPA"
{  "code": 200,  "node_num": 0,  "stream_id": "stream_001",  "analytic_id": "NFV4-MPA",  "config": {},  "message": "configuration has been successfully retrieved from the runtime pipeline"}
{  "code": 400,  "message": "analytic_id=NFV4-MPA is already exists in stream=stream_001 !"}
DELETE
/pipeline/{node_num}/{stream_id}/NFV4-MPA

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

node_num*integer

Nomor node (0 untuk single-node deployment).

stream_id*string

ID stream video yang akan diproses.

analytic_id*string

ID analitik Multi-Logics: NFV4-MPA (tanpa atribut), NFV4-MPAA (atribut generasi 1), atau NFV4-MPA2 (atribut generasi 2).

Value in"NFV4-MPA" | "NFV4-MPAA" | "NFV4-MPA2"

Response Body

application/json

application/json

curl -X DELETE "http://localhost:4004/pipeline/0/stream_001/NFV4-MPA"
{  "code": 200,  "message": "pipeline successfully deleted",  "node_num": 0,  "stream_id": "stream_001",  "analytic_id": "NFV4-MPA"}
{  "code": 400,  "message": "analytic_id=NFV4-MPA is already exists in stream=stream_001 !"}

Manajemen Pipeline — Counting Sederhana

Endpoint dengan bentuk yang sama untuk NFV4-PC (counting orang), NFV4-PCA (counting orang — field atribut pada event tidak fungsional, lihat Varian & Cara Kerja), dan NFV4-HC (counting kepala). Tidak ada sub_analytics — hanya satu logic counting yang selalu aktif. Ganti segmen terakhir path dengan analytic_id yang diinginkan.

POST
/pipeline/{node_num}/{stream_id}/NFV4-PC

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

node_num*integer

Nomor node (0 untuk single-node deployment).

stream_id*string

ID stream video yang akan diproses.

analytic_id*string

ID analitik counting sederhana: NFV4-PC (orang), NFV4-PCA (orang, atribut TIDAK fungsional), atau NFV4-HC (kepala).

Value in"NFV4-PC" | "NFV4-PCA" | "NFV4-HC"

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

curl -X POST "http://localhost:4004/pipeline/0/stream_001/NFV4-PC" \  -H "Content-Type: application/json" \  -d '{}'
{  "code": 200,  "message": "pipeline successfully created",  "node_num": 0,  "stream_id": "stream_001",  "analytic_id": "NFV4-MPA"}
{  "code": 400,  "message": "analytic_id=NFV4-MPA is already exists in stream=stream_001 !"}
PUT
/pipeline/{node_num}/{stream_id}/NFV4-PC

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

node_num*integer

Nomor node (0 untuk single-node deployment).

stream_id*string

ID stream video yang akan diproses.

analytic_id*string

ID analitik counting sederhana: NFV4-PC (orang), NFV4-PCA (orang, atribut TIDAK fungsional), atau NFV4-HC (kepala).

Value in"NFV4-PC" | "NFV4-PCA" | "NFV4-HC"

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

curl -X PUT "http://localhost:4004/pipeline/0/stream_001/NFV4-PC" \  -H "Content-Type: application/json" \  -d '{}'
{  "code": 200,  "message": "pipeline successfully updated",  "node_num": 0,  "stream_id": "stream_001",  "analytic_id": "NFV4-MPA"}
{  "code": 400,  "message": "analytic_id=NFV4-MPA is already exists in stream=stream_001 !"}
GET
/pipeline/{node_num}/{stream_id}/NFV4-PC

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

node_num*integer

Nomor node (0 untuk single-node deployment).

stream_id*string

ID stream video yang akan diproses.

analytic_id*string

ID analitik counting sederhana: NFV4-PC (orang), NFV4-PCA (orang, atribut TIDAK fungsional), atau NFV4-HC (kepala).

Value in"NFV4-PC" | "NFV4-PCA" | "NFV4-HC"

Response Body

application/json

application/json

curl -X GET "http://localhost:4004/pipeline/0/stream_001/NFV4-PC"
{  "code": 200,  "node_num": 0,  "stream_id": "stream_001",  "analytic_id": "NFV4-MPA",  "config": {},  "message": "configuration has been successfully retrieved from the runtime pipeline"}
{  "code": 400,  "message": "analytic_id=NFV4-MPA is already exists in stream=stream_001 !"}
DELETE
/pipeline/{node_num}/{stream_id}/NFV4-PC

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

node_num*integer

Nomor node (0 untuk single-node deployment).

stream_id*string

ID stream video yang akan diproses.

analytic_id*string

ID analitik counting sederhana: NFV4-PC (orang), NFV4-PCA (orang, atribut TIDAK fungsional), atau NFV4-HC (kepala).

Value in"NFV4-PC" | "NFV4-PCA" | "NFV4-HC"

Response Body

application/json

application/json

curl -X DELETE "http://localhost:4004/pipeline/0/stream_001/NFV4-PC"
{  "code": 200,  "message": "pipeline successfully deleted",  "node_num": 0,  "stream_id": "stream_001",  "analytic_id": "NFV4-MPA"}
{  "code": 400,  "message": "analytic_id=NFV4-MPA is already exists in stream=stream_001 !"}

Manajemen Pipeline — Dwelling & Density Sederhana

Endpoint dengan bentuk yang sama untuk NFV4-PD (dwelling orang, masih ditandai Experimental dan tanpa parameter tuning) dan NFV4-HD (density kepala). Ganti segmen terakhir path dengan analytic_id yang diinginkan.

POST
/pipeline/{node_num}/{stream_id}/NFV4-PD

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

node_num*integer

Nomor node (0 untuk single-node deployment).

stream_id*string

ID stream video yang akan diproses.

analytic_id*string

ID analitik dwelling/density sederhana: NFV4-PD (dwelling orang, Experimental) atau NFV4-HD (density kepala).

Value in"NFV4-PD" | "NFV4-HD"

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

curl -X POST "http://localhost:4004/pipeline/0/stream_001/NFV4-PD" \  -H "Content-Type: application/json" \  -d '{}'
{  "code": 200,  "message": "pipeline successfully created",  "node_num": 0,  "stream_id": "stream_001",  "analytic_id": "NFV4-MPA"}
{  "code": 400,  "message": "analytic_id=NFV4-MPA is already exists in stream=stream_001 !"}
PUT
/pipeline/{node_num}/{stream_id}/NFV4-PD

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

node_num*integer

Nomor node (0 untuk single-node deployment).

stream_id*string

ID stream video yang akan diproses.

analytic_id*string

ID analitik dwelling/density sederhana: NFV4-PD (dwelling orang, Experimental) atau NFV4-HD (density kepala).

Value in"NFV4-PD" | "NFV4-HD"

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

curl -X PUT "http://localhost:4004/pipeline/0/stream_001/NFV4-PD" \  -H "Content-Type: application/json" \  -d '{}'
{  "code": 200,  "message": "pipeline successfully updated",  "node_num": 0,  "stream_id": "stream_001",  "analytic_id": "NFV4-MPA"}
{  "code": 400,  "message": "analytic_id=NFV4-MPA is already exists in stream=stream_001 !"}
GET
/pipeline/{node_num}/{stream_id}/NFV4-PD

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

node_num*integer

Nomor node (0 untuk single-node deployment).

stream_id*string

ID stream video yang akan diproses.

analytic_id*string

ID analitik dwelling/density sederhana: NFV4-PD (dwelling orang, Experimental) atau NFV4-HD (density kepala).

Value in"NFV4-PD" | "NFV4-HD"

Response Body

application/json

application/json

curl -X GET "http://localhost:4004/pipeline/0/stream_001/NFV4-PD"
{  "code": 200,  "node_num": 0,  "stream_id": "stream_001",  "analytic_id": "NFV4-MPA",  "config": {},  "message": "configuration has been successfully retrieved from the runtime pipeline"}
{  "code": 400,  "message": "analytic_id=NFV4-MPA is already exists in stream=stream_001 !"}
DELETE
/pipeline/{node_num}/{stream_id}/NFV4-PD

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

node_num*integer

Nomor node (0 untuk single-node deployment).

stream_id*string

ID stream video yang akan diproses.

analytic_id*string

ID analitik dwelling/density sederhana: NFV4-PD (dwelling orang, Experimental) atau NFV4-HD (density kepala).

Value in"NFV4-PD" | "NFV4-HD"

Response Body

application/json

application/json

curl -X DELETE "http://localhost:4004/pipeline/0/stream_001/NFV4-PD"
{  "code": 200,  "message": "pipeline successfully deleted",  "node_num": 0,  "stream_id": "stream_001",  "analytic_id": "NFV4-MPA"}
{  "code": 400,  "message": "analytic_id=NFV4-MPA is already exists in stream=stream_001 !"}

Visualisasi (MJPEG)

GET /mjpeg/{node_num}/{stream_id}/{analytic_id}

Mengembalikan MJPEG stream dengan overlay pipeline yang berjalan (garis counting, polygon ROI, bounding box) — berguna untuk memverifikasi posisi garis/ROI secara langsung di browser. Endpoint generik GET /mjpeg/{node_num}/{stream_id} (tanpa analytic_id) juga tersedia dan menampilkan stream mentah tanpa overlay.

Parameter Query (Opsional)

ParameterTipeDeskripsiDefault
fpsintegerFrame rate output MJPEG0
heightintegerTinggi frame output dalam piksel320
jqintegerKualitas JPEG output (1–100)60
# Buka di browser untuk preview langsung
http://localhost:4004/mjpeg/0/stream_001/NFV4-MPA?fps=15&height=480&jq=70

Bentuk path /pipeline/{node_num}/{stream_id}/{analytic_id}/mjpeg tidak ada — endpoint MJPEG berdiri sendiri di /mjpeg/..., bukan sub-path dari /pipeline/.... Begitu pula /pipeline/{node_num}/{stream_id}/{analytic_id}/snapshot dan /pipeline/{node_num}/{stream_id}/{analytic_id}/config — keduanya tidak ada di server manapun. GET /visual/... juga ada di Visionaire, tetapi mengembalikan halaman viewer HTML, bukan gambar/stream — gunakan /mjpeg/... jika Anda butuh output gambar untuk diintegrasikan.


Event Streaming (WebSocket)

Visionaire mengirim setiap event hasil deteksi/inferensi melalui WebSocket. Untuk berlangganan event yang dihasilkan oleh pipeline People Analytics pada stream tertentu, buka koneksi WebSocket ke endpoint berikut — segmen terakhir harus sama dengan analytic_id pipeline yang dibuat:

ws://<host>:4004/event_channel/{node_num}/{stream_id}/{analytic_id}

Setelah koneksi terbuka, server akan langsung mendorong (push) setiap event ke client tanpa perlu handshake atau pesan subscribe. Tutup koneksi untuk berhenti menerima event.

Parameter Path

ParameterTipeDeskripsi
node_numintegerNomor node tempat stream berjalan (0 = master)
stream_idstringID stream yang akan dipantau
analytic_idstringSalah satu dari NFV4-MPA, NFV4-MPAA, NFV4-MPA2, NFV4-PC, NFV4-PCA, NFV4-HC, NFV4-PD, NFV4-HD

Query Parameter (Opsional)

ParameterTipeDeskripsi
logicstringFilter event berdasarkan nama logic (counting, roi_counting, dwelling, density) yang aktif pada pipeline. Tanpa parameter ini, semua event dari analitik akan dikirim.

Contoh Koneksi

const ws = new WebSocket(
  'ws://localhost:4004/event_channel/0/<stream_id>/NFV4-MPA'
);

ws.onmessage = (msg) => {
  const event = JSON.parse(msg.data);
  console.log(event.primary_text, event.pipeline_data);
};

ws.onerror = (err) => console.error('WebSocket error', err);
ws.onclose = () => console.log('Disconnected');
import asyncio
import json
import websockets

async def listen():
    url = "ws://localhost:4004/event_channel/0/<stream_id>/NFV4-MPA"
    async with websockets.connect(url) as ws:
        async for msg in ws:
            event = json.loads(msg)
            print(event["primary_text"], event["pipeline_data"])

asyncio.run(listen())

Filter Berdasarkan Logic

Jika pipeline Multi-Logics menjalankan beberapa logic sekaligus, Anda dapat memfilter event hanya untuk satu logic dengan menambahkan query parameter:

ws://<host>:4004/event_channel/{node_num}/{stream_id}/NFV4-MPA?logic=counting

Endpoint Channel Lainnya

Untuk mendengarkan event yang lebih luas (lintas analitik atau lintas stream), gunakan endpoint berikut yang dijelaskan pada Developer Guide:

EndpointCakupan
WS /event_channel/Semua event dari seluruh node
WS /event_channel/{node_num}/Semua event dari satu node
WS /event_channel/{node_num}/{stream_id}Semua event dari satu stream (semua analitik)

Struktur Event

Pipeline memancarkan satu event setiap kali sebuah objek selesai diproses oleh logic yang aktif dan lolos semua filter. Event dikirim melalui event channel WebSocket (/event_channel/{node_num}/{stream_id}/{analytic_id}) dan disimpan ke database node kecuali --db-disable-event-store aktif.

Semua modul analitik Visionaire memakai envelope yang sama; bagian yang spesifik People Analytics ada di pipeline_data, dan bentuknya berbeda per logic (counting, roi_counting, dwelling, density).

{
  "timestamp": 1705314600,
  "node_num": 0,
  "stream_id": "5136c6c0916cd30c",
  "stream_name": "Lobby Utama",
  "stream_address": "rtsp://10.7.2.50:554/stream",
  "stream_longitude": 106.823649,
  "stream_latitude": -6.261376,
  "analytic_id": "NFV4-MPAA",
  "primary_text": "person",
  "secondary_text": "in",
  "pipeline_data": {
    "confidence": 0.85,
    "label": "person",
    "area_name": "Main Entrance",
    "direction": "in",
    "tracker_id": 5,
    "group_id": 0,
    "logic": "counting",
    "attributes": {
      "person": { "label": "person", "confidence": 0.85 },
      "age": { "label": "Adult", "confidence": 0.88 },
      "gender": { "label": "Male", "confidence": 0.92 },
      "mask": { "label": "No mask", "confidence": 0.95 },
      "glasses": { "label": "No glasses", "confidence": 0.88 },
      "head_covering": { "label": "None", "confidence": 0.81 },
      "upper_color": { "label": "Blue", "confidence": 0.79 },
      "lower_color": { "label": "Black", "confidence": 0.84 }
    },
    "event_id": "1705314600-3a1f9d4c"
  },
  "image_jpeg": "<base64 JPEG>"
}

Field Envelope

FieldTipeDeskripsi
timestampintWaktu event dalam epoch detik (UTC).
node_numintNomor node tempat pipeline berjalan.
stream_idstringIdentifier stream sumber.
stream_namestringNama stream.
stream_addressstringURL sumber video stream.
stream_longitude, stream_latitudefloatPosisi kamera.
analytic_idstringVarian pipeline yang memancarkan event — salah satu dari NFV4-MPA, NFV4-MPAA, NFV4-MPA2, NFV4-PC, NFV4-PCA, NFV4-HC, NFV4-PD, NFV4-HD.
primary_textstringBergantung pada logic — label objek (counting/roi_counting), nama area (dwelling/density).
secondary_textstringBergantung pada logic — arah (counting/roi_counting), durasi dalam detik berformat teks (dwelling), jumlah estimasi (density).
pipeline_dataobjectDetail hasil logic — lihat tabel per logic di bawah.
image_jpegstring (base64)Crop JPEG objek/area saat event terjadi.

Tidak ada field event_id di level atas maupun timestamp_ms — hanya pipeline_data.event_id (format <timestamp>-<hash8>) dan timestamp dalam detik.

Field pipeline_data per Logic

FieldTipeTersedia Pada
confidencefloatcounting, roi_counting, dwelling
labelstringcounting, roi_counting, dwelling (selalu "person", atau label kelas kepala pada NFV4-HC/NFV4-HD)
area_namestringcounting, roi_counting, dwelling
directionstringcounting, roi_counting ("in" / "out")
tracker_idintegercounting, roi_counting, dwelling
group_idintegercounting, roi_counting, dwelling — terisi jika enable_group_tracking aktif (Multi-Logics saja)
logicstringSemua — "counting", "roi_counting", "dwelling", atau "density"
attributesobjectcounting, roi_counting, dwelling — hanya berisi field selain {} kosong pada NFV4-MPAA/NFV4-MPA2
time_inint (epoch ms)dwelling
time_outint (epoch ms) atau nulldwelling — null jika objek belum keluar ROI saat event dipancarkan
time_alertint (epoch ms) atau nulldwelling (Multi-Logics saja) — terisi jika dwelling_treshold_alert_sec terlampaui
durationfloat (detik)dwelling
areastringdensity (nama ROI)
estimationintegerdensity (jumlah orang dalam ROI)
intervalinteger (detik)density
detectedarraydensity (Multi-Logics saja) — rincian per objek dengan tracker_id, bbox, label, confidence, dan attributes saat dump_attributes: true
event_idstringSemua — hanya ada pada Multi-Logics (NFV4-MPA/NFV4-MPAA/NFV4-MPA2); varian sederhana tidak menyertakan event_id

Varian sederhana (NFV4-PC, NFV4-PCA, NFV4-HC, NFV4-PD, NFV4-HD) memancarkan pipeline_data dengan field yang lebih sedikit — tidak ada group_id, logic, maupun event_id. NFV4-PD/NFV4-HD juga tidak memiliki attributes.

Contoh Event per Logic

{
  "analytic_id": "NFV4-MPA",
  "stream_id": "stream_001",
  "timestamp": 1705314600,
  "primary_text": "person",
  "secondary_text": "in",
  "pipeline_data": {
    "logic": "counting",
    "label": "person",
    "confidence": 0.85,
    "tracker_id": 5,
    "group_id": 0,
    "area_name": "Main Entrance",
    "direction": "in",
    "attributes": { "person": { "label": "person", "confidence": 0.85 } },
    "event_id": "1705314600-3a1f9d4c"
  }
}
{
  "analytic_id": "NFV4-MPA",
  "stream_id": "stream_001",
  "timestamp": 1705314600,
  "primary_text": "Restricted Zone",
  "secondary_text": "45.000 s",
  "pipeline_data": {
    "logic": "dwelling",
    "label": "person",
    "confidence": 0.75,
    "tracker_id": 12,
    "group_id": 0,
    "area_name": "Restricted Zone",
    "time_in": 1705314555000,
    "time_out": null,
    "time_alert": null,
    "duration": 45.0,
    "attributes": { "person": { "label": "person", "confidence": 0.75 } },
    "event_id": "1705314600-9f2a71bc"
  }
}
{
  "analytic_id": "NFV4-MPAA",
  "stream_id": "stream_001",
  "timestamp": 1705314600,
  "primary_text": "Lobby",
  "secondary_text": "25",
  "pipeline_data": {
    "logic": "density",
    "interval": 10,
    "area": "Lobby",
    "estimation": 25,
    "detected": [
      {
        "tracker_id": 7,
        "label": "person",
        "confidence": 0.82,
        "bbox": [100, 150, 180, 370],
        "attributes": { "age": { "label": "Adult", "confidence": 0.81 }, "gender": { "label": "Female", "confidence": 0.9 } }
      }
    ],
    "event_id": "1705314600-6c1d40aa"
  }
}
{
  "analytic_id": "NFV4-PC",
  "stream_id": "stream_001",
  "timestamp": 1705314600,
  "primary_text": "person",
  "secondary_text": "in",
  "pipeline_data": {
    "confidence": 0.85,
    "label": "person",
    "area_name": "Main Entrance",
    "direction": "in",
    "tracker_id": 5
  }
}

On this page