After lesson 6. No code in this page — it is the six lessons seen from above, and what they cost to take to a real instrument.
You started with an empty directory and a PC with nothing plugged into it. You now have two projects and a bench.
What you built
Six lessons, and nothing in them was a demo mode except the mocks:
| Lesson 1 | A device server, and a client that talks to it |
| Lesson 2 | Three servers, declared as a fleet, agreeing on a dataset |
| Lesson 3 | The three driven as one instrument — a rig |
| Lesson 4 | An experiment: a plan, records, resume, and frames that stay put |
| Lesson 5 | A monitor, the record file as a stream, and the view plotted live |
| Lesson 6 | A reader for the spectrometer's frames, two more views, all three docked — and the run as a video |
Three things came out of it, and each one is worth naming by what it guarantees rather than by what it contains.
The bench is three device servers, declared once in a fleet file, each speaking the same vocabulary over TCP and reachable from anything that knows its address. That is why nothing you wrote afterwards had to know what an instrument is.
The experiment is a plan, a journal, records and a run directory. It refuses to start on a rig that is not there, it survives being interrupted, it never carries an image over the network, and every row it writes says which step produced it and what was asked of that step.
The views are three, all of them yours — a curve, a spectrum and a map — reading the file the run was already writing. Each is a schema, a declaration of what it draws, and a projection of one row onto the other; none of them mentions a window, a file format or an instrument. Nothing had to be added to the measurement to make it watchable, and nothing about watching it can disturb it.
Taking it to a real bench
The demo was arranged so that the step to real instruments is the smallest one in the tutorial. Everything that changes is configuration, and it is worth seeing the whole list at once — partly to size the job, partly because not being on the list is the interesting property:
| Demo | Real bench | |
|---|---|---|
| Server arguments | --mock, PLESTY_MOCK_DATASET, PLESTY_MOCK_BENCH |
none of the three — the driver opens the instrument |
| Where servers run | all three on this PC | on the PCs the instruments are plugged into |
.env |
three localhost ports |
the hostnames of those PCs, one file per deployment |
| The share | one directory, named twice identically | one disk, spelled D:\data by the camera's PC and /Volumes/lab-data here |
| The numbers | replayed from a stored sweep | the light |
And the list of code that changes: none of it. rig.py, experiment.py, monitors.py, frames.py, viz.py are the same files. That is not a claim about how nice the demo is — it is the reason the platform splits things where it does. A module never learns a hostname, a plan never learns a disk, and a view never learns where a frame came from, so none of them has anything to change when the lab does.
frames.py is the one worth checking against your intuition, because it does know a file format — and still does not change. The real spectrometer writes the same SPE the mock replayed; what differs is that the file is now on a share this machine spells differently, and that difference was never in the reader. It arrives as run.local, from the two spellings the run journaled when it started.
Two things do become real work, and both are deliberately outside a quickstart:
- The instrument driver. The three you used are hub modules someone wrote — schemas, a traffic manager, a command solver, mock tests. Build a Device is that job end to end.
- The compliance tier. Your project ran at
pixel, the prototype default, because it has no release tag. Tagging0.1.0moves it tonebulaand1.0.0toquantum, and each tier turns on gates the one below let pass — type strictness, coverage, docs that build, a security audit. A module that is going to be used by people who did not write it is expected to climb that ladder, and the gates say exactly what each step costs.
Then the small print that turns a working project into a shared one: push it, let CI run the same plesty check your pre-push hook runs, tag a release, and the pipeline publishes the package and its documentation. Publishing is one page, and the tutorial you have just finished is most of what it assumes.
What to keep
What is worth carrying out of all six lessons is smaller than the code, and it is the same idea three times: the thing that changes between deployments is never the thing you wrote. An address lives in .env, a tuning value in config/*.yaml, a disk in two environment variables, and the module, the plan and the view stay put. That is what makes a measurement you can hand to someone else, run on different hardware next year, and still trust the numbers from.
Where to go next:
- Build a Device — your own instrument module, the way the three you used were written.
- Build an Experiment — the reference for what lesson 4 skimmed: plan validation, retries, run layout.
- Quality Gates — what
plesty checkis checking, tier by tier, and why the standard tightens as a module matures. - plesty-common-monitors — the general forms of the three views you wrote, worth reading before writing a fourth.
And if something in these six lessons was wrong, unclear, or out of date, the page you are reading is a Markdown file in a public repository — the contributor guide is the short version of how to fix it.