Introduction to Automation Plugins
Automation plugins are modular components that allow the platform to communicate with external devices (such as lab analyzers) or software systems (such as EMRs, FHIR servers, or surveillance databases).
Plugins are used to:
- Receive test orders from connected systems
- Collect and normalize lab results from machines
- Synchronize data with national databases or hospital platforms
- Handle real-time or batch communication workflows
Each plugin is defined by:
- A manifest file called
automation.json
- An entrypoint script that exports a
start()
function
Plugin Types
Type | Description |
---|---|
device | Connects to a physical machine. Produces lab results and may receive test orders. |
system | Connects to an external software system. Exchanges structured health data. |
Key Concepts
Term | Description |
---|---|
automation.json | Declares metadata, capabilities, and communication details for the plugin. |
entrypoint | A module that defines the plugin’s behavior by exporting a start() function. |
capabilities | Describes which FHIR resources the plugin can produce or observe. |
context | An object passed into the plugin at runtime, providing methods for data exchange and status updates. |
automation.json
Each plugin must include a automation.json
file at the root of the plugin folder. This file defines:
- The plugin's metadata (id, name, category, publisher)
- Its entrypoint file
- Declared capabilities using FHIR resource types
- The device or system it supports
You can validate your automation.json
file using the official schema:
You can also reference the schema directly in your plugin definition file for autocomplete and validation:
{
"$schema": "https://automation.labxpert.io/automation.schema.json",
"id": "openmrs-fhir-plugin",
"name": "OpenMRS FHIR Plugin",
// ...
}
The start()
Function
Each plugin must export a start()
function. The platform will invoke it and pass in a typed context object:
import type { Context } from "automation-runtime";
import automation from "./automation.json";
export async function start(context: Context<typeof automation>) {
context.status("connecting");
const connection = await connectToDeviceOrSystem();
context.status("connected");
for await (const result of connection.getResults()) {
// Produce a structured FHIR Observation
context.produce({
resourceType: "Observation",
valueQuantity: { value: result.value, unit: result.unit }
});
// Optionally emit raw vendor message
context.produce({
resourceType: "Message",
content: result.rawLine
});
}
}
The Context Object
The context
object provides methods that allow plugins to interact with the Automation runtime:
status(status: string)
Updates the plugin’s operational or connection status (e.g. "connecting"
, "connected"
, "error"
).
produce(resource: FHIRResource | Message)
Emits either:
- A structured FHIR resource (like
Observation
,ServiceRequest
, orDiagnosticReport
) - A raw
Message
object for unstructured or vendor-specific payloads
on(resourceType: string, handler: (resource) => void)
Listens for incoming FHIR resources based on the plugin’s declared capabilities (e.g., test orders or patient updates).
Typing with Context<typeof automation>
For best development experience and strict validation, pass the imported automation.json
to the Context
generic:
import automation from "./automation.json";
import type { Context } from "automation-runtime";
const context: Context<typeof automation>
This ensures all capability declarations are type-checked at compile time.