--- alias: tutorials-automation-scheduled-action-scenario-02-fixed-validity-window description: "Show how to use validity windows, readiness checks, and post-action validation to constrain a controller update to a fixed maintenance period." --- # Scenario 2 - Controller Version Update - Fixed Validity Window ## Overview This scenario shows how to use the **Validity** field as the primary design constraint for an **Automation Controller** version update that must complete within a fixed maintenance window and must not execute outside it. When the window closes, tasks expire cleanly rather than silently retrying in the next production period. A **DEE Action** **Post-Action Validation** registers each completed update as a traceable record in the ERP system. In this example, the cookie factory's molding **Controller** is updated during a year-end holiday shutdown, running in parallel with [Scenario 1](01-change-automation-manager-cookie-lines.md) on separate **Resources**. Both operations are independent and can proceed simultaneously. ### When to Use - **Holiday or shutdown windows** - maintenance that must complete within a fixed production pause and must not spill over into the next production period under any circumstances. - **Compliance deadlines** - regulatory or certification updates with a hard expiry date; if the update does not complete before the deadline, the Definition expires cleanly and a new process must begin rather than silently retrying. - **Annual equipment overhauls** - one-time updates aligned to a scheduled annual or seasonal maintenance event where the window is fixed, known in advance, and will not recur for months. - **Event-driven one-shot maintenance** - updates tied to a specific operational event (end of season, major product changeover, facility audit) that will not repeat on a predictable schedule. - **Risk-bounded rollouts** - when you want automatic expiry as a safety net: if the update did not happen within the intended window, the system stops trying rather than executing at an unintended time in the next production period. ### Example The cookie factory's molding lines are due for a **Controller** update during the same year-end holiday shutdown as [Scenario 1](01-change-automation-manager-cookie-lines.md). The two operations run in parallel on separate resources. The molding update must complete within the 3-day window. Any molder that does not reach a ready state before the window closes will have its task expire cleanly rather than silently retry in the next production period. - **Resources**: `ASA Molder-01`, `ASA Molder-02`. - **Controller**: `MoldingController`. - Current version: revision `B`, version `4`. - Target version: revision `B`, version `5`. ```mermaid graph LR subgraph current["MoldingController B/4 (current)"] M1[Molder-01] M2[Molder-02] end M1 -->|UpdateControllerVersion| M1T[Molder-01] M2 -->|UpdateControllerVersion| M2T[Molder-02] subgraph target["MoldingController B/5 (target)"] M1T M2T end ``` ## Understanding Validity `Validity` is the number of days a task remains active before it expires. A task that reaches its `ValidUntil` timestamp without being processed transitions to `State = Expired` and stops being evaluated. Choosing the right `Validity` value is a deliberate design decision: | Choice | Effect | |---|---| | Too short | Tasks expire before molders reach a ready state, missing the window entirely. | | Too long | The Definition keeps evaluating tasks well past the intended window, risking unintended execution in a later production period. | | Matched to the event | Tasks are active exactly as long as the maintenance window lasts, and expire cleanly when the window closes. | Table 1: Validity Design Choices For this scenario, the year-end holiday shutdown lasts 3 days (Saturday through Monday). Setting `Validity = 3` means each task is active for exactly 72 hours from the moment the Definition is enabled, then expires if not processed. ```mermaid gantt title Holiday Window - Validity = 3 days dateFormat YYYY-MM-DD section Factory Holiday pause :done, hp, 2024-12-28, 3d Production resumes :milestone, m1, 2024-12-31, 0d section Tasks Enable Definition :milestone, m0, 2024-12-28, 0d Tasks active :active, v1, 2024-12-28, 3d Tasks expire :crit, exp, 2024-12-31, 1d ``` ## Prerequisites Before creating the Definition, confirm the following: - Load the Scenario 2 automation master data into MES. It creates the `MoldingController [B.4]` and `MoldingController [B.5]` **Controller** definitions, `molding-manager` record, and both molder instances (master data package: [01-automation-masterdata.json](./masterdata/scenario02/01-automation-masterdata.json)). - All target instances are currently running `MoldingController` revision `B`, version `4`. - Version `B/5` is available on the **Controller** definition. - Each molder **Resource** has a valid MES state model that includes `Standby` or `Scheduled Down`. - The maintenance window start and end times in UTC are confirmed with the operations team. - MES Configuration Entry `/Cmf/Tutorials/AutomationScheduleAction/Scenario2/ErpRegistrationEnabled` is set to `true` if you want the sample **Post-Action Validation DEE** to end in `ProcessedSuccess`. Set it to `false` to demonstrate `ValidationFailed`. - 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_Scenario2_RegisterMolderUpdateInERP`](./dees/ASA_Scenario2_RegisterMolderUpdateInERP.cs) is created and deployed in MES before enabling the Definition (see [[howto-iot-import-dee-action]]). !!! warning "Enable the Definition at the right moment" `ValidUntil` is calculated from the moment each task is created, which happens when the Definition is first evaluated after being enabled. Enable the Definition at the start of the maintenance window, not before, so the validity countdown aligns with the available time. ## Configuration ### Why This Pattern This Definition uses the following combination of components: | Component | Type | Purpose | |---|---|---| | **Context** | `AutomationController` | Discovers all instances running `MoldingController B/4`. | | **Pre-Conditions** | `AllowedWeekdays` + `AllowedTimeWindow` | Restricts execution strictly to the holiday window. Provides a secondary guard even within the validity period. | | **Detector** | `EntityStateInList` | Confirms the molder is in a safe state before acting. | | **Acceptance Gate** | `ReadyDelay` | Requires the molder to hold the ready state continuously for a minimum period before acting and prevents triggering on a brief transition during cool-down. | | **Action** | `UpdateControllerVersion` | Updates the controller from `B/4` to `B/5`. | | **Post Action Validations** | `MaxStartupTime` + `CustomDeeAction` | Two validations in order: first confirms the updated runtime starts within the timeout; second registers the completed maintenance event in the ERP system. Both must pass. | Table 2: Scenario 2 Component Design The time-window preconditions and the `Validity` field serve different purposes and complement each other: `Validity` defines the task lifetime, while `AllowedTimeWindow` restricts within which hours of each day the action can run. ### 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_Molding_HolidayUpdate_B5` and a description that captures its purpose (for example, "Update molding controllers from B4 to B5 during the year-end holiday shutdown."). - Set **Is Enabled** to **Disabled** for now. - Set **Validity** to `3` days. Setting the validity to 3 aligns the task lifetime exactly with the 3-day holiday pause (Saturday–Monday), so tasks expire cleanly when the window closes without retrying in the next production period. For **Context**, select **Automation Controller**, enter `MoldingController` as the controller. - Set **Revision** to `B` and **Version** to `4`. This targets all instances currently running `MoldingController B/4` (one task per instance). For the **Detector**, select **Entity State In List** and add `Standby` and `Scheduled Down` to the state list. For the **Action**, select **Update Controller Version** and set **Revision** to `B` and **Version** to `5`. 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 3: Scenario 2 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**, **Sunday**, and **Monday** to match the three days of the holiday pause. Adjust to your actual calendar if needed. **2. Allowed Time Window** - Set the window to `00:00–23:59` to allow processing at any time of day during the holiday pause. Use a narrower range if you want to avoid overnight processing. !!! warning "All times are evaluated in UTC" Adjust both Pre-Conditions to match your planned maintenance window. If your plant operates in a different timezone, convert the window to UTC before entering it here. #### Tab 3 - Acceptance Gates Select :material-plus: and select **Ready Delay**. Set the delay to `120` seconds. A 2-minute stability check is sufficient here because the holiday shutdown is a known, sustained pause rather than a brief operational transition. #### Tab 4 - Post-Action Validations Select :material-plus: twice to add the following validations in this order: **1. Max Startup Time** - Set the timeout to `300` seconds. This waits up to 5 minutes for the updated runtime to start. **2. DEE Action** - Enter `ASA_Scenario2_RegisterMolderUpdateInERP` as the action. This registers the completed update as a maintenance record in the ERP. If the ERP is unreachable or rejects the record, the task is marked `ValidationFailed`. !!! 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 at the start of the holiday window, the system processes each task as follows: 1. **Context** discovers all instances running `MoldingController B/4` and creates one task per instance. `ValidUntil` is set for each task from this moment. 2. On every polling pass, the task checks whether `ValidUntil` has passed. If it has, the task transitions to `State = Expired` and stops being evaluated. 3. Weekday and time-window **Pre-Conditions** are checked. Tasks are skipped if outside the allowed days or hours. 4. `EntityStateInList` checks whether the molder is in `Standby` or `Scheduled Down`. 5. `ReadyDelay` confirms the molder has been in that state for at least 2 minutes. 6. The **Action** updates the controller from `B/4` to `B/5`. 7. `MaxStartupTime` waits up to 5 minutes for the updated runtime to start. 8. `ASA_Scenario2_RegisterMolderUpdateInERP` registers the completed update as a maintenance record in the ERP. If it fails, the task is marked `ValidationFailed`. 9. The task is finalized and notifications are sent. ```mermaid flowchart TD A(["Task created
ValidUntil set"]) --> EXP{"ValidUntil
reached?"} EXP -- Yes --> T_EXP(["Expired
(no retry)"]) EXP -- No --> B{"Sat-Mon
any time?"} B -- No --> S1([SkippedPreConditionFailed]) B -- Yes --> C{"Molder state =
Standby or
Scheduled Down?"} C -- No --> S2([SkippedNotReady]) C -- Yes --> D{"Stable 2+ min?"} D -- No --> S3([SkippedGateFailed]) D -- Yes --> E["UpdateControllerVersion B/4 to B/5"] E --> F{"Running within
300 s?"} F -- No --> FAIL([ValidationFailed]) F -- Yes --> H{"ASA_Scenario2_Register
MolderUpdateInERP passes?"} H -- No --> FAIL H -- Yes --> OK([ProcessedSuccess]) style T_EXP fill:#ffebee,stroke:#c62828,stroke-width:2px style EXP fill:#ffebee,stroke:#c62828,stroke-width:1px style T_EXP fill:#ffebee,stroke:#c62828,stroke-width:2px style EXP fill:#ffebee,stroke:#c62828,stroke-width:1px ``` ## Monitoring Progress During the Window Check **Automation Scheduled Action** tasks regularly while the window is open: - Tasks showing `SkippedNotReady` are waiting for their molder to enter a ready state. This is normal at the start of the window. - Tasks showing `ProcessedSuccess` have completed. Confirm these in the runtime inventory. - Tasks approaching `ValidUntil` without a terminal state need attention (the molder may be stuck in a non-ready state). !!! tip "Set up notifications to track progress without manual monitoring" Configure `NotifySuccessTemplate` and `NotifyFailureTemplate` to send alerts to the maintenance team as each molder is processed. This avoids the need to poll the task list manually during the window. ## Expected Task Outcomes | `LastOutcome` | `State` | Meaning | |---|---|---| | `ProcessedSuccess` | `Processed` | Controller updated and runtime started successfully within the window. | | `IgnoredNoOp` | `Ignored` | Instance was already running `B/5` - no change needed. | | `ActionFailed` | `Failed` | Version update failed. Check manager capacity and controller definition. | | `ValidationFailed` | `Failed` | Update ran but the runtime did not start within 5 minutes, or the ERP registration failed. | | `SkippedNotReady` | (task stays active) | Molder is still in production or in a transitional state. | | `SkippedGateFailed` | *(task stays active) | Molder entered a ready state but has not held it for 2 minutes yet. | | (no outcome) | `Expired` | `ValidUntil` was reached before the task could be processed. | Table 4: Scenario 2 Task Outcomes ## Simulating This Scenario Confirm the Scenario 2 master data is loaded and all molder instances are running on `molding-manager` before starting. This scenario uses `EntityStateInList` for readiness as no file operations are needed. The focus is on enabling the Definition at the right moment and observing the `Validity` lifecycle. ### To Run the Scenario with a Compressed Window For a demo, set `Validity = 0.042` (approximately 1 hour) and `AllowedWeekdays` to all days with `AllowedTimeWindow = ["00:00-23:59"]`. This compresses the 3-day holiday window into a 1-hour demo window, making expiry observable within a single session. ### Standard Simulation Steps 1. Enable the Definition at the agreed window start time. Tasks are created immediately and `ValidUntil` is set for each. 2. Note the `ValidUntil` value on one or two tasks. This is the hard deadline for those tasks. 3. Navigate to `ASA Molder-01` and transition its state to `Standby` or `Scheduled Down`. 4. After 2 minutes (ReadyDelay **Acceptance Gate**), the task processes and transitions to `ProcessedSuccess`. ### To Simulate an Expiry 1. Leave `ASA Molder-02` in `Running` state throughout the simulated window. 2. Watch `LastEvaluatedAt` update on each polling pass while `LastOutcome` remains `SkippedNotReady`. 3. When `ValidUntil` is reached, the task transitions to `State = Expired`. `LastEvaluatedAt` stops updating. 4. Transition `ASA Molder-02` to `Standby` after expiry and confirm that the task does not react. It is permanently terminal. ### To Demonstrate the Validity Misalignment Risk 1. Create a second identical Definition with `Validity = 10` (or 10 hours for the compressed demo). 2. Enable both at the same time. 3. After the compressed window closes, confirm the 3-day/10-hour Definition still has active tasks. 4. If any molder enters a ready state (`Standby` or `Scheduled Down`) after the intended window, the long-validity Definition will still process it. !!! tip "Watching the expiry live" Sort tasks by `ValidUntil` ascending in the Automation Scheduled Action Task list to see which tasks are closest to expiry at any point during the window. ### To Observe the Ignored Outcome Before enabling the Definition, manually update one instance to `MoldingController B/5` directly from the **Automation Controller Instance** record. Enable the Definition and the task for that instance transitions immediately to `IgnoredNoOp` because the target instance is already in the desired state. ### To Reset and Repeat 1. Revert the instance back to `MoldingController B/4` from the **Automation Controller Instance** record. 2. Create a new Definition (the original tasks are in a terminal state and will not re-evaluate). Set a new `Validity` aligned to the next available maintenance slot. ## Handling Expired Tasks If any tasks reach `State = Expired`, the update did not happen for those molders during the holiday window. The Definition is no longer active for those targets. ### Immediate Steps 1. Open each expired task and note the molder name and `LastEvaluatedAt` timestamp. 2. Check the molder state history to understand why it never reached a ready state during the window. 3. Document the expired molders for your maintenance log and escalation process. ### To Re-Run the Update 1. Create a new **Automation Scheduled Action** Definition targeting only the missed molders, using a new validity window aligned to the next available maintenance slot. 2. Confirm with the operations team that the next window is appropriate before enabling. !!! warning "Do not extend Validity on the original Definition" Editing the `Validity` of the original Definition after the window has closed can reactivate tasks at an unintended time. Create a new Definition for the next maintenance slot instead. !!! note "Expired is a terminal state" A task with `State = Expired` does not recover on its own. It stops being evaluated permanently. The only path forward is a new Definition or a new task through an approved process.