/// /// Copyright (c) 2013-2015 Sensus Metering Systems /// using System; using System.Collections.Generic; using System.IO; using log4net; using Config.Entities; using TBF.BenchControl; using TBF.Resources; namespace TBF.BenchControl.ResultsWriters.Basic { public class Writer : ComponentBase, IOperation, GenericDevices.IResultsWriter { private static readonly ILog log = LogManager.GetLogger(typeof(Writer)); public override string ToString() { return string.Format("ResultsWriters.Basic({0})", Cfg.ToString(1)); } readonly WriterCfg writerCfg; readonly string separatorStr; /// /// Result items to print /// IList rsltItems; /// /// Results to print /// Results.Entities.Batch batch; StreamWriter writer; public Writer() {} public Writer(WriterCfg cfg) : base(cfg) { writerCfg = cfg; switch (cfg.Separator) { default: case Separator.None: separatorStr = string.Empty; break; case Separator.Space: separatorStr = " "; break; case Separator.Tabulator: separatorStr = "\t"; break; case Separator.Comma: separatorStr = ","; break; case Separator.Semicolon: separatorStr = ";"; break; } log.Debug(this.ToString()); } /// /// Eliminate spaces conditionally, depesing on bool WriterCfg.EliminateSpaces /// /// Input string /// Output string string ElSpaces(string item) { if (writerCfg.EliminateSpaces) return item.Replace(" ", string.Empty); else return item; } /// /// Returns a file name derived from a DateTime structure. /// Creates directories on this path as a side effect. /// /// Date and time /// File name string GetFilename(DateTime time) { string directory = writerCfg.DestinationPath; /// Ends with "\\"; Directory.CreateDirectory(directory); if (writerCfg.YearFolders) { directory = string.Format("{0}{1}\\", directory, time.Year.ToString()); Directory.CreateDirectory(directory); } if (writerCfg.MonthFolders) { string monthStr /* = now.Month.ToString("D2")*/; switch (time.Month) { default: case 1: monthStr = "January"; break; case 2: monthStr = "February"; break; case 3: monthStr = "March"; break; case 4: monthStr = "April"; break; case 5: monthStr = "May"; break; case 6: monthStr = "June"; break; case 7: monthStr = "July"; break; case 8: monthStr = "August"; break; case 9: monthStr = "September"; break; case 10: monthStr = "October"; break; case 11: monthStr = "November"; break; case 12: monthStr = "December"; break; } directory = string.Format("{0}{1}\\", directory, monthStr); Directory.CreateDirectory(directory); } if (writerCfg.DayFolders) { directory = string.Format("{0}{1}\\", directory, time.Day.ToString("D2")); Directory.CreateDirectory(directory); } return string.Format("{0}{1}{2}{3}-{4}{5}.txt", directory, (time.Year % 100).ToString("D2"), time.Month.ToString("D2"), time.Day.ToString("D2"), time.Hour.ToString("D2"), time.Minute.ToString("D2")); } /// /// Writes the test cycle results into a file, Events: Event.ResultsWritten /// /// Procedure to print the results of /// Results to write into the file /// Reference to the operation public IOperation WriteResultsOp(Results.Entities.Batch batchResults) { this.batch = batchResults; if (batch.WaterMeters.Count > 0 && !batch.WaterMeters[0].Compound()) { rsltItems = Results.ItemSpec.FromStrArray(Program.LocalSettings.RsltItems_Printer_SingleWM); } else { rsltItems = Results.ItemSpec.FromStrArray(Program.LocalSettings.RsltItems_Printer_CombinedWM); } try { writer = new StreamWriter(System.IO.File.Create(GetFilename(batch.EndTime))); } catch { writer = null; } return this; } /// Start this operation public void Start() { if (writer == null) return; ///---------- /// Header ///---------- writer.WriteLine(batch.ProtocolTitle); writer.WriteLine(string.Empty); string[] leftColumn = new string[] { "Batch number: ", "Date and time: ", "Procedure:", Strings.User_, "Ambient temperature: ", "Ambient pressure: ", "Ambient humidity: ", }; string[] rightColumn = new string[] { batch.BatchNr.ToString(), //batch.EndTime.ToShortDateString() + " " + batch.EndTime.ToShortTimeString(), string.Format("{0}.{1}.{2} {3}:{4}", batch.EndTime.Year.ToString("D4"), batch.EndTime.Month.ToString("D2"), batch.EndTime.Day.ToString("D2"), batch.EndTime.Hour.ToString("D2"), batch.EndTime.Minute.ToString("D2")), batch.ProcedureName, batch.UserName, batch.AmbientTempAve().ToString("F1") + " °C", batch.AmbientPressAve().ToString("F0") + " mbar", batch.AmbientHumiAve().ToString("F0") + " %", }; /// Determine max. left column width in characters int maxLen = 0; foreach (var s in leftColumn) if (s.Length > maxLen) maxLen = s.Length; /// Write aligned columns for (int i = 0; i < Math.Min(leftColumn.Length, rightColumn.Length); i++) { writer.Write(leftColumn[i]); writer.Write(new string(' ', maxLen - leftColumn[i].Length + 3)); writer.WriteLine(rightColumn[i]); } writer.WriteLine(string.Empty); ///-------- /// Body ///-------- foreach (var wm in batch.WaterMeters) WriteWM(wm); } /// /// Write one water meter results /// /// Water meter number (0-based) void WriteWM(Results.Entities.WaterMeter wm) { /// Determine column widths int[] columnWidths = new int[rsltItems.Count]; int totalWidth = 0; for (int i = 0; i < rsltItems.Count; i++) { columnWidths[i] = ElSpaces(rsltItems[i].ClmnHeaderText).Length; foreach (var mtr in wm.MeterTestRslts) { string itemText; if (!wm.Compound()) { /// Single water meter itemText = rsltItems[i].Print(mtr); } else if (mtr.CompoundMeterId == (byte)CompoundMeterId.Compound) { Results.Entities.MeterTestRslt mainMtr = wm.GetMeterTestRslt(mtr.Name(), CompoundMeterId.CompoundMain); Results.Entities.MeterTestRslt auxMtr = wm.GetMeterTestRslt(mtr.Name(), CompoundMeterId.CompoundAux); itemText = rsltItems[i].PrintCombined(mainMtr, auxMtr, mtr); } else { continue; } /// Strip color information string[] texts = itemText.Split(new char[] { '|' }); if (texts.Length == 2) { itemText = texts[0]; } int len = ElSpaces(itemText).Length; if (len > columnWidths[i]) columnWidths[i] = len; } totalWidth += columnWidths[i]; } totalWidth += 3 * (rsltItems.Count - 1); if (totalWidth < 0) totalWidth = 0; /// Write water meter number and s/n writer.Write(string.Format("Water meter {0}", wm.WMPosition)); if (!string.IsNullOrEmpty(wm.SerialNr)) writer.Write(string.Format(" s/n: {0}", wm.SerialNr)); writer.WriteLine(string.Empty); writer.WriteLine(new String('-', totalWidth)); /// Horizontal line above the header /// Write column headers for (int i = 0; i < rsltItems.Count; i++) { writer.Write(ElSpaces(rsltItems[i].ClmnHeaderText)); if (i < rsltItems.Count - 1) { if (!writerCfg.EliminateSpaces) { writer.Write(new string(' ', columnWidths[i] - rsltItems[i].ClmnHeaderText.Length + 3)); } writer.Write(separatorStr); } else { writer.WriteLine(string.Empty); } } writer.WriteLine(new String('-', totalWidth)); /// Horizontal line between the header and the body /// Write table data foreach (var mtr in wm.MeterTestRslts) { if (mtr != null) { for (int i = 0; i < rsltItems.Count; i++) { string itemText; /// /// Fetch an item /// if (!wm.Compound()) { /// Single water meter itemText = rsltItems[i].Print(mtr); } else if (mtr.CompoundMeterId == (byte)CompoundMeterId.Compound) { Results.Entities.MeterTestRslt mainMtr = wm.GetMeterTestRslt(mtr.Name(), CompoundMeterId.CompoundMain); Results.Entities.MeterTestRslt auxMtr = wm.GetMeterTestRslt(mtr.Name(), CompoundMeterId.CompoundAux); itemText = rsltItems[i].PrintCombined(mainMtr, auxMtr, mtr); } else { continue; } /// /// Print the item /// string[] texts = itemText.Split(new char[] { '|' }); if (texts.Length == 2) { itemText = texts[0]; } /// Strip color information writer.Write(ElSpaces(itemText)); if (i < rsltItems.Count - 1) { if (!writerCfg.EliminateSpaces) { writer.Write(new string(' ', columnWidths[i] - itemText.Length + 3)); } writer.Write(separatorStr); } else { writer.WriteLine(string.Empty); } } } } writer.WriteLine(new String('-', totalWidth)); /// Horizontal line below the body writer.WriteLine(string.Empty); } /// Run this operation /// Event.ResultsWritten public Event Run() { return Event.ResultsWritten; } /// Stop this operation public void Stop() { if (writer != null) writer.Close(); writer = null; } } }