Initial commit with Dockerfile and demo code
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
# Demo script — 6 minutes
|
||||
|
||||
One story, told once, with a clear beginning and end: *the twin sees a bearing
|
||||
failing before it fails, explains why in plain language, and lets you test a fix
|
||||
before touching the plant.*
|
||||
|
||||
Resist the urge to show every feature. The four faults exist so you can answer
|
||||
"what else can it do?" — not so you can fire all of them.
|
||||
|
||||
**Before you walk in:** `npm run dev`, open `http://localhost:5173`, confirm the
|
||||
header shows *Telemetry live* and the copilot badge shows a provider. Leave the
|
||||
clock at **1×**. Press **Reset** if anyone has been clicking around — the line
|
||||
comes back pre-warmed to a realistic ~88% OEE.
|
||||
|
||||
---
|
||||
|
||||
## 0:00 — What they are looking at (45s)
|
||||
|
||||
> "This is a live digital twin of a five-station production line — infeed,
|
||||
> machining, curing oven, vision inspection, packing. Everything on this screen is
|
||||
> being computed from a running model of the line, not replayed from a video."
|
||||
|
||||
Orbit the 3D view once, slowly. Click **CNC-02** in the 3D scene — the detail
|
||||
charts below change with it.
|
||||
|
||||
> "OEE is 88%. Availability is 100% — nothing has broken down this shift.
|
||||
> Performance is 91%, and that's micro-stops. Quality is 97.6%. That's a well-run
|
||||
> line having a normal day."
|
||||
|
||||
**Why this beat matters:** the baseline has to be believable before the failure
|
||||
means anything. If they accept 88%, they will accept everything that follows.
|
||||
|
||||
## 0:45 — Show that it is a model, not a dashboard (60s)
|
||||
|
||||
In **What-if controls**, drag **Oven setpoint** from 305 to 330 °C. Point at the
|
||||
Zone temperatures chart, then at Burner duty.
|
||||
|
||||
> "Watch the response. It doesn't jump — it takes about half a minute of run time
|
||||
> to settle, and ten seconds in it's only 44% of the way there. And look at burner
|
||||
> duty: it spikes from 68 to 85% and then settles back to 74% as the controller
|
||||
> finds the new equilibrium. That's a thermal model with a real time constant and
|
||||
> a controller on top. A dashboard would just redraw a number."
|
||||
|
||||
Measured: 305 °C → 316 at 10 s → 328 at 25 s → within 1 °C of setpoint by 30 s.
|
||||
|
||||
Drag it back to 305.
|
||||
|
||||
> "That's the point of a twin: you can ask 'what happens if' without doing it to
|
||||
> the actual plant."
|
||||
|
||||
## 1:45 — Inject the fault and compress time (45s)
|
||||
|
||||
Click **Inject** on *CNC-02 bearing degradation*. Then set the clock to **60×**.
|
||||
|
||||
> "I've just started a spindle bearing degrading. In a real plant this plays out
|
||||
> over days. I'm running the clock at 60×, so we'll watch it in about thirty
|
||||
> seconds. Everything else stays physical — the clock is the only thing I sped up."
|
||||
|
||||
Say the 60× out loud. Point at the sim clock. Never let them think this is
|
||||
real-time.
|
||||
|
||||
Watch the **Bearing Vibration** chart climb toward the dashed **Warn 3.5** line.
|
||||
|
||||
## 2:30 — The prediction (60s)
|
||||
|
||||
A purple **Trend** card appears above the charts, and an alarm appears in the feed.
|
||||
|
||||
> "There it is. Vibration is at 2.9 and rising 0.18 per minute. Nothing is over
|
||||
> limit yet — but it's telling me I hit the 4.5 alarm limit in about 27 minutes of
|
||||
> run time."
|
||||
|
||||
If asked how — and someone always asks:
|
||||
|
||||
> "It's a least-squares fit over the last twenty minutes, extrapolated to the
|
||||
> limit, and it only reports when the fit is good enough to mean anything — that
|
||||
> r² of 0.65 is the fit quality. It's a regression, not a black box. I can show
|
||||
> you the arithmetic."
|
||||
|
||||
**Do not call this AI.** Calling a straight-line fit "AI prediction" is the fastest
|
||||
way to lose the engineer in the room.
|
||||
|
||||
## 3:30 — The copilot (90s)
|
||||
|
||||
Let it cross 4.5. OEE is now falling visibly. Click **Explain this** on the
|
||||
bearing alarm.
|
||||
|
||||
While it thinks:
|
||||
|
||||
> "This is reading the live telemetry — states, readings against limits, the OEE
|
||||
> breakdown, the measured trends. What it is *not* told is which fault I injected.
|
||||
> It has to work that out from the data, same as your engineer would."
|
||||
|
||||
Read the answer out. It will trace vibration → tool wear → rejects → OEE.
|
||||
|
||||
> "Notice it separates what's measured from what's inferred, and it traced the
|
||||
> whole chain: the vibration is raising tool wear, which is pushing parts out of
|
||||
> tolerance, which is why the reject rate went from 2% to 5% — and that's what's
|
||||
> dragging OEE down, not the machine stopping."
|
||||
|
||||
Then click **Draft a maintenance work order**.
|
||||
|
||||
> "And it writes the work order. That goes to your CMMS."
|
||||
|
||||
**If the cloud model is slow:** switch the selector to **Local** before the
|
||||
meeting. See *Provider choice* below — a 20-second silence kills this beat.
|
||||
|
||||
## 5:00 — The intervention (45s)
|
||||
|
||||
> "So: I know the bearing is going, I know roughly when, and I know what it's
|
||||
> costing me. Let me act on it."
|
||||
|
||||
Click **Clear** on the bearing fault, then **Tool change**. Set the clock to
|
||||
**20×**.
|
||||
|
||||
> "Bearing replaced, fresh tooling. Watch the reject rate come back down and OEE
|
||||
> recover. The twin closed the loop — it found it, explained it, and confirmed the
|
||||
> fix worked."
|
||||
|
||||
## 5:45 — Land it (30s)
|
||||
|
||||
> "Two things to take away. This is running on a simulated line today, but the
|
||||
> ingest layer is built to take your data — MQTT, OPC-UA, or a historian export —
|
||||
> and nothing above that layer changes when we swap it. Second, the reasoning is
|
||||
> reproducible: I can turn the language model off entirely and the same diagnosis
|
||||
> comes out of a rule engine."
|
||||
|
||||
Switch the copilot to **Offline rules** and ask *"Why is OEE down?"* — it answers
|
||||
instantly.
|
||||
|
||||
> "Same conclusion, no model, no network. The AI makes it conversational. It isn't
|
||||
> where the analysis comes from."
|
||||
|
||||
That last move is worth more than it looks: it is the answer to "is the AI just
|
||||
making this up?", and it lands better as a demonstration than as a claim.
|
||||
|
||||
---
|
||||
|
||||
## Provider choice — decide before you present
|
||||
|
||||
Open **AI ⚙** in the header, pick a model, and hit **Test**. It reports
|
||||
time-to-first-token and tells you whether that model is presentable live. Do this
|
||||
on the demo machine, on the demo network, before the meeting — cloud latency
|
||||
measured anywhere between 2 s and 36 s on consecutive identical calls.
|
||||
|
||||
| Setting | First token | Use it when |
|
||||
|---|---|---|
|
||||
| **Cloud** (`stealth/ox-alpha`) | 2–35 s, variable | Best analysis. Good for the follow-up conversation, risky for the live beat. |
|
||||
| **Local** (Ollama) | ~1–2 s | The live walkthrough. Needs `ollama serve` running. |
|
||||
| **Offline rules** | instant | No network at all. Your safety net, and the credibility proof at the end. |
|
||||
|
||||
The copilot panel shows which one answered every message, so you always know. The
|
||||
selector there overrides the default per question, so you can run the walkthrough
|
||||
on Local and switch to Cloud for a deeper answer when someone pushes.
|
||||
|
||||
Your choice is saved, so set it once while preparing and it will still be there.
|
||||
|
||||
## Questions you will get
|
||||
|
||||
**"Is this our real data?"** No — it is a simulated line. The adapters for your
|
||||
data are in `server/ingest/`, and `docs/architecture.md` shows exactly where they
|
||||
plug in. Nothing above that layer changes.
|
||||
|
||||
**"How does it predict the failure?"** Least-squares fit over recent run time,
|
||||
extrapolated to the alarm threshold, suppressed when r² is too low to trust. Open
|
||||
`server/analytics/trend.js` if they want to see it.
|
||||
|
||||
**"Could it control the line?"** Technically yes over OPC-UA; deliberately
|
||||
read-only here. Writing setpoints to a PLC needs interlocks, an audit trail and
|
||||
their sign-off. Say that — it builds more trust than saying yes.
|
||||
|
||||
**"Why is OEE only 88% at the start?"** Because a line that reads 100% is a line
|
||||
nobody believes. Micro-stops and unplanned stops are modelled, so the number moves
|
||||
for reasons you can name.
|
||||
|
||||
**"Can it run on the plant floor / offline?"** Yes. It is one Node process and a
|
||||
static front end, and with the local model or the rule engine it needs no internet
|
||||
at all.
|
||||
|
||||
## If something goes wrong
|
||||
|
||||
- **Charts empty / "Disconnected"** — the server died. `npm run dev` again; the
|
||||
dashboard reconnects on its own and the server comes back pre-warmed.
|
||||
- **Copilot returns nothing** — switch to **Offline rules** and carry on. This is
|
||||
why that mode exists.
|
||||
- **The line is in a strange state** — press **Reset**. It clears faults, learned
|
||||
baselines and history, and re-warms to a clean ~88% OEE in under a second.
|
||||
- **The 3D is choppy** — drop the clock to 20×. The model is fine; it is the
|
||||
render loop competing with the projector.
|
||||
Reference in New Issue
Block a user