// ============================================================================= // DEE Action: ASA_Scenario5_ExecuteStationRecalibration // Scenario: 5 — Custom DEE Action at Every Stage // Stage: Action // // Purpose: // Execute the baking oven recalibration procedure for the target station // by calling the QMS API. This is the only DEE in this scenario that changes // system state — all other DEE actions are read-only checks. // // Unlike built-in actions (UpdateControllerVersion, ChangeAutomationManager), // CustomDeeAction does NOT auto-detect a no-op state. If the oven is already // calibrated, this action should complete successfully — re-calibration is // acceptable and treated as a success rather than a no-op. // // Simulation: // The recalibration outcome for each station is controlled by a per-resource // MES Configuration Entry, toggled independently from the MES UI: // // Path : /Cmf/Tutorials/AutomationScheduleAction/Scenario5/RecalibrationSucceeds/{resourceName} // Type : Boolean // Value: true → recalibration submitted successfully → proceed to post-action validation // false → QMS rejected the request → ActionFailed // // Example entries for the tutorial resources: // /Cmf/Tutorials/AutomationScheduleAction/Scenario5/RecalibrationSucceeds/ASA Baker-01 // /Cmf/Tutorials/AutomationScheduleAction/Scenario5/RecalibrationSucceeds/ASA Baker-02 // // Set to false to demonstrate an ActionFailed outcome independently of the // post-action validation result. // // DEE Contract: // Input - Task : AutomationScheduledActionTask (includes target entity via EntityName) // Output - Result : Boolean (true = recalibration submitted, false / exception = ActionFailed) // // Fail-closed: any exception propagates as ActionFailed on the task. // ============================================================================= using Cmf.Foundation.BusinessOrchestration.Abstractions; using Cmf.Foundation.BusinessOrchestration.ConfigurationManagement.InputObjects; using Cmf.Foundation.Common.Abstractions; using Cmf.Foundation.Configuration.Abstractions; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; namespace Cmf.Custom.Tutorials.AutomationScheduleAction.Actions { public class ASA_Scenario5_ExecuteStationRecalibration : DeeDevBase { public override bool DeeTestCondition(Dictionary Input) { //---Start DEE Condition Code--- return true; //---End DEE Condition Code--- } public override Dictionary DeeActionCode(Dictionary Input) { //---Start DEE Code--- UseReference("", "Cmf.Foundation.BusinessOrchestration.Abstractions"); UseReference("", "Cmf.Foundation.BusinessOrchestration.ConfigurationManagement"); UseReference("", "Cmf.Foundation.BusinessOrchestration.ConfigurationManagement.InputObjects"); IServiceProvider _svcProvider = Input["ServiceProvider"] as IServiceProvider; IEntityFactory _entFactory = _svcProvider.GetService(); //INPUT: Automation Scheduled Action Task var task = Input["Task"] as IAutomationScheduledActionTask; string resourceName = task?.EntityName ?? string.Empty; // In production this is where the QMS API call would go // For simulation, we just read the config value to determine if the recalibration submission is successful const string configParentPath = "/Cmf/Tutorials/AutomationScheduleAction/Scenario5/RecalibrationSucceeds"; string configPath = $"{configParentPath}/{resourceName}"; IConfig recalibConfig = _entFactory.Create(); if (!recalibConfig.TryLoad(configPath)) { recalibConfig.Name = resourceName; recalibConfig.ValueType = "System.Boolean"; recalibConfig.Value = false; recalibConfig.Create(configParentPath); } bool submitted = recalibConfig.GetConfigValue(); //OUTPUT: Boolean - true if task run successfully, otherwise return false to indicate ActionFailed Input["Result"] = submitted; //---End DEE Code--- return Input; } } }