215 lines
8.6 KiB
C#
215 lines
8.6 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using CtrEditor.HydraulicSimulator.TSNet;
|
|
|
|
namespace CtrEditor.HydraulicSimulator.TSNet.Examples
|
|
{
|
|
/// <summary>
|
|
/// Ejemplo de uso del simulador TSNet en tiempo real
|
|
/// Demuestra cómo ejecutar simulaciones de 1 segundo consecutivamente
|
|
/// </summary>
|
|
public class RealTimeSimulationExample
|
|
{
|
|
private TSNetRealTimeSimulator _realTimeSimulator;
|
|
|
|
/// <summary>
|
|
/// Ejemplo principal de simulación en tiempo real
|
|
/// </summary>
|
|
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");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Simula cambios dinámicos en bombas y válvulas durante la simulación
|
|
/// </summary>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Maneja el evento de ciclo completado
|
|
/// </summary>
|
|
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();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Maneja errores de simulación
|
|
/// </summary>
|
|
private void OnSimulationError(object sender, SimulationErrorEventArgs e)
|
|
{
|
|
Console.WriteLine($"❌ Error de simulación: {e.Message}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ejemplo específico para integración con MainViewModel
|
|
/// </summary>
|
|
public class MainViewModelIntegrationExample
|
|
{
|
|
private TSNetRealTimeSimulator _simulator;
|
|
|
|
/// <summary>
|
|
/// Integra el simulador con MainViewModel para actualizar objetos CtrEditor
|
|
/// </summary>
|
|
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");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Actualiza los objetos CtrEditor con los resultados de TSNet
|
|
/// </summary>
|
|
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
|
|
}
|
|
|
|
/// <summary>
|
|
/// Permite control manual de bombas durante la simulación
|
|
/// </summary>
|
|
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}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Permite control manual de válvulas durante la simulación
|
|
/// </summary>
|
|
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}%");
|
|
}
|
|
}
|
|
}
|
|
} |