Compare commits

...

4 Commits

11 changed files with 257 additions and 192 deletions

View File

@ -175,8 +175,8 @@ namespace TBF.Rig.ControlBoard.Uni
double reqFlowLo = (0.7 * qFrom) + (0.3 * reqFlowAve); /// Move the lower limit 15% of the range up
double reqFlowHi = (0.7 * qTo) + (0.3 * reqFlowAve); /// Move the upper limit 15% of the range down
///
uniCB.SetFlow(false, regV.Idx1, 2000.0 * reqFlowLo / flowMeter.NominalFlow,
2000.0 * reqFlowHi / flowMeter.NominalFlow);
uniCB.SetFlow(false, regV.Idx1, flowMeter.NominalFreq * reqFlowLo / flowMeter.NominalFlow,
flowMeter.NominalFreq * reqFlowHi / flowMeter.NominalFlow);
if (readDivTransition)
{
/// Schedule reading diverter transition data

View File

@ -803,12 +803,60 @@ namespace TBF.Rig.ControlBoard.Uni
/// </summary>
public void SetFlow(bool isFromUI, int regVId, double freqLo, double freqHi, int regulationMinStep = 0)
{
if (IsUIBlocked && isFromUI) return;
LiveLogDiag.Log1("----------------------------------------");
LiveLogDiag.Log1(
"SetFlow() >> ENTER isFromUI={0} regVId={1} freqLo={2} freqHi={3} regulationMinStep={4} IsUIBlocked={5}",
isFromUI, regVId, freqLo, freqHi, regulationMinStep, IsUIBlocked);
actionQueue.Enqueue(Action.SetFlow(isFromUI, regVId, freqLo, freqHi, Convert.ToInt32(Math.Round(Devices.PidCoef)), 200, regulationMinStep));
log.InfoFormat("Enqueue( SetFlow(rv={0}, fLo={1}, fHi={2}, pid={3}) )", regVId, freqLo, freqHi, Convert.ToInt32(Math.Round(Devices.PidCoef)));
if (IsUIBlocked && isFromUI)
{
LiveLogDiag.Log1(
"SetFlow() >> EXIT (UI BLOCKED) isFromUI={0}",
isFromUI);
return;
}
foreach (var a in actionQueue) log.DebugFormat(" {0}", a);
int pid = Convert.ToInt32(Math.Round(Devices.PidCoef));
int fixedParam = 200;
LiveLogDiag.Log1(
"SetFlow() >> PREPARE pid={0} fixedParam={1} regulationMinStep={2}",
pid, fixedParam, regulationMinStep);
var action = Action.SetFlow(
isFromUI,
regVId,
freqLo,
freqHi,
pid,
fixedParam,
regulationMinStep);
LiveLogDiag.Log1(
"SetFlow() >> ACTION CREATED: rv={0} fLo={1} fHi={2} pid={3} p6={4} minStep={5}",
regVId, freqLo, freqHi, pid, fixedParam, regulationMinStep);
actionQueue.Enqueue(action);
LiveLogDiag.Log1(
"SetFlow() >> ENQUEUED actionQueue.Count={0}",
actionQueue.Count);
log.InfoFormat(
"Enqueue( SetFlow(rv={0}, fLo={1}, fHi={2}, pid={3}) )",
regVId, freqLo, freqHi, pid);
int i = 0;
foreach (var a in actionQueue)
{
LiveLogDiag.Log1(
"SetFlow() >> QUEUE[{0}] = {1}",
i++, a);
log.DebugFormat(" {0}", a);
}
LiveLogDiag.Log1("SetFlow() >> EXIT");
LiveLogDiag.Log1("----------------------------------------");
}
public void StartTest(bool isFromUI, int flowMId, int divId, int divThreshold,
@ -981,5 +1029,18 @@ namespace TBF.Rig.ControlBoard.Uni
{
/// TODO
}
/// <summary>
/// Logging
/// For activation use compilation condition: LIVELOGDIAG_FlowMeter_cs
/// </summary>
static class LiveLogDiag
{
[Conditional("LIVELOGDIAG_UniCB_cs")]
public static void Log1(string format, params object[] args)
{
LiveLogCache.Instance.AddLog("UniCB.cs LOG>> " + string.Format(format, args));
}
}
}
}

View File

@ -6,20 +6,21 @@ using TBF.Rig.Generic;
namespace TBF.Rig.Uni.FlowMetersInParallel
{
public class Factory : IComponentFactory
{
public class Factory : IComponentFactory
{
public string ClassName { get { return GetType().Namespace.Substring(12); } }
public override string ToString() { return ClassName; }
public IComponent DummyComponent() { return new FlowMeter(); }
public IComponent DummyComponent() { return new FlowMeter(); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new FlowMeter(cfg, components); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new FlowMeter(cfg, components); }
public IComponentCfg DefaultConfig() { return new FlowMeterCfg(this, "I11+I12"); }
public IComponentCfg DefaultConfig() { return new FlowMeterCfg(this, "I11+I12"); }
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
{
return ComponentCfgBase.CreateFromDbEntity(FlowMeterCfg.Serializer, component, this);
}
}
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
{
return ComponentCfgBase.CreateFromDbEntity(FlowMeterCfg.Serializer, component, this);
}
}
}

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using log4net;
using SchematicDrawing;
using SharedComponents;
using TBF.Boxes;
using TBF.Rig.ControlBoard.Uni;
using TBF.Rig.GenericDevices;
@ -12,17 +13,16 @@ using TBF.Rig.GenericDevices;
namespace TBF.Rig.Uni.FlowMetersInParallel
{
public class FlowMeter : ComponentBase, IFlowMeter, IDrawingItCmpntWithMeasuredVal
{
private static readonly ILog log = LogManager.GetLogger(typeof(FlowMeter));
{
private static readonly ILog log = LogManager.GetLogger(typeof(FlowMeter));
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
readonly FlowMeterCfg myCfg;
readonly FlowMeterCfg flowMeterCfg;
UniCB uniCB;
IFlowMeterSingle flowMtr1;
IFlowMeterSingle flowMtr2;
IFlowMeterSingle flowMtr3;
IFlowMeterSingle inactiveFlowMtr;
double nominalFlow;
double nominalFreq;
double ltrPerPulse;
@ -34,22 +34,20 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
public double NominalFreq { get { return nominalFreq; } }
public double LtrPerPulse { get { return ltrPerPulse; } }
public SchematicDrawing.IDrawingItem DrawingItem { get { return myCfg as SchematicDrawing.IDrawingItem; } }
public string MsrdFormat { get { return myCfg.MsrdFormat; } }
public Common.Unit MsrdUnit { get { return myCfg.MsrdUnit; } }
public double MsrdValLimLo { get { return myCfg.MsrdValLimLo; } set { myCfg.MsrdValLimLo = value; } }
public double MsrdValLimHi { get { return myCfg.MsrdValLimHi; } set { myCfg.MsrdValLimHi = value; } }
public SchematicDrawing.IDrawingItem DrawingItem { get { return flowMeterCfg as SchematicDrawing.IDrawingItem; } }
public string MsrdFormat { get { return flowMeterCfg.MsrdFormat; } }
public Common.Unit MsrdUnit { get { return flowMeterCfg.MsrdUnit; } }
public double MsrdValLimLo { get { return flowMeterCfg.MsrdValLimLo; } set { flowMeterCfg.MsrdValLimLo = value; } }
public double MsrdValLimHi { get { return flowMeterCfg.MsrdValLimHi; } set { flowMeterCfg.MsrdValLimHi = value; } }
public bool MsrmntAvailable
{
get
{
bool result = true;
if (flowMtr1 != null) result = (result && flowMtr1.MsrmntAvailable);
if (flowMtr2 != null) result = (result && flowMtr2.MsrmntAvailable);
if (flowMtr3 != null) result = (result && flowMtr3.MsrmntAvailable);
if (inactiveFlowMtr != null) result = (result && !inactiveFlowMtr.MsrmntAvailable);
if (flowMtr1 != null) result = result && flowMtr1.MsrmntAvailable;
if (flowMtr2 != null) result = result && flowMtr2.MsrmntAvailable;
if (flowMtr3 != null) result = result && flowMtr3.MsrmntAvailable;
return result;
}
}
@ -61,24 +59,22 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
public string AltString { get { return "Invalid format"; } }
public FlowMeter() { }
public FlowMeter() { }
public FlowMeter(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
myCfg = cfg as FlowMeterCfg;
}
public FlowMeter(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
flowMeterCfg = cfg as FlowMeterCfg;
}
public override void Initialize()
{
uniCB = TbfComponents.FindComponent(myCfg.ParentName) as UniCB;
uniCB = TbfComponents.FindComponent(flowMeterCfg.ParentName) as UniCB;
if (uniCB == null) throw new Exception("Cannot find " + Name + " parent");
if (!string.IsNullOrEmpty(myCfg.Flowmeter1)) flowMtr1 = TbfComponents.FindComponent(myCfg.Flowmeter1) as IFlowMeterSingle;
if (!string.IsNullOrEmpty(myCfg.Flowmeter2)) flowMtr2 = TbfComponents.FindComponent(myCfg.Flowmeter2) as IFlowMeterSingle;
if (!string.IsNullOrEmpty(myCfg.Flowmeter3)) flowMtr3 = TbfComponents.FindComponent(myCfg.Flowmeter3) as IFlowMeterSingle;
if (!string.IsNullOrEmpty(myCfg.InactiveFlowmtr)) inactiveFlowMtr = TbfComponents.FindComponent(myCfg.InactiveFlowmtr) as IFlowMeterSingle;
if (!string.IsNullOrEmpty(flowMeterCfg.Flowmeter1)) flowMtr1 = TbfComponents.FindComponent(flowMeterCfg.Flowmeter1) as IFlowMeterSingle;
if (!string.IsNullOrEmpty(flowMeterCfg.Flowmeter2)) flowMtr2 = TbfComponents.FindComponent(flowMeterCfg.Flowmeter2) as IFlowMeterSingle;
if (!string.IsNullOrEmpty(flowMeterCfg.Flowmeter3)) flowMtr3 = TbfComponents.FindComponent(flowMeterCfg.Flowmeter3) as IFlowMeterSingle;
nominalFlow = 0;
flowMetersCount = 0;
@ -91,8 +87,8 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
flowMetersBitfield |= (4 << flowMtr1.Idx1);
flowMetersCount++;
}
if (flowMtr2 != null)
{
if (flowMtr2 != null)
{
nominalFlow += flowMtr2.NominalFlow;
nominalFreq += flowMtr2.NominalFreq;
flowMetersBitfield |= (4 << flowMtr2.Idx1);
@ -109,15 +105,31 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
MsrdValLimHi = nominalFlow;
nominalFreq = nominalFreq / flowMetersCount;
ltrPerPulse = nominalFlow / (3.6 * nominalFreq); /// Nominal freq. is sum of particular nominal frquencies
log.FatalFormat("{0} initialized: {1} nom.flow={2} m3/h nom.freq={3} Hz bitfield=0x{4:X2}",
Name, this, nominalFlow, nominalFreq, flowMetersBitfield);
Name, nominalFlow, nominalFreq, flowMetersBitfield);
}
public double ReadFlow()
{
return ReadFrequency() * nominalFlow / nominalFreq;
double flowByNewFormulaSum = 0;
if (flowMtr1 != null)
{
flowByNewFormulaSum += flowMtr1.NominalFlow * uniCB.Data.ReferenceFreq[1] / flowMtr1.NominalFreq;
}
if (flowMtr2 != null)
{
flowByNewFormulaSum += flowMtr2.NominalFlow * uniCB.Data.ReferenceFreq[2] / flowMtr2.NominalFreq;
}
if (flowMtr3 != null)
{
flowByNewFormulaSum += flowMtr3.NominalFlow * uniCB.Data.ReferenceFreq[3] / flowMtr3.NominalFreq;
}
return flowByNewFormulaSum/*ReadFrequency() * nominalFlow / nominalFreq*/;
}
public double ReadFrequency()
@ -125,27 +137,26 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
return uniCB.RefFrequency;
}
/// <summary>
/// Events: FlowDone, Error
/// </summary>
/// <param name="flow">Reference to a variable for the flow in Bar</param>
/// <returns>ReadFlowOp instance reference casted to IOperaton</returns>
public IOperation ReadFlowOp(ref DoubleBox flow)
{
return new ReadFlowOp(this, ref flow);
}
/// <summary>
/// Events: flowDone, Error
/// </summary>
/// <param name="flow">Reference to a variable for the flow in Bar</param>
/// <param name="flowDone">Event returned when measurement done</param>
/// <returns>ReadFlowOp instance reference casted to IOperaton</returns>
public IOperation ReadFlowOp(ref DoubleBox flow, Event flowDone)
{
return new ReadFlowOp(this, ref flow, flowDone);
}
/// <summary>
/// Events: FlowDone, Error
/// </summary>
/// <param name="flow">Reference to a variable for the flow in Bar</param>
/// <returns>ReadFlowOp instance reference casted to IOperaton</returns>
public IOperation ReadFlowOp(ref DoubleBox flow)
{
return new ReadFlowOp(this, ref flow);
}
/// <summary>
/// Events: flowDone, Error
/// </summary>
/// <param name="flow">Reference to a variable for the flow in Bar</param>
/// <param name="flowDone">Event returned when measurement done</param>
/// <returns>ReadFlowOp instance reference casted to IOperaton</returns>
public IOperation ReadFlowOp(ref DoubleBox flow, Event flowDone)
{
return new ReadFlowOp(this, ref flow, flowDone);
}
double flowRawSum;
double flowSum;
@ -197,7 +208,7 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
public double LtrPerPulseCorrected(double flow, float temperature)
{
double ltrPerPulseCorrected = (flowRawSum == 0) ? LtrPerPulse : LtrPerPulse * flowSum / flowRawSum;
log.WarnFormat("LtrPerPulseCorrected() flow = {0:F3} m3/h flowRawSum = {1:F3} m3/h flowSum = {2:F3} m3/h temperature = {3:F1} C ltrPerPulseCorrected = {4}", flow, flowRawSum, flowSum, temperature, ltrPerPulseCorrected);
log.WarnFormat("LtrPerPulseCorrected() flow = {0} m3/h flowRawSum = {1} m3/h flowSum = {2} m3/h temperature = {3} C ltrPerPulseCorrected = {4}", flow, flowRawSum, flowSum, temperature, ltrPerPulseCorrected);
return ltrPerPulseCorrected;
}
}

View File

@ -13,9 +13,9 @@ using TBF.Rig.Generic;
namespace TBF.Rig.Uni.FlowMetersInParallel
{
public class FlowMeterCfg : ComponentCfgBase, IChildComponentCfg, IParamsProvider, IDrawingItemWithMeasuredVal
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(FlowMeterCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(FlowMeterCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities)
{
@ -24,15 +24,14 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
return new Configs.ParamsProvider.ComponentCfgCtrl(this, parents);
}
///
/// Serialized parameters
///
///
/// Serialized parameters
///
public string Flowmeter1; /// 0 Flowmeter component name or string.Empty
public string Flowmeter2; /// 1 - ' ' -
public string Flowmeter3; /// 2 - ' ' -
public string InactiveFlowmtr; /// 3 Inactive flowmeter component name or string.Empty
public string MsrdFormat { get; set; } /// 4
public Unit MsrdUnit { get; set; } /// 5
public string MsrdFormat { get; set; } /// 3
public Unit MsrdUnit { get; set; } /// 4
/// Schematic drawing info
public Shape Shape { get; set; }
@ -58,9 +57,6 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
private IEnumerable<Config.Entities.Component> flowMeters;
[XmlIgnore]
public bool IsOffline { get; set; }
/// Private parameterless constructor invoked by all other (public) constructors
FlowMeterCfg()
{
@ -82,12 +78,13 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
public string ComponentName { get { return Name; } }
public bool IsOffline { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public void InitializeAll()
{
Flowmeter1 = "I11";
Flowmeter2 = "I12";
Flowmeter3 = string.Empty;
InactiveFlowmtr = "I13";
MsrdFormat = "{0:F3} m3/h";
MsrdUnit = Unit.m3ph;
}
@ -97,9 +94,8 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
"Flow meter 1", /// 0
"Flow meter 2", /// 1
"Flow meter 3", /// 2
"Inactive flow meter", /// 3
"Display format", /// 4
"Unit of flow on a display", /// 5
"Display format", /// 3
"Unit of flow on a display", /// 4
};
public string ParamName(int i) { return paramNames[i]; }
public int ParamsCount() { return paramNames.Length; }
@ -111,48 +107,44 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
case 0:
case 1:
case 2:
case 3:
if (flowMeters == null) return null;
var fmtrs = new List<string>();
foreach (var fmtr in flowMeters) fmtrs.Add(fmtr.Name);
fmtrs.Add("---");
return fmtrs;
case 5:
return new string[] { "m3/h", "l/h", "gal/m" };
case 4:
return new string[] { "m3/h", "l/h" };
default:
return null;
}
}
public string ToString(int i)
{
public string ToString(int i)
{
switch (i)
{
case 0: return string.IsNullOrEmpty(Flowmeter1) ? "---" : Flowmeter1;
case 1: return string.IsNullOrEmpty(Flowmeter2) ? "---" : Flowmeter2;
case 2: return string.IsNullOrEmpty(Flowmeter3) ? "---" : Flowmeter3;
case 3: return string.IsNullOrEmpty(InactiveFlowmtr) ? "---" : InactiveFlowmtr;
case 4: return MsrdFormat;
case 5: return MsrdUnit.ToDescription();
case 3: return MsrdFormat;
case 4: return MsrdUnit.ToDescription();
default:
return string.Format("Name={0} {1} {2} {3} ~{4} fmt={5} unit={6} Lo={7} Hi={8}",
Name, Flowmeter1, Flowmeter2, Flowmeter3, InactiveFlowmtr,
return string.Format("Name={0} {1} {2} {3} fmt={4} unit={5} Lo={6} Hi={7}",
Name, Flowmeter1, Flowmeter2, Flowmeter3,
MsrdFormat, MsrdUnit.ToDescription(), MsrdValLimLo, MsrdValLimHi);
}
}
}
public CfgUpdateFlags UpdateParam(int i, string str)
{
switch (i)
{
case 0: Flowmeter1 = (str != "---") ? str : string.Empty; return CfgUpdateFlags.RestartRqrd;
case 1: Flowmeter2 = (str != "---") ? str : string.Empty; return CfgUpdateFlags.RestartRqrd;
case 2: Flowmeter3 = (str != "---") ? str : string.Empty; return CfgUpdateFlags.RestartRqrd;
case 3: InactiveFlowmtr = (str != "---") ? str : string.Empty; return CfgUpdateFlags.RestartRqrd;
case 4: MsrdFormat = str; return CfgUpdateFlags.RestartRqrd;
//case 5: MsrdUnit = (str == "l/h") ? Unit.lph : Unit.m3ph; return CfgUpdateFlags.RestartRqrd;
case 5: MsrdUnit = ParseFlowUnit(str); return CfgUpdateFlags.RestartRqrd;
case 0: Flowmeter1 = (str != "---") ? str : string.Empty; return CfgUpdateFlags.RestartRqrd;
case 1: Flowmeter2 = (str != "---") ? str : string.Empty; return CfgUpdateFlags.RestartRqrd;
case 2: Flowmeter3 = (str != "---") ? str : string.Empty; return CfgUpdateFlags.RestartRqrd;
case 3: MsrdFormat = str; return CfgUpdateFlags.RestartRqrd;
case 4: MsrdUnit = (str == "l/h") ? Unit.lph : Unit.m3ph; return CfgUpdateFlags.RestartRqrd;
default:
return CfgUpdateFlags.None;
}
@ -167,11 +159,10 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
case 0:
case 1:
case 2:
case 3:
case 5:
case 4:
if (ParamValues(i).Contains(str)) return true;
break;
case 4:
case 3:
return true;
default:
message = "Invalid index";
@ -187,7 +178,6 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
prms.Flowmeter1 = this.Flowmeter1;
prms.Flowmeter2 = this.Flowmeter2;
prms.Flowmeter3 = this.Flowmeter3;
prms.InactiveFlowmtr = this.InactiveFlowmtr;
prms.MsrdFormat = this.MsrdFormat;
prms.MsrdUnit = this.MsrdUnit;
}
@ -203,19 +193,5 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
{
return true; /// =OK, do nothing
}
public static Unit ParseFlowUnit(string str)
{
//Check if the string is a valid unit description
Unit fromDescription = Units.FromDescription(str);
if (fromDescription != Unit.None) return fromDescription;
//check if the string is a valid unit name
switch (str)
{
case "l/h": return Unit.lph;
case "gal/m": return Unit.USgalpm;
case "m3/h":
default: return Unit.m3ph;
}
}
}
}

View File

@ -8,57 +8,57 @@ using TBF.Rig.GenericDevices;
namespace TBF.Rig.Uni.FlowMetersInParallel
{
public class ReadFlowOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(ReadFlowOp));
public class ReadFlowOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(ReadFlowOp));
public override string ToString() { return string.Format("ReadFlowOp({0},.,.,{1})", flowMeter.Idx1, eventDone); }
/// Set by the constructor
/// Set by the constructor
readonly IFlowMeter flowMeter;
readonly DoubleBox flowBox;
readonly Event eventDone;
readonly DoubleBox flowBox;
readonly Event eventDone;
/// <summary>
/// Events: FlowInDone, FlowOutDone or Error
/// </summary>
/// <param name="flowMeter">Flow meter reference</param>
/// <param name="flowBox">Reference to the measured flow variable, value is in bar</param>
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
/// <summary>
/// Events: FlowInDone, FlowOutDone or Error
/// </summary>
/// <param name="flowMeter">Flow meter reference</param>
/// <param name="flowBox">Reference to the measured flow variable, value is in bar</param>
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
public ReadFlowOp(IFlowMeter flowMeter, ref DoubleBox flowBox, Event eventDone)
{
if (flowMeter == null) throw new ArgumentNullException();
this.flowMeter = flowMeter;
this.eventDone = eventDone;
this.flowBox = flowBox;
this.eventDone = eventDone;
this.flowBox = flowBox;
log.Debug(this.ToString());
log.Debug(this.ToString());
}
public ReadFlowOp(IFlowMeter flowMeter, ref DoubleBox flowBox)
: this(flowMeter, ref flowBox, Event.FlowMeasurementDone)
{
}
: this(flowMeter, ref flowBox, Event.FlowMeasurementDone)
{
}
/// <summary>Start this operation</summary>
public void Start() { }
/// <summary>Start this operation</summary>
public void Start() { }
/// <summary>Run this operation</summary>
/// <returns>
/// Event.FlowInDone or Event.FlowOutDone
/// </returns>
public Event Run()
{
/// <summary>Run this operation</summary>
/// <returns>
/// Event.FlowInDone or Event.FlowOutDone
/// </returns>
public Event Run()
{
if (flowMeter.MsrmntAvailable)
{
{
if (flowBox != null) flowBox.Val = flowMeter.ReadFlow();
return eventDone;
}
return eventDone;
}
return Event.Error;
}
}
/// <summary>Stop this operation</summary>
public void Stop() { }
}
/// <summary>Stop this operation</summary>
public void Stop() { }
}
}

View File

@ -1,10 +1,9 @@
///
/// Copyright (c) 2021-2023 Sensus Slovensko a.s.
/// Copyright (c) 2021 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using log4net;
using TBF.Rig.ControlBoard.Uni;
using TBF.Rig.GenericDevices;
namespace TBF.Rig.Uni.RegValve
@ -14,12 +13,12 @@ namespace TBF.Rig.Uni.RegValve
private static readonly ILog log = LogManager.GetLogger(typeof(ChangeRegValvePositionOp));
public override string ToString()
{
return string.Format("ChangeRegValvePositionOp({0},{1}s)", regV.Name, timePulseSec.ToString("F2"));
return string.Format("ChangeRegValvePositionOp({0},{1}s)", regulValve.Name, timePulseSec.ToString("F2"));
}
/// Set by the constructor
readonly UniCB uniCB;
readonly RegValve regV;
readonly TBF.Rig.ControlBoard.Uni.UniCB controlBoard;
readonly RegValve regulValve;
readonly int regulValveNr;
readonly double timePulseSec;
@ -33,14 +32,14 @@ namespace TBF.Rig.Uni.RegValve
/// <param name="posHiPct">Upper limit of the position to be achieved</param>
/// <param name="timeout">Timeout in sec. for setting the flow</param>
/// <remarks>Only Elde.Valve flow are used, other flow on the lists are ignored</remarks>
public ChangeRegValvePositionOp(UniCB uniCB, RegValve regV, double timePulseSec)
public ChangeRegValvePositionOp(TBF.Rig.ControlBoard.IControlBoard cb, RegValve rv, double timePulseSec)
{
this.uniCB = uniCB;
if (this.uniCB == null) throw new ArgumentNullException("ctrlBoard");
controlBoard = cb as TBF.Rig.ControlBoard.Uni.UniCB;
if (controlBoard == null) throw new ArgumentNullException("ctrlBoard");
this.regV = regV as RegValve;
if (this.regV == null) throw new ArgumentNullException("regValve is null or not Uni");
regulValveNr = this.regV.Idx1;
regulValve = rv as RegValve;
if (regulValve == null) throw new ArgumentNullException("regValve is null or not Elde");
regulValveNr = this.regulValve.Idx1;
this.timePulseSec = timePulseSec;
@ -50,7 +49,13 @@ namespace TBF.Rig.Uni.RegValve
/// <summary>Start this operation</summary>
public void Start()
{
uniCB.RegVlvIncrMove(false, regulValveNr, timePulseSec);
//double positionPct = controlBoard.RValvePosition(regulValveNr);
//log.WarnFormat("RV#={0}, actPos={1}%", regulValveNr, positionPct.ToString("F1"));
//controlBoard.ValveMove(regulValveNr,
// TBF.Rig.ControlBoard.Legacy.RegulValveMode.PulseWidth,
// new double[2] { timePulseSec, timePulseSec },
// regulValve.StableTime);
}
/// <summary>Run this operation</summary>
@ -59,6 +64,9 @@ namespace TBF.Rig.Uni.RegValve
/// </returns>
public Event Run()
{
//float positionPct = controlBoard.RValvePosition(regulValveNr);
//log.WarnFormat("RV#={0}, actPos={1}%", regulValveNr, positionPct.ToString("F1"));
return Event.PositionReached;
}

View File

@ -1,5 +1,5 @@
///
/// Copyright (c) 2021 Sensus Slovensko a.s.
/// Copyright (c) 2021 Sensus Metering Systems
///
using System.Collections.Generic;
using TBF.Rig.Generic;

View File

@ -1,5 +1,5 @@
///
/// Copyright (c) 2021 Sensus Slovensko a.s.
/// Copyright (c) 2021 Sensus Metering Systems
///
using System;
using log4net;

View File

@ -19,10 +19,11 @@ namespace TBF.Rig.Uni.RegValve
return string.Format("SetFlowOp({0}, Qfrom={1}, Qto={2})", regV.Name, shrinkedTgtFlowLo, shrinkedTgtFlowHi);
}
public const double RqrdFlowRangeRatio = 0.5;
///
/// Set by the constructor
/// Set by the constructor
///
readonly UniCB uniCB;
readonly RegValve regV;
@ -35,8 +36,8 @@ namespace TBF.Rig.Uni.RegValve
readonly bool leaveFlowControlRunning;
readonly double maximalFlow;
///
///
/// Internal state of this operation
///
enum OpState
@ -55,12 +56,13 @@ namespace TBF.Rig.Uni.RegValve
double currentReqFlowLo;
double currentReqFlowHi;
double targetPositionLo;
double targetPositionHi;
double targetPositionLo;
double targetPositionHi;
int startTime;
int setFlowTime;
int expireTime;
DoubleBox msrdFlow;
DoubleBox flowBox;
int isFlowOkDuration;
@ -69,23 +71,23 @@ namespace TBF.Rig.Uni.RegValve
/// Events: FlowSet, FlowTimeOut
/// </summary>
/// <param name="uniCB">Control board device</param>
/// <param name="regValve">Regulation valve component</param>
/// <param name="regulValve">Regulation valve component</param>
/// <param name="flowMeter">Flowmeter component</param>
/// <param name="qFrom">Lower limit of the flow to be achieved in [m3/h]</param>
/// <param name="qTo">Upper limit of the flow to be achieved in [m3/h]</param>
/// <param name="msrdFlow">DoubleBox for measured flow</param>
/// <param name="pidCoef">PID coefficient (float)</param>
/// <param name="timeout">Timeout for the flow setting in [s]</param>
/// <param name="delay">Flow setting starts after this delay in [s]</param>
/// <param name="delay">Flow setting starts after this delay [s]</param>
/// <param name="leaveFlowControlRunning">true = Leave the measurement running after op. stop</param>
/// <remarks>Only Elde.Valve flow are used, other flow on the lists are ignored</remarks>
public SetFlowOp(UniCB uniCB, IRegValve regValve, IFlowMeter flowMeter, double qFrom, double qTo, DoubleBox msrdFlow,
public SetFlowOp(UniCB uniCB, IRegValve regValve, IFlowMeter flowMeter, double qFrom, double qTo, DoubleBox flowBox,
int timeout, int delay, bool leaveFlowControlRunning)
{
this.uniCB = uniCB;
if (this.uniCB == null) throw new ArgumentNullException("Control board is null or not Uni");
this.uniCB = uniCB;
if (this.uniCB == null) throw new ArgumentNullException("cBoard is null or not Uni");
this.regV = regValve as RegValve;
if (this.regV == null) throw new ArgumentNullException(string.Format("{0} is not Uni.RegValve", regValve.Name));
if (this.regV == null) throw new ArgumentNullException("regValve is null or not Uni");
this.flowMeter = flowMeter;
if (this.flowMeter == null) throw new ArgumentNullException("flowMeter");
@ -95,14 +97,15 @@ namespace TBF.Rig.Uni.RegValve
double rqrdFlowLoBeforeCorr = qFrom - MeasurementCorrection.GetCorrection(qFrom, flowMeter.Corrections);
double rqrdFlowHiBeforeCorr = qTo - MeasurementCorrection.GetCorrection(qTo, flowMeter.Corrections);
targetFlowAve = (rqrdFlowLoBeforeCorr + rqrdFlowHiBeforeCorr) / 2;
shrinkedTgtFlowLo = (RqrdFlowRangeRatio * rqrdFlowLoBeforeCorr)
+ ((1 - RqrdFlowRangeRatio) * targetFlowAve); /// Move the lower limit 15% of the range up
shrinkedTgtFlowHi = (RqrdFlowRangeRatio * rqrdFlowHiBeforeCorr)
+ ((1 - RqrdFlowRangeRatio) * targetFlowAve); /// Move the upper limit 15% of the range down
shrinkedTgtFlowLo = (RqrdFlowRangeRatio * rqrdFlowLoBeforeCorr) + ((1 - RqrdFlowRangeRatio) * targetFlowAve); /// Move the lower limit 15% of the range up
shrinkedTgtFlowHi = (RqrdFlowRangeRatio * rqrdFlowHiBeforeCorr) + ((1 - RqrdFlowRangeRatio) * targetFlowAve); /// Move the upper limit 15% of the range down
this.flowBox = flowBox;
if (this.flowBox == null) throw new ArgumentNullException("flowBox");
this.msrdFlow = msrdFlow;
this.timeout = timeout;
this.delay = delay;
this.leaveFlowControlRunning = leaveFlowControlRunning;
log.Debug(this.ToString());
@ -168,13 +171,16 @@ namespace TBF.Rig.Uni.RegValve
return;
}
/// <summary>Start this operation</summary>
/// <summary>
/// Start this operation
/// </summary>
public void Start()
{
log.InfoFormat("SetFlowOp:Start() rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regV.Idx1, flowMeter.Idx1, currentReqFlowLo, currentReqFlowHi);
/// Store the current time, etc.
startTime = StateMachine.Time;
setFlowTime = StateMachine.Time + delay;
expireTime = StateMachine.Time + timeout;
if (expireTime < 0) expireTime = int.MaxValue;
@ -267,16 +273,17 @@ namespace TBF.Rig.Uni.RegValve
///
double frequency = flowMeter.ReadFrequency();
double flow = flowMeter.ReadFlow();
if (msrdFlow != null && flow != 0) msrdFlow.Val = flow;
if (flow != 0) flowBox.Val = flow;
if (currentReqFlowLo <= flow && flow <= currentReqFlowHi)
if ((currentReqFlowLo <= flow) && (flow <= currentReqFlowHi))
{
isFlowOkDuration++; /// Increment the flow within range duration
/// Flow is within range
isFlowOkDuration++;
if (isFlowOkDuration >= regV.FlowStableSec)
{
/// Flow is within range for sufficiently long time
if (regV.StoredPositionReuse)
if (regV.regValveCfg.StoredPositionReuse)
{
double rvPosition = regV.Position; /// Read the current position
double storedPosition;
@ -323,12 +330,13 @@ namespace TBF.Rig.Uni.RegValve
}
}
/// <summary>Stop this operation</summary>
/// <summary>Start this operation</summary>
public void Stop()
{
if (!leaveFlowControlRunning)
{
uniCB.StopFlowControl(false, regV.Idx1); /// Stop the flow measurement
/// Stop flow measurement
uniCB.StopFlowControl(false, regV.Idx1);
}
opState = OpState.Idle;

View File

@ -71,7 +71,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE;CAMERA;LANG_PL;IPERL;</DefineConstants>
<DefineConstants>TRACE;CAMERA;LANG_PL;IPERL;LIVELOGDIAG_FlowMeter_cs;LIVELOGDIAG_RegValve_cs</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>