Skip to content

Synthetic Data — REST API

The Demo Factory flow for REST API serves seven mock endpoints via Node-RED. Every request returns a realistic JSON response generated on the fly with JavaScript, so you can test the REST data source in Pirivision without a real backend service.


Endpoint List

Endpoint Response Description
GET /api/oee/today Single object Live OEE summary
GET /api/sayac/anlik Single object Monotonically increasing production counter
GET /api/sicaklik/trend?hat=HAT-1&hours=24 Array Temperature history at 5-minute granularity
GET /api/vardiya/dun Array (3) Yesterday's total production per shift
GET /api/durus/dagilim?gun=7 Array (5) Downtime type distribution
GET /api/alarm/son50 Array (50) Last 50 alarm records
GET /api/recete?makine=M01 Array (8 / 4) Machine recipe parameters

Response Generation Logic

GET /api/oee/today

OEE components are generated randomly within realistic ranges on each request:

msg.payload = {
    hat:               "HAT-1",
    oee:               +(78 + Math.random() * 12).toFixed(1),   // 78–90 %
    performans:        +(85 + Math.random() * 10).toFixed(1),   // 85–95 %
    kalite:            +(95 + Math.random() *  4).toFixed(1),   // 95–99 %
    kullanilabilirlik: +(88 + Math.random() *  8).toFixed(1),   // 88–96 %
    ts:                new Date().toISOString()
};

Example response:

{ "hat": "HAT-1", "oee": 83.4, "performans": 91.2, "kalite": 97.1, "kullanilabilirlik": 92.5, "ts": "..." }


GET /api/sayac/anlik

Increments by one on every request; resets only when Node-RED restarts:

let n = context.get('n') || 0;
n = n + 1;
context.set('n', n);

msg.payload = { sayac: n, ts: new Date().toISOString(), hat: "HAT-1" };

GET /api/sicaklik/trend?hat=HAT-1&hours=24

Generates historical data points at 5-minute granularity based on the hours parameter (default: 24 hours → ~289 points). Values use the same formula as the PostgreSQL temperature model:

const hat    = msg.req.query.hat   || 'HAT-1';
const hours  = parseInt(msg.req.query.hours || '24', 10);
const points = hours * 12;   // 12 points per hour
const now    = Date.now();
const data   = [];

for (let i = points; i >= 0; i--) {
    const ts    = new Date(now - i * 5 * 60 * 1000);
    const t     = ts.getTime() / 1000;
    const value = +(70 + 5 * Math.sin(t / 3600) + (Math.random() - 0.5) * 1.5).toFixed(2);
    data.push({ ts: ts.toISOString(), value, unit: "°C", makine_id: "M01", hat_id: hat });
}
msg.payload = data;

GET /api/vardiya/dun

Total production count for each of yesterday's three shifts:

msg.payload = [
    { vardiya: "V1", toplam: 4000 + Math.floor(Math.random() * 800) },
    { vardiya: "V2", toplam: 4000 + Math.floor(Math.random() * 800) },
    { vardiya: "V3", toplam: 3500 + Math.floor(Math.random() * 800) }
];

GET /api/durus/dagilim?gun=7

Returns a count for five downtime types scaled by the gun (days) parameter, sorted descending:

const gun    = parseInt(msg.req.query.gun || '7', 10);
const tipler = ['Planned Maintenance','Breakdown','Setup Change','Material Wait','Shift Handover'];

msg.payload = tipler
    .map(t => ({ duris_tipi: t, adet: Math.floor(20 + Math.random() * 120 * (gun / 7)) }))
    .sort((a, b) => b.adet - a.adet);

GET /api/alarm/son50

50 alarm records; each with a random machine, code, description, and priority:

const kodlar      = ['ALR-001','ALR-002','ALR-003','ALR-004','ALR-005'];
const aciklamalar = [
    'High temperature threshold exceeded', 'Low pressure warning',
    'Motor vibration level high', 'Oil level critical',
    'Sensor communication error'
];
const oncelikler = ['Low','Medium','High','Critical'];
const now = Date.now();
const data = [];

for (let i = 0; i < 50; i++) {
    const ts = new Date(now - i * Math.floor(Math.random() * 20 * 60 * 1000));
    data.push({
        zaman:      ts.toLocaleString('en-US'),
        makine_id:  'M0' + (1 + Math.floor(Math.random() * 6)),
        alarm_kodu: kodlar[Math.floor(Math.random() * kodlar.length)],
        aciklama:   aciklamalar[Math.floor(Math.random() * aciklamalar.length)],
        oncelik:    oncelikler[Math.floor(Math.random() * oncelikler.length)]
    });
}
msg.payload = data;

GET /api/recete?makine=M01

Returns the recipe list for the given machine. M01 returns 8 parameters, M02 returns 4; any other value falls back to the M01 list:

const makine    = msg.req.query.makine || 'M01';
const paramsM01 = [
    { etiket: 'Temperature Setpoint', deger: '85.00 °C'    },
    { etiket: 'Pressure Setpoint',    deger: '6.50 bar'    },
    { etiket: 'Line Speed',           deger: '120.00 m/min' },
    { etiket: 'Mix Ratio',            deger: '45.00 %'     },
    { etiket: 'Cooling Time',         deger: '30.00 s'     },
    { etiket: 'Press Tonnage',        deger: '250.00 ton'  },
    { etiket: 'Oil Temperature',      deger: '55.00 °C'    },
    { etiket: 'Cycle Time',           deger: '18.50 s'     }
];
const paramsM02 = [
    { etiket: 'Temperature Setpoint', deger: '90.00 °C'    },
    { etiket: 'Pressure Setpoint',    deger: '7.00 bar'    },
    { etiket: 'Line Speed',           deger: '100.00 m/min' },
    { etiket: 'Mix Ratio',            deger: '50.00 %'     }
];
msg.payload = makine === 'M02' ? paramsM02 : paramsM01;

Loading into Node-RED

  1. Open the Node-RED UI (http://<server>:1880) in your browser.
  2. Click the menu in the top-right corner → Import.
  3. Select the demo_fabrika_rest.json file → ImportDeploy.

Once the flow is active all endpoints are ready to receive requests.


Adding to Pirivision

  1. Go to Port → New Data Source → REST API.
  2. Enter the Node-RED server address as the Base URL (e.g. http://<server>:1880).
  3. Click Test and Save to store the connection.

Once saved, select this source in Compass and use any of the endpoints listed above.