Each source is a protocol adapter configured under `adapters` (or `nats`/`mqtt` for
streaming). All normalize to `CanonicalMachineData`.

| Type | Key options |
| --- | --- |
| `modbus` | `host`, `port`, `unit`, `registers` (with mapping to axes/spindle/metadata) |
| `opcua` | `endpoint`, `nodes` (mapping types), security |
| `http` | `url`, `interval`, `headers`, polls any REST endpoint |
| `mqtt` | `url`, `topic`, `qos` (ingests under `opexmx.ingest.*`) |
| `nats` | `url`, `subject` (ingests under `opexmx.ingest.*`) |
| `inject` | Manual / test source fired from the UI or `POST /api/sources/{key}/inject` |
| `focas` | Fanuc native CNC API: `host`, `port`. Loads `fwlib30.dll` for deep controller data (program, tool, spindle load, axis positions, alarms). Windows-only. |
| `mtconnect` | HTTP/XML streaming standard: `agent_url`. Cross-platform, multi-vendor (Fanuc, Haas, Siemens). |

## CNC adapters: FOCAS vs MTConnect

OpexFlow ships **both** a FOCAS adapter and an MTConnect adapter, and normalizes them to
the same `CanonicalMachineData` shape — so downstream transforms and sinks don't care
which one produced the event.

- **FOCAS** (FANUC Open CNC API Specifications) links against Fanuc's `fwlib30.dll` and
  reads program numbers, tool data, spindle load, axis positions, and alarms directly from
  the control. It gives depth (controller internals the standardized protocols don't
  expose) but is Fanuc-specific.
- **MTConnect** is an open, XML/HTTPS standard. Many modern controls — Fanuc included —
  expose an MTConnect agent that streams a standardized data-item model (spindle speed,
  feed, program, axis positions, controller mode). One consumer works across vendors.

> **Warning**
>
> **FOCAS is Windows-only.** `fwlib30.dll` is a native Windows library that can't be loaded
> on Linux or ARM. Because of this, **the FOCAS adapter self-disables with a clear status on
> Linux/ARM** rather than failing opaquely — you always know why it's off. MTConnect, being
> HTTP-based, runs cross-platform on any OS.
>
> For a mixed floor: point Fanuc machines needing deep data at a FOCAS adapter on a Windows
> edge node, and everything else at MTConnect on Linux or ARM. Both land in the same
> normalized schema.