---
alias: tutorials-automation-scheduled-action-scenario-03-no-materials-on-resource
description: "Show how to combine material-based readiness, time windows, and a sanitation confirmation gate to update controllers during a clean maintenance state."
---
# Scenario 3 - Controller Version Update - No Materials on Resource
## Overview
This scenario shows how to use the `No Materials on Resource` **Detector** combined with a `Ready Delay` **Acceptance Gate** to trigger a **Controller** version update only after a **Resource** has been continuously empty for a sustained period. This pattern filters out transient empty states, such as the brief gap between batches, and only acts once a genuine, stable clear state is confirmed. A second **DEE Action Acceptance Gate** verifies an external record before proceeding.
In this example, the cookie factory's mixing **Controller** update is tied to the weekly sanitation cycle: the update runs only during the weekend CIP window, after all **Materials** have cleared and a completed sanitation record has been logged in the food safety system.
### When to Use
- **CIP and sanitation windows** - applying a **Controller** update only after a Clean-In-Place cycle has completed and the equipment is confirmed empty, ensuring the update never interrupts a cleaning run.
- **Changeover protection** - preventing execution during the brief **Material** gap between batches (when the resource is momentarily empty) by requiring a sustained empty period before acting.
- **Material-driven scheduling** - when the right moment to perform maintenance is defined by production completing naturally rather than by a fixed time window; the equipment tells you when it is ready by having no materials.
- **Regulatory compliance** - pairing a zero-material confirmation with a **Controller** update creates a documented record that maintenance was performed during a verified clean state, useful for audit purposes.
### Example
The cookie factory has just completed a sticky caramel production run on its mixing lines. Before updating the mixing **Controller** from `B/6` to `B/7`, the system waits for each mixer to fully clear: 10 consecutive minutes with no **Materials** on the **Resource** confirms a genuine CIP state rather than an inter-batch gap. A second gate verifies that a sanitation record has been logged in the food safety system before proceeding.
- **Resources**: `ASA Mixer-01`, `ASA Mixer-02`, `ASA Mixer-03`.
- **Controller**: `MixingController`.
- Current version: revision `B`, version `6`.
- Target version: revision `B`, version `7`.
```mermaid
graph LR
subgraph current["MixingController B/6 (current)"]
X1[Mixer-01] & X2[Mixer-02] & X3[Mixer-03]
end
X1 -->|UpdateControllerVersion| X1T[Mixer-01]
X2 -->|UpdateControllerVersion| X2T[Mixer-02]
X3 -->|UpdateControllerVersion| X3T[Mixer-03]
subgraph target["MixingController B/7 (target)"]
X1T & X2T & X3T
end
```
## Prerequisites
Before creating the Definition, confirm the following:
- Load the Scenario 3 automation master data into MES as it creates the `MixingController [B.6]` and `MixingController [B.7]` **Controller** definitions, `mixing-manager-nextgen` record, and all three mixer instances (master data package: [01-automation-masterdata.json](./masterdata/scenario03/01-automation-masterdata.json)).
- All target instances are currently running `MixingController` revision `B`, version `6`.
- Each **Resource** is correctly linked to its **Automation Controller Instance**. The `NoMaterialsOnResource` **Detector** depends on this link.
- Maintenance version `B/7` is available on the **Controller** definition.
- For the sample **DEE Action Acceptance Gate**, create MES Configuration Entries under `/Cmf/Tutorials/AutomationScheduleAction/Scenario3/SanitationRecordLogged/{resourceName}` and set the target **Resource** to `true` when you want the sanitation-record gate to pass.
- Notification templates `ASA PreAction Template`, `ASA Success Template`, `ASA Failure Template`, and `ASA Ignored Template` exist in MES if you intend to use notifications.
- **DEE action** [`ASA_Scenario3_CheckSanitationRecordLogged`](./dees/ASA_Scenario3_CheckSanitationRecordLogged.cs) is created and deployed in MES before enabling the Definition (see [[howto-iot-import-dee-action]]).
## Configuration
### Why This Pattern
This Definition uses the following combination of components:
| Component | Type | Purpose |
|---|---|---|
| **Context** | `AutomationController` | Discovers all instances currently running `MixingController B/6`. |
| **Pre-Conditions** | `AllowedWeekdays` + `AllowedTimeWindow` | Restricts processing to the planned weekend sanitation window only. |
| **Detector** | `NoMaterialsOnResource` | Confirms no active or queued materials remain on the mixer resource. |
| **Acceptance Gates** | `ReadyDelay` + `CustomDeeAction` | Two gates in order: first requires the resource to remain empty for 10 minutes, filtering out inter-batch gaps; second verifies the sanitation record has been logged in the food safety system. Both must pass. |
| **Action** | `UpdateControllerVersion` | Applies the controller update from `B/6` to `B/7`. |
| **Post Action Validation** | `MaxStartupTime` | Confirms the updated runtime starts within 8 minutes. |
Table 1: Scenario 3 Component Design
### Create the Definition
Open **Automation Scheduled Action** and select **Create** (see [[user-guide-automation-scheduled-action-create|Create Definition]]). The wizard has four tabs.
#### Tab 1 - General Data
Start by filling in the general definition fields.
- Give it a name like `CF_Mixer_Sanitation_Window_Update` and a description that captures its purpose (for example, "Update mixer controller only when sanitation window is open and resources are cleanly empty.")
- Set **Is Enabled** to **Disabled** for now.
- Set **Validity** to `3` days. This covers one full weekend plus some margin. Adjust if your sanitation schedule spans more than one weekend.
For **Context**, select **Automation Controller**, enter `MixingController` as the controller.
- Set **Revision** to `B` and **Version** to `6`.
This targets all instances currently running `MixingController B/6`, one task per instance.
For the **Detector**, select `No Materials on Resource`. This confirms no active or queued **Materials** remain on the mixer **Resource**. Sub-resources are not evaluated.
For the **Action**, select **Update Controller Version**:
- Set **Revision** to `B` and **Version** to `7`.
Optionally, configure notification templates to be alerted at key moments:
| Event | Template |
|---|---|
| Pre-Action | `ASA PreAction Template` |
| Success | `ASA Success Template` |
| Failure | `ASA Failure Template` |
| Ignored | `ASA Ignored Template` |
Table 2: Scenario 3 Notification Templates
#### Tab 2 - Pre-Conditions
Select :material-plus: twice to add the following pre-conditions in this order:
**1. Allowed Weekdays** - Set the weekdays to `Saturday` and `Sunday` to restrict processing to the weekend sanitation schedule.
**2. Allowed Time Window** - Set the window to `01:00–05:00`. This is the narrow sanitation window in UTC. Adjust for your plant timezone offset.
#### Tab 3 - Acceptance Gates
Select :material-plus: twice to add the following gates in this order:
**1. Ready Delay** - Set the delay to `600` seconds. The **Resource** must remain empty for 10 consecutive minutes before this gate passes. This filters out the brief **Material** gap between batches, which is shorter than a genuine CIP state. Adjust to a value that reliably distinguishes a true sanitation state from a normal batch gap in your process.
**2. DEE Action** - Enter `ASA_Scenario3_CheckSanitationRecordLogged` as the **Action**. This queries the food safety system to confirm a completed sanitation record exists for this **Resource**. If the **Action** returns `false`, the task stays at `SkippedGateFailed` until the record is available.
#### Tab 4 - Post-Action Validations
Select :material-plus: and select **Max Startup Time**. Set the timeout to `480` seconds. This waits up to 8 minutes for the updated runtime to reach a running state.
!!! tip "Verify tasks before enabling"
Click **Save** with **Is Enabled** set to **Disabled**. The system immediately resolves the context and creates one task per target instance.
Before enabling, open **Automation Scheduled Action Tasks** and confirm:
- All expected targets appear in the task list.
- No unexpected targets are included.
Once the task list is correct, enable the Definition from the top ribbon (see [[user-guide-automation-scheduled-action-enable-disable|Enable or Disable Definition]]).
## How It Works at Runtime
After you enable the Definition, the system processes each task on every polling pass as follows:
1. **Context** discovers all instances running `MixingController B/6` and creates one task per instance.
2. Weekday and time-window preconditions are checked against current UTC time. Tasks are skipped outside the Saturday–Sunday `01:00–05:00` window.
3. `NoMaterialsOnResource` checks whether the linked mixer **Resource** has any active or queued materials. If any **Materials** are present, the task is skipped on this pass.
4. The `ReadyDelay` **Acceptance Gate** confirms the **Resource** has been empty for at least 10 consecutive minutes.
5. `ASA_Scenario3_CheckSanitationRecordLogged` queries the food safety system to confirm a completed sanitation record exists for this **Resource**. If it returns `false`, the task is skipped with `SkippedGateFailed` and retried on the next pass.
6. The **Action** updates the **Controller** runtime from `B/6` to `B/7`.
7. `MaxStartupTime` waits up to 8 minutes for the updated runtime to reach a running state.
8. The task is finalized with outcome and notifications are sent.
```mermaid
flowchart TD
A([Task per Mixer resource]) --> B{"Sat or Sun?
01:00-05:00 UTC?"}
B -- No --> S1([SkippedPreConditionFailed])
B -- Yes --> C{"No active or queued
materials on resource?"}
C -- No --> S2([SkippedNotReady])
C -- Yes --> D{"Empty 10+ min?"}
D -- No --> S3([SkippedGateFailed])
D -- Yes --> G{"Sanitation record
logged?"}
G -- No --> S3
G -- Yes --> E["UpdateControllerVersion
B/6 to B/7"]
E --> F{"Running within
480 s?"}
F -- No --> FAIL([ValidationFailed])
F -- Yes --> OK([ProcessedSuccess])
```
## Expected Task Outcomes
| `LastOutcome` | `State` | Meaning |
|---|---|---|
| `ProcessedSuccess` | `Processed` | **Controller** updated and runtime started successfully within the timeout. |
| `IgnoredNoOp` | `Ignored` | Instance was already running `B/7` - no change needed. |
| `ActionFailed` | `Failed` | Version update failed. Check **Manager** capacity and **Controller** definition availability. |
| `ValidationFailed` | `Failed` | Update ran but the runtime did not reach running state within 8 minutes. |
| `SkippedPreConditionFailed` | (task stays active) | Current UTC time or weekday is outside the sanitation window. |
| `SkippedNotReady` | (task stays active) | **Resource** still has active or queued materials. |
| `SkippedGateFailed` | (task stays active) | **Resource** became empty but has not sustained that state for 10 minutes yet, or the sanitation record check returned `false`. |
Table 3: Scenario 3 Task Outcomes
## Simulating This Scenario
Confirm the Scenario 3 master data is loaded and all mixer instances are running on `mixing-manager-nextgen` before starting. This scenario uses `NoMaterialsOnResource` as the **Detector** so that readiness is controlled by **Material** assignments, not by file operations.
### Adjusting the Time Window for a Quick Demo
The Definition only evaluates inside the `Sat/Sun 01:00–05:00` window. For a development demo, temporarily update `AllowedWeekdays` to include all days and `AllowedTimeWindow` to `["00:00-23:59"]` so you can run at any time. Restore the production values before deployment.
### Preparing a Non-Ready Initial State
Track in a **Material** lot on one or more **Resources** before enabling the Definition. This creates a non-ready starting state so you can observe the task in `SkippedNotReady` before triggering readiness.
### To Trigger Processing for One Resource
1. Complete or scrap all **Materials** currently tracked in on `ASA Mixer-01`. The **Resource** must have no active or queued **Materials**.
2. Open **Automation Scheduled Action** Task and confirm `IsReady` becomes `true` for the `ASA Mixer-01` task.
3. Wait 10 minutes without tracking in new **Materials**. The `ReadyDelay` gate passes.
4. Set `/Cmf/Tutorials/AutomationScheduleAction/Scenario3/SanitationRecordLogged/ASA Mixer-01` to `true`. The sample **DEE Action Acceptance Gate** reads this value; if you leave it `false`, the task remains at `SkippedGateFailed`.
5. The task executes `UpdateControllerVersion` from `B/6` to `B/7`.
6. The task transitions to `ProcessedSuccess`.
### To Demonstrate the Gate Reset
1. Clear materials from `ASA Mixer-02` - `IsReady` becomes `true`.
2. After 7 minutes, track in a new material lot on `ASA Mixer-02`.
3. `IsReady` drops to `false` and `ReadyStateChangedAt` resets.
4. Complete that material again - the 10-minute countdown restarts from zero.
### To Observe the Difference Between `SkippedPreConditionFailed` and `SkippedNotReady`
- Outside the allowed window: tasks show `SkippedPreConditionFailed`. The **Detector** is never evaluated.
- Inside the window but with **Materials** present: tasks show `SkippedNotReady`. The **Pre-Condition** passed, the **Detector** returned not ready.
### To Observe the Ignored Outcome
Before enabling the Definition, manually update one instance to `MixingController B/7` directly from the **Automation Controller Instance** record. Enable the Definition and the task for that instance transitions immediately to `IgnoredNoOp` because the instance is already in the desired state.
### To Reset and Repeat
1. Revert the instance back to `MixingController B/6` from the **Automation Controller Instance** record.
2. Track in **Materials** on the **Resource** to restore a non-ready starting state.
3. Create a new Definition (the original tasks are in a terminal state and will not re-evaluate).
## Troubleshooting
### Cross-Midnight Windows Must Be Split
`AllowedTimeWindow` does not support windows that span midnight (for example, `22:00-02:00`). Split the window into two entries: `"22:00-23:59"` and `"00:00-02:00"`. Both entries must be specified, the **Pre-Condition** passes if the current time falls within either one.
### OnHold Materials Are Not Detected
`NoMaterialsOnResource` only evaluates active and queued **Materials**. **Materials** in an `OnHold` state are ignored by this **Detector**. If your process treats on-hold **Materials** as a blocking condition, add a **DEE Action Pre-Condition** or **Acceptance Gate** to check for them explicitly.
### Resource-to-Instance Mapping Is Required
`NoMaterialsOnResource` works by inspecting the **Resource** linked to the **Automation Controller Instance**. If that link is missing or incorrect, the **Detector** cannot retrieve the **Material** status and will return not ready on every pass. Verify **Resource** assignments before enabling the Definition.
### Adjusting the Ready Delay for Your Process
The 10-minute ready delay is designed to exclude the typical inter-batch gap on cookie mixing lines. If your process has longer or shorter transition periods, adjust the `ReadyDelay` value to one that reliably distinguishes a true sanitation state from a normal batch gap.