From 8e6d4570477f97fa10b180d9f69208ed61854aef Mon Sep 17 00:00:00 2001 From: Miguel Date: Sat, 6 Sep 2025 00:38:07 +0200 Subject: [PATCH] Refactor hydraulic components: Updated osHydPipe and osHydPump to improve code clarity by changing region comments to regular comments. Enhanced osHydTank with a new OnMove method and improved initialization in ucHydTank.xaml. Updated StateSerializer to include default values during serialization. --- CtrEditor.csproj | 1 - Documentation/HydraulicComponents.md | 374 ++++++++++++++++ FilterDebugTest.cs | 43 -- .../Examples/SimpleHydraulicSystemExample.cs | 179 -------- .../HydraulicComponents/osHydDischargeTank.cs | 408 ------------------ ObjetosSim/HydraulicComponents/osHydPipe.cs | 36 +- ObjetosSim/HydraulicComponents/osHydPump.cs | 27 +- ObjetosSim/HydraulicComponents/osHydTank.cs | 34 +- .../ucHydDischargeTank.xaml | 101 ----- .../ucHydDischargeTank.xaml.cs | 70 --- ObjetosSim/HydraulicComponents/ucHydTank.xaml | 30 +- Serialization/StateSerializer.cs | 1 + test_osBaseItemsSource.cs | 39 -- 13 files changed, 441 insertions(+), 902 deletions(-) create mode 100644 Documentation/HydraulicComponents.md delete mode 100644 FilterDebugTest.cs delete mode 100644 HydraulicSimulator/Examples/SimpleHydraulicSystemExample.cs delete mode 100644 ObjetosSim/HydraulicComponents/osHydDischargeTank.cs delete mode 100644 ObjetosSim/HydraulicComponents/ucHydDischargeTank.xaml delete mode 100644 ObjetosSim/HydraulicComponents/ucHydDischargeTank.xaml.cs delete mode 100644 test_osBaseItemsSource.cs diff --git a/CtrEditor.csproj b/CtrEditor.csproj index 3608e46..c2c428d 100644 --- a/CtrEditor.csproj +++ b/CtrEditor.csproj @@ -193,7 +193,6 @@ - diff --git a/Documentation/HydraulicComponents.md b/Documentation/HydraulicComponents.md new file mode 100644 index 0000000..9b21c8c --- /dev/null +++ b/Documentation/HydraulicComponents.md @@ -0,0 +1,374 @@ +# Sistema de Componentes Hidráulicos - CtrEditor + +## 📋 Resumen del Sistema + +Este documento describe todos los componentes necesarios para implementar un sistema hidráulico completo en CtrEditor. El sistema está diseñado con una arquitectura modular que permite simular circuitos hidráulicos industriales complejos. + +--- + +## 🎯 Componentes Existentes + +### ✅ **Tanque Hidráulico** - `osHydTank` +- **Archivo**: `osHydTank.cs` / `ucHydTank.xaml` +- **Descripción**: Tanque hidráulico con gestión dinámica de nivel y presión configurable +- **Tipos**: Suction, Intermediate, Storage, Process +- **Características**: + - Múltiples tipos de tanque via enum `HydraulicTankType` + - Presión fija o variable (`IsFixedPressure`) + - Gestión completa de flujos entrada/salida + - Cálculos dinámicos de nivel y volumen + - Propiedades visuales para UI (colores, indicadores) + - Conexiones configurables de entrada y salida + +### ✅ **Tubería Hidráulica** - `osHydPipe` +- **Archivo**: `osHydPipe.cs` / `ucHydPipe.xaml` +- **Descripción**: Tubería para transporte de fluido hidráulico +- **Características**: + - Cálculo de pérdidas de carga por fricción + - Diferentes materiales y rugosidades + - Diámetros configurables + - Longitud variable + - Resistencia hidráulica calculada + +### ✅ **Bomba Hidráulica** - `osHydPump` +- **Archivo**: `osHydPump.cs` / `ucHydPump.xaml` +- **Descripción**: Bomba para generar presión y caudal en el sistema +- **Tipos**: Centrifugal, Positive Displacement, Variable Displacement +- **Características**: + - Curvas características configurables + - Control de velocidad variable + - Eficiencia energética + - Protección contra cavitación + - Control PID integrado + +--- + +## 🔧 Componentes de Control (Por Implementar) + +### **Válvulas** - `osHydValve` +- **Archivo**: `osHydValve.cs` / `ucHydValve.xaml` +- **Descripción**: Válvula general configurable para control de flujo +- **Tipos**: + - `Ball` - Válvula de bola (on/off) + - `Gate` - Válvula de compuerta + - `Globe` - Válvula de globo + - `Check` - Válvula de retención + - `Relief` - Válvula de alivio + - `Throttle` - Válvula de estrangulación +- **Estados**: `Open`, `Closed`, `Partial` +- **Propiedades**: + - Coeficiente de flujo (Cv) + - Pérdida de presión + - Posición del actuador + - Tiempo de operación + +### **Actuadores Hidráulicos** - `osHydActuator` +- **Archivo**: `osHydActuator.cs` / `ucHydActuator.xaml` +- **Descripción**: Cilindros y actuadores hidráulicos +- **Tipos**: + - `SingleAction` - Cilindro de simple efecto + - `DoubleAction` - Cilindro de doble efecto + - `Rotary` - Actuador rotativo +- **Propiedades**: + - Diámetro del pistón + - Carrera (stroke) + - Fuerza desarrollada + - Velocidad de actuación + - Posición actual + +--- + +## 📊 Instrumentación (Por Implementar) + +### **Sensor de Presión** - `osHydPressureSensor` +- **Archivo**: `osHydPressureSensor.cs` / `ucHydPressureSensor.xaml` +- **Descripción**: Medición de presión en el sistema +- **Propiedades**: + - Rango de medición (0-1000 bar) + - Precisión (±0.1%) + - Tiempo de respuesta + - Señal de salida (4-20mA, 0-10V) + - Calibración automática + +### **Sensor de Caudal** - `osHydFlowSensor` +- **Archivo**: `osHydFlowSensor.cs` / `ucHydFlowSensor.xaml` +- **Descripción**: Medición de caudal volumétrico +- **Tipos**: Electromagnetic, Turbine, Vortex, Ultrasonic +- **Propiedades**: + - Rango de caudal (L/min) + - Pérdida de presión + - Precisión de medición + - Compensación de temperatura + +### **Sensor de Nivel** - `osHydLevelSensor` +- **Archivo**: `osHydLevelSensor.cs` / `ucHydLevelSensor.xaml` +- **Descripción**: Medición de nivel en tanques +- **Tipos**: Ultrasonic, Radar, Capacitive, Float +- **Propiedades**: + - Altura de medición + - Zona muerta + - Material del tanque + - Constante dieléctrica del fluido + +### **Sensor de Temperatura** - `osHydTemperatureSensor` +- **Archivo**: `osHydTemperatureSensor.cs` / `ucHydTemperatureSensor.xaml` +- **Descripción**: Medición de temperatura del fluido +- **Tipos**: Thermocouple, RTD, Thermistor +- **Propiedades**: + - Rango de temperatura (-40°C a +200°C) + - Tiempo de respuesta térmica + - Exactitud (±0.1°C) + - Inmersión requerida + +--- + +## 🔀 Conexiones y Distribución (Por Implementar) + +### **Conexión en T** - `osHydTee` +- **Archivo**: `osHydTee.cs` / `ucHydTee.xaml` +- **Descripción**: Conexión de tres vías para dividir flujo +- **Propiedades**: + - Diámetro de entrada + - Diámetros de salida + - Coeficiente de pérdida + - Material de construcción + +### **Codo 90°** - `osHydElbow` +- **Archivo**: `osHydElbow.cs` / `ucHydElbow.xaml` +- **Descripción**: Cambio de dirección a 90 grados +- **Propiedades**: + - Radio de curvatura + - Ángulo (45°, 90°, custom) + - Factor de pérdida K + - Diámetro interno + +### **Conexión Cruzada** - `osHydCross` +- **Archivo**: `osHydCross.cs` / `ucHydCross.xaml` +- **Descripción**: Conexión de cuatro vías +- **Propiedades**: + - Configuración de flujos + - Pérdidas por turbulencia + - Diámetros de conexión + +### **Reductor de Diámetro** - `osHydReducer` +- **Archivo**: `osHydReducer.cs` / `ucHydReducer.xaml` +- **Descripción**: Cambio gradual de diámetro de tubería +- **Tipos**: Concentric, Eccentric +- **Propiedades**: + - Diámetro de entrada + - Diámetro de salida + - Ángulo de reducción + - Pérdida por expansión/contracción + +### **Distribuidor Multiple** - `osHydManifold` +- **Archivo**: `osHydManifold.cs` / `ucHydManifold.xaml` +- **Descripción**: Distribuidor de múltiples salidas +- **Propiedades**: + - Número de salidas (2-12) + - Distribución de caudal + - Válvulas integradas opcionales + - Presión de entrada común + +--- + +## 🎛️ Control Avanzado (Por Implementar) + +### **Regulador de Presión** - `osHydPressureRegulator` +- **Archivo**: `osHydPressureRegulator.cs` / `ucHydPressureRegulator.xaml` +- **Descripción**: Control automático de presión +- **Propiedades**: + - Presión de consigna (setpoint) + - Banda proporcional + - Control PID integrado + - Rango de regulación + - Precisión de control + +### **Regulador de Caudal** - `osHydFlowRegulator` +- **Archivo**: `osHydFlowRegulator.cs` / `ucHydFlowRegulator.xaml` +- **Descripción**: Control automático de caudal +- **Propiedades**: + - Caudal de consigna + - Compensación de presión + - Tiempo de respuesta + - Estabilidad de flujo + +### **Válvula de Alivio** - `osHydPressureRelief` +- **Archivo**: `osHydPressureRelief.cs` / `ucHydPressureRelief.xaml` +- **Descripción**: Protección contra sobrepresión +- **Propiedades**: + - Presión de apertura + - Presión de cierre + - Capacidad de descarga + - Tipo de pilotaje + +--- + +## 🌡️ Gestión Térmica (Por Implementar) + +### **Filtro Hidráulico** - `osHydFilter` +- **Archivo**: `osHydFilter.cs` / `ucHydFilter.xaml` +- **Descripción**: Filtración de partículas y contaminantes +- **Tipos**: + - `Suction` - Filtro de aspiración + - `Return` - Filtro de retorno + - `Pressure` - Filtro de presión + - `Bypass` - Filtro de bypass +- **Propiedades**: + - Grado de filtración (micrones) + - Capacidad de retención + - Pérdida de presión + - Indicador de saturación + +### **Enfriador** - `osHydCooler` +- **Archivo**: `osHydCooler.cs` / `ucHydCooler.xaml` +- **Descripción**: Enfriamiento del fluido hidráulico +- **Tipos**: Air-cooled, Water-cooled +- **Propiedades**: + - Capacidad de enfriamiento (kW) + - Temperatura de entrada/salida + - Caudal de fluido refrigerante + - Eficiencia térmica + +### **Calentador** - `osHydHeater` +- **Archivo**: `osHydHeater.cs` / `ucHydHeater.xaml` +- **Descripción**: Calentamiento del fluido hidráulico +- **Propiedades**: + - Potencia de calentamiento (kW) + - Temperatura objetivo + - Control de temperatura + - Protección contra sobrecalentamiento + +### **Intercambiador de Calor** - `osHydHeatExchanger` +- **Archivo**: `osHydHeatExchanger.cs` / `ucHydHeatExchanger.xaml` +- **Descripción**: Intercambio térmico entre fluidos +- **Tipos**: Plate, Shell-and-tube, Coaxial +- **Propiedades**: + - Coeficiente de transferencia térmica + - Área de intercambio + - Configuración de flujos + - Eficiencia térmica + +--- + +## 🔄 Componentes Especializados (Por Implementar) + +### **Acumulador Hidráulico** - `osHydAccumulator` +- **Archivo**: `osHydAccumulator.cs` / `ucHydAccumulator.xaml` +- **Descripción**: Almacenamiento de energía hidráulica +- **Tipos**: + - `Bladder` - Membrana elastomérica + - `Piston` - Pistón separador + - `Diaphragm` - Diafragma metálico +- **Propiedades**: + - Volumen total + - Presión de precarga + - Volumen útil + - Tiempo de descarga + +### **Motor Hidráulico** - `osHydMotor` +- **Archivo**: `osHydMotor.cs` / `ucHydMotor.xaml` +- **Descripción**: Conversión de energía hidráulica a mecánica rotativa +- **Tipos**: + - `Gear` - Motor de engranajes + - `Vane` - Motor de paletas + - `Piston` - Motor de pistones + - `Radial` - Motor radial +- **Propiedades**: + - Cilindrada (cm³/rev) + - Velocidad nominal (rpm) + - Par motor (Nm) + - Eficiencia volumétrica/mecánica + +--- + +## 📋 Plan de Implementación + +### **Fase 1 - Componentes Básicos** ⭐⭐⭐ +1. `osHydValve` (Ball, Check, Relief) +2. `osHydPressureSensor` +3. `osHydFlowSensor` +4. `osHydTee` + +### **Fase 2 - Control Intermedio** ⭐⭐ +5. `osHydActuator` +6. `osHydPressureRegulator` +7. `osHydFilter` +8. `osHydManifold` + +### **Fase 3 - Componentes Avanzados** ⭐ +9. `osHydAccumulator` +10. `osHydMotor` +11. `osHydCooler` +12. `osHydHeatExchanger` + +### **Fase 4 - Instrumentación Completa** +13. `osHydLevelSensor` +14. `osHydTemperatureSensor` +15. `osHydFlowRegulator` +16. Componentes de conexión restantes + +--- + +## 💡 Arquitectura de Interfaces + +### **Interfaces Base** +```csharp +// Control de flujo +public interface IHydraulicFlowController +{ + double FlowCoefficient { get; set; } + double PressureDrop { get; } + ValveState CurrentState { get; set; } +} + +// Actuadores +public interface IHydraulicActuator +{ + double Force { get; } + double Stroke { get; set; } + double Velocity { get; } + ActuatorType Type { get; } +} + +// Sensores +public interface IHydraulicSensor +{ + double MeasuredValue { get; } + string Units { get; } + bool IsCalibrated { get; set; } + double Accuracy { get; } +} + +// Componentes térmicos +public interface IHydraulicThermalComponent +{ + double ThermalCapacity { get; } + double HeatTransferCoefficient { get; } + double OperatingTemperature { get; set; } +} +``` + +--- + +## 🎯 Objetivos del Sistema + +- **Modularidad**: Cada componente es independiente y reutilizable +- **Realismo**: Cálculos basados en principios de ingeniería hidráulica +- **Flexibilidad**: Configuración adaptable a diferentes aplicaciones +- **Integración**: Compatible con el sistema de simulación existente +- **Escalabilidad**: Fácil adición de nuevos componentes +- **Documentación**: Cada componente bien documentado y ejemplificado + +--- + +## 📚 Referencias Técnicas + +- ISO 1219-1: Símbolos gráficos para esquemas de circuitos hidráulicos +- ISO 4413: Transmisiones hidráulicas - Reglas generales y requisitos de seguridad +- NFPA T3.5.17: Hidráulica industrial - Estándares de filtración +- API 610: Bombas centrífugas para servicios de refinería petroquímica + +--- + +*Documento generado automáticamente - CtrEditor v2024* +*Última actualización: Septiembre 2025* diff --git a/FilterDebugTest.cs b/FilterDebugTest.cs deleted file mode 100644 index 02d5c8a..0000000 --- a/FilterDebugTest.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Linq; -using CtrEditor.ObjetosSim.HydraulicComponents; - -namespace CtrEditor.Test -{ - class FilterDebugTest - { - static void TestHydraulicComponentDetection() - { - // Test hydraulic component detection logic like in osVisFilter - var tankType = typeof(osHydTank); - var pipeType = typeof(osHydPipe); - - Console.WriteLine("=== Tank Type Analysis ==="); - Console.WriteLine($"Tank Type: {tankType.FullName}"); - Console.WriteLine($"Tank Namespace: {tankType.Namespace}"); - Console.WriteLine($"Has HydraulicComponents in namespace: {tankType.Namespace?.Contains("HydraulicComponents")}"); - Console.WriteLine($"Tank Interfaces: {string.Join(", ", tankType.GetInterfaces().Select(i => i.Name))}"); - Console.WriteLine($"Has Hydraulic interface: {tankType.GetInterfaces().Any(i => i.Name.Contains("Hydraulic"))}"); - - Console.WriteLine("\n=== Pipe Type Analysis ==="); - Console.WriteLine($"Pipe Type: {pipeType.FullName}"); - Console.WriteLine($"Pipe Namespace: {pipeType.Namespace}"); - Console.WriteLine($"Has HydraulicComponents in namespace: {pipeType.Namespace?.Contains("HydraulicComponents")}"); - Console.WriteLine($"Pipe Interfaces: {string.Join(", ", pipeType.GetInterfaces().Select(i => i.Name))}"); - Console.WriteLine($"Has Hydraulic interface: {pipeType.GetInterfaces().Any(i => i.Name.Contains("Hydraulic"))}"); - - // Test the exact logic from IsHydraulicComponentType - Console.WriteLine("\n=== IsHydraulicComponentType Logic Test ==="); - bool tankIsHydraulic = tankType.Namespace != null && - (tankType.Namespace.Contains("HydraulicComponents") || - tankType.GetInterfaces().Any(i => i.Name.Contains("Hydraulic"))); - - bool pipeIsHydraulic = pipeType.Namespace != null && - (pipeType.Namespace.Contains("HydraulicComponents") || - pipeType.GetInterfaces().Any(i => i.Name.Contains("Hydraulic"))); - - Console.WriteLine($"Tank IsHydraulicComponentType: {tankIsHydraulic}"); - Console.WriteLine($"Pipe IsHydraulicComponentType: {pipeIsHydraulic}"); - } - } -} diff --git a/HydraulicSimulator/Examples/SimpleHydraulicSystemExample.cs b/HydraulicSimulator/Examples/SimpleHydraulicSystemExample.cs deleted file mode 100644 index ca17bb1..0000000 --- a/HydraulicSimulator/Examples/SimpleHydraulicSystemExample.cs +++ /dev/null @@ -1,179 +0,0 @@ -using System; -using System.Collections.Generic; -using HydraulicSimulator.Models; -using CtrEditor.HydraulicSimulator; -using CtrEditor.ObjetosSim.HydraulicComponents; - -namespace CtrEditor.HydraulicSimulator.Examples -{ - /// - /// Ejemplo de uso de los componentes hidráulicos según la documentación - /// Muestra cómo crear una red simple: Bomba -> Tubería -> Tanque de Descarga - /// - public class SimpleHydraulicSystemExample - { - /// - /// Crea un sistema hidráulico simple con bomba, tubería y tanque - /// - public static void RunExample() - { - Console.WriteLine("🚀 Iniciando ejemplo de sistema hidráulico simple"); - Console.WriteLine("Sistema: Bomba -> Tubería -> Tanque de Descarga"); - Console.WriteLine(); - - // 1. Crear la red hidráulica - var network = new HydraulicNetwork(); - - // 2. Agregar nodos según la documentación - network.AddNode("SUMINISTRO", 0); // Tanque de suministro a presión atmosférica - network.AddNode("BOMBA_OUT"); // Salida de bomba (presión calculada) - network.AddNode("TANQUE_DESCARGA", 0); // Tanque de descarga libre - - // 3. Crear elementos hidráulicos - var pump = new PumpHQ( - h0: 80, // Cabeza a caudal cero: 80 metros - q0: 0.01, // Caudal a cabeza cero: 0.01 m³/s (36 m³/h) - speedRel: 1.0, // Velocidad nominal - direction: 1 // Dirección normal - ); - - var pipe = new Pipe( - length: 50, // 50 metros de longitud - diameter: 0.08, // 80mm de diámetro - roughness: 0.0015 // Rugosidad del acero comercial - ); - - // 4. Conectar elementos en ramas según la documentación - network.AddBranch("SUMINISTRO", "BOMBA_OUT", - new List { pump }, "Bomba_Principal"); - - network.AddBranch("BOMBA_OUT", "TANQUE_DESCARGA", - new List { pipe }, "Tuberia_Descarga"); - - // 5. Resolver la red - Console.WriteLine("⚙️ Resolviendo red hidráulica..."); - var result = network.Solve( - maxIterations: 200, - tolerance: 1e-4, - verbose: true - ); - - // 6. Mostrar resultados - if (result.Converged) - { - Console.WriteLine("✅ Simulación exitosa!"); - Console.WriteLine($"Convergió en {result.Iterations} iteraciones"); - Console.WriteLine(); - - ShowResults(result); - ShowComponentAnalysis(result, pump, pipe); - } - else - { - Console.WriteLine($"❌ No convergió después de {result.Iterations} iteraciones"); - Console.WriteLine($"Error final: {result.Residual:E6}"); - } - } - - private static void ShowResults(SolutionResult result) - { - Console.WriteLine("📊 RESULTADOS DE LA SIMULACIÓN:"); - Console.WriteLine("═══════════════════════════════"); - - // Flujos - Console.WriteLine("🌊 Flujos:"); - foreach (var flow in result.Flows) - { - double flowM3h = flow.Value * 3600; // Convertir a m³/h - double flowLmin = flow.Value * 60000; // Convertir a L/min - Console.WriteLine($" {flow.Key}:"); - Console.WriteLine($" {flow.Value:F6} m³/s = {flowM3h:F2} m³/h = {flowLmin:F1} L/min"); - } - - Console.WriteLine(); - - // Presiones - Console.WriteLine("📈 Presiones:"); - foreach (var pressure in result.Pressures) - { - double pressureBar = pressure.Value / 100000.0; // Convertir a bar - double pressureKPa = pressure.Value / 1000.0; // Convertir a kPa - Console.WriteLine($" {pressure.Key}:"); - Console.WriteLine($" {pressure.Value:F0} Pa = {pressureKPa:F1} kPa = {pressureBar:F3} bar"); - } - } - - private static void ShowComponentAnalysis(SolutionResult result, PumpHQ pump, Pipe pipe) - { - Console.WriteLine(); - Console.WriteLine("🔧 ANÁLISIS DE COMPONENTES:"); - Console.WriteLine("═══════════════════════════"); - - // Análisis de la bomba - if (result.Flows.TryGetValue("Bomba_Principal", out double pumpFlow)) - { - double pumpFlowM3h = pumpFlow * 3600; - double pumpHead = pump.Dp(pumpFlow, Fluid.Water20C) / (1000 * 9.81); // Convertir Pa a metros - double pumpPower = pumpFlow * pump.Dp(pumpFlow, Fluid.Water20C) / 1000; // Potencia hidráulica en kW - - Console.WriteLine("💨 Bomba:"); - Console.WriteLine($" Caudal: {pumpFlowM3h:F1} m³/h"); - Console.WriteLine($" Cabeza: {pumpHead:F1} m"); - Console.WriteLine($" Potencia hidráulica: {pumpPower:F2} kW"); - } - - // Análisis de la tubería - if (result.Flows.TryGetValue("Tuberia_Descarga", out double pipeFlow)) - { - double pipePressureDrop = pipe.Dp(pipeFlow, Fluid.Water20C); - double pipeHeadLoss = pipePressureDrop / (1000 * 9.81); // Convertir Pa a metros - double velocity = Math.Abs(pipeFlow) / (Math.PI * (pipe.D * pipe.D) / 4.0); - - Console.WriteLine(); - Console.WriteLine("🚰 Tubería:"); - Console.WriteLine($" Caudal: {pipeFlow * 3600:F1} m³/h"); - Console.WriteLine($" Velocidad: {velocity:F2} m/s"); - Console.WriteLine($" Pérdida de carga: {pipeHeadLoss:F2} m"); - Console.WriteLine($" Pérdida de presión: {pipePressureDrop / 1000:F1} kPa"); - } - } - - /// - /// Ejemplo de cómo los objetos gráficos osHyd* se integrarían en la simulación - /// - public static void ShowGraphicObjectsIntegration() - { - Console.WriteLine(); - Console.WriteLine("🎨 INTEGRACIÓN CON OBJETOS GRÁFICOS:"); - Console.WriteLine("═══════════════════════════════════"); - Console.WriteLine(); - Console.WriteLine("Los objetos creados (osHydPump, osHydPipe, osHydDischargeTank)"); - Console.WriteLine("se integran automáticamente en el sistema de la siguiente manera:"); - Console.WriteLine(); - Console.WriteLine("1. 📋 Registro automático:"); - Console.WriteLine(" - Se registran por reflexión usando NombreCategoria() = \"Hidráulicos\""); - Console.WriteLine(" - Aparecen en la categoría \"Hidráulicos\" del editor"); - Console.WriteLine(); - Console.WriteLine("2. 🔗 Sistema de conexiones:"); - Console.WriteLine(" - Usan ItemsSource para filtrar componentes"); - Console.WriteLine(" - Similar al sistema Motor/Transporte existente"); - Console.WriteLine(" - Conexiones: Id_InletComponent, Id_OutletComponent"); - Console.WriteLine(); - Console.WriteLine("3. 🚫 No participan en Bepu:"); - Console.WriteLine(" - Override Start() sin crear geometrías Bepu"); - Console.WriteLine(" - Solo participan en el simulador hidráulico"); - Console.WriteLine(); - Console.WriteLine("4. 📊 Integración con HydraulicSimulationManager:"); - Console.WriteLine(" - Implementan IHydraulicComponent para GetHydraulicNodes()"); - Console.WriteLine(" - Implementan GetHydraulicElements() para el solver"); - Console.WriteLine(" - Reciben resultados via ApplyHydraulicResults()"); - Console.WriteLine(); - Console.WriteLine("5. 🎯 Ejemplo de configuración:"); - Console.WriteLine(" osHydPump (Nombre=\"Bomba_01\", H0=80m, Q0=36m³/h)"); - Console.WriteLine(" ↓ (Id_OutletComponent=\"Tuberia_01\")"); - Console.WriteLine(" osHydPipe (Nombre=\"Tuberia_01\", L=50m, D=80mm)"); - Console.WriteLine(" ↓ (Id_OutletComponent=\"Tanque_01\")"); - Console.WriteLine(" osHydDischargeTank (Nombre=\"Tanque_01\", Area=1m²)"); - } - } -} diff --git a/ObjetosSim/HydraulicComponents/osHydDischargeTank.cs b/ObjetosSim/HydraulicComponents/osHydDischargeTank.cs deleted file mode 100644 index 3c5e776..0000000 --- a/ObjetosSim/HydraulicComponents/osHydDischargeTank.cs +++ /dev/null @@ -1,408 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Windows.Media; -using CtrEditor.HydraulicSimulator; -using CtrEditor.ObjetosSim; -using CtrEditor.FuncionesBase; -using HydraulicSimulator.Models; -using Newtonsoft.Json; -using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; -using CommunityToolkit.Mvvm.ComponentModel; -using LibS7Adv; - -namespace CtrEditor.ObjetosSim.HydraulicComponents -{ - /// - /// Tanque de descarga hidráulico con cálculo de nivel dinámico - /// - public partial class osHydDischargeTank : osBase, IHydraulicTank, IosBase - { - #region Properties - - private double _area = 1.0; // m² - private double _currentVolume = 0.5; // m³ - private double _maxVolume = 2.0; // m³ - private double _minVolume = 0.0; // m³ - private double _currentHeight = 0.0; - private double _currentPressure = 0.0; - - // Propiedades visuales - [ObservableProperty] - [property: Category("🎨 Apariencia")] - [property: Description("Ancho visual del tanque en metros")] - [property: Name("Ancho")] - private float ancho = 0.5f; - - [ObservableProperty] - [property: Category("🎨 Apariencia")] - [property: Description("Alto visual del tanque en metros")] - [property: Name("Alto")] - private float alto = 0.8f; - - [ObservableProperty] - [property: Category("🎨 Apariencia")] - [property: Description("Color visual del tanque")] - [property: Name("Color")] - private Brush colorButton_oculto = Brushes.LightBlue; - - [ObservableProperty] - [property: Category("🎨 Apariencia")] - [property: Description("Ángulo de rotación del tanque en grados")] - [property: Name("Ángulo")] - private float angulo = 0f; - - [Category("🔧 Tanque Hidráulico")] - [Description("Área de la base del tanque en m² (alias para compatibilidad)")] - [Name("Área Base (m²)")] - public double Area - { - get => _area; - set => SetProperty(ref _area, Math.Max(0.1, value)); - } - - [Category("🔧 Tanque Hidráulico")] - [Description("Presión del tanque en Pa")] - [Name("Presión Tanque (Pa)")] - public double TankPressure - { - get => _currentPressure; - set => SetProperty(ref _currentPressure, value); - } - - [Category("🔧 Tanque Hidráulico")] - [Description("Nivel actual del tanque en metros")] - [Name("Nivel (m)")] - public double Level - { - get => _currentHeight; - set - { - SetProperty(ref _currentHeight, value); - CurrentVolume = value * Area; - } - } - - [Category("🔧 Tanque Hidráulico")] - [Description("Área de la sección transversal del tanque en m²")] - [Name("Área Sección (m²)")] - public double CrossSectionalArea - { - get => _area; - set => SetProperty(ref _area, Math.Max(0.1, value)); - } - - [Category("🔧 Tanque Hidráulico")] - [Description("Indica si el tanque tiene presión fija")] - [Name("Presión Fija")] - [ReadOnly(true)] - public bool IsFixedPressure => false; // Los tanques de descarga tienen presión calculada - - [Category("🔧 Tanque Hidráulico")] - [Description("Volumen actual del tanque en m³")] - [Name("Volumen Actual (m³)")] - public double CurrentVolume - { - get => _currentVolume; - set => SetProperty(ref _currentVolume, Math.Max(MinVolume, Math.Min(MaxVolume, value))); - } - - [Category("🔧 Tanque Hidráulico")] - [Description("Volumen máximo del tanque en m³")] - [Name("Volumen Máximo (m³)")] - public double MaxVolume - { - get => _maxVolume; - set => SetProperty(ref _maxVolume, Math.Max(CurrentVolume, value)); - } - - [Category("🔧 Tanque Hidráulico")] - [Description("Volumen mínimo del tanque en m³")] - [Name("Volumen Mínimo (m³)")] - public double MinVolume - { - get => _minVolume; - set => SetProperty(ref _minVolume, Math.Max(0.0, Math.Min(CurrentVolume, value))); - } - - [ObservableProperty] - [property: Category("🔗 Conexiones")] - [property: Description("Componente conectado en la entrada")] - [property: Name("Componente Entrada")] - [property: ItemsSource(typeof(osBaseItemsSource))] - private string id_InletComponent = ""; - - [Category("📊 Estado")] - [Description("Altura actual del líquido en metros")] - [Name("Altura Actual (m)")] - [ReadOnly(true)] - public double CurrentHeight - { - get => _currentHeight; - set => SetProperty(ref _currentHeight, value); - } - - [Category("📊 Estado")] - [Description("Presión hidrostática en el fondo del tanque en Pa")] - [Name("Presión Fondo (Pa)")] - [ReadOnly(true)] - public double CurrentPressure - { - get => _currentPressure; - set => SetProperty(ref _currentPressure, value); - } - - [Category("📊 Estado")] - [Description("Porcentaje de llenado del tanque")] - [Name("Nivel (%)")] - [ReadOnly(true)] - public double FillPercentage => MaxVolume > 0 ? (CurrentVolume / MaxVolume) * 100.0 : 0.0; - - #endregion - - #region Component References - - [JsonIgnore] - private IHydraulicComponent InletComponent = null; - - [JsonIgnore] - private PropertyChangedEventHandler inletPropertyChangedHandler; - - [JsonIgnore] - public Action ActualizarTamaño { get; set; } - - #endregion - - #region IHydraulicComponent Implementation - - public bool HasHydraulicComponents => true; - - public List GetHydraulicNodes() - { - var nodes = new List(); - - // El tanque de descarga debe ser un nodo de presión fija para servir como referencia del sistema - // Presión = presión atmosférica + presión hidrostática - double pressureReference = 101325.0 + TankPressure; // Pa (1 atm + presión hidrostática) - nodes.Add(new HydraulicNodeDefinition(Nombre, true, pressureReference, "Tanque de descarga (referencia)")); - - Debug.WriteLine($"Tanque {Nombre}: Nodo de presión fija creado - {pressureReference:F0} Pa ({pressureReference/100000:F2} bar)"); - - return nodes; - } - - public List GetHydraulicElements() - { - // Los tanques no son elementos, son nodos - return new List(); - } - - public void UpdateHydraulicProperties() - { - // Actualizar presión basada en el nivel actual - UpdateHeightAndPressure(); - } - - public void ApplyHydraulicResults(Dictionary flows, Dictionary pressures) - { - // Actualizar presión del tanque - if (pressures.TryGetValue(Nombre, out double pressure)) - { - TankPressure = pressure; - // Calcular nivel basado en la presión hidrostática - Level = pressure / (1000.0 * 9.81); // Asumiendo densidad del agua - } - - // Calcular flujo neto hacia el tanque - double netFlow = 0.0; - foreach (var flow in flows) - { - if (flow.Key.EndsWith($"->{Nombre}")) - netFlow += flow.Value; // Flujo entrante - else if (flow.Key.StartsWith($"{Nombre}->")) - netFlow -= flow.Value; // Flujo saliente - } - - // Aquí podrías actualizar el volumen en función del tiempo - // Esto se haría en el update loop principal de la simulación - } - - #endregion - - #region IHydraulicPressureReceiver Implementation - - public void SetPressure(double pressure) - { - TankPressure = pressure; - // Actualizar nivel basado en presión hidrostática - Level = pressure / (1000.0 * 9.81); - } - - public double GetPressure() - { - return TankPressure; - } - - #endregion - - #region Connection Management - - partial void OnId_InletComponentChanged(string value) - { - if (InletComponent != null && inletPropertyChangedHandler != null) - ((INotifyPropertyChanged)InletComponent).PropertyChanged -= inletPropertyChangedHandler; - - if (_mainViewModel != null && !string.IsNullOrEmpty(value)) - { - InletComponent = (IHydraulicComponent)_mainViewModel.ObjetosSimulables - .FirstOrDefault(s => s is IHydraulicComponent comp && - ((osBase)comp).Nombre == value); - - if (InletComponent != null) - { - inletPropertyChangedHandler = (sender, e) => - { - if (e.PropertyName == nameof(osBase.Nombre)) - { - Id_InletComponent = ((osBase)sender).Nombre; - } - }; - ((INotifyPropertyChanged)InletComponent).PropertyChanged += inletPropertyChangedHandler; - } - } - } - - #endregion - - #region Volume and Level Calculations - - private void UpdateHeightAndPressure() - { - Level = Area > 0 ? CurrentVolume / Area : 0.0; - // Presión hidrostática en el fondo del tanque (densidad del agua = 1000 kg/m³) - TankPressure = 1000.0 * 9.81 * Level; - } - - /// - /// Actualiza el volumen del tanque basado en flujos netos según la documentación - /// - /// Diccionario de flujos de la simulación - /// Intervalo de tiempo en segundos - public void UpdateVolume(Dictionary flows, double deltaTime) - { - double netFlow = 0.0; - - // Sumar flujos entrantes, restar salientes - foreach (var flow in flows) - { - if (flow.Key.EndsWith($"->{Nombre}")) - netFlow += flow.Value; // Entrante - else if (flow.Key.StartsWith($"{Nombre}->")) - netFlow -= flow.Value; // Saliente - } - - // Actualizar volumen - CurrentVolume += netFlow * deltaTime; - CurrentVolume = Math.Max(MinVolume, Math.Min(MaxVolume, CurrentVolume)); - - // Actualizar altura y presión - UpdateHeightAndPressure(); - } - - /// - /// Calcula la presión en el fondo del tanque según la documentación - /// - /// Densidad del fluido (kg/m³) - /// Presión hidrostática en Pa - public double BottomPressure(double density = 1000.0) - { - return density * 9.81 * Level; // ρgh - } - - #endregion - - #region osBase Implementation - - public static string NombreCategoria() => "Componentes Hidráulicos"; - - public static string NombreClase() => "Tanque de Descarga"; - - private string nombre = NombreClase(); - - [Category("Identificación")] - [Description("Nombre identificativo del objeto")] - [Name("Nombre")] - public override string Nombre - { - get => nombre; - set => SetProperty(ref nombre, value); - } - - public override void AltoChanged(float value) - { - ActualizarGeometrias(); - } - - public override void AnchoChanged(float value) - { - ActualizarGeometrias(); - } - - public void Start() - { - // Los tanques no participan en la simulación física Bepu - // Solo en el sistema hidráulico - UpdateHeightAndPressure(); - } - - public override void UpdateGeometryStart() - { - ActualizarGeometrias(); - } - - public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds) - { - // Los tanques pueden tener sensores de nivel - // Implementar aquí si es necesario - } - - private void ActualizarGeometrias() - { - try - { - // Actualizar geometría visual - if (this.ActualizarTamaño != null) - this.ActualizarTamaño(Ancho, Alto); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"Error actualizando geometría: {ex.Message}"); - } - } - - public void Inicializar(int valorInicial) - { - UpdateHeightAndPressure(); - OnId_InletComponentChanged(Id_InletComponent); - } - - public void Disposing() - { - if (InletComponent != null && inletPropertyChangedHandler != null) - ((INotifyPropertyChanged)InletComponent).PropertyChanged -= inletPropertyChangedHandler; - } - - #endregion - - #region Constructor - - public osHydDischargeTank() - { - UpdateHeightAndPressure(); - } - - #endregion - } -} diff --git a/ObjetosSim/HydraulicComponents/osHydPipe.cs b/ObjetosSim/HydraulicComponents/osHydPipe.cs index c362532..3479c5a 100644 --- a/ObjetosSim/HydraulicComponents/osHydPipe.cs +++ b/ObjetosSim/HydraulicComponents/osHydPipe.cs @@ -19,7 +19,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents /// public partial class osHydPipe : osBase, IHydraulicPipe, IosBase { - #region Properties + // Properties private double _length = 1.0; // metros private double _diameter = 0.05; // metros (50mm) @@ -120,9 +120,9 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents set => SetProperty(ref pipeId, value); } - #endregion + - #region Component References + // Component References [JsonIgnore] private IHydraulicComponent ComponenteA = null; @@ -139,15 +139,15 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents [JsonIgnore] public Action ActualizarTamaño { get; set; } - #endregion + - #region IHydraulicPipe Implementation + // IHydraulicPipe Implementation // Ya implementadas las propiedades Length, Diameter, Roughness arriba - #endregion + - #region IHydraulicComponent Implementation + // IHydraulicComponent Implementation public bool HasHydraulicComponents => true; @@ -277,9 +277,9 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents } } - #endregion + - #region IHydraulicFlowReceiver Implementation + // IHydraulicFlowReceiver Implementation public void SetFlow(double flow) { @@ -291,9 +291,9 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents return CurrentFlow; } - #endregion + - #region IHydraulicPressureReceiver Implementation + // IHydraulicPressureReceiver Implementation public void SetPressure(double pressure) { @@ -305,9 +305,9 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents return PressureDrop; } - #endregion + - #region Connection Management + // Connection Management partial void OnId_ComponenteAChanged(string value) { @@ -359,9 +359,9 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents } } - #endregion + - #region osBase Implementation + // osBase Implementation public static string NombreCategoria() => "Componentes Hidráulicos"; @@ -434,9 +434,9 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents ((INotifyPropertyChanged)ComponenteB).PropertyChanged -= componenteBPropertyChangedHandler; } - #endregion + - #region Constructor + // Constructor public osHydPipe() { @@ -444,6 +444,6 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents IsVisFilter = true; // Asegurar que el componente hidráulico sea visible en filtros } - #endregion + } } diff --git a/ObjetosSim/HydraulicComponents/osHydPump.cs b/ObjetosSim/HydraulicComponents/osHydPump.cs index 332024d..183a7ad 100644 --- a/ObjetosSim/HydraulicComponents/osHydPump.cs +++ b/ObjetosSim/HydraulicComponents/osHydPump.cs @@ -25,7 +25,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents return "Bomba Hidráulica"; } - #region Properties + // Properties [ObservableProperty] [property: JsonIgnore] @@ -176,9 +176,9 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents [JsonIgnore] public double CurrentFlowLMin => CurrentFlow * 60000.0; // m³/s a L/min - #endregion - #region Constructor y Métodos Base + + // Constructor y Métodos Base private string nombre = NombreClase(); @@ -201,9 +201,6 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents Angulo = 0f; // Asegurar que el movimiento esté habilitado Lock_movement = false; - // Inicializar posición por defecto - Left = 0.0f; - Top = 0.0f; ImageSource_oculta = ImageFromPath("/imagenes/pump_stop.png"); } @@ -240,9 +237,9 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents // Los objetos hidráulicos no tienen geometría que limpiar } - #endregion - #region IHydraulicComponent Implementation + + // IHydraulicComponent Implementation [JsonIgnore] public bool HasHydraulicComponents => true; @@ -343,9 +340,9 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents OnPropertyChanged(nameof(CurrentPressureBar)); } - #endregion - #region IHydraulicFlowReceiver Implementation + + // IHydraulicFlowReceiver Implementation public void SetFlow(double flow) { @@ -357,9 +354,9 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents return CurrentFlow; } - #endregion - #region IHydraulicPressureReceiver Implementation + + // IHydraulicPressureReceiver Implementation public void SetPressure(double pressure) { @@ -371,9 +368,9 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents return CurrentPressure; } - #endregion - #region Helper Methods + + // Helper Methods /// /// Invalida la red hidráulica para forzar reconstrucción @@ -387,7 +384,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents } } - #endregion + } /// diff --git a/ObjetosSim/HydraulicComponents/osHydTank.cs b/ObjetosSim/HydraulicComponents/osHydTank.cs index 60a7662..ad1782c 100644 --- a/ObjetosSim/HydraulicComponents/osHydTank.cs +++ b/ObjetosSim/HydraulicComponents/osHydTank.cs @@ -41,7 +41,8 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents private string _connectedInletPipe = ""; private string _connectedOutletPipe = ""; private double _lastUpdateTime = 0.0; - private readonly object _levelLock = new object(); + [JsonIgnore] + private object _levelLock = new object(); private PropertyChangedEventHandler? inletPropertyChangedHandler; private PropertyChangedEventHandler? outletPropertyChangedHandler; @@ -95,13 +96,15 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents Angulo = 0f; // Asegurar que el movimiento esté habilitado Lock_movement = false; - // Inicializar posición por defecto ImageSource_oculta = ImageFromPath("/imagenes/tank.png"); _currentVolume = _currentLevel * _crossSectionalArea; _maxVolume = _maxLevel * _crossSectionalArea; IsVisFilter = true; // Asegurar que el componente hidráulico sea visible en filtros UpdateTankPressure(); + // Inicializar el lock para thread safety + EnsureLockInitialized(); + // Debug: Confirmar que el constructor se ejecuta Debug.WriteLine($"osHydTank Constructor: Nombre='{Nombre}', Tamaño={Tamano}, ZIndex={zIndex_fromFrames}, IsVisFilter={IsVisFilter}, Lock_movement={Lock_movement}"); } @@ -120,6 +123,13 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents set => SetProperty(ref nombre, value); } + public override void OnMove(float LeftPixels, float TopPixels) + { + // Método básico de movimiento como otros objetos + // Debug para verificar que se llama + Debug.WriteLine($"osHydTank.OnMove: LeftPixels={LeftPixels}, TopPixels={TopPixels}, Left={Left}, Top={Top}"); + } + public override void OnResize(float Delta_Width, float Delta_Height) { Tamano += Delta_Width + Delta_Height; @@ -280,6 +290,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents get => _currentLevel; private set { + EnsureLockInitialized(); lock (_levelLock) { var clampedLevel = Math.Max(_minLevel, Math.Min(_maxLevel, value)); @@ -768,11 +779,28 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents + // Serialization Support + + /// + /// Se llama antes de la serialización para asegurar que el lock esté disponible + /// + private void EnsureLockInitialized() + { + if (_levelLock == null) + _levelLock = new object(); + } + + + // osBase Overrides public override void ucLoaded() { - // Inicialización cuando se carga el UserControl + // El UserControl ya se ha cargado y podemos obtener las coordenadas para + // crear el objeto de simulacion + base.ucLoaded(); + + // Inicialización específica del tanque hidráulico UpdateVolumeCalculations(); UpdateTankPressure(); diff --git a/ObjetosSim/HydraulicComponents/ucHydDischargeTank.xaml b/ObjetosSim/HydraulicComponents/ucHydDischargeTank.xaml deleted file mode 100644 index 444e208..0000000 --- a/ObjetosSim/HydraulicComponents/ucHydDischargeTank.xaml +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Blue - 0.6 - - - - - - - - - - - - - - - - - - - - - diff --git a/ObjetosSim/HydraulicComponents/ucHydDischargeTank.xaml.cs b/ObjetosSim/HydraulicComponents/ucHydDischargeTank.xaml.cs deleted file mode 100644 index da5d993..0000000 --- a/ObjetosSim/HydraulicComponents/ucHydDischargeTank.xaml.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.Windows.Controls; -using System.Windows.Media; -using System.Windows; -using CtrEditor.ObjetosSim; -using CtrEditor.FuncionesBase; - -namespace CtrEditor.ObjetosSim.HydraulicComponents -{ - /// - /// Interaction logic for ucHydDischargeTank.xaml - /// - public partial class ucHydDischargeTank : UserControl, IDataContainer - { - public osBase? Datos { get; set; } - public int zIndex_fromFrames { get; set; } = 0; - - private bool _isHighlighted = false; - - public ucHydDischargeTank() - { - InitializeComponent(); - this.Loaded += OnLoaded; - this.Unloaded += OnUnloaded; - DataContextChanged += OnDataContextChanged; - } - - private void OnLoaded(object sender, RoutedEventArgs e) - { - Datos?.ucLoaded(); - } - - private void OnUnloaded(object sender, RoutedEventArgs e) - { - Datos?.ucUnLoaded(); - } - - private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) - { - if (DataContext is osHydDischargeTank tank) - { - Datos = tank; - } - } - - #region IDataContainer Implementation - - public void Highlight(bool state) - { - _isHighlighted = state; - - if (state) - { - rectTank.Stroke = new SolidColorBrush(Colors.Yellow); - rectTank.StrokeThickness = 3; - } - else - { - rectTank.Stroke = new SolidColorBrush(Colors.DarkSlateGray); - rectTank.StrokeThickness = 2; - } - } - - #endregion - - public ZIndexEnum ZIndex_Base() - { - return ZIndexEnum.Estaticos; - } - } -} diff --git a/ObjetosSim/HydraulicComponents/ucHydTank.xaml b/ObjetosSim/HydraulicComponents/ucHydTank.xaml index 08ef26b..49cb02a 100644 --- a/ObjetosSim/HydraulicComponents/ucHydTank.xaml +++ b/ObjetosSim/HydraulicComponents/ucHydTank.xaml @@ -8,6 +8,9 @@ mc:Ignorable="d"> + + + @@ -21,8 +24,7 @@ + Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"> - - - - - - - + Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"> diff --git a/Serialization/StateSerializer.cs b/Serialization/StateSerializer.cs index 80438bb..593ca9d 100644 --- a/Serialization/StateSerializer.cs +++ b/Serialization/StateSerializer.cs @@ -270,6 +270,7 @@ namespace CtrEditor.Serialization { Formatting = Formatting.Indented, NullValueHandling = NullValueHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Include, // Incluir valores por defecto TypeNameHandling = TypeNameHandling.Auto, ObjectCreationHandling = ObjectCreationHandling.Replace, ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor, diff --git a/test_osBaseItemsSource.cs b/test_osBaseItemsSource.cs deleted file mode 100644 index 82c20c4..0000000 --- a/test_osBaseItemsSource.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; -using CtrEditor.ObjetosSim; -using CtrEditor.ObjetosSim.HydraulicComponents; -using CtrEditor.HydraulicSimulator; - -// Este archivo es solo para verificar que la corrección funciona -// Se puede eliminar después de confirmar que todo funciona bien - -namespace CtrEditor.Test -{ - class TestItemsSource - { - static void TestTypeAssignability() - { - // Crear instancias de objetos hidráulicos - var pipe = new osHydPipe(); - var tank = new osHydDischargeTank(); - var pump = new osHydPump(); - var hydTank = new osHydTank(); - - // Probar la corrección - debería ser true para todos - Console.WriteLine($"osHydPipe implements IHydraulicComponent: {typeof(IHydraulicComponent).IsAssignableFrom(pipe.GetType())}"); - Console.WriteLine($"osHydDischargeTank implements IHydraulicComponent: {typeof(IHydraulicComponent).IsAssignableFrom(tank.GetType())}"); - Console.WriteLine($"osHydPump implements IHydraulicComponent: {typeof(IHydraulicComponent).IsAssignableFrom(pump.GetType())}"); - Console.WriteLine($"osHydTank implements IHydraulicComponent: {typeof(IHydraulicComponent).IsAssignableFrom(hydTank.GetType())}"); - - // Verificar NombreCategoria y NombreClase - Console.WriteLine($"osHydTank.NombreCategoria(): {osHydTank.NombreCategoria()}"); - Console.WriteLine($"osHydTank.NombreClase(): {osHydTank.NombreClase()}"); - - // La comparación anterior que fallaba - Console.WriteLine($"osHydPipe.GetType() == typeof(IHydraulicComponent): {pipe.GetType() == typeof(IHydraulicComponent)}"); - Console.WriteLine($"osHydDischargeTank.GetType() == typeof(IHydraulicComponent): {tank.GetType() == typeof(IHydraulicComponent)}"); - Console.WriteLine($"osHydPump.GetType() == typeof(IHydraulicComponent): {pump.GetType() == typeof(IHydraulicComponent)}"); - Console.WriteLine($"osHydTank.GetType() == typeof(IHydraulicComponent): {hydTank.GetType() == typeof(IHydraulicComponent)}"); - } - } -}