Systems Analysis architecture hardware software scada

From Pump to Cloud: Hardware and Software Architecture Explained

By Jason Lillywhite, PE March 10, 2026

A frequent question we get from utilities and engineering firms is: "How does our physical pump data actually reach your cloud simulators?"

Understanding the full pipeline—from the physical hardware at the pump station to the software architecture running our Digital Twins—is crucial for modern water systems evaluation. This post breaks down the common setups.

1. The Hardware Telemetry Setup

Before any software can run a simulation, we need telemetry. Modern pump stations are equipped with various sensors (flow meters, pressure transducers, RPM dials). These sensors feed raw analog signals into a Programmable Logic Controller (PLC) which digitizes the data.

Here is the typical flow of data from the concrete floor to the cloud:

graph LR
    subgraph "Local Pump Station Hardware"
    A((Sensors<br>Flow/Head)) -->|Analog 4-20mA| B[PLC Panel]
    B -->|Modbus/TCP| C{SCADA Server}
    end

    subgraph "Remote Cloud Infrastructure"
    C -.->|Secure API Push| D[(Time-Series<br>Database)]
    D -->|Query| E([Digital Twin Engine])
    end

    %% Styling
    style A fill:#fef3c7,stroke:#d97706
    style B fill:#e2e8f0,stroke:#64748b
    style C fill:#e0f2fe,stroke:#0284c7,stroke-width:2px
    style D fill:#f8fafc,stroke:#94a3b8
    style E fill:#dcfce7,stroke:#16a34a,stroke-width:2px

The SCADA server acts as the local brain, but the magic happens when it securely pushes that time-series data up to a cloud database, making it instantly available for computational modeling.

2. The Software Architecture (Digital Twin)

Once the raw data hits our cloud, our software stack takes over. Lillywhite Water Solutions relies on a robust Django application paired with an asynchronous job queue to handle heavy hydraulic simulations without freezing the user interface.

graph TD
    %% Define Nodes
    User([Web Dashboard User])
    Django[Django Web Server]
    Worker[Django-Q Asynchronous Worker]
    SimEngine[Lillywhite Simulation Engine<br>EPANET/Custom Python]
    DB[(PostgreSQL/SQLite<br>Models & Results)]

    %% Connections
    User -->|Initiates Simulation Request| Django
    Django -->|Saves Job| DB
    Django -->|Dispatches Task| Worker
    Worker -->|Executes Complex Math| SimEngine
    SimEngine -->|Updates Status/Results| DB
    DB -.->|Polled via HTMX/JS| User

    %% Styling
    style User fill:#fef3c7,stroke:#d97706
    style Django fill:#e0f2fe,stroke:#0284c7,stroke-width:2px
    style Worker fill:#f1f5f9,stroke:#64748b,stroke-dasharray: 5 5
    style SimEngine fill:#dcfce7,stroke:#16a34a,stroke-width:2px
    style DB fill:#f8fafc,stroke:#94a3b8

Why Asynchronous Workers?

As you can see in the diagram above, the Django Web Server never runs the complex simulation directly. If it did, your web browser would spin endlessly. Instead, it delegates the intense calculations to the Django-Q Worker. This allows the user to continue navigating the site or viewing other charts while the Simulation Engine churns through thousands of hydraulic parameters in the background.

With these architectures in place, we guarantee both the safe transmission of hardware data and the high-performance execution of our software simulations!