using System; using System.Ext.Xml; using System.IO; using System.Text; using System.Xml; using GHI.Processor; using Microsoft.SPOT; using SWModules; //TODO P2 move all these parameters into appropriate classes namespace HWModules { public static class MissionConfig { static MissionConfig() { //default values PlatformName = "CPF003"; IBFillLowerLimit = 3.0; IBFillUpperLimit = 97.0; SOSetBellowsPosition = 45.0; SOSetBellowsJV = 200000; RMSetBellowsPosition = 5.0; ABRetractSlowJV = 200000; ABRetractFastJV = 200000; ABPressureThreshold = 0.3; DeanchorJV = 150000; DeanchorVelocityLimit = 0.05; DeanchorPressureMinimum = 5.0; DeanchorPressureCountThreshold = 10; AccDeaccLimit = 100000; AnchorPressureCountThreshold = 4; AnchorPressureMinimum = 4.0; AnchorVelocityLimit = 0.025; ExitAnchorPressureThreshold = 5.0; ApproachVelocity = 0.01; CpPressureCutoff = 1; CpRunPumpTime = 2; CPMode = true; SBE41CommandModeSamplePeriod = 3000; //msec SBE41CPSamplePeriod = 1000; //msec EngrLoggerVerbosityLevel = 4; DebuggerVerbosityLevel = 4; SetPreMissionDelayPeriod(30); SetSystemDataSamplePeriod(10); StringPotInverseSlope = 7668560.96 ;// ORIG 1.304025625e-07; StringPotIntercept= 18.706119; MissionParkDepth = 150; MissionParkSamplePeriodMinutes = 2; MissionParkTimeHours = 0; MissionParkTimeMinutes = 5; } /// /// Time to spend in park states, minutes component /// public static int MissionParkTimeMinutes { get { return _missionParkTimeMinutes; } set { if (CheckIntValue(value,ParkMinuteLimits))_missionParkTimeMinutes = value; } } /// /// Time to spend in park states, hours component /// public static int MissionParkTimeHours { get { return _missionParkTimeHours; } set { if (CheckIntValue(value,ParkHourLimits))_missionParkTimeHours = value; } } /// /// Time between instrument sampling during park states in minutes. /// public static int MissionParkSamplePeriodMinutes { get { return _missionParkSamplePeriodMinutes; } set { if (CheckIntValue(value, ParkMinuteLimits)) _missionParkSamplePeriodMinutes = value; } } /// /// Depth (Pressure) to enter park state in decibar. /// public static float MissionParkDepth { get { return _missionParkDepth; } set { if (CheckDoubleValue(value, ParkDepthLimits)) _missionParkDepth = value; } } /// /// String representation for a unique identifier for each CPF, /// used in generation of logged data file names, tags, and logins /// back at the remote data & control portal. /// public static string PlatformName { get; set; } /// /// Calibration inverted slope for the conversion of voltage to % full for internal bellows. /// public static double StringPotInverseSlope { get { return _stringPotInverseSlope;} set { _stringPotInverseSlope = value; _stringPotSlope = 1 / value; } } /// /// Calibration sloe for the conversion of voltage to % full internal bellows. /// This is a get only property, must be set with /// public static double StringPotSlope { get { return _stringPotSlope; } } /// /// Calibration intercept for the conversion of voltage to % full. /// public static double StringPotIntercept { get; set; } /// /// Lower limit of the bellows (in percent full) /// public static double IBFillLowerLimit { get { return _bellowsLowerLimit; } set { if (CheckDoubleValue(value, BellowsLimits)) _bellowsLowerLimit = value; } } /// /// Upper limit of the bellows (in percent full) /// public static double IBFillUpperLimit { get { return _bellowsUpperLimit; } set { if (CheckDoubleValue(value, BellowsLimits)) _bellowsUpperLimit = value; } } /// /// Bellows position in percent full to set when in surface ops mode. /// public static double SOSetBellowsPosition { get { return _soSetBellowsPosition; } set { if (CheckDoubleValue(value, BellowsLimits)) _soSetBellowsPosition = value; } } /// /// Pump speed for adjustments to the bellows position in surface ops mode. /// public static int SOSetBellowsJV { get { return _soSetBellowsJv; } set { if (CheckIntValue(value, JVLimits)) _soSetBellowsJv = value; } } /// /// Bellows position in percent full to set when in recovery mode. /// public static double RMSetBellowsPosition { get { return _rmSetBellowsPosition; } set { if (CheckDoubleValue(value, BellowsLimits)) _rmSetBellowsPosition = value; } } /// /// Pump speed for bellows control during retract fast modes. /// public static int ABRetractFastJV { get { return _abRetractFastJv; } set { if (CheckIntValue(value, JVLimits)) _abRetractFastJv = value; } } /// /// Pump speed for bellows control during retract slow modes. /// public static int ABRetractSlowJV { get { return _abRetractSlowJv; } set { if (CheckIntValue(value, JVLimits)) _abRetractSlowJv = value; } } /// /// Minimum pressure in decibars to transition from ABretract Mode /// to Descend mode. /// public static double ABPressureThreshold { get { return _abPressureThreshold; } set { if (CheckDoubleValue(value,SurfacePressureLimits)) _abPressureThreshold = value; } } /// /// Pump velocity during deanchoring. /// public static int DeanchorJV { get { return _deanchorJv; } set { if (CheckIntValue(value, JVLimits)) _deanchorJv = value; } } //Anchoring// /// /// Sets the detection limit for determining when the system is deanchored. /// This is a pressure velocity (decibars/sec). /// public static double DeanchorVelocityLimit { get { return _deanchorVelocityLimit; } set { if (CheckDoubleValue(value, VelocityLimits)) _deanchorVelocityLimit = value; } } /// /// Minimum pressure in decibars away from anchored pressure to determine /// deanchoring is complete. /// public static double DeanchorPressureMinimum { get { return _deanchorPressureMinimum; } set { if (CheckDoubleValue(value, DeanchorPressureMinimumLimits)) _deanchorPressureMinimum = value; } } /// /// Number of consecutive valid points in the "deanchored" state to /// exit the deanchoring state. /// public static int DeanchorPressureCountThreshold { get { return _deanchorPressureCountThreshold; } set { if (CheckIntValue(value, AnchorCountLimits)) _deanchorPressureCountThreshold = value; } } /// /// Sets the number of consecutive count of pressures below target /// to determine the system has been anchored. /// public static int AnchorPressureCountThreshold { get { return _anchorPressureCountThreshold; } set { if (CheckIntValue(value, AnchorCountLimits)) _anchorPressureCountThreshold = value; } } /// /// The minimum pressure in decibars where anchoring can be tested against. /// public static double AnchorPressureMinimum { get { return _anchorPressureMinimum; } set { if (CheckDoubleValue(value, SurfacePressureLimits)) _anchorPressureMinimum = value; } } /// /// Maximum vertical velocity in decibars per second when /// determining if the system has reached bottom. /// public static double AnchorVelocityLimit { get { return _anchorVelocityLimit; } set { if (CheckDoubleValue(value, VelocityLimits)) _anchorVelocityLimit = value; } } /// /// Counts per second squared motor acceleration/deacceleration limit for Elmo Twitter /// // TODO P1 work into XML file public static int AccDeaccLimit { get { return _accDeaccLimit; } private set { _accDeaccLimit = value; } } /// /// Pressure difference in decibar we are willing to accept between pressure sensor /// updates to make sure we are properly anchored. /// public static double ExitAnchorPressureThreshold { get { return _exitAnchorPressureThreshold; } set { if (CheckDoubleValue(value,ExitAnchorLimits)) _exitAnchorPressureThreshold = value; } } /// /// Target pressure velocity (decibars/sec) when approaching a target depth. /// public static double ApproachVelocity { get { return _approachVelocity; } set { if (CheckDoubleValue(value, VelocityLimits)) _approachVelocity = value; } } /// /// CP mode stops below this pressure in deciBars /// public static double CpPressureCutoff { get { return _cpPressureCutoff; } set { if (CheckDoubleValue(value, CpPressureCutoffLimits))_cpPressureCutoff = value; } } /// /// run the pump for this many seconds before starting CP mode /// public static int CpRunPumpTime { get { return _cpRunPumpTime; } set { if (CheckIntValue(value, CpRunTimeLimits)) _cpRunPumpTime = value; } } /// /// Sample period for the SBE when in Sample mode in milliseconds. /// public static int SBE41CommandModeSamplePeriod { get { return _sbe41CommandModeSamplePeriod; } set { if (CheckIntValue(value,SBE41CommandPeriodLimits)) _sbe41CommandModeSamplePeriod = value; } } /// /// Sample Period for the SBE CTD when in CP mode in milliseconds /// public static int SBE41CPSamplePeriod { get { return _sbe41CpSamplePeriod; } set { if (CheckIntValue(value, SBE41SamplePeriodLimits)) _sbe41CpSamplePeriod = value; } } /// /// Puts SBE41 in CP mode during ascend states only. /// public static bool CPMode { get; set; } //Puts SBE41 in CP mode during ascend state only /// /// Verbosity level when printing messages to the console (0-5) /// public static int EngrLoggerVerbosityLevel { get { return _engrLoggerVerbosityLevel; } set { if (CheckIntValue(value,VerbosityLimits)) _engrLoggerVerbosityLevel = value; } } /// /// Verbosity level when printing messages to the debugger (0-5) /// public static int DebuggerVerbosityLevel { get { return _debuggerVerbosityLevel; } set { if (CheckIntValue(value,VerbosityLimits)) _debuggerVerbosityLevel = value; } } //System// /// /// Period of seconds between acquisition of core health /// data for the vehicle. /// public static TimeSpan SystemDataSamplePeriod { get { return _systemDataSamplePeriod; } } /// /// Sets the period for checking mission critical system sensors. /// /// public static void SetSystemDataSamplePeriod(int secs) { if (!CheckIntValue(secs, SystemSamplePeriodLimits)) return; _systemDataSamplePeriod = new TimeSpan(0,0,secs); } /// /// Sets the value of the PremissionDelayPeriod timespan object. /// /// public static void SetPreMissionDelayPeriod(int secs) { if (!CheckIntValue(secs, PremissionDelayLimits)) return; _preMissionDelayPeriod = new TimeSpan(0,0,secs); } /// /// Timespan of premission, limited to 20 minutes (1200 seconds) /// public static TimeSpan PreMissionDelayPeriod { get { return _preMissionDelayPeriod; } } private static bool CheckDoubleValue(double value, DoubleLimits limits) { return value >= limits.Min && value <= limits.Max; } private static bool CheckIntValue(int value, IntLimits limits) { return value >= limits.Min && value <= limits.Max; } #region CONSTANTS public static readonly TimeSpan smCyclePeriod = new TimeSpan(0, 0, 0, 1, 0); //msec public static readonly int smCyclePeriodMilliseconds = (int) (smCyclePeriod.Ticks / TimeSpan.TicksPerMillisecond); private struct IntLimits { public int Max; public int Min; } private struct DoubleLimits { public double Max; public double Min; } // Limits Definitions // private static readonly DoubleLimits BellowsLimits = new DoubleLimits() {Max = 100.0, Min = 0}; private static readonly IntLimits JVLimits = new IntLimits() {Max = 200000, Min = -200000}; private static readonly IntLimits VerbosityLimits = new IntLimits() {Max = 5, Min = 0}; private static readonly DoubleLimits VelocityLimits = new DoubleLimits() {Min = -1, Max = 1.0}; private static readonly DoubleLimits ExitAnchorLimits = new DoubleLimits() {Min = 1, Max = 10}; private static readonly DoubleLimits SurfacePressureLimits = new DoubleLimits() {Min = 0, Max=10.0 };//decibars private static readonly IntLimits PremissionDelayLimits = new IntLimits() { Min = 0 ,Max = 1200 }; //seconds private static readonly IntLimits SystemSamplePeriodLimits = new IntLimits() {Min = 1, Max = 1200};//seconds private static readonly DoubleLimits CpPressureCutoffLimits = new DoubleLimits() {Min = 1.0, Max = 20.0}; //decibars private static readonly IntLimits CpRunTimeLimits = new IntLimits() {Min = 0, Max = 1200 };//seconds private static readonly IntLimits SBE41SamplePeriodLimits = new IntLimits() {Min = 1000, Max = 3000};//milliseconds private static readonly IntLimits SBE41CommandPeriodLimits = new IntLimits() {Min = 2600, Max = 60000};//milliseconds private static readonly IntLimits AnchorCountLimits = new IntLimits() {Min = 1, Max = 200};//counts private static readonly DoubleLimits DeanchorPressureMinimumLimits = new DoubleLimits() {Min = .1, Max = 10.0}; //decibars private static readonly IntLimits ParkMinuteLimits = new IntLimits() {Max = 1000, Min = 0}; private static readonly IntLimits ParkHourLimits = new IntLimits() {Max = 100, Min = 0}; private static readonly DoubleLimits ParkDepthLimits = new DoubleLimits() {Max = 125, Min = 0}; // backing fields definitions // private static int _engrLoggerVerbosityLevel; private static int _debuggerVerbosityLevel; private static double _deanchorVelocityThreshold; private static double _deanchorVelocityLimit; private static double _anchorVelocityLimit; private static int _accDeaccLimit; private static double _approachVelocity; private static double _exitAnchorPressureThreshold; private static double _anchorPressureMinimum; private static double _abPressureThreshold; private static TimeSpan _preMissionDelayPeriod; private static double _cpPressureCutoff; private static int _cpRunPumpTime; private static int _sbe41CommandModeSamplePeriod; private static int _sbe41CpSamplePeriod; private static int _anchorPressureCountThreshold; private static TimeSpan _systemDataSamplePeriod; private static double _bellowsLowerLimit; private static double _rmSetBellowsPosition; private static double _soSetBellowsPosition; private static double _bellowsUpperLimit; private static int _abRetractFastJv; private static int _abRetractSlowJv; private static int _soSetBellowsJv; private static int _deanchorJv; private static int _stringPotDirection; private static double _deanchorPressureMinimum; private static int _deanchorPressureCountThreshold; private static int _missionParkSamplePeriodMinutes; private static double _stringPotInverseSlope; private static double _stringPotSlope; private static float _missionParkDepth; private static int _missionParkTimeHours; private static int _missionParkTimeMinutes; #endregion #region FILE_IO public static bool LoadConfig(string fname) { var sd = SDStorage.Instance; if (!File.Exists(fname)) { EngrLogger.Comment("Configuration File Does Not Exist, Creating..."); CreateDefaultConfigFile(fname); return true; } using (var stream = new FileStream(fname, FileMode.Open, FileAccess.Read, FileShare.None, 2048)) { //var xmlSettings = new XmlReaderSettings() //{ //IgnoreComments = true, //IgnoreWhitespace = true, //IgnoreProcessingInstructions = false, //}; using (XmlReader reader = XmlReader.Create(stream)) { var count = 0; while (!reader.EOF && stream.CanRead) { try { reader.Read(); count++; if (reader.Name != "item") continue; string key = null; string value = reader.GetAttribute("value"); try { switch (key = reader.GetAttribute("key").ToLower()) { case "name": PlatformName = value; break; case "engrlogverb": EngrLoggerVerbosityLevel = int.Parse(value); break; case "debuglogverb": DebuggerVerbosityLevel = int.Parse(value); break; case "sysdatasampperiod": SetSystemDataSamplePeriod(int.Parse(value)); break; case "premissdelayperiod": SetPreMissionDelayPeriod(int.Parse(value)); break; case "stringpotinverseslope": StringPotInverseSlope = double.Parse(value); break; case "stringpotint": StringPotIntercept = double.Parse(value); break; case "bellowslower": IBFillLowerLimit = double.Parse(value); break; case "bellowsupper": IBFillUpperLimit = double.Parse(value); break; case "sobellowspos": SOSetBellowsPosition = double.Parse(value); break; case "sobellowsjv": SOSetBellowsJV = int.Parse(value); break; case "rmbellowspos": RMSetBellowsPosition = double.Parse(value); break; case "abretfastjv": ABRetractFastJV = int.Parse(value); break; case "abretslowjv": ABRetractSlowJV = int.Parse(value); break; case "abpressthres": ABPressureThreshold = double.Parse(value); break; case "deanchorjv": DeanchorJV = int.Parse(value); break; case "deanchorvellim": DeanchorVelocityLimit = double.Parse(value); break; case "deanchorpressmin": DeanchorPressureMinimum = double.Parse(value); break; case "deanchorcount": DeanchorPressureCountThreshold = int.Parse(value); break; case "anchorcount": AnchorPressureCountThreshold = int.Parse(value); break; case "anchorpressmin": AnchorPressureMinimum = double.Parse(value); break; case "anchorvellim": AnchorVelocityLimit = double.Parse(value); break; case "exitanchorpressthres": ExitAnchorPressureThreshold = double.Parse(value); break; case "approachvel": ApproachVelocity = double.Parse(value); break; case "cppresscutoff": CpPressureCutoff = double.Parse(value); break; case "cprunpumptime": CpRunPumpTime = int.Parse(value); break; case "cpmode": CPMode = int.Parse(value) == 1; break; case "sbecomsampperiod": SBE41CPSamplePeriod = int.Parse(value); break; case "sbecpsampperiod": SBE41CPSamplePeriod = int.Parse(value); break; case "parkdepth": MissionParkDepth = (float) double.Parse(value); break; case "parksampmin": MissionParkSamplePeriodMinutes = int.Parse(value); break; case "parktimehrs": MissionParkTimeHours = int.Parse(value); break; case "parktimemin": MissionParkTimeMinutes = int.Parse(value); break; default: throw new ArgumentException("Unknown item present in xml file: " + key); } } catch (Exception err) { EngrLogger.Comment(err.ToString()); } //finally{ Debug.Print(key);} } catch (Exception e) { EngrLogger.Comment(e.ToString()); // If we can't load a config, let's at least try to create one. EngrLogger.Comment("MissionConfig::LoadConfig: Error Loading config, creating new file."); stream.Close(); CreateDefaultConfigFile(fname); } } EngrLogger.Comment("Configuration load complete for file " + fname + ", " + count + " attributes loaded."); } } return true; } private static void CreateDefaultConfigFile(string fname) { // Check Directory Exists // if (!Directory.Exists(@"\SD\")) { EngrLogger.Comment("Cannot Create Config File, SD card not mounted."); return; } //using (var stream = new MemoryStream()) using (var stream = new FileStream(fname, FileMode.Create, FileAccess.ReadWrite, FileShare.None,2048)) { using (var xmlwrite = XmlWriter.Create(stream)) { xmlwrite.WriteProcessingInstruction("xml","version=\"1.0\" encoding=\"utf-8\""); // xmlwrite.WriteComment("Automatically Generated by CPF Program"); xmlwrite.WriteStartElement("cpf"); AddItemToXml(xmlwrite,"name", PlatformName); AddItemToXml(xmlwrite,"engrlogverb", EngrLoggerVerbosityLevel); AddItemToXml(xmlwrite,"debuglogverb", DebuggerVerbosityLevel); AddItemToXml(xmlwrite,"sysdatasampperiod", (int)(SystemDataSamplePeriod.Ticks/TimeSpan.TicksPerSecond)); AddItemToXml(xmlwrite,"premissdelayperiod", (int)(PreMissionDelayPeriod.Ticks/TimeSpan.TicksPerSecond)); AddItemToXml(xmlwrite,"stringpotinverseslope", StringPotInverseSlope); AddItemToXml(xmlwrite,"stringpotint", StringPotIntercept); AddItemToXml(xmlwrite,"bellowslower", IBFillLowerLimit); AddItemToXml(xmlwrite,"bellowsupper",IBFillUpperLimit); AddItemToXml(xmlwrite,"sobellowspos", SOSetBellowsPosition); AddItemToXml(xmlwrite,"sobellowsjv", SOSetBellowsJV); AddItemToXml(xmlwrite,"rmbellowspos", RMSetBellowsPosition); AddItemToXml(xmlwrite,"abretfastjv", ABRetractFastJV); AddItemToXml(xmlwrite,"abretslowjv",ABRetractSlowJV); AddItemToXml(xmlwrite,"abpressthres", ABPressureThreshold); AddItemToXml(xmlwrite,"deanchorjv",DeanchorJV); AddItemToXml(xmlwrite,"deanchorvellim", DeanchorVelocityLimit); AddItemToXml(xmlwrite,"deanchorpressmin", DeanchorPressureMinimum); AddItemToXml(xmlwrite,"deanchorcount", DeanchorPressureCountThreshold); AddItemToXml(xmlwrite,"anchorcount", AnchorPressureCountThreshold); AddItemToXml(xmlwrite,"anchorpressmin", AnchorPressureMinimum); AddItemToXml(xmlwrite,"anchorvellim", AnchorVelocityLimit); AddItemToXml(xmlwrite,"exitanchorpressthres", ExitAnchorPressureThreshold); AddItemToXml(xmlwrite,"approachvel", ApproachVelocity); AddItemToXml(xmlwrite,"cppresscutoff", CpPressureCutoff); AddItemToXml(xmlwrite,"cprunpumptime", CpRunPumpTime); AddItemToXml(xmlwrite,"cpmode", CPMode?1:0); AddItemToXml(xmlwrite,"sbecomsampperiod", SBE41CommandModeSamplePeriod); AddItemToXml(xmlwrite,"sbecpsampperiod", SBE41CPSamplePeriod); AddItemToXml(xmlwrite,"parkdepth", MissionParkDepth); AddItemToXml(xmlwrite,"parksampmin", MissionParkSamplePeriodMinutes); AddItemToXml(xmlwrite,"parktimehrs", MissionParkTimeHours); AddItemToXml(xmlwrite,"parktimemin", MissionParkTimeMinutes); xmlwrite.WriteEndElement(); xmlwrite.Flush(); } //Ends XmlWriting } //Ends Filestream // Print File using (var stream = new FileStream(fname, FileMode.Open,FileAccess.Read, FileShare.None, 1890)) { var b = new byte[1890]; while (stream.Read(b, 0, b.Length) > 0) { var ss = SafeEncoding.GetChars(b); Debug.Print(new string(ss)); //Clear for next Array.Clear(b,0,b.Length); } } } private static void AddItemToXml(XmlWriter writer, string key, string value) { writer.WriteStartElement("item"); writer.WriteAttributeString("key",key); writer.WriteAttributeString("value", value); writer.WriteEndElement(); writer.Flush(); } private static void AddItemToXml(XmlWriter writer, string key, int value) { AddItemToXml(writer,key,value.ToString()); } private static void AddItemToXml(XmlWriter writer, string key, double value) { AddItemToXml(writer,key,value.ToString("F2")); } #endregion public new static string ToString() { var builder = new StringBuilder(2000); const string crlf = "\r\n"; builder.Append("MISSION CONFIGURATION").Append(crlf); builder.Append("Name:\t").Append(PlatformName).Append(crlf); builder.Append("StringPotInverseSlope:\t").Append(StringPotInverseSlope).Append(crlf); builder.Append("StringPotSlope:\t").Append(StringPotSlope).Append(crlf); builder.Append("StringPotIntercept:\t").Append(StringPotIntercept).Append(crlf); builder.Append("BellowsLowerLimit:\t").Append(IBFillLowerLimit).Append(crlf); builder.Append("BellowsUpperLimit:\t").Append(IBFillUpperLimit).Append(crlf); builder.Append("SOSetBellowsPosition:\t").Append(SOSetBellowsPosition).Append(crlf); builder.Append("SOSetBellowsJV:\t").Append(SOSetBellowsJV).Append(crlf); builder.Append("RMSetBellowsPosition:\t").Append(RMSetBellowsPosition).Append(crlf); builder.Append("ABRetractFastJV:\t").Append(ABRetractFastJV).Append(crlf); builder.Append("ABRetractSlowJV:\t").Append(ABRetractSlowJV).Append(crlf); builder.Append("ABPressureThreshold:\t").Append(ABPressureThreshold).Append(crlf); builder.Append("DeanchorJV:\t").Append(DeanchorJV).Append(crlf); builder.Append("DeanchorVelocityLimit:\t").Append(DeanchorVelocityLimit).Append(crlf); builder.Append("DeanchorPressureMinimum:\t").Append(DeanchorPressureMinimum).Append(crlf); builder.Append("DeanchorPressureCountThreshold:\t").Append(DeanchorPressureCountThreshold).Append(crlf); builder.Append("AnchorPressureCountThreshold:\t").Append(AnchorPressureCountThreshold).Append(crlf); builder.Append("AnchorPressureMinimum:\t").Append(AnchorPressureMinimum).Append(crlf); builder.Append("AnchorVelocityLimit:\t").Append(AnchorVelocityLimit).Append(crlf); builder.Append("ExitAnchorPressureThreshold:\t").Append(ExitAnchorPressureThreshold).Append(crlf); builder.Append("ApproachVelocity:\t").Append(ApproachVelocity).Append(crlf); builder.Append("CpPressureCutoff:\t").Append(CpPressureCutoff).Append(crlf); builder.Append("CpRunPumpTime:\t").Append(CpRunPumpTime).Append(crlf); builder.Append("SBE41CommandModeSamplePeriod:\t").Append(SBE41CommandModeSamplePeriod).Append(crlf); builder.Append("SBE41CPSamplePeriod:\t").Append(SBE41CPSamplePeriod).Append(crlf); builder.Append("CPMode:\t").Append(CPMode).Append(crlf); builder.Append("EngrLoggerVerbosityLevel:\t").Append(EngrLoggerVerbosityLevel).Append(crlf); builder.Append("DebuggerVerbosityLevel:\t").Append(DebuggerVerbosityLevel).Append(crlf); builder.Append("SystemDataSamplePeriod:\t").Append(SystemDataSamplePeriod).Append(crlf); builder.Append("PreMissionDelayPeriod:\t").Append(PreMissionDelayPeriod).Append(crlf); builder.Append("PreMissionDelayPeriod:\t").Append(PreMissionDelayPeriod).Append(crlf); builder.Append("MissionParkDepth:\t").Append(MissionParkDepth).Append(crlf); builder.Append("MissionParkSamplePeriodMinutes:\t").Append(MissionParkSamplePeriodMinutes).Append(crlf); builder.Append("MissionParkTimeHours:\t").Append(MissionParkTimeHours).Append(crlf); builder.Append("MissionParkTimeMinutes:\t").Append(MissionParkTimeMinutes).Append(crlf); return builder.ToString(); } } }