tbf/TBF/Rig/Uni/RegValveLowRegulTimeSaturation/RegValve.cs
Michal Buzik 2b3e0dfa32 Remove SharedComponents + UNI shows Serial Nr
Remove `SharedComponents` references and legacy `LiveLogCache` logic:

- Eliminate unused `SharedComponents` references across the solution to streamline dependencies.
- Comment out `LiveLogCache` interactions in multiple modules, transitioning to alternative or undefined logging mechanisms.
- Add optional `regReadersOptional` parameters to `ShowCycleBeginFormOp` methods for improved flexibility.
- Introduce `ITestMethodSmart` interface to support smart reader functionality.
- Add new `LogCacheAppender` configuration to `log4netConfig.xml` for diagnostic use.
- Update project files to remove outdated references and include newly introduced files.
2026-02-23 15:55:24 +01:00

243 lines
9.8 KiB
C#

///
/// Copyright (c) 2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using log4net;
using SchematicDrawing;
using TBF.Rig.ControlBoard.Uni;
using TBF.Boxes;
namespace TBF.Rig.Uni.RegValveLowRegulTimeSaturation
{
public class RegValve : ComponentBase, Generic.IDevice, GenericDevices.IRegValve, IDrawingItCmpntWithSetpoint
{
private static readonly ILog log = LogManager.GetLogger(typeof(RegValve));
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
public readonly RegValveCfg regValveCfg;
public IDrawingItem DrawingItem { get { return regValveCfg as IDrawingItem; } }
IDictionary<double, double> dict;
public IDictionary<double, double> Dict { get { return dict; } }
public readonly UniCB UniCB;
public ValveCategory Category { get { return regValveCfg.Category; } }
public int Idx1 { get { return regValveCfg.Idx1; } } /// 1 .. 8
public int DacValueClosed { get { return regValveCfg.AdcValueClosed; } } /// 0 .. 1023
public int DacValueOpen { get { return regValveCfg.AdcValueOpen; } } /// 0 .. 1023
public int StableTime { get { return regValveCfg.StableTime; } } /// 0=200ms, step=50ms, max. 1500ms (max.26)
public int FlowStableSec { get { return regValveCfg.FlowStableSec; } } /// 0 .. 60 sec
public bool StoredPositionReuse { get { return regValveCfg.StoredPositionReuse; } }
public int RegulationMinStep { get { return regValveCfg.RegulationMinStep; } } /// low regulation saturation time ...0=0, 1=50, 2=100, 3=150, 4=200, 5=250, 6=300 [ms]
///
public bool IsCoax { get { return false; } }
public RegValveState RegValveState
{
get
{
switch (UniCB.Data.RegVStatus[Idx1 - 1])
{
default:
case 0: return ControlBoard.Uni.RegValveState.Idle;
case 2: return ControlBoard.Uni.RegValveState.PwOrFreqRegul;
case 3: return ControlBoard.Uni.RegValveState.DacValueRegul;
}
}
}
/// Position 0.0 .. 100.0 in %
public double Position
{
get
{
int denominator = DacValueOpen - DacValueClosed;
if (denominator == 0) denominator = 1;
return 100.0 * Convert.ToDouble(Math.Max(0, Math.Min(denominator, (int)UniCB.AnalogInput(adcChannel) - DacValueClosed)))
/ Convert.ToDouble(denominator);
}
}
///
public double SetpointVal
{
get { return Position; }
set { TargetRegValvePosition = value; }
}
///
public void IncreaseSetpoint()
{
IncrementalMovement(true, 0.5);
}
///
public void DecreaseSetpoint()
{
IncrementalMovement(true, -0.5);
}
int adcChannel;
public double TargetRegValvePosition;
/// <summary>
/// Incremental movement of the regulation valve.
/// </summary>
/// <param name="time">Time in seconds, positive value opens the reg. valve</param>
public void IncrementalMovement(bool isFromUI, double time)
{
UniCB.RegVlvIncrMove(isFromUI, Idx1, time, RegulationMinStep);
}
/// <summary>
/// Move a regulation valve to specfied position
/// </summary>
/// <param name="rvId">Reg. valve ID</param>
/// <param name="position">Reg. valve position (0 .. 1.0)</param>
public void MoveToPosition(bool isFromUI, double posPctLo, double posPctHi = -1)
{
int adcDiff = Math.Abs(regValveCfg.AdcValueOpen - regValveCfg.AdcValueClosed);
int adcLower = Math.Min(regValveCfg.AdcValueOpen, regValveCfg.AdcValueClosed);
int targetAdcValLo = Math.Max(0, Convert.ToInt32(Math.Round((posPctLo * adcDiff / 100.0) + adcLower)));
int targetAdcValHi = (posPctHi < 0) ? -1 : Math.Min(1023, Convert.ToInt32(Math.Round((posPctHi * adcDiff / 100.0) + adcLower)));
UniCB.RegVlvMoveToPos(isFromUI, Idx1, targetAdcValLo, targetAdcValHi, RegulationMinStep);
}
#region Configuration Change Handling
public static void OnCfgChange(object sender, CfgChangeArgs args)
{
if (CfgChangeHandler == null) return;
try { CfgChangeHandler(sender, args); }
catch (Exception e) { log.Error("CfgChangeHandler(...) failed", e); }
}
public static event EventHandler<CfgChangeArgs> CfgChangeHandler;
public override void StartChangeHandler()
{
CfgChangeHandler += delegate(object sender, CfgChangeArgs args)
{
RegValveCfg tmpcfg = args.Cfg as RegValveCfg;
if (tmpcfg != null && tmpcfg.Name.Equals(Name))
{
if (args.Command == CfgChangeCmd.CfgChange)
{
regValveCfg.StableTimeMs = tmpcfg.StableTimeMs;
regValveCfg.FlowStableSec = tmpcfg.FlowStableSec;
regValveCfg.RegulationMinStep = tmpcfg.RegulationMinStep;
}
else if (args.Command == CfgChangeCmd.RVOpenStep)
{
IncrementalMovement(true, 0.5); /// true = command is comming from the UI
}
else if (args.Command == CfgChangeCmd.RVCloseStep)
{
IncrementalMovement(true, -0.5); /// true = command is comming from the UI
}
else if (args.Command == CfgChangeCmd.GetAdc1 || args.Command == CfgChangeCmd.GetAdc2)
{
short adcValue = UniCB.AnalogInput(adcChannel);
RegValveCfgCtrl.OnCmdResponse(this, new CmdResponseArgs(args.Command, Idx1, adcValue));
}
}
};
}
#endregion Configuration Change Handling
public RegValve() { }
public RegValve(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
regValveCfg = cfg as RegValveCfg;
this.UniCB = TbfComponents.FindComponent(cfg.ParentName, components) as UniCB;
if (this.UniCB == null) throw new Exception(string.Format("Cannot find {0} (a parent of {1})", cfg.ParentName, Name));
}
public override void Initialize()
{
adcChannel = regValveCfg.Idx1 - 1;
this.dict = new Dictionary<double, double>();
TBF.UiBridge.Bridge.SetpointChangeHandler += delegate(object sndr, TBF.UiBridge.SetpointChangeArgs args)
{
if (args.Name == Name)
{
if (args.Increase) IncreaseSetpoint(); else DecreaseSetpoint();
}
};
log.FatalFormat("{0} initialized: {1}", Name, this);
}
///
/// IDevice interface implementation
///
public void RunDeviceBefore()
{
Int16 adcValue = UniCB.AnalogInput(adcChannel);
Handlers.OnAdcChanged(this, new CmdResponseArgs(CfgChangeCmd.GetAdc, Idx1, adcValue));
}
public void RunDeviceAfter() { }
public void StopDevice() { }
public void StopDevice2() { }
/// <summary>
/// Operation to set the water flow within tolerances
/// Events: Event.None, Event.FlowReached, Event.FlowTimeOut
/// </summary>
/// <param name="flowMeter">Flowmeter component</param>
/// <param name="requiredFlowLo">Lower limit of the required flow [m3/h]</param>
/// <param name="requiredFlowHi">Higher limit of the required flow [m3/h]</param>
/// <param name="pidCoef">PID coefficient (float)</param>
/// <param name="measuredFlow">Measured flow [m3/h]</param>
/// <param name="timeout">Timeout in [s]</param>
/// <returns>SetFlowOp instance</returns>
public IOperation SetFlowOp(GenericDevices.IFlowMeter flowMeter, double requiredFlowLo, double requiredFlowHi, DoubleBox measuredFlow, int timeout, int delay)
{
return new SetFlowOp(UniCB, this, flowMeter, requiredFlowLo, requiredFlowHi, measuredFlow, timeout, delay);
}
/// <summary>
/// Operation to set the water flow within tolerances. Leave the measurement running.
/// Events: Event.None, Event.FlowReached, Event.FlowTimeOut
/// </summary>
/// <param name="flowMeter">Flowmeter component</param>
/// <param name="requiredFlowLo">Lower limit of the required flow [m3/h]</param>
/// <param name="requiredFlowHi">Higher limit of the required flow [m3/h]</param>
/// <param name="measuredFlow">Measured flow [m3/h]</param>
/// <param name="timeout">Timeout in [s]</param>
/// <returns>SetFlowOp instance</returns>
public IOperation SetFlowAndMeasureOp(GenericDevices.IFlowMeter flowMeter, double requiredFlowLo, double requiredFlowHi,
DoubleBox measuredFlow, int timeout, float filterConstant)
{
return new SetFlowOp(UniCB, this, flowMeter, requiredFlowLo, requiredFlowHi, measuredFlow, timeout, 0, true);
}
/// <summary>
/// Operation to set the regulation valve to a required position
/// Events: Event.None
/// </summary>
/// <param name="flowLo">Lower limit of the required valve position in [%]</param>
/// <param name="flowLo">Higher limit of the required valve position in [%]</param>
/// <returns>SetPositionOp instance</returns>
public IOperation SetRegValvePositionOp(double pctLo, double pctHi, int timeoutMs)
{
return new SetRegValvePositionOp(UniCB, this, pctLo, pctHi, timeoutMs);
}
public IOperation ChangeRegValvePositionOp(double timePulseSec)
{
return new ChangeRegValvePositionOp(UniCB, this, timePulseSec);
}
}
}