Compare commits

...
27 changed files with 1948 additions and 48 deletions
+1 -1
View File
@@ -23,7 +23,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+2 -2
View File
@@ -16,7 +16,7 @@
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
@@ -27,7 +27,7 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
+2 -2
View File
@@ -97,7 +97,7 @@
<BaseAddress>285212672</BaseAddress>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<FileAlignment>4096</FileAlignment>
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
<CodeAnalysisFailOnMissingRules>false</CodeAnalysisFailOnMissingRules>
@@ -110,7 +110,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
<FileAlignment>4096</FileAlignment>
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
<CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
<Prefer32Bit>false</Prefer32Bit>
+1 -1
View File
@@ -22,7 +22,7 @@
<DefineConstants>TRACE;DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+2 -2
View File
@@ -16,7 +16,7 @@
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
@@ -28,7 +28,7 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
+1 -1
View File
@@ -20,7 +20,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
+2 -2
View File
@@ -16,7 +16,7 @@
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
@@ -27,7 +27,7 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
+2 -2
View File
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
[assembly: AssemblyVersion("3.1.1746.0")]
[assembly: AssemblyFileVersion("3.1.1746.0")]
[assembly: AssemblyVersion("3.1.1773.0")]
[assembly: AssemblyFileVersion("3.1.1773.0")]
+37 -7
View File
@@ -1,5 +1,5 @@
///
/// Copyright (c) 2015-2019 Sensus Slovensko a.s.
/// Copyright (c) 2015-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
@@ -15,6 +15,9 @@ namespace TBF.Rig.Output.DB.SensusOracle
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(DatabaseCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
static readonly string AkaPwd = "········";
static readonly string AkaPwd1 = "·"; /// One character only
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities)
{
return new Configs.ParamsProvider.ComponentCfgCtrl(this, null);
@@ -96,13 +99,13 @@ namespace TBF.Rig.Output.DB.SensusOracle
{
case 0: return ProductionDataSource;
case 1: return ProductionUserId;
case 2: return ProductionPassword;
case 2: return AkaPwd;
case 3: return QualityDataSource;
case 4: return QualityUserId;
case 5: return QualityPassword;
case 5: return AkaPwd;
case 6: return TestDataSource;
case 7: return TestUserId;
case 8: return TestPassword;
case 8: return AkaPwd;
case 9: return ProducerId.ToString();
default:
return string.Format("{0}: Production={1} Quality={2} Test={3}",
@@ -119,13 +122,40 @@ namespace TBF.Rig.Output.DB.SensusOracle
{
case 0: ProductionDataSource = str; return CfgUpdateFlags.RestartRqrd;
case 1: ProductionUserId = str; return CfgUpdateFlags.RestartRqrd;
case 2: ProductionPassword = str; return CfgUpdateFlags.RestartRqrd;
case 2:
if (!str.Contains(AkaPwd1))
{
ProductionPassword = str;
return CfgUpdateFlags.RestartRqrd;
}
else
{
return CfgUpdateFlags.None;
}
case 3: QualityDataSource = str; return CfgUpdateFlags.RestartRqrd;
case 4: QualityUserId = str; return CfgUpdateFlags.RestartRqrd;
case 5: QualityPassword = str; return CfgUpdateFlags.RestartRqrd;
case 5:
if (!str.Contains(AkaPwd1))
{
QualityPassword = str;
return CfgUpdateFlags.RestartRqrd;
}
else
{
return CfgUpdateFlags.None;
}
case 6: TestDataSource = str; return CfgUpdateFlags.RestartRqrd;
case 7: TestUserId = str; return CfgUpdateFlags.RestartRqrd;
case 8: TestPassword = str; return CfgUpdateFlags.RestartRqrd;
case 8:
if (!str.Contains(AkaPwd1))
{
TestPassword = str;
return CfgUpdateFlags.RestartRqrd;
}
else
{
return CfgUpdateFlags.None;
}
case 9: ProducerId = int.Parse(str); return CfgUpdateFlags.RestartRqrd;
default:
return CfgUpdateFlags.None;
@@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml.Serialization;
using log4net;
using Common;
using Config.Entities;
using Results.Output;
@@ -16,7 +17,8 @@ namespace TBF.Rig.Output.DB.SensusOracle
{
public class ProcedureParams : ProcedureParamsBase, IParamsProvider, IProcedureParams
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(ProcedureParams) })[0];
private static readonly ILog log = LogManager.GetLogger(typeof(ProcedureParams));
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(ProcedureParams) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public DBUsed DBUsed; /// 0
@@ -140,11 +142,11 @@ namespace TBF.Rig.Output.DB.SensusOracle
}
break;
case 2: WMTypeId = int.Parse(strValue); break;
case 3: YearOfManufacture = int.Parse(strValue); break;
case 4: SaveResults = (strValue == Strings.yes); break;
case 5: ReadStartInfo = (strValue == Strings.yes); break;
case 6: StartInfoIsRequired = (strValue == Strings.yes); break;
case 2: WMTypeId = int.Parse(strValue); return CfgUpdateFlags.None;
case 3: YearOfManufacture = int.Parse(strValue); return CfgUpdateFlags.None;
case 4: SaveResults = (strValue == Strings.yes); return CfgUpdateFlags.None;
case 5: ReadStartInfo = (strValue == Strings.yes); return CfgUpdateFlags.None;
case 6: StartInfoIsRequired = (strValue == Strings.yes); return CfgUpdateFlags.None;
case 7:
for (DesigMode db = 0; db < DesigMode.Count; db++)
@@ -267,8 +269,9 @@ namespace TBF.Rig.Output.DB.SensusOracle
if (tmp != null) tmp.CopyContentTo(this);
}
catch
catch (Exception exc)
{
log.ErrorFormat("Failed to UpdateFromDbEntity({0}): {1}", dbEntity, exc.Message);
}
}
+25
View File
@@ -0,0 +1,25 @@
///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System.Collections.Generic;
using TBF.Rig.Generic;
namespace TBF.Rig.Scales.MettlerToledo
{
public class Factory : IComponentFactory
{
public string ClassName { get { return GetType().Namespace.Substring(8); } }
public override string ToString() { return ClassName; }
public IComponent DummyComponent() { return new Scale(); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new Scale(cfg); }
public IComponentCfg DefaultConfig() { return new ScaleCfg("WT", this); }
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
{
return ComponentCfgBase.CreateFromDbEntity(ScaleCfg.Serializer, component, this);
}
}
}
@@ -0,0 +1,84 @@
///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using log4net;
namespace TBF.Rig.Scales.MettlerToledo
{
public class GetSerNumOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(GetSerNumOp));
public override string ToString() { return string.Format("GetSerNumOp(.,.)"); }
/// Set by the constructor
Scale scale;
string serialNumber;
bool activityStarted;
/// <summary>
/// Events: BalanceDone, Error
/// </summary>
/// <param name="scale">Balance device instance</param>
/// <param name="serialNumber">Reference to the serialNumber</param>
public GetSerNumOp(Scale scale, ref string serialNumber)
{
if (scale == null) throw new ArgumentNullException("balanceDev");
this.scale = scale;
this.serialNumber = serialNumber;
log.Debug(this.ToString());
}
/// <summary>Start this operation</summary>
public void Start()
{
if (scale.Activity == Activity.Idle)
{
scale.SendGetSerialNumberCmd();
activityStarted = true;
scale.Activity = Activity.RunningOperation;
}
else
{
activityStarted = false;
}
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.None
/// Event.BalanceDone
/// </returns>
public Event Run()
{
if (!activityStarted && scale.Activity == Activity.Idle)
{
scale.SendGetSerialNumberCmd();
activityStarted = true;
scale.Activity = Activity.RunningOperation;
return Event.Busy;
}
if (scale.MsrmntState == MsrmntState.Valid)
{
serialNumber = scale.SerialNumber;
return Event.ScaleDone; /// S/N read successful
}
if (scale.MsrmntState == MsrmntState.Failed)
{
return Event.Error; /// S/N read failed
}
return Event.Busy; /// No result yet
}
/// <summary>Stop this operation</summary>
public void Stop()
{
if (scale.MsrmntState == MsrmntState.Busy) scale.MsrmntState = MsrmntState.Failed;
scale.Activity = Activity.Idle;
}
}
}
@@ -0,0 +1,230 @@
///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using log4net;
using Common;
using Config.Entities;
using TBF.Boxes;
namespace TBF.Rig.Scales.MettlerToledo
{
/// <summary>
/// Operation to read more mass values and average them to obtain a more accurate result.
/// </summary>
public class ReadStableMassOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(ReadStableMassOp));
public override string ToString() { return string.Format("ReadStableMassOp(.,{0},.)", totalReadingsCount); }
/// Set by the constructor
readonly Scale scale;
readonly DoubleBox result;
readonly int delayBefore;
readonly MassMethod method; /// by the scale, mass spread threshold or mass standard deviation threshold
readonly int totalReadingsCount;
readonly double maxSpread; /// Maximum spread of measurements in kg (otherwise the measurement continues)
/// Operation specific
double[] massReadings;
double[] sortedMassReadings;
int currentReadingsCount;
int startTime;
bool measurementCompleted;
int timeout;
/// <summary>
/// Events: BalanceDone, Error
/// </summary>
/// <param name="scale">Balance device instance</param>
/// <param name="result">Reference to the measured mass in kg</param>
/// <param name="readingsCount">Required mass readings count (>= 4)</param>
/// <param name="maxSpread">Maximum spread of measurements in kg (otherwise the measurement continues)</param>
/// <param name="method">Method: false = slow (precise), true = fast (immediate)</param>
public ReadStableMassOp(GenericDevices.IScale scale, ref DoubleBox result, int delayBefore, MassMethod method,
int readingsCount, double maxSpread)
{
this.scale = scale as Scale;
if (this.scale == null) throw new ArgumentNullException("balanceDev");
this.result = result;
this.delayBefore = delayBefore;
this.method = method;
this.totalReadingsCount = (readingsCount < 4) ? 5 : readingsCount; /// readingsCount is at least 4
this.maxSpread = (maxSpread == 0) ? (scale.Capacity / 20000.0) : maxSpread;
massReadings = new double[totalReadingsCount];
sortedMassReadings = new double[totalReadingsCount];
currentReadingsCount = 0;
measurementCompleted = false;
timeout = (method == MassMethod.Scale) ? 60 : 2;
log.Debug(this.ToString());
}
/// Internal states of this operation
enum OpState
{
WaitingBeforeMeasurment,
MassMeasurement,
}
OpState opState;
/// <summary>
/// Call scale.XYStartMeasurement() function and set measurementStarted flag.
/// </summary>
void StartMeasurement()
{
if (method == MassMethod.Scale)
scale.SendStableMeasurementCmd();
else
scale.SendImmediateMeasurementCmd();
}
/// <summary>Start this operation</summary>
public void Start()
{
startTime = StateMachine.Time;
currentReadingsCount = 0;
measurementCompleted = false;
if (delayBefore == 0 && scale.Activity == Activity.Idle)
{
StartMeasurement();
scale.Activity = Activity.RunningOperation;
opState = OpState.MassMeasurement;
}
else
{
opState = OpState.WaitingBeforeMeasurment;
}
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.None
/// Event.BalanceDone
/// Event.Error . . . . . Current.Tick == null
/// </returns>
public Event Run()
{
if (opState == OpState.WaitingBeforeMeasurment)
{
if (StateMachine.Time >= startTime + delayBefore && scale.Activity == Activity.Idle)
{
StartMeasurement();
scale.Activity = Activity.RunningOperation;
opState = OpState.MassMeasurement;
}
return Event.None;
}
scale.MsrmntTime++;
if (measurementCompleted)
{
return Event.ScaleDone;
}
if (scale.MsrmntState == MsrmntState.Busy)
{
/// Measurement is in progress - resend command if timeout occurs
if (scale.MsrmntTime >= timeout) StartMeasurement();
return Event.None; /// Wait for a mass measurement
}
if (scale.MsrmntState == MsrmntState.Valid)
{
/// Save the measurement
if (currentReadingsCount < totalReadingsCount)
{
massReadings[currentReadingsCount++] = scale.Mass;
}
else
{
/// Shift data in the (already full) buffer, save the mass into the last buffer item
for (int i = 1; i < totalReadingsCount; i++)
{
massReadings[i - 1] = massReadings[i];
}
massReadings[totalReadingsCount - 1] = scale.Mass;
}
}
if (currentReadingsCount >= totalReadingsCount)
{
Array.Copy(massReadings, sortedMassReadings, totalReadingsCount);
Array.Sort(sortedMassReadings);
if (method == MassMethod.Spread)
{
/// Immediate mass measurement, end condition calculated below
if ((sortedMassReadings[totalReadingsCount - 2] - sortedMassReadings[1]) <= maxSpread)
{
double massSum = 0;
for (int i = 1; i < totalReadingsCount - 1; i++) massSum += sortedMassReadings[i];
result.Val = (massSum / (totalReadingsCount - 2));
log.InfoFormat("ReadStableMassOp.Run() ... valid mass={0} ... returning Event.BalanceDone", result.Val);
measurementCompleted = true;
return Event.ScaleDone; /// Mass has just been calculated
}
}
else if (method == MassMethod.StdDev)
{
/// Immediate mass measurement, end condition calculated below
double massSum = 0;
for (int i = 1; i < totalReadingsCount - 1; i++) massSum += sortedMassReadings[i];
double ave = (massSum / (totalReadingsCount - 2));
double sdev = 0;
for (int i = 1; i < totalReadingsCount - 1; i++) sdev += ((sortedMassReadings[i] - ave) * (sortedMassReadings[i] - ave));
if (Math.Sqrt(sdev / (totalReadingsCount - 2)) <= maxSpread)
{
result.Val = ave;
log.InfoFormat("ReadStableMassOp.Run() ... valid mass={0} ... returning Event.BalanceDone", result.Val);
measurementCompleted = true;
return Event.ScaleDone; /// Mass has just been calculated
}
}
else
{
/// Stable mass measurement
/// Sort, exclude min. and max. values, calculate the average
double massSum = 0;
for (int i = 1; i < totalReadingsCount - 1; i++) massSum += massReadings[i];
result.Val = (massSum / (totalReadingsCount - 2));
log.InfoFormat("ReadStableMassOp.Run() ... valid mass={0} ... returning Event.BalanceDone", result.Val);
measurementCompleted = true;
return Event.ScaleDone; /// Mass has just been calculated
}
}
if (measurementCompleted)
{
return Event.ScaleDone;
}
else
{
StartMeasurement(); /// Start a new measurement
return Event.None;
}
}
/// <summary>Stop this operation</summary>
public void Stop()
{
if (scale.MsrmntState == MsrmntState.Busy) scale.MsrmntState = MsrmntState.Failed;
scale.Activity = Activity.Idle;
}
}
}
+603
View File
@@ -0,0 +1,603 @@
///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.IO.Ports;
using log4net;
using Common;
using Config.Entities;
using SchematicDrawing;
using TBF.Rig.Generic;
using TBF.Rig.GenericDevices;
using TBF.Boxes;
using TBF.Resources;
namespace TBF.Rig.Scales.MettlerToledo
{
public enum Activity
{
Idle,
ImmediateMeasurement,
RunningOperation,
}
/// <summary>
/// Mettler Toledo ICS4_5 Weighting terminal connected via serial interface (RS232)
/// </summary>
/// <note>
/// Implemented and tested on 15.10.2013 by Milan Hanajik
/// </note>
public class Scale : TankDraining, IDevice, GenericDevices.IScale, GenericDevices.IHasCalendarEvents, IDrawingItCmpntWithMeasuredVal
{
private static readonly ILog log = LogManager.GetLogger(typeof(Scale));
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
/// Configuration and wrappers
protected readonly ScaleCfg scaleCfg;
///
public double Capacity { get { return scaleCfg.Capacity; } }
public int EmptyTimeSec { get { return scaleCfg.DrainTimeSec; } }
public IValve DrainValve2 { get { return null; } }
public float BuoyancyTemp { get { return scaleCfg.BuoyancyTemp; } }
public float BuoyancyPress { get { return scaleCfg.BuoyancyPress; } }
public float BuoyancyHumi { get { return scaleCfg.BuoyancyHumi; } }
public double WeightStandardDensity { get { return scaleCfg.WeightStandardDensity; } }
///
Protocol proto { get { return scaleCfg.Protocol; } }
///
public IDrawingItem DrawingItem { get { return scaleCfg as IDrawingItem; } }
protected SerialPort serialPort;
protected StringBuilder stringBuilder;
/// <summary>The state of the mass measurement</summary>
public Activity Activity;
public MsrmntState MsrmntState { get { return msrmntState; } set { msrmntState = value; } }
protected MsrmntState msrmntState;
/// <summary>Time since the last serial command in seconds</summary>
public int MsrmntTime;
/// <summary>The mass after StartMassMeasurement() when MsrmntState == MsrmntState.Valid</summary>
public double Mass { get { return mass; } }
protected double mass;
public bool MsrmntAvailable { get { return true; } }
public double MeasuredVal { get { return mass; } }
public string AltString { get { return string.Empty; } }
/// <summary>The time stamp after StartMassMeasurement() when MsrmntState == MsrmntState.Valid</summary>
public int MsrmntTimeStamp { get { return msrmntTimeStamp; } }
protected int msrmntTimeStamp;
public string Format { get { return scaleCfg.MsrdFormat; } }
/// <summary>Serial number after GetSerialNumber() when MsrmntState == MsrmntState.Valid</summary>
public string SerialNumber { get { return serialNumber; } }
string serialNumber;
public Scale() { }
/// <summary>
/// Constructor
/// </summary>
/// <param name="cfg">Balance properties</param>
/// <param components="cfg">A list of components loaded so far</param>
public Scale(Generic.IComponentCfg cfg)
: base(cfg)
{
scaleCfg = cfg as ScaleCfg;
}
public override void Initialize()
{
base.Initialize(); /// Initializes DrainValve, etc., should be called in DebugMode.Simulate
Activity = Activity.Idle;
msrmntState = MsrmntState.Failed; /// Data not valid yet
MsrmntTime = 0;
stringBuilder = new StringBuilder(40);
if (scaleCfg.CalibValidDate != DateTime.MinValue && scaleCfg.CalibValidDate.Date < DateTime.Now.Date)
{
throw new Exception(string.Format("{0}: {1}", Name, Strings.Calibration_certificate_validity_expired));
}
if (scaleCfg.DebugLevel == DebugMode.Normal)
{
string comPortName = "COM" + scaleCfg.ComPortNr.ToString();
serialPort = new SerialPort(comPortName, scaleCfg.BaudRate, scaleCfg.Parity, scaleCfg.DataBits, scaleCfg.StopBits);
serialPort.Handshake = scaleCfg.Handshake;
serialPort.Open();
log.FatalFormat("{0} - Device successfully initialized", Name);
}
else
{
serialPort = null;
log.FatalFormat("{0} - Device simulated", Name);
}
}
public IList<Config.CalendarEvent.ICalendarEvent> GetCalendarEvents()
{
DateTime calibrationDue = scaleCfg.CalibValidDate;
IList<Config.CalendarEvent.ICalendarEvent> calendarEvents = new List<Config.CalendarEvent.ICalendarEvent>();
if (calibrationDue > TBF.UI.Constants.MinDate)
{
/// Calibration due date calendar event
calendarEvents.Add(new TBF.UI.Calendar.CalibrationDueDateEvent(calibrationDue.Date, Name,
string.Format(Strings.Calibration_due_date_is_0,
calibrationDue.Date.ToString(TBF.UI.Constants.DateFormat))));
if (DateTime.Now.Date <= calibrationDue.AddDays(-7))
{
/// Weekly reminders (last 5 weeks)
calendarEvents.Add(new TBF.UI.Calendar.CalibrationReminderEvent(calibrationDue.Date.AddDays(-35), Name,
string.Format(Strings.Calibration_due_date_is_0,
calibrationDue.Date.ToString(TBF.UI.Constants.DateFormat)),
false));
}
if (DateTime.Now.Date <= calibrationDue.Date)
{
/// Daily reminders (last 5 days)
calendarEvents.Add(new TBF.UI.Calendar.CalibrationReminderEvent(calibrationDue.AddDays(-5), Name,
string.Format(Strings.Calibration_due_date_is_0,
calibrationDue.Date.ToString(TBF.UI.Constants.DateFormat)),
true));
}
}
return calendarEvents;
}
public override bool IsEmpty()
{
return DrainValve.State ? (mass <= scaleCfg.Empty) : (mass <= scaleCfg.EmptyUp);
}
public override bool ContainsMoreThen(float thld)
{
return (mass >= thld);
}
public virtual void SendZeroWhenStableCmd()
{
if (scaleCfg.DebugLevel == DebugMode.Simulate) return;
if (msrmntState == MsrmntState.Busy)
{
log.WarnFormat("{0} - ZeroWhenStable() returns without starting zeroing the scale because measurementState == MeasurementState.Busy", Name);
return;
}
log.InfoFormat("{0} - SendZeroWhenStableCmd() - \"Z\\r\\n\"", Name);
msrmntState = MsrmntState.Busy;
MsrmntTime = 0;
stringBuilder.Clear();
serialPort.Write("Z\r\n");
}
public virtual void SendTaraCmd()
{
if (scaleCfg.DebugLevel == DebugMode.Simulate) return;
if (msrmntState == MsrmntState.Busy)
{
log.WarnFormat("{0} - Taring() returns without starting taring the scale because measurementState == MeasurementState.Busy", Name);
return;
}
log.InfoFormat("{0} - SendTaraCmd() - - \"T\\r\\n\"", Name);
msrmntState = MsrmntState.Busy;
MsrmntTime = 0;
stringBuilder.Clear();
serialPort.Write("T\r\n");
}
/// <summary>
/// Get a stable mass measurement
/// </summary>
public void SendStableMeasurementCmd()
{
if (scaleCfg.DebugLevel == DebugMode.Simulate) return;
if (msrmntState == MsrmntState.Busy)
{
log.WarnFormat("{0} - GetStableMassMeasurement() returns without starting a measurement because measurementState == MeasurementState.Busy", Name);
return;
}
log.InfoFormat("{0} - SendStableMeasurementCmd() - \"S\\r\\n\"", Name);
msrmntState = MsrmntState.Busy;
MsrmntTime = 0;
stringBuilder.Clear();
serialPort.Write("S\r\n");
}
/// <summary>
/// Get an immediate mass measurement
/// </summary>
public void SendImmediateMeasurementCmd()
{
if (scaleCfg.DebugLevel == DebugMode.Simulate || serialPort == null) return;
if (msrmntState == MsrmntState.Busy)
{
log.WarnFormat("{0} - GetImmediateMassMeasurement() returns without starting a measurement because measurementState == MeasurementState.Busy", Name);
return;
}
log.InfoFormat("{0} - SendImmediateMeasurementCmd() - \"SI\\r\\n\"", Name);
msrmntState = MsrmntState.Busy;
MsrmntTime = 0;
stringBuilder.Clear();
serialPort.Write("SI\r\n");
}
/// <summary>
/// Get the serial number
/// </summary>
/// <remarks>After a successful SetUnits(kg) mass is still sent in g. MH 15.10.2013</remarks>
public void SendSetUnitsCmd(Common.Unit unit)
{
if (scaleCfg.DebugLevel == DebugMode.Simulate) return;
if (proto == Protocol.SICS)
{
/// Set Units command is only supported by SICS protocol
if (msrmntState == MsrmntState.Busy)
{
log.WarnFormat("{0} - SetUnits() returns without setting the units because measurementState == MeasurementState.Busy", Name);
return;
}
msrmntState = MsrmntState.Busy;
stringBuilder.Clear();
switch (unit)
{
case Common.Unit.g:
log.InfoFormat("{0} - SetUnits({1}) - \"U g\\r\\n\"", Name, unit);
serialPort.Write("U g\r\n");
break;
case Common.Unit.t:
log.InfoFormat("{0} - SetUnits({1}) - \"U t\\r\\n\"", Name, unit);
serialPort.Write("U t\r\n");
break;
case Common.Unit.lb:
log.InfoFormat("{0} - SetUnits({1}) - \"U lb\\r\\n\"", Name, unit);
serialPort.Write("U lb\r\n");
break;
case Common.Unit.oz:
log.InfoFormat("{0} - SetUnits({1}) - \"U oz\\r\\n\"", Name, unit);
serialPort.Write("U oz\r\n");
break;
case Common.Unit.kg:
default:
log.InfoFormat("{0} - SetUnits({1}) - \"U kg\\r\\n\"", Name, unit);
serialPort.Write("U kg\r\n");
break;
}
}
}
/// <summary>
/// Get the serial number
/// </summary>
public void SendGetSerialNumberCmd()
{
if (scaleCfg.DebugLevel == DebugMode.Simulate) return;
if (proto == Protocol.SICS)
{
/// Get Serial Number command is only supported by SICS protocol
if (msrmntState == MsrmntState.Busy)
{
log.WarnFormat("{0} - SendGetSerialNumberCmd() returns without getting the s/n because measurementState == MeasurementState.Busy", Name);
return;
}
log.WarnFormat("{0} - SendGetSerialNumberCmd() - \"I4\\r\\n\"", Name);
msrmntState = MsrmntState.Busy;
stringBuilder.Clear();
serialPort.Write("I4\r\n");
}
}
/// <summary>
/// Parse characters received from the serial port
/// </summary>
public virtual void RunDeviceBefore()
{
base.RunBefore();
if (scaleCfg.DebugLevel == DebugMode.Simulate)
{
mass = 123.456;
msrmntState = MsrmntState.Valid;
msrmntTimeStamp = StateMachine.Time;
return;
}
if (serialPort == null)
{
log.ErrorFormat("{0} - RunDevice() - serial port closed", Name);
return;
}
log.DebugFormat("{0} - RunDeviceBefore()", Name);
if (msrmntState != MsrmntState.Busy) return; /// No measurement in progress
///
if (Activity == Activity.ImmediateMeasurement)
{
Activity = Activity.Idle;
}
string justReceived = serialPort.ReadExisting();
if (justReceived != null && justReceived.Length > 0)
{
log.DebugFormat("{0} - RunDeviceBefore() received {1}", Name, justReceived);
stringBuilder.Append(justReceived);
if (stringBuilder.ToString().EndsWith("\r\n"))
{
msrmntTimeStamp = StateMachine.Time;
string received = stringBuilder.ToString();
/// Eliminate double spaces in the received string
while (true)
{
string tmp = received.Replace(" ", " ");
if (tmp.Length == received.Length) break;
received = tmp;
}
string[] field = received.Substring(0, received.Length - 2).Split(new char[] { ' ' });
double m; /// Result of double.TryParse
///
/// Mass measurement
///
if (proto == Protocol.SICS && field.Length == 4 && field[0] == "S" && (field[1] == "S" || field[1] == "D")
&& double.TryParse(field[2], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign,
CultureInfo.InvariantCulture, out m))
{
/// Stable (field[1] == "S") or dynamic (field[1] == "D") mass measurement
mass = Common.Units.ConvertFrom(ParseUnit(field[3]), m);
msrmntState = MsrmntState.Valid;
}
else if (proto == Protocol.ID1 && field.Length >= 3 && (field[0] == "S" || field[0] == "SD")
&& double.TryParse(field[1], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign,
CultureInfo.InvariantCulture, out m))
{
/// Stable mass: field[1] = <mass> field[2] = "kg"
mass = Common.Units.ConvertFrom(ParseUnit(field[2]), m);
msrmntState = MsrmntState.Valid;
}
else if ((proto == Protocol.ID1 && field.Length == 1 && field[0] == "SI-") ||
(proto == Protocol.SICS && field.Length == 2 && field[0] == "S" && field[1] == "-"))
{
/// Invalid value : Scale is in underload range
mass = 0;
msrmntState = MsrmntState.Failed;
}
else if ((proto == Protocol.ID1 && field.Length == 1 && field[0] == "SI+") ||
(proto == Protocol.SICS && field.Length == 2 && field[0] == "S" && field[1] == "+") ||
(proto == Protocol.SICS && field.Length >= 2 && field[0] == "SI" && field[1] == "I"))
{
/// Invalid value : Scale is in overload range
/// "SI I<cr><lf>" received in case of overload -> empty the tank
mass = scaleCfg.Capacity;
msrmntState = MsrmntState.Overload;
}
else if ((proto == Protocol.ID1 && field.Length == 1 && field[0] == "SI") ||
(proto == Protocol.SICS && field.Length >= 2 && field[0] == "S" && field[1] == "I"))
{
/// Invalid value
msrmntState = MsrmntState.Failed;
}
///
/// Zero
///
else if ((proto == Protocol.ID1 && field.Length == 1 && field[0] == "ZB") ||
(proto == Protocol.SICS && field.Length == 2 && field[0] == "Z" && field[1] == "A"))
{
/// Zero command successful, reading is 0 now
mass = 0;
msrmntState = MsrmntState.Valid;
}
else if (proto == Protocol.ID1 && field.Length == 1 && field[0] == "Z-")
{
/// Zero command cannot be executed : Below lower limit of zero set range
mass = 0;
msrmntState = MsrmntState.Failed;
}
else if (proto == Protocol.ID1 && field.Length == 1 && field[0] == "Z+")
{
/// Zero command cannot be executed : Above upper limit of zero set range
mass = 0;
msrmntState = MsrmntState.Overload;
}
///
/// Tare
///
else if (proto == Protocol.ID1 && field.Length >= 3 && field[0] == "TB"
&& double.TryParse(field[1], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign,
CultureInfo.InvariantCulture, out m))
{
/// Tare command successful : response is "TB value unit\r\n"
mass = Common.Units.ConvertFrom(ParseUnit(field[2]), m);
msrmntState = MsrmntState.Valid;
}
else if (proto == Protocol.SICS && field.Length == 4 && field[0] == "T" && field[1] == "S"
&& double.TryParse(field[2], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign,
CultureInfo.InvariantCulture, out m))
{
/// Taring, SICS protocol
mass = Common.Units.ConvertFrom(ParseUnit(field[3]), m);
msrmntState = MsrmntState.Valid;
}
else if (proto == Protocol.ID1 && field.Length == 1 && field[0] == "T-")
{
/// Tare command cannot be executed : Below lower limit of zero set range
msrmntState = MsrmntState.Failed;
}
else if ((proto == Protocol.ID1 && field.Length == 1 && field[0] == "T+") ||
(proto == Protocol.SICS && field.Length >= 2 && field[1] == "I"))
{
/// Tare command cannot be executed : Above upper limit of zero set range
msrmntState = MsrmntState.Overload;
}
///
/// Serial number
///
else if (proto == Protocol.SICS && field.Length == 3 && (field[0] == "I4" || field[0] == "IA")
&& field[1] == "A" && field[2].Length >= 3)
{
/// Serial number
serialNumber = field[2].Substring(1, field[2].Length - 2);
msrmntState = MsrmntState.Valid;
}
///
/// Units
///
else if (proto == Protocol.SICS && field.Length == 2 && field[0] == "U" && field[1] == "A")
{
msrmntState = MsrmntState.Valid;
}
else
{
/// Response was not recognised
msrmntState = MsrmntState.Failed;
}
/// Logging
if (field.Length > 0)
{
if (msrmntState == MsrmntState.Valid || msrmntState == MsrmntState.Busy)
{
log.InfoFormat("{0} - Received \"{1}<cr><lf>\", Mass = {2}, MsrmntState = {3}", Name, received, mass, msrmntState);
}
else
{
log.ErrorFormat("{0} - Received \"{1}<cr><lf>\", Mass = {2}, MsrmntState = {3}", Name, received, mass, msrmntState);
}
}
}
}
}
/// <summary>Run this device</summary>
public void RunDeviceAfter()
{
if (Activity == Activity.Idle)
{
SendImmediateMeasurementCmd();
Activity = Activity.ImmediateMeasurement;
}
base.RunAfter();
}
/// <summary>Stop this device</summary>
public void StopDevice()
{
if ((scaleCfg.DebugLevel != DebugMode.Simulate) && (serialPort != null))
{
serialPort.Close();
serialPort = null;
}
}
public void StopDevice2() { }
/// <summary>
/// Events: BalanceDone, Error
/// </summary>
/// <returns>ZeroOp reference</returns>
public IOperation ZeroOp()
{
switch (scaleCfg.ActionAfter1stDraining)
{
case ActionA1D.Zero:
return new ZeroOp(this);
case ActionA1D.Tara:
var dummy = new DoubleBox();
return new TaringOp(this, ref dummy);
default:
return null;
}
}
/// <summary>
/// Events: BalanceDone, Error
/// </summary>
/// <param name="result">Reference to a variable for 'tara' in kg</param>
/// <returns>TaringOp reference</returns>
public IOperation TaringOp(ref DoubleBox tara)
{
return new TaringOp(this, ref tara);
}
/// <summary>
/// Events: BalanceDone, Error
/// </summary>
/// <param name="result">Reference to a variable for the measured mass in kg</param>
/// <param name="readingsCount">Required mass readings count (>= 3)</param>
/// <param name="maxSpread">Maximum spread of measurements in kg (otherwise the measurement continues)</param>
/// <param name="method">Method: false = slow (precise), true = fast (immediate)</param>
/// <returns>ReadMassAverageOp instance reference casted to IOperaton</returns>
public IOperation ReadStableMassOp(ref DoubleBox mass, int delayBefore, MassMethod method, int readingsCount, double maxSpread)
{
return new ReadStableMassOp(this, ref mass, delayBefore, method, readingsCount, maxSpread);
}
/// <summary>
/// Events: BalanceDone, Error
/// </summary>
/// <param name="serialNumber">Reference to the serialNumber</param>
/// <returns>GetBalanceSNOp instance reference casted to IOperaton</returns>
public virtual IOperation GetSerNumOp(ref string serialNumber)
{
return (proto == Protocol.SICS) ? new GetSerNumOp(this, ref serialNumber) : null;
}
/// <summary>
/// Events: BalanceDone, Error
/// </summary>
/// <param name="units"></param>
/// <returns>SetUnitsOp instance reference casted to IOperaton</returns>
public IOperation SetUnitsOp(Common.Unit units)
{
return (proto == Protocol.SICS) ? new SetUnitsOp(this, units) : null;
}
/// <summary>
/// Parse a string representing mass units.
/// Defaults to 'kg'in case unitStr not recognized.
/// </summary>
/// <param name="unitStr">String: "kg", "g", "t", "lb" or "oz" expected</param>
/// <returns></returns>
protected Common.Unit ParseUnit(string unitStr)
{
if (unitStr == "g") return Common.Unit.g;
if (unitStr == "t") return Common.Unit.t;
if (unitStr == "lb") return Common.Unit.lb;
if (unitStr == "oz") return Common.Unit.oz;
return Common.Unit.kg;
}
}
}
+322
View File
@@ -0,0 +1,322 @@
///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Xml.Serialization;
using Common;
using Config.Entities;
using SchematicDrawing;
using TBF.Rig.Generic;
namespace TBF.Rig.Scales.MettlerToledo
{
public enum Protocol
{
SICS,
ID1,
}
public enum ActionA1D
{
Zero,
Tara,
None,
}
public class ScaleCfg : ComponentCfgBase, GenericDevices.IScaleCfg, GenericDevices.ITankDrainingCfg, IParamsProvider, IDrawingItemWithMeasuredVal
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(ScaleCfg) })[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 int ComPortNr;
public int BaudRate;
public Parity Parity;
public int DataBits;
public StopBits StopBits;
public Handshake Handshake;
public Protocol Protocol;
public float Capacity { get; set; } /// Max. water mass in 'kg' or volume in 'l'
public float Empty { get; set; } /// Mass threshold for 'Tank is empty' in 'kg' (or volume in 'l')
public float EmptyUp { get; set; } /// Mass threshold for 'Tank is empty' in 'kg' (or volume in 'l') when the drain valve is not open
public string Evaporation { get; set; }
public string DrainValve { get; set; }
public int DrainTimeSec { get; set; }
public ActionA1D ActionAfter1stDraining { get; set; }
/// Buoyancy related serialized parameters displayed in Metrology tab page
public float BuoyancyTemp { get; set; }
public float BuoyancyPress { get; set; }
public float BuoyancyHumi { get; set; }
public float WeightStandardDensity { get; set; }
/// Calibration info serialized parameters displayed in Metrology tab page
public string CalibCertificateNr { get; set; }
public DateTime CalibDate { get; set; }
public DateTime CalibValidDate { get; set; }
/// Schematic drawing info
public Shape Shape { get; set; }
public int X { get; set; }
public int Y { get; set; }
public Sz Sz { get; set; }
public Orient Orient { get; set; }
public bool Flip { get; set; }
public int LblX { get; set; }
public int LblY { get; set; }
public Orient LblOrient { get; set; }
public int MsrdX { get; set; }
public int MsrdY { get; set; }
public Orient MsrdOrient { get; set; }
public string MsrdFormat { get; set; }
public Common.Unit MsrdUnit { get; set; }
[XmlIgnore]
public IList<GNode> GNodes { get; set; }
[XmlIgnore]
public double MsrdValLimLo { get { return 0; } set { } }
[XmlIgnore]
public double MsrdValLimHi { get { return Capacity; } set { } }
/// Private parameterless constructor invoked by all other (public) constructors
ScaleCfg()
{
GNodes = new List<GNode>();
}
public ScaleCfg(string name, IComponentFactory factory)
: this()
{
Name = name;
Factory = factory;
ParentName = string.Empty;
InitializeAll();
}
public string ComponentName { get { return Name; } }
public void InitializeAll()
{
Shape = Shape.Scale;
Sz = Sz.M;
MsrdFormat = "{0:F3}";
MsrdUnit = Common.Unit.kg;
ComPortNr = 3;
BaudRate = 2400;
Parity = System.IO.Ports.Parity.Even;
DataBits = 7;
StopBits = System.IO.Ports.StopBits.One;
Handshake = System.IO.Ports.Handshake.None;
Protocol = Protocol.SICS;
Capacity = 200.0f;
Empty = 20.0f;
EmptyUp = 2.0f;
DrainValve = "VB1";
DrainTimeSec = 180;
ActionAfter1stDraining = ActionA1D.Zero;
Evaporation = string.Empty;
BuoyancyTemp = 20.0f;
BuoyancyPress = 1.0f;
BuoyancyHumi = 40.0f;
}
string[] paramNames = new string[]
{
"Serial port number", /// 0
"Baud rate", /// 1
"Parity", /// 2
"Data bits", /// 3
"Stop bits", /// 4
"Handshake", /// 5
"Protocol", /// 6
"Capacity [kg]", /// 7
"Is empty threshold when draining [kg]", /// 8
"Is empty threshold when closed [kg]", /// 9
"Drain valve", /// 10
"Drain time [s]", /// 11
"Action after the 1st draining", /// 12
"Evaporation", /// 13
};
public string ParamName(int i) { return paramNames[i]; }
public int ParamsCount() { return paramNames.Length; }
public ICollection<string> ParamValues(int i)
{
switch (i)
{
case 1:
return new string[] { "150", "300", "600", "1200",
"2400", "4800", "9600", "19200",
"38400", "57600", "76800", "115200"};
case 2:
return new string[] { Parity.None.ToString(),
Parity.Odd.ToString(),
Parity.Even.ToString() };
case 3:
return new string[] { "7", "8" };
case 4:
return new string[] { StopBits.None.ToString(),
StopBits.One.ToString(),
StopBits.OnePointFive.ToString(),
StopBits.Two.ToString() };
case 5:
return new string[] { Handshake.None.ToString(),
Handshake.XOnXOff.ToString(),
Handshake.RequestToSend.ToString(),
Handshake.RequestToSendXOnXOff.ToString() };
case 6:
return new string[] { Protocol.SICS.ToString(), Protocol.ID1.ToString() };
case 10:
IList<string> valves = new List<string>();
foreach (var c in StateMachine.MasterValves) valves.Add(c.Name);
if (valves.Count > 0) return valves;
return new string[] { "VB1", "VB2", "VB3" };
case 12:
return new string[] { ActionA1D.Zero.ToString(),
ActionA1D.Tara.ToString(),
ActionA1D.None.ToString() };
case 7:
case 8:
case 9:
case 11:
case 13:
default:
return null;
}
}
public string ToString(int i)
{
switch (i)
{
case 0: return ComPortNr.ToString();
case 1: return BaudRate.ToString();
case 2: return Parity.ToString();
case 3: return DataBits.ToString();
case 4: return StopBits.ToString();
case 5: return Handshake.ToString();
case 6: return Protocol.ToString();
case 7: return Capacity.ToString();
case 8: return Empty.ToString();
case 9: return EmptyUp.ToString();
case 10: return DrainValve;
case 11: return DrainTimeSec.ToString();
case 12: return ActionAfter1stDraining.ToString();
case 13: return Evaporation;
default:
return string.Format("Name={0}, {1}kg, empty={2}kg, emptyUp={3}kg, drainVlv={4}, drainTm={5}s, Com{6}, {7}Bd, {8}-bits, parity={9}, stopBits={10}, {11}",
Name, Capacity, Empty, EmptyUp, DrainValve, DrainTimeSec, ComPortNr, BaudRate, DataBits, Parity, StopBits, Handshake);
}
}
public CfgUpdateFlags UpdateParam(int i, string str)
{
switch (i)
{
case 0: ComPortNr = int.Parse(str); return CfgUpdateFlags.RestartRqrd;
case 1: BaudRate = int.Parse(str); return CfgUpdateFlags.RestartRqrd;
case 2: Parity = TBF.Utils.GetParity(str); return CfgUpdateFlags.RestartRqrd;
case 3: DataBits = int.Parse(str); return CfgUpdateFlags.RestartRqrd;
case 4: StopBits = TBF.Utils.GetStopBits(str); return CfgUpdateFlags.RestartRqrd;
case 5: Handshake = TBF.Utils.GetHandshake(str); return CfgUpdateFlags.RestartRqrd;
case 6: Protocol = (str == Protocol.SICS.ToString()) ? Protocol.SICS : Protocol.ID1; return CfgUpdateFlags.RestartRqrd;
case 7: Capacity = Utils.ParseUFloat(str); return CfgUpdateFlags.RestartRqrd;
case 8: Empty = Utils.ParseUFloat(str); return CfgUpdateFlags.RestartRqrd;
case 9: EmptyUp = Utils.ParseUFloat(str); return CfgUpdateFlags.RestartRqrd;
case 10: DrainValve = str; return CfgUpdateFlags.RestartRqrd;
case 11: DrainTimeSec = int.Parse(str); return CfgUpdateFlags.RestartRqrd;
case 12:
ActionAfter1stDraining = (str == ActionA1D.Zero.ToString()) ? ActionA1D.Zero
: (str == ActionA1D.Tara.ToString()) ? ActionA1D.Tara
: ActionA1D.None;
return CfgUpdateFlags.RestartRqrd;
case 13: Evaporation = str; return CfgUpdateFlags.RestartRqrd;
default: return CfgUpdateFlags.None;
}
}
public bool ValidateParam(int i, string strValue, out string message)
{
message = string.Empty;
int idummy;
float fdummy;
switch (i)
{
case 0: /// ComPortNr
case 11: /// DrainTimeSec
if (int.TryParse(strValue, out idummy) && idummy > 0) return true;
break;
case 1: /// BaudRate
case 2: /// Parity
case 3: /// DataBits
case 4: /// StopBits
case 5: /// Handshake
case 6: /// Protocol
case 10: /// DrainValve
case 12: /// ActionAfter1stDraining
if (ParamValues(i).Contains(strValue)) return true;
break;
case 7: /// Capacity
case 8: /// Empty
case 9: /// EmptyUp
if (Utils.TryParseUFloat(strValue, out fdummy)) return true;
break;
case 13: /// Evaporation
default:
message = "Invalid index";
return false;
}
message = ParamName(i) + " is invalid";
return false;
}
void CopyContentTo(ScaleCfg prms)
{
prms.ComPortNr = this.ComPortNr;
prms.BaudRate = this.BaudRate;
prms.Parity = this.Parity;
prms.DataBits = this.DataBits;
prms.StopBits = this.StopBits;
prms.Handshake = this.Handshake;
prms.Protocol = this.Protocol;
prms.Capacity = this.Capacity;
prms.Empty = this.Empty;
prms.EmptyUp = this.EmptyUp;
prms.DrainValve = this.DrainValve;
prms.DrainTimeSec = this.DrainTimeSec;
prms.ActionAfter1stDraining = this.ActionAfter1stDraining;
prms.Evaporation = this.Evaporation;
prms.BuoyancyTemp = this.BuoyancyTemp;
prms.BuoyancyPress = this.BuoyancyPress;
prms.BuoyancyHumi = this.BuoyancyHumi;
}
public IParamsProvider Clone()
{
ScaleCfg pars = new ScaleCfg();
CopyContentTo(pars);
return pars;
}
public bool UpdateEmbeddedDbEntity()
{
return true; /// =OK, do nothing
}
}
}
@@ -0,0 +1,81 @@
///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
namespace TBF.Rig.Scales.MettlerToledo
{
public class SetUnitsOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(SetUnitsOp));
public override string ToString() { return string.Format("SetUnitsOp({0})", units); }
/// Set by the constructor
Scale scale;
Common.Unit units;
bool activityStarted;
/// <summary>
/// Events: BalanceDone, Error
/// </summary>
/// <param name="scale">Balance device instance</param>
/// <param name="result">Reference to the serialNumber</param>
public SetUnitsOp(Scale scale, Common.Unit units)
{
if (scale == null) throw new ArgumentNullException("balanceDev");
this.scale = scale;
this.units = units;
log.Debug(this.ToString());
}
/// <summary>Start this operation</summary>
public void Start()
{
log.DebugFormat("{0} - SetUnitsOp - Start()", scale.Name);
if (scale.Activity == Activity.Idle)
{
scale.SendSetUnitsCmd(units);
activityStarted = true;
scale.Activity = Activity.RunningOperation;
}
else
{
activityStarted = false;
}
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.None
/// Event.BalanceDone
/// </returns>
public Event Run()
{
if (!activityStarted && scale.Activity == Activity.Idle)
{
scale.SendSetUnitsCmd(units);
activityStarted = true;
scale.Activity = Activity.RunningOperation;
return Event.None;
}
if (scale.MsrmntState == MsrmntState.Valid) return Event.ScaleDone; /// Units set
if (scale.MsrmntState == MsrmntState.Failed) return Event.Error; /// Failed
return Event.None; /// No result yet
}
/// <summary>Stop this operation</summary>
public void Stop()
{
if (scale.MsrmntState == MsrmntState.Busy) scale.MsrmntState = MsrmntState.Failed;
scale.Activity = Activity.Idle;
log.DebugFormat("{0} - SetUnitsOp - Stop()", scale.Name);
}
}
}
+100
View File
@@ -0,0 +1,100 @@
///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using log4net;
using TBF.Boxes;
namespace TBF.Rig.Scales.MettlerToledo
{
public class TaringOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(TaringOp));
public override string ToString() { return string.Format("TaringOp(.,.)"); }
bool done;
/// Set by the constructor
Scale scale;
DoubleBox tara;
bool activityStarted;
/// <summary>
/// Events: BalanceDone, Error
/// </summary>
/// <param name="scale">Balance device instance</param>
/// <param name="result">Reference to variable for 'tara' in kg</param>
public TaringOp(Scale scale, ref DoubleBox tara)
{
if (scale == null) throw new ArgumentNullException("balanceDev");
this.scale = scale;
this.tara = tara;
log.Debug(this.ToString());
}
/// <summary>Start this operation</summary>
public void Start()
{
log.DebugFormat("{0} - TaringOp - tart()", scale.Name);
done = false;
if (scale.Activity == Activity.Idle)
{
scale.SendTaraCmd();
activityStarted = true;
scale.Activity = Activity.RunningOperation;
}
else
{
activityStarted = false;
}
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.None
/// Event.BalanceDone
/// Event.Error . . . . . Current.Tick == null
/// </returns>
public Event Run()
{
if (!activityStarted && scale.Activity == Activity.Idle)
{
scale.SendTaraCmd();
activityStarted = true;
scale.Activity = Activity.RunningOperation;
return Event.Busy;
}
if (done) return Event.ScaleDone; /// Taring has been done already
if (scale.MsrmntState == MsrmntState.Busy) return Event.Busy;
if (scale.MsrmntState == MsrmntState.Overload)
{
tara.Val = scale.Capacity;
done = true;
return Event.ScaleOverload;
}
if (scale.MsrmntState == MsrmntState.Valid)
{
tara.Val = scale.Mass;
done = true;
return Event.ScaleDone; /// Taring completed
}
scale.SendTaraCmd(); /// Failed -> repeat taring
return Event.Busy;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
if (scale.MsrmntState == MsrmntState.Busy) scale.MsrmntState = MsrmntState.Failed;
scale.Activity = Activity.Idle;
log.DebugFormat("{0} - TaringOp - Stop()", scale.Name);
}
}
}
+95
View File
@@ -0,0 +1,95 @@
///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using log4net;
namespace TBF.Rig.Scales.MettlerToledo
{
public class ZeroOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(ZeroOp));
public override string ToString() { return string.Format("ZeroOp(.,.)"); }
bool done;
/// Set by the constructor
Scale scale;
bool activityStarted;
/// <summary>
/// Events: BalanceDone, Error
/// </summary>
/// <param name="scale">Balance device instance</param>
/// <param name="result">Reference to variable for 'tara' in kg</param>
public ZeroOp(Scale scale)
{
if (scale == null) throw new ArgumentNullException("balanceDev");
this.scale = scale;
log.Debug(this.ToString());
}
/// <summary>Start this operation</summary>
public void Start()
{
log.DebugFormat("{0} - ZeroOp - Start()", scale.Name);
done = false;
if (scale.Activity == Activity.Idle)
{
scale.SendZeroWhenStableCmd();
activityStarted = true;
scale.Activity = Activity.RunningOperation;
}
else
{
activityStarted = false;
}
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.None
/// Event.BalanceDone
/// Event.Error . . . . . Current.Tick == null
/// </returns>
public Event Run()
{
if (!activityStarted && scale.Activity == Activity.Idle)
{
scale.SendZeroWhenStableCmd();
activityStarted = true;
scale.Activity = Activity.RunningOperation;
return Event.Busy;
}
if (done) return Event.ScaleDone; /// Zeroing has been done already
if (scale.MsrmntState == MsrmntState.Busy) return Event.Busy;
if (scale.MsrmntState == MsrmntState.Overload)
{
done = true;
return Event.ScaleOverload;
}
if (scale.MsrmntState == MsrmntState.Valid)
{
done = true;
return Event.ScaleDone; /// Zeroing completed
}
scale.SendZeroWhenStableCmd(); /// Failed -> repeat zeroing
return Event.Busy;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
if (scale.MsrmntState == MsrmntState.Busy) scale.MsrmntState = MsrmntState.Failed;
scale.Activity = Activity.Idle;
log.DebugFormat("{0} - ZeroOp - Stop()", scale.Name);
}
}
}
+208
View File
@@ -0,0 +1,208 @@
///
/// Copyright (c) 2017-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using log4net;
using TBF.Rig.GenericDevices;
using TBF.Resources;
namespace TBF.Rig.Scales
{
public enum DrainState
{
None,
OpeningDV_Start,
OpeningDV_Run,
OpeningDV_Stop,
Draining,
ClosingDV_Start,
ClosingDV_Run,
ClosingDV_Stop,
TankClosed,
}
public class TankDraining : ComponentBase, ITankDraining, ISequenceCondition
{
private static readonly ILog log = LogManager.GetLogger(typeof(TankDraining));
readonly GenericDevices.ITankDrainingCfg tankDrainingCfg;
bool hasDrainValve { get { return !string.IsNullOrEmpty(tankDrainingCfg.DrainValve); } } /// Available in UI (unlike 'drainValve')
IValve drainValve;
public IValve DrainValve { get { return drainValve; } }
IEvaporation evaporationCmpnt;
IOperation openTheDrainValveOp;
IOperation closeTheDrainValveOp;
IOperation waitTankIsEmptyOp;
IOperation waitTankContainsMoreThenThld1Op;
IOperation waitTankContainsMoreThenThld2Op;
IOperation waitTankContainsMoreThenThld3Op;
IOperation waitTankContainsMoreThenThld4Op;
DrainState drainState;
public TankDraining()
: base()
{
openTheDrainValveOp = null;
closeTheDrainValveOp = null;
waitTankIsEmptyOp = null;
waitTankContainsMoreThenThld1Op = null;
waitTankContainsMoreThenThld2Op = null;
waitTankContainsMoreThenThld3Op = null;
waitTankContainsMoreThenThld4Op = null;
}
public TankDraining(Generic.IComponentCfg cfg)
: base(cfg)
{
tankDrainingCfg = cfg as GenericDevices.ITankDrainingCfg;
if (tankDrainingCfg == null) throw new Exception(string.Format("Cannot create component {0}", cfg.Name));
openTheDrainValveOp = null;
closeTheDrainValveOp = null;
waitTankIsEmptyOp = null;
waitTankContainsMoreThenThld1Op = null;
waitTankContainsMoreThenThld2Op = null;
waitTankContainsMoreThenThld3Op = null;
waitTankContainsMoreThenThld4Op = null;
}
public override void Initialize()
{
drainValve = TbfComponents.FindComponent(tankDrainingCfg.DrainValve) as IValve;
evaporationCmpnt = TbfComponents.FindComponent(tankDrainingCfg.Evaporation) as IEvaporation;
if (drainValve == null) throw new Exception(string.Format("{0} is missing a drain valve", Name));
openTheDrainValveOp = new BuiltIn.SetValvesOp(StateMachine.ControlBoard, drainValve, null);
closeTheDrainValveOp = new BuiltIn.SetValvesOp(StateMachine.ControlBoard, null, drainValve);
waitTankIsEmptyOp = new WaitTankEmptyOp(this);
Various.TankWithLevelMsrmnt.TankCfg tankCfg = tankDrainingCfg as Various.TankWithLevelMsrmnt.TankCfg;
if (tankCfg != null)
{
waitTankContainsMoreThenThld1Op = new WaitTankContainsMoreThenOp(this, tankCfg.ThldLevel1);
waitTankContainsMoreThenThld2Op = new WaitTankContainsMoreThenOp(this, tankCfg.ThldLevel2);
waitTankContainsMoreThenThld3Op = new WaitTankContainsMoreThenOp(this, tankCfg.ThldLevel3);
waitTankContainsMoreThenThld4Op = new WaitTankContainsMoreThenOp(this, tankCfg.ThldLevel4);
}
}
protected void RunBefore()
{
switch (drainState)
{
case DrainState.OpeningDV_Start:
openTheDrainValveOp.Start();
drainState = DrainState.OpeningDV_Run;
return;
case DrainState.OpeningDV_Run:
if (openTheDrainValveOp.Run() == Event.ValvesSet) drainState = DrainState.OpeningDV_Stop;
return;
case DrainState.OpeningDV_Stop:
openTheDrainValveOp.Stop();
return;
case DrainState.Draining:
if (IsEmpty()) drainState = DrainState.ClosingDV_Start;
return;
case DrainState.ClosingDV_Start:
closeTheDrainValveOp.Start();
drainState = DrainState.ClosingDV_Run;
return;
case DrainState.ClosingDV_Run:
if (closeTheDrainValveOp.Run() == Event.ValvesSet) drainState = DrainState.ClosingDV_Stop;
return;
case DrainState.ClosingDV_Stop:
closeTheDrainValveOp.Stop();
return;
default:
return;
}
}
protected void RunAfter() { } /// Not used
public virtual string GetName() { return string.Empty; }
public virtual bool IsEmpty() { return false; }
public virtual bool ContainsMoreThen(float thld) { return thld == 0; }
/// <summary>
/// For a given temperature in [°C] returns an evaporation rate in [kg/s]
/// </summary>
public double EvaporationRate(double temperature)
{
return (evaporationCmpnt != null) ? evaporationCmpnt.EvaporationRate(temperature) : 0;
}
public int ConditionsCount
{
get { return hasDrainValve ? 3 : ((tankDrainingCfg is Various.TankWithLevelMsrmnt.TankCfg) ? 4 : 0); }
}
/// Strings are added to the combo-box for transition sequence condition selection
public string ConditionName(int i)
{
if (hasDrainValve)
{
switch (i)
{
case 0: return string.Format(Strings._0_open_the_drain_valve, Name);
case 1: return string.Format(Strings._0_close_the_drain_valve, Name);
case 2: return string.Format(Strings._0_wait_until_the_tank_is_empty, Name);
}
}
else if (tankDrainingCfg is Various.TankWithLevelMsrmnt.TankCfg)
{
var tankCfg = tankDrainingCfg as Various.TankWithLevelMsrmnt.TankCfg;
switch (i)
{
case 0: return string.Format(Strings._0_wait_until_tank_contains_more_then_1_l, Name, tankCfg.ThldLevel1);
case 1: return string.Format(Strings._0_wait_until_tank_contains_more_then_1_l, Name, tankCfg.ThldLevel2);
case 2: return string.Format(Strings._0_wait_until_tank_contains_more_then_1_l, Name, tankCfg.ThldLevel3);
case 3: return string.Format(Strings._0_wait_until_tank_contains_more_then_1_l, Name, tankCfg.ThldLevel4);
}
}
return string.Empty; // Default
}
/// Operation to be executed as a part of a transition sequence
public IOperation ConditionOp(int i)
{
if (hasDrainValve)
{
switch (i)
{
case 0: return openTheDrainValveOp;
case 1: return closeTheDrainValveOp;
case 2: return waitTankIsEmptyOp;
}
}
else if (tankDrainingCfg is Various.TankWithLevelMsrmnt.TankCfg)
{
switch (i)
{
case 0: return waitTankContainsMoreThenThld1Op;
case 1: return waitTankContainsMoreThenThld2Op;
case 2: return waitTankContainsMoreThenThld3Op;
case 3: return waitTankContainsMoreThenThld4Op;
}
}
return null; /// Default
}
}
}
@@ -0,0 +1,51 @@
///
/// Copyright (c) 2018-2021 Sensus Slovensko a.s.
///
using log4net;
namespace TBF.Rig.Scales
{
public class WaitTankContainsMoreThenOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(WaitTankContainsMoreThenOp));
public override string ToString() { return string.Format("WaitTankFullOp()"); }
readonly GenericDevices.ITankDraining tankDraining;
float threshodLevel;
bool conditionMet;
/// <summary>
/// Events: ConditionMet, ConditionNotMet
/// </summary>
/// <param name="tankDraining">Tank draining (Balance device) instance</param>
public WaitTankContainsMoreThenOp(GenericDevices.ITankDraining tankDraining, float thresholdLevel)
{
this.tankDraining = tankDraining;
this.threshodLevel = thresholdLevel;
log.Debug(this.ToString());
}
/// <summary>Start this operation</summary>
public void Start()
{
conditionMet = tankDraining.ContainsMoreThen(threshodLevel);
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.ConditionMet . . . tank is empty
/// Event.ConditionNotMet . tank is not empty
/// </returns>
public Event Run()
{
conditionMet = conditionMet || tankDraining.ContainsMoreThen(threshodLevel);
return conditionMet ? Event.ConditionMet : Event.ConditionNotMet;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}
+50
View File
@@ -0,0 +1,50 @@
///
/// Copyright (c) 2017-2021 Sensus Slovensko a.s.
///
using log4net;
namespace TBF.Rig.Scales
{
public class WaitTankEmptyOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(WaitTankEmptyOp));
public override string ToString() { return string.Format("WaitTankEmptyOp()"); }
readonly GenericDevices.ITankDraining tankDraining;
bool conditionMet;
/// <summary>
/// Events: ConditionMet, ConditionNotMet
/// </summary>
/// <param name="tankDraining">Tank draining (Balance device) instance</param>
public WaitTankEmptyOp(GenericDevices.ITankDraining tankDraining)
{
this.tankDraining = tankDraining;
log.Debug(this.ToString());
}
/// <summary>Start this operation</summary>
public void Start()
{
conditionMet = tankDraining.IsEmpty();
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.ConditionMet . . . tank is empty
/// Event.ConditionNotMet . tank is not empty
/// </returns>
public Event Run()
{
conditionMet = conditionMet || tankDraining.IsEmpty();
return conditionMet ? Event.ConditionMet : Event.ConditionNotMet;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}
+4 -3
View File
@@ -64,9 +64,10 @@ namespace TBF.Rig
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<BuiltIn.ValveEx.Valve> LogicalFnValves; /// list of logical function valves
public static IList<IValve> MasterValves = new List<IValve>(); /// list of directly controlled valves
public static IList<IValve> CoupledValves = new List<IValve>(); /// list of coupled valves
public static IList<BuiltIn.ValveEx.Valve> LogicalFnValves =
new List<BuiltIn.ValveEx.Valve>(); /// list of logical function valves
public static IList<string> LoopStartNames;
public static IList<string> LoopEndNames;
+9 -4
View File
@@ -56,9 +56,6 @@ namespace TBF.Rig
Factories.Add(new Hart.Nivotrack.Factory());
Factories.Add(new Keithley.Multimeter_2010_RS232.Factory()); /// Keithley.Multimeter_2010_RS232
Factories.Add(new Keithley.TempMeter.Factory()); /// Keithley.TempMeter
Factories.Add(new MettlerToledo.Standard.BalanceFactory()); /// MettlerToledo Balance
Factories.Add(new MettlerToledo.Standard.BalanceOldFactory()); /// MettlerToledoBalanceOld
Factories.Add(new MettlerToledo.Standard.BalanceNewFactory()); /// MettlerToledoBalanceSN
Factories.Add(new Modbus.Common.Factory()); /// Modbus
Factories.Add(new Modbus.Ambient.Comet.Factory()); /// Comet Ambient temp./pressure/humidity measurement via a modbus on a PC
Factories.Add(new Modbus.Easytherm.Factory()); /// Modbus.Easytherm
@@ -123,6 +120,7 @@ namespace TBF.Rig
Factories.Add(new RegisterReaders.KPackE.RegisterReader.Factory()); /// KPackE register reader
Factories.Add(new RegisterReaders.KPackE.Radio.Factory()); /// Radio for KPackE register readers
Factories.Add(new Uni.RegValve.Factory());
Factories.Add(new Scales.MettlerToledo.Factory());
Factories.Add(new TestMethods.Adjustment.Factory());
Factories.Add(new TestMethods.ChangeFlowDirection.Factory());
Factories.Add(new TestMethods.CombinedWithDetection.TestMethodFactory());
@@ -193,7 +191,14 @@ namespace TBF.Rig
Factories.Add(new Various.StatisticsMonitoring.Factory());
Factories.Add(new Various.TankWithLevelMsrmnt.Factory());
Factories.Add(new WaterMeters.WaterMeter.WaterMeterFactory()); /// 'WaterMeter'
}
#if OBSOLETE
/// Obsolete components
Factories.Add(new MettlerToledo.Standard.BalanceFactory()); /// MettlerToledo Balance
Factories.Add(new MettlerToledo.Standard.BalanceOldFactory()); /// MettlerToledoBalanceOld
Factories.Add(new MettlerToledo.Standard.BalanceNewFactory()); /// MettlerToledoBalanceSN
#endif
}
/// <summary>
/// Get a component factory given the component name
+15 -4
View File
@@ -43,7 +43,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
@@ -53,7 +53,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
@@ -62,7 +62,7 @@
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
@@ -73,7 +73,7 @@
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
@@ -1113,6 +1113,17 @@
</Compile>
<Compile Include="Rig\RegisterReaders\StandingStartStop\Factory.cs" />
<Compile Include="Rig\RegisterReaders\StandingStartStop\RRProcParams.cs" />
<Compile Include="Rig\Scales\MettlerToledo\ScaleCfg.cs" />
<Compile Include="Rig\Scales\MettlerToledo\Scale.cs" />
<Compile Include="Rig\Scales\MettlerToledo\Factory.cs" />
<Compile Include="Rig\Scales\MettlerToledo\GetSerNumOp.cs" />
<Compile Include="Rig\Scales\MettlerToledo\ReadStableMassOp.cs" />
<Compile Include="Rig\Scales\MettlerToledo\SetUnitsOp.cs" />
<Compile Include="Rig\Scales\MettlerToledo\TaringOp.cs" />
<Compile Include="Rig\Scales\MettlerToledo\ZeroOp.cs" />
<Compile Include="Rig\Scales\TankDraining.cs" />
<Compile Include="Rig\Scales\WaitTankContainsMoreThenOp.cs" />
<Compile Include="Rig\Scales\WaitTankEmptyOp.cs" />
<Compile Include="Rig\Sequences\DeferredTestEvaluationData.cs" />
<Compile Include="Rig\Sequences\MainSeqUtils.cs" />
<Compile Include="Rig\Sequences\Plotter.cs" />
+7 -7
View File
@@ -75,9 +75,9 @@ namespace TBF.UI.Procedures
/// SharedDlgButtons configuration
#if KEMPNO_50 || KRAKOW_50
sharedButtons.RequiredGroupMembership = new Common.GID[] { Common.GID.TestingSpecialists, Common.GID.WaterMeterAuthority };
sharedButtons.RequiredGroupMembership = new GID[] { GID.TestingSpecialists, GID.WaterMeterAuthority };
#else
sharedButtons.RequiredGroupMembership = new Common.GID[] { Common.GID.TestingSpecialists, Common.GID.Metrologists };
sharedButtons.RequiredGroupMembership = new GID[] { GID.TestingSpecialists, GID.Metrologists };
#endif
sharedButtons.OptionalButtons = SharedButtons.Buttons.Add |
@@ -130,11 +130,11 @@ namespace TBF.UI.Procedures
this.initialMode = initialMode;
#if KEMPNO_50 || KRAKOW_50
sharedButtons.RequiredGroupMembership = procedure.Protected ? new Common.GID[] { Common.GID.WaterMeterAuthority }
: new Common.GID[] { Common.GID.TestingSpecialists, Common.GID.WaterMeterAuthority };
sharedButtons.RequiredGroupMembership = procedure.Protected ? new GID[] { GID.WaterMeterAuthority }
: new GID[] { GID.TestingSpecialists, GID.WaterMeterAuthority };
#else
sharedButtons.RequiredGroupMembership = procedure.Protected ? new Common.GID[] { Common.GID.Metrologists }
: new Common.GID[] { Common.GID.TestingSpecialists, Common.GID.Metrologists };
sharedButtons.RequiredGroupMembership = procedure.Protected ? new GID[] { GID.Metrologists }
: new GID[] { GID.TestingSpecialists, GID.Metrologists };
#endif
if (initialMode == Mode.PermanentlyLocked) sharedButtons.DisableUnlock();
@@ -1924,7 +1924,7 @@ namespace TBF.UI.Procedures
procNameTextBox.Enabled = true;
descriptionTextBox.Enabled = true;
variantTextBox.Enabled = true;
protectedCheckBox.Enabled = GlobalData.CurrentUser.IsMemberOf(Common.GID.Metrologists);
protectedCheckBox.Enabled = GlobalData.CurrentUser.IsMemberOf(GID.Metrologists);
mustBeCompleteCheckBox.Enabled = true;
manualControlDisabledCheckBox.Enabled = true;
dataEntryComboBox.Enabled = true;
+2 -1
View File
@@ -4,6 +4,7 @@
using System;
using System.Windows.Forms;
using log4net;
using Common;
using TBF.Resources;
using TBF.UI.Shared;
@@ -24,7 +25,7 @@ namespace TBF.UI.Procedures
InitializeComponent();
/// SharedDlgButtons configuration
sharedButtons.RequiredGroupMembership = new Common.GID[] { Common.GID.TestingSpecialists, Common.GID.Metrologists };
sharedButtons.RequiredGroupMembership = new GID[] { GID.TestingSpecialists, GID.Metrologists };
#if TEST_PROFILES
sharedButtons.OptionalButtons = SharedButtons.Buttons.Add | SharedButtons.Buttons.Remove |
+2 -2
View File
@@ -31,7 +31,7 @@
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
@@ -42,7 +42,7 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>