Aerospace Machining
A machine shop cutting aerospace structures, over MTConnect. Seven CNC machines in four cells, 133 tags.
Operator view | port 4018 |
|---|---|
Protocol server | port 5028 |
Devices and tags | 7 machines, 133 tags |
Litmus Edge driver | MTConnect |
Image | aerospace-machining-demo |
Scenarios
Four scenarios at once, one per cell, each with a healthy machine beside it so the comparison is on screen rather than remembered.
- A dulling cutter scrapping a forging worth more than the cycle. Flank wear raises cutting force, the unsupported web deflects and springs back, and more material comes off than the program asked for. Nothing alarms: the tool life counter still has parts left. Spindle load climbs from about 55 to 80 percent while the drawing is still being met, and the web crosses the minimum a few parts before the fixed count change would have caught it.
- A cold machine cutting the first parts of a shift oversize. A ballscrew that is cold is short, so the axis under-travels and the part comes out thick. It corrects itself as the screw warms through, which is why it is expensive: the parts are already cut. This and the wear scenario push the same measured feature in opposite directions, so one band strip carries both.
- Cutting edge thrown away by changing on a count. Carbide is changed on a fixed part count rather than on condition, so most of every edge is discarded. This one runs with nothing injected at all, and the figure is on screen from the first frame.
- A spindle that stays available and stops earning. A pallet pool runs dry overnight. The machine stays powered, stays AVAILABLE, and simply stops being ACTIVE. Every dashboard watching availability says it is fine.
Tag names
Every other solution in this set hand-maps its registers: Modbus has no self-description, so each address is assigned and then has to be defended.
Here the names come from the standard. EXECUTION, SPINDLE_SPEED, PATH_FEEDRATE, LOAD, PART_COUNT and TOOL_NUMBER are DataItem types defined by MTConnect Part 2, and a real shop already publishes them under exactly those names. Litmus Edge browses the agent and discovers the shop rather than being told about it, and every reading on the operator view is labelled with the DataItem it arrived as, so what is on screen and what is in DeviceHub are the same string.
The whole shop is served by one MTConnect agent on one port. Litmus Edge tells the seven machines apart by device name, which is how a real agent is deployed.
What it creates on Litmus Edge
Seven DeviceHub devices on the MTConnect Ethernet (Gen1.3) driver, 19 tags each. One MachineTool Digital Twin model with seven instances, because a shop buys the same class of machine repeatedly and the eighth machine should be an instance rather than a modelling exercise. Four Analytics groups:
Group | What it computes, on the Edge |
|---|---|
Tool Wear Risk | spindle load against what a sharp edge pulls, classified |
First Part Quality | the probed feature against the drawing the twin carries |
Thermal Readiness | the gap to thermal equilibrium, per machine |
Spindle Utilisation | Up/DownTime by Value on the spindle |
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:
aerospace-machining:
image: us-docker.pkg.dev/litmus-customer-facing/litmus-solutions/aerospace-machining-demo:0.3.0
container_name: aerospace-machining-demo
restart: unless-stopped
ports:
- target: 4018
published: 4018
protocol: tcp
- target: 5028
published: 5028
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: "4018"
AGENT_PORT: "5028"
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:4018.
Option 2: load the downloaded archive
Download aerospace-machining-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 aerospace-machining-demo-0.3.0-amd64.tar.gzdocker load prints the image it added:
Loaded image: us-docker.pkg.dev/litmus-customer-facing/litmus-solutions/aerospace-machining-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 aerospace-machining-demo \
--restart unless-stopped \
-p 4018:4018 \
-p 5028:5028 \
-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/aerospace-machining-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 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 |
SEED | 7 | makes a run repeatable |
Operator view
Across the top: the worst spindle in the shop and the shop average behind it, scrap for the run in dollars, the value of cutting edge discarded, and spindle hours lost.
The headline names the worst machine rather than reporting only the average, because an average over seven spindles can move by at most a seventh of one machine's loss, which reads as noise.
Below, the four cells side by side. Each machine is drawn as a machining centre with its head riding in Z and its cutter turning, under two meters: spindle load, and the probed feature against the acceptance band from the drawing. Every reading is labelled with the MTConnect DataItem it came from.
Faults are the four scenarios above, injected per machine, each with a card naming the DataHub topics to watch and what changes about them.
Apply and remove
The header carries both controls. Apply to Edge pushes the devices, twins and analytics; it greys out once the solution is on the Edge. Remove from Edge previews first, listing exactly what would be removed and from which Edge, and only then offers to remove it.
The solution removes only what it created. It also records which Edge its apply landed on and removes from that one, so repointing at a different Edge in between cannot leave the first one carrying a solution nobody can see.
The operator view stays on its waiting panel until Litmus Edge is verified to be carrying the shop. Every value on the page is read back from the Edge, so a page showing data is itself evidence the chain is working.
Reports
Export report produces one self-contained HTML file: the shift's money figures, the probed feature against the drawing with the acceptance band behind it, the distribution against the spec limits, where the spindle time went, and time in each Execution state per machine. No scripts and no external requests, so it opens offline and prints.
Stop the solution
docker compose downUse Remove from Edge on the operator view, or Clean up in the Solutions provisioner, to remove what it created on the Edge.