Skip to content

Archie360/SCADA_dashboard

Repository files navigation

Modbus SCADA Demo

A fully self-contained Python simulation of an industrial PLC ↔ SCADA data acquisition stack, built as a portfolio project demonstrating real-world industrial automation concepts.

Alt text

┌───────────────────────────────────────────────────────────────────┐
│                                                                   │
│   ┌─────────────────┐   Modbus TCP   ┌──────────────────────┐     │
│   │  PLC Simulator  │◄──────────────►│    SCADA Client      │     │
│   │ (pymodbus srvr) │    port 5020   │  (pymodbus client)   │     │
│   │                 │                │  → sensor_log.csv    │     │
│   │  5 registers:   │                └──────────────────────┘     │
│   │  • Temperature  │                                             │
│   │  • Pressure     │   Modbus TCP   ┌──────────────────────┐     │
│   │  • Pump status  │◄──────────────►│   Dash Dashboard     │     │
│   │  • Valve status │    port 5020   │  localhost:8050      │     │
│   │  • Flow rate    │                │  live charts + alerts│     │
│   └─────────────────┘                └──────────────────────┘     │
│                                                                   │
└───────────────────────────────────────────────────────────────────┘

What This Demonstrates

Skill How it's shown
Modbus TCP protocol pymodbus server (slave) + client (master), FC3 holding registers
PLC register mapping Raw integer encoding with scale factors (e.g.275 → 27.5 °C)
Industrial data acquisition 1-second polling loop with error recovery and reconnect
SCADA HMI concepts Real-time dashboard with threshold alerting, status badges, trend charts
Data logging Timestamped CSV with alert column for offline analysis
Full-stack OT integration Field device → protocol layer → visualisation layer

Project Structure

modbus-scada-demo/
│
├── config.py            # ★ Single source of truth: hosts, ports, register map, thresholds
├── plc_simulator.py     # Modbus TCP Server — simulates a PLC with 5 live registers
├── scada_client.py      # Modbus TCP Client — polls PLC, logs to CSV, prints alerts
├── dashboard.py         # Dash web dashboard — live gauges, trend charts, alerts
├── run_demo.py          # One-command launcher for all three processes
│
├── data/
│   └── sensor_log.csv   # Created at runtime by scada_client.py
│
├── requirements.txt
└── .gitignore

Quick Start

1 — Install dependencies

pip install -r requirements.txt

2a — Run everything with one command

python run_demo.py

Then open http://localhost:8050 in your browser. Press Ctrl-C once to stop all processes.

2b — Run each component in a separate terminal (recommended for learning)

# Terminal 1 — start the PLC
python plc_simulator.py

# Terminal 2 — start the data logger (after PLC is running)
python scada_client.py

# Terminal 3 — start the dashboard
python dashboard.py

Register Map

All data is stored in Holding Registers (Modbus Function Code 3).

Address Tag Raw encoding Engineering value Example
0 Temperature int × 0.1 → °C 20–41 °C 27527.5 °C
1 Pressure int × 0.01 → bar 1–5 bar 3503.50 bar
2 Pump Status 0 or 1 OFF / ON 1 → Pump running
3 Valve Status 0 or 1 CLOSED / OPEN 0 → Valve closed
4 Flow Rate int × 0.1 → L/min 0–18 L/min 12512.5 L/min

Simulation Physics

The PLC simulator advances a physics model every second:

  • Temperature — 60-second sine wave: 27 + 14·sin(2π·t/60) + Gaussian noise
  • Pressure — 40-second cosine wave: 3 + 2·cos(2π·t/40) + Gaussian noise
  • Pump — switches ON when temperature > 32 °C (cooling pump logic)
  • Valve — opens when pressure > 3.8 bar (pressure-relief valve logic)
  • Flow — proportional to pump state with turbulence noise

This creates natural threshold crossings that let you see the alert system fire without manual intervention.


Alert Thresholds

Defined in config.py — change them freely:

Tag Low High
Temperature 15 °C 38 °C
Pressure 1.5 bar 5.0 bar
Flow Rate 3.0 L/min 18.0 L/min

CSV Log Format

data/sensor_log.csv is created automatically:

timestamp,temperature_c,pressure_bar,pump_status,valve_status,flow_rate_lpm,alerts
2024-11-01 14:23:01,27.5,3.50,1,0,12.5,OK
2024-11-01 14:23:02,38.9,4.92,1,1,14.1,🚨 HIGH Temperature: 38.9 °C (max 38.0 °C)

Load it in pandas for post-run analysis:

import pandas as pd
df = pd.read_csv("data/sensor_log.csv", parse_dates=["timestamp"])
df.set_index("timestamp", inplace=True)
df[["temperature_c", "pressure_bar"]].plot()

Configuration

All parameters live in config.py:

MODBUS_HOST    = "localhost"
MODBUS_PORT    = 5020       # change to 502 for a real PLC (needs root on Linux)
MODBUS_SLAVE_ID = 1

THRESHOLDS = {
    "temperature": {"low": 15.0, "high": 38.0},
    ...
}

To point the client and dashboard at a real PLC instead of the simulator:

python scada_client.py --host 192.168.1.100 --port 502

Tech Stack

  • pymodbus 3.7 — Modbus TCP server and client
  • Dash 2.17 — Reactive web framework for the HMI
  • Plotly 5.22 — Interactive charts
  • Python 3.10+

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages