12 KiB
TSNet Phase 2 Integration Architecture
Overview
Este documento describe la arquitectura completa del sistema TSNet Phase 2 integrado con CtrEditor, que proporciona simulación hidráulica unificada para tanques, bombas y tuberías.
Arquitectura del Sistema
Principios de Diseño
- Separación de Responsabilidades: Los componentes UI se enfocan en visualización, TSNet maneja todos los cálculos hidráulicos
- Configuración Inmutable: La configuración se captura al inicio de simulación y permanece congelada durante la ejecución
- Thread Safety: Diseñado para uso seguro en entornos multi-threaded
- Trazabilidad: Logging comprensivo para debugging y monitoreo
Componentes Principales
1. Adaptadores TSNet
Los adaptadores actúan como puentes entre los componentes UI de CtrEditor y el motor de simulación TSNet.
TSNetTankAdapter
// Ubicación: HydraulicSimulator/TSNet/Components/TSNetTankAdapter.cs
public class TSNetTankAdapter
{
public TankConfiguration Configuration { get; private set; }
public TSNetTankResults Results { get; private set; }
public string TankId => tankId;
public void CaptureConfigurationForSimulation()
public void ResetCalculatedValues()
}
Responsabilidades:
- Capturar configuración de tanques al inicio de simulación
- Almacenar resultados calculados por TSNet
- Proporcionar ID único para identificación en TSNet
TSNetPumpAdapter
// Ubicación: HydraulicSimulator/TSNet/Components/TSNetPumpAdapter.cs
public class TSNetPumpAdapter
{
public PumpConfiguration Configuration { get; private set; }
public TSNetPumpResults Results { get; private set; }
public string NodeId => nodeId;
public void CaptureConfigurationForSimulation()
public void ResetCalculatedValues()
}
Responsabilidades:
- Capturar configuración de bombas (head, flujo máximo, velocidad)
- Almacenar resultados operacionales de TSNet
- Gestionar estado operacional de la bomba
TSNetPipeAdapter
// Ubicación: HydraulicSimulator/TSNet/Components/TSNetPipeAdapter.cs
public class TSNetPipeAdapter
{
public PipeConfiguration Configuration { get; private set; }
public TSNetPipeResults Results { get; private set; }
public string PipeId => pipeId;
public void CaptureConfigurationForSimulation()
public void ResetCalculatedValues()
}
Responsabilidades:
- Capturar configuración de tuberías (longitud, diámetro, rugosidad)
- Almacenar resultados de flujo y pérdidas de presión
- Gestionar propiedades del fluido
2. Clases de Resultados
TSNetTankResults
public class TSNetTankResults
{
// Resultados hidráulicos calculados
public double CalculatedLevelM { get; set; }
public double CalculatedVolumeL { get; set; }
public double CalculatedPressureBar { get; set; }
public double InletFlowM3s { get; set; }
public double OutletFlowM3s { get; set; }
public double NetFlowM3s { get; set; }
// Propiedades del fluido
public int CalculatedFluidType { get; set; }
public string CalculatedFluidDescription { get; set; }
public double CalculatedFluidTemperature { get; set; }
// Estado
public bool IsOverflowing { get; set; }
public bool IsEmpty { get; set; }
public string Status { get; set; }
public DateTime Timestamp { get; set; }
}
TSNetPumpResults
public class TSNetPumpResults
{
// Resultados operacionales
public double CalculatedFlowM3s { get; set; }
public double CalculatedFlowLMin { get; set; }
public double CalculatedHeadM { get; set; }
public double InletPressureBar { get; set; }
public double OutletPressureBar { get; set; }
public double PressureDifferentialBar { get; set; }
public double CalculatedEfficiency { get; set; }
public double PowerConsumptionKW { get; set; }
// Estado operacional
public bool IsOperating { get; set; }
public bool IsCavitating { get; set; }
public string OperationalStatus { get; set; }
public DateTime Timestamp { get; set; }
}
TSNetPipeResults
public class TSNetPipeResults
{
// Resultados de flujo
public double CalculatedFlowM3s { get; set; }
public double CalculatedFlowLMin { get; set; }
public double FlowVelocityMs { get; set; }
public string FlowDirection { get; set; }
// Propiedades hidráulicas
public double PressureDropBar { get; set; }
public double ReynoldsNumber { get; set; }
public string FlowRegime { get; set; }
public double FrictionFactor { get; set; }
public double HeadLossM { get; set; }
// Análisis del flujo
public bool IsFlowActive { get; set; }
public bool IsFlowReversed { get; set; }
public string FlowStatus { get; set; }
public DateTime Timestamp { get; set; }
}
Integración con Componentes UI
Patrón de Integración
Cada componente hidráulico (osHydTank, osHydPump, osHydPipe) sigue el mismo patrón de integración:
1. Inicialización del Adapter
// En el constructor del componente
public osHydTank()
{
// ... inicialización base ...
// Inicializar TSNet adapter
TSNetAdapter = new TSNetTankAdapter(this);
// ... resto de inicialización ...
}
2. Captura de Configuración
// En ucLoaded - cuando el componente se carga completamente
private void ucLoaded(object sender, RoutedEventArgs e)
{
// Capturar configuración para TSNet
TSNetAdapter?.CaptureConfigurationForSimulation();
// Configurar propiedades específicas del componente
// ...
}
3. Actualización de Control (Solo Visual)
// UpdateControl ahora SOLO maneja actualizaciones visuales
public override void UpdateControl(double TimeNow)
{
if (!IsLoaded) return;
// SOLO actualizaciones visuales - NO cálculos hidráulicos
UpdateVisualState();
UpdateColorIndication();
UpdateAnimations();
// Los cálculos hidráulicos los hace TSNet
}
4. Aplicación de Resultados TSNet
// ApplyHydraulicResults aplica EXCLUSIVAMENTE datos de TSNet
protected override void ApplyHydraulicResults(
Dictionary<string, double> flows,
Dictionary<string, double> pressures)
{
try
{
if (TSNetAdapter?.Results != null)
{
// Aplicar resultados de TSNet al componente
CurrentFlow = TSNetAdapter.Results.CalculatedFlowM3s;
CurrentPressure = TSNetAdapter.Results.CalculatedPressureBar;
// Actualizar propiedades visuales basadas en TSNet
UpdateVisualPropertiesFromTSNet();
// Log para debugging
LogTSNetApplication();
}
}
catch (Exception ex)
{
dataDebug.AddDataToDebugger($"Error applying TSNet results: {ex.Message}");
}
}
Flujo de Datos
1. Inicio de Simulación
Usuario inicia simulación
↓
Componentes capturan configuración
↓
TSNet recibe configuración inmutable
↓
Simulación comienza
2. Durante la Simulación
TSNet calcula resultados hidráulicos
↓
Resultados se almacenan en Results classes
↓
ApplyHydraulicResults actualiza componentes UI
↓
UpdateControl actualiza solo aspectos visuales
3. Fin de Simulación
Simulación termina
↓
ResetCalculatedValues limpia resultados
↓
Componentes listos para nueva simulación
Eliminación de Cálculos Duplicados
Antes de TSNet Phase 2
Cada componente tenía sus propios cálculos hidráulicos:
// ELIMINADO - ya no se hace
private void CalculateInternalPressure()
{
// Cálculos internos duplicados
}
private void UpdateInternalFlow()
{
// Lógica hidráulica local
}
Después de TSNet Phase 2
Todos los cálculos hidráulicos los hace TSNet:
// NUEVO - solo aplicar resultados TSNet
private void ApplyTSNetResults()
{
if (TSNetAdapter?.Results != null)
{
// Usar valores calculados por TSNet
CurrentPressure = TSNetAdapter.Results.CalculatedPressureBar;
CurrentFlow = TSNetAdapter.Results.CalculatedFlowM3s;
}
}
Beneficios de la Arquitectura
1. Consistencia
- Todos los cálculos hidráulicos provienen de una sola fuente (TSNet)
- No hay discrepancias entre componentes
- Resultados coherentes en toda la red
2. Mantenibilidad
- Lógica hidráulica centralizada en TSNet
- Componentes UI enfocados en visualización
- Fácil debugging y modificación
3. Escalabilidad
- Nuevos componentes hidráulicos siguen el mismo patrón
- TSNet puede manejar redes complejas
- Performance optimizada
4. Trazabilidad
- Logging comprensivo en cada paso
- Estados claramente definidos
- Fácil identificación de problemas
Debugging y Monitoreo
Logging Integrado
Cada adapter incluye logging detallado:
private void LogTSNetApplication()
{
try
{
dataDebug.AddDataToDebugger($"Tank {TSNetAdapter.TankId} - TSNet Results Applied:");
dataDebug.AddDataToDebugger($" Pressure: {TSNetAdapter.Results.CalculatedPressureBar} bar");
dataDebug.AddDataToDebugger($" Level: {TSNetAdapter.Results.CalculatedLevelM} m");
dataDebug.AddDataToDebugger($" Volume: {TSNetAdapter.Results.CalculatedVolumeL} L");
dataDebug.AddDataToDebugger($" Updated: {TSNetAdapter.Results.Timestamp}");
}
catch (Exception ex)
{
dataDebug.AddDataToDebugger($"Error logging TSNet application: {ex.Message}");
}
}
Estados de Validación
Los adapters incluyen validación de estado:
public bool IsConfigurationValid()
{
return Configuration != null &&
!string.IsNullOrEmpty(TankId) &&
Configuration.MinLevelM >= 0 &&
Configuration.MaxLevelM > Configuration.MinLevelM;
}
Extensibilidad
Nuevos Componentes Hidráulicos
Para agregar un nuevo componente hidráulico:
- Crear Adapter Class:
public class TSNetNewComponentAdapter
{
public NewComponentConfiguration Configuration { get; private set; }
public TSNetNewComponentResults Results { get; private set; }
public void CaptureConfigurationForSimulation() { }
public void ResetCalculatedValues() { }
}
- Crear Results Class:
public class TSNetNewComponentResults
{
public DateTime Timestamp { get; set; }
// ... propiedades específicas del componente
}
- Integrar en Componente UI:
public class osNewComponent : osBase
{
public TSNetNewComponentAdapter? TSNetAdapter { get; private set; }
public osNewComponent()
{
TSNetAdapter = new TSNetNewComponentAdapter(this);
}
// Seguir el patrón estándar de integración
}
Archivos de Configuración
Estructura del Proyecto
HydraulicSimulator/
├── TSNet/
│ ├── Components/
│ │ ├── TSNetTankAdapter.cs
│ │ ├── TSNetPumpAdapter.cs
│ │ ├── TSNetPipeAdapter.cs
│ │ └── TSNetResults.cs
│ ├── TSNetSimulationManager.cs
│ └── TSNetINPGenerator.cs
├── Tests/
│ └── TSNetIntegrationTest.cs
└── HydraulicSimulationManager.cs
ObjetosSim/
├── HydraulicComponents/
│ ├── osHydTank.cs # Integrado con TSNetTankAdapter
│ ├── osHydPump.cs # Integrado con TSNetPumpAdapter
│ └── osHydPipe.cs # Integrado con TSNetPipeAdapter
└── osBase.cs
Consideraciones de Performance
Optimizaciones Implementadas
- Configuración Inmutable: Se captura una sola vez al inicio
- Lazy Loading: Los adapters se inicializan solo cuando se necesitan
- Caching: Los resultados se cachean hasta la siguiente actualización
- Thread Safety: Locks mínimos para máximo rendimiento
Métricas de Performance
- Tiempo de inicio: Reducido al eliminar cálculos duplicados
- Memory footprint: Optimizado con objetos compartidos
- CPU usage: Menor al centralizar cálculos en TSNet
Conclusión
La integración TSNet Phase 2 proporciona una arquitectura robusta, escalable y mantenible para simulación hidráulica en CtrEditor. La separación clara entre cálculo (TSNet) y visualización (componentes UI) mejora tanto la consistencia como la performance del sistema.
La implementación sigue principios de ingeniería de software sólidos y proporciona una base excelente para futuras expansiones del sistema hidráulico.