TBF.Rig.DataEntry.Double24
This commit is contained in:
parent
284feb73dc
commit
71517b6cdb
857
TBF/BenchControl/StateMachine.cs
Normal file
857
TBF/BenchControl/StateMachine.cs
Normal file
@ -0,0 +1,857 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using NHibernate;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using TBF.BenchControl.Generic;
|
||||
using TBF.BenchControl.GenericDevices;
|
||||
using TBF.BenchControl.Sequences;
|
||||
using Dirichlet.Numerics;
|
||||
using TBF.Resources;
|
||||
|
||||
namespace TBF.BenchControl
|
||||
{
|
||||
public enum MachineState
|
||||
{
|
||||
Undefined = 0,
|
||||
Disabled,
|
||||
StartingUp, /// Start-up: Initialize() of all devices + start of the worker thread
|
||||
FailedToStart, /// Most likely Initialize() of any device thrown an exception
|
||||
Running, /// RunDeviceBefore() and RunDeviceAfter() of all devices, Start()/Run()/Stop() of operations
|
||||
ShuttingDown, /// Shutdown: StopDevice() and StopDevice2() of all devices
|
||||
Off, /// Off after the shutdown
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This class controls real test bench behavior.
|
||||
/// It is based on a state machine
|
||||
/// </summary>
|
||||
public static class StateMachine
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(StateMachine));
|
||||
private static readonly ILog wlog = LogManager.GetLogger(typeof(StateMachine));
|
||||
|
||||
/// Private devices and components
|
||||
static IList<IComponent> components; /// list of all components
|
||||
static IList<IDevice> devices; /// list of devices
|
||||
///
|
||||
/// Bench paths
|
||||
static IList<Config.Entities.FeedingPath> feedingPaths;
|
||||
static IList<Config.Entities.BenchPath> benchPaths;
|
||||
static IList<Config.Entities.OutputPath> outputPaths;
|
||||
static IList<Config.Entities.MetersPath> metersPaths;
|
||||
static IList<Config.Entities.HeatMetersPath> heatMetersPaths;
|
||||
public static IList<Config.Entities.TransitionSequence> TransitionSequences;
|
||||
public static IList<Config.Entities.TransitionStep> TransitionSteps;
|
||||
|
||||
/// Public components
|
||||
public static Elde.ControlBoardDev ControlBoard;
|
||||
public static GenericDevices.IAmbient Ambient;
|
||||
public static IOperation BenchWaitingOp;
|
||||
public static IOperation BenchErrorOp;
|
||||
public static GenericDevices.IScaleOrTank Tank1;
|
||||
public static GenericDevices.IScaleOrTank Tank2;
|
||||
public static GenericDevices.IScaleOrTank Tank3;
|
||||
public static GenericDevices.IValve DrainValve1;
|
||||
public static GenericDevices.IValve DrainValve2;
|
||||
public static GenericDevices.IValve DrainValve3;
|
||||
public static IList<IValve> MasterValves; /// list of directly controlled valves
|
||||
public static IList<IValve> CoupledValves; /// list of coupled valves
|
||||
public static IList<Elde.ValveEx.Valve> ExtendedValves; /// list of extended valves
|
||||
|
||||
public static IList<string> LoopStartNames;
|
||||
public static IList<string> LoopEndNames;
|
||||
|
||||
/// Time and synchronization
|
||||
#if TURA_IPERL || TURA_IPERL_NEW
|
||||
public const int Period = 2; /// State machine period in sec.
|
||||
#else
|
||||
public const int Period = 1; /// State machine period in sec.
|
||||
#endif
|
||||
|
||||
static DateTime startDateTime; /// DateTime of time instance when the state machine worker thread starts
|
||||
static int currentTimeSec; /// Time from the start of the state machine in seconds
|
||||
|
||||
public static MachineState MachineState; /// see enum MachineState for explanation
|
||||
|
||||
/// Worker thread and database session
|
||||
static Thread workerThread;
|
||||
|
||||
static IList<State> states; /// list of states
|
||||
|
||||
public static DateTime CycleStartTimeStamp;
|
||||
|
||||
public static IList<IValve> DefaultValvesOpen
|
||||
{
|
||||
get
|
||||
{
|
||||
return GenericDevices.ValveBase.Merge(
|
||||
Utils.ValvesOpen((feedingPaths != null && feedingPaths.Count > 0) ? feedingPaths[0] : null),
|
||||
Utils.ValvesOpen((benchPaths != null && benchPaths.Count > 0) ? benchPaths[0] : null),
|
||||
Utils.ValvesOpen((outputPaths != null && outputPaths.Count > 0) ? outputPaths[0] : null)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static IList<IValve> DefaultValvesClose
|
||||
{
|
||||
get
|
||||
{
|
||||
return GenericDevices.ValveBase.Merge(
|
||||
Utils.ValvesClose((feedingPaths != null && feedingPaths.Count > 0) ? feedingPaths[0] : null),
|
||||
Utils.ValvesClose((benchPaths != null && benchPaths.Count > 0) ? benchPaths[0] : null),
|
||||
Utils.ValvesClose((outputPaths != null && outputPaths.Count > 0) ? outputPaths[0] : null)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loaded by LoadProcedure() or IOperation LoadProcedureOp(...)
|
||||
/// </summary>
|
||||
public static Procedure Procedure; /// Procedure
|
||||
public static TestInstance[] TestInstances; /// Tests
|
||||
public static bool IsRemoteProcedure;
|
||||
|
||||
|
||||
/// Hardware devices connected to the PC controlling the bench.
|
||||
public static IList<IComponent> Components { get { return components; } }
|
||||
public static IList<IDevice> Devices { get { return devices; } }
|
||||
|
||||
/// <summary>
|
||||
/// DateTime of time instance when the state machine worker thread starts
|
||||
/// </summary>
|
||||
public static DateTime StartDateTime { get { return startDateTime; } }
|
||||
|
||||
/// <summary>
|
||||
/// Current state name
|
||||
/// </summary>
|
||||
public static int Time
|
||||
{
|
||||
get { return currentTimeSec; }
|
||||
set { currentTimeSec = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
static StateMachine()
|
||||
{
|
||||
devices = new List<IDevice>();
|
||||
states = new List<State>();
|
||||
currentTimeSec = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a device to the state machine.
|
||||
/// </summary>
|
||||
/// <param name="obj">Device</param>
|
||||
public static void AddDevice(IDevice device)
|
||||
{
|
||||
if (device != null && !devices.Contains(device)) devices.Add(device);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a state to the state machine.
|
||||
/// In this way a sequence can be created programtically.
|
||||
/// </summary>
|
||||
/// <param name="obj">State</param>
|
||||
public static void AddState(State state)
|
||||
{
|
||||
if (state != null && !states.Contains(state)) states.Add(state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the state from the state machine.
|
||||
/// </summary>
|
||||
/// <param name="obj">State</param>
|
||||
public static void RemoveState(State state)
|
||||
{
|
||||
if (state != null && state != State.CurrentState && states.Contains(state)) states.Remove(state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a state from a label
|
||||
/// </summary>
|
||||
/// <param name="label"></param>
|
||||
/// <returns>The matching state or null</returns>
|
||||
static State GetStateFromLabel(string label)
|
||||
{
|
||||
if (label == null) return null;
|
||||
|
||||
foreach (State state in states)
|
||||
{
|
||||
if (state.Label != null && state.Label.Equals(label)) return state;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start the state machine in the state 'label' in a desired mode of operation.
|
||||
/// This method is called in the UI thread and creates a new state machine thread.
|
||||
/// This method call should be embedded in: try { StateMachine.Start(...); } catch { }
|
||||
/// to handle configuration problems. Calls CreateDevices(mode) and CreateStates().
|
||||
/// </summary>
|
||||
/// <param name="mode">Mode of operation</param>
|
||||
/// <param name="benchData">A copy of bench data used by the state machine</param>
|
||||
/// <param name="label">Identifies the initial state</param>
|
||||
#if DN100
|
||||
public static void InitializeBoardEtc(ControlCom2VB.ControlCom2panel ctrlBrdComponent)
|
||||
#elif FUZHOU_150 || MUNICH
|
||||
public static void InitializeBoardEtc(ControlComponent3Munich.UserControl1 ctrlBrdComponent)
|
||||
#elif FUZHOU_300
|
||||
public static void InitializeBoardEtc(ControlComponent3F300.UserControl1 ctrlBrdComponent)
|
||||
#elif BERLIN || GELSENWASSER || GENESIS || IZRAEL_200 || PETERSBURG_200 || PUCHONG_200 || SLM_150
|
||||
public static void InitializeBoardEtc(ControlComponent_Izrael2014.UserControl1 ctrlBrdComponent)
|
||||
#else /// all newer benches
|
||||
public static void InitializeBoardEtc(ControlComponent_Torino2015.UserControl1 ctrlBrdComponent)
|
||||
#endif
|
||||
{
|
||||
/// Load the list of components (entities) from the database.
|
||||
/// Then create the components (derived from IComponent).
|
||||
components = BenchControl.TbfComponents.LoadComponentsFromDB(TBF.DB.CreateSession(Common.DBKind.Config));
|
||||
MasterValves = GenericDevices.ValveBase.MasterValves(components);
|
||||
CoupledValves = GenericDevices.ValveBase.CoupledValves(components);
|
||||
ExtendedValves = GenericDevices.ValveBase.ExtendedValves(components);
|
||||
|
||||
/// Find all balances (to initialize tank capacities in the control board)
|
||||
/// Find the control board
|
||||
IList<IScaleOrTank> tanks = new List<IScaleOrTank>();
|
||||
ProcessData.IperlHeads = new List<TestMethods.iPerlCommunication.iPerlHead.IperlHead>();
|
||||
SequenceBase.FlowMeters = new List<IFlowMeter>();
|
||||
SequenceBase.RegulValves = new List<IRegValve>();
|
||||
SequenceBase.FeedingRegulValves = new List<IRegValve>();
|
||||
SequenceBase.OutputRegulValves = new List<IRegValve>();
|
||||
SequenceBase.PumpsWithFM = new List<IPumpFM>();
|
||||
SequenceBase.WaterMeters = new List<IWaterMeter>();
|
||||
SequenceBase.Cameras = new List<ICamera>();
|
||||
LoopStartNames = new List<string>();
|
||||
LoopEndNames = new List<string>();
|
||||
UInt128 valvesToInvert = 0;
|
||||
foreach (var cmpnt in components)
|
||||
{
|
||||
if (cmpnt is Elde.ControlBoardDev) ControlBoard = cmpnt as Elde.ControlBoardDev;
|
||||
if (cmpnt is IBenchInfo) ProcessData.BenchInfo = cmpnt as IBenchInfo;
|
||||
if (cmpnt is IErrorFlags) ProcessData.ErrorFlagsComp = cmpnt as IErrorFlags;
|
||||
if (cmpnt is IStatisticsMonitoring) ProcessData.StatisticsMonitoringComp = cmpnt as IStatisticsMonitoring;
|
||||
|
||||
if ((cmpnt is Output.DB.SensusOracle.Database) && (ProcessData.OracleDB == null))
|
||||
{
|
||||
/// The 1st Oracle database component found --> store the reference
|
||||
ProcessData.OracleDB = cmpnt as Output.DB.SensusOracle.Database;
|
||||
}
|
||||
if ((cmpnt is Output.DB.ProductionTracing.Tracing) && (ProcessData.TracingDB == null))
|
||||
{
|
||||
/// The 1st production tracing database component found --> store the reference
|
||||
ProcessData.TracingDB = cmpnt as Output.DB.ProductionTracing.Tracing;
|
||||
}
|
||||
|
||||
if (cmpnt is TestMethods.iPerlCommunication.iPerlHead.IperlHead)
|
||||
{
|
||||
ProcessData.IperlHeads.Add(cmpnt as TestMethods.iPerlCommunication.iPerlHead.IperlHead);
|
||||
}
|
||||
if (cmpnt is IFlowMeter) SequenceBase.FlowMeters.Add(cmpnt as IFlowMeter);
|
||||
if ((cmpnt is IRegValve) && !(cmpnt is BenchControl.Elde.RegulValveTandem.RegulValveTandem))
|
||||
{
|
||||
IRegValve rv = cmpnt as IRegValve;
|
||||
SequenceBase.RegulValves.Add(rv);
|
||||
if (rv.Category == ValveCategory.Feeding) SequenceBase.FeedingRegulValves.Add(rv);
|
||||
if (rv.Category == ValveCategory.Output) SequenceBase.OutputRegulValves.Add(rv);
|
||||
}
|
||||
if (cmpnt is IPumpFM && !(cmpnt is Elde.PumpTandem.Pump))
|
||||
{
|
||||
SequenceBase.PumpsWithFM.Add(cmpnt as IPumpFM);
|
||||
}
|
||||
if (cmpnt is IWaterMeter) SequenceBase.WaterMeters.Add(cmpnt as IWaterMeter);
|
||||
if (cmpnt is ICamera) SequenceBase.Cameras.Add(cmpnt as ICamera);
|
||||
if (cmpnt is GenericDevices.IAmbient) Ambient = cmpnt as GenericDevices.IAmbient;
|
||||
|
||||
if (cmpnt is GenericDevices.IParallelOutput && cmpnt.Name.ToLower().Contains("tower"))
|
||||
{
|
||||
BenchWaitingOp = (cmpnt as GenericDevices.IParallelOutput).ShowBenchWaitingOp();
|
||||
BenchErrorOp = (cmpnt as GenericDevices.IParallelOutput).ShowBenchErrorOp();
|
||||
}
|
||||
|
||||
if (cmpnt is ITestMethod && cmpnt.ClassName == "TestMethods.OuterLoop.Start") LoopStartNames.Add(cmpnt.Name);
|
||||
if (cmpnt is ITestMethod && cmpnt.ClassName == "TestMethods.OuterLoop.End") LoopEndNames.Add(cmpnt.Name);
|
||||
|
||||
if (cmpnt is IScaleOrTank)
|
||||
{
|
||||
IScaleOrTank tank = cmpnt as IScaleOrTank;
|
||||
tanks.Add(tank);
|
||||
if (Tank1 == null) Tank1 = tank;
|
||||
else if (Tank2 == null) Tank2 = tank;
|
||||
else if (Tank3 == null) Tank3 = tank;
|
||||
}
|
||||
|
||||
Elde.Valve.Valve eldeValve = (cmpnt as Elde.Valve.Valve);
|
||||
if ((eldeValve != null) && eldeValve.Inverted) valvesToInvert |= eldeValve.Mask;
|
||||
}
|
||||
|
||||
/// Pre-initialize the control board (= buffer the arguments ctrlBrdComponent, tankCapacities)
|
||||
if (ControlBoard != null)
|
||||
{
|
||||
/// Create an array with tank capacities from 'tanks' list
|
||||
double[] tankCapacities = new double[tanks.Count];
|
||||
for (int i = 0; i < tankCapacities.Length; i++) tankCapacities[i] = tanks[i].Capacity;
|
||||
|
||||
ControlBoard.InitializeEldeComponent(ctrlBrdComponent, valvesToInvert, tankCapacities);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Control board component is missing");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static string CurrentlyInitializedComponentName;
|
||||
///
|
||||
public static string InitializeComponents()
|
||||
{
|
||||
CurrentlyInitializedComponentName = "-";
|
||||
|
||||
bool anyComponentIsInSimulMode = false;
|
||||
StringBuilder inSimulMode = new StringBuilder();
|
||||
|
||||
/// Add all devices to the state machine and initialize them
|
||||
foreach (var cmpnt in components)
|
||||
{
|
||||
if (cmpnt.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
inSimulMode.AppendFormat("{0}{1}", anyComponentIsInSimulMode ? ", " : "", cmpnt.Name);
|
||||
anyComponentIsInSimulMode = true;
|
||||
}
|
||||
|
||||
if (cmpnt is IDevice)
|
||||
{
|
||||
devices.Add(cmpnt as IDevice); /// Only components that were initialized are added
|
||||
UiBridge.Bridge.OnActivity(null, cmpnt.Name); /// Info
|
||||
}
|
||||
|
||||
CurrentlyInitializedComponentName = cmpnt.Name;
|
||||
cmpnt.Initialize();
|
||||
cmpnt.StartChangeHandler(); /// Start handling parameter change events
|
||||
}
|
||||
|
||||
CurrentlyInitializedComponentName = "---";
|
||||
|
||||
///
|
||||
/// (1) Propagate debug levels from parents to children when necessary
|
||||
/// (2) Set drain valves DrainValve1, DrainValve2 and DrainValve3
|
||||
///
|
||||
foreach (var cmpnt in components)
|
||||
{
|
||||
if (cmpnt.Cfg is IChildComponentCfg && !string.IsNullOrEmpty(cmpnt.Cfg.ParentName) &&
|
||||
(cmpnt.Cfg.DebugLevel == DebugMode.Inherit || cmpnt.Cfg.DebugLevel == DebugMode.AutoDetect))
|
||||
{
|
||||
foreach (var par in components)
|
||||
{
|
||||
if (par.Cfg.Name.Equals(cmpnt.Cfg.ParentName)) { cmpnt.Cfg.DebugLevel = par.Cfg.DebugLevel; break; }
|
||||
}
|
||||
}
|
||||
|
||||
if (cmpnt is IScaleOrTank)
|
||||
{
|
||||
IScaleOrTank tank = cmpnt as IScaleOrTank;
|
||||
|
||||
if (tank == Tank1 && DrainValve1 == null)
|
||||
{
|
||||
DrainValve1 = tank.DrainValve;
|
||||
log.WarnFormat("InitializeComponents() ... Scale1={0} DrainValve1={1}",
|
||||
tank.Name, (DrainValve1 != null) ? DrainValve1.Name : "---");
|
||||
}
|
||||
else if (tank == Tank2 && DrainValve2 == null)
|
||||
{
|
||||
DrainValve2 = tank.DrainValve;
|
||||
log.WarnFormat("InitializeComponents() ... Scale2={0} DrainValve2={1}",
|
||||
tank.Name, (DrainValve2 != null) ? DrainValve2.Name : "---");
|
||||
}
|
||||
else if (tank == Tank3 && DrainValve3 == null)
|
||||
{
|
||||
DrainValve3 = tank.DrainValve;
|
||||
log.WarnFormat("InitializeComponents() ... Scale3={0} DrainValve3={1}",
|
||||
tank.Name, (DrainValve3 != null) ? DrainValve3.Name : "---");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (anyComponentIsInSimulMode)
|
||||
return inSimulMode.ToString();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop devices that were started by InitializeDevices().
|
||||
/// Works correctly also after exeption from InitializeDevices() as only ...
|
||||
/// ... correctly started devices were added in 'devices' list.
|
||||
/// </summary>
|
||||
public static void StopDevices()
|
||||
{
|
||||
for (int i = devices.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var dev = devices[i];
|
||||
UiBridge.Bridge.OnActivity(null, string.Format("1. {0}", dev.Name)); /// Info
|
||||
dev.StopDevice();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop devices that were started by InitializeDevices().
|
||||
/// Works correctly also after exeption from InitializeDevices() as only ...
|
||||
/// ... correctly started devices were added in 'devices' list.
|
||||
/// </summary>
|
||||
public static void StopDevices2()
|
||||
{
|
||||
for (int i = devices.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var dev = devices[i];
|
||||
UiBridge.Bridge.OnActivity(null, string.Format("2. {0}", dev.Name)); /// Info
|
||||
dev.StopDevice2();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks remote and local configuration DB paths and transitions for compatibility
|
||||
/// </summary>
|
||||
/// <returns>true when DB-s are compatible</returns>
|
||||
public static bool IsRemoteDBCompatible(out string message)
|
||||
{
|
||||
IList<Config.Entities.FeedingPath> remoteFeedingPaths;
|
||||
IList<Config.Entities.BenchPath> remoteBenchPaths;
|
||||
IList<Config.Entities.OutputPath> remoteOutputPaths;
|
||||
IList<Config.Entities.MetersPath> remoteMetersPaths;
|
||||
IList<Config.Entities.TransitionSequence> remoteTransitions;
|
||||
|
||||
try
|
||||
{
|
||||
ISession remoteSession = TBF.DB.CreateSession(Common.DBKind.RemoteConfig);
|
||||
remoteFeedingPaths = remoteSession.QueryOver<Config.Entities.FeedingPath>().List();
|
||||
remoteBenchPaths = remoteSession.QueryOver<Config.Entities.BenchPath>().List();
|
||||
remoteOutputPaths = remoteSession.QueryOver<Config.Entities.OutputPath>().List();
|
||||
remoteMetersPaths = remoteSession.QueryOver<Config.Entities.MetersPath>().List();
|
||||
remoteTransitions = remoteSession.QueryOver<Config.Entities.TransitionSequence>().List();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
message = "Cannot open remote database";
|
||||
return false;
|
||||
}
|
||||
|
||||
ISession localSession = TBF.DB.CreateSession(Common.DBKind.Config);
|
||||
var localFeedingPaths = localSession.QueryOver<Config.Entities.FeedingPath>().List();
|
||||
var localBenchPaths = localSession.QueryOver<Config.Entities.BenchPath>().List();
|
||||
var localOutputPaths = localSession.QueryOver<Config.Entities.OutputPath>().List();
|
||||
var localMetersPaths = localSession.QueryOver<Config.Entities.MetersPath>().List();
|
||||
var localTransitions = localSession.QueryOver<Config.Entities.TransitionSequence>().List();
|
||||
|
||||
string subMsg;
|
||||
if (!IsCompatible(localFeedingPaths, remoteFeedingPaths, out subMsg))
|
||||
{
|
||||
message = string.Format("Feeding: {0}", subMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsCompatible(localBenchPaths, remoteBenchPaths, out subMsg))
|
||||
{
|
||||
message = string.Format("Bench: {0}", subMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsCompatible(localOutputPaths, remoteOutputPaths, out subMsg))
|
||||
{
|
||||
message = string.Format("Output: {0}", subMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsCompatible(localMetersPaths, remoteMetersPaths, out subMsg))
|
||||
{
|
||||
message = string.Format("Sensors: {0}", subMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsCompatible(localTransitions, remoteTransitions, out subMsg))
|
||||
{
|
||||
message = string.Format("Transitions: {0}", subMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
message = string.Empty;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <typeparam name="T">FeedingPath, BenchPath, OutputPath, MetersPath or TransitionSequence</typeparam>
|
||||
/// <param name="localList">Local list of paths or transitions</param>
|
||||
/// <param name="remoteList">Remote list of paths or transitions</param>
|
||||
/// <param name="message">Message specifying a cause of incompatibility</param>
|
||||
/// <returns>true when lists are compatible, otherwise false</returns>
|
||||
private static bool IsCompatible<T>(IList<T> localList, IList<T> remoteList, out string message)
|
||||
{
|
||||
message = "Local list is empty";
|
||||
if ((localList == null) || (localList.Count == 0) || !(localList[0] is IHasName)) return false;
|
||||
|
||||
message = "Remote list is empty";
|
||||
if ((remoteList == null) || (remoteList.Count == 0) || !(remoteList[0] is IHasName)) return false;
|
||||
|
||||
///
|
||||
/// Each path or transition on a remote list must exist on a local list
|
||||
///
|
||||
foreach (var rItem in remoteList)
|
||||
{
|
||||
bool exists = false;
|
||||
foreach (var lItem in localList)
|
||||
{
|
||||
if ((rItem as IHasName).Name == (lItem as IHasName).Name)
|
||||
{
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
message = string.Format("Remote item {0} does not exist on a local list", (rItem as IHasName).Name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
message = string.Empty;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Start the state machine
|
||||
/// </summary>
|
||||
public static void Start()
|
||||
{
|
||||
if (MachineState != MachineState.StartingUp)
|
||||
{
|
||||
/// Unexpected MachineState (not MachineState.StartingUp) --> prevent worker thread from starting
|
||||
///
|
||||
MachineState = MachineState.FailedToStart;
|
||||
return;
|
||||
}
|
||||
|
||||
workerThread = new Thread(Worker);
|
||||
workerThread.CurrentCulture = Thread.CurrentThread.CurrentCulture;
|
||||
workerThread.CurrentUICulture = Thread.CurrentThread.CurrentUICulture;
|
||||
workerThread.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads all paths and transitions from the DB.
|
||||
/// Updates StatMachine.feedingPaths ... StatMachine.meterPaths, StatMachine.TransitionSequences
|
||||
/// </summary>
|
||||
public static void LoadPathsAndTransitions(ISession session)
|
||||
{
|
||||
feedingPaths = session.QueryOver<Config.Entities.FeedingPath>().OrderBy(x => x.ItemNr).Asc.List();
|
||||
benchPaths = session.QueryOver<Config.Entities.BenchPath>().OrderBy(x => x.ItemNr).Asc.List();
|
||||
outputPaths = session.QueryOver<Config.Entities.OutputPath>().OrderBy(x => x.ItemNr).Asc.List();
|
||||
metersPaths = session.QueryOver<Config.Entities.MetersPath>().OrderBy(x => x.ItemNr).Asc.List();
|
||||
TransitionSequences = session.QueryOver<TransitionSequence>().OrderBy(x => x.ItemNr).Asc.List();
|
||||
TransitionSteps = session.QueryOver<TransitionStep>().OrderBy(x => x.ItemNr).Asc.List();
|
||||
#if HEAT_METERS
|
||||
heatMetersPaths = session.QueryOver<Config.Entities.HeatMetersPath>().OrderBy(x => x.ItemNr).Asc.List();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads selected procedure from the DB.
|
||||
/// Updates StateMachine.Procedure and StateMachine.Tests
|
||||
/// </summary>
|
||||
public static bool LoadProcedure(ISession session, string procedureName, bool isRemote, IList<string> autoTests = null)
|
||||
{
|
||||
Procedure = null;
|
||||
|
||||
IList<Procedure> selectedProcs = session.QueryOver<Procedure>()
|
||||
.Where(x => (x.ProcedureState == Common.ProcedureState.Active))
|
||||
.And(x => (x.Name == procedureName))
|
||||
.List();
|
||||
if (selectedProcs.Count == 1)
|
||||
{
|
||||
IsRemoteProcedure = isRemote;
|
||||
Procedure = selectedProcs[0];
|
||||
TestInstances = selectedProcs[0].UpdateTestInstances(LoopStartNames, LoopEndNames, autoTests);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadProcedureParams(Procedure procedure)
|
||||
{
|
||||
foreach (var cmpnt in components)
|
||||
{
|
||||
cmpnt.Cfg.LoadProcedureParamsFromDB(procedure);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadTestParams(Test test)
|
||||
{
|
||||
foreach (var cmpnt in components)
|
||||
{
|
||||
cmpnt.Cfg.LoadTestParamsFromDB(test);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called from the sequence to update paths based on the selected test
|
||||
/// </summary>
|
||||
/// <param name="test">Selected test</param>
|
||||
/// <param name="pfeed"></param>
|
||||
/// <param name="pben"></param>
|
||||
/// <param name="pout"></param>
|
||||
/// <param name="pmtrs"></param>
|
||||
/// <param name="transitionBefore">Transition sequence entity</param>
|
||||
/// <param name="transitionAfter">Transition sequence entity</param>
|
||||
/// <param name="errorMsg">Error message in case of incorrect configuration</param>
|
||||
/// <returns>true when loaded configuration is correct (all four paths are defined !=null, etc.)</returns>
|
||||
public static bool GetPaths(Test test,
|
||||
bool heatMetersPathRequired,
|
||||
out FeedingPath pfeed,
|
||||
out BenchPath pben,
|
||||
out OutputPath pout,
|
||||
out MetersPath pmtrs,
|
||||
out HeatMetersPath phmtrs,
|
||||
out TransitionSequence transitionBefore,
|
||||
out TransitionSequence transitionBetween,
|
||||
out TransitionSequence transitionAfter,
|
||||
out string errorMsg)
|
||||
{
|
||||
ITestMethod tm = TbfComponents.FindComponent(test.Method) as ITestMethod;
|
||||
bool isHydroTest = (tm != null) ? tm.DoTransitions() : false;
|
||||
|
||||
pfeed = null;
|
||||
pben = null;
|
||||
pout = null;
|
||||
phmtrs = null;
|
||||
transitionBefore = null;
|
||||
transitionBetween = null;
|
||||
transitionAfter = null;
|
||||
|
||||
foreach (var path in feedingPaths)
|
||||
{
|
||||
if (test.FeedingPath == path.Name) { pfeed = new FeedingPath(path, components); break; }
|
||||
}
|
||||
|
||||
foreach (var path in benchPaths)
|
||||
{
|
||||
if (test.BenchPath == path.Name) { pben = new BenchPath(path, components); break; }
|
||||
}
|
||||
|
||||
foreach (var path in outputPaths)
|
||||
{
|
||||
if (test.OutputPath == path.Name) { pout = new OutputPath(path, components); break; }
|
||||
}
|
||||
|
||||
pmtrs = GetMetersPath(test);
|
||||
|
||||
if (isHydroTest && (pfeed == null)) errorMsg = Strings.Cannot_load_feeding_path;
|
||||
else if (isHydroTest && (pben == null)) errorMsg = Strings.Cannot_load_bench_path;
|
||||
else if (isHydroTest && (pout == null)) errorMsg = Strings.Cannot_load_output_path;
|
||||
else if (pmtrs == null) errorMsg = Strings.Cannot_load_sensor_path;
|
||||
else errorMsg = string.Empty;
|
||||
if ((isHydroTest && (pfeed == null || pben == null || pout == null)) || (pmtrs == null))
|
||||
{
|
||||
log.ErrorFormat("GetPaths({0},...) returns false, wrong configuration", test.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
#if HEAT_METERS
|
||||
foreach (var path in heatMetersPaths)
|
||||
{
|
||||
if (test.HeatMetersPath == path.Name) { phmtrs = new HeatMetersPath(path, components); break; }
|
||||
}
|
||||
#endif
|
||||
if (heatMetersPathRequired && phmtrs == null)
|
||||
{
|
||||
log.ErrorFormat("GetPaths({0},...) returns false, missing heat meters sensors", test.Name);
|
||||
errorMsg = "Cannot load heat meters sensors";
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var tr in TransitionSequences)
|
||||
{
|
||||
if (tr.Name == test.TransBefore) transitionBefore = tr;
|
||||
if (tr.Name == test.TransBetween) transitionBetween = tr;
|
||||
if (tr.Name == test.TransAfter) transitionAfter = tr;
|
||||
}
|
||||
|
||||
if (isHydroTest && pout.Scale == null)
|
||||
{
|
||||
log.ErrorFormat("GetPaths({0},...) returns false, missing scales in output path {1}", test.Name, test.OutputPath);
|
||||
errorMsg = string.Format("No balance specified in path {0}", test.OutputPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Config.Formulas.RealDensity() < 500.0f || Config.Formulas.RealDensity() > 2000.0f)
|
||||
{
|
||||
log.ErrorFormat("GetPaths({0},...) returns false, density was not specified", test.Name);
|
||||
errorMsg = string.Format("Density was not specified");
|
||||
return false;
|
||||
}
|
||||
|
||||
log.WarnFormat("GetPaths({0},...) returns true, paths loaded OK, isHydroTest={1}", test.Name, isHydroTest);
|
||||
errorMsg = string.Empty;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Updates paths based on the selected test
|
||||
/// </summary>
|
||||
public static MetersPath GetMetersPath(Test test)
|
||||
{
|
||||
MetersPath pmtrs = null;
|
||||
foreach (var path in metersPaths)
|
||||
{
|
||||
if (test.MetersPath == path.Name) { pmtrs = new MetersPath(path, components); break; }
|
||||
}
|
||||
if (pmtrs != null)
|
||||
{
|
||||
int count = Math.Min(TBF.Data.WMsCount, pmtrs.RegisterReaders.Length);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if ((pmtrs.RegisterReaders[i] != null) &&
|
||||
(pmtrs.RegisterReaders[i].Cfg.DebugLevel == DebugMode.DetectedOff))
|
||||
{
|
||||
pmtrs.RegisterReaders[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pmtrs;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is and example sequence of RunDeviceBefore() / RunOperations() / RunDeviceAfter() calls
|
||||
* as they are executed during normal run from the progran start to the end.
|
||||
*
|
||||
foreach (var device in devices) device.RunDeviceBefore(); . . . . . . in StateMachine.Worker()
|
||||
State.Create(...).AddOperation(...).AddOperation(...).EnterState() . . in the sequence in Execute(...)
|
||||
|
||||
foreach (var device in devices) device.RunDeviceAfter(); . . . . . . . in WaitRunDevsRunOps()
|
||||
WaitNextTick() (may throw QuitStateMachineException) . . . . . . . . in WaitRunDevsRunOps()
|
||||
foreach (var device in devices) device.RunDeviceBefore(); . . . . . . in WaitRunDevsRunOps()
|
||||
IList<Event> events = State.RunOperations(); . . . . . . . . . . . . . in WaitRunDevsRunOps()
|
||||
|
||||
foreach (var device in devices) device.RunDeviceAfter(); . . . . . . . in WaitRunDevsRunOps()
|
||||
WaitNextTick() (may throw QuitStateMachineException) . . . . . . . . in WaitRunDevsRunOps()
|
||||
foreach (var device in devices) device.RunDeviceBefore(); . . . . . . in WaitRunDevsRunOps()
|
||||
IList<Event> events = State.RunOperations(); . . . . . . . . . . . . . in WaitRunDevsRunOps()
|
||||
|
||||
State.Create(...).AddOperation(...).AddOperation(...).EnterState() . . in the sequence in Execute(...)
|
||||
|
||||
foreach (var device in devices) device.RunDeviceAfter(); . . . . . . . in WaitRunDevsRunOps()
|
||||
WaitNextTick() (may throw QuitStateMachineException) . . . . . . . . in WaitRunDevsRunOps()
|
||||
foreach (var device in devices) device.RunDeviceBefore(); . . . . . . in WaitRunDevsRunOps()
|
||||
IList<Event> events = State.RunOperations(); . . . . . . . . . . . . . in WaitRunDevsRunOps()
|
||||
|
||||
foreach (var device in devices) device.RunDeviceAfter(); . . . . . . . in WaitRunDevsRunOps()
|
||||
WaitNextTick() (assume QuitStateMachineException thrown) . . . . . . in WaitRunDevsRunOps()
|
||||
State.StopOperations(); . . . . . . . . . . . . . . . . . . . . . . . in StateMachine.Worker() catch()
|
||||
foreach (var device in devices) device.StopDevice(); . . . . . . . . . in StateMachine.Worker() catch()
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Worker thread: calls Start(), Run() and Stop() methods of operations.
|
||||
/// It uses 'currentState', 'nextState' and 'quitStateMachine' static fields.
|
||||
/// </summary>
|
||||
static void Worker()
|
||||
{
|
||||
MachineState = MachineState.Running;
|
||||
startDateTime = DateTime.Now;
|
||||
CycleStartTimeStamp = startDateTime; /// Do not leave CycleStartTimeStamp uninitialized
|
||||
wlog.InfoFormat(" currentTime = {0}s startDateTime = {1}", currentTimeSec.ToString(), startDateTime.ToString());
|
||||
|
||||
/// Run all devices for the first time
|
||||
foreach (var device in devices) device.RunDeviceBefore();
|
||||
|
||||
SequenceBase.ReferenceFlowmetersCount = SequenceBase.FlowMeters.Count;
|
||||
SequenceBase.CalibratedLtrPerRefPulse = new double[SequenceBase.ReferenceFlowmetersCount];
|
||||
foreach (var flowmtr in SequenceBase.FlowMeters)
|
||||
{
|
||||
int ix = flowmtr.Idx1;
|
||||
if (ix > 0 && ix <= SequenceBase.ReferenceFlowmetersCount)
|
||||
{
|
||||
SequenceBase.CalibratedLtrPerRefPulse[ix - 1] = flowmtr.NominalFlow / 7200.0;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Run the main sequence
|
||||
///
|
||||
(new Sequences.MainSeq()).Execute();
|
||||
|
||||
StateMachine.MachineState = MachineState.Off; /// Update StateMachine.MachineState
|
||||
TBF.UiBridge.Bridge.Bench2UI(TBF.UiBridge.ButtonsEtc.Shutdown); /// Let UI know the state machine is shut down now
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Do stuff that is repeated in the state execution loops most often
|
||||
/// </summary>
|
||||
/// <returns>List of Event-s returned from the state operations, null == quit</returns>
|
||||
public static IList<Event> WaitRunDevsRunOps(bool lastTime = false)
|
||||
{
|
||||
Thread.Sleep(100); /// Insert 1/10 sec.delay between RunOperations() and RunDeviceAfter()
|
||||
|
||||
for (int i = devices.Count - 1; i >= 0; i-- )
|
||||
{
|
||||
devices[i].RunDeviceAfter();
|
||||
}
|
||||
|
||||
WaitNextTick();
|
||||
|
||||
if (lastTime)
|
||||
{
|
||||
///
|
||||
/// Executed when the state machine is being stopped
|
||||
///
|
||||
State.StopOperations();
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var device in devices)
|
||||
{
|
||||
device.RunDeviceBefore();
|
||||
}
|
||||
|
||||
Thread.Sleep(100); /// Insert 1/10 sec.delay between RunDeviceBefore() and RunOperations()
|
||||
|
||||
return State.RunOperations(); /// Returns events from all running operations
|
||||
/// This is followed by a state change in the sequence
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Wait time period - synchronize
|
||||
/// </summary>
|
||||
/// <returns>true when interrupted by 'quitStateMachine', otherwise false</returns>
|
||||
public static void WaitNextTick()
|
||||
{
|
||||
int currentTimeSecFromClock = Convert.ToInt32(Math.Round((DateTime.Now - startDateTime).TotalSeconds - 0.2));
|
||||
|
||||
currentTimeSec = Math.Max(currentTimeSec, currentTimeSecFromClock) + Period;
|
||||
|
||||
DateTime nextTickDateTime = startDateTime + TimeSpan.FromSeconds(currentTimeSec);
|
||||
|
||||
while (DateTime.Now < nextTickDateTime)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14,12 +14,15 @@ namespace TBF.Rig.DataContainers.BenchInfo.Extended
|
||||
/// <summary>
|
||||
/// Holds information identifying the test bench - serializable configuration.
|
||||
/// </summary>
|
||||
public class ComponentCfg : ComponentCfgBase, Generic.IComponentCfg, Config.Entities.IParamsProvider
|
||||
public class ComponentCfg : ComponentCfgBase, Generic.IComponentCfg, IParamsProvider
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(ComponentCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new Configs.ParamsProvider.ComponentCfgCtrl(this, null); }
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities)
|
||||
{
|
||||
return new Configs.ParamsProvider.ComponentCfgCtrl(this, null);
|
||||
}
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
@ -151,11 +154,6 @@ namespace TBF.Rig.DataContainers.BenchInfo.Extended
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
if (i == -1)
|
||||
{
|
||||
return string.Format("{0}: Bench name={1}, Bench Id={2}, Procedures={3}", Name, TestBenchName, TestBenchId, RemoteDBUse.ToDescription());
|
||||
}
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0: return TestBenchName;
|
||||
@ -175,7 +173,8 @@ namespace TBF.Rig.DataContainers.BenchInfo.Extended
|
||||
case 14: return TempUnit.ToDescription();
|
||||
case 15: return PressUnit.ToDescription();
|
||||
case 16: return LenghtUnit.ToDescription();
|
||||
default: return string.Empty;
|
||||
default:
|
||||
return string.Format("{0}: Bench name={1}, Bench Id={2}, Procedures={3}", Name, TestBenchName, TestBenchId, RemoteDBUse.ToDescription());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
///
|
||||
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
||||
///
|
||||
namespace TBF.Rig.DataEntry.Fewa
|
||||
namespace TBF.Rig.DataEntry.Double24
|
||||
{
|
||||
partial class CycleBeginningForm
|
||||
{
|
||||
@ -134,6 +134,10 @@ namespace TBF.Rig.DataEntry.Fewa
|
||||
this.suffixComboBox15 = new System.Windows.Forms.ComboBox();
|
||||
this.suffixComboBox14 = new System.Windows.Forms.ComboBox();
|
||||
this.suffixComboBox13 = new System.Windows.Forms.ComboBox();
|
||||
this.snLabel = new System.Windows.Forms.Label();
|
||||
this.snLabel2 = new System.Windows.Forms.Label();
|
||||
this.column2Label = new System.Windows.Forms.Label();
|
||||
this.columnm2Label2 = new System.Windows.Forms.Label();
|
||||
this.orderGroupBox.SuspendLayout();
|
||||
this.prefixGroupBox.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
@ -877,11 +881,35 @@ namespace TBF.Rig.DataEntry.Fewa
|
||||
this.suffixComboBox13.TextChanged += new System.EventHandler(this.suffixComboBox13_TextChanged);
|
||||
this.suffixComboBox13.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.suffixComboBox13_KeyPress);
|
||||
//
|
||||
// snLabel
|
||||
//
|
||||
resources.ApplyResources(this.snLabel, "snLabel");
|
||||
this.snLabel.Name = "snLabel";
|
||||
//
|
||||
// snLabel2
|
||||
//
|
||||
resources.ApplyResources(this.snLabel2, "snLabel2");
|
||||
this.snLabel2.Name = "snLabel2";
|
||||
//
|
||||
// column2Label
|
||||
//
|
||||
resources.ApplyResources(this.column2Label, "column2Label");
|
||||
this.column2Label.Name = "column2Label";
|
||||
//
|
||||
// columnm2Label2
|
||||
//
|
||||
resources.ApplyResources(this.columnm2Label2, "columnm2Label2");
|
||||
this.columnm2Label2.Name = "columnm2Label2";
|
||||
//
|
||||
// CycleBeginningForm
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.DarkGray;
|
||||
this.Controls.Add(this.columnm2Label2);
|
||||
this.Controls.Add(this.column2Label);
|
||||
this.Controls.Add(this.snLabel2);
|
||||
this.Controls.Add(this.snLabel);
|
||||
this.Controls.Add(this.suffixComboBox24);
|
||||
this.Controls.Add(this.suffixComboBox23);
|
||||
this.Controls.Add(this.suffixComboBox22);
|
||||
@ -1098,5 +1126,9 @@ namespace TBF.Rig.DataEntry.Fewa
|
||||
private System.Windows.Forms.ComboBox suffixComboBox15;
|
||||
private System.Windows.Forms.ComboBox suffixComboBox14;
|
||||
private System.Windows.Forms.ComboBox suffixComboBox13;
|
||||
private System.Windows.Forms.Label snLabel;
|
||||
private System.Windows.Forms.Label snLabel2;
|
||||
private System.Windows.Forms.Label column2Label;
|
||||
private System.Windows.Forms.Label columnm2Label2;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
///
|
||||
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -7,7 +7,7 @@ using System.Windows.Forms;
|
||||
using log4net;
|
||||
using TBF.Resources;
|
||||
|
||||
namespace TBF.Rig.DataEntry.Fewa
|
||||
namespace TBF.Rig.DataEntry.Double24
|
||||
{
|
||||
public partial class CycleBeginningForm : Form, GenericDevices.IHasCompleted
|
||||
{
|
||||
@ -15,12 +15,14 @@ namespace TBF.Rig.DataEntry.Fewa
|
||||
|
||||
/// <summary> Number of water meters </summary>
|
||||
public readonly int WMsCount;
|
||||
readonly EntryFormCfg entryFormCfg;
|
||||
|
||||
/// To be retrieved after the form is closed
|
||||
public string PurchaseOrder;
|
||||
public string Prefix;
|
||||
public string[] SNText;
|
||||
public string[] SN2Text;
|
||||
string[] suffixText;
|
||||
public string[] Column2Text;
|
||||
public string[] suffixText;
|
||||
public bool[] Disabled;
|
||||
|
||||
/// Set to 'true' when the form closes
|
||||
@ -31,7 +33,7 @@ namespace TBF.Rig.DataEntry.Fewa
|
||||
int textBoxesCount;
|
||||
Label[] labels;
|
||||
ComboBox[] comboBoxes;
|
||||
ComboBox[] suffixComboBoxes;
|
||||
ComboBox[] column2ComboBoxes;
|
||||
CheckBox[] checkBoxes;
|
||||
IList<ComboBox> enabledComboBoxes;
|
||||
|
||||
@ -56,7 +58,7 @@ namespace TBF.Rig.DataEntry.Fewa
|
||||
comboBox13, comboBox14, comboBox15, comboBox16, comboBox17, comboBox18,
|
||||
comboBox19, comboBox20, comboBox21, comboBox22, comboBox23, comboBox24,
|
||||
};
|
||||
suffixComboBoxes = new ComboBox[]
|
||||
column2ComboBoxes = new ComboBox[]
|
||||
{
|
||||
suffixComboBox1, suffixComboBox2, suffixComboBox3, suffixComboBox4, suffixComboBox5, suffixComboBox6,
|
||||
suffixComboBox7, suffixComboBox8, suffixComboBox9, suffixComboBox10, suffixComboBox11, suffixComboBox12,
|
||||
@ -80,15 +82,27 @@ namespace TBF.Rig.DataEntry.Fewa
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="waterMetersCount">Number of text boxes for serial numbers</param>
|
||||
public CycleBeginningForm(int waterMetersCount)
|
||||
public CycleBeginningForm(int waterMetersCount, EntryFormCfg entryFormCfg)
|
||||
: this()
|
||||
{
|
||||
this.WMsCount = waterMetersCount;
|
||||
this.entryFormCfg = entryFormCfg;
|
||||
|
||||
SNText = new string[WMsCount];
|
||||
SN2Text = new string[WMsCount];
|
||||
Column2Text = new string[WMsCount];
|
||||
suffixText = new string[WMsCount];
|
||||
Disabled = new bool[WMsCount];
|
||||
|
||||
if (entryFormCfg.HideOrderSelection)
|
||||
orderGroupBox.Visible = false;
|
||||
else
|
||||
PrepareOrderCombo(orderComboBox);
|
||||
|
||||
if (entryFormCfg.HidePrefix)
|
||||
prefixGroupBox.Visible = false;
|
||||
else
|
||||
PreparePrefixCombo(prefixComboBox);
|
||||
|
||||
ShuffleTextBoxes(TBF.Data.WMsCount, TBF.Data.LineSize);
|
||||
|
||||
//Height = 147 + WaterMetersCount * 90;
|
||||
@ -114,7 +128,7 @@ namespace TBF.Rig.DataEntry.Fewa
|
||||
{
|
||||
labels[dest] = labels[l * lineSize + l * gap + i];
|
||||
comboBoxes[dest] = comboBoxes[l * lineSize + l * gap + i];
|
||||
suffixComboBoxes[dest] = suffixComboBoxes[l * lineSize + l * gap + i];
|
||||
column2ComboBoxes[dest] = column2ComboBoxes[l * lineSize + l * gap + i];
|
||||
checkBoxes[dest] = checkBoxes[l * lineSize + l * gap + i];
|
||||
dest++;
|
||||
}
|
||||
@ -127,21 +141,18 @@ namespace TBF.Rig.DataEntry.Fewa
|
||||
{
|
||||
Localize();
|
||||
|
||||
PrepareOrderCombo(orderComboBox);
|
||||
PreparePrefixCombo(prefixComboBox);
|
||||
|
||||
for (int i = 0; i < textBoxesCount; i++)
|
||||
{
|
||||
if (Program.LocalSettings.LastSNTextsCount == textBoxesCount)
|
||||
{
|
||||
comboBoxes[i].Items.Add((Program.LocalSettings.LastSNTexts[i] == null) ? string.Empty : Program.LocalSettings.LastSNTexts[i]);
|
||||
suffixComboBoxes[i].Items.Add((Program.LocalSettings.LastAuxSNTexts[i] == null) ? string.Empty : Program.LocalSettings.LastAuxSNTexts[i]);
|
||||
column2ComboBoxes[i].Items.Add((Program.LocalSettings.LastAuxSNTexts[i] == null) ? string.Empty : Program.LocalSettings.LastAuxSNTexts[i]);
|
||||
}
|
||||
|
||||
labels[i].Visible = comboBoxes[i].Visible = suffixComboBoxes[i].Visible = checkBoxes[i].Visible = true;
|
||||
labels[i].Visible = comboBoxes[i].Visible = column2ComboBoxes[i].Visible = checkBoxes[i].Visible = true;
|
||||
|
||||
enabledComboBoxes.Add(comboBoxes[i]);
|
||||
enabledComboBoxes.Add(suffixComboBoxes[i]);
|
||||
enabledComboBoxes.Add(column2ComboBoxes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,12 +160,11 @@ namespace TBF.Rig.DataEntry.Fewa
|
||||
{
|
||||
Text = Strings.Data;
|
||||
orderGroupBox.Text = Strings.Purchase_order;
|
||||
for (int i = 0; i < textBoxesCount; i++)
|
||||
{
|
||||
labels[i].Text = Strings.Serial_Number + " " + (i + 1).ToString();
|
||||
}
|
||||
for (int i = 0; i < textBoxesCount; i++) labels[i].Text = (i + 1).ToString();
|
||||
okButton.Text = Strings.OkBtnText;
|
||||
clearButton.Text = Strings.ClearBtnText;
|
||||
|
||||
column2Label.Text = columnm2Label2.Text = entryFormCfg.Column2Caption;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -190,12 +200,13 @@ namespace TBF.Rig.DataEntry.Fewa
|
||||
for (int i = 0; i < Math.Min(WMsCount, textBoxesCount); i++)
|
||||
{
|
||||
SNText[i] = comboBoxes[i].Text;
|
||||
suffixText[i] = suffixComboBoxes[i].Text;
|
||||
SN2Text[i] = string.Format("{0}{1}", prefixComboBox.Text, suffixComboBoxes[i].Text);
|
||||
suffixText[i] = column2ComboBoxes[i].Text;
|
||||
Column2Text[i] = string.Format("{0}{1}", prefixComboBox.Text, column2ComboBoxes[i].Text);
|
||||
Disabled[i] = !checkBoxes[i].Checked;
|
||||
}
|
||||
|
||||
PurchaseOrder = orderComboBox.Text;
|
||||
PurchaseOrder = entryFormCfg.HideOrderSelection ? string.Empty : orderComboBox.Text;
|
||||
Prefix = entryFormCfg.HidePrefix ? string.Empty : prefixComboBox.Text;
|
||||
Program.LocalSettings.UpdateHistory(orderComboBox.Text, ref Program.LocalSettings.PurchaseOrderHistory);
|
||||
Program.LocalSettings.UpdateHistory(prefixComboBox.Text, ref Program.LocalSettings.PrefixHistory);
|
||||
Program.LocalSettings.LastSNTexts = SNText;
|
||||
@ -273,8 +284,8 @@ namespace TBF.Rig.DataEntry.Fewa
|
||||
for (int i = 0; i < Math.Min(WMsCount, textBoxesCount); i++)
|
||||
{
|
||||
if (Program.LocalSettings.LastSNTextsCount > i) comboBoxes[i].Text = Program.LocalSettings.LastSNTexts[i];
|
||||
if (Program.LocalSettings.LastAuxSNTextsCount > i) suffixComboBoxes[i].Text = Program.LocalSettings.LastAuxSNTexts[i];
|
||||
checkBoxes[i].Checked = !string.IsNullOrEmpty(comboBoxes[i].Text) || !string.IsNullOrEmpty(suffixComboBoxes[i].Text);
|
||||
if (Program.LocalSettings.LastAuxSNTextsCount > i) column2ComboBoxes[i].Text = Program.LocalSettings.LastAuxSNTexts[i];
|
||||
checkBoxes[i].Checked = !string.IsNullOrEmpty(comboBoxes[i].Text) || !string.IsNullOrEmpty(column2ComboBoxes[i].Text);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
///
|
||||
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
||||
///
|
||||
namespace TBF.Rig.DataEntry.Fewa
|
||||
namespace TBF.Rig.DataEntry.Double24
|
||||
{
|
||||
partial class CycleEndForm
|
||||
{
|
||||
@ -1,12 +1,12 @@
|
||||
///
|
||||
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using log4net;
|
||||
using TBF.Resources;
|
||||
|
||||
namespace TBF.Rig.DataEntry.Fewa
|
||||
namespace TBF.Rig.DataEntry.Double24
|
||||
{
|
||||
public partial class CycleEndForm : Form, GenericDevices.IHasCompleted
|
||||
{
|
||||
@ -1,9 +1,9 @@
|
||||
///
|
||||
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using TBF.Rig.GenericDevices;
|
||||
|
||||
namespace TBF.Rig.DataEntry.Fewa
|
||||
namespace TBF.Rig.DataEntry.Double24
|
||||
{
|
||||
public class EntryForm : EntryFormNoStartEnd, IHasWMStatesForm
|
||||
{
|
||||
206
TBF/Rig/DataEntry/Double24/EntryFormCfg.cs
Normal file
206
TBF/Rig/DataEntry/Double24/EntryFormCfg.cs
Normal file
@ -0,0 +1,206 @@
|
||||
///
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using Common;
|
||||
using Config;
|
||||
using Config.Entities;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.DataEntry.Double24
|
||||
{
|
||||
public class EntryFormCfg : ComponentCfgBase, Generic.IComponentCfg, IParamsProvider
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(EntryFormCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities)
|
||||
{
|
||||
return new Configs.ParamsProvider.ComponentCfgCtrl(this, null);
|
||||
}
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
public bool EnterSerialNrsAtTheEnd;
|
||||
public bool ShowCycleEndForm;
|
||||
public bool HideOrderSelection;
|
||||
public bool HidePrefix;
|
||||
public string Column2Caption;
|
||||
public Col2Dest Column2Destination;
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
EntryFormCfg() { }
|
||||
|
||||
public EntryFormCfg(IComponentFactory factory, string name)
|
||||
: this()
|
||||
{
|
||||
this.Factory = factory;
|
||||
this.Name = name;
|
||||
ParentName = string.Empty;
|
||||
InitializeAll();
|
||||
}
|
||||
|
||||
public string ComponentName { get { return Name; } }
|
||||
|
||||
public void InitializeAll()
|
||||
{
|
||||
EnterSerialNrsAtTheEnd = false;
|
||||
ShowCycleEndForm = false;
|
||||
HideOrderSelection = false;
|
||||
HidePrefix = true;
|
||||
Column2Caption = "Radio address";
|
||||
Column2Destination = Col2Dest.RadioAddress;
|
||||
}
|
||||
|
||||
string[] paramNames = new string[]
|
||||
{
|
||||
Strings.Enter_SNs_at_the_end,
|
||||
Strings.Show_cycle_end_form,
|
||||
"Hide order selection",
|
||||
"Hide prefix selection",
|
||||
"Column 2 caption",
|
||||
"Column 2 destination",
|
||||
};
|
||||
public string ParamName(int i) { return paramNames[i]; }
|
||||
public int ParamsCount() { return paramNames.Length; }
|
||||
|
||||
public ICollection<string> ParamValues(int i)
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
return new string[] { Strings.yes, Strings.no };
|
||||
case 4:
|
||||
return null;
|
||||
case 5:
|
||||
for (Col2Dest c2d = 0; c2d < Col2Dest.Count; c2d++) list.Add(c2d.ToDescription());
|
||||
return list;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
return EnterSerialNrsAtTheEnd ? Strings.yes : Strings.no;
|
||||
case 1:
|
||||
return ShowCycleEndForm ? Strings.yes : Strings.no;
|
||||
case 2:
|
||||
return HideOrderSelection ? Strings.yes : Strings.no;
|
||||
case 3:
|
||||
return HidePrefix ? Strings.yes : Strings.no;
|
||||
case 4:
|
||||
return Column2Caption;
|
||||
case 5:
|
||||
return Column2Destination.ToDescription();
|
||||
default:
|
||||
return string.Format("Name={0}, Enter SNs at the end={1}, Show cycle end form={2}", Name, EnterSerialNrsAtTheEnd, ShowCycleEndForm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public CfgUpdateFlags UpdateParam(int i, string str)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
EnterSerialNrsAtTheEnd = (str == Strings.yes);
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
case 1:
|
||||
ShowCycleEndForm = (str == Strings.yes);
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
case 2:
|
||||
HideOrderSelection = (str == Strings.yes);
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
case 3:
|
||||
HidePrefix = (str == Strings.yes);
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
case 4:
|
||||
Column2Caption = str;
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
case 5:
|
||||
for (Col2Dest c2d = 0; c2d < Col2Dest.Count; c2d++)
|
||||
{
|
||||
if (str == c2d.ToDescription())
|
||||
{
|
||||
Column2Destination = c2d;
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
}
|
||||
}
|
||||
return CfgUpdateFlags.None;
|
||||
default:
|
||||
return CfgUpdateFlags.None;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ValidateParam(int i, string str, out string message)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 5:
|
||||
message = string.Empty;
|
||||
if (ParamValues(i).Contains(str)) return true;
|
||||
break;
|
||||
case 4:
|
||||
message = string.Empty;
|
||||
return true;
|
||||
default:
|
||||
message = "Invalid index";
|
||||
return false;
|
||||
}
|
||||
|
||||
message = string.Format(Strings.Invalid_0, ParamName(i)) ;
|
||||
return false;
|
||||
}
|
||||
|
||||
void CopyContentTo(EntryFormCfg prms)
|
||||
{
|
||||
prms.EnterSerialNrsAtTheEnd = EnterSerialNrsAtTheEnd;
|
||||
prms.ShowCycleEndForm = ShowCycleEndForm;
|
||||
prms.HideOrderSelection = HideOrderSelection;
|
||||
prms.HidePrefix = HidePrefix;
|
||||
prms.Column2Caption = Column2Caption;
|
||||
prms.Column2Destination = Column2Destination;
|
||||
}
|
||||
|
||||
public Config.Entities.IParamsProvider Clone()
|
||||
{
|
||||
EntryFormCfg pars = new EntryFormCfg();
|
||||
CopyContentTo(pars);
|
||||
return pars;
|
||||
}
|
||||
|
||||
public bool UpdateEmbeddedDbEntity()
|
||||
{
|
||||
return true; /// =OK, do nothing
|
||||
}
|
||||
}
|
||||
|
||||
public enum Col2Dest
|
||||
{
|
||||
[Description("Radio address")] RadioAddress,
|
||||
[Description("Serial nr. Aux")] SerialNrAux,
|
||||
[Description("Purchase order")] OrderNr,
|
||||
[Description("Remark")] Remark,
|
||||
#if ORACLE_DB
|
||||
[Description("Suffix")] Suffix,
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
///
|
||||
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -8,7 +8,7 @@ using Config.Entities;
|
||||
using TBF.Rig;
|
||||
using TBF.Rig.GenericDevices;
|
||||
|
||||
namespace TBF.Rig.DataEntry.Fewa
|
||||
namespace TBF.Rig.DataEntry.Double24
|
||||
{
|
||||
public class EntryFormNoStartEnd : ComponentBase, IOperation, IDataEntry, IHasCycleBeginForm, IHasCycleEndForm
|
||||
{
|
||||
@ -123,7 +123,7 @@ namespace TBF.Rig.DataEntry.Fewa
|
||||
///
|
||||
void OpenBeginningDlg(EntryFormNoStartEnd myRef)
|
||||
{
|
||||
myRef.modelessDlg = new CycleBeginningForm(TBF.Data.WMsCount);
|
||||
myRef.modelessDlg = new CycleBeginningForm(TBF.Data.WMsCount, entryFormCfg);
|
||||
modelessDlg.Show();
|
||||
}
|
||||
///
|
||||
@ -199,8 +199,39 @@ namespace TBF.Rig.DataEntry.Fewa
|
||||
{
|
||||
waterMeters[i].Disabled = disabled[i] = dlg.Disabled[i];
|
||||
waterMeters[i].SerialNr = dlg.SNText[i];
|
||||
waterMeters[i].SerialNrAux = dlg.SN2Text[i];
|
||||
if (dlg.PurchaseOrder != null) waterMeters[i].PurchaseOrder = dlg.PurchaseOrder;
|
||||
switch (entryFormCfg.Column2Destination)
|
||||
{
|
||||
case Col2Dest.RadioAddress:
|
||||
waterMeters[i].RadioAddress = dlg.Column2Text[i];
|
||||
break;
|
||||
case Col2Dest.SerialNrAux:
|
||||
waterMeters[i].SerialNrAux = dlg.Column2Text[i];
|
||||
break;
|
||||
case Col2Dest.OrderNr:
|
||||
waterMeters[i].PurchaseOrder = dlg.Column2Text[i];
|
||||
break;
|
||||
#if ORACLE_DB
|
||||
case Col2Dest.Suffix:
|
||||
waterMeters[i].Suffix = dlg.Column2Text[i];
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
case Col2Dest.Remark:
|
||||
waterMeters[i].Remark = dlg.Column2Text[i];
|
||||
break;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(dlg.PurchaseOrder) && !entryFormCfg.HideOrderSelection)
|
||||
{
|
||||
waterMeters[i].PurchaseOrder = dlg.PurchaseOrder;
|
||||
}
|
||||
|
||||
#if ORACLE_DB
|
||||
if (!string.IsNullOrEmpty(dlg.Prefix) && !entryFormCfg.HidePrefix)
|
||||
{
|
||||
waterMeters[i].Prefix = dlg.PurchaseOrder;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,20 +1,20 @@
|
||||
///
|
||||
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.DataEntry.Fewa
|
||||
namespace TBF.Rig.DataEntry.Double24
|
||||
{
|
||||
public class Factory : IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return "DataEntry.Fewa"; } }
|
||||
public string ClassName { get { return GetType().Namespace.Substring(8); } }
|
||||
|
||||
public IComponent DummyComponent() { return new EntryFormNoStartEnd(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new EntryForm(cfg); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new EntryFormCfg(this); }
|
||||
public IComponentCfg DefaultConfig() { return new EntryFormCfg(this, GetType().Namespace.Substring(8)); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
@ -1,20 +1,20 @@
|
||||
///
|
||||
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.DataEntry.Fewa
|
||||
namespace TBF.Rig.DataEntry.Double24
|
||||
{
|
||||
public class FactoryNoStartEnd : IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return "DataEntry.Fewa.NoStartEnd"; } }
|
||||
public string ClassName { get { return GetType().Namespace.Substring(8) + "-NoStartEnd"; } }
|
||||
|
||||
public IComponent DummyComponent() { return new EntryFormNoStartEnd(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new EntryFormNoStartEnd(cfg); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new EntryFormCfg(this); }
|
||||
public IComponentCfg DefaultConfig() { return new EntryFormCfg(this, GetType().Namespace.Substring(8) + "-NoStartEnd"); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
@ -1,5 +1,5 @@
|
||||
///
|
||||
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -8,7 +8,7 @@ using log4net;
|
||||
using TBF.Rig.GenericDevices;
|
||||
using TBF.Resources;
|
||||
|
||||
namespace TBF.Rig.DataEntry.Fewa
|
||||
namespace TBF.Rig.DataEntry.Double24
|
||||
{
|
||||
public partial class TestStartEndForm : Form, GenericDevices.IHasCompleted
|
||||
{
|
||||
@ -1,7 +1,7 @@
|
||||
///
|
||||
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
||||
///
|
||||
namespace TBF.Rig.DataEntry.Fewa
|
||||
namespace TBF.Rig.DataEntry.Double24
|
||||
{
|
||||
partial class TestStartEndForm
|
||||
{
|
||||
@ -1,45 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.DataEntry.Fewa
|
||||
{
|
||||
public class EntryFormCfg : ComponentCfgBase, Generic.IComponentCfg
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(EntryFormCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new EntryFormCfgCtrl(); }
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
public bool EnterSerialNrsAtTheEnd;
|
||||
public bool ShowCycleEndForm;
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
EntryFormCfg()
|
||||
{
|
||||
Name = "DataEntry-FEWA";
|
||||
ParentName = string.Empty;
|
||||
EnterSerialNrsAtTheEnd = false;
|
||||
ShowCycleEndForm = false;
|
||||
}
|
||||
|
||||
public EntryFormCfg(IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
this.Factory = factory;
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
return string.Format("Name={0}, EnterSNsAtTheEnd={1}, ShowEndForm={2}", Name, EnterSerialNrsAtTheEnd, ShowCycleEndForm);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,84 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Resources;
|
||||
|
||||
namespace TBF.Rig.DataEntry.Fewa
|
||||
{
|
||||
public partial class EntryFormCfgCtrl : UserControl, IComponentCfgCtrl
|
||||
{
|
||||
public bool ShowMore { get { return false; } }
|
||||
|
||||
EntryFormCfg config;
|
||||
public IComponentCfg Config
|
||||
{
|
||||
get { return config as IComponentCfg; }
|
||||
set
|
||||
{
|
||||
config = value as EntryFormCfg;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public EntryFormCfgCtrl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void EntryFormCfgCtrl_Load(object sender, EventArgs e)
|
||||
{
|
||||
Localize();
|
||||
Redraw();
|
||||
}
|
||||
|
||||
void Localize()
|
||||
{
|
||||
enterSNsAtTheEndCheckBox.Text = Strings.Enter_SNs_at_the_end;
|
||||
showEndStateFormCheckBox.Text = Strings.Show_cycle_end_form;
|
||||
}
|
||||
|
||||
public void Closing()
|
||||
{
|
||||
}
|
||||
|
||||
void Redraw()
|
||||
{
|
||||
if (config == null) return; /// Control was not loaded, settings were not changed
|
||||
classNameLabel.Text = config.Factory.ClassName;
|
||||
nameTextBox.Text = config.Name;
|
||||
enterSNsAtTheEndCheckBox.Checked = config.EnterSerialNrsAtTheEnd;
|
||||
showEndStateFormCheckBox.Checked = config.ShowCycleEndForm;
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
{
|
||||
nameTextBox.Enabled = true;
|
||||
enterSNsAtTheEndCheckBox.Enabled = true;
|
||||
showEndStateFormCheckBox.Enabled = true;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags VerifyCfg(ref string message)
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
return flags;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateCfg()
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.RestartRqrd;
|
||||
|
||||
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
|
||||
|
||||
config.Name = nameTextBox.Text;
|
||||
config.EnterSerialNrsAtTheEnd = enterSNsAtTheEndCheckBox.Checked;
|
||||
config.ShowCycleEndForm = showEndStateFormCheckBox.Checked;
|
||||
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
114
TBF/Rig/DataEntry/Fewa/EntryFormCfgCtrl.designer.cs
generated
114
TBF/Rig/DataEntry/Fewa/EntryFormCfgCtrl.designer.cs
generated
@ -1,114 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
||||
///
|
||||
namespace TBF.Rig.DataEntry.Fewa
|
||||
{
|
||||
partial class EntryFormCfgCtrl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.nameTextBox = new System.Windows.Forms.TextBox();
|
||||
this.nameLabel = new System.Windows.Forms.Label();
|
||||
this.classNameLabel = new System.Windows.Forms.Label();
|
||||
this.showEndStateFormCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.enterSNsAtTheEndCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// nameTextBox
|
||||
//
|
||||
this.nameTextBox.Enabled = false;
|
||||
this.nameTextBox.Location = new System.Drawing.Point(99, 57);
|
||||
this.nameTextBox.Name = "nameTextBox";
|
||||
this.nameTextBox.Size = new System.Drawing.Size(130, 20);
|
||||
this.nameTextBox.TabIndex = 2;
|
||||
//
|
||||
// nameLabel
|
||||
//
|
||||
this.nameLabel.AutoSize = true;
|
||||
this.nameLabel.Location = new System.Drawing.Point(35, 60);
|
||||
this.nameLabel.Name = "nameLabel";
|
||||
this.nameLabel.Size = new System.Drawing.Size(35, 13);
|
||||
this.nameLabel.TabIndex = 1;
|
||||
this.nameLabel.Text = "Name";
|
||||
//
|
||||
// classNameLabel
|
||||
//
|
||||
this.classNameLabel.AutoSize = true;
|
||||
this.classNameLabel.Location = new System.Drawing.Point(96, 33);
|
||||
this.classNameLabel.Name = "classNameLabel";
|
||||
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
|
||||
this.classNameLabel.TabIndex = 0;
|
||||
this.classNameLabel.Text = "ComonentName";
|
||||
//
|
||||
// showEndStateFormCheckBox
|
||||
//
|
||||
this.showEndStateFormCheckBox.AutoSize = true;
|
||||
this.showEndStateFormCheckBox.Enabled = false;
|
||||
this.showEndStateFormCheckBox.Location = new System.Drawing.Point(99, 112);
|
||||
this.showEndStateFormCheckBox.Name = "showEndStateFormCheckBox";
|
||||
this.showEndStateFormCheckBox.Size = new System.Drawing.Size(151, 17);
|
||||
this.showEndStateFormCheckBox.TabIndex = 4;
|
||||
this.showEndStateFormCheckBox.Text = "Watermeter end state form";
|
||||
this.showEndStateFormCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// enterSNsAtTheEndCheckBox
|
||||
//
|
||||
this.enterSNsAtTheEndCheckBox.AutoSize = true;
|
||||
this.enterSNsAtTheEndCheckBox.Enabled = false;
|
||||
this.enterSNsAtTheEndCheckBox.Location = new System.Drawing.Point(99, 89);
|
||||
this.enterSNsAtTheEndCheckBox.Name = "enterSNsAtTheEndCheckBox";
|
||||
this.enterSNsAtTheEndCheckBox.Size = new System.Drawing.Size(167, 17);
|
||||
this.enterSNsAtTheEndCheckBox.TabIndex = 3;
|
||||
this.enterSNsAtTheEndCheckBox.Text = "Enter serial number at the end";
|
||||
this.enterSNsAtTheEndCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// EntryFormCfgCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.enterSNsAtTheEndCheckBox);
|
||||
this.Controls.Add(this.showEndStateFormCheckBox);
|
||||
this.Controls.Add(this.nameTextBox);
|
||||
this.Controls.Add(this.nameLabel);
|
||||
this.Controls.Add(this.classNameLabel);
|
||||
this.Name = "EntryFormCfgCtrl";
|
||||
this.Size = new System.Drawing.Size(300, 200);
|
||||
this.Load += new System.EventHandler(this.EntryFormCfgCtrl_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox nameTextBox;
|
||||
private System.Windows.Forms.Label nameLabel;
|
||||
private System.Windows.Forms.Label classNameLabel;
|
||||
private System.Windows.Forms.CheckBox showEndStateFormCheckBox;
|
||||
private System.Windows.Forms.CheckBox enterSNsAtTheEndCheckBox;
|
||||
}
|
||||
}
|
||||
@ -1,120 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@ -25,8 +25,8 @@ namespace TBF.Rig
|
||||
Factories.Add(new Elde.CoverTest.Factory());
|
||||
Factories.Add(new DataEntry.Combined.EntryFormFactory());
|
||||
Factories.Add(new DataEntry.DataStream.Factory());
|
||||
Factories.Add(new DataEntry.Fewa.Factory());
|
||||
Factories.Add(new DataEntry.Fewa.FactoryNoStartEnd());
|
||||
Factories.Add(new DataEntry.Double24.Factory());
|
||||
Factories.Add(new DataEntry.Double24.FactoryNoStartEnd());
|
||||
Factories.Add(new DataEntry.HeatMeters6.Factory());
|
||||
Factories.Add(new DataEntry.HeatMeters12.Factory());
|
||||
Factories.Add(new DataEntry.Munich3.EntryFormFactory());
|
||||
|
||||
@ -241,33 +241,27 @@
|
||||
<Compile Include="Rig\DataEntry\DataStream\TestStartEndForm.designer.cs">
|
||||
<DependentUpon>TestStartEndForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\DataEntry\Fewa\CycleBeginningForm.cs">
|
||||
<Compile Include="Rig\DataEntry\Double24\CycleBeginningForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\DataEntry\Fewa\CycleBeginningForm.designer.cs">
|
||||
<Compile Include="Rig\DataEntry\Double24\CycleBeginningForm.designer.cs">
|
||||
<DependentUpon>CycleBeginningForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\DataEntry\Fewa\CycleEndForm.cs">
|
||||
<Compile Include="Rig\DataEntry\Double24\CycleEndForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\DataEntry\Fewa\CycleEndForm.designer.cs">
|
||||
<Compile Include="Rig\DataEntry\Double24\CycleEndForm.designer.cs">
|
||||
<DependentUpon>CycleEndForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\DataEntry\Fewa\EntryForm.cs" />
|
||||
<Compile Include="Rig\DataEntry\Fewa\EntryFormCfg.cs" />
|
||||
<Compile Include="Rig\DataEntry\Fewa\EntryFormCfgCtrl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\DataEntry\Fewa\EntryFormCfgCtrl.designer.cs">
|
||||
<DependentUpon>EntryFormCfgCtrl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\DataEntry\Fewa\EntryFormNoStartEnd.cs" />
|
||||
<Compile Include="Rig\DataEntry\Fewa\Factory.cs" />
|
||||
<Compile Include="Rig\DataEntry\Fewa\FactoryNoStartEnd.cs" />
|
||||
<Compile Include="Rig\DataEntry\Fewa\TestStartEndForm.cs">
|
||||
<Compile Include="Rig\DataEntry\Double24\EntryForm.cs" />
|
||||
<Compile Include="Rig\DataEntry\Double24\EntryFormCfg.cs" />
|
||||
<Compile Include="Rig\DataEntry\Double24\EntryFormNoStartEnd.cs" />
|
||||
<Compile Include="Rig\DataEntry\Double24\Factory.cs" />
|
||||
<Compile Include="Rig\DataEntry\Double24\FactoryNoStartEnd.cs" />
|
||||
<Compile Include="Rig\DataEntry\Double24\TestStartEndForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\DataEntry\Fewa\TestStartEndForm.designer.cs">
|
||||
<Compile Include="Rig\DataEntry\Double24\TestStartEndForm.designer.cs">
|
||||
<DependentUpon>TestStartEndForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\DataEntry\HeatMeters12\CycleBeginningForm.cs">
|
||||
@ -2772,16 +2766,13 @@
|
||||
<EmbeddedResource Include="Rig\DataEntry\DataStream\TestStartEndForm.resx">
|
||||
<DependentUpon>TestStartEndForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\DataEntry\Fewa\CycleBeginningForm.resx">
|
||||
<EmbeddedResource Include="Rig\DataEntry\Double24\CycleBeginningForm.resx">
|
||||
<DependentUpon>CycleBeginningForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\DataEntry\Fewa\CycleEndForm.resx">
|
||||
<EmbeddedResource Include="Rig\DataEntry\Double24\CycleEndForm.resx">
|
||||
<DependentUpon>CycleEndForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\DataEntry\Fewa\EntryFormCfgCtrl.resx">
|
||||
<DependentUpon>EntryFormCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\DataEntry\Fewa\TestStartEndForm.resx">
|
||||
<EmbeddedResource Include="Rig\DataEntry\Double24\TestStartEndForm.resx">
|
||||
<DependentUpon>TestStartEndForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\DataEntry\HeatMeters12\CycleBeginningForm.pl.resx">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user