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 { /// /// 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.IBalance2 { /// /// 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("MettlerToledo.BalanceNew({0})", Cfg.ToString(1)); } /// Serial number after GetSerialNumber() when MsrmntState == MsrmntState.Valid public string SerialNumber { get { return serialNumber; } } string serialNumber; public BalanceNewDev(BalanceCfg cfg, IList components) : base(cfg, components) { log.Debug(this.ToString()); } /// /// Get the serial number /// 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"); } /// /// Parse characters received from the serial port /// 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", "").Replace("\n", "")); 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", "").Replace("\n", ""), serialNumber); } else { msrmntState = MsrmntState.Failed; log.WarnFormat("Balance response = {0}, error !!!", received.Replace("\r", "").Replace("\n", "")); } } 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", "").Replace("\n", "")); } else { msrmntState = MsrmntState.Failed; log.WarnFormat("Balance response = \"{0}\", error !!!", received.Replace("\r", "").Replace("\n", "")); } } 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", "").Replace("\n", ""), 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", "").Replace("\n", ""), 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", "").Replace("\n", ""), 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", "").Replace("\n", ""), mass); } else { msrmntState = MsrmntState.Failed; log.WarnFormat("Balance response = \"{0}\", Overload or and unexpected error !!!", received.Replace("\r", "").Replace("\n", "")); } } 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", "").Replace("\n", ""), 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", "").Replace("\n", ""), mass); } else { msrmntState = MsrmntState.Failed; log.WarnFormat("Balance response = \"{0}\", Overload or and unexpected error !!!", received.Replace("\r", "").Replace("\n", "")); } } 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", "").Replace("\n", "")); } else { msrmntState = MsrmntState.Failed; log.WarnFormat("Balance response = \"{0}\", Unexpected error !!!", received.Replace("\r", "").Replace("\n", "")); } } else if (fields[0].Equals("SI")) /// "SI I" 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", "").Replace("\n", "")); } } } } } /// /// Events: BalanceDone, Error /// /// Reference to the serialNumber /// GetBalanceSNOp instance reference casted to IOperaton public IOperation GetBalanceSNOp(ref string serialNumber) { return new GetBalanceSNOp(this, ref serialNumber); } /// /// Events: BalanceDone, Error /// /// /// SetUnitsOp instance reference casted to IOperaton public IOperation SetUnitsOp(Units units) { return new SetUnitsOp(this, units); } } }