Action.IsFromUI, MeasureFlow works OK, SetFlow in progress, ver. 3.1.1624

This commit is contained in:
Milan Hanajik
2021-03-10 16:51:52 +01:00
parent 6f701adb9e
commit a21766b944
39 changed files with 393 additions and 307 deletions
+1 -1
View File
@@ -21,7 +21,7 @@ namespace TBF.Rig.Ambient.Comet
public class Ambient : ComponentBase, IDevice, IOperation, GenericDevices.IAmbient, IDrawingItCmpntWithMeasuredVal
{
private static readonly ILog log = LogManager.GetLogger(typeof(Ambient));
public override string ToString() { return string.Format("Ambient({0})", Cfg.ToString(1)); }
public override string ToString() { return string.Format("Ambient({0})", Cfg.ToString(-1)); }
///
/// Configuration and wrappers
+1 -1
View File
@@ -26,8 +26,8 @@ namespace TBF.Rig.ControlBoard
///
/// Values valid during a test
///
int FlowmeterId { get; }
double RefFrequency { get; }
double RefFlow { get; }
///
/// Last test results
@@ -71,6 +71,8 @@ namespace TBF.Rig.ControlBoard.Legacy
public bool ManualUIAllowed { get { return controlCom.ManualUIAllowed; } set { controlCom.ManualUIAllowed = value; } }
public float ValveOpenCloseTime { get { return controlCom.ValveOpenCloseTime; } }
public int FlowmeterId { get { return (int)(controlCom.StatusP & Legacy.StatusP.RefFlowMeterMask); } }
/// <summary> Extracted from the StatusP in RunDeviceBefore </summary>
public bool EmergencyStop { get { return emergencyStop; } }
bool emergencyStop;
+1 -1
View File
@@ -256,8 +256,8 @@ namespace TBF.Rig.ControlBoard.Papouch
public UInt64 DigitalInputs { get { return 0; } }
public int FlowmeterId { get { return 0; } }
public double RefFrequency { get { return 0; } }
public double RefFlow { get { return 0; } }
///
/// Last test result
+96 -46
View File
@@ -11,11 +11,12 @@ namespace TBF.Rig.ControlBoard.Uni
public enum ActionID
{
/// Basic
RequestDataOnly = 0,
ChangeRoute = 1, /// Change digital outputs (route)
MeasureFlow = 2, /// Activate a flow meter to measure the flow
SetFlow = 4, /// Set flow
StartTest = 8, /// Start a test
StopTest = 0x10, /// Stop a test or a flow regulation
Stop = 0x10, /// Stop a test or a flow regulation
RegVlvIncrMove = 0x20,
RegVlvMoveToPos = 0x40,
RegVlvStop = 0x80,
@@ -33,6 +34,7 @@ namespace TBF.Rig.ControlBoard.Uni
private static readonly ILog log = LogManager.GetLogger(typeof(Action));
public ActionID ActionId { get; set; }
public bool IsFromUI { get; set; } /// false = action is comming from the state machine, true = action is comming from the UI
public ulong Route { get; set; } /// ChangeRoute argument
public int FlowMId { get; set; } /// MeasureFlow, SetFlow and StartTest argument
public int RegVId { get; set; } /// SetFlow and StartTest argument
@@ -40,6 +42,7 @@ namespace TBF.Rig.ControlBoard.Uni
public Command StartStop { get; set; } /// MeasureFlow, SetFlow, StartTest, StopTest and SwitchDiverter
public bool IsSyncMethod { get; set; } /// StartTest argument
public bool IsDivUsed { get; set; } /// StartTest argument
public bool IsStartStop { get; set; } /// StartTest argument
public bool ToTank { get; set; } /// SwitchDiverter argument
public int TotalPulsesCount { get; set; } /// StartTest argument
public int MassPulsesCount { get; set; } /// StartTest argument
@@ -58,6 +61,7 @@ namespace TBF.Rig.ControlBoard.Uni
FlowMId = -1;
RegVId = -1;
DivId = -1;
TotalPulsesCount = -1;
StartStop = Command.None;
RegVMode = RegValveMode.None;
@@ -65,7 +69,7 @@ namespace TBF.Rig.ControlBoard.Uni
Route = 0;
IsSyncMethod = false;
IsDivUsed = false;
TotalPulsesCount = 0;
IsStartStop = false;
MassPulsesCount = 0;
RVMovePar1 = 0;
RVMovePar2 = 0;
@@ -83,11 +87,23 @@ namespace TBF.Rig.ControlBoard.Uni
}
///----------------------------------------------------------------------------------------------
public static Action ChangeRoute(ulong route)
public static Action RequestDataOnly()
{
return new Action
{
ActionId = ActionID.RequestDataOnly,
IsFromUI = false,
};
}
///----------------------------------------------------------------------------------------------
public static Action ChangeRoute(bool isFromUI, ulong route)
{
return new Action
{
ActionId = ActionID.ChangeRoute,
IsFromUI = isFromUI,
///
Route = route,
};
}
@@ -98,55 +114,62 @@ namespace TBF.Rig.ControlBoard.Uni
/// Check whether new action arguments are compatible with alredy collected arguments (true = yes)
bool CheckSharedChangeRouteArgs(Action newAction)
{
return Route == newAction.Route;
return true;
}
///----------------------------------------------------------------------------------------------
public static Action MeasureFlow(int flowMeterId)
public static Action MeasureFlow(bool isFromUI, int flowMeterId)
{
return new Action
{
ActionId = ActionID.MeasureFlow,
IsFromUI = isFromUI,
///
FlowMId = flowMeterId,
TotalPulsesCount = 0x7FFFFF,
MassPulsesCount = 0x7FFFFF,
StartStop = Command.Start,
};
}
void SetMeasureFlowArgs(Action action)
{
FlowMId = action.FlowMId;
TotalPulsesCount = action.TotalPulsesCount;
MassPulsesCount = action.MassPulsesCount;
StartStop = Command.Start;
}
/// Check whether new action arguments are compatible with alredy collected arguments (true = yes)
bool CheckSharedMeasureFlowArgs(Action newAction)
{
return (FlowMId == -1 || FlowMId == newAction.FlowMId) &&
(TotalPulsesCount == -1 || TotalPulsesCount == newAction.TotalPulsesCount) &&
(StartStop == Command.None || StartStop == Command.Start);
}
///----------------------------------------------------------------------------------------------
public static Action SetFlow(int flowMeterId, int regValveId, double freqLo, double freqHi,
int pid, int tolerRV, int stabTime)
public static Action SetFlow(bool isFromUI, int regValveId, double freqLo, double freqHi,
int pid, int stabTime_ms)
{
int rvMovePar1 = Convert.ToInt32(Math.Round(13.1072 * freqLo));
int rvMovePar2 = Convert.ToInt32(Math.Round(13.1072 * freqHi));
int stabTime = Convert.ToInt32(Math.Round(stabTime_ms / 200.0));
return new Action
{
ActionId = ActionID.SetFlow,
FlowMId = flowMeterId,
IsFromUI = isFromUI,
///
RegVId = regValveId,
RegVMode = RegValveMode.TargetFrequency,
RVMovePar1 = rvMovePar1,
RVMovePar2 = rvMovePar2,
PID = pid,
TolerRV = tolerRV,
TolerRV = 0,
StabTime = stabTime,
StartStop = Command.Start,
};
}
void SetSetFlowArgs(Action action)
{
FlowMId = action.FlowMId;
RegVId = action.RegVId;
RegVMode = action.RegVMode;
RVMovePar1 = action.RVMovePar1;
@@ -154,31 +177,29 @@ namespace TBF.Rig.ControlBoard.Uni
PID = action.PID;
TolerRV = action.TolerRV;
StabTime = action.StabTime;
StartStop = Command.Start;
}
/// Check whether new action arguments are compatible with alredy collected arguments (true = yes)
bool CheckSharedSetFlowArgs(Action newAction)
{
return (FlowMId == -1 || FlowMId == newAction.FlowMId) &&
(RegVId == -1 || RegVId == newAction.RegVId) &&
(RegVMode == RegValveMode.None || RegVMode == newAction.RegVMode) &&
(RVMovePar1 == -1 || RVMovePar1 == newAction.RVMovePar1) &&
(RVMovePar2 == -1 || RVMovePar2 == newAction.RVMovePar2) &&
(StartStop == Command.None || StartStop == Command.Start);
return (RegVId == -1 || RegVId == newAction.RegVId) &&
(RegVMode == RegValveMode.None || RegVMode == newAction.RegVMode);
}
///----------------------------------------------------------------------------------------------
public static Action StartTest(int flowMId, int divId, int divThreshold, bool isSyncMethod,
bool isDivUsed, int totalPulsesCount, int massPulsesCount = -1)
public static Action StartTest(bool isFromUI, int flowMId, int divId, int divThreshold, bool isSyncMethod,
bool isDivUsed, bool isStartStop, int totalPulsesCount, int massPulsesCount = -1)
{
return new Action
{
ActionId = ActionID.StartTest,
IsFromUI = isFromUI,
///
FlowMId = flowMId,
DivId = divId,
DivThreshold = divThreshold,
IsSyncMethod = isSyncMethod,
IsDivUsed = isDivUsed,
IsStartStop = isStartStop,
TotalPulsesCount = totalPulsesCount,
MassPulsesCount = (massPulsesCount == -1) ? totalPulsesCount : massPulsesCount,
StartStop = Command.Start,
@@ -191,6 +212,7 @@ namespace TBF.Rig.ControlBoard.Uni
DivThreshold = action.DivThreshold;
IsSyncMethod = action.IsSyncMethod;
IsDivUsed = action.IsDivUsed;
IsStartStop = action.IsStartStop;
TotalPulsesCount = action.TotalPulsesCount;
MassPulsesCount = action.MassPulsesCount;
StartStop = Command.Start;
@@ -200,36 +222,41 @@ namespace TBF.Rig.ControlBoard.Uni
{
return (FlowMId == -1 || FlowMId == newAction.FlowMId) &&
(DivId == -1 || DivId == newAction.DivId) &&
(TotalPulsesCount == -1 || TotalPulsesCount == newAction.TotalPulsesCount) &&
(StartStop == Command.None || StartStop == Command.Start);
}
///----------------------------------------------------------------------------------------------
public static Action StopTest()
public static Action Stop(bool isFromUI)
{
return new Action()
{
ActionId = ActionID.StopTest,
ActionId = ActionID.Stop,
IsFromUI = isFromUI,
///
StartStop = Command.Stop,
};
}
void SetStopTestArgs(Action action)
void SetStopArgs(Action action)
{
StartStop = Command.Stop;
}
/// Check whether new action arguments are compatible with alredy collected arguments (true = yes)
bool CheckSharedStopTestArgs(Action action)
bool CheckSharedStopArgs(Action action)
{
return (StartStop == Command.None || StartStop == Command.Stop);
}
///----------------------------------------------------------------------------------------------
public static Action RegVlvIncrMove(int regValveId, double timeSec)
public static Action RegVlvIncrMove(bool isFromUI, int regValveId, double timeSec)
{
int rvMovePar = Math.Abs(Convert.ToInt32(Math.Round(timeSec / 0.050))); /// Step is 50 ms
return new Action
{
ActionId = ActionID.RegVlvIncrMove,
IsFromUI = isFromUI,
///
RegVId = regValveId,
RegVMode = (timeSec >= 0) ? RegValveMode.PulseWidth : (RegValveMode.PulseWidth | RegValveMode.NegPulseWidth),
RVMovePar1 = rvMovePar,
@@ -251,7 +278,7 @@ namespace TBF.Rig.ControlBoard.Uni
}
///----------------------------------------------------------------------------------------------
public static Action RegVlvMoveToPos(int regValveId, double positionLo, double positionHi = -1)
public static Action RegVlvMoveToPos(bool isFromUI, int regValveId, double positionLo, double positionHi = -1)
{
int rvMovePar1, rvMovePar2; /// TODO
///
@@ -271,6 +298,8 @@ namespace TBF.Rig.ControlBoard.Uni
return new Action
{
ActionId = ActionID.RegVlvMoveToPos,
IsFromUI = isFromUI,
///
RegVId = regValveId,
RegVMode = RegValveMode.TargetPosition,
RVMovePar1 = rvMovePar1,
@@ -292,11 +321,13 @@ namespace TBF.Rig.ControlBoard.Uni
}
///----------------------------------------------------------------------------------------------
public static Action RegVlvStop(int regValveId)
public static Action RegVlvStop(bool isFromUI, int regValveId)
{
return new Action
{
ActionId = ActionID.RegVlvStop,
IsFromUI = isFromUI,
///
RegVId = regValveId,
RegVMode = RegValveMode.Stop,
RVMovePar1 = 0,
@@ -318,11 +349,13 @@ namespace TBF.Rig.ControlBoard.Uni
}
///----------------------------------------------------------------------------------------------
public static Action SwitchDiverter(int divId, bool toTank)
public static Action SwitchDiverter(bool isFromUI, int divId, bool toTank)
{
return new Action
{
ActionId = ActionID.SwitchDiverter,
IsFromUI = isFromUI,
///
DivId = divId,
ToTank = toTank,
StartStop = Command.Start,
@@ -352,7 +385,7 @@ namespace TBF.Rig.ControlBoard.Uni
case ActionID.MeasureFlow: SetMeasureFlowArgs(action); return;
case ActionID.SetFlow: SetSetFlowArgs(action); return;
case ActionID.StartTest: SetStartTestArgs(action); return;
case ActionID.StopTest: SetStopTestArgs(action); return;
case ActionID.Stop: SetStopArgs(action); return;
case ActionID.RegVlvIncrMove: SetRegVlvIncrMoveArgs(action); return;
case ActionID.RegVlvMoveToPos: SetRegVlvMoveToPosArgs(action); return;
case ActionID.RegVlvStop: SetRegVlvStopArgs(action); return;
@@ -370,11 +403,12 @@ namespace TBF.Rig.ControlBoard.Uni
{
switch (action.ActionId)
{
case ActionID.RequestDataOnly: return true;
case ActionID.ChangeRoute: return CheckSharedChangeRouteArgs(action);
case ActionID.MeasureFlow: return CheckSharedMeasureFlowArgs(action);
case ActionID.SetFlow: return CheckSharedSetFlowArgs(action);
case ActionID.StartTest: return CheckSharedStartTestArgs(action);
case ActionID.StopTest: return CheckSharedStopTestArgs(action);
case ActionID.Stop: return CheckSharedStopArgs(action);
case ActionID.RegVlvIncrMove: return CheckSharedRegVlvIncrMoveArgs(action);
case ActionID.RegVlvMoveToPos: return CheckSharedRegVlvMoveToPosArgs(action);
case ActionID.RegVlvStop: return CheckSharedRegVlvStopArgs(action);
@@ -384,22 +418,17 @@ namespace TBF.Rig.ControlBoard.Uni
}
///----------------------------------------------------------------------------------------------
public static Action FetchNonConflictingActions(Queue<Action> queue)
public static Action FetchNonConflictingActions(Queue<Action> queue, bool blockUI = false)
{
log.Debug("Fetching non conflicting actions:");
if (queue == null || queue.Count == 0) return null;
Action resultA = queue.Dequeue();
log.Debug(resultA.ToString());
Action combinedAction = Action.RequestDataOnly();
while (queue.Count > 0)
{
var peekA = queue.Peek();
if ((resultA.ActionId & peekA.ActionId) == 0 && resultA.CheckSharedArgs(peekA) == true)
if ((combinedAction.ActionId & peekA.ActionId) == 0 && combinedAction.CheckSharedArgs(peekA) == true)
{
/// ActionId would not be repeated and arguments are compatible => apply the new action
resultA.SetArgs(peekA);
combinedAction.SetArgs(peekA);
log.Debug(peekA.ToString());
queue.Dequeue();
}
@@ -410,7 +439,28 @@ namespace TBF.Rig.ControlBoard.Uni
}
}
return resultA;
log.InfoFormat("Combined action: {0} Rt={1} Et={2} RV={3} Div#={4} Cmd={5} Sync={6} wDiv={7} S/S={8} ToTank={9} Puls={10} MPls={11} RVMode={12} P1={13} P2={14}",
((int)combinedAction.ActionId).ToString("X3"),
combinedAction.Route.ToString("X12"),
combinedAction.FlowMId,
combinedAction.RegVId,
combinedAction.DivId,
combinedAction.StartStop,
combinedAction.IsSyncMethod,
combinedAction.IsDivUsed,
combinedAction.IsStartStop,
combinedAction.ToTank,
combinedAction.TotalPulsesCount,
combinedAction.MassPulsesCount,
combinedAction.RegVMode,
combinedAction.RVMovePar1,
combinedAction.RVMovePar2,
combinedAction.PID,
combinedAction.TolerRV,
combinedAction.StabTime,
combinedAction.DivThreshold);
return combinedAction;
}
public override string ToString()
@@ -419,22 +469,22 @@ namespace TBF.Rig.ControlBoard.Uni
switch (ActionId)
{
case ActionID.ChangeRoute:
args = string.Format("Route={0}", Route.ToString("X16"));
args = string.Format("Rt={0}", Route.ToString("X12"));
break;
case ActionID.MeasureFlow:
args = string.Format("Etalon={0}", FlowMId);
args = string.Format("Et={0}", FlowMId);
break;
case ActionID.SetFlow:
args = string.Format("Etalon={0} RV={1} Par1={2} Par2={3}", FlowMId, RegVId, RVMovePar1, RVMovePar2);
args = string.Format("RV={0} P1={1} P2={2}", RegVId, RVMovePar1, RVMovePar2);
break;
case ActionID.StartTest:
args = string.Format("Etalon={0} TotalP={1} MassP={2}", FlowMId, TotalPulsesCount, MassPulsesCount);
args = string.Format("Et={0} Puls={1} MPls={2} Sync={3} Div={4} SS={5}", FlowMId, TotalPulsesCount, MassPulsesCount, IsSyncMethod, IsDivUsed, IsStartStop);
break;
case ActionID.RegVlvIncrMove:
args = string.Format("Time={0}ms", (RegVMode & RegValveMode.NegPulseWidth) != 0 ? -50 * RVMovePar1 : 50 * RVMovePar1);
args = string.Format("RV={0} Time={1}ms", RegVId, (RegVMode & RegValveMode.NegPulseWidth) != 0 ? -50 * RVMovePar1 : 50 * RVMovePar1);
break;
case ActionID.RegVlvMoveToPos:
args = string.Format("Position={0}%", 0); /// TODO
args = string.Format("RV={0} Pos={1}%", RegVId, 0); /// TODO
break;
default:
args = string.Empty;
+10 -4
View File
@@ -2,10 +2,14 @@
/// Copyright (c) 2021 Sensus Slovensko a.s.
///
using System;
using log4net;
namespace TBF.Rig.ControlBoard.Uni
{
public class GeneralData
{
private static readonly ILog log = LogManager.GetLogger(typeof(GeneralData));
public const int MessageLen = 303;
public const byte MessageCode = (byte)' ';
@@ -64,7 +68,7 @@ namespace TBF.Rig.ControlBoard.Uni
/// <param name="data">Received data</param>
/// <param name="offs">Offset to the files</param>
/// <returns></returns>
Int16 GetInt16(byte[] data, int offs) { return BitConverter.ToInt16(data, offs); }
Int16 GetInt16(byte[] data, int offs) { return BitConverter.ToInt16(data, offs); }
UInt16 GetUInt16(byte[] data, int offs) { return BitConverter.ToUInt16(data, offs); }
UInt32 GetUInt24(byte[] data, int offs) { return BitConverter.ToUInt32(data, offs) & 0x00FFFFFF; }
UInt32 GetUInt32(byte[] data, int offs) { return BitConverter.ToUInt32(data, offs); }
@@ -154,7 +158,7 @@ namespace TBF.Rig.ControlBoard.Uni
par2[2] = GetUInt16(data, offs + (int)Poz.Per3); /// Byte 266,267
par1[2] = GetUInt16(data, offs + (int)Poz.Per3 + 2); /// Byte 268,269
///
ReferenceFreq[0] = (par2[0] != 0) ? (5.0f * par1[0] / par2[0]) : 0.0f;
ReferenceFreq[0] = (par2[0] != 0) ? (5000.0 * Convert.ToDouble(par1[0]) / Convert.ToDouble(par2[0])) : 0.0;
ReferenceFreq[1] = ReferenceFreq[2] = ReferenceFreq[3] = 0;
///
if ((State & (ulong)StatusP.TestWithRefFlowmtr) != 0 && (State & (ulong)StatusP.FlowmtrNrMask) == 0)
@@ -167,12 +171,12 @@ namespace TBF.Rig.ControlBoard.Uni
if ((State & (ulong)StatusP.Flowmtr2Active) != 0)
{
ReferenceFreq[2] = (par2[1] != 0) ? (5.0f * par1[1] / par2[1]) : 0.0f;
ReferenceFreq[2] = (par2[1] != 0) ? (5000.0 * Convert.ToDouble(par1[1]) / Convert.ToDouble(par2[1])) : 0.0;
}
if ((State & (ulong)StatusP.Flowmtr3Active) != 0)
{
ReferenceFreq[3] = (par2[2] != 0) ? (5.0f * par1[2] / par2[2]) : 0.0f;
ReferenceFreq[3] = (par2[2] != 0) ? (5000.0 * Convert.ToDouble(par1[2]) / Convert.ToDouble(par2[2])) : 0.0;
}
ReferenceFreq[0] = ReferenceFreq[1] + ReferenceFreq[2] + ReferenceFreq[3];
@@ -191,6 +195,8 @@ namespace TBF.Rig.ControlBoard.Uni
EtPulses2 = Convert.ToInt32(GetUInt24(data, offs + (int)Poz.ETX2)); /// Byte 294,295,296
EtPulses3 = Convert.ToInt32(GetUInt24(data, offs + (int)Poz.ETX3)); /// Byte 297,298.299 !!!!!!!!!!!!!!!
log.InfoFormat("Et={0} State={1:X14} Freq={2}", (State & 7), (State & 0xFFFFFFFFFFFFFFF8UL), ReferenceFreq[0]);
}
}
+9 -11
View File
@@ -3,12 +3,15 @@
///
using System;
using System.Diagnostics;
using log4net;
using Dirichlet.Numerics;
namespace TBF.Rig.ControlBoard.Uni
{
public static class OutputMessage
{
private static readonly ILog log = LogManager.GetLogger(typeof(OutputMessage));
public const int PayloadLen = 38;
public const byte MessageCode = (byte)' ';
@@ -70,9 +73,9 @@ namespace TBF.Rig.ControlBoard.Uni
message[34] = 0; /// PrudParH
message[35] = (byte)Math.Max(1, Math.Min(255, action.PID)); /// PIDRV
message[36] = (byte)Math.Max(4, Math.Min(255, action.TolerRV)); /// TolerRV (4..20 mA reg.valve only)
message[36] = 0; // (byte)Math.Max(4, Math.Min(255, action.TolerRV)); /// TolerRV (4..20 mA reg.valve only)
message[37] = (byte)Math.Max(0, Math.Min(255, action.StabTime)); /// StabRV
message[38] = (byte)((action.DivThreshold >> 2) & 0xFF); /// HranAK
message[38] = 0x1A; // (byte)((action.DivThreshold >> 2) & 0xFF); /// HranAK
message[39] = 0;
message[40] = 0;
@@ -97,21 +100,16 @@ namespace TBF.Rig.ControlBoard.Uni
{
int param = action.FlowMId & (int)StartParam.EtalonMask;
if (action.IsDivUsed)
param |= (int)StartParam.DiverterStart;
if (action.IsSyncMethod)
param |= (int)StartParam.SynchroMethod;
else
param |= (int)StartParam.StartStopMethod;
if (action.IsDivUsed) param |= (int)StartParam.DiverterStart;
if (action.IsSyncMethod) param |= (int)StartParam.SynchroMethod;
if (action.IsStartStop) param |= (int)StartParam.StartStopMethod;
return (byte)param;
}
static byte GetStopParams(Action action)
{
int param = 0;
return (byte)param;
return (byte)0xFF;
}
}
+140 -68
View File
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using log4net;
using Common;
@@ -12,13 +13,14 @@ using Config.Entities;
using Dirichlet.Numerics;
using TBF.Rig.GenericDevices;
using TBF.Rig.Sequences;
using TBF.UiBridge;
namespace TBF.Rig.ControlBoard.Uni
{
public class UniCB : ComponentBase, IControlBoard, SchematicDrawing.IDrawingItCmpntWithMeasuredVal
{
private static readonly ILog log = LogManager.GetLogger(typeof(UniCB));
public override string ToString() { return string.Format("CBoard({0})", cbCfg != null ? cbCfg.ToString(1) : string.Empty); }
public override string ToString() { return string.Format("CBoard({0})", cbCfg != null ? cbCfg.ToString(-1) : string.Empty); }
/// TBF component configuration and useful wrappers
readonly UniCBCfg cbCfg;
@@ -36,13 +38,14 @@ namespace TBF.Rig.ControlBoard.Uni
{
get {
altString.Clear();
altString.AppendFormat("Stat: {0}.{1}.{2}.{3}\n", (State >> 48) & 0xFF, (State >> 40) & 0xFF, (State >> 32) & 0xFF, Convert.ToUInt32(State & 0xFFFFFFFF).ToString("X6"));
altString.AppendFormat("DI: {0}\n", ToBin40(DigitalInputs));
altString.AppendFormat("DO: {0}\n", ToBin40((UInt64)Route));
altString.AppendFormat("AI0 {0:D3} AI1 {1:D3} AI2 {2:D3} AI3 {3:D3} AI4 {4:D3} AI5 {5:D3} ",
altString.AppendFormat("DO: {0}\n", ToBin40(((UInt64)Route) >> 8));
altString.AppendFormat("AI0: {0:D3} AI1: {1:D3} AI2: {2:D3} AI3: {3:D3} AI4: {4:D3} AI5: {5:D3}\n",
AnalogInput(0), AnalogInput(1), AnalogInput(2), AnalogInput(3), AnalogInput(4), AnalogInput(5));
altString.AppendFormat("AI8 {0:D3} AI9 {1:D3} AI10 {2:D3} AI11 {3:D3}\n",
altString.AppendFormat("AI8: {0:D3} AI9: {1:D3} AI10: {2:D3} AI11: {3:D3}\n",
AnalogInput(8), AnalogInput(9), AnalogInput(10), AnalogInput(11));
altString.AppendFormat("Freq {0} Freq1 {0} Freq2 {0} Freq3 {0}", RefFrequency, RefFrequency1, RefFrequency2, RefFrequency3);
altString.AppendFormat("Freq: {0:F1} Hz", RefFrequency);
return altString.ToString();
}
}
@@ -69,19 +72,9 @@ namespace TBF.Rig.ControlBoard.Uni
}
}
/// Uni CB state
UInt32 currentOutputs;
bool outputsInitialized;
DateTime lastOutputsChange;
int lastStateMachineTime = 0;
/// Propagated from configurations of other components
UInt128 benchModelRoute;
UInt128 valvesToInvert; /// Route = valesToInvert ^ RequiredRouteWithoutInvertedVlaves
readonly UInt128 routeMask; /// This mask masks out virtual valves, routeMask is set in the constructor
///
/// Serial communication
///
SerialPort serialPort; /// Seral port or null: Check serialPort.IsOpen before using the serial port
const int BUFFER_SIZE = 4000; /// Size of input buffers
byte[] buffer; /// Buffer for data received in one attempt in RunDeviceBefore()
@@ -89,8 +82,20 @@ namespace TBF.Rig.ControlBoard.Uni
int[] cumulativeSums;
int rcvdBytesCount; /// Count of valid bytes in rcvdData buffer
///
/// Digital outputs, states of electromagnetic valves
///
UInt128 benchModelRoute;
UInt128 valvesToInvert; /// Propagated from configurations of other components
readonly UInt128 routeMask; /// This mask masks out virtual valves, routeMask is set in the constructor
bool outputsInitialized;
int lastStateMachineTime = 0;
/// UI actions are blocked when true
public bool IsUIBlocked { get; set; }
/// Message queue
Queue<Action> scheduledActionQueue;
Queue<Action> actionQueue;
/// Received data
public GeneralData Data;
@@ -98,9 +103,13 @@ namespace TBF.Rig.ControlBoard.Uni
ScopeAnalyzerData scopeAnalyzerData;
SwitchCountersData switchCounterData;
public UInt64 State { get { return Data.State; } } /// Control board state
/// Current flow meter ID
public int FlowmeterId { get { return Convert.ToInt32(Data.State & (ulong)StatusP.FlowmtrNrMask); } }
public UInt64 DigitalInputs { get { return Data.Vstupy; } } /// Digital inputs
public UInt64 State { get { return Data.State; } } /// Control board state
public UInt64 DigitalInputs { get { return Data.Vstupy; } } /// Digital inputs
public Int16 AnalogInput(int channel)
{
if (Data.AnalogInput != null && channel >= 0 && channel < Data.AnalogInput.Length)
@@ -121,11 +130,6 @@ namespace TBF.Rig.ControlBoard.Uni
public double RefFrequency2 { get { return Data.ReferenceFreq[2]; } }
public double RefFrequency3 { get { return Data.ReferenceFreq[3]; } }
public double RefFlow
{
get { return (Devices != null && Devices.FlowMeter != null) ? Devices.FlowMeter.ReadFlow() : 0.0; }
}
/// Last test results
public double TestTime { set; get; }
public int RefPulses { set; get; }
@@ -162,19 +166,12 @@ namespace TBF.Rig.ControlBoard.Uni
public UniCB(Generic.IComponentCfg cfg)
: base(cfg)
{
#if DEBUG
Debug.WriteLine("");
Debug.WriteLine("Uni CB enums");
Debug.WriteLine("");
foreach (var e in Enum.GetValues(typeof(Poz)))
{
Debug.WriteLine(string.Format("{0} ... {1}", e, ((int)e)));
}
#endif
cbCfg = cfg as UniCBCfg;
devices = new OutputPath(string.Empty, 0);
scheduledActionQueue = new Queue<Action>();
actionQueue = new Queue<Action>();
actionQueue.Enqueue(Action.Stop(false)); /// Stop all
outputsInitialized = false;
Data = new GeneralData();
divTransitionData = null;
@@ -364,27 +361,52 @@ namespace TBF.Rig.ControlBoard.Uni
if (!outputsInitialized || Data.Vystupy != (ulong)benchModelRoute || (StateMachine.Time - lastStateMachineTime) >= 15)
{
scheduledActionQueue.Enqueue(Action.ChangeRoute((ulong)benchModelRoute));
log.InfoFormat("Enqueue( ChangeRoute(route={0:X}) )", benchModelRoute);
foreach (var a in scheduledActionQueue) log.DebugFormat(" {0}", a);
var actionsToModify = actionQueue.Where(x => (x.ActionId == ActionID.ChangeRoute));
bool oneModified = false;
foreach (var a in actionsToModify)
{
if (oneModified)
{
log.ErrorFormat("ChangeRoute !!! TWO actions of the same type in the queue");
break; /// Do not modify more actions, this should never happen
}
oneModified = true;
a.Route = (ulong)benchModelRoute;
log.InfoFormat("ChangeRoute(route={0:X}) ... an action in the queue modified", benchModelRoute);
}
if (!oneModified)
{
actionQueue.Enqueue(Action.ChangeRoute(false, (ulong)benchModelRoute));
log.InfoFormat("ChangeRoute(route={0:X}) ... a new action enqueued", benchModelRoute);
}
foreach (var a in actionQueue) log.DebugFormat(" {0}", a);
}
var combinedAction = Action.FetchNonConflictingActions(scheduledActionQueue);
var combinedAction = Action.FetchNonConflictingActions(actionQueue); /// Default action is RequestDataOnly
byte[] outData = OutputMessage.GetMessage(combinedAction, config);
if (outData != null && outData.Length > 0)
{
if ((combinedAction.ActionId & ActionID.ChangeRoute) != 0)
{
outputsInitialized = true;
lastStateMachineTime = StateMachine.Time;
}
serialPort.Write(outData, 0, outData.Length);
string s = Telegram.LogTelegram("Sent: ", outData);
Debug.WriteLine(s);
log.Debug(s);
}
ProcessData.UpdateMeasuredValuesAndSetpoints();
TBF.UiBridge.Bridge.OnStateMachineTick(this, new TBF.UiBridge.StateMachineTickEventArgs(Route, ProcessData.MsrmntAvailableFlags,
ProcessData.MeasuredValues,
ProcessData.AltStrings,
ProcessData.Setpoints));
Bridge.OnStateMachineTick(this, new StateMachineTickEventArgs(Route, ProcessData.MsrmntAvailableFlags, ProcessData.MeasuredValues,
ProcessData.AltStrings, ProcessData.Setpoints));
}
public void StopDevice()
@@ -540,18 +562,45 @@ namespace TBF.Rig.ControlBoard.Uni
#endregion
public void MeasureFlow(int flowMeterId)
public void MeasureFlow(bool isFromUI, int flowMeterId)
{
scheduledActionQueue.Enqueue(Action.MeasureFlow(flowMeterId));
if (IsUIBlocked && isFromUI) return;
actionQueue.Enqueue(Action.MeasureFlow(isFromUI, flowMeterId));
log.InfoFormat("Enqueue( MeasureFlow(fm={0}) )", flowMeterId);
foreach (var a in scheduledActionQueue) log.DebugFormat(" {0}", a);
foreach (var a in actionQueue) log.DebugFormat(" {0}", a);
}
public void SetFlow(int flowMeterId, int regVId, double freqLo, double freqHi)
/// <summary>
/// To be used with a regulation valve controlled by incremental pulses.
/// Stability time is fixed: 200 ms
/// </summary>
public void SetFlow(bool isFromUI, int regVId, double freqLo, double freqHi)
{
scheduledActionQueue.Enqueue(Action.SetFlow(flowMeterId, regVId, freqLo, freqHi, Convert.ToInt32(Math.Round(Devices.PidCoef)), 0, 200));
log.InfoFormat("Enqueue( SetFlow(fm={0}, rv={1}, fLo={2}, fHi={3}, pid={4}) )", flowMeterId, regVId, freqLo, freqHi, Convert.ToInt32(Math.Round(Devices.PidCoef)));
foreach (var a in scheduledActionQueue) log.DebugFormat(" {0}", a);
if (IsUIBlocked && isFromUI) return;
actionQueue.Enqueue(Action.SetFlow(isFromUI, regVId, freqLo, freqHi, Convert.ToInt32(Math.Round(Devices.PidCoef)), 200));
log.InfoFormat("Enqueue( SetFlow(rv={0}, fLo={1}, fHi={2}, pid={3}) )", regVId, freqLo, freqHi, Convert.ToInt32(Math.Round(Devices.PidCoef)));
foreach (var a in actionQueue) log.DebugFormat(" {0}", a);
}
public void StartTest(bool isFromUI, int flowMId, int divId, int divThreshold, bool isSyncMethod,
bool isDivUsed, bool isStartStop, int totalPulsesCount, int massPulsesCount = -1)
{
if (IsUIBlocked && isFromUI) return;
actionQueue.Enqueue(Action.StartTest(isFromUI, flowMId, divId, divThreshold, isSyncMethod, isDivUsed, isStartStop, totalPulsesCount, massPulsesCount));
log.InfoFormat("Enqueue( StartTest(fm={0}, div={1}, Sync={2}, s/s={3}, withDiv={4}, totalPulsesCount={5}) )", flowMId, divId, isSyncMethod, isDivUsed, isStartStop, totalPulsesCount);
foreach (var a in actionQueue) log.DebugFormat(" {0}", a);
}
public void Stop(bool isFromUI)
{
if (IsUIBlocked && isFromUI) return;
actionQueue.Enqueue(Action.Stop(isFromUI));
log.InfoFormat("Enqueue( Stop() )");
foreach (var a in actionQueue) log.DebugFormat(" {0}", a);
}
/// <summary>
@@ -559,11 +608,35 @@ namespace TBF.Rig.ControlBoard.Uni
/// </summary>
/// <param name="rvId">Reg. valve ID</param>
/// <param name="time">Time in seconds, positive value opens the reg. valve</param>
public void RegVlvIncrMove(int regVId, double time)
public void RegVlvIncrMove(bool isFromUI, int regVId, double time)
{
scheduledActionQueue.Enqueue(Action.RegVlvIncrMove(regVId, time));
log.InfoFormat("Enqueue( RegVlvIncrMove(rv={0}, time={1}) )", regVId, time);
foreach (var a in scheduledActionQueue) log.DebugFormat(" {0}", a);
if (IsUIBlocked && isFromUI) return;
var newAction = Action.RegVlvIncrMove(isFromUI, regVId, time);
var actionsToModify = actionQueue.Where(x => (x.ActionId == ActionID.RegVlvIncrMove && x.RegVId == newAction.RegVId));
bool oneModified = false;
foreach (var a in actionsToModify)
{
if (oneModified)
{
log.ErrorFormat("RegVlvIncrMove !!! TWO actions of the same type in the queue");
break; /// Do not modify more actions, this should never happen
}
a.RVMovePar1 += newAction.RVMovePar1;
a.RVMovePar2 += newAction.RVMovePar2;
oneModified = true;
log.InfoFormat("RegVlvIncrMove(UI={0}, RV={1}, time={2}) ... an action in the queue modified", isFromUI, regVId, time);
}
if (!oneModified)
{
actionQueue.Enqueue(newAction);
log.InfoFormat("RegVlvIncrMove(UI={0}, RV={1}, time={2}) ... a new action enqueued", isFromUI, regVId, time);
}
foreach (var a in actionQueue) log.DebugFormat(" {0}", a);
}
/// <summary>
@@ -571,29 +644,28 @@ namespace TBF.Rig.ControlBoard.Uni
/// </summary>
/// <param name="rvId">Reg. valve ID</param>
/// <param name="position">Reg. valve position (0 .. 1.0)</param>
public void RegVlvMoveToPos(int regVId, double positionLo, double positionHi = -1)
public void RegVlvMoveToPos(bool isFromUI, int regVId, double positionLo, double positionHi = -1)
{
scheduledActionQueue.Enqueue(Action.RegVlvMoveToPos(regVId, positionLo, positionHi));
if (IsUIBlocked && isFromUI) return;
actionQueue.Enqueue(Action.RegVlvMoveToPos(isFromUI, regVId, positionLo, positionHi));
log.InfoFormat("Enqueue( RegVlvMoveToPos(rv={0}, positionLo={1}, positionHi={2}) )", regVId, positionLo, positionHi);
foreach (var a in scheduledActionQueue) log.DebugFormat(" {0}", a);
foreach (var a in actionQueue) log.DebugFormat(" {0}", a);
}
public void DiverterToTank(int divNr1)
public void SwitchDiverter(bool isFromUI, int divNr1, bool toTank)
{
scheduledActionQueue.Enqueue(Action.SwitchDiverter(divNr1, true));
log.InfoFormat("Enqueue( SwitchDiverter(div={0}, true) )", divNr1);
foreach (var a in scheduledActionQueue) log.DebugFormat(" {0}", a);
if (IsUIBlocked && isFromUI) return;
actionQueue.Enqueue(Action.SwitchDiverter(isFromUI, divNr1, toTank));
log.InfoFormat("Enqueue( SwitchDiverter(div={0}, toTank={1}) )", divNr1, toTank);
foreach (var a in actionQueue) log.DebugFormat(" {0}", a);
}
public void DiverterToSink(int divNr1)
public void ReadDiverterTransition(bool isFromUI, int divNr1)
{
scheduledActionQueue.Enqueue(Action.SwitchDiverter(divNr1, false));
log.InfoFormat("Enqueue( SwitchDiverter(div={0}, false) )", divNr1);
foreach (var a in scheduledActionQueue) log.DebugFormat(" {0}", a);
}
if (IsUIBlocked && isFromUI) return;
public void ReadDiverterTransition(int divNr1)
{
/// TODO
}
}
+2 -1
View File
@@ -102,7 +102,8 @@ namespace TBF.Rig.ControlBoard.Uni
{
if (i == -1)
{
return string.Format("{0}: COM{1}, VirtValvesRngLO={2}, VirtValvesRngeHI={3}", Name, ComPortNr, VirtValvesRangeLo, VirtValvesRangeHi);
return string.Format("{0}: COM{1} DIVs={2} VBs={3} RVs={4} VirtVRangeLo={5}, VirtVRangeHi={6}",
Name, ComPortNr, DivertersCount, DrainValvesCount, RegValvesCount, VirtValvesRangeLo, VirtValvesRangeHi);
}
switch (i)
+1 -1
View File
@@ -23,7 +23,7 @@ namespace TBF.Rig.Modbus.Common
public class Modbus : ComponentBase, IDevice, GenericDevices.IModbus
{
private static readonly ILog log = LogManager.GetLogger(typeof(Modbus));
public override string ToString() { return string.Format("Modbus({0})", Cfg.ToString(1)); }
public override string ToString() { return string.Format("Modbus({0})", Cfg.ToString(-1)); }
const int MinTelegramLen = 4;
@@ -13,7 +13,7 @@ namespace TBF.Rig.Modbus.PressureMeter.Meret
public class PressureMeter : ComponentBase, GenericDevices.IPressureMeter, IDevice, IDrawingItCmpntWithMeasuredVal
{
private static readonly ILog log = LogManager.GetLogger(typeof(PressureMeter));
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(1)); }
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
readonly PressureMeterCfg pressureMtrCfg;
public IDrawingItem DrawingItem { get { return pressureMtrCfg as IDrawingItem; } }
+1 -1
View File
@@ -15,7 +15,7 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
public class TempMeter : ComponentBase, GenericDevices.ITempMeter, GenericDevices.IHasCalendarEvents, SchematicDrawing.IDrawingItCmpntWithMeasuredVal
{
private static readonly ILog log = LogManager.GetLogger(typeof(TempMeter));
public override string ToString() { return string.Format("TempMeter({0})", Cfg.ToString(1)); }
public override string ToString() { return string.Format("TempMeter({0})", Cfg.ToString(-1)); }
readonly TempMeterCfg tempMtrCfg;
///
+1 -1
View File
@@ -13,7 +13,7 @@ namespace TBF.Rig.Modbus.TempMeter.Meret
public class TempMeter : ComponentBase, GenericDevices.ITempMeter, IDevice, IDrawingItCmpntWithMeasuredVal
{
private static readonly ILog log = LogManager.GetLogger(typeof(TempMeter));
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(1)); }
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
readonly TempMeterCfg tempMtrCfg;
public IDrawingItem DrawingItem { get { return tempMtrCfg as IDrawingItem; } }
@@ -406,7 +406,7 @@ namespace TBF.Rig.TestMethods.Adjustment
}
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
Bridge.OnProcessData(this, new ProcessDataEventArgs(test, repetitionNr, Config.Entities.Progress.Test));
@@ -559,7 +559,7 @@ namespace TBF.Rig.TestMethods.DiverterTest
//------------------------------------------------
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
@@ -356,7 +356,7 @@ namespace TBF.Rig.TestMethods.Endurance
//------------------------------------------------
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
@@ -588,7 +588,7 @@ namespace TBF.Rig.TestMethods.Endurance
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
}
@@ -627,7 +627,7 @@ namespace TBF.Rig.TestMethods.Endurance
//------------------------------------------------
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
@@ -656,7 +656,7 @@ namespace TBF.Rig.TestMethods.Endurance
}
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
@@ -583,7 +583,7 @@ namespace TBF.Rig.TestMethods.FixedStart
}
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
@@ -460,7 +460,7 @@ namespace TBF.Rig.TestMethods.FixedStartAdvanced
}
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
Bridge.OnProcessData(this, new ProcessDataEventArgs(test, repetitionNr, Config.Entities.Progress.Test));
@@ -621,7 +621,7 @@ namespace TBF.Rig.TestMethods.FixedStartDeferredEval
}
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
@@ -547,7 +547,7 @@ namespace TBF.Rig.TestMethods.FixedStartMassCollAdvanced
}
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
@@ -732,7 +732,7 @@ namespace TBF.Rig.TestMethods.FixedStartMassCollDeferredEval
}
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
@@ -709,7 +709,7 @@ namespace TBF.Rig.TestMethods.FixedStartMassCollection
}
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
@@ -547,7 +547,7 @@ namespace TBF.Rig.TestMethods.FixedStartTankCollection
}
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
@@ -447,7 +447,7 @@ namespace TBF.Rig.TestMethods.FlyingStart
//------------------------------------------------
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
@@ -635,7 +635,7 @@ namespace TBF.Rig.TestMethods.FlyingStartFirstRepetWithMassColl
//------------------------------------------------
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
@@ -742,7 +742,7 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollComparative
//------------------------------------------------
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
@@ -1204,7 +1204,7 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollProlonged
void DoInsideMeasurementLoop(ControlBoard.IControlBoard cBrd, HeatMeters.TestParams heatMetersTestParams, Config.Entities.Test test, int repetitionNr, int estimtdEndTime, bool showRemainingTimeMsg = true)
{
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
UpdateEnergy(heatMetersTestParams);
@@ -621,7 +621,7 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollection
//------------------------------------------------
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
@@ -440,7 +440,7 @@ namespace TBF.Rig.TestMethods.FlyingStartTankCollection
//------------------------------------------------
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
@@ -368,7 +368,7 @@ namespace TBF.Rig.TestMethods.PulsesTest
}
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
Bridge.OnProcessData(this, new ProcessDataEventArgs(test, repetitionNr, Config.Entities.Progress.Test));
@@ -370,7 +370,7 @@ namespace TBF.Rig.TestMethods.PulsesTestManual
}
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = cBrd.RefFlow;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics(StateMachine.Time);
Bridge.OnProcessData(this, new ProcessDataEventArgs(test, repetitionNr, Config.Entities.Progress.Test));
+6 -6
View File
@@ -15,7 +15,7 @@ namespace TBF.Rig.Uni.Diverter
public class Diverter : ComponentBase, IDevice, GenericDevices.IDiverter, GenericDevices.ISequenceCondition, GenericDevices.IHasCalendarEvents, SchematicDrawing.IDrawingItCmpnt
{
private static readonly ILog log = LogManager.GetLogger(typeof(Diverter));
public override string ToString() { return string.Format("Diverter({0})", Cfg.ToString(1)); }
public override string ToString() { return string.Format("Diverter({0})", Cfg.ToString(-1)); }
/// <summary>
@@ -93,8 +93,8 @@ namespace TBF.Rig.Uni.Diverter
// Name, cBoard.RegValveCalib.GetLength(0), diverterCfg.AdcNr);
//}
diverterToTankOp = new SwitchDiverterOp(cBoard, true, DiverterNr);
diverterToSinkOp = new SwitchDiverterOp(cBoard, false, DiverterNr);
diverterToTankOp = new SwitchDiverterOp(cBoard, DiverterNr, true);
diverterToSinkOp = new SwitchDiverterOp(cBoard, DiverterNr, false);
log.Warn(this.ToString());
}
@@ -196,15 +196,15 @@ namespace TBF.Rig.Uni.Diverter
}
else if (args.Command == CfgChangeCmd.DivToTank)
{
cBoard.DiverterToTank(diverterCfg.DivNr1);
cBoard.SwitchDiverter(true, diverterCfg.DivNr1, true);
}
else if (args.Command == CfgChangeCmd.DivToSink)
{
cBoard.DiverterToSink(diverterCfg.DivNr1);
cBoard.SwitchDiverter(true, diverterCfg.DivNr1, false);
}
else if (args.Command == CfgChangeCmd.ReadDivTransition)
{
cBoard.ReadDiverterTransition(diverterCfg.DivNr1);
cBoard.ReadDiverterTransition(true, diverterCfg.DivNr1);
}
}
};
+8 -13
View File
@@ -1,31 +1,26 @@
///
/// Copyright (c) 2021 Sensus Slovensko a.s.
///
using TBF.Rig.ControlBoard.Uni;
namespace TBF.Rig.Uni.Diverter
{
public class SwitchDiverterOp : IOperation
{
TBF.Rig.ControlBoard.Uni.UniCB cBoard;
bool toTank;
int diverterNr; /// 1 .. 5
readonly UniCB cBoard;
readonly int diverterNr; /// 1 .. 5
readonly bool toTank;
public SwitchDiverterOp(TBF.Rig.ControlBoard.Uni.UniCB cBoard, bool toTank, int diverterNr)
public SwitchDiverterOp(UniCB cBoard, int diverterNr, bool toTank)
{
this.cBoard = cBoard;
this.toTank = toTank;
this.diverterNr = diverterNr;
this.toTank = toTank;
}
public void Start()
{
if (toTank)
{
cBoard.DiverterToTank(diverterNr);
}
else
{
cBoard.DiverterToSink(diverterNr);
}
cBoard.SwitchDiverter(false, diverterNr, toTank);
}
public Event Run()
+57 -86
View File
@@ -14,24 +14,61 @@ namespace TBF.Rig.Uni.FlowMeter
public class FlowMeter : ComponentBase, Generic.IDevice, GenericDevices.IFlowMeter, GenericDevices.IHasCalendarEvents, IDrawingItCmpntWithMeasuredVal
{
private static readonly ILog log = LogManager.GetLogger(typeof(FlowMeter));
public override string ToString() { return string.Format("FlowMeter({0})", Cfg.ToString(1)); }
public override string ToString() { return string.Format("FlowMeter({0})", Cfg.ToString(-1)); }
readonly FlowMeterCfg flowMeterCfg;
public SchematicDrawing.IDrawingItem DrawingItem { get { return flowMeterCfg as SchematicDrawing.IDrawingItem; } }
readonly UniCB cBoard;
public bool MsrmntAvailable
{
get { return cBoard.Devices != null && cBoard.Devices.FlowMeter != null && cBoard.Devices.FlowMeter.Idx1 == Idx1; }
}
public double MeasuredVal { get { return cBoard.RefFrequency * NominalFlow / 2000.0; } }
public string AltString { get { return string.Format("Calibration expires on {0:dd.MM.yyyy}", flowMeterCfg.CalibValidDate); } }
public int Idx1 { get { return (flowMeterCfg != null) ? flowMeterCfg.Idx1 : 0; } }
public double NominalFlow { get { return (flowMeterCfg != null) ? flowMeterCfg.NominalFlow : 0; } }
public double LtrPerPulse { get { return (flowMeterCfg != null) ? flowMeterCfg.NominalFlow / 7200.0 : 0; } } /// Nominal frequency is 2000 Hz
public SchematicDrawing.IDrawingItem DrawingItem { get { return flowMeterCfg as SchematicDrawing.IDrawingItem; } }
public bool MsrmntAvailable
{
get {
if ((uniCB.State & (ulong)StatusP.TestWithRefFlowmtr) == 0) return false; /// Not a test with flow meter
if (uniCB.FlowmeterId == Idx1) return true; /// Flow meter is active, ID matches
if (uniCB.FlowmeterId == 0)
{
/// Measurement with parallel flow meters is active
switch (Idx1)
{
case 1: return (uniCB.State & (ulong)StatusP.Flowmtr1Active) != 0;
case 2: return (uniCB.State & (ulong)StatusP.Flowmtr2Active) != 0;
case 3: return (uniCB.State & (ulong)StatusP.Flowmtr3Active) != 0;
default: return false;
}
}
return false;
}
}
public double MeasuredVal { get { return NominalFlow * ReadFrequency() / 2000.0; } }
public string AltString { get { return string.Format("Calibration expires on {0:dd.MM.yyyy}", flowMeterCfg.CalibValidDate); } }
///
public double ReadFlow() { return NominalFlow * ReadFrequency() / 2000.0; }
///
public double ReadFrequency()
{
if (uniCB.FlowmeterId == Idx1) return uniCB.RefFrequency;
if (uniCB.FlowmeterId == 0)
{
switch (Idx1)
{
case 1: return (uniCB.State & (ulong)StatusP.Flowmtr1Active) != 0 ? uniCB.Data.ReferenceFreq[1] : 0;
case 2: return (uniCB.State & (ulong)StatusP.Flowmtr2Active) != 0 ? uniCB.Data.ReferenceFreq[2] : 0;
case 3: return (uniCB.State & (ulong)StatusP.Flowmtr3Active) != 0 ? uniCB.Data.ReferenceFreq[3] : 0;
default: return 0;
}
}
return 0;
}
public double LtrPerPulseCorrected(double flow, int rangeIx)
{
/// Apply correction
@@ -45,24 +82,18 @@ namespace TBF.Rig.Uni.FlowMeter
}
public bool RangeEnabled(int ix) { return flowMeterCfg.RangeEnabled(ix); }
public double GetTempLo(int ix) { return flowMeterCfg.GetTempLo(ix); }
public double GetTempHi(int ix) { return flowMeterCfg.GetTempHi(ix); }
public double GetPressLo(int ix) { return flowMeterCfg.GetPressLo(ix); }
public double GetPressHi(int ix) { return flowMeterCfg.GetPressHi(ix); }
readonly UniCB uniCB;
public FlowMeter()
{
}
public FlowMeter() { }
public FlowMeter(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
flowMeterCfg = cfg as FlowMeterCfg;
cBoard = TbfComponents.FindComponent(cfg.ParentName, components) as UniCB;
if (cBoard == null) throw new Exception(string.Format("Cannot find {0} (a parent of {1})", cfg.ParentName, Name));
uniCB = TbfComponents.FindComponent(cfg.ParentName, components) as UniCB;
if (uniCB == null) throw new Exception(string.Format("Cannot find {0} (a parent of {1})", cfg.ParentName, Name));
log.Warn(this.ToString());
}
@@ -74,8 +105,9 @@ namespace TBF.Rig.Uni.FlowMeter
{
for (int r = 0; r <= 5; r++)
{
if (RangeEnabled(r) && flowMeterCfg.GetCalibValidDate(r) != DateTime.MinValue
&& flowMeterCfg.GetCalibValidDate(r).Date < DateTime.Now.Date)
if (flowMeterCfg.RangeEnabled(r) &&
flowMeterCfg.GetCalibValidDate(r) != DateTime.MinValue &&
flowMeterCfg.GetCalibValidDate(r).Date < DateTime.Now.Date)
{
throw new Exception(string.Format("{0}/r{1}: {2}", Name, r, Strings.Calibration_certificate_validity_expired));
}
@@ -83,7 +115,7 @@ namespace TBF.Rig.Uni.FlowMeter
TBF.UiBridge.Bridge.MeasurementRequestHandler += delegate(object sender, TBF.UiBridge.MeasurementRequestArgs args)
{
if (args.Name == Name) { cBoard.MeasureFlow(Idx1); }
if (args.Name == Name) { uniCB.MeasureFlow(true, Idx1); } /// true = command is comming form the UI
};
log.FatalFormat("Successfully initialized device {0}", Name);
@@ -128,67 +160,6 @@ namespace TBF.Rig.Uni.FlowMeter
}
public bool IsActive
{
get
{
if ((cBoard.State & (ulong)StatusP.TestWithRefFlowmtr) == 0)
{
/// Not a test with flow meter
return false;
}
else if ((int)(cBoard.State & (ulong)StatusP.FlowmtrNrMask) == Idx1)
{
/// Flow meter is active, ID matches
return true;
}
else if ((int)(cBoard.State & (ulong)StatusP.FlowmtrNrMask) == 0)
{
/// Measurement with parallel flow meters is active
switch (Idx1)
{
case 1: return (cBoard.State & (ulong)StatusP.Flowmtr1Active) != 0;
case 2: return (cBoard.State & (ulong)StatusP.Flowmtr2Active) != 0;
case 3: return (cBoard.State & (ulong)StatusP.Flowmtr3Active) != 0;
default: return false;
}
}
else
{
return false;
}
}
}
public double ReadFrequency()
{
if ((int)(cBoard.State & (ulong)StatusP.FlowmtrNrMask) == Idx1)
{
return cBoard.RefFrequency;
}
else if (Idx1 == 1 && (cBoard.State & (ulong)StatusP.Flowmtr1Active) != 0)
{
return cBoard.Data.ReferenceFreq[1];
}
else if (Idx1 == 2 && (cBoard.State & (ulong)StatusP.Flowmtr2Active) != 0)
{
return cBoard.Data.ReferenceFreq[2];
}
else if (Idx1 == 3 && (cBoard.State & (ulong)StatusP.Flowmtr3Active) != 0)
{
return cBoard.Data.ReferenceFreq[3];
}
else
{
return 0;
}
}
public double ReadFlow()
{
return flowMeterCfg.NominalFlow * ReadFrequency() / 2000.0;
}
/// <summary>
/// Events: FlowDone, Error
/// </summary>
+1 -1
View File
@@ -48,7 +48,7 @@ namespace TBF.Rig.Uni.FlowMeter
/// </returns>
public Event Run()
{
if (flowMeter.IsActive)
if (flowMeter.MsrmntAvailable)
{
flowBox.Val = flowMeter.ReadFlow();
return eventDone;
+7 -16
View File
@@ -14,7 +14,7 @@ namespace TBF.Rig.Uni.RegValve
public class RegValve : ComponentBase, IDevice, GenericDevices.IRegValve, IDrawingItCmpntWithSetpoint
{
private static readonly ILog log = LogManager.GetLogger(typeof(RegValve));
public override string ToString() { return string.Format("RegulValve({0})", Cfg.ToString(1)); }
public override string ToString() { return string.Format("RegulValve({0})", Cfg.ToString(-1)); }
public readonly RegValveCfg regValveCfg;
@@ -65,23 +65,14 @@ namespace TBF.Rig.Uni.RegValve
public RegValveState RegValveState;
public double TargetRegValvePosition;
public void SendCommand(Command command, int v1, int v2, int v3, StopDevs v4)
{
/// TODO
}
public void SetFlow(int flowMeterId, double freqLo, double freqHi)
{
uniCB.SetFlow(flowMeterId, Idx1, freqLo, freqHi);
}
/// <summary>
/// Incremental movement of the regulation valve.
/// </summary>
/// <param name="time">Time in seconds, positive value opens the reg. valve</param>
public void IncrementalMovement(double time)
public void IncrementalMovement(bool isFromUI, double time)
{
uniCB.RegVlvIncrMove(Idx1, time);
uniCB.RegVlvIncrMove(isFromUI, Idx1, time);
}
/// <summary>
@@ -89,9 +80,9 @@ namespace TBF.Rig.Uni.RegValve
/// </summary>
/// <param name="rvId">Reg. valve ID</param>
/// <param name="position">Reg. valve position (0 .. 1.0)</param>
public void MoveToPosition(double positionLo, double positionHi = -1)
public void MoveToPosition(bool isFromUI, double positionLo, double positionHi = -1)
{
uniCB.RegVlvMoveToPos(Idx1, positionLo, positionHi);
uniCB.RegVlvMoveToPos(isFromUI, Idx1, positionLo, positionHi);
}
@@ -120,11 +111,11 @@ namespace TBF.Rig.Uni.RegValve
}
else if (args.Command == CfgChangeCmd.RVOpenStep)
{
IncrementalMovement(0.5);
IncrementalMovement(true, 0.5); /// true = command is comming from the UI
}
else if (args.Command == CfgChangeCmd.RVCloseStep)
{
IncrementalMovement(-0.5);
IncrementalMovement(true, -0.5); /// true = command is comming from the UI
}
else if (args.Command == CfgChangeCmd.GetAdc1 || args.Command == CfgChangeCmd.GetAdc2)
{
+24 -24
View File
@@ -19,9 +19,9 @@ namespace TBF.Rig.Uni.RegValve
}
/// Set by the constructor
readonly UniCB cBoard;
readonly UniCB uniCB;
readonly RegValve regV;
readonly int regulValveNr;
readonly int regValveId;
readonly IFlowMeter flowMeter;
readonly double shrinkedTgtFlowLo;
readonly double shrinkedTgtFlowHi;
@@ -81,8 +81,8 @@ namespace TBF.Rig.Uni.RegValve
public SetFlowOp(UniCB cBoard, IRegValve regValve, IFlowMeter flowMeter, double targetFlowLo, double targetFlowHi,
DoubleBox flowBox, bool reTryCmds, int timeout, bool leaveMeasurementRunning)
{
this.cBoard = cBoard;
if (this.cBoard == null) throw new ArgumentNullException("cBoard is null or not Uni");
this.uniCB = cBoard;
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("regValve is null or not Uni");
@@ -186,20 +186,20 @@ namespace TBF.Rig.Uni.RegValve
if (regV.regValveCfg.StoredPositionReuse && FetchTargetPosition(targetFlowAve, out targetPositionLo, out targetPositionHi))
{
log.InfoFormat("SetFlowOp:Start() rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3} FETCHED: posLo={4} posHi={5}",
regulValveNr, flowMeter.Idx1, currentReqFlowLo, currentReqFlowHi, targetPositionLo, targetPositionHi);
regValveId, flowMeter.Idx1, currentReqFlowLo, currentReqFlowHi, targetPositionLo, targetPositionHi);
opState = OpState.ValveMoveToPosition1;
}
else
{
log.InfoFormat("SetFlowOp:Start() rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regulValveNr, flowMeter.Idx1, currentReqFlowLo, currentReqFlowHi);
regValveId, flowMeter.Idx1, currentReqFlowLo, currentReqFlowHi);
opState = OpState.ValveMoveToFlow1;
}
/// Start flow measurement
regV.SendCommand(Command.Start, int.MaxValue, int.MaxValue, 0, 0); /// TestMethods=0, StopDevs=0
uniCB.MeasureFlow(false, flowMeter.Idx1);
}
/// <summary>Run this operation</summary>
@@ -222,7 +222,7 @@ namespace TBF.Rig.Uni.RegValve
}
log.InfoFormat("SetFlowOp:Run(T={0}) rv#={1} pos={2}% freq={3} flow={4} opState={5}",
StateMachine.Time - startTime, regulValveNr, rvPosition.ToString("F1"), flowMtrFreq, flow, opState);
StateMachine.Time - startTime, regValveId, rvPosition.ToString("F1"), flowMtrFreq, flow, opState);
if (StateMachine.Time > expireTime)
{
@@ -235,21 +235,21 @@ namespace TBF.Rig.Uni.RegValve
if (regV.regValveCfg.StoredPositionReuse && FetchTargetPosition(targetFlowAve, out targetPositionLo, out targetPositionHi))
{
log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3} FETCHED: posLo={4} posHi={5}",
regulValveNr, flowMeter.Idx1, currentReqFlowLo, currentReqFlowHi, targetPositionLo, targetPositionHi);
regValveId, flowMeter.Idx1, currentReqFlowLo, currentReqFlowHi, targetPositionLo, targetPositionHi);
opState = OpState.ValveMoveToPosition1;
}
else
{
log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regulValveNr, flowMeter.Idx1, currentReqFlowLo, currentReqFlowHi);
regValveId, flowMeter.Idx1, currentReqFlowLo, currentReqFlowHi);
opState = OpState.ValveMoveToFlow1;
}
/// Start flow measurement
regV.SendCommand(Command.Start, int.MaxValue, int.MaxValue, 0, 0); /// TestMethods=0, StopDevs=0
return Event.Starting;
uniCB.MeasureFlow(false, flowMeter.Idx1);
return Event.Starting;
}
else if (opState == OpState.ValveMoveToPosition1)
{
@@ -259,7 +259,7 @@ namespace TBF.Rig.Uni.RegValve
else if (opState == OpState.ValveMoveToPosition2) /// Move to position
{
/// Issues the appropriate ValveMove(...) command
regV.MoveToPosition(targetPositionLo, targetPositionHi);
regV.MoveToPosition(false, targetPositionLo, targetPositionHi);
opState = OpState.SettingPosition;
return Event.Starting;
@@ -278,7 +278,7 @@ namespace TBF.Rig.Uni.RegValve
}
else if (opState == OpState.CheckStatePosition) /// Verify
{
if ((cBoard.State & (ulong)StatusP.TestWithRefFlowmtr) == 0)
if ((uniCB.State & (ulong)StatusP.TestWithRefFlowmtr) == 0)
{
opState = OpState.SendCommandAgain;
return Event.Starting;
@@ -286,10 +286,10 @@ namespace TBF.Rig.Uni.RegValve
else if (regV.RegValveState != RegValveState.DacValueRegul)
{
/// Repeat appropriate ValveMove(...) command
regV.MoveToPosition(targetPositionLo, targetPositionHi);
regV.MoveToPosition(false, targetPositionLo, targetPositionHi);
log.InfoFormat("SetFlowOp: ValveMove({0}, Position, {1}, {2}, {3})",
regulValveNr, targetPositionLo, targetPositionHi, regV.StableTime);
regValveId, targetPositionLo, targetPositionHi, regV.StableTime);
opState = OpState.ValveMoveToPosition3;
return Event.Starting;
@@ -325,11 +325,11 @@ namespace TBF.Rig.Uni.RegValve
}
log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regulValveNr, flowMeter.Idx1, currentReqFlowLo, currentReqFlowHi);
regValveId, flowMeter.Idx1, currentReqFlowLo, currentReqFlowHi);
double freqLo = 2000.0 * currentReqFlowLo / nominalFlow;
double freqHi = 2000.0 * currentReqFlowHi / nominalFlow;
regV.SetFlow(flowMeter.Idx1,freqLo, freqHi);
uniCB.SetFlow(false, regV.Idx1, freqLo, freqHi);
opState = OpState.ValveMoveToFlow3;
return Event.Starting;
@@ -348,7 +348,7 @@ namespace TBF.Rig.Uni.RegValve
}
else if (opState == OpState.CheckStateFlow) /// Verify the flow setting
{
if ( (cBoard.State & (ulong)StatusP.TestWithRefFlowmtr) == 0 ||
if ( (uniCB.State & (ulong)StatusP.TestWithRefFlowmtr) == 0 ||
(regV.RegValveState & RegValveState.PwOrFreqRegul) != RegValveState.PwOrFreqRegul)
{
opState = OpState.SendCommandAgain;
@@ -359,10 +359,10 @@ namespace TBF.Rig.Uni.RegValve
/// Done once, issues an appropriate ValveMove(...) command
double freqLo = 2000.0 * currentReqFlowLo / nominalFlow;
double freqHi = 2000.0 * currentReqFlowHi / nominalFlow;
regV.SetFlow(flowMeter.Idx1, freqLo, freqHi);
uniCB.SetFlow(false, regV.Idx1, freqLo, freqHi);
log.InfoFormat("SetFlowOp: ValveMove({0}, Frequency, {1}, {2}, {3})",
regulValveNr, freqLo, freqHi, regV.StableTime);
regValveId, freqLo, freqHi, regV.StableTime);
opState = OpState.ValveMoveToFlow3;
return Event.Starting;
@@ -394,14 +394,14 @@ namespace TBF.Rig.Uni.RegValve
StoreTargetPosition(targetFlowAve, (rvPosition + storedPosition) / 2.0);
log.InfoFormat("Run(): rv#={0} reqFlow={1} pos={2}% stored={3} <--- Updating a stored position",
regulValveNr, targetFlowAve, rvPosition.ToString("F1"), storedPosition);
regValveId, targetFlowAve, rvPosition.ToString("F1"), storedPosition);
}
else
{
/// store the valve position
StoreTargetPosition(targetFlowAve, rvPosition);
log.InfoFormat("Run(): rv#={0} reqFlow={1} pos={2}% <--- Storing a new position",
regulValveNr, targetFlowAve, rvPosition.ToString("F1"));
regValveId, targetFlowAve, rvPosition.ToString("F1"));
}
}
@@ -440,7 +440,7 @@ namespace TBF.Rig.Uni.RegValve
if (!leaveMeasurementRunning)
{
/// Stop measurement
regV.SendCommand(Command.Stop, 50000, 50000, 0, StopDevs.RegValveRegulation); /// TestMethods=0
uniCB.Stop(false);
}
opState = OpState.Idle;
@@ -107,7 +107,7 @@ namespace TBF.Rig.Uni.RegValve
firstRun = false;
regV.MoveToPosition(posLoPct, posHiPct);
regV.MoveToPosition(false, posLoPct, posHiPct);
opState = OpState.CheckState;
return Event.None;
}