# 01 Production Status

In this tutorial you build a dashboard that shows the current production status of two machines side by side. Constant variables store the machine UUIDs, and all data comes from the ENLYZE API:

<figure><img src="https://4261006941-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSNEuiyRRKwuqtIcaEt45%2Fuploads%2Fgit-blob-d68b34996f7b30712d2973701c31058df26cdd3d%2Fgrafana-status-hero-01.png?alt=media" alt=""><figcaption></figcaption></figure>

## What you will learn

* Constant variables for fixed machine configurations
* Fetch machine names from the API instead of hard-coding them
* Detect running production runs with JSONata
* Display OEE metrics from production runs
* Multi-machine layout with side-by-side panels

## Prerequisites

* [API queries](https://docs.enlyze.com/en/integrations/grafana/advanced-api/02-api-queries), [Variables](https://docs.enlyze.com/en/integrations/grafana/advanced-api/03-variables), and [Advanced variables](https://docs.enlyze.com/en/integrations/grafana/advanced-api/03b-advanced-variables) completed
* Understanding of the `production-runs` endpoint and JSONata

***

## When to use constant variables

In [Variables](https://docs.enlyze.com/en/integrations/grafana/advanced-api/03-variables) and [Advanced variables](https://docs.enlyze.com/en/integrations/grafana/advanced-api/03b-advanced-variables) you created query variables with dropdown selection. For shopfloor displays or status monitors that always show the same machines, a dropdown is unnecessary.

Constant variables solve this case:

* **Fixed configuration**: The machine UUIDs are defined directly in the variable settings
* **Hidden**: `Hide: Variable` hides them from the dashboard, since users should not change them
* **Single point of configuration**: To swap a machine, you only change the variable instead of editing every query individually

***

## Create constant variables

Create a new dashboard and add two constant variables:

| Name       | Type     | Value                                  | Hide     |
| ---------- | -------- | -------------------------------------- | -------- |
| `machine1` | Constant | `141e0927-62b3-4e76-8398-ad82d20f397f` | Variable |
| `machine2` | Constant | `f5c0b9d4-e89e-43ad-b81c-16bd5cbe3646` | Variable |

You can find the UUIDs in the ENLYZE web app or via the `machines` endpoint.

***

## Display machine names

Instead of storing the machine name as another constant, you fetch it from the API. This way the name stays up to date if it is renamed in ENLYZE.

Create a **Stat** panel with these settings:

| Setting       | Value                  |
| ------------- | ---------------------- |
| URL           | `machines/${machine1}` |
| Root selector | *(empty)*              |

Under **Value options** > **Fields**, select `name` from the dropdown. This makes the panel show only the machine name.

<figure><img src="https://4261006941-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSNEuiyRRKwuqtIcaEt45%2Fuploads%2Fgit-blob-2bbc2ecaf8260512e64d7154ee9e9075e6ac7bc9%2Fgrafana-status-machine-name-01.png?alt=media" alt=""><figcaption><p>Stat panel with API query for the machine name</p></figcaption></figure>

You know this pattern from [Variables](https://docs.enlyze.com/en/integrations/grafana/advanced-api/03-variables): the API returns a JSON object with all fields of the machine. The field selector makes the panel display only the `name` field.

Configure the panel:

* **Color mode**: None
* **Text mode**: Value
* **Transparent**: Enable (for a clean layout without panel borders)

***

## Detect the running production run

The `production-runs` endpoint returns production runs sorted by start time. The most recent run is at position `[0]`. If it has no `end` timestamp, it is still running.

### Status indicator

Create a **Stat** panel:

| Setting       | Value                                                                     |
| ------------- | ------------------------------------------------------------------------- |
| URL           | `production-runs`                                                         |
| Query Params  | `machine=${machine1}`, `start=${__from:date:iso}`, `end=${__to:date:iso}` |
| Root selector | `$.data[0].end = null ? "Running" : "Completed"`                          |

The root selector is a JSONata expression: if the `end` of the most recent run is `null`, it returns "Running", otherwise "Completed".

Under **Value Mappings**, create two entries:

| Value     | Display   | Color |
| --------- | --------- | ----- |
| Running   | Running   | Green |
| Completed | Completed | Blue  |

Set **Color mode** to **Background**.

### Current production run

Create a second **Stat** panel for the production order number:

| Setting       | Value                                                                     |
| ------------- | ------------------------------------------------------------------------- |
| URL           | `production-runs`                                                         |
| Query Params  | `machine=${machine1}`, `start=${__from:date:iso}`, `end=${__to:date:iso}` |
| Root selector | `$.data[0].production_order`                                              |

<figure><img src="https://4261006941-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSNEuiyRRKwuqtIcaEt45%2Fuploads%2Fgit-blob-e62678ebed503c8522736f86960dbc2cc6a4c3ce%2Fgrafana-status-run-indicator-01.png?alt=media" alt=""><figcaption><p>Status indicator and current production run</p></figcaption></figure>

***

## OEE of the latest production run

The `production-runs` endpoint includes OEE metrics per production run. Create four **Stat** panels for OEE, Availability, Performance, and Quality.

### OEE panel

| Setting       | Value                                                                     |
| ------------- | ------------------------------------------------------------------------- |
| URL           | `production-runs`                                                         |
| Query Params  | `machine=${machine1}`, `start=${__from:date:iso}`, `end=${__to:date:iso}` |
| Root selector | `$.data`                                                                  |

Expand **Parsing options & Result fields** and add a **Column**:

| Selector             | Title        | Type   |
| -------------------- | ------------ | ------ |
| `productivity.score` | Productivity | Number |

Configure the panel:

* **Unit**: Percent (0.0-1.0)
* **Color mode**: Background
* **Thresholds**: Red (base), Yellow (0.6), Green (0.8)
* **Value Mapping**: `null` -> "NO DATA" (Gray)

### Why columns instead of the root selector?

It would be tempting to extract the score directly in the root selector, e.g. `$.data[0].productivity.score`. This works as long as the API returns data. However, if a machine did not run during the selected time range, `$.data` is an empty array. Accessing `[0]` then fails, and Grafana shows an error instead of an empty panel.

The solution: set the root selector to `$.data` and extract the value via a **Column** (`productivity.score`). When there is no data, the column returns `null`. You can then display this `null` value as "NO DATA" using a **Value Mapping**.

### Additional OEE panels

Create panels for the remaining metrics using the same pattern:

| Panel        | Root selector | Column Selector      |
| ------------ | ------------- | -------------------- |
| Availability | `$.data`      | `availability.score` |
| Performance  | `$.data`      | `performance.score`  |
| Quality      | `$.data`      | `quality.score`      |

Configure a value mapping for `null` -> "NO DATA" in gray on all panels. Not all machines provide quality data, and machines without production in the selected time range show "NO DATA" for all metrics.

<figure><img src="https://4261006941-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSNEuiyRRKwuqtIcaEt45%2Fuploads%2Fgit-blob-7107c838bdb8aaf51a49ee227624210e514ca966%2Fgrafana-status-oee-row-01.png?alt=media" alt=""><figcaption><p>OEE metrics of the latest production run</p></figcaption></figure>

***

## Production run details table

Show the latest production runs with OEE details as a table.

Create a **Table** panel:

| Setting       | Value                                                                     |
| ------------- | ------------------------------------------------------------------------- |
| URL           | `production-runs`                                                         |
| Query Params  | `machine=${machine1}`, `start=${__from:date:iso}`, `end=${__to:date:iso}` |
| Root selector | `$.data`                                                                  |

Add columns under **Parsing options & Result fields**:

| Selector               | Title | Type      |
| ---------------------- | ----- | --------- |
| `production_order`     | Order | String    |
| `start`                | Start | Timestamp |
| `productivity.score`   | OEE   | Number    |
| `quantity_yield.value` | Yield | Number    |

Configure a **Field Override** for the OEE column:

* **Unit**: Percent (0.0-1.0)
* **Min**: 0, **Max**: 1
* **Cell type**: Gauge (basic)
* **Color scheme**: Continuous - RdYlGr

<figure><img src="https://4261006941-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSNEuiyRRKwuqtIcaEt45%2Fuploads%2Fgit-blob-fd494b7d4c8f5cb2418116338a6df32b2f23abe9%2Fgrafana-status-runs-table-01.png?alt=media" alt=""><figcaption><p>Production runs table with OEE as gauge cell</p></figcaption></figure>

***

## Add the second machine

Duplicate all panels from the first machine and replace `${machine1}` with `${machine2}` in every query. Position the panels side by side: left side (x=0, width 12) for Machine 1, right side (x=12, width 12) for Machine 2.

{% hint style="info" %}
For dashboards with many machines, manually duplicating panels is impractical. Use the repeat pattern from [Advanced variables](https://docs.enlyze.com/en/integrations/grafana/advanced-api/03b-advanced-variables) instead to automatically repeat panels for each machine.
{% endhint %}

***

## Tips

* **Auto-refresh**: For shopfloor displays, set a refresh interval of 30 seconds to 1 minute (top right, next to the time picker).
* **Running production runs**: The API returns production runs sorted by start time. `$.data[0]` is always the most recent run in the selected time range.
* **More machines**: For each additional machine, add a constant variable and duplicate the panels. With three or more machines, the repeat pattern from [Advanced variables](https://docs.enlyze.com/en/integrations/grafana/advanced-api/03b-advanced-variables) is worth using.

***

## Next steps

* [**OEE dashboard**](https://docs.enlyze.com/en/integrations/grafana/production-dashboards/05-oee-dashboard) -- Create aggregated OEE reports with the `productivity-metrics` endpoint


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.enlyze.com/en/integrations/grafana/production-dashboards/04-production-status.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
