Skip to main content
PET_02 / HackNU · KTZ challenge

Locomotive Digital Twin
Fleet telemetryApril 2026

My roleTeam of two. I built the onboard simulator, wear model, dispatch server and dashboard; my teammate built the LocoPanel onboard UI
TimelineApril 2026, HackNU hackathon
Delivered3 Dockerized services, 4 simulated locomotives, a fleet dashboard
crisis_alertProblem

Spot component wear before a breakdown

Kazakhstan Railways (KTZ) asked for a digital twin of the KZ8A electric and TE33A diesel locomotives. The twin had to take in telemetry continuously, estimate accumulated wear per component, and warn the dispatcher early about overheating, catenary voltage drops or a turbocharger failure.

4
simulated locomotives
2
series: KZ8A and TE33A
60 s
aggregation interval
Stack[SYSTEM_ARCHITECTURE]

Onboard unit, broker and dispatch

Each locomotive runs in its own container: a FastAPI service simulates sensors, scores risk per component and publishes packets to MQTT. The dispatch server subscribes to an EMQX broker, aggregates data into PostgreSQL once a minute, and serves REST and WebSocket to the dashboard.

  • Python
  • FastAPI
  • MQTT (EMQX)
  • WebSocket
  • PostgreSQL
  • Docker
codeLocoAppBack/app/telemetry/risk.py
if risk_type == "linear_hi":
    warn: float = comp_cfg["warn"]
    crit: float = comp_cfg["crit"]
    if value <= warn:
        return 0.0
    if value >= crit:
        return 1.0
    return _curve((value - warn) / (crit - warn), exponent)
risk ∈ [0.0, 1.0]
Decisions

Lesson

What I would do differently

I never found the locomotives' technical documentation, although it was publicly available, so I set the thresholds without it. Competing teams went deeper into how the locomotives work and had stronger visuals. Next time I will start with the domain documentation and only then write code.