feat: Enhance hydraulic simulation components and integrate new object management
- Updated UserControlFactory to support hydraulic simulation manager in AssignDatos method. - Introduced new classes for hydraulic simulation objects: simHydraulicBase, simHydraulicPump, simHydraulicTank, and simHydraulicPipe. - Implemented methods for updating properties and applying simulation results in hydraulic components. - Enhanced osHydPipe, osHydPump, and osHydTank classes to manage hydraulic simulation objects and their properties. - Added methods for creating, removing, and clearing hydraulic simulation objects in HydraulicSimulationManager. - Improved error handling and logging in various components to facilitate debugging. - Refactored XAML and code-behind files to align with new namespace structure for hydraulic components.
This commit is contained in:
parent
8e6d457047
commit
e6a8bb8cbe
|
@ -275,7 +275,7 @@ namespace CtrEditor
|
||||||
|
|
||||||
if (userControl != null)
|
if (userControl != null)
|
||||||
{
|
{
|
||||||
UserControlFactory.AssignDatos(userControl, osObjeto, _mainViewModel.simulationManager);
|
UserControlFactory.AssignDatos(userControl, osObjeto, _mainViewModel.simulationManager, _mainViewModel.hydraulicSimulationManager);
|
||||||
osObjeto._mainViewModel = _mainViewModel;
|
osObjeto._mainViewModel = _mainViewModel;
|
||||||
|
|
||||||
if (osObjeto.Id == null)
|
if (osObjeto.Id == null)
|
||||||
|
|
|
@ -451,6 +451,13 @@ namespace CtrEditor.HydraulicSimulator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void UpdateObjectProperties()
|
private void UpdateObjectProperties()
|
||||||
{
|
{
|
||||||
|
// Actualizar objetos hidráulicos específicos
|
||||||
|
foreach (var simObj in HydraulicSimObjects)
|
||||||
|
{
|
||||||
|
simObj.UpdateProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualizar objetos hidráulicos generales (legacy)
|
||||||
foreach (var obj in HydraulicObjects)
|
foreach (var obj in HydraulicObjects)
|
||||||
{
|
{
|
||||||
// Aquí se implementará la actualización de propiedades específicas
|
// Aquí se implementará la actualización de propiedades específicas
|
||||||
|
@ -548,6 +555,14 @@ namespace CtrEditor.HydraulicSimulator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void ApplyResultsToObjects()
|
private void ApplyResultsToObjects()
|
||||||
{
|
{
|
||||||
|
// Aplicar resultados a objetos hidráulicos específicos
|
||||||
|
foreach (var simObj in HydraulicSimObjects)
|
||||||
|
{
|
||||||
|
ApplyResultsToSimObject(simObj);
|
||||||
|
simObj.ApplySimulationResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aplicar resultados a objetos hidráulicos generales (legacy)
|
||||||
foreach (var obj in HydraulicObjects)
|
foreach (var obj in HydraulicObjects)
|
||||||
{
|
{
|
||||||
// Aplicar caudales y presiones calculados al objeto
|
// Aplicar caudales y presiones calculados al objeto
|
||||||
|
@ -555,6 +570,58 @@ namespace CtrEditor.HydraulicSimulator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Aplica los resultados de la simulación a un objeto específico
|
||||||
|
/// </summary>
|
||||||
|
private void ApplyResultsToSimObject(simHydraulicBase simObj)
|
||||||
|
{
|
||||||
|
// Aplicar resultados específicos según el tipo de objeto
|
||||||
|
if (simObj is simHydraulicPump pump)
|
||||||
|
{
|
||||||
|
// Buscar flujo y presión de la bomba en los resultados
|
||||||
|
string pumpBranchName = $"{pump.Nombre}_Pump";
|
||||||
|
if (LastSolutionResult.Flows.TryGetValue(pumpBranchName, out double flow))
|
||||||
|
{
|
||||||
|
pump.CurrentFlow = flow;
|
||||||
|
}
|
||||||
|
|
||||||
|
string inletNodeName = $"{pump.Nombre}_In";
|
||||||
|
if (LastSolutionResult.Pressures.TryGetValue(inletNodeName, out double pressure))
|
||||||
|
{
|
||||||
|
pump.CurrentPressure = pressure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (simObj is simHydraulicTank tank)
|
||||||
|
{
|
||||||
|
// Buscar flujos de entrada y salida del tanque
|
||||||
|
// Esto requeriría mapeo de tuberías conectadas
|
||||||
|
// Por ahora, aplicar presión del tanque
|
||||||
|
string tankNodeName = $"{tank.Nombre}_Tank";
|
||||||
|
if (LastSolutionResult.Pressures.TryGetValue(tankNodeName, out double pressure))
|
||||||
|
{
|
||||||
|
tank.CurrentPressure = pressure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (simObj is simHydraulicPipe pipe)
|
||||||
|
{
|
||||||
|
// Buscar flujo a través de la tubería
|
||||||
|
string pipeBranchName = $"{pipe.Nombre}_Pipe";
|
||||||
|
if (LastSolutionResult.Flows.TryGetValue(pipeBranchName, out double flow))
|
||||||
|
{
|
||||||
|
pipe.CurrentFlow = flow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calcular pérdida de presión
|
||||||
|
string fromNode = pipe.ComponenteAId;
|
||||||
|
string toNode = pipe.ComponenteBId;
|
||||||
|
if (LastSolutionResult.Pressures.TryGetValue(fromNode, out double pressureA) &&
|
||||||
|
LastSolutionResult.Pressures.TryGetValue(toNode, out double pressureB))
|
||||||
|
{
|
||||||
|
pipe.PressureDrop = pressureA - pressureB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Aplica los resultados a un objeto específico
|
/// Aplica los resultados a un objeto específico
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -729,5 +796,103 @@ namespace CtrEditor.HydraulicSimulator
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Hydraulic Object Creation
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lista de objetos hidráulicos específicos del simulador
|
||||||
|
/// </summary>
|
||||||
|
public List<simHydraulicBase> HydraulicSimObjects { get; private set; } = new List<simHydraulicBase>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Crea una bomba hidráulica en la simulación
|
||||||
|
/// </summary>
|
||||||
|
public simHydraulicPump AddPump(double pumpHead, double maxFlow, double speedRatio, bool isRunning, int direction)
|
||||||
|
{
|
||||||
|
var pump = new simHydraulicPump(this)
|
||||||
|
{
|
||||||
|
PumpHead = pumpHead,
|
||||||
|
MaxFlow = maxFlow,
|
||||||
|
SpeedRatio = speedRatio,
|
||||||
|
IsRunning = isRunning,
|
||||||
|
PumpDirection = direction
|
||||||
|
};
|
||||||
|
|
||||||
|
HydraulicSimObjects.Add(pump);
|
||||||
|
_networkNeedsRebuild = true;
|
||||||
|
|
||||||
|
Debug.WriteLine($"Bomba hidráulica creada: H={pumpHead}m, Q={maxFlow}m³/s");
|
||||||
|
return pump;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Crea un tanque hidráulico en la simulación
|
||||||
|
/// </summary>
|
||||||
|
public simHydraulicTank AddTank(double pressure, double currentLevel, double maxLevel, double minLevel, double crossSectionalArea, bool isFixedPressure)
|
||||||
|
{
|
||||||
|
var tank = new simHydraulicTank(this)
|
||||||
|
{
|
||||||
|
TankPressure = pressure,
|
||||||
|
CurrentLevel = currentLevel,
|
||||||
|
MaxLevel = maxLevel,
|
||||||
|
MinLevel = minLevel,
|
||||||
|
CrossSectionalArea = crossSectionalArea,
|
||||||
|
IsFixedPressure = isFixedPressure
|
||||||
|
};
|
||||||
|
|
||||||
|
HydraulicSimObjects.Add(tank);
|
||||||
|
_networkNeedsRebuild = true;
|
||||||
|
|
||||||
|
Debug.WriteLine($"Tanque hidráulico creado: P={pressure}Pa, Nivel={currentLevel}m");
|
||||||
|
return tank;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Crea una tubería hidráulica en la simulación
|
||||||
|
/// </summary>
|
||||||
|
public simHydraulicPipe AddPipe(double length, double diameter, double roughness, string componenteAId, string componenteBId)
|
||||||
|
{
|
||||||
|
var pipe = new simHydraulicPipe(this)
|
||||||
|
{
|
||||||
|
Length = length,
|
||||||
|
Diameter = diameter,
|
||||||
|
Roughness = roughness,
|
||||||
|
ComponenteAId = componenteAId,
|
||||||
|
ComponenteBId = componenteBId
|
||||||
|
};
|
||||||
|
|
||||||
|
HydraulicSimObjects.Add(pipe);
|
||||||
|
_networkNeedsRebuild = true;
|
||||||
|
|
||||||
|
Debug.WriteLine($"Tubería hidráulica creada: L={length}m, D={diameter}m");
|
||||||
|
return pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remueve un objeto hidráulico de la simulación
|
||||||
|
/// </summary>
|
||||||
|
public void Remove(simHydraulicBase hydraulicObject)
|
||||||
|
{
|
||||||
|
if (hydraulicObject != null && HydraulicSimObjects.Contains(hydraulicObject))
|
||||||
|
{
|
||||||
|
HydraulicSimObjects.Remove(hydraulicObject);
|
||||||
|
_networkNeedsRebuild = true;
|
||||||
|
|
||||||
|
Debug.WriteLine($"Objeto hidráulico removido: {hydraulicObject.SimObjectType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Limpia todos los objetos hidráulicos específicos
|
||||||
|
/// </summary>
|
||||||
|
public void ClearHydraulicSimObjects()
|
||||||
|
{
|
||||||
|
HydraulicSimObjects.Clear();
|
||||||
|
_networkNeedsRebuild = true;
|
||||||
|
|
||||||
|
Debug.WriteLine("Todos los objetos hidráulicos específicos han sido limpiados");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,179 @@
|
||||||
|
using System.Numerics;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using CtrEditor.ObjetosSim;
|
||||||
|
|
||||||
|
namespace CtrEditor.HydraulicSimulator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Clase base para objetos hidráulicos en la simulación
|
||||||
|
/// Similar a simBase pero para el sistema hidráulico
|
||||||
|
/// </summary>
|
||||||
|
public class simHydraulicBase
|
||||||
|
{
|
||||||
|
public string SimObjectType { get; set; } = "";
|
||||||
|
public osBase WpfObject { get; set; }
|
||||||
|
public string Nombre { get; set; }
|
||||||
|
public bool Descartar { get; set; } = false;
|
||||||
|
|
||||||
|
protected HydraulicSimulationManager _hydraulicManager;
|
||||||
|
|
||||||
|
public simHydraulicBase(HydraulicSimulationManager hydraulicManager)
|
||||||
|
{
|
||||||
|
_hydraulicManager = hydraulicManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Método virtual para actualizar propiedades específicas del objeto
|
||||||
|
/// </summary>
|
||||||
|
public virtual void UpdateProperties()
|
||||||
|
{
|
||||||
|
// Implementación base - puede ser sobrescrita
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Método virtual para aplicar resultados de la simulación al objeto WPF
|
||||||
|
/// </summary>
|
||||||
|
public virtual void ApplySimulationResults()
|
||||||
|
{
|
||||||
|
// Implementación base - puede ser sobrescrita
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Representa una bomba hidráulica en la simulación
|
||||||
|
/// </summary>
|
||||||
|
public class simHydraulicPump : simHydraulicBase
|
||||||
|
{
|
||||||
|
public double PumpHead { get; set; }
|
||||||
|
public double MaxFlow { get; set; }
|
||||||
|
public double SpeedRatio { get; set; }
|
||||||
|
public bool IsRunning { get; set; }
|
||||||
|
public int PumpDirection { get; set; }
|
||||||
|
|
||||||
|
// Resultados de la simulación
|
||||||
|
public double CurrentFlow { get; set; }
|
||||||
|
public double CurrentPressure { get; set; }
|
||||||
|
|
||||||
|
public simHydraulicPump(HydraulicSimulationManager hydraulicManager) : base(hydraulicManager)
|
||||||
|
{
|
||||||
|
SimObjectType = "HydraulicPump";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateProperties()
|
||||||
|
{
|
||||||
|
// Actualizar propiedades específicas de la bomba
|
||||||
|
if (WpfObject is IHydraulicPump pump)
|
||||||
|
{
|
||||||
|
PumpHead = pump.PumpHead;
|
||||||
|
MaxFlow = pump.MaxFlow;
|
||||||
|
SpeedRatio = pump.SpeedRatio;
|
||||||
|
IsRunning = pump.IsRunning;
|
||||||
|
PumpDirection = pump.PumpDirection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ApplySimulationResults()
|
||||||
|
{
|
||||||
|
// Aplicar resultados al objeto WPF
|
||||||
|
if (WpfObject is IHydraulicPump pump)
|
||||||
|
{
|
||||||
|
pump.SetFlow(CurrentFlow);
|
||||||
|
pump.SetPressure(CurrentPressure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Representa un tanque hidráulico en la simulación
|
||||||
|
/// </summary>
|
||||||
|
public class simHydraulicTank : simHydraulicBase
|
||||||
|
{
|
||||||
|
public double TankPressure { get; set; }
|
||||||
|
public double CurrentLevel { get; set; }
|
||||||
|
public double MaxLevel { get; set; }
|
||||||
|
public double MinLevel { get; set; }
|
||||||
|
public double CrossSectionalArea { get; set; }
|
||||||
|
public bool IsFixedPressure { get; set; }
|
||||||
|
|
||||||
|
// Resultados de la simulación
|
||||||
|
public double InletFlow { get; set; }
|
||||||
|
public double OutletFlow { get; set; }
|
||||||
|
public double CurrentPressure { get; set; }
|
||||||
|
|
||||||
|
public simHydraulicTank(HydraulicSimulationManager hydraulicManager) : base(hydraulicManager)
|
||||||
|
{
|
||||||
|
SimObjectType = "HydraulicTank";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateProperties()
|
||||||
|
{
|
||||||
|
// Actualizar propiedades específicas del tanque
|
||||||
|
if (WpfObject is osHydTank tank)
|
||||||
|
{
|
||||||
|
TankPressure = tank.TankPressure;
|
||||||
|
CurrentLevel = tank.CurrentLevel;
|
||||||
|
MaxLevel = tank.MaxLevel;
|
||||||
|
MinLevel = tank.MinLevel;
|
||||||
|
CrossSectionalArea = tank.CrossSectionalArea;
|
||||||
|
IsFixedPressure = tank.IsFixedPressure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ApplySimulationResults()
|
||||||
|
{
|
||||||
|
// Aplicar resultados al objeto WPF
|
||||||
|
if (WpfObject is IHydraulicFlowReceiver flowReceiver)
|
||||||
|
{
|
||||||
|
flowReceiver.SetFlow(InletFlow - OutletFlow); // Flujo neto
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WpfObject is IHydraulicPressureReceiver pressureReceiver)
|
||||||
|
{
|
||||||
|
pressureReceiver.SetPressure(CurrentPressure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Representa una tubería hidráulica en la simulación
|
||||||
|
/// </summary>
|
||||||
|
public class simHydraulicPipe : simHydraulicBase
|
||||||
|
{
|
||||||
|
public double Length { get; set; }
|
||||||
|
public double Diameter { get; set; }
|
||||||
|
public double Roughness { get; set; }
|
||||||
|
public string ComponenteAId { get; set; }
|
||||||
|
public string ComponenteBId { get; set; }
|
||||||
|
|
||||||
|
// Resultados de la simulación
|
||||||
|
public double CurrentFlow { get; set; }
|
||||||
|
public double PressureDrop { get; set; }
|
||||||
|
|
||||||
|
public simHydraulicPipe(HydraulicSimulationManager hydraulicManager) : base(hydraulicManager)
|
||||||
|
{
|
||||||
|
SimObjectType = "HydraulicPipe";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateProperties()
|
||||||
|
{
|
||||||
|
// Actualizar propiedades específicas de la tubería
|
||||||
|
if (WpfObject is IHydraulicPipe pipe)
|
||||||
|
{
|
||||||
|
Length = pipe.Length;
|
||||||
|
Diameter = pipe.Diameter;
|
||||||
|
Roughness = pipe.Roughness;
|
||||||
|
// Obtener IDs de componentes conectados (esto se manejará en el manager)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ApplySimulationResults()
|
||||||
|
{
|
||||||
|
// Aplicar resultados al objeto WPF
|
||||||
|
if (WpfObject is IHydraulicPipe pipe)
|
||||||
|
{
|
||||||
|
pipe.SetFlow(CurrentFlow);
|
||||||
|
pipe.SetPressure(PressureDrop); // En tuberías, "presión" es la pérdida de presión
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -813,7 +813,7 @@ namespace CtrEditor
|
||||||
if (userControl != null)
|
if (userControl != null)
|
||||||
{
|
{
|
||||||
// Asignar los datos al UserControl
|
// Asignar los datos al UserControl
|
||||||
UserControlFactory.AssignDatos(userControl, osObjeto, simulationManager);
|
UserControlFactory.AssignDatos(userControl, osObjeto, simulationManager, hydraulicSimulationManager);
|
||||||
osObjeto._mainViewModel = this;
|
osObjeto._mainViewModel = this;
|
||||||
if (osObjeto.Id == null) // Para los objetos salvados antes de usar UniqueID
|
if (osObjeto.Id == null) // Para los objetos salvados antes de usar UniqueID
|
||||||
osObjeto.Id = new UniqueId().ObtenerNuevaID();
|
osObjeto.Id = new UniqueId().ObtenerNuevaID();
|
||||||
|
|
|
@ -971,7 +971,37 @@ namespace CtrEditor
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var serializedData = JsonConvert.SerializeObject(original, settings);
|
var serializedData = JsonConvert.SerializeObject(original, settings);
|
||||||
|
Debug.WriteLine($"CreateCopyUsingExistingLogic - Serialized data: {serializedData}");
|
||||||
|
|
||||||
copy = JsonConvert.DeserializeObject<osBase>(serializedData, settings);
|
copy = JsonConvert.DeserializeObject<osBase>(serializedData, settings);
|
||||||
|
|
||||||
|
if (copy == null)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"CreateCopyUsingExistingLogic - Deserialización devolvió null para tipo: {original.GetType().Name}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"CreateCopyUsingExistingLogic - Copia exitosa de tipo: {copy.GetType().Name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (JsonSerializationException jsonEx)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"CreateCopyUsingExistingLogic - Error de serialización JSON: {jsonEx.Message}");
|
||||||
|
Debug.WriteLine($"CreateCopyUsingExistingLogic - StackTrace: {jsonEx.StackTrace}");
|
||||||
|
if (jsonEx.InnerException != null)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"CreateCopyUsingExistingLogic - Inner Exception: {jsonEx.InnerException.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"CreateCopyUsingExistingLogic - Error general: {ex.Message}");
|
||||||
|
Debug.WriteLine($"CreateCopyUsingExistingLogic - Tipo de excepción: {ex.GetType().Name}");
|
||||||
|
Debug.WriteLine($"CreateCopyUsingExistingLogic - StackTrace: {ex.StackTrace}");
|
||||||
|
if (ex.InnerException != null)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"CreateCopyUsingExistingLogic - Inner Exception: {ex.InnerException.Message}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,13 +12,15 @@ using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using LibS7Adv;
|
using LibS7Adv;
|
||||||
|
|
||||||
namespace CtrEditor.ObjetosSim.HydraulicComponents
|
namespace CtrEditor.ObjetosSim
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tubería hidráulica que conecta componentes del sistema hidráulico
|
/// Tubería hidráulica que conecta componentes del sistema hidráulico
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class osHydPipe : osBase, IHydraulicPipe, IosBase
|
public partial class osHydPipe : osBase, IHydraulicFlowReceiver, IHydraulicPressureReceiver, IosBase
|
||||||
{
|
{
|
||||||
|
// Referencia al objeto de simulación hidráulica específico
|
||||||
|
private simHydraulicPipe SimHydraulicPipe;
|
||||||
// Properties
|
// Properties
|
||||||
|
|
||||||
private double _length = 1.0; // metros
|
private double _length = 1.0; // metros
|
||||||
|
@ -396,9 +398,59 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
|
|
||||||
public override void UpdateGeometryStart()
|
public override void UpdateGeometryStart()
|
||||||
{
|
{
|
||||||
|
// Se llama cuando inicia la simulación - crear objeto hidráulico si no existe
|
||||||
|
if (SimHydraulicPipe == null && !string.IsNullOrEmpty(Id_ComponenteA) && !string.IsNullOrEmpty(Id_ComponenteB))
|
||||||
|
{
|
||||||
|
SimHydraulicPipe = hydraulicSimulationManager.AddPipe(Length, Diameter, Roughness, Id_ComponenteA, Id_ComponenteB);
|
||||||
|
SimHydraulicPipe.SimObjectType = "HydraulicPipe";
|
||||||
|
SimHydraulicPipe.WpfObject = this;
|
||||||
|
SimHydraulicPipe.Nombre = Nombre;
|
||||||
|
}
|
||||||
|
else if (SimHydraulicPipe != null)
|
||||||
|
{
|
||||||
|
// Actualizar propiedades si el objeto ya existe
|
||||||
|
SimHydraulicPipe.Length = Length;
|
||||||
|
SimHydraulicPipe.Diameter = Diameter;
|
||||||
|
SimHydraulicPipe.Roughness = Roughness;
|
||||||
|
SimHydraulicPipe.ComponenteAId = Id_ComponenteA;
|
||||||
|
SimHydraulicPipe.ComponenteBId = Id_ComponenteB;
|
||||||
|
}
|
||||||
|
|
||||||
ActualizarGeometrias();
|
ActualizarGeometrias();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void UpdateGeometryStep()
|
||||||
|
{
|
||||||
|
// Los objetos hidráulicos actualizan sus resultados
|
||||||
|
// a través de ApplySimulationResults() desde HydraulicSimulationManager
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateControl(int elapsedMilliseconds)
|
||||||
|
{
|
||||||
|
// Actualizar propiedades desde la simulación hidráulica
|
||||||
|
if (SimHydraulicPipe != null)
|
||||||
|
{
|
||||||
|
CurrentFlow = SimHydraulicPipe.CurrentFlow;
|
||||||
|
PressureDrop = SimHydraulicPipe.PressureDrop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ucLoaded()
|
||||||
|
{
|
||||||
|
// Objeto hidráulico se crea en UpdateGeometryStart cuando inicia la simulación
|
||||||
|
base.ucLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ucUnLoaded()
|
||||||
|
{
|
||||||
|
// Remover objeto hidráulico de la simulación
|
||||||
|
if (SimHydraulicPipe != null)
|
||||||
|
{
|
||||||
|
hydraulicSimulationManager.Remove(SimHydraulicPipe);
|
||||||
|
SimHydraulicPipe = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
|
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
|
||||||
{
|
{
|
||||||
// Las tuberías no tienen control PLC directo
|
// Las tuberías no tienen control PLC directo
|
||||||
|
|
|
@ -11,13 +11,16 @@ using Newtonsoft.Json;
|
||||||
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
namespace CtrEditor.ObjetosSim.HydraulicComponents
|
namespace CtrEditor.ObjetosSim
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Bomba hidráulica que implementa las interfaces del simulador hidráulico
|
/// Bomba hidráulica que implementa las interfaces del simulador hidráulico
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class osHydPump : osBase, IHydraulicPump, IosBase
|
public partial class osHydPump : osBase, IHydraulicFlowReceiver, IHydraulicPressureReceiver, IosBase
|
||||||
{
|
{
|
||||||
|
// Referencia al objeto de simulación hidráulica específico
|
||||||
|
private simHydraulicPump SimHydraulicPump;
|
||||||
|
|
||||||
public static string NombreCategoria() => "Componentes Hidráulicos";
|
public static string NombreCategoria() => "Componentes Hidráulicos";
|
||||||
|
|
||||||
public static string NombreClase()
|
public static string NombreClase()
|
||||||
|
@ -206,35 +209,62 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
|
|
||||||
public override void UpdateGeometryStart()
|
public override void UpdateGeometryStart()
|
||||||
{
|
{
|
||||||
// Los objetos hidráulicos se registran automáticamente
|
// Se llama cuando inicia la simulación - crear objeto hidráulico si no existe
|
||||||
// cuando inicia la simulación a través de las interfaces
|
if (SimHydraulicPump == null)
|
||||||
|
{
|
||||||
|
SimHydraulicPump = hydraulicSimulationManager.AddPump(PumpHead, MaxFlow, SpeedRatio, IsRunning, PumpDirection);
|
||||||
|
SimHydraulicPump.SimObjectType = "HydraulicPump";
|
||||||
|
SimHydraulicPump.WpfObject = this;
|
||||||
|
SimHydraulicPump.Nombre = Nombre;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Actualizar propiedades si el objeto ya existe
|
||||||
|
SimHydraulicPump.PumpHead = PumpHead;
|
||||||
|
SimHydraulicPump.MaxFlow = MaxFlow;
|
||||||
|
SimHydraulicPump.SpeedRatio = SpeedRatio;
|
||||||
|
SimHydraulicPump.IsRunning = IsRunning;
|
||||||
|
SimHydraulicPump.PumpDirection = PumpDirection;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateGeometryStep()
|
public override void UpdateGeometryStep()
|
||||||
{
|
{
|
||||||
// Los objetos hidráulicos actualizan sus resultados
|
// Los objetos hidráulicos actualizan sus resultados
|
||||||
// a través de ApplyHydraulicResults()
|
// a través de ApplySimulationResults() desde HydraulicSimulationManager
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateControl(int elapsedMilliseconds)
|
public override void UpdateControl(int elapsedMilliseconds)
|
||||||
{
|
{
|
||||||
// Actualizar el color según el estado
|
// Actualizar propiedades desde la simulación hidráulica
|
||||||
if (IsRunning)
|
if (SimHydraulicPump != null)
|
||||||
ColorButton_oculto = Brushes.Green;
|
{
|
||||||
else
|
CurrentFlow = SimHydraulicPump.CurrentFlow;
|
||||||
ColorButton_oculto = Brushes.Gray;
|
CurrentPressure = SimHydraulicPump.CurrentPressure;
|
||||||
|
|
||||||
|
// Actualizar el color según el estado
|
||||||
|
if (IsRunning)
|
||||||
|
ColorButton_oculto = Brushes.Green;
|
||||||
|
else
|
||||||
|
ColorButton_oculto = Brushes.Gray;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ucLoaded()
|
public override void ucLoaded()
|
||||||
{
|
{
|
||||||
// Los objetos hidráulicos no necesitan geometría física
|
// Objeto hidráulico se crea en UpdateGeometryStart cuando inicia la simulación
|
||||||
base.ucLoaded();
|
base.ucLoaded();
|
||||||
UpdatePumpImage();
|
UpdatePumpImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ucUnLoaded()
|
public override void ucUnLoaded()
|
||||||
{
|
{
|
||||||
// Los objetos hidráulicos no tienen geometría que limpiar
|
// Remover objeto hidráulico de la simulación
|
||||||
|
if (SimHydraulicPump != null)
|
||||||
|
{
|
||||||
|
hydraulicSimulationManager.Remove(SimHydraulicPump);
|
||||||
|
SimHydraulicPump = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -368,23 +398,13 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
return CurrentPressure;
|
return CurrentPressure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Helper Methods
|
// Helper Methods
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invalida la red hidráulica para forzar reconstrucción
|
|
||||||
/// </summary>
|
|
||||||
private void InvalidateHydraulicNetwork()
|
private void InvalidateHydraulicNetwork()
|
||||||
{
|
{
|
||||||
// Si tenemos acceso al MainViewModel, invalidar la red
|
hydraulicSimulationManager?.InvalidateNetwork();
|
||||||
if (_mainViewModel?.hydraulicSimulationManager != null)
|
|
||||||
{
|
|
||||||
_mainViewModel.hydraulicSimulationManager.InvalidateNetwork();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -13,13 +13,15 @@ using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using LibS7Adv;
|
using LibS7Adv;
|
||||||
|
|
||||||
namespace CtrEditor.ObjetosSim.HydraulicComponents
|
namespace CtrEditor.ObjetosSim
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tanque hidráulico con gestión dinámica de nivel y presión configurable
|
/// Tanque hidráulico con gestión dinámica de nivel y presión configurable
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class osHydTank : osBase, IHydraulicComponent, IHydraulicFlowReceiver, IHydraulicPressureReceiver, IosBase
|
public partial class osHydTank : osBase, IHydraulicFlowReceiver, IHydraulicPressureReceiver, IosBase
|
||||||
{
|
{
|
||||||
|
// Referencia al objeto de simulación hidráulica específico
|
||||||
|
private simHydraulicTank SimHydraulicTank;
|
||||||
public static string NombreCategoria() => "Componentes Hidráulicos";
|
public static string NombreCategoria() => "Componentes Hidráulicos";
|
||||||
|
|
||||||
public static string NombreClase() => "Tanque Hidráulico";
|
public static string NombreClase() => "Tanque Hidráulico";
|
||||||
|
@ -63,13 +65,6 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
[property: JsonIgnore]
|
|
||||||
[property: Category("Apariencia")]
|
|
||||||
[property: Description("Imagen visual")]
|
|
||||||
[property: Name("Imagen")]
|
|
||||||
public ImageSource imageSource_oculta;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
[property: Category("🎨 Apariencia")]
|
[property: Category("🎨 Apariencia")]
|
||||||
[property: Description("Tamaño visual del tanque")]
|
[property: Description("Tamaño visual del tanque")]
|
||||||
|
@ -88,25 +83,37 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
// Constructor
|
// Constructor
|
||||||
public osHydTank()
|
public osHydTank()
|
||||||
{
|
{
|
||||||
Nombre = "Tanque Hidráulico";
|
// Inicializar el lock primero para thread safety
|
||||||
Tamano = 1.0f; // Usar un tamaño mayor para mayor visibilidad
|
|
||||||
// Inicializar dimensiones usando las propiedades de osBase
|
|
||||||
Ancho = 0.30f;
|
|
||||||
Alto = 0.40f;
|
|
||||||
Angulo = 0f;
|
|
||||||
// Asegurar que el movimiento esté habilitado
|
|
||||||
Lock_movement = false;
|
|
||||||
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();
|
EnsureLockInitialized();
|
||||||
|
|
||||||
// Debug: Confirmar que el constructor se ejecuta
|
try
|
||||||
Debug.WriteLine($"osHydTank Constructor: Nombre='{Nombre}', Tamaño={Tamano}, ZIndex={zIndex_fromFrames}, IsVisFilter={IsVisFilter}, Lock_movement={Lock_movement}");
|
{
|
||||||
|
Nombre = "Tanque Hidráulico";
|
||||||
|
Tamano = 1.0f; // Usar un tamaño mayor para mayor visibilidad
|
||||||
|
// Inicializar dimensiones usando las propiedades de osBase
|
||||||
|
Ancho = 0.30f;
|
||||||
|
Alto = 0.40f;
|
||||||
|
Angulo = 0f;
|
||||||
|
// Asegurar que el movimiento esté habilitado
|
||||||
|
Lock_movement = false;
|
||||||
|
|
||||||
|
// No cargar imagen aquí - se carga en ucLoaded()
|
||||||
|
// para evitar problemas de serialización
|
||||||
|
|
||||||
|
// Cálculos seguros
|
||||||
|
SafeUpdateVolumeCalculations();
|
||||||
|
IsVisFilter = true; // Asegurar que el componente hidráulico sea visible en filtros
|
||||||
|
SafeUpdateTankPressure();
|
||||||
|
|
||||||
|
// 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}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"Error in osHydTank constructor: {ex.Message}");
|
||||||
|
// Inicializar valores por defecto mínimos
|
||||||
|
InitializeDefaults();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -137,18 +144,49 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
|
|
||||||
public override void UpdateGeometryStart()
|
public override void UpdateGeometryStart()
|
||||||
{
|
{
|
||||||
// Los objetos hidráulicos se registran automáticamente
|
// Se llama cuando inicia la simulación - crear objeto hidráulico si no existe
|
||||||
// cuando inicia la simulación a través de las interfaces
|
if (SimHydraulicTank == null)
|
||||||
|
{
|
||||||
|
SimHydraulicTank = hydraulicSimulationManager.AddTank(TankPressure, CurrentLevel, MaxLevel, MinLevel, CrossSectionalArea, IsFixedPressure);
|
||||||
|
SimHydraulicTank.SimObjectType = "HydraulicTank";
|
||||||
|
SimHydraulicTank.WpfObject = this;
|
||||||
|
SimHydraulicTank.Nombre = Nombre;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Actualizar propiedades si el objeto ya existe
|
||||||
|
SimHydraulicTank.TankPressure = TankPressure;
|
||||||
|
SimHydraulicTank.CurrentLevel = CurrentLevel;
|
||||||
|
SimHydraulicTank.MaxLevel = MaxLevel;
|
||||||
|
SimHydraulicTank.MinLevel = MinLevel;
|
||||||
|
SimHydraulicTank.CrossSectionalArea = CrossSectionalArea;
|
||||||
|
SimHydraulicTank.IsFixedPressure = IsFixedPressure;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateGeometryStep()
|
public override void UpdateGeometryStep()
|
||||||
{
|
{
|
||||||
// Los objetos hidráulicos actualizan sus resultados
|
// Los objetos hidráulicos actualizan sus resultados
|
||||||
// a través de ApplyHydraulicResults()
|
// a través de ApplySimulationResults() desde HydraulicSimulationManager
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateControl(int elapsedMilliseconds)
|
public override void UpdateControl(int elapsedMilliseconds)
|
||||||
{
|
{
|
||||||
|
// Actualizar propiedades desde la simulación hidráulica
|
||||||
|
if (SimHydraulicTank != null)
|
||||||
|
{
|
||||||
|
InletFlow = SimHydraulicTank.InletFlow;
|
||||||
|
OutletFlow = SimHydraulicTank.OutletFlow;
|
||||||
|
CurrentPressure = SimHydraulicTank.CurrentPressure;
|
||||||
|
|
||||||
|
// Actualizar nivel del tanque basado en el balance de flujo
|
||||||
|
double deltaTime = elapsedMilliseconds / 1000.0; // Convertir a segundos
|
||||||
|
if (deltaTime > 0)
|
||||||
|
{
|
||||||
|
UpdateLevelFromFlowBalance(deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Actualizar el color según el estado del tanque
|
// Actualizar el color según el estado del tanque
|
||||||
var percentage = FillPercentage;
|
var percentage = FillPercentage;
|
||||||
if (percentage < 20)
|
if (percentage < 20)
|
||||||
|
@ -191,7 +229,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
{
|
{
|
||||||
if (SetProperty(ref _crossSectionalArea, Math.Max(0.1, value)))
|
if (SetProperty(ref _crossSectionalArea, Math.Max(0.1, value)))
|
||||||
{
|
{
|
||||||
UpdateVolumeCalculations();
|
SafeUpdateVolumeCalculations();
|
||||||
InvalidateHydraulicNetwork();
|
InvalidateHydraulicNetwork();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,7 +247,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
{
|
{
|
||||||
if (_currentLevel > _maxLevel)
|
if (_currentLevel > _maxLevel)
|
||||||
CurrentLevel = _maxLevel;
|
CurrentLevel = _maxLevel;
|
||||||
UpdateVolumeCalculations();
|
SafeUpdateVolumeCalculations();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +264,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
{
|
{
|
||||||
if (_currentLevel < _minLevel)
|
if (_currentLevel < _minLevel)
|
||||||
CurrentLevel = _minLevel;
|
CurrentLevel = _minLevel;
|
||||||
UpdateVolumeCalculations();
|
SafeUpdateVolumeCalculations();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,7 +283,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
{
|
{
|
||||||
if (SetProperty(ref _isFixedPressure, value))
|
if (SetProperty(ref _isFixedPressure, value))
|
||||||
{
|
{
|
||||||
UpdateTankPressure();
|
SafeUpdateTankPressure();
|
||||||
InvalidateHydraulicNetwork();
|
InvalidateHydraulicNetwork();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,7 +299,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
{
|
{
|
||||||
if (SetProperty(ref _tankPressure, Math.Max(0, value)))
|
if (SetProperty(ref _tankPressure, Math.Max(0, value)))
|
||||||
{
|
{
|
||||||
UpdateTankPressure();
|
SafeUpdateTankPressure();
|
||||||
InvalidateHydraulicNetwork();
|
InvalidateHydraulicNetwork();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,7 +334,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
var clampedLevel = Math.Max(_minLevel, Math.Min(_maxLevel, value));
|
var clampedLevel = Math.Max(_minLevel, Math.Min(_maxLevel, value));
|
||||||
if (SetProperty(ref _currentLevel, clampedLevel))
|
if (SetProperty(ref _currentLevel, clampedLevel))
|
||||||
{
|
{
|
||||||
UpdateVolumeCalculations();
|
SafeUpdateVolumeCalculations();
|
||||||
OnPropertyChanged(nameof(FillPercentage));
|
OnPropertyChanged(nameof(FillPercentage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -442,8 +480,8 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
public void UpdateHydraulicProperties()
|
public void UpdateHydraulicProperties()
|
||||||
{
|
{
|
||||||
// Actualizar propiedades antes de la simulación
|
// Actualizar propiedades antes de la simulación
|
||||||
UpdateTankPressure();
|
SafeUpdateTankPressure();
|
||||||
UpdateVolumeCalculations();
|
SafeUpdateVolumeCalculations();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyHydraulicResults(Dictionary<string, double> flows, Dictionary<string, double> pressures)
|
public void ApplyHydraulicResults(Dictionary<string, double> flows, Dictionary<string, double> pressures)
|
||||||
|
@ -588,6 +626,67 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
|
|
||||||
// Private Methods
|
// Private Methods
|
||||||
|
|
||||||
|
private void InitializeDefaults()
|
||||||
|
{
|
||||||
|
// Valores mínimos para que el objeto sea funcional
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(nombre))
|
||||||
|
nombre = "Tanque Hidráulico";
|
||||||
|
|
||||||
|
if (Tamano <= 0)
|
||||||
|
Tamano = 1.0f;
|
||||||
|
|
||||||
|
if (Ancho <= 0)
|
||||||
|
Ancho = 0.30f;
|
||||||
|
|
||||||
|
if (Alto <= 0)
|
||||||
|
Alto = 0.40f;
|
||||||
|
|
||||||
|
SafeUpdateVolumeCalculations();
|
||||||
|
SafeUpdateTankPressure();
|
||||||
|
|
||||||
|
Debug.WriteLine("osHydTank: Initialized with default values");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"Error in InitializeDefaults: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SafeUpdateVolumeCalculations()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_currentVolume = _currentLevel * _crossSectionalArea;
|
||||||
|
_maxVolume = _maxLevel * _crossSectionalArea;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"Error in SafeUpdateVolumeCalculations: {ex.Message}");
|
||||||
|
// Usar valores por defecto seguros
|
||||||
|
_currentVolume = 1.0;
|
||||||
|
_maxVolume = 2.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SafeUpdateTankPressure()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (IsFixedPressure)
|
||||||
|
{
|
||||||
|
CurrentPressure = TankPressure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"Error in SafeUpdateTankPressure: {ex.Message}");
|
||||||
|
// Usar presión atmosférica por defecto
|
||||||
|
_currentPressure = 101325.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private string GetTankDescription()
|
private string GetTankDescription()
|
||||||
{
|
{
|
||||||
return TankType switch
|
return TankType switch
|
||||||
|
@ -751,15 +850,15 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
// Inicialización del tanque para la simulación
|
// Inicialización del tanque para la simulación
|
||||||
UpdateVolumeCalculations();
|
SafeUpdateVolumeCalculations();
|
||||||
UpdateTankPressure();
|
SafeUpdateTankPressure();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Inicializar(int valorInicial)
|
public void Inicializar(int valorInicial)
|
||||||
{
|
{
|
||||||
// Inicialización con valor inicial
|
// Inicialización con valor inicial
|
||||||
UpdateVolumeCalculations();
|
SafeUpdateVolumeCalculations();
|
||||||
UpdateTankPressure();
|
SafeUpdateTankPressure();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Disposing()
|
public void Disposing()
|
||||||
|
@ -800,9 +899,11 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
// crear el objeto de simulacion
|
// crear el objeto de simulacion
|
||||||
base.ucLoaded();
|
base.ucLoaded();
|
||||||
|
|
||||||
|
Debug.WriteLine($"osHydTank.ucLoaded(): Componente hidráulico cargado correctamente");
|
||||||
|
|
||||||
// Inicialización específica del tanque hidráulico
|
// Inicialización específica del tanque hidráulico
|
||||||
UpdateVolumeCalculations();
|
SafeUpdateVolumeCalculations();
|
||||||
UpdateTankPressure();
|
SafeUpdateTankPressure();
|
||||||
|
|
||||||
// Debug: Confirmar que el UserControl se está cargando
|
// Debug: Confirmar que el UserControl se está cargando
|
||||||
Debug.WriteLine($"osHydTank.ucLoaded(): Tanque '{Nombre}' cargado - Tamaño: {Tamano}, ZIndex: {zIndex_fromFrames}");
|
Debug.WriteLine($"osHydTank.ucLoaded(): Tanque '{Nombre}' cargado - Tamaño: {Tamano}, ZIndex: {zIndex_fromFrames}");
|
||||||
|
@ -810,7 +911,12 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||||
|
|
||||||
public override void ucUnLoaded()
|
public override void ucUnLoaded()
|
||||||
{
|
{
|
||||||
// Los tanques hidráulicos no tienen geometría que limpiar
|
// Remover objeto hidráulico de la simulación
|
||||||
|
if (SimHydraulicTank != null)
|
||||||
|
{
|
||||||
|
hydraulicSimulationManager.Remove(SimHydraulicTank);
|
||||||
|
SimHydraulicTank = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<UserControl x:Class="CtrEditor.ObjetosSim.HydraulicComponents.ucHydPipe"
|
<UserControl x:Class="CtrEditor.ObjetosSim.ucHydPipe"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim.HydraulicComponents"
|
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
|
||||||
<UserControl.DataContext>
|
<UserControl.DataContext>
|
||||||
|
|
|
@ -4,7 +4,7 @@ using System.Windows;
|
||||||
using CtrEditor.ObjetosSim;
|
using CtrEditor.ObjetosSim;
|
||||||
using CtrEditor.FuncionesBase;
|
using CtrEditor.FuncionesBase;
|
||||||
|
|
||||||
namespace CtrEditor.ObjetosSim.HydraulicComponents
|
namespace CtrEditor.ObjetosSim
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for ucHydPipe.xaml
|
/// Interaction logic for ucHydPipe.xaml
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<UserControl x:Class="CtrEditor.ObjetosSim.HydraulicComponents.ucHydPump"
|
<UserControl x:Class="CtrEditor.ObjetosSim.ucHydPump"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:CtrEditor.ObjetosSim"
|
xmlns:local="clr-namespace:CtrEditor.ObjetosSim"
|
||||||
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim.HydraulicComponents"
|
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
|
||||||
<!-- DataContext se establece desde el objeto padre, no aquí -->
|
<!-- DataContext se establece desde el objeto padre, no aquí -->
|
||||||
|
|
|
@ -6,7 +6,7 @@ using System.Windows.Media;
|
||||||
using CtrEditor.ObjetosSim;
|
using CtrEditor.ObjetosSim;
|
||||||
using CtrEditor.FuncionesBase;
|
using CtrEditor.FuncionesBase;
|
||||||
|
|
||||||
namespace CtrEditor.ObjetosSim.HydraulicComponents
|
namespace CtrEditor.ObjetosSim
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// UserControl para la bomba hidráulica
|
/// UserControl para la bomba hidráulica
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<UserControl x:Class="CtrEditor.ObjetosSim.HydraulicComponents.ucHydTank"
|
<UserControl x:Class="CtrEditor.ObjetosSim.ucHydTank"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:CtrEditor.ObjetosSim"
|
xmlns:local="clr-namespace:CtrEditor.ObjetosSim"
|
||||||
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim.HydraulicComponents"
|
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
|
||||||
<!-- DataContext se establece desde el objeto padre, no aquí -->
|
<!-- DataContext se establece desde el objeto padre, no aquí -->
|
||||||
|
|
|
@ -8,7 +8,7 @@ using System.Diagnostics;
|
||||||
using CtrEditor.ObjetosSim;
|
using CtrEditor.ObjetosSim;
|
||||||
using CtrEditor.FuncionesBase;
|
using CtrEditor.FuncionesBase;
|
||||||
|
|
||||||
namespace CtrEditor.ObjetosSim.HydraulicComponents
|
namespace CtrEditor.ObjetosSim
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// UserControl para el tanque hidráulico osHydTank
|
/// UserControl para el tanque hidráulico osHydTank
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
using CtrEditor.HydraulicSimulator;
|
||||||
using CtrEditor.Simulacion;
|
using CtrEditor.Simulacion;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System;
|
using System;
|
||||||
|
@ -77,7 +78,7 @@ namespace CtrEditor.ObjetosSim
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AssignDatos(UserControl userControl, osBase datos, SimulationManagerBEPU simulationManager)
|
public static void AssignDatos(UserControl userControl, osBase datos, SimulationManagerBEPU simulationManager, HydraulicSimulationManager hydraulicSimulationManager = null)
|
||||||
{
|
{
|
||||||
if (userControl is IDataContainer dataContainer)
|
if (userControl is IDataContainer dataContainer)
|
||||||
{
|
{
|
||||||
|
@ -85,6 +86,7 @@ namespace CtrEditor.ObjetosSim
|
||||||
userControl.DataContext = datos;
|
userControl.DataContext = datos;
|
||||||
datos.VisualRepresentation = userControl;
|
datos.VisualRepresentation = userControl;
|
||||||
datos.simulationManager = simulationManager;
|
datos.simulationManager = simulationManager;
|
||||||
|
datos.hydraulicSimulationManager = hydraulicSimulationManager;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CtrEditor.FuncionesBase;
|
using CtrEditor.FuncionesBase;
|
||||||
|
using CtrEditor.HydraulicSimulator;
|
||||||
using CtrEditor.Serialization;
|
using CtrEditor.Serialization;
|
||||||
using CtrEditor.Services;
|
using CtrEditor.Services;
|
||||||
using CtrEditor.Simulacion;
|
using CtrEditor.Simulacion;
|
||||||
|
@ -45,19 +46,22 @@ namespace CtrEditor.ObjetosSim
|
||||||
private MainViewModel? _mainViewModel;
|
private MainViewModel? _mainViewModel;
|
||||||
private UserControl? VisualRepresentation;
|
private UserControl? VisualRepresentation;
|
||||||
private SimulationManagerBEPU? simulationManager;
|
private SimulationManagerBEPU? simulationManager;
|
||||||
|
private HydraulicSimulationManager? hydraulicSimulationManager;
|
||||||
|
|
||||||
public DataSaveToSerialize(MainViewModel a, UserControl b, SimulationManagerBEPU c)
|
public DataSaveToSerialize(MainViewModel a, UserControl b, SimulationManagerBEPU c, HydraulicSimulationManager d = null)
|
||||||
{
|
{
|
||||||
_mainViewModel = a;
|
_mainViewModel = a;
|
||||||
VisualRepresentation = b;
|
VisualRepresentation = b;
|
||||||
simulationManager = c;
|
simulationManager = c;
|
||||||
|
hydraulicSimulationManager = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DataRestoreAfterSerialize(out MainViewModel a, out UserControl b, out SimulationManagerBEPU c)
|
public void DataRestoreAfterSerialize(out MainViewModel a, out UserControl b, out SimulationManagerBEPU c, out HydraulicSimulationManager d)
|
||||||
{
|
{
|
||||||
a = _mainViewModel;
|
a = _mainViewModel;
|
||||||
b = VisualRepresentation;
|
b = VisualRepresentation;
|
||||||
c = simulationManager;
|
c = simulationManager;
|
||||||
|
d = hydraulicSimulationManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1054,16 +1058,23 @@ namespace CtrEditor.ObjetosSim
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public SimulationManagerBEPU simulationManager;
|
public SimulationManagerBEPU simulationManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Link al Simulador hidráulico.
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public HydraulicSimulationManager hydraulicSimulationManager;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Prepara la clase para ser serializable poniendo a null los objetos que tienen referencias circulares
|
/// Prepara la clase para ser serializable poniendo a null los objetos que tienen referencias circulares
|
||||||
/// Luego se debe llamar a RestaurarDatosNoSerializables para restaurar el estado original
|
/// Luego se debe llamar a RestaurarDatosNoSerializables para restaurar el estado original
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SalvarDatosNoSerializables()
|
public void SalvarDatosNoSerializables()
|
||||||
{
|
{
|
||||||
DataSave = new DataSaveToSerialize(_mainViewModel, _visualRepresentation, simulationManager);
|
DataSave = new DataSaveToSerialize(_mainViewModel, _visualRepresentation, simulationManager, hydraulicSimulationManager);
|
||||||
_mainViewModel = null;
|
_mainViewModel = null;
|
||||||
_visualRepresentation = null;
|
_visualRepresentation = null;
|
||||||
simulationManager = null;
|
simulationManager = null;
|
||||||
|
hydraulicSimulationManager = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1072,7 +1083,7 @@ namespace CtrEditor.ObjetosSim
|
||||||
public void RestaurarDatosNoSerializables()
|
public void RestaurarDatosNoSerializables()
|
||||||
{
|
{
|
||||||
if (DataSave == null) return;
|
if (DataSave == null) return;
|
||||||
DataSave.DataRestoreAfterSerialize(out _mainViewModel, out _visualRepresentation, out simulationManager);
|
DataSave.DataRestoreAfterSerialize(out _mainViewModel, out _visualRepresentation, out simulationManager, out hydraulicSimulationManager);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Se llama una unica vez al conectar con el PLC.
|
/// Se llama una unica vez al conectar con el PLC.
|
||||||
|
|
Loading…
Reference in New Issue