CREATE SCHEMA IF NOT EXISTS mv_hot; CREATE TABLE IF NOT EXISTS mv_hot.edge_oee_machine_targets ( machine_id TEXT PRIMARY KEY, machine_name TEXT NOT NULL, asset TEXT NOT NULL, target_cycle_rate_ppm NUMERIC(10,2) NOT NULL DEFAULT 10.00, value_hour_eur NUMERIC(10,2) NOT NULL DEFAULT 36.00, quality_pct_default NUMERIC(10,2) NOT NULL DEFAULT 100.00, notes TEXT ); INSERT INTO mv_hot.edge_oee_machine_targets ( machine_id, machine_name, asset, target_cycle_rate_ppm, value_hour_eur, quality_pct_default, notes ) VALUES ( 'C_DEMO', 'Cortadora demo', 'revpi_oee_node_01', 10.00, 36.00, 100.00, 'Demo Edge-OEE con I_1 como marcha/paro, I_2 como pulso de ciclo y SDM120-M como energĂ­a real.' ) ON CONFLICT (machine_id) DO UPDATE SET machine_name = EXCLUDED.machine_name, asset = EXCLUDED.asset, target_cycle_rate_ppm = EXCLUDED.target_cycle_rate_ppm, value_hour_eur = EXCLUDED.value_hour_eur, quality_pct_default = EXCLUDED.quality_pct_default, notes = EXCLUDED.notes; CREATE OR REPLACE VIEW mv_hot.edge_oee_live_telemetry AS SELECT r.ts, EXTRACT(EPOCH FROM (now() - r.ts))::int AS age_s, r.tenant, r.site, r.asset, COALESCE(r.machine_id, r.payload_json ->> 'machine_id') AS machine_id, COALESCE(r.order_id, r.payload_json ->> 'order_id') AS order_id, r.voltage_l1_v, r.current_l1_a, r.power_total_kw, r.frequency_hz, r.import_kwh, r.export_kwh, r.comm_ok, r.error_text, CASE WHEN r.payload_json ? 'machine_auto_signal' THEN (r.payload_json ->> 'machine_auto_signal')::boolean ELSE NULL END AS machine_auto_signal, CASE WHEN r.payload_json ? 'machine_running' THEN (r.payload_json ->> 'machine_running')::boolean ELSE NULL END AS machine_running, CASE WHEN r.payload_json ? 'cycle_pulse_count' THEN (r.payload_json ->> 'cycle_pulse_count')::bigint ELSE NULL END AS cycle_pulse_count, CASE WHEN r.payload_json ? 'cycle_rate_ppm' THEN (r.payload_json ->> 'cycle_rate_ppm')::numeric ELSE NULL END AS cycle_rate_ppm, CASE WHEN r.payload_json ? 'last_cycle_age_s' AND r.payload_json ->> 'last_cycle_age_s' IS NOT NULL AND r.payload_json ->> 'last_cycle_age_s' <> 'null' THEN (r.payload_json ->> 'last_cycle_age_s')::numeric ELSE NULL END AS last_cycle_age_s, r.payload_json -> 'digital_inputs' AS digital_inputs, r.payload_json FROM mv_hot.edge_oee_eastron_readings r WHERE r.asset = 'revpi_oee_node_01' ORDER BY r.ts DESC; CREATE OR REPLACE VIEW mv_hot.edge_oee_latest_machine_snapshot AS SELECT DISTINCT ON (asset) * FROM mv_hot.edge_oee_live_telemetry ORDER BY asset, ts DESC;