tbf/TestBenchFramework/BenchControl/MettlerToledo/BalanceNewDev.cs
Milan Hanajik 94de991bf6 Everything works OK after serious changes:
- all components, componentCfg-s and parameter providers use base classes
 - less boilerplate code, simpler access to test/procedure parameters from code
 - CreateTestParams(test), CreateProcedureParams(procedure) methods added
 - TestBenchSim class is made static, it is not inheritted by any device anymore
2015-01-02 12:51:27 +01:00

261 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.IO.Ports;
using log4net;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.MettlerToledo
{
/// <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 BalanceNewDev : BalanceDev, IDevice, GenericDevices.IBalance2
{
/// <summary>
/// Info: StartMassMeasurement() and "Balnce response = .., Mass = ..."
/// Warn: Start measurement when busy is true
/// </summary>
private static readonly ILog log = LogManager.GetLogger(typeof(BalanceNewDev));
public override string ToString() { return string.Format("MettlerToledo.BalanceNew({0})", Cfg.ToString(1)); }
/// <summary>Serial number after GetSerialNumber() when MsrmntState == MsrmntState.Valid</summary>
public string SerialNumber { get { return serialNumber; } }
string serialNumber;
public BalanceNewDev(BalanceCfg cfg, IList<Generic.IComponent> components)
: base(cfg, components)
{
log.Debug(this.ToString());
}
/// <summary>
/// Get the serial number
/// </summary>
public void GetSerialNumber()
{
if (balanceCfg.DebugLevel == Entities.DebugMode.Simulate) return;
if (msrmntState == MsrmntState.Busy)
{
log.Warn("GetSerialNumber() returns without getting the s/n because measurementState == MeasurementState.Busy");
return;
}
log.Info("GetSerialNumber()");
msrmntState = MsrmntState.Busy;
stringBuilder.Clear();
serialPort.Write("I4\r\n");
}
/// <summary>
/// Parse characters received from the serial port
/// </summary>
public override void RunDeviceBefore()
{
if (balanceCfg.DebugLevel == Entities.DebugMode.Simulate)
{
mass = TestBenchSim.GetSimMass(balanceNr);
Masses[balanceNr] = mass;
serialNumber = "1234567890";
msrmntState = MsrmntState.Valid;
msrmntTimeStamp = StateMachine.Time;
return;
}
log.Debug("RunDevice()");
if (base.msrmntState != MsrmntState.Busy) return; /// No measurement in progress
string justReceived = serialPort.ReadExisting();
if (justReceived != null && justReceived.Length > 0)
{
log.Debug("RunDevice() received " + justReceived);
stringBuilder.Append(justReceived);
if (stringBuilder.ToString().EndsWith("\r\n"))
{
msrmntTimeStamp = StateMachine.Time;
string received = stringBuilder.ToString();
while (true)
{
string tmp = received.Replace(" ", " ");
if (tmp.Length == received.Length) break;
received = tmp;
}
string[] fields = received.Substring(0, received.Length - 2).Split(new char[] { ' ' });
if (fields.Length < 2)
{
msrmntState = MsrmntState.Failed;
log.WarnFormat("Balance response = {0}, Unexpected error !!!",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"));
return;
}
if (fields[0].Equals("I4")) /// Serial number
{
if (fields.Length == 3 && fields[1].Equals("A") && fields[2].Length >= 3)
{
serialNumber = fields[2].Substring(1, fields[2].Length - 2);
msrmntState = MsrmntState.Valid;
log.InfoFormat("Balance response = {0}, s/n = {1}",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"), serialNumber);
}
else
{
msrmntState = MsrmntState.Failed;
log.WarnFormat("Balance response = {0}, error !!!",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"));
}
}
else if (fields[0].Equals("Z")) /// Zero when stable
{
if (fields.Length == 2 && fields[1].Equals("A"))
{
mass = 0;
Masses[balanceNr] = mass;
msrmntState = MsrmntState.Valid;
log.InfoFormat("Balance response = {0}",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"));
}
else
{
msrmntState = MsrmntState.Failed;
log.WarnFormat("Balance response = \"{0}\", error !!!",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"));
}
}
else if (fields[0].Equals("S")) /// Stable (field[1] == "S") or dynamic (field[1] == "D") mass measurement
{
if (fields.Length == 4 && fields[1].Equals("S") &&
float.TryParse(fields[2], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowLeadingWhite,
CultureInfo.InvariantCulture, out mass))
{
if (fields[3].Equals("g")) mass /= 1000.0f;
if (fields[3].Equals("t")) mass *= 1000.0f;
Masses[balanceNr] = mass;
msrmntState = MsrmntState.Valid;
log.InfoFormat("Balance response = {0}, Mass = {1}",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"), mass);
}
else if (fields.Length == 4 && fields[1].Equals("D") &&
float.TryParse(fields[2], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowLeadingWhite,
CultureInfo.InvariantCulture, out mass))
{
if (fields[3].Equals("g")) mass /= 1000.0f;
if (fields[3].Equals("t")) mass *= 1000.0f;
Masses[balanceNr] = mass;
msrmntState = MsrmntState.Valid;
log.InfoFormat("Balance response = {0}, Mass = {1}",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"), mass);
}
else if (fields.Length == 2 && fields[1].Equals("-"))
{
mass = 0;
Masses[balanceNr] = mass;
msrmntState = MsrmntState.Valid;
log.InfoFormat("Balance response = {0}, Mass = {1}",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"), mass);
}
else if (fields.Length >= 2 && fields[1].Equals("I"))
{
mass = balanceCfg.Capacity;
Masses[balanceNr] = mass;
msrmntState = MsrmntState.Overload;
log.InfoFormat("Balance response = {0}, Overload",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"), mass);
}
else
{
msrmntState = MsrmntState.Failed;
log.WarnFormat("Balance response = \"{0}\", Overload or and unexpected error !!!",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"));
}
}
else if (fields[0].Equals("T")) /// Taring
{
if (fields.Length == 4 && fields[1].Equals("S") &&
float.TryParse(fields[2], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowLeadingWhite,
CultureInfo.InvariantCulture, out mass))
{
if (fields[3].Equals("g")) mass /= 1000.0f;
if (fields[3].Equals("t")) mass *= 1000.0f;
msrmntState = MsrmntState.Valid;
log.InfoFormat("Balance response = {0}, Mass = {1}",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"), mass);
}
else if (fields.Length >= 2 && fields[1].Equals("I"))
{
mass = mass = balanceCfg.Capacity;
msrmntState = MsrmntState.Overload;
log.InfoFormat("Balance response = {0}, Overload",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"), mass);
}
else
{
msrmntState = MsrmntState.Failed;
log.WarnFormat("Balance response = \"{0}\", Overload or and unexpected error !!!",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"));
}
}
else if (fields[0].Equals("U"))
{
if (fields.Length == 2 && fields[1].Equals("A"))
{
msrmntState = MsrmntState.Valid;
log.InfoFormat("Balance response = \"{0}\"",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"));
}
else
{
msrmntState = MsrmntState.Failed;
log.WarnFormat("Balance response = \"{0}\", Unexpected error !!!",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"));
}
}
else if (fields[0].Equals("SI")) /// "SI I<cr><lf>" received in case of overload -> empty the tank
{
if (fields.Length >= 2 && fields[1].Equals("I"))
{
mass = balanceCfg.Capacity;
Masses[balanceNr] = mass;
msrmntState = MsrmntState.Valid;
//msrmntState = MsrmntState.Overload;
log.WarnFormat("Balance response = \"{0}\", Overload.",
received.Replace("\r", "<cr>").Replace("\n", "<lf>"));
}
}
}
}
}
/// <summary>
/// Events: BalanceDone, Error
/// </summary>
/// <param name="serialNumber">Reference to the serialNumber</param>
/// <returns>GetBalanceSNOp instance reference casted to IOperaton</returns>
public IOperation GetBalanceSNOp(ref string serialNumber)
{
return new GetBalanceSNOp(this, ref serialNumber);
}
/// <summary>
/// Events: BalanceDone, Error
/// </summary>
/// <param name="units"></param>
/// <returns>SetUnitsOp instance reference casted to IOperaton</returns>
public IOperation SetUnitsOp(Units units)
{
return new SetUnitsOp(this, units);
}
}
}