Skip to main content

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

TypeDescription
deviceConnects to a physical machine. Produces lab results and may receive test orders.
systemConnects to an external software system. Exchanges structured health data.

Key Concepts

TermDescription
automation.jsonDeclares metadata, capabilities, and communication details for the plugin.
entrypointA module that defines the plugin’s behavior by exporting a start() function.
capabilitiesDescribes which FHIR resources the plugin can produce or observe.
contextAn 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:

View 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, or DiagnosticReport)
  • 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.