CtrEditor/HydraulicSimulator/TSNet/Components/TSNetPumpAdapter.cs

156 lines
5.4 KiB
C#

using System;
using System.Collections.Generic;
using CtrEditor.ObjetosSim;
namespace CtrEditor.HydraulicSimulator.TSNet.Components
{
/// <summary>
/// Adaptador simplificado para osHydPump - SOLO lectura de configuración y almacenamiento de resultados
/// Los valores se capturan al INICIAR la simulación y no se modifican durante la ejecución
/// </summary>
public class TSNetPumpAdapter
{
private readonly osHydPump pump;
private string nodeId;
// Configuración capturada al inicio de simulación (INMUTABLE durante simulación)
public PumpConfiguration Configuration { get; private set; }
// Resultados calculados por TSNet (SOLO escritura desde TSNet)
public TSNetPumpResults Results { get; private set; }
public TSNetPumpAdapter(osHydPump pump)
{
this.pump = pump ?? throw new ArgumentNullException(nameof(pump));
// Validación defensiva para Id
if (pump.Id == null)
{
throw new InvalidOperationException($"La bomba '{pump.Nombre ?? "sin nombre"}' no tiene un Id válido");
}
this.nodeId = $"PUMP_{pump.Id.Value}";
this.Results = new TSNetPumpResults { PumpId = nodeId };
}
/// <summary>
/// ID único del nodo de bomba para TSNet
/// </summary>
public string NodeId => nodeId;
/// <summary>
/// Captura la configuración actual de la bomba al INICIO de la simulación
/// Esta configuración queda CONGELADA hasta que se detenga y reinicie la simulación
/// </summary>
public void CaptureConfigurationForSimulation()
{
Configuration = new PumpConfiguration
{
PumpId = nodeId,
PumpHead = pump.PumpHead,
MaxFlow = pump.MaxFlow,
SpeedRatio = pump.SpeedRatio,
IsRunning = pump.IsRunning,
PumpDirection = pump.PumpDirection.ToString(), // Convertir int a string
Position = new PumpPosition { X = pump.Left, Y = pump.Top },
CapturedAt = DateTime.Now
};
}
/// <summary>
/// Resetea los resultados (para nueva simulación)
/// </summary>
public void ResetCalculatedValues()
{
Results = new TSNetPumpResults { PumpId = nodeId };
}
/// <summary>
/// Validación de configuración capturada
/// </summary>
public List<string> ValidateConfiguration()
{
var errors = new List<string>();
if (Configuration == null)
{
errors.Add($"Bomba {NodeId}: Configuración no capturada");
return errors;
}
if (Configuration.PumpHead <= 0)
errors.Add($"Bomba {NodeId}: PumpHead debe ser mayor que 0");
if (Configuration.MaxFlow <= 0)
errors.Add($"Bomba {NodeId}: MaxFlow debe ser mayor que 0");
if (Configuration.SpeedRatio < 0 || Configuration.SpeedRatio > 1)
errors.Add($"Bomba {NodeId}: SpeedRatio debe estar entre 0 y 1");
return errors;
}
public override string ToString()
{
var configStatus = Configuration != null ? "Configured" : "Not Configured";
var resultStatus = Results?.OperationalStatus ?? "No Results";
return $"TSNetPumpAdapter[{NodeId}] - Config: {configStatus}, Results: {resultStatus}";
}
/// <summary>
/// Aplica los resultados de TSNet a la bomba
/// </summary>
public void ApplyTSNetResults(Dictionary<string, double> flows, Dictionary<string, double> pressures)
{
if (Results == null) return;
try
{
// Actualizar resultados desde los diccionarios de TSNet
if (flows.ContainsKey(NodeId))
{
Results.CalculatedFlowM3s = flows[NodeId];
Results.CalculatedFlowLMin = flows[NodeId] * 60000; // m³/s a L/min
}
if (pressures.ContainsKey(NodeId))
{
Results.OutletPressureBar = pressures[NodeId] / 100000.0; // Pa a bar
}
Results.Timestamp = DateTime.Now;
Results.OperationalStatus = "Updated from TSNet";
}
catch (Exception ex)
{
Results.OperationalStatus = $"Error: {ex.Message}";
}
}
}
/// <summary>
/// Configuración inmutable de la bomba capturada al inicio de simulación
/// </summary>
public class PumpConfiguration
{
public string PumpId { get; set; }
public DateTime CapturedAt { get; set; }
// Propiedades de la bomba
public double PumpHead { get; set; }
public double MaxFlow { get; set; }
public double SpeedRatio { get; set; }
public bool IsRunning { get; set; }
public string PumpDirection { get; set; }
public PumpPosition Position { get; set; }
}
/// <summary>
/// Posición de la bomba en el canvas
/// </summary>
public class PumpPosition
{
public double X { get; set; }
public double Y { get; set; }
}
}