Skip to content

Synthetic Data — PostgreSQL

The Demo Factory dataset for PostgreSQL covers the vast majority of chart and query examples in Pirivision. Below you will find which tables are created, how the data is generated, and how to add this source to Pirivision.


Created Tables

All tables are created in the public schema.

Reference Tables

Four lookup tables holding fixed values:

-- 2 production lines
CREATE TABLE public.hatlar (
    hat_id  text PRIMARY KEY,
    ad      text NOT NULL
);

-- 6 machines (3 per line)
CREATE TABLE public.makineler (
    makine_id  text PRIMARY KEY,
    hat_id     text NOT NULL REFERENCES public.hatlar (hat_id),
    marka      text NOT NULL,
    model      text NOT NULL
);

-- 3 shifts
CREATE TABLE public.vardiyalar (
    vardiya    text PRIMARY KEY,
    baslangic  time NOT NULL,
    bitis      time NOT NULL,
    aciklama   text NOT NULL
);

-- 4 product families
CREATE TABLE public.urun_aileleri (
    urun_kodu  text PRIMARY KEY,
    ad         text NOT NULL
);

Fixed values inserted into these tables:

INSERT INTO public.hatlar VALUES
    ('HAT-1', 'Production Line 1'),
    ('HAT-2', 'Production Line 2');

INSERT INTO public.makineler VALUES
    ('M01', 'HAT-1', 'Siemens',    'PXC-100'),
    ('M02', 'HAT-1', 'ABB',        'IRB-2600'),
    ('M03', 'HAT-1', 'Fanuc',      'R-2000iC'),
    ('M04', 'HAT-2', 'Kuka',       'KR-210'),
    ('M05', 'HAT-2', 'Mitsubishi', 'RV-7FR'),
    ('M06', 'HAT-2', 'Yaskawa',    'GP-25');

INSERT INTO public.vardiyalar VALUES
    ('V1', '06:00', '14:00', 'Morning Shift'),
    ('V2', '14:00', '22:00', 'Afternoon Shift'),
    ('V3', '22:00', '06:00', 'Night Shift');

INSERT INTO public.urun_aileleri VALUES
    ('A', 'Product-A'), ('B', 'Product-B'),
    ('C', 'Product-C'), ('D', 'Product-D');

Event and Time-Series Tables

sensor_zaman_serisi — ~51 840 rows

Temperature and pressure readings at 5-minute intervals for every machine over 30 days.

CREATE TABLE public.sensor_zaman_serisi (
    ts          timestamptz NOT NULL,
    hat_id      text        NOT NULL REFERENCES public.hatlar    (hat_id),
    makine_id   text        NOT NULL REFERENCES public.makineler (makine_id),
    sicaklik    numeric(6,2),
    basinc      numeric(5,2)
);

Data is generated with the formula 30 days × 288 time points × 6 machines. Temperature is computed from a 70 °C base value with an hourly sine wave, a machine-specific offset, and small random noise:

INSERT INTO public.sensor_zaman_serisi (ts, hat_id, makine_id, sicaklik, basinc)
SELECT
    g.ts,
    m.hat_id,
    m.makine_id,
    ROUND( (70
            + 5 * sin(extract(epoch FROM g.ts) / 3600.0)
            + (CASE WHEN m.makine_id IN ('M01','M04') THEN -1.5
                    WHEN m.makine_id IN ('M02','M05') THEN  0.0
                    ELSE  1.5 END)
            + (random() - 0.5) * 3.0
           )::numeric, 2) AS sicaklik,
    ROUND( (6.5
            + 0.4 * sin(extract(epoch FROM g.ts) / 5400.0)
            + (random() - 0.5) * 0.3
           )::numeric, 2) AS basinc
FROM generate_series(
        NOW() - INTERVAL '30 days',
        NOW(),
        INTERVAL '5 minutes'
     ) AS g(ts)
CROSS JOIN public.makineler AS m;

vardiya_uretim — ~540 rows

Production count and target per machine and shift for every day.

CREATE TABLE public.vardiya_uretim (
    ts            date    NOT NULL,
    hat_id        text    NOT NULL REFERENCES public.hatlar        (hat_id),
    makine_id     text    NOT NULL REFERENCES public.makineler     (makine_id),
    vardiya       text    NOT NULL REFERENCES public.vardiyalar    (vardiya),
    urun_kodu     text    NOT NULL REFERENCES public.urun_aileleri (urun_kodu),
    uretim_adet   integer NOT NULL,
    hedef         integer NOT NULL
);
INSERT INTO public.vardiya_uretim
    (ts, hat_id, makine_id, vardiya, urun_kodu, uretim_adet, hedef)
SELECT
    d.gun,
    m.hat_id,
    m.makine_id,
    v.vardiya,
    (ARRAY['A','B','C','D'])[1 + floor(random()*4)::int],
    (250 + floor(random() * 200))::int,
    400
FROM generate_series(
        CURRENT_DATE - INTERVAL '30 days',
        CURRENT_DATE,
        INTERVAL '1 day'
     ) AS d(gun)
CROSS JOIN public.makineler AS m
CROSS JOIN public.vardiyalar AS v;

duris_log

5–15 downtime records per machine per day; downtime type and duration are chosen randomly.

CREATE TABLE public.duris_log (
    ts          timestamptz NOT NULL,
    hat_id      text        NOT NULL REFERENCES public.hatlar    (hat_id),
    makine_id   text        NOT NULL REFERENCES public.makineler (makine_id),
    duris_tipi  text        NOT NULL,
    sure_dk     integer     NOT NULL
);
INSERT INTO public.duris_log (ts, hat_id, makine_id, duris_tipi, sure_dk)
SELECT
    d.gun + (random() * INTERVAL '24 hours'),
    m.hat_id,
    m.makine_id,
    (ARRAY['Planned Maintenance','Breakdown','Setup Change',
           'Material Wait','Shift Handover'])
        [1 + floor(random()*5)::int],
    (5 + floor(random() * 90))::int
FROM generate_series(
        CURRENT_DATE - INTERVAL '30 days',
        CURRENT_DATE,
        INTERVAL '1 day'
     ) AS d(gun)
CROSS JOIN public.makineler AS m
CROSS JOIN generate_series(1, (5 + floor(random() * 10))::int) AS k(n);

alarm_log

2–8 alarms per day; five alarm codes, machine, and priority are assigned randomly.

CREATE TABLE public.alarm_log (
    ts           timestamptz NOT NULL,
    makine_id    text        NOT NULL REFERENCES public.makineler (makine_id),
    alarm_kodu   text        NOT NULL,
    aciklama     text        NOT NULL,
    oncelik      text        NOT NULL
);
CREATE INDEX ON public.alarm_log (ts DESC);
INSERT INTO public.alarm_log (ts, makine_id, alarm_kodu, aciklama, oncelik)
SELECT
    d.gun + (random() * INTERVAL '24 hours'),
    'M0' || (1 + floor(random()*6))::int,
    (ARRAY['ALR-001','ALR-002','ALR-003','ALR-004','ALR-005'])
        [1 + floor(random()*5)::int],
    (ARRAY['High temperature threshold exceeded','Low pressure warning',
           'Motor vibration level high','Oil level critical',
           'Sensor communication error'])
        [1 + floor(random()*5)::int],
    (ARRAY['Low','Medium','High','Critical'])
        [1 + floor(random()*4)::int]
FROM generate_series(
        CURRENT_DATE - INTERVAL '30 days',
        CURRENT_DATE,
        INTERVAL '1 day'
     ) AS d(gun)
CROSS JOIN generate_series(1, (2 + floor(random() * 7))::int) AS k(n);

oee_gunluk

30 days of daily OEE metrics per line; values are generated randomly within realistic ranges.

CREATE TABLE public.oee_gunluk (
    ts                 date         NOT NULL,
    hat_id             text         NOT NULL REFERENCES public.hatlar (hat_id),
    oee_yuzde          numeric(5,2) NOT NULL,
    performans         numeric(5,2) NOT NULL,
    kalite             numeric(5,2) NOT NULL,
    kullanilabilirlik  numeric(5,2) NOT NULL,
    PRIMARY KEY (ts, hat_id)
);
INSERT INTO public.oee_gunluk
    (ts, hat_id, oee_yuzde, performans, kalite, kullanilabilirlik)
SELECT
    d.gun,
    h.hat_id,
    ROUND((75 + (random() * 20))::numeric, 2),   -- OEE 75–95%
    ROUND((85 + (random() * 12))::numeric, 2),   -- Performance 85–97%
    ROUND((95 + (random() *  5))::numeric, 2),   -- Quality 95–100%
    ROUND((88 + (random() * 10))::numeric, 2)    -- Availability 88–98%
FROM generate_series(
        CURRENT_DATE - INTERVAL '30 days',
        CURRENT_DATE,
        INTERVAL '1 day'
     ) AS d(gun)
CROSS JOIN public.hatlar AS h;

recete_parametre

8 fixed machine parameters for M01, 4 for M02.

CREATE TABLE public.recete_parametre (
    makine_id      text          NOT NULL REFERENCES public.makineler (makine_id),
    parametre_adi  text          NOT NULL,
    deger          numeric(10,2) NOT NULL,
    birim          text          NOT NULL,
    siralama       integer       NOT NULL,
    PRIMARY KEY (makine_id, parametre_adi)
);

INSERT INTO public.recete_parametre VALUES
    ('M01', 'Temperature Setpoint',  85.00, '°C',   1),
    ('M01', 'Pressure Setpoint',      6.50, 'bar',  2),
    ('M01', 'Line Speed',           120.00, 'm/min', 3),
    ('M01', 'Mix Ratio',             45.00, '%',    4),
    ('M01', 'Cooling Time',          30.00, 's',    5),
    ('M01', 'Press Tonnage',        250.00, 'ton',  6),
    ('M01', 'Oil Temperature',       55.00, '°C',   7),
    ('M01', 'Cycle Time',            18.50, 's',    8),
    ('M02', 'Temperature Setpoint',  90.00, '°C',   1),
    ('M02', 'Pressure Setpoint',      7.00, 'bar',  2),
    ('M02', 'Line Speed',           100.00, 'm/min', 3),
    ('M02', 'Mix Ratio',             50.00, '%',    4);

Loading into the Database

Run the SQL script against your PostgreSQL database:

psql -h <server> -U <user> -d <database> -f demo_fabrika.sql

When the script completes, you will see summary messages reporting the row count for each table:

NOTICE:  sensor_zaman_serisi : 51840 rows
NOTICE:  vardiya_uretim      : 540 rows
NOTICE:  oee_gunluk          : 62 rows
...

Running the script again is safe — it drops the existing demo tables first, then re-creates them.


Adding to Pirivision

  1. Go to Port → New Data Source → PostgreSQL.
  2. Enter the server, port, database, and credentials.
  3. Click Test and Save to store the connection.

Once saved, you can write queries against this database in Compass.