Description
This project is a mini-SCADA simulation of a 3-Phase Separator, designed using Inductive Automation’s Ignition Perspective module.
It visually represents the oil, gas, and water separation process using animated SVG components, dynamic tag bindings, and live status colors.
The system displays real-time instrumentation (pressure, flow, and level indicators) and valve operations (feed, oil, gas, and water lines).
All components are connected to Ignition’s Programmable Device Simulator, allowing realistic process behavior without external PLC hardware.
The design emphasizes reusability, data-driven visualization, and field-accurate logic for use in operator training, portfolio demonstration, or SCADA system development practice.
Purpose of this Project
Th goal of this project was to:
| Simulate real SCADA logic for a 3-phase separator using Ignition’s tag and scripting features. |
| Demonstrate live visualization and alarm logic (normal, warning, and alarm conditions). |
Develop reusable components such as Level_Indicator and Valve that can be dropped into any industrial process. |
| Provide a portfolio-ready project that shows control system design, process logic, and visualization skills. |
This setup mirrors real oil & gas facility operations where level, flow, and pressure indicators interact with valves to maintain separation efficiency.
Components
| Component | Description | Role |
|---|---|---|
| Main View (3-Phase Separator) | Contains the SVG layout of the tank, valves, and piping. | Serves as the process overview. Each element is clickable and linked to live data. |
| Level_Indicator View | Independent view showing one process variable (e.g., PC, FC, LC). | Converts tag data into a live animated gauge with alarms and thresholds. |
| Valve View | Independent view showing one valve’s open/close/fault state. | Animates color and blinking to show live operation or faults. |
| Session Custom Paths | Stores all tag paths for the simulated process. | Centralizes configuration—one change updates all linked bindings. |
Below are the standalone SVGs:




Component Details and Bindings
View Parameters and Custom Properties
Level_Indicator View

| Parameter | Type | Description |
|---|---|---|
euHi / euLo | Float | Engineering range of the variable. |
level_name | String | Identifies which indicator (PC, FC, LC). |
pvPath | String | Tag path to the live process variable. |
units | String | Unit of measurement (%, kPa, m³/h). |
Custom Properties
| Name | Description |
|---|---|
pv | Reads the tag value via {view.params.pvPath}. |
valueText | Displays formatted process value and units. |
pct | Calculates percent of full scale. |
state | Evaluates alarm status (normal/warn/alarm). |
hiHi, hi, lo, loLo | Dynamic thresholds depending on indicator type. |
Bindings (Visual)
SVG fill-paint → Script transform for color and blinking.
Label (valueText) → Displays numeric value and units.
Label_0 (state) → Shows text “normal / warn / alarm” with matching color.
Logic
Percent Calculation
min(
max(
( {this.custom.pv} - {view.params.euLo} ) /
max(0.000001, {view.params.euHi} - {view.params.euLo}),
0),
1)
Normalizes any PV between its engineering limits into a 0–1 percentage.
State Logic
if(
{value} >= {this.custom.hiHi} || {value} <= {this.custom.loLo},
"alarm",
if(
{value} >= {this.custom.hi} || {value} <= {this.custom.lo},
"warn",
"normal"
)
)
Determines the indicator’s state based on high/low threshold bands.
Dynamic Thresholds
if({value}="PC",95,
if({value}="FC",100,600))
Each indicator type (Pressure, Flow, Level) has different alarm limits.
Color/Blinking Script
try:
sec = system.date.getSecond(self.view.custom.clock)
except:
sec = system.date.getSecond(system.date.now())
if value == "alarm":
return "#E53935" if (sec % 2) == 0 else "#808080"
elif value == "warn":
return "#FFB300"
else:
return "#808080"
This Python script makes the SVG flash red when in alarm, amber for warning, and gray when normal.
Valve View

| Parameter | Type | Description |
|---|---|---|
valve_name | String | The display name of the valve shown on the operator interface (e.g., Feed Valve, Gas Valve, Water Valve). Used for identification beside the SVG. |
statePath | String | Tag path connected to the simulated valve position signal (e.g., [default]_MyDevice_/Random/Short1). Represents the valve’s open/closed feedback status or percentage. |
faultPath | String | Tag path connected to the simulated valve fault signal (e.g., [default]_MyDevice_/Random/Short2). When this signal is very low (≤ 1), a fault condition is triggered. |
Custom Properties
| Name | Description |
|---|---|
isOpen | Evaluates whether the valve is open. Returns True when the valve’s position feedback is ≥ 95% (open), False when ≤ 5% (closed), and indicates moving between these limits. |
fault | Boolean condition derived from the fault signal. Returns True when the fault signal ≤ 1 (fault active), otherwise False. |
state | Determines the valve condition ("open", "mov", "closed", or "fault") based on priority. Drives both the SVG fill color and state text. |
Bindings (Visual)
SVG fill-paint → Script Transform — Controls color and blinking based on the valve’s state.
Label (valve_name) → Displays the name of the valve.
Label_0 (state) → Shows the valve’s state text (“OPEN”, “MOV”, “CLOSED”, “FAULT”) with color matching the SVG fill.
Logic
State Logic
if(
{view.params.faultPath} != "" && isGood({this.custom.fault}) && {this.custom.fault},
"fault",
if(
isGood({this.custom.isOpen}) && {this.custom.isOpen},
"open",
if(tag({view.params.statePath}) > 5 && tag({view.params.statePath}) < 95, "mov", "closed")
)
)
Determines the valve’s state based on the open/close feedback and fault conditions.
Priority: Fault → Open → Moving → Closed.
Color
if value == "fault":
return "#E53935"
elif value == "open":
return "#808080"
elif value == "mov":
return "#607D8B"
else:
return "#000000"
This script dynamically changes the valve’s SVG color based on its operational state:
- Open → Green
- Moving → Amber
- Closed → Slate Gray
- Fault → Blinking Red/White
The blinking animation is achieved by toggling color each second using the system clock.
Overall Process Flow
- Programmable Device Simulator generates analog and digital tag values (
SineandRandomtags). - Bindings connect those simulated tags to each SVG-based component.
- Script transforms and expressions interpret tag values into readable states.
- Color and label bindings visualize those states on screen.
- When a fault or alarm condition occurs, the associated SVG blinks red, providing intuitive operator feedback.
View the Interactive Displays
If you’d like to see the Level 2 screen in full clarity, you can view them directly on my live demo page:
➡️ SCADA Display Portfolio – Michelle Alzola
This page is a simple viewer designed to showcase the UI/UX layout only.
The displays are static and do not represent a functioning SCADA system—they are visual mockups intended for portfolio demonstration purposes.
Final Remarks
This 3-Phase Separator project demonstrates a complete mini-SCADA workflow:
- Real-time data acquisition from a simulated source.
- Logical state evaluation for alarms and movement.
- Dynamic SVG visualization with meaningful color coding.
- Modular design — components can be reused across different systems.
References
Jonach, T., & Haddadi, B. (2023, May 09). Dynamic Simulation of a Gas and Oil Separation Plant with Focus on the Water Output Quality. Retrieved from MDPI: https://www.mdpi.com/1996-1073/16/10/4111



