/// /// 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); } } }