using System; using System.Threading.Tasks; using CtrEditor.HydraulicSimulator.TSNet; namespace CtrEditor.HydraulicSimulator.TSNet.Examples { /// /// Ejemplo de uso del simulador TSNet en tiempo real /// Demuestra cómo ejecutar simulaciones de 1 segundo consecutivamente /// public class RealTimeSimulationExample { private TSNetRealTimeSimulator _realTimeSimulator; /// /// Ejemplo principal de simulación en tiempo real /// public async Task RunExample() { Console.WriteLine("=== EJEMPLO DE SIMULACIÓN TSNET EN TIEMPO REAL ==="); Console.WriteLine("Simulaciones de 1 segundo consecutivas con cambios dinámicos\n"); // 1. Crear el simulador _realTimeSimulator = new TSNetRealTimeSimulator(); // 2. Suscribirse a eventos _realTimeSimulator.CycleCompleted += OnSimulationCycleCompleted; _realTimeSimulator.SimulationError += OnSimulationError; // 3. Configurar intervalo de simulación (1 segundo) _realTimeSimulator.SimulationInterval = TimeSpan.FromSeconds(1.0); Console.WriteLine("🚀 Iniciando simulación en tiempo real..."); // 4. Iniciar simulación _realTimeSimulator.StartRealTimeSimulation(); // 5. Simular cambios dinámicos durante la simulación await SimulateDynamicChanges(); // 6. Detener simulación Console.WriteLine("\n🛑 Deteniendo simulación..."); _realTimeSimulator.StopRealTimeSimulation(); // 7. Limpiar recursos _realTimeSimulator.Dispose(); Console.WriteLine("✅ Simulación completada"); } /// /// Simula cambios dinámicos en bombas y válvulas durante la simulación /// private async Task SimulateDynamicChanges() { Console.WriteLine("📊 Ejecutando simulación por 10 segundos con cambios dinámicos...\n"); // Esperar 2 segundos iniciales await Task.Delay(2000); // Cambio 1: Reducir velocidad de bomba al 80% Console.WriteLine("🔧 t=2s: Reduciendo velocidad de PUMP1 al 80%"); _realTimeSimulator.UpdatePumpSpeed("PUMP1", 0.8); // Esperar 2 segundos await Task.Delay(2000); // Cambio 2: Cerrar válvula al 50% Console.WriteLine("🔧 t=4s: Cerrando VALVE1 al 50%"); _realTimeSimulator.UpdateValveOpening("VALVE1", 50.0); // Esperar 2 segundos await Task.Delay(2000); // Cambio 3: Acelerar bomba al 120% (si es posible) Console.WriteLine("🔧 t=6s: Acelerando PUMP1 al 100%"); _realTimeSimulator.UpdatePumpSpeed("PUMP1", 1.0); // Esperar 2 segundos await Task.Delay(2000); // Cambio 4: Abrir válvula completamente Console.WriteLine("🔧 t=8s: Abriendo VALVE1 completamente"); _realTimeSimulator.UpdateValveOpening("VALVE1", 100.0); // Esperar 2 segundos finales await Task.Delay(2000); } /// /// Maneja el evento de ciclo completado /// private void OnSimulationCycleCompleted(object sender, SimulationCycleCompletedEventArgs e) { Console.WriteLine($"⏱️ t={e.SimulationTime:F1}s | Ciclo: {e.CycleDuration.TotalMilliseconds:F0}ms"); // Mostrar estados de tanques foreach (var tank in e.TankStates) { Console.WriteLine($" 🚰 {tank.Key}: Nivel={tank.Value.CurrentLevel:F2}m, Volumen={tank.Value.CurrentVolume:F1}L"); } // Mostrar estados de bombas foreach (var pump in e.PumpStates) { var status = pump.Value.IsRunning ? "ON" : "OFF"; Console.WriteLine($" ⚙️ {pump.Key}: {status}, Velocidad={pump.Value.SpeedRatio:F1}, Flujo={pump.Value.CurrentFlow:F2}L/s"); } // Mostrar estados de válvulas foreach (var valve in e.ValveStates) { var status = valve.Value.IsOpen ? "OPEN" : "CLOSED"; Console.WriteLine($" 🚪 {valve.Key}: {status}, Apertura={valve.Value.OpeningPercentage:F1}%, Flujo={valve.Value.CurrentFlow:F2}L/s"); } Console.WriteLine(); } /// /// Maneja errores de simulación /// private void OnSimulationError(object sender, SimulationErrorEventArgs e) { Console.WriteLine($"❌ Error de simulación: {e.Message}"); } } /// /// Ejemplo específico para integración con MainViewModel /// public class MainViewModelIntegrationExample { private TSNetRealTimeSimulator _simulator; /// /// Integra el simulador con MainViewModel para actualizar objetos CtrEditor /// public void IntegrateWithMainViewModel() { _simulator = new TSNetRealTimeSimulator(); // Suscribirse a eventos para actualizar objetos CtrEditor _simulator.CycleCompleted += UpdateCtrEditorObjects; Console.WriteLine("🔗 Simulador TSNet integrado con MainViewModel"); Console.WriteLine("📊 Los objetos CtrEditor se actualizarán cada segundo"); } /// /// Actualiza los objetos CtrEditor con los resultados de TSNet /// private void UpdateCtrEditorObjects(object sender, SimulationCycleCompletedEventArgs e) { // Actualizar tanques CtrEditor foreach (var tankState in e.TankStates) { // Buscar el objeto osHydTank correspondiente // var tank = FindTankById(tankState.Key); // if (tank != null) // { // tank.CurrentLevel = tankState.Value.CurrentLevel; // tank.CurrentVolume = tankState.Value.CurrentVolume; // tank.CurrentPressure = tankState.Value.CurrentPressure; // tank.NotifyPropertyChanged(); // Actualizar UI // } Console.WriteLine($"🔄 Actualizando tanque {tankState.Key}: Nivel={tankState.Value.CurrentLevel:F2}m"); } // Actualizar bombas CtrEditor foreach (var pumpState in e.PumpStates) { // Buscar el objeto osHydPump correspondiente // var pump = FindPumpById(pumpState.Key); // if (pump != null) // { // pump.CurrentFlow = pumpState.Value.CurrentFlow; // pump.CurrentHead = pumpState.Value.CurrentHead; // pump.IsRunning = pumpState.Value.IsRunning; // pump.NotifyPropertyChanged(); // Actualizar UI // } Console.WriteLine($"🔄 Actualizando bomba {pumpState.Key}: Flujo={pumpState.Value.CurrentFlow:F2}L/s"); } // Actualizar tuberías (pipes) si es necesario // Los resultados de flujo en tuberías también están disponibles en TSNet } /// /// Permite control manual de bombas durante la simulación /// public void ControlPumpFromUI(string pumpId, double speedRatio) { if (_simulator != null && _simulator.IsRunning) { _simulator.UpdatePumpSpeed(pumpId, speedRatio); Console.WriteLine($"🎛️ Control manual: Bomba {pumpId} velocidad {speedRatio:F1}"); } } /// /// Permite control manual de válvulas durante la simulación /// public void ControlValveFromUI(string valveId, double openingPercentage) { if (_simulator != null && _simulator.IsRunning) { _simulator.UpdateValveOpening(valveId, openingPercentage); Console.WriteLine($"🎛️ Control manual: Válvula {valveId} apertura {openingPercentage:F1}%"); } } } }