# What Took BI Engineers Hours, WrenAI Did in 15 Minutes — A Hands-On Test with Manufacturing Data

As a data engineer with years of experience building pipelines and dashboards, I've always felt the traditional BI workflow could be faster: connecting data sources, writing SQL, designing visualizations, tweaking layouts, iterating with stakeholders.

So when I heard about GenBI (Generative Business Intelligence) — the idea that AI can generate dashboards from natural language — I was skeptical. I decided to put it to the test with a real dataset and a real use case.

## The Dataset: Manufacturing Downtime

I used the [Manufacturing Downtime dataset](https://mavenanalytics.io/data-playground/manufacturing-downtime) from Maven Analytics, a well-known practice dataset that simulates a soda bottling production line. It contains four tables:

*   **Line Productivity** — a fact table with details for each batch produced, including operator, product, and start/end times
    
*   **Products** — a dimension table with product details like flavor and size
    
*   **Line Downtime** — a fact table recording downtime in minutes by factor for each batch
    
*   **Downtime Factors** — a dimension table categorizing each downtime factor (e.g., machine failure, operator error, inventory shortage)
    

![image](https://cdn.hashnode.com/uploads/covers/6a7a822667e5903ca79d87c7/271aa4cd-35d3-4815-9012-1d4493ba3dee.png align="center")

The business questions I wanted to answer were straightforward but typical of what a manufacturing operations team would ask:

1.  What are the leading factors causing downtime?
    
2.  Which operators are experiencing the most downtime?
    
3.  Are certain operators struggling with specific types of issues?
    

## The Traditional Approach

In a traditional BI workflow, answering these questions means exploring the schema, figuring out that the downtime table needs to be unpivoted first, writing SQL joins across all four tables, building aggregations, choosing chart types, and arranging everything into a coherent dashboard. For a seasoned BI engineer, this typically takes 2–4 hours. For someone less experienced, it could take a full day.

But the bigger problem isn't speed — it's that **the knowledge isn't transferable**. The metrics live in SQL queries, in DAX formulas, or in a dbt semantic layer. The business logic lives in the engineer's head. Some good data teams write documentation, but it still takes time for a new analyst to internalize it. And every time a stakeholder requests a new dashboard, the whole process starts over.

This is where a semantic layer changes the equation — not just by speeding things up, but by making the business context explicit, reusable, and queryable by anyone.

## The Wren AI Approach: From Excel to Dashboard in 15 Minutes

Here's where things got interesting. Wren AI is an open-source GenBI engine that lets you connect a data source, define a semantic model, and then ask questions in natural language. It generates SQL, runs it, and produces visualizations.

### Setting Up the Project

The dataset is a single Excel file with a CSV data dictionary — that's it.

![image](https://cdn.hashnode.com/uploads/covers/6a7a822667e5903ca79d87c7/d61d5a37-2294-49a0-a524-4cc7f42dee54.png align="center")

I asked Claude Code to set up the Wren AI project by pointing it at the [quickstart guide](https://docs.getwren.ai/oss/get_started/quickstart):

> Read the quickstart guide in this url https://docs.getwren.ai/oss/get\_started/quickstart. Guide me how to set up a Wren AI project for the Excel file in this folder.

Claude Code handled the entire setup: created a Python environment, installed Wren AI and DuckDB, loaded all four Excel sheets into a DuckDB database, installed the Wren CLI skill, created a database profile, and scaffolded the project structure.

The most notable thing: **Claude automatically detected that the Line Downtime table was in wide/pivoted format and unpivoted it** into a normalized `(batch, factor, downtime_minutes)` structure — a data modeling decision that would normally require human judgment.

![image](https://cdn.hashnode.com/uploads/covers/6a7a822667e5903ca79d87c7/77d10f86-8c76-40ea-83bd-e56cd152be95.png align="center")

### Setting Up the Semantic Layer (5–10 minutes)

The semantic layer is where you tell the AI what "downtime" means, how tables relate, and what metrics matter. Think of it as teaching the AI your business context.

Using the `/wren` skill, Claude Code generated a metadata YAML file for each table and a relationships file defining how they connect:

![image](https://cdn.hashnode.com/uploads/covers/6a7a822667e5903ca79d87c7/1b8e8f89-f5e3-4d1f-b26e-8842fb5f67d8.png align="center")

For example, the downtime factors table:

![image](https://cdn.hashnode.com/uploads/covers/6a7a822667e5903ca79d87c7/69065b2b-d07e-4bc5-a5f2-8340943b7623.png align="center")

And the relationships between all four models:

![image](https://cdn.hashnode.com/uploads/covers/6a7a822667e5903ca79d87c7/7b6fd2f0-22ea-43a0-97eb-2e722af86708.png align="center")

![image](https://cdn.hashnode.com/uploads/covers/6a7a822667e5903ca79d87c7/d3b295c4-b3a5-451b-92ca-fd106a811f68.png align="center")

### Asking Questions

Once the semantic model was in place, I simply asked natural language questions.

*"What are the top downtime factors by total minutes?"*

> Machine adjustment is the biggest downtime factor at 332 total minutes, followed by Machine failure (254) and Inventory shortage (225). Notably, the top contributor is an operator error, but the next two are not — so downtime splits roughly evenly between operator-caused and non-operator causes.

<details>
<summary>View the generated SQL and results</summary>
<pre><code class="language-sql">SELECT df.description, df.operator_error, SUM(ld.downtime_minutes) AS total_minutes
FROM line_downtime ld
JOIN downtime_factors df ON ld.factor = df.factor
GROUP BY df.description, df.operator_error
ORDER BY total_minutes DESC
</code></pre>
<pre><code>       description operator_error total_minutes
Machine adjustment            Yes           332
   Machine failure             No           254
Inventory shortage             No           225
      Batch change            Yes           160
Batch coding error            Yes           145
             Other             No            74
     Product spill            Yes            57
 Calibration error            Yes            49
    Labeling error             No            42
      Label switch            Yes            33
 Conveyor belt jam             No            17
</code></pre>
</details>

*"Show me total downtime by operator."*

> Charlie leads with 384 total downtime minutes across 17 events, closely followed by Dee (370 min, 19 events). Mac and Dennis are lower overall, but Mac has the highest minutes-per-event average (~25.5 min/event vs Dee's ~19.5), suggesting fewer but longer downtime incidents.

<details>
<summary>View the generated SQL and results</summary>
<pre><code class="language-sql">SELECT lp.operator, SUM(ld.downtime_minutes) AS total_minutes,
       COUNT(ld.downtime_minutes) AS downtime_events
FROM line_downtime ld
JOIN line_productivity lp ON ld.batch = CAST(lp.batch AS TEXT)
GROUP BY lp.operator
ORDER BY total_minutes DESC
</code></pre>
<pre><code>operator total_minutes  downtime_events
 Charlie           384               17
     Dee           370               19
     Mac           332               13
  Dennis           302               12
</code></pre>
</details>

Wren AI generated correct SQL and returned results within seconds for each question.

### Adding a Cube (Optional)

A cube is a semantic aggregation object: a model plus declared measures, dimensions, and time grains. It's optional, but useful when you want pre-defined, reusable aggregations — so everyone agrees on what "total downtime" means and can slice it without writing SQL.

My prompt:

> Use the /wren skill to add a cube named "downtime" over the line\_downtime model, total\_downtime\_minutes as sum(downtime\_minutes), broken down by operator, factor and product

This created a view that pre-joins all four tables, and a cube definition on top of it:

```yaml
name: downtime
base_object: downtime_detail
measures:
  - name: total_downtime_minutes
    expression: SUM(downtime_minutes)
    type: BIGINT
dimensions:
  - name: operator
    expression: operator
    type: TEXT
  - name: factor
    expression: factor_description
    type: TEXT
  - name: product
    expression: product
    type: TEXT
```

<details>
<summary>View the underlying view definition</summary>
<pre><code class="language-yaml">name: downtime_detail
properties:
  description: "Pre-joined view of downtime events with operator, product, and factor details"
statement: |
  SELECT
    ld.batch, ld.factor, ld.downtime_minutes,
    df.description AS factor_description, df.operator_error,
    lp.operator, lp.product, lp.date,
    p.flavor, p.size
  FROM line_downtime ld
    JOIN downtime_factors df ON ld.factor = df.factor
    JOIN line_productivity lp ON ld.batch = CAST(lp.batch AS TEXT)
    JOIN products p ON lp.product = p.product
</code></pre>
</details>

Now anyone can query the cube directly:

```bash
wren cube query --cube downtime --measures total_downtime_minutes --dimensions operator,factor
```

### Building a Dashboard

With the cube in place, I asked Wren AI to generate a dashboard:

> Use the /wren skill to build a GenBI dashboard from the downtime cube: downtime, filterable by product, operator and factor. Then preview it locally.

The result: a local preview dashboard with KPI cards (total downtime: 1,388 min, average per event: 23 min), bar charts by operator, product, and factor, dropdown filters, and a sortable detail table.

![Vercel screenshot](https://cdn.hashnode.com/uploads/covers/6a7a822667e5903ca79d87c7/6307e89a-5d14-4009-9a8c-75bc1ffb2e2e.png align="center")

**Total: ~15 minutes** from a raw Excel file to an interactive dashboard.

## What Impressed Me

**The semantic layer makes the difference.** This is what separates Wren AI from a simple "GPT wrapper over SQL." The semantic model — built using Wren's Modeling Definition Language (MDL) — gives the AI a structured understanding of data relationships and business terms. Without it, the AI would be guessing at joins and column meanings. With it, the results were accurate and contextually appropriate.

**It handled follow-up questions naturally.** After seeing the top downtime factors, I could ask *"Break this down by operator"* and the AI understood the context. This conversational flow is something traditional BI tools simply don't offer.

## What You Should Know (The Honest Part)

**The semantic model setup is not optional.** If you skip it or define it poorly, output quality drops significantly. Someone with data modeling experience still needs to be involved — GenBI doesn't eliminate the need for BI engineers, it redirects their effort from writing queries to defining business context.

**Chart customization is minimal.** You can't control colors, axes, or layout the way you would in Power BI or Tableau. But that's by design: Wren AI prioritizes speed of insight over presentation polish. If your stakeholders need pixel-perfect branded dashboards, you'd use Wren AI for exploration and hand off the final presentation to a traditional BI tool.

**Complex business logic needs guidance.** For straightforward aggregations and breakdowns, Wren AI performed well. For more complex calculations — like efficiency ratios or time-weighted averages — you'd need to define those as metrics in the semantic layer rather than expecting the AI to infer them.

## The Bigger Picture

This isn't about replacing BI engineers — it's about changing what they spend their time on. Instead of writing repetitive aggregation queries and building routine dashboards, they can focus on the semantic layer: defining business logic, ensuring data quality, and building the foundation that makes GenBI reliable. For manufacturing teams specifically, downtime analysis shouldn't require a half-day turnaround. An operations manager should be able to ask *"Why did Line 3 have so much downtime last week?"* and get an answer in seconds.

* * *

*I'm a data engineer exploring how GenBI is reshaping the BI landscape. I write about hands-on experiences with tools like Wren AI and Databricks Genie. Follow me for more practical takes on the future of data analytics.*
