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}%");
}
}
}
}