---
title: "Machine monitoring app-based architecture patterns"
slug: "machine-monitoring-app-based-architecture-patterns"
updated: 2025-12-22T17:27:47Z
published: 2025-12-22T17:27:47Z
---

> ## Documentation Index
> Fetch the complete documentation index at: https://support.tulip.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Machine monitoring app-based architecture patterns

Tulip offers flexibility in how you structure apps around machines. The right pattern depends on your team's technical maturity, process standardization, and budget.

## Pattern 1: Composable machine apps (1:1 model)

**Structure**: One machine → One app → One station → One terminal

**Architecture diagram**:
![Machine Terminal App Pattern 1 - Composable Machine Apps.png](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Machine%20Terminal%20App%20Pattern%201%20-%20Composable%20Machine%20Apps(1).png){height="" width=""}

### Use cases

- **Entry-level citizen developers** building their first machine monitoring apps  
- **Quick proof-of-concept** deployments where simplicity outweighs efficiency  
- **Custom human processes** per machine instance (e.g., Machine 1 requires unique inspection steps not applicable to Machine 2)  
- **Operations-led development** where developers have multiple roles and limited time

### Why this matters

This pattern physically maps software to hardware 1:1, eliminating abstraction. Developers can identify a machine on the shop floor and map it to its own app. This clarity reduces mental effort and makes troubleshooting intuitive.

### Example

**Scenario**: A food and beverage manufacturer has 3 packaging lines. Each line has unique downtime reasons, part configurations, and operator workflows.

### Implementation

- Create {{glossary.Machine Type}}: "Packaging Line"  
- Create 3 machines: "Line A", "Line B", "Line C"  
- Build 3 apps: "Line A Terminal", "Line B Terminal", "Line C Terminal"  
- Assign each app to a dedicated station with a fixed terminal

#### Benefits
* Clear data isolation prevents cross-machine data corruption
* Easy to customize per-machine workflows
* Simple troubleshooting (problem is always in one self-contained app) 

#### Limitations
* Requires one physical terminal per machine (hardware cost)
* Global app changes require updating 3 separate apps
* Not scalable beyond approximately 10 machines


## Pattern 2: Machine assignment to station app

**Structure**: One machine type → One app → Multiple stations (machine dynamically assigned via station mapping)

**Architecture diagram**:
![Machine Terminal App Pattern 2 - Machine Assigned Station.png](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Machine%20Terminal%20App%20Pattern%202%20-%20Machine%20Assigned%20Station.png){height="" width=""}

### Use cases

- **Standardized processes** across identical machine types  
- **Full-time citizen developers** comfortable with abstraction and trigger logic  
- **Horizontal scaling** needed (10+ machines of same type)  
- **Centralized app maintenance** is a priority

### How it works

1. Assign each machine to a station in **Shop Floor > Machines** (Configuration tab)  
2. In the app, use **"at this station"** trigger conditions to dynamically reference the assigned machine  
3. When the app runs on Station 1, it interacts with Machine 1. When it runs on Station 2, it interacts with Machine 2

#### Example app trigger

**When**: Machine at this station outputs State Change
**If**: Machine Output / State Change = Down
**Then**: Create Table Record in 'Status History' Table.


<img src="https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Log%20to%20Status%20History%20when%20Machine%20Stopped.png" 
     alt="Log to Status History when Machine Stopped" 
     style="border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0,0,0,0.15); border-radius: 4px; max-width: 100%; height: auto;">


### Example

**Scenario**: Automotive tier-1 supplier has 15 identical CNC mills running the same production process.

#### Implementation

- Create machine type: "CNC Mill 5-Axis"  
- Create 15 machines (CNC-001 through CNC-015)  
- Build **one app**: "CNC Operator Terminal"  
- Create 15 stations, assign one machine to each  
- Deploy the single app to all 15 stations

#### Benefits
* Single app to maintain (global updates propagate instantly)
* Reduced app development time for fleet deployments
* Uses "at this station" trigger logic (built-in dynamic machine reference)  

#### Limitations
* Still requires one terminal per station (hardware cost remains)
* All machines must be the same type with identical attributes
* Custom per-machine logic requires conditional branching (added complexity)



## Pattern 3: Machine variable app (floating terminal)


**Structure**: One app → Multiple machine types → Variable-based machine selection → Shared/floating terminal

**Architecture diagram**:
![Machine Terminal App Pattern 3 - Machine Variable.png](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Machine%20Terminal%20App%20Pattern%203%20-%20Machine%20Variable.png){height="" width=""}

### Use cases

- **Budget constraints**: Limited terminals available  
- **Floating operator model**: One operator moves between machines with a shared iPad  
- **Machines don't require continuous monitoring**: App only needs to run during active operations

### Critical limitation: Not headless

**This pattern does not support background/headless monitoring.** If the app is closed, then no machine triggers fire. This pattern is **only suitable** for:

- Human-initiated data entry (operator logs defects, part counts)  
- Ad-hoc machine inspections  
- Scenarios where machines don't generate data when app is not running

### How it works

1. Create a **machine variable** in the app (e.g., `selectedMachine`)  
2. Add a dropdown widget or QR code scan to populate `selectedMachine` at runtime  
3. Use `selectedMachine` in all trigger references

#### Example app trigger

**When**: machine Machine Variable 'Selected Machine' outputs {Attribute}
**Then**: Store Last Machine Output to Variable

<img src="https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Store%20Machine%20Variable%20Output%20to%20Variable.png" 
     alt="Store Machine Variable Output to Variable" 
     style="border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0,0,0,0.15); border-radius: 4px; max-width: 100%; height: auto;">

### Example

**Scenario**: Pharmaceutical lab has 5 analytical instruments that only run during scheduled tests. Technicians use a shared iPad to log test parameters and results.

#### Implementation

- Create 5 machines (HPLC-1, GC-MS-2, etc.)  
- Build one app: "Lab Equipment Log"  
- Add dropdown: "Select Instrument" → populates `selectedMachine` variable  
- Technician carries iPad between instruments, selects active machine, logs data

#### Benefits
* Minimal hardware cost (one shared terminal)
* Flexible machine selection at runtime
* Ideal for ad-hoc/intermittent workflows

#### Limitations
* **Not headless** - app must be actively running for any logic to execute
* No background monitoring when app is closed
* Complex state management (Which machine is currently active?)
* Not suitable for 24/7 OEE tracking


## Architecture pattern decision tree

Use this decision tree to select the best pattern for your needs:
![Machine Terminal App Pattern Architect Options v2.png](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Machine%20Terminal%20App%20Pattern%20Architect%20Options%20v2.png){height="" width=""}


## Further reading

* [Machine monitoring - Headless vs. app-based architecture](/r230/docs/machine-monitoring-headless-vs-app-based-architecture)
* [Variables](/r230/docs/variables)

{{snippet.Did you find what you were looking for}}
