How-to — switch a module off¶
A plant installs what it needs and no more. This page is how a plant that does not do serialised traceability, or does not have an ERP, stops serving those parts of the MES — and what exactly "off" means, because the answer is narrower than it sounds.
Nothing here changes anything for a plant that does not use it. With no setting, every module is on, which is what every plant had before the setting existed.
The setting¶
One environment variable, MES_MODULES, read left to right:
| Value | Means |
|---|---|
all |
every module. This is the default |
all,-quality |
every module except quality |
all,-quality,-erp |
every module except those two |
quality,maintenance |
the kernel, plus those two, and nothing else optional |
A name this version does not have is refused when the plant starts, with the list of module names in the message. It is not ignored: a typo that silently changes nothing is how a plant comes to believe it switched a module off while it is still serving it.
It is read once, at start-up, like shadow mode. Changing which modules a plant serves is a restart.
What "off" means¶
Off means not served:
- its API routes are gone, and answer 404 — not 403, and not an error page. A caller asking a plant for something it does not do is told the route does not exist;
- it is absent from
/openapi.json, so an integrator reading the plant's own API document sees what that plant actually offers; - its dashboard screens are not served. A page that loaded and then failed every fetch would look broken rather than absent;
- its agent tools are not registered, so an MCP client listing this plant's tools does not see them.
What "off" does not mean¶
Off does not mean not stored.
The database schema is one migration chain for every plant
(0021,
0022). A disabled
module's tables are still created by fsmes migrate, its existing rows are
untouched, and everything is exactly where it was when the module is switched
back on. Nothing about this setting drops a table or deletes a row.
That is deliberate. A plant that switches quality off for a quarter and back on should find its specifications and its calibration history waiting, not a hole. It also means switching a module off does not reclaim disk.
Switching a module off does not remove its data
If a module must go for a reason other than "we do not use it" — a retention rule, a regulator — turning it off is not the tool. Its rows are still in the database and still in every backup.
The modules¶
Twenty-three modules, of which nine are the kernel and cannot be switched off — master data, routings, orders, dispatch, execution, equipment, audit, auth and the dashboard front door. A plant without those is not an MES, and asking for it is refused.
The fourteen a plant may switch are:
| Module | What goes with it |
|---|---|
quality |
specifications, checks, non-conformances, SPC, the gauge register |
maintenance |
plans, orders due on use, the maintenance workspace |
scheduling |
the schedule board and the working calendar |
serialization |
serialised units, genealogy by serial, the trace screen |
documents |
controlled work instructions and their revisions |
coa |
certificates of analysis |
adjustments |
the recommendation queue — the only path to a PLC |
triggers |
what the plant does when a signal crosses a line |
erp |
the ERP connector and its settings (MES_ERP_*, MES_ERPNEXT_*) |
analysis |
the shift analysis screen |
line |
the line view, including the 3D scene |
kpis |
the OEE and order KPI routes |
assist |
the in-screen assistant |
design |
the design partner (a development tool) |
The authoritative list is src/fsmes/modules.py, which also says, per module,
which routers it mounts, which screens it serves, which agent tools it
registers and which tables its rows live in.
Turning one off¶
MES_MODULES=all,-serialization fsmes serve
or, in a plant's .env:
MES_MODULES=all,-serialization,-coa
Check it took:
curl -s localhost:8000/openapi.json | grep -c '"/trace'
# 0
What this is for¶
M8's goal is two plant packs with different modules enabled running from one
codebase. This setting is the mechanism; the plant pack is where
it lives. A pack's [modules] table compiles down to exactly this string, so
a plant that sets MES_MODULES by hand is setting the same thing:
[modules]
serialization = false
coa = false
becomes all,-serialization,-coa. all is written first and the pack's own
words after it, so a module added by a later release arrives switched on
rather than silently missing from a plant that has never heard of it. A
module name this version does not have, or a kernel module, is refused by
fsmes pack check before the plant ever starts.
labs/multiplant/finewire is the plant that does it: a wire-drawing hall
with no serial units and no certificates, whose /trace and /coa routes
answer 404 and whose agent registers eight tool files where a full plant
registers ten.
How the boundary is kept¶
Two tests, and they are worth knowing about because they are what stops this capability quietly rotting:
tests/test_core_purity.pyforbids the kernel importing a module. A module the kernel imports cannot be switched off — the setting could decline to mount its routes, but the kernel would still drag the package in at start-up.tests/test_no_tenant_literals.pyforbids a plant's name, equipment code or material code appearing in code undersrc/. It builds its list from the lab plants inlabs/— each pack'splant.tomland its master data — rather than from a list somebody typed, so a new plant extends the guard instead of escaping it. This is house rule 4 — config, not code, at plant boundaries — as a measurement.