Skip to content
MACHHUB MACHHUB MACHHUB
Contribute to this page

Processes & Flows

MACHHUB has two distinct features for running logic on the platform, and it is important not to confuse them:

  • Processes are serverless functions — you write code (Python or TypeScript) that runs on the platform, triggered by a schedule, a tag change, an HTTP call, or manually.
  • Flows are Node-RED pipelines — primarily used to ingest data from physical devices (PLCs, sensors, industrial controllers) and other sources not natively supported by MACHHUB’s data connectors.
ProcessesFlows
AuthoringCode (Python / TypeScript)Node-RED visual editor
Mental modelServerless function: execute(context)Wired graph of nodes
Primary purposeBusiness logic, automation, transforms, scheduled jobsDevice data ingestion, protocol bridging
Triggerscron, interval, tag_change, http, manualDevice events, timers, incoming messages
InputsDeclared inputs resolved before run (tag, sql)Messages flowing into nodes from devices
OutputsDeclared outputs applied after run (sql, tag_write)Tag writes, collection inserts via MACHHUB nodes
Run from SDKsdk.processes.execute(name, input)— (not run from the SDK)
Best forCustom logic, integrations, transforms, scheduled jobsPLCs, Modbus, OPC-UA, serial, HTTP devices

A Process is a function the platform runs for you in an isolated worker. You write only the function body; MACHHUB resolves your declared inputs beforehand and applies your declared outputs afterward.

flowchart LR
  T["Trigger\n(cron / interval / tag_change / http / manual)"] --> I["Inputs\n(tag values, SQL query results)"]
  I --> E["execute(context)\nyour code (Python or TypeScript)"]
  E --> O["Outputs\n(SQL write, tag_write)"]

A TypeScript process body looks like this — note the SDK is injected for you as a global sdk, so there is no import or initialization:

async function execute(context: ProcessContext): Promise<any> {
const { inputs, trigger } = context;
// The SDK is available as a global inside a TypeScript process.
const readings = await sdk.collection('myapp.readings').getAll();
// ...your logic...
return { count: readings.length };
}

Triggers, inputs, outputs, Python processes, packaging, and deployment are covered in Authoring Processes. To invoke a process from an app, see SDK → Processes.

A Flow is a Node-RED pipeline. In the MACHHUB ecosystem, Flows are the primary way to ingest data from physical devices — PLCs, sensors, and any source using a protocol (Modbus, OPC-UA, serial, HTTP, etc.) that MACHHUB does not natively support as a data connector.

MACHHUB provides the @machhub-dev/node-red-nodes library, which adds the following nodes to your Node-RED palette:

NodeWhat it does
MACHHUB ConfigStores connection details (host, credentials) shared by all other nodes. Optional when Flows run from the MACHHUB Platform web console — the connection is already managed by MACHHUB.
Tag ReadSubscribes to a MACHHUB tag (or wildcard MQTT topic) and emits values into the flow.
Tag WritePublishes msg.payload to a selected MACHHUB tag.
Bulk Tag WriteWrites to multiple tags simultaneously from a single object payload.
CollectionRuns CRUD operations (Select / Create / Update / Delete) on a MACHHUB Collection.
DB QueryExecutes a raw SurrealQL query against the MACHHUB database.

A typical ingestion flow reads from a device, transforms the raw value, then writes it into MACHHUB as a tag or collection record:

flowchart LR
  PLC["PLC / sensor\n(Modbus / OPC-UA / serial)"] --> NR["Node-RED nodes\n(protocol adapter)"]
  NR --> TW["Tag Write\n(machhub-dev/node-red-nodes)"]
  TW --> MACHHUB["MACHHUB Platform\n(UNS tag / Collection)"]

Because Flows write into the same UNS tags as the rest of the platform, a tag populated by a Flow can trigger a Process, feed the Historian, or be subscribed to by your SDK app — all without any extra wiring.

  • Use a Process for business logic, alerts, data transforms, scheduled batch jobs, or any integration you would naturally write as code.
  • Use a Flow when you need to pull data from a physical device or a protocol that MACHHUB does not natively support — bridge the data in, then let the platform handle the rest.

Next: learn to author Processes, or read about the Unified Namespace that both features build on.