///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using System.Globalization;
using log4net;
using Common;
using Config.Entities;
using TBF.Rig.Generic;
namespace TBF.Rig.MettlerToledo.Standard
{
///
/// Mettler Toledo ICS4_5 Weighting terminal connected via serial interface (RS232)
///
///
/// Implemented and tested on 15.10.2013 by Milan Hanajik
///
public class BalanceNewDev : BalanceDev, IDevice, GenericDevices.IScale
{
///
/// Info: StartMassMeasurement() and "Balnce response = .., Mass = ..."
/// Warn: Start measurement when busy is true
///
private static readonly ILog log = LogManager.GetLogger(typeof(BalanceNewDev));
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
/// Serial number after GetSerialNumber() when MsrmntState == MsrmntState.Valid
public string SerialNumber { get { return serialNumber; } }
string serialNumber;
public BalanceNewDev() { }
public BalanceNewDev(Generic.IComponentCfg cfg)
: base(cfg)
{
}
///
/// Get the serial number
///
public void SendGetSerialNumberCmd()
{
if (balanceCfg.DebugLevel == DebugMode.Simulate) return;
if (serialPort == null || !serialPort.IsOpen)
{
log.ErrorFormat("{0} - SendGetSerialNumberCmd() - serial port closed", Name);
return;
}
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");
}
///
/// Parse characters received from the serial port
///
public override void RunDeviceBefore()
{
base.RunBefore();
if (balanceCfg.DebugLevel == DebugMode.Simulate)
{
mass = TestBenchSim.GetSimMass(balanceNr);
Masses[balanceNr] = mass;
serialNumber = "1234567890";
msrmntState = MsrmntState.Valid;
msrmntTimeStamp = StateMachine.Time;
return;
}
if (serialPort == null || !serialPort.IsOpen)
{
log.ErrorFormat("{0} - RunDeviceBefore() - serial port closed", Name);
return;
}
log.DebugFormat("{0} - RunDeviceBefore()", Name);
if (base.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[] { ' ' });
if (field.Length < 2)
{
msrmntState = MsrmntState.Failed;
log.WarnFormat("{0} - Balance response = {1}, Unexpected error !!!", Name,
received.Replace("\r", "").Replace("\n", ""));
return;
}
if (field[0] == "I4" || field[0] == "IA") /// Serial number
{
if (field.Length == 3 && field[1] == "A" && field[2].Length >= 3)
{
serialNumber = field[2].Substring(1, field[2].Length - 2);
msrmntState = MsrmntState.Valid;
log.WarnFormat("{0} - Balance response = {1}, s/n = {2}", Name,
received.Replace("\r", "").Replace("\n", ""), serialNumber);
}
else
{
msrmntState = MsrmntState.Failed;
log.WarnFormat("{0} - Balance response = {1}, error !!!", Name,
received.Replace("\r", "").Replace("\n", ""));
}
}
else if (field[0] == "Z") /// Zero when stable
{
if (field.Length == 2 && field[1] == "A")
{
mass = 0;
Masses[balanceNr] = mass;
msrmntState = MsrmntState.Valid;
log.WarnFormat("{0} - Balance response = {1}", Name,
received.Replace("\r", "").Replace("\n", ""));
}
else
{
msrmntState = MsrmntState.Failed;
log.WarnFormat("{0} - Balance response = \"{1}\", error !!!", Name,
received.Replace("\r", "").Replace("\n", ""));
}
}
else if (field[0] == "S") /// Stable (field[1] == "S") or dynamic (field[1] == "D") mass measurement
{
if (field.Length == 4 && (field[1] == "S" || field[1] == "D") &&
double.TryParse(field[2], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowLeadingWhite,
CultureInfo.InvariantCulture, out mass))
{
mass = Common.Units.ConvertFrom(ParseUnit(field[3]), mass);
Masses[balanceNr] = mass;
msrmntState = MsrmntState.Valid;
log.InfoFormat("{0} - Balance response = {1}, Mass = {2}", Name,
received.Replace("\r", "").Replace("\n", ""), mass);
}
else if (field.Length == 2 && field[1] == "-")
{
//mass = 0;
//Masses[balanceNr] = mass;
msrmntState = MsrmntState.Failed;
log.InfoFormat("{0} - Balance response = {1}, Mass = {2}", Name,
received.Replace("\r", "").Replace("\n", ""), mass);
}
else if (field.Length == 2 && field[1] == "+")
{
//mass = Capacity;
//Masses[balanceNr] = mass;
msrmntState = MsrmntState.Overload;
log.InfoFormat("{0} - Balance response = {1}, Overload", Name,
received.Replace("\r", "").Replace("\n", ""));
}
else if (field.Length >= 2 && field[1] == "I")
{
//mass = balanceCfg.Capacity;
//Masses[balanceNr] = mass;
msrmntState = MsrmntState.Overload;
log.InfoFormat("{0} - Balance response = {1}, Overload", Name,
received.Replace("\r", "").Replace("\n", ""), mass);
}
else
{
msrmntState = MsrmntState.Failed;
log.WarnFormat("{0} - Balance response = \"{1}\", Overload or and unexpected error !!!", Name,
received.Replace("\r", "").Replace("\n", ""));
}
}
else if (field[0] == "T") /// Taring
{
if (field.Length == 4 && field[1] == "S" &&
double.TryParse(field[2], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowLeadingWhite,
CultureInfo.InvariantCulture, out mass))
{
mass = Common.Units.ConvertFrom(ParseUnit(field[3]), mass);
msrmntState = MsrmntState.Valid;
log.WarnFormat("{0} - Balance response = {1}, Mass = {2}", Name,
received.Replace("\r", "").Replace("\n", ""), mass);
}
else if (field.Length >= 2 && field[1] == "I")
{
mass = mass = balanceCfg.Capacity;
msrmntState = MsrmntState.Overload;
log.WarnFormat("{0} - Balance response = {1}, Overload", Name,
received.Replace("\r", "").Replace("\n", ""), mass);
}
else
{
msrmntState = MsrmntState.Failed;
log.WarnFormat("{0} - Balance response = \"{1}\", Overload or and unexpected error !!!", Name,
received.Replace("\r", "").Replace("\n", ""));
}
}
else if (field[0] == "U")
{
if (field.Length == 2 && field[1] == "A")
{
msrmntState = MsrmntState.Valid;
log.InfoFormat("{0} - Balance response = \"{1}\"", Name,
received.Replace("\r", "").Replace("\n", ""));
}
else
{
msrmntState = MsrmntState.Failed;
log.WarnFormat("{0} - Balance response = \"{1}\", Unexpected error !!!", Name,
received.Replace("\r", "").Replace("\n", ""));
}
}
else if (field[0] == "SI") /// "SI I" received in case of overload -> empty the tank
{
if (field.Length >= 2 && field[1] == "I")
{
mass = balanceCfg.Capacity;
Masses[balanceNr] = mass;
msrmntState = MsrmntState.Valid;
//msrmntState = MsrmntState.Overload;
log.WarnFormat("{0} - Balance response = \"{1}\", Overload.", Name,
received.Replace("\r", "").Replace("\n", ""));
}
}
}
}
}
///
/// Events: BalanceDone, Error
///
/// Reference to the serialNumber
/// GetBalanceSNOp instance reference casted to IOperaton
public override IOperation GetSerNumOp(ref string serialNumber)
{
return new GetSerNumOp(this, ref serialNumber);
}
///
/// Events: BalanceDone, Error
///
///
/// SetUnitsOp instance reference casted to IOperaton
public IOperation SetUnitsOp(Common.Unit units)
{
return new SetUnitsOp(this, units);
}
}
}