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
- Open the Node-RED UI (
http://<server>:1880) in your browser. - Click the menu in the top-right corner → Import.
- Select the
demo_fabrika_rest.jsonfile → Import → Deploy.
Once the flow is active all endpoints are ready to receive requests.
Adding to Pirivision
- Go to Port → New Data Source → REST API.
- Enter the Node-RED server address as the Base URL (e.g.
http://<server>:1880). - Click Test and Save to store the connection.
Once saved, select this source in Compass and use any of the endpoints listed above.