Skip to Content

← All functionalities

Geotechnical slope monitoringServer (Node-RED)FTPCommunication

Delivering sensor data to an official platform by FTP

Many official auscultation platforms still ingest data the classic way: a CSV file dropped on an FTP server at fixed intervals. This FTP data upload example shows the Python script we run in a real slope monitoring deployment: Node-RED aggregates readings from four ESP32 PLC 14 Ethernet stations into a JSON file, and the script turns them into a timestamped .est file with 169 channels and pushes it with ftplib every measurement interval.

A strict file format, generated safely

The platform expects one CSV line per delivery — record id, date, time and a fixed number of channel columns. The script iterates canal_001 to canal_169 and writes an empty column for any channel without data, so a sensor outage never shifts the columns of the ones that did report. Filenames embed a full timestamp, making every delivery unique and traceable.

Twelve lines of ftplib

Python's standard library covers the whole transfer: FTP(host), login, cwd and storbinary inside a try/finally that guarantees quit(). Credentials are placeholders (FTP_USER, FTP_PASS) to be loaded from environment variables in production — never hardcode them in a script that lives in a repository.

Failures leave evidence

If the upload fails, the .est file stays in the outbox directory for manual retry and the script exits non-zero, which Node-RED's exec node catches to trigger an email alert. The platform also notices the missing interval on its side, so a silent gap is impossible.

A snippet from the implementation

Straight from the example as deployed on the Server (Node-RED) — copy it freely:

def read_readings(path):
    """Loads the JSON with the latest readings aggregated by Node-RED.

    Expected format: {"channel_001": 12.34, "channel_002": -0.07, ...}
    """
    try:
        with open(path) as f:
            return json.load(f)
    except (OSError, ValueError) as e:
        print(f"ERROR reading readings: {e}")
        return {}

The full example is a complete program — wiring header, setup and main loop — ready to adapt to your application.

Frequently asked questions

Why FTP instead of a REST API?

Because the receiving platform defines the interface, and in geotechnical monitoring FTP file drops remain the standard. The pattern is decades old, firewall-friendly and trivial to audit from the file listing.

Where does the channel data come from?

Node-RED polls each PLC station over HTTP, merges the readings into a JSON file on disk, and launches this script with an exec node each measurement interval. The script and the flows stay decoupled.

How should credentials be handled in production?

Keep FTP_USER and FTP_PASS out of the code. Load them from environment variables or a config file with restricted permissions outside the repository, and rotate them if the device is serviced by third parties.

Related functionalities