// ============================================================================= // DEE Action: ASA_Scenario4_ValidatePackerIo // Scenario: 4 — Controller Version Update on Workflow Ready Signal // Stage: Post-Action Validation (second validation, after MaxStartupTime) // // Purpose: // After PackingController A/3 has been updated to A/4 and the instance has // confirmed started (MaxStartupTime passed), verify that the packer's I/O // connections are healthy. This catches cases where the runtime started but // field device communication has not been fully re-established. // If any I/O point is in a faulted or disconnected state, return false so // the task is marked ValidationFailed for operator investigation. // // Simulation: // The I/O health state for each resource is controlled by a per-resource // MES Configuration Entry, toggled independently from the MES UI: // // Path : /Cmf/Tutorials/AutomationScheduleAction/Scenario4/IoHealthy/{resourceName} // Type : Boolean // Value: true → all I/O points connected → ProcessedSuccess // false → I/O fault detected → ValidationFailed // // Example entries for the tutorial resources: // /Cmf/Tutorials/AutomationScheduleAction/Scenario4/IoHealthy/ASA Packer-01 // /Cmf/Tutorials/AutomationScheduleAction/Scenario4/IoHealthy/ASA Packer-02 // // Set to false for a specific packer to demonstrate a ValidationFailed outcome // while other packers complete successfully. // // DEE Contract: // Input - Task : AutomationScheduledActionTask (includes linked resource via EntityName) // Output - Result : Boolean (true = all I/O healthy, false = I/O fault detected) // // Fail-closed: any exception or missing config is treated as false. // ============================================================================= 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_Scenario4_ValidatePackerIo : 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(); var task = Input["Task"] as IAutomationScheduledActionTask; string resourceName = task?.EntityName ?? string.Empty; // In production this is where the driver diagnostic query would go // For simulation, we just read the config value to determine I/O health const string configParentPath = "/Cmf/Tutorials/AutomationScheduleAction/Scenario4/IoHealthy"; string configPath = $"{configParentPath}/{resourceName}"; IConfig ioConfig = _entFactory.Create(); if (!ioConfig.TryLoad(configPath)) { ioConfig.Name = resourceName; ioConfig.ValueType = "System.Boolean"; ioConfig.Value = false; ioConfig.Create(configParentPath); } bool ioHealthy = ioConfig.GetConfigValue(); Input["Result"] = ioHealthy; //---End DEE Code--- return Input; } } }