Grid substation
A 110/20 kV distribution substation with two transformers and six feeders, on IEC 60870-5-104. Nine devices and 69 points.
Operator view | port 4016 |
|---|---|
Protocol server | port 5026 |
Devices and tags | 9 devices, 69 points |
Litmus Edge driver | IEC 60870-5-104 |
Image | grid-substation-demo |
Scenarios
- Thermal margin as a forecast. A transformer's hot spot is not a threshold to alarm on but a curve to project. The useful question is how long the current loading can continue, not whether it is over a limit right now.
- The tap changer wear counter. Operations accumulate towards maintenance. A counter that adds up over months is worth more than an alarm that fires after the fact.
- A recloser sequence, end to end, on the wire. A feeder fault produces a burst of protection events in under a second. The demonstration is what an Edge does with a burst: capture it at the resolution it happened rather than at the rate someone chose to poll.
Overview
Most of the solutions here poll steadily. A substation does not. The data that matters arrives in bursts around an event, and the value of an Edge is that it is close enough to catch the whole sequence.
IEC 60870-5-104 is report by exception for exactly this reason, and the solution uses it that way.
What it creates on Litmus Edge
Nine DeviceHub devices covering the two transformers, six feeders and the station itself, with 69 points over IEC 60870-5-104. A Digital Twin model and instance for each transformer and feeder. Analytics groups behind the thermal margin, tap changer wear and event figures.
Requirements
- Litmus Edge 4.0.x, reachable over HTTPS from the host running the solution
- An API token for that Edge, or a username and password, or a client id and secret
- Docker, and Docker Compose for the compose deployment
- A network path in both directions: the solution reaches the Edge's API, and the Edge reaches this host on the protocol port
Deploy
The solution ships two ways. Use the registry if the host can reach Google Artifact Registry, and the downloaded archive if it cannot.
Option 1: pull from the registry
Requires a read-only registry credential, supplied by Litmus separately.
cat key.json | docker login -u _json_key --password-stdin https://us-docker.pkg.devSave this as docker-compose.yml:
services:
grid-substation:
image: us-docker.pkg.dev/litmus-customer-facing/litmus-solutions/grid-substation-demo:0.3.0
container_name: grid-substation-demo
restart: unless-stopped
ports:
- target: 4016
published: 4016
protocol: tcp
- target: 5026
published: 5026
protocol: tcp
environment:
# Fill these in.
EDGE_URL: "${EDGE_URL:-}"
EDGE_API_TOKEN: "${EDGE_API_TOKEN:-}"
SIM_HOST: "${SIM_HOST:-auto}"
APPLY_ON_START: "${APPLY_ON_START:-1}"
EDGE_VERIFY_TLS: "${EDGE_VERIFY_TLS:-0}"
HTTP_PORT: "4016"
IEC104_PORT: "5026"
AUTOSTART: "1"
TIME_SCALE: "120"
SEED: "7"
LOG_LEVEL: "INFO"EDGE_URL=https://10.0.0.5
EDGE_API_TOKEN=your-token
SIM_HOST=10.0.0.9docker compose up -dOpen http://localhost:4016.
The page stays on its waiting panel until the Edge carries this solution's devices. That is deliberate: the simulation does not tick and no value is shown until Litmus Edge is verified to hold the devices and poll them, so nothing on screen can be mistaken for data that never made the trip. With APPLY_ON_START at its default of 1 the solution configures the Edge itself on startup, which takes 30 to 60 seconds. If you set it to 0, or the apply failed, press Apply to Edge in the page header.
Option 2: load the downloaded archive
Download grid-substation-demo-0.3.0-amd64.tar.gz from the solution's page on portal.litmus.io. The archive is the container image, not a source bundle, and needs no registry access.
docker load -i grid-substation-demo-0.3.0-amd64.tar.gzdocker load prints the image it added:
Loaded image: us-docker.pkg.dev/litmus-customer-facing/litmus-solutions/grid-substation-demo:0.3.0That reference is the one the compose file above already names, so the same docker-compose.yml and .env now work offline with no docker login:
docker compose up -dTo run it without Compose, pass the same three values on the command line:
docker run -d \
--name grid-substation-demo \
--restart unless-stopped \
-p 4016:4016 \
-p 5026:5026 \
-e EDGE_URL=https://10.0.0.5 \
-e EDGE_API_TOKEN=your-token \
-e SIM_HOST=10.0.0.9 \
us-docker.pkg.dev/litmus-customer-facing/litmus-solutions/grid-substation-demo:0.3.0Configuration
Variable | Default | What it does |
|---|---|---|
EDGE_URL | the Docker host | Litmus Edge to configure |
EDGE_API_TOKEN | unset | token for that Edge. Or a username and password, or a client id and secret |
SIM_HOST | auto | address the Edge polls to reach this solution |
APPLY_ON_START | 1 | configure the Edge on startup |
EDGE_VERIFY_TLS | 0 | 1 checks the Edge's certificate |
TIME_SCALE | 120 | the station clock runs 120x, so a daily load curve passes in twelve minutes |
SEED | 7 | makes a run repeatable |
Operator view
The station single line: the 110 kV bus, both transformers with their loading, hot spot temperature and tap position, the 20 kV bus, and the six feeders with their currents.
Above it, station load, worst transformer, bus voltage and frequency, feeders open, and ambient temperature, since the thermal margin depends on it.
Every value on the page is read back from Litmus Edge rather than from the simulator, and the page says how many reads it has made and how old the newest is.
Faults include a feeder fault with a recloser sequence, a transformer cooling fan failure, tap changer hunting and a load surge.
Apply and remove
docker compose downUse Clean up in the Solutions provisioner to remove what it created on the Edge.