Skip to main content
Version: 2.2

Walkthrough: Antigravity + Gemini

This walkthrough shows how we used Antigravity with Gemini Pro 3.1 to build three production pipelines and a comprehensive monitoring dashboard for the Caliperline demo environment — entirely through natural language prompts.

Prerequisites

The connections used in this walkthrough (Modbus, OPC UA, REST, etc.) were set up automatically via the Digital Factory Simulator easy setup. If you want to follow along, run the DFS setup first — it will create all the Caliperline connections and simulated devices for you.

What We Built

By the end of this session, the AI had created:

  • 3 pipelines covering Modbus, OPC UA, and REST protocols
  • 1 dashboard with 9 panels across 6 visualization types (state-timeline, gauge, line chart, pie chart, and tables)
  • All wired together: pipelines publish to UNS topics, dashboard reads from those topics

Part 1: Building the Pipelines

Prompt:

Can you design and implement some pipelines using the Caliperline connections?

That's it — one open-ended prompt. Gemini explored the available connections, discovered their protocols and functions, and autonomously designed three pipelines covering different patterns. Here's what it built.

Pipeline 1: OP10 Modbus Telemetry

What the AI did:

  1. Called connectors_list_connections with search "Caliperline" to discover all 8 connections and their types
  2. Called connectors_list_functions on the Modbus, OPC UA, and REST connections to understand what data was available
  3. Called engine_list_node_types to understand available pipeline nodes
  4. Decided to create three pipelines based on the connection types and available functions
  5. Called engine_create_pipeline for the first pipeline with this flow:

Resulting pipeline:

Caliperline OP10 Telemetry pipeline in the Pipeline Designer

The OP10 Telemetry pipeline — 4 nodes polling Modbus every 10 seconds

NodeTypePurpose
Every 10strigger.schedulePolls every 10 seconds
Read OP10 Modbusconnected.modbus.readgroupReads all registers with readAll: true and continueOnError: true
Format Telemetrylogic.javascriptIterates over results, extracts successful values, adds machine field
Publish to UNSsystem.uns.publishPublishes to caliperline/machines/op10/telemetry

The JavaScript node that Gemini generated handles the Modbus read group output format correctly — it filters out the _meta key and only includes registers that read successfully:

const data = $node['Read OP10 Modbus'];
const payload = {};
for (const [key, result] of Object.entries(data)) {
if (key !== '_meta' && result.success) {
payload[key] = result.value;
}
}
payload.machine = 'OP10-CNC';
return { payload };

Live output (from uns_fetch_recent):

{
"machine": "OP10-CNC",
"State": 3,
"SpindleSpeed": 500,
"SpindleLoad": 62,
"Temperature": 262,
"Vibration": 129,
"PowerKW": 358,
"PartsProduced": 32,
"PartsGood": 31,
"PartsBad": 1,
"FaultActive": 1,
"FaultCode": 4,
"RunTime": 67436544,
"DownTime": 0
}

Pipeline 2: OP20 OPC UA Fault Alerts

Still working from the same prompt, Gemini created the second pipeline — this time with conditional branching:

Resulting pipeline:

Caliperline OP20 Fault Alerts pipeline in the Pipeline Designer

The OP20 Fault Alerts pipeline — conditional branching only publishes when a fault is active

NodeTypePurpose
Every 5strigger.schedulePolls every 5 seconds
Read OP20 Faultsconnected.opcua.readgroupReads 3 specific functions by alias: FaultActive, FaultCode, FaultName
Is Fault Active?logic.conditionChecks FaultActive.value === true
Construct Alertlogic.javascriptBuilds the alert payload (only runs when fault is active)
Publish Alertsystem.uns.publishPublishes to caliperline/alerts/op20/fault

Key detail: the edge from the condition node to the JavaScript node uses sourcePort: "true", so the alert is only constructed and published when a fault is actually active. The AI got this branching pattern right on the first try.

The JavaScript node includes defensive checks for each OPC UA read result:

const data = $node['Read OP20 Faults'];
return {
payload: {
machine: 'OP20-CNC',
faultCode: data.FaultCode && data.FaultCode.success ? data.FaultCode.value : 'UNKNOWN',
faultName: data.FaultName && data.FaultName.success ? data.FaultName.value : 'Unknown Fault',
severity: 'critical',
timestamp: new Date().toISOString()
}
};

Pipeline 3: MES Orders Sync

The third and final pipeline from the same prompt — a REST API integration:

Resulting pipeline:

Caliperline MES Orders Sync pipeline in the Pipeline Designer

The MES Orders Sync pipeline — REST API polling every minute

NodeTypePurpose
Every 1mtrigger.scheduleSyncs every minute
Fetch MES Ordersconnected.rest.requestCalls the MES API to get active orders
Format Orders Payloadlogic.javascriptWraps the response with metadata
Publish Orders to UNSsystem.uns.publishPublishes to caliperline/mes/orders/active

The JavaScript enriches the raw REST response:

const reqResult = $node['Fetch MES Orders'];
return {
payload: {
source: 'MES',
totalActive: Array.isArray(reqResult.data) ? reqResult.data.length : 0,
orders: reqResult.data || []
}
};

Part 2: Building the Dashboard

With all three pipelines running and publishing data, we asked the AI to create a monitoring dashboard.

Prompt:

Now, I want you to create a comprehensive dashboard using those pipelines you just created.

What the AI did:

  1. Called uns_fetch_recent on each topic to check the data schema and actual value ranges
  2. Called uns_list_panel_types to understand panel configuration options
  3. Called uns_create_dashboard with 9 panels arranged in a grid layout

Resulting dashboard:

Dashboard top section showing Machine State timeline, Spindle Speed and Load gauges, and Vibration line chart

Top: Machine State timeline with color-coded states, gauges for Spindle Speed and Load, and a Vibration trend line

Dashboard middle section showing gauge values and vibration details

Middle: Spindle gauges with threshold bands, Vibration chart showing real-time fluctuations

Dashboard bottom section showing Temperature and Power gauges and Production Quality donut chart

Bottom: Temperature and Power gauges, Production Quality donut chart (96.88% good parts)

Panel details

Gauges — All four gauges use three-tier threshold bands:

GaugeNormal (green)Warning (yellow)Critical (red)
Spindle Speed0–8,000 RPM8,000–9,0009,000–10,000
Spindle Load0–75%75–90%90–100%
Temperature0–300°C300–400°C400–500°C
Power0–800 kW800–900 kW900–1,000 kW

Vibration line chart — Uses threshold bands as background overlays (opacity 15%) to visually highlight when vibration enters warning or critical zones.

State timeline — Maps numeric state values to human-readable labels with color coding: 5 → Running (green), 4 → Idle (yellow), 3 → Fault (red).

Tables — Both tables are sorted by time (descending) so the most recent entries appear first.

Dashboard configuration

Time range: last 1 hour (relative)
Refresh rate: 5 seconds
Labels: system=caliperline, view=comprehensive
Grid: 12 columns

Observations

A few things we noticed working with Antigravity + Gemini Pro 3.1 on MaestroHub MCP:

  • Protocol awareness — Gemini correctly handled three different protocol patterns (Modbus readAll, OPC UA with specific function aliases, REST request/response) without confusion.
  • Branching logic — The OP20 fault alert pipeline used sourcePort: "true" on the condition edge correctly on the first attempt.
  • Defensive code — The generated JavaScript includes null checks and fallbacks (data.FaultCode && data.FaultCode.success ? ...), which is important for real industrial connections that may intermittently fail.
  • Dashboard data awareness — Before creating panels, Gemini fetched recent data to understand the actual field names and value ranges rather than guessing thresholds.
  • Complete on first try — The dashboard was created with all 9 panels in a single prompt, including the OP20 fault alerts table.
  • Autonomy from a vague prompt — Given just "design and implement some pipelines using the Caliperline connections", Gemini explored 8 connections, chose 3 that had meaningful data, designed appropriate pipeline patterns for each protocol, and created all three — without being told what to build.

Prompts Summary

For quick reference, here are all the prompts used in order:

  1. "Can you design and implement some pipelines using the Caliperline connections?"
  2. "Now, I want you to create a comprehensive dashboard using those pipelines you just created."

Two prompts. Three pipelines. One dashboard. Zero lines of code written manually.