소스 검색

Various small fixes, mostly commenting.

Gregory 3 년 전
부모
커밋
019fe18e1c

+ 6 - 1
crusherScanner/CustomTypes.cs

@@ -38,6 +38,10 @@
         public bool LimsConnection { get; set; }
         public string LimsConnString { get; set; }
         public bool PrepmasterConnection { get; set; }
+        public bool LoggingDebug { get; set; }
+        public bool LoggingInfo { get; set; }
+        public bool LoggingWarning { get; set; }
+        public bool LoggingError { get; set; }
     }
 
     public struct Logs
@@ -51,7 +55,8 @@
     {
         Error = 0,
         Warning = 1,
-        Information = 2
+        Information = 2,
+        Debug = 3
     }
     
 }

+ 3 - 0
crusherScanner/FileAccess.cs

@@ -6,6 +6,9 @@ using System.Threading.Tasks;
 
 namespace crusherScanner
 {
+    /// <summary>
+    /// File access for ML jobs usinf CSV parse.
+    /// </summary>
     internal class FileAccess
     {
 

+ 13 - 10
crusherScanner/Form1.Designer.cs

@@ -1,5 +1,8 @@
 namespace crusherScanner
 {
+    /// <summary>
+    /// Main window of the application.
+    /// </summary>
     partial class Form1
     {
         /// <summary>
@@ -120,7 +123,7 @@
             this.toolStripSeparator5,
             this.purgeToolStripMenuItem1});
             this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem";
-            this.settingsToolStripMenuItem.Size = new System.Drawing.Size(270, 34);
+            this.settingsToolStripMenuItem.Size = new System.Drawing.Size(195, 34);
             this.settingsToolStripMenuItem.Text = "Settings";
             // 
             // editToolStripMenuItem
@@ -164,7 +167,7 @@
             // toolStripSeparator2
             // 
             this.toolStripSeparator2.Name = "toolStripSeparator2";
-            this.toolStripSeparator2.Size = new System.Drawing.Size(267, 6);
+            this.toolStripSeparator2.Size = new System.Drawing.Size(192, 6);
             // 
             // logsToolStripMenuItem
             // 
@@ -173,34 +176,34 @@
             this.openDirectoryToolStripMenuItem,
             this.purgeToolStripMenuItem});
             this.logsToolStripMenuItem.Name = "logsToolStripMenuItem";
-            this.logsToolStripMenuItem.Size = new System.Drawing.Size(270, 34);
+            this.logsToolStripMenuItem.Size = new System.Drawing.Size(195, 34);
             this.logsToolStripMenuItem.Text = "Logs";
             // 
             // openCurrentToolStripMenuItem
             // 
             this.openCurrentToolStripMenuItem.Name = "openCurrentToolStripMenuItem";
-            this.openCurrentToolStripMenuItem.Size = new System.Drawing.Size(270, 34);
+            this.openCurrentToolStripMenuItem.Size = new System.Drawing.Size(233, 34);
             this.openCurrentToolStripMenuItem.Text = "Open current";
             this.openCurrentToolStripMenuItem.Click += new System.EventHandler(this.openCurrentToolStripMenuItem_Click);
             // 
             // openDirectoryToolStripMenuItem
             // 
             this.openDirectoryToolStripMenuItem.Name = "openDirectoryToolStripMenuItem";
-            this.openDirectoryToolStripMenuItem.Size = new System.Drawing.Size(270, 34);
+            this.openDirectoryToolStripMenuItem.Size = new System.Drawing.Size(233, 34);
             this.openDirectoryToolStripMenuItem.Text = "Open directory";
             this.openDirectoryToolStripMenuItem.Click += new System.EventHandler(this.openDirectoryToolStripMenuItem_Click);
             // 
             // purgeToolStripMenuItem
             // 
             this.purgeToolStripMenuItem.Name = "purgeToolStripMenuItem";
-            this.purgeToolStripMenuItem.Size = new System.Drawing.Size(270, 34);
+            this.purgeToolStripMenuItem.Size = new System.Drawing.Size(233, 34);
             this.purgeToolStripMenuItem.Text = "Purge";
             this.purgeToolStripMenuItem.Click += new System.EventHandler(this.purgeToolStripMenuItem_Click);
             // 
             // toolStripSeparator3
             // 
             this.toolStripSeparator3.Name = "toolStripSeparator3";
-            this.toolStripSeparator3.Size = new System.Drawing.Size(267, 6);
+            this.toolStripSeparator3.Size = new System.Drawing.Size(192, 6);
             // 
             // reinitializeToolStripMenuItem
             // 
@@ -208,7 +211,7 @@
             this.reinitializeSettingsToolStripMenuItem,
             this.testSettingsToolStripMenuItem});
             this.reinitializeToolStripMenuItem.Name = "reinitializeToolStripMenuItem";
-            this.reinitializeToolStripMenuItem.Size = new System.Drawing.Size(270, 34);
+            this.reinitializeToolStripMenuItem.Size = new System.Drawing.Size(195, 34);
             this.reinitializeToolStripMenuItem.Text = "Reinitialize";
             // 
             // reinitializeSettingsToolStripMenuItem
@@ -227,12 +230,12 @@
             // toolStripSeparator4
             // 
             this.toolStripSeparator4.Name = "toolStripSeparator4";
-            this.toolStripSeparator4.Size = new System.Drawing.Size(267, 6);
+            this.toolStripSeparator4.Size = new System.Drawing.Size(192, 6);
             // 
             // ExitToolStripMenuItem
             // 
             this.ExitToolStripMenuItem.Name = "ExitToolStripMenuItem";
-            this.ExitToolStripMenuItem.Size = new System.Drawing.Size(270, 34);
+            this.ExitToolStripMenuItem.Size = new System.Drawing.Size(195, 34);
             this.ExitToolStripMenuItem.Text = "Exit";
             this.ExitToolStripMenuItem.Click += new System.EventHandler(this.ExitToolStripMenuItem_Click);
             // 

+ 8 - 4
crusherScanner/Form1.cs

@@ -5,6 +5,9 @@ namespace crusherScanner
         private static ProgramFunctions? dataCore;
         private static int counter = 0;
 
+        /// <summary>
+        /// Form 1 Initializer.
+        /// </summary>
         public Form1()
         {
             InitializeComponent();
@@ -12,7 +15,7 @@ namespace crusherScanner
 
         private void Form1_Load(object sender, EventArgs e)
         {
-            Logging.Append("Crusher Scanner Appliction " + Application.ProductVersion + " is starting.");
+            Logging.Append(LogLevel.Information,"Crusher Scanner Appliction " + Application.ProductVersion + " is starting.");
             TextBox1.Enabled = false;
             toolStripStatusLabel5.Text = "";
             toolStripStatusLabel2.Text = "0";
@@ -25,11 +28,10 @@ namespace crusherScanner
             label2.Hide();
             label1.Hide();
             WindowState = FormWindowState.Maximized;
-            //TopMost = true;
             dataCore = new ProgramFunctions();
             TextBox1.Enabled = true;
             TextBox1.Focus();
-            Logging.Append("Crusher Scanner Appliction " + Application.ProductVersion + " has started.");
+            Logging.Append(LogLevel.Information,"Crusher Scanner Appliction " + Application.ProductVersion + " has started.");
         }
 
         private void TextBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
@@ -37,7 +39,7 @@ namespace crusherScanner
             Scan scanned = new();
             scanned.BufferCount = -1;
             counter = 2;
-            scanned.barcode = TextBox1.Text.Trim();
+            scanned.barcode = TextBox1.Text.Trim().ToUpper();
             if (e.KeyValue == 13 && dataCore != null)
             {
                 scanned = ProgramFunctions.StartChecks(scanned);
@@ -197,6 +199,7 @@ namespace crusherScanner
         {
             if (e.Argument!=null)
             {
+                TextBox1.Enabled = false;
                 WorkingDirControl.UpdateWorkingDir(e);
             }
         }
@@ -211,6 +214,7 @@ namespace crusherScanner
                 toolStripProgressBar1.Value = scan.JobCount;
                 toolStripStatusLabel5.Text = (scan.JobTotal - (int)scan.JobCount).ToString();
             }
+            TextBox1.Enabled = true;
         }
 
         private void openDirectoryToolStripMenuItem_Click(object sender, EventArgs e)

+ 5 - 5
crusherScanner/Form1.resx

@@ -61,19 +61,19 @@
     <value>17, 17</value>
   </metadata>
   <metadata name="saveFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>363, 17</value>
+    <value>174, 20</value>
   </metadata>
   <metadata name="openFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>551, 17</value>
+    <value>374, 20</value>
   </metadata>
   <metadata name="Timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>745, 17</value>
+    <value>561, 26</value>
   </metadata>
   <metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>859, 17</value>
+    <value>697, 21</value>
   </metadata>
   <metadata name="backgroundWorker1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>1017, 17</value>
+    <value>846, 17</value>
   </metadata>
   <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
   <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">

+ 97 - 13
crusherScanner/LimsAccess.cs

@@ -6,27 +6,111 @@ using System.Threading.Tasks;
 
 namespace crusherScanner
 {
+    // TODO: Caution memory leak be here. Consider flushing buffer SIDs after a period of time.
     internal class LimsAccess
     {
+        /// <summary>
+        /// Buffer of sample ID's from LIMS or sample list file.
+        /// </summary>
+        private static HashSet<string> SIDs = new();
+
         /// <summary>
         ///  Check if barcode is found in LIMS samples.
         /// </summary>
         /// <param name="barcode">Barcode as string to check LIMS for.</param>
         public static Scan IsInLims(Scan barcode)
         {
-            //TODO: Actully check LIMS for sample ID.
-            barcode.isInLims = true;
-            return barcode;
-            //https://www.guru99.com/c-sharp-access-database.html#:~:text=Code%20Explanation%3A-%201%20The%20first%20step%20is%20to,connection%20to%20the%20database.%20...%20More%20items...%20
-            //string connetionString;
-            //SqlConnection cnn;
-            //connetionString = @"Data Source=WIN-50GP30FGO75;Initial Catalog=Demodb;User ID=sa;Password=demol23";
-            //cnn = new SqlConnection(connetionString);
-            //cnn.Open();
-            //MessageBox.Show("Connection Open  !");
-            //cnn.Close();
-            //or
-            //https://dax.tips/2020/08/24/using-visual-studio-code-to-query-power-bi/
+
+            // Is sample ID in buffer
+            if(CheckBuffer(barcode))
+            {
+                barcode.isInLims = true;
+                return barcode;
+            }
+
+            // LIMS connection enabled, ask LIMS for sample ID.
+            if (Properties.Settings.Default.LimsConnection)
+            {
+
+                //TODO: Actully check LIMS for sample ID. And fill buffer.
+                barcode.isInLims = true;
+                return barcode;
+                //https://www.guru99.com/c-sharp-access-database.html#:~:text=Code%20Explanation%3A-%201%20The%20first%20step%20is%20to,connection%20to%20the%20database.%20...%20More%20items...%20
+                //string connetionString;
+                //SqlConnection cnn;
+                //connetionString = @"Data Source=WIN-50GP30FGO75;Initial Catalog=Demodb;User ID=sa;Password=demol23";
+                //cnn = new SqlConnection(connetionString);
+                //cnn.Open();
+                //MessageBox.Show("Connection Open  !");
+                //cnn.Close();
+                //or
+                //https://dax.tips/2020/08/24/using-visual-studio-code-to-query-power-bi/
+            }
+            else // LIMS connection disabled. Check for a fall back file or return true.
+            {
+                if (CheckFileStore("sampleList.csv") && CheckFileStore(Properties.Settings.Default.OreDefWorkFile + "\\sampleList.csv") && CheckBuffer(barcode))
+                {
+                    barcode.isInLims = true;
+                    return barcode;
+                }
+                else 
+                {
+                    barcode.isInLims = false;
+                    return barcode;
+                }
+            }
         }
+
+        /// <summary>
+        /// Check if the sample list file is available and load into the buffer.
+        /// </summary>
+        /// <returns></returns>
+        private static bool CheckFileStore(string LimsList)
+        {
+            // No file list found, assume no checking and return true.
+            if(!File.Exists(LimsList))
+            {
+                return true;
+            }
+
+            // File list found, load into buffer and check if barcode exists.
+            using FileStream sampleList = new(LimsList, FileMode.Open, System.IO.FileAccess.Read, FileShare.None);
+            {
+                using StreamReader Reader = new(sampleList);
+                {
+                    while (true)
+                    {
+                        var line = Reader.ReadLine();
+                        if (line != null && line != "")
+                        {
+                            SIDs.Add(line.Trim());
+                        }
+                        else
+                        {
+                            break;
+                        }
+                    }
+                }
+            }
+            return false;
+        }
+
+        /// <summary>
+        /// Check to see if the sample ID is in the buffer.
+        /// </summary>
+        /// <param name="barcode">barcode (sample ID)</param>
+        /// <returns></returns>
+        private static bool CheckBuffer(Scan barcode)
+        {
+
+            if(SIDs.Contains(barcode.barcode))
+            {
+                return true;
+            }
+
+            return false;
+
+        }
+
     }
 }

+ 36 - 3
crusherScanner/Logging.cs

@@ -14,10 +14,17 @@ namespace crusherScanner
         /// <summary>
         /// Create/Append the current log file.
         /// </summary>
+        /// <param name="level">Logging level.</param>
         /// <param name="message">Message to be written into the log file.</param>
         /// <returns></returns>
-        public static bool Append(string message)
+        public static bool Append(LogLevel level,string message)
         {
+            // Invert logic, exit if loglevel not enabled.
+            if(!LoggingLevel(level))
+            {
+                return true;
+            }
+            
             var dt = DateTime.Now;
             if (!Directory.Exists(LocalLogDir))
             {
@@ -53,7 +60,7 @@ namespace crusherScanner
             try
             {
 
-                File.AppendAllText(LocalLogDir + "\\" + logFile, dt.ToString("yyyyMMddTHHmmss") + "---" + message + "\n");
+                File.AppendAllText(LocalLogDir + "\\" + logFile, dt.ToString("yyyyMMddTHHmmss") + "-" + level.ToString() + "-" + message + "\n");
             }
             catch (Exception ex)
             {
@@ -110,5 +117,31 @@ namespace crusherScanner
             }.Start();
         }
 
+        /// <summary>
+        /// Is the logging for this message true;
+        /// </summary>
+        /// <param name="level">Loglevel for this message.</param>
+        /// <returns></returns>
+        private static bool LoggingLevel(LogLevel level)
+        {
+            if (Properties.Settings.Default.LoggingError && (level == LogLevel.Error))
+            {
+                return true;
+            }
+            if (Properties.Settings.Default.LoggingWarning && (level == LogLevel.Warning))
+            {
+                return true;
+            }
+            if (Properties.Settings.Default.LoggingInfo && (level == LogLevel.Information))
+            {
+                return true;
+            }
+            if (Properties.Settings.Default.LoggingDebug && (level == LogLevel.Debug))
+            {
+                return true;
+            }
+            return false;
+        }
+
+    }
     }
-}

+ 2 - 2
crusherScanner/OreDefData.cs

@@ -25,9 +25,9 @@ namespace crusherScanner
                 OreDefTypesArray = OreDefTypes.Split(',');
                 for (int i = 0; i < OreDefTypesArray.Length; i++)
                 {
-                    if (scanned.barcode.Contains(OreDefTypesArray[i]))
+                    if (scanned.barcode.Contains(OreDefTypesArray[i].Trim()))
                     {
-                        scanned.sampleType = OreDefTypesArray[i];
+                        scanned.sampleType = OreDefTypesArray[i].Trim();
                         return scanned;
                     }
                 }

+ 84 - 17
crusherScanner/ProgramFunctions.cs

@@ -8,6 +8,9 @@ using System.Threading.Tasks;
 
 namespace crusherScanner
 {
+    /// <summary>
+    /// Main entry point for sample checking functions.
+    /// </summary>
     public class ProgramFunctions
     {
         private static string lastBarcodeScanned = "";
@@ -15,13 +18,12 @@ namespace crusherScanner
 
         #region Contructor
 
+        /// <summary>
+        /// Constructor to load initial settings.
+        /// </summary>
         public ProgramFunctions()
         {
-            Settings tmp = new();
-            //TODO: remove debug values.
-            tmp.CrusherNo = 1;
-            tmp.OreDefInFile = "te";
-            SettingsHandler.CheckSettings(tmp);
+            
             // no initial configuration present
             if (Properties.Settings.Default.OreDefInFile == "")
             {
@@ -29,7 +31,7 @@ namespace crusherScanner
                 {
                     MessageBox.Show("No configuration stored,\nloading configuration from 'config.json'","Settings",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
                     JsonHandler conf = new("config.json", true);
-                    //ImportConfigFile("config.json");
+                    ImportConfigFile("config.json");
                 }
                 else
                 {
@@ -47,6 +49,17 @@ namespace crusherScanner
 
         #region Main logic
 
+        /// <summary>
+        /// Check scanned sample ID in following order;
+        ///  - LIMS existence (active samples in the last 90 days). warn operator if not.
+        ///  - Is this an Ore def sample (RCA, RCB, RCC).
+        ///  - If not Ore def pass sample to crusher.
+        ///  - If Ore def without contamination send to crusher.
+        ///  - If sample has contamination not the ID and only send to crusher if scanned twice.
+        ///  - If sample could not be found in the Ore def lists. warn operator.
+        /// </summary>
+        /// <param name="scanned">Scaned sample details.</param>
+        /// <returns></returns>
         public static Scan StartChecks(Scan scanned)
         {
             scanned.messageState = true;
@@ -106,28 +119,73 @@ namespace crusherScanner
 
         #region Settings functions
 
+        /// <summary>
+        /// Import app configuration from a JSON file.
+        /// </summary>
+        /// <param name="configFile">Path to file. (defaults to "config.json" in app directory)</param>
         public static void ImportConfigFile(string configFile = "config.json")
         {
+            Settings tmpSettings = new();
+
+            // Open JSON file to read
             string data = File.ReadAllText(configFile);
             using JsonDocument doc = JsonDocument.Parse(data);
             JsonElement root = doc.RootElement;
-
             var config = root;
 
-            Properties.Settings.Default.CrusherNo = (int)config.GetProperty("CrusherNo").GetInt32();
-            Properties.Settings.Default.PrepmasterMagazineSerial = config.GetProperty("Serial").ToString();
-            Properties.Settings.Default.OreDefInFile = config.GetProperty("OreDefInFile").ToString();
-            Properties.Settings.Default.OreDefWorkFile = config.GetProperty("OreDefWorkFile").ToString();
-            Properties.Settings.Default.OreDefOutFile = config.GetProperty("OreDefOutFile").ToString();
-            Properties.Settings.Default.OutputFormat = config.GetProperty("OutputFormat").ToString();
-            Properties.Settings.Default.Save();
+            // Set config data from JSON into temp settings var for handling.
+            tmpSettings.CrusherNo = (int)config.GetProperty("CrusherNo").GetInt32();
+            tmpSettings.PrepmasterMagazineSerial = config.GetProperty("Serial").ToString();
+            tmpSettings.OreDefInFile = config.GetProperty("OreDefInFile").ToString();
+            tmpSettings.OreDefWorkFile = config.GetProperty("OreDefWorkFile").ToString();
+            tmpSettings.OreDefOutFile = config.GetProperty("OreDefOutFile").ToString();
+            tmpSettings.OutputFormat = config.GetProperty("OutputFormat").ToString();
+            tmpSettings.OreDefTypes = config.GetProperty("OreDefTypes").ToString();
+            tmpSettings.LimsConnection = config.GetProperty("LimsConnection").GetBoolean();
+            tmpSettings.LimsConnString = config.GetProperty("LimsConnString").ToString();
+            tmpSettings.PrepmasterConnection = config.GetProperty("PrepmasterConnection").GetBoolean();
+            tmpSettings.LoggingDebug = config.GetProperty("LoggingDebug").GetBoolean();
+            tmpSettings.LoggingInfo = config.GetProperty("LoggingInfo").GetBoolean();
+            tmpSettings.LoggingWarning = config.GetProperty("LoggingWarning").GetBoolean();
+            tmpSettings.LoggingError = config.GetProperty("LoggingError").GetBoolean();
+
+            // Check settings, if good save to applications cache.
+            if(SettingsHandler.CheckSettings(tmpSettings))
+            {
+                SaveSettings(tmpSettings);
+            }
+
         }
 
         /// <summary>
-        ///  Export a Json configuration file.
+        /// Save settings from temp var to app cache.
         /// </summary>
-        /// <param name="configFile">File path and file name to save the config file to.</param>
-        public static void ExportConfigFile(string configFile = "config.json")
+        /// <param name="configuration">Pre checked settings to save.</param>
+        public static void SaveSettings(Settings configuration)
+        {
+            Properties.Settings.Default.CrusherNo = configuration.CrusherNo;
+            Properties.Settings.Default.PrepmasterMagazineSerial = configuration.PrepmasterMagazineSerial;
+            Properties.Settings.Default.OreDefInFile = configuration.OreDefInFile;
+            Properties.Settings.Default.OreDefWorkFile = configuration.OreDefWorkFile;
+            Properties.Settings.Default.OreDefOutFile = configuration.OreDefOutFile;
+            Properties.Settings.Default.OutputFormat = configuration.OutputFormat;
+            Properties.Settings.Default.OreDefTypes = configuration.OreDefTypes;
+            Properties.Settings.Default.LimsConnection = configuration.LimsConnection;
+            Properties.Settings.Default.LimsConnString = configuration.LimsConnString;
+            Properties.Settings.Default.PrepmasterConnection = configuration.PrepmasterConnection;
+            Properties.Settings.Default.LoggingDebug = configuration.LoggingDebug;
+            Properties.Settings.Default.LoggingInfo = configuration.LoggingInfo;
+            Properties.Settings.Default.LoggingWarning = configuration.LoggingWarning;
+            Properties.Settings.Default.LoggingError = configuration.LoggingError;
+
+            Properties.Settings.Default.Save();
+        }
+
+            /// <summary>
+            ///  Export a Json configuration file.
+            /// </summary>
+            /// <param name="configFile">File path and file name to save the config file to.</param>
+            public static void ExportConfigFile(string configFile = "config.json")
         {
             using var ms = new MemoryStream();
             using var writer = new Utf8JsonWriter(ms);
@@ -139,6 +197,15 @@ namespace crusherScanner
             writer.WriteString("OreDefWorkFile", Properties.Settings.Default.OreDefWorkFile);
             writer.WriteString("OreDefOutFile", Properties.Settings.Default.OreDefOutFile);
             writer.WriteString("OutputFormat", Properties.Settings.Default.OutputFormat);
+            writer.WriteString("OreDefTypes", Properties.Settings.Default.OreDefTypes);
+            writer.WriteBoolean("LimsConnection", Properties.Settings.Default.LimsConnection);
+            writer.WriteString("LimsConnString", Properties.Settings.Default.LimsConnString);
+            writer.WriteBoolean("PrepmasterConnection", Properties.Settings.Default.PrepmasterConnection);
+            writer.WriteBoolean("LoggingDebug", Properties.Settings.Default.LoggingDebug);
+            writer.WriteBoolean("LoggingInfo", Properties.Settings.Default.LoggingInfo);
+            writer.WriteBoolean("LoggingWarning", Properties.Settings.Default.LoggingWarning);
+            writer.WriteBoolean("LoggingError", Properties.Settings.Default.LoggingError);
+
             writer.WriteEndObject();
             writer.Flush();
             string json = Encoding.UTF8.GetString(ms.ToArray());

+ 63 - 0
crusherScanner/Properties/Resources.Designer.cs

@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace crusherScanner.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("crusherScanner.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 101 - 0
crusherScanner/Properties/Resources.resx

@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+	<!-- 
+		Microsoft ResX Schema
+
+		Version 1.3
+
+		The primary goals of this format is to allow a simple XML format 
+		that is mostly human readable. The generation and parsing of the 
+		various data types are done through the TypeConverter classes 
+		associated with the data types.
+
+		Example:
+
+		... ado.net/XML headers & schema ...
+		<resheader name="resmimetype">text/microsoft-resx</resheader>
+		<resheader name="version">1.3</resheader>
+		<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+		<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+		<data name="Name1">this is my long string</data>
+		<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+		<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+			[base64 mime encoded serialized .NET Framework object]
+		</data>
+		<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+			[base64 mime encoded string representing a byte array form of the .NET Framework object]
+		</data>
+
+		There are any number of "resheader" rows that contain simple 
+		name/value pairs.
+
+		Each data row contains a name, and value. The row also contains a 
+		type or mimetype. Type corresponds to a .NET class that support 
+		text/value conversion through the TypeConverter architecture. 
+		Classes that don't support this are serialized and stored with the 
+		mimetype set.
+
+		The mimetype is used for serialized objects, and tells the 
+		ResXResourceReader how to depersist the object. This is currently not 
+		extensible. For a given mimetype the value must be set accordingly:
+
+		Note - application/x-microsoft.net.object.binary.base64 is the format 
+		that the ResXResourceWriter will generate, however the reader can 
+		read any of the formats listed below.
+
+		mimetype: application/x-microsoft.net.object.binary.base64
+		value   : The object must be serialized with 
+			: System.Serialization.Formatters.Binary.BinaryFormatter
+			: and then encoded with base64 encoding.
+
+		mimetype: application/x-microsoft.net.object.soap.base64
+		value   : The object must be serialized with 
+			: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+			: and then encoded with base64 encoding.
+
+		mimetype: application/x-microsoft.net.object.bytearray.base64
+		value   : The object must be serialized into a byte array 
+			: using a System.ComponentModel.TypeConverter
+			: and then encoded with base64 encoding.
+	-->
+	
+	<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+		<xsd:element name="root" msdata:IsDataSet="true">
+			<xsd:complexType>
+				<xsd:choice maxOccurs="unbounded">
+					<xsd:element name="data">
+						<xsd:complexType>
+							<xsd:sequence>
+								<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+								<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+							</xsd:sequence>
+							<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+							<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+							<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+						</xsd:complexType>
+					</xsd:element>
+					<xsd:element name="resheader">
+						<xsd:complexType>
+							<xsd:sequence>
+								<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+							</xsd:sequence>
+							<xsd:attribute name="name" type="xsd:string" use="required" />
+						</xsd:complexType>
+					</xsd:element>
+				</xsd:choice>
+			</xsd:complexType>
+		</xsd:element>
+	</xsd:schema>
+	<resheader name="resmimetype">
+		<value>text/microsoft-resx</value>
+	</resheader>
+	<resheader name="version">
+		<value>1.3</value>
+	</resheader>
+	<resheader name="reader">
+		<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+	</resheader>
+	<resheader name="writer">
+		<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+	</resheader>
+</root>

+ 49 - 1
crusherScanner/Properties/Settings.Designer.cs

@@ -25,7 +25,7 @@ namespace crusherScanner.Properties {
         
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("COM1,9600,Parity.None,8,StopBits.One")]
+        [global::System.Configuration.DefaultSettingValueAttribute("COM1,9600,None,8,One")]
         public string PrepmasterMagazineSerial {
             get {
                 return ((string)(this["PrepmasterMagazineSerial"]));
@@ -142,5 +142,53 @@ namespace crusherScanner.Properties {
                 this["PrepmasterConnection"] = value;
             }
         }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("False")]
+        public bool LoggingDebug {
+            get {
+                return ((bool)(this["LoggingDebug"]));
+            }
+            set {
+                this["LoggingDebug"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("True")]
+        public bool LoggingInfo {
+            get {
+                return ((bool)(this["LoggingInfo"]));
+            }
+            set {
+                this["LoggingInfo"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("True")]
+        public bool LoggingWarning {
+            get {
+                return ((bool)(this["LoggingWarning"]));
+            }
+            set {
+                this["LoggingWarning"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("True")]
+        public bool LoggingError {
+            get {
+                return ((bool)(this["LoggingError"]));
+            }
+            set {
+                this["LoggingError"] = value;
+            }
+        }
     }
 }

+ 13 - 1
crusherScanner/Properties/Settings.settings

@@ -3,7 +3,7 @@
   <Profiles />
   <Settings>
     <Setting Name="PrepmasterMagazineSerial" Type="System.String" Scope="User">
-      <Value Profile="(Default)">COM1,9600,Parity.None,8,StopBits.One</Value>
+      <Value Profile="(Default)">COM1,9600,None,8,One</Value>
     </Setting>
     <Setting Name="OreDefInFile" Type="System.String" Scope="User">
       <Value Profile="(Default)" />
@@ -32,5 +32,17 @@
     <Setting Name="PrepmasterConnection" Type="System.Boolean" Scope="User">
       <Value Profile="(Default)">False</Value>
     </Setting>
+    <Setting Name="LoggingDebug" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">False</Value>
+    </Setting>
+    <Setting Name="LoggingInfo" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
+    <Setting Name="LoggingWarning" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
+    <Setting Name="LoggingError" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
   </Settings>
 </SettingsFile>

+ 48 - 12
crusherScanner/SerialAccess.cs

@@ -24,11 +24,12 @@ namespace crusherScanner
             }
             else if (barcode != "")
             {
-                if (!SerialReady)
-                {
+                //if (!SerialReady)
+                //{
                     SetupSerial();
-                }
-                SendSerial(barcode);
+                //}
+                Logging.Append(LogLevel.Information, "Sending " + barcode + " to crusher input.");
+               SendSerial(barcode);
             }
         }
 
@@ -38,8 +39,7 @@ namespace crusherScanner
         private static void SetupSerial()
         {
             //TODO: use settings for connection
-            _serialPort = new SerialPort("COM1", 19200, Parity.None, 8, StopBits.One);
-            _serialPort.Handshake = Handshake.None;
+            _serialPort = SetSerialSettings();
 
             try
             {
@@ -48,7 +48,7 @@ namespace crusherScanner
             }
             catch (Exception ex)
             {
-                Logging.Append("Error opening serial port :: " + ex.Message);
+                Logging.Append(LogLevel.Error, "Opening serial port :: " + ex.Message);
                 MessageBox.Show("Error opening serial port :: " + ex.Message, "Error!");
             }
             finally
@@ -59,15 +59,50 @@ namespace crusherScanner
         }
 
         /// <summary>
-        /// Send data to the serial connection.
+        /// Set the initial values for the serial port from the saved settings.
         /// </summary>
-        /// <param name="data">The sample ID to send to Prepmaster.</param>
-        private static void SendSerial(string data)
+        /// <returns>Configured SerialPort.</returns>
+        private static SerialPort SetSerialSettings()
+        {
+            
+            string[] serialSettings = Properties.Settings.Default.PrepmasterMagazineSerial.Split(',');
+            Logging.Append(LogLevel.Information, "Opening serial port : using " + String.Join(',', serialSettings));
+
+            switch (serialSettings.Count())
+            {
+                case 1:
+                    _serialPort = new SerialPort(serialSettings[0].Trim());
+                    break;
+                case 2:
+                    _serialPort = new SerialPort(serialSettings[0].Trim(), int.Parse(serialSettings[1].Trim()));
+                    break;
+                case 3:
+                    _serialPort = new SerialPort(serialSettings[0].Trim(), int.Parse(serialSettings[1].Trim()), (Parity)Enum.Parse(typeof(Parity), serialSettings[2].Trim()));
+                    break;
+                case 4:
+                    _serialPort = new SerialPort(serialSettings[0].Trim(), int.Parse(serialSettings[1].Trim()), (Parity)Enum.Parse(typeof(Parity), serialSettings[2].Trim()), int.Parse(serialSettings[3].Trim()));
+                    break;
+                case 5:
+                    _serialPort = new SerialPort(serialSettings[0].Trim(), int.Parse(serialSettings[1].Trim()), (Parity)Enum.Parse(typeof(Parity), serialSettings[2].Trim()), int.Parse(serialSettings[3].Trim()), (StopBits)Enum.Parse(typeof(StopBits), serialSettings[4].Trim()));
+                    break;
+                default:
+                    _serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
+                    break;
+            }
+            _serialPort.Handshake = Handshake.None;
+            return _serialPort;
+        }
+
+            /// <summary>
+            /// Send data to the serial connection.
+            /// </summary>
+            /// <param name="data">The sample ID to send to Prepmaster.</param>
+            private static void SendSerial(string data)
         {
 
             if (_serialPort == null)
             {
-                Logging.Append("Error opening serial port :: _serialPort is null");
+                Logging.Append(LogLevel.Error, "Opening serial port :: _serialPort is null");
                 MessageBox.Show("Error opening serial port :: Serial device may have been unpluged.", "Error!");
                 SerialReady = false;
                 return;
@@ -81,10 +116,11 @@ namespace crusherScanner
                     _serialPort.Open();
                     _serialPort.Write(data + "\r\n");
                 }
+                _serialPort.Close();
             }
             catch (Exception ex)
             {
-                Logging.Append("Error opening serial port :: " + ex.Message);
+                Logging.Append(LogLevel.Error, "Opening serial port :: " + ex.Message);
                 MessageBox.Show("Error opening/writing to serial port :: " + ex.Message, "Error!");
             }
         }

+ 221 - 34
crusherScanner/SettingsDialog.Designer.cs

@@ -47,13 +47,31 @@
             this.button4 = new System.Windows.Forms.Button();
             this.button5 = new System.Windows.Forms.Button();
             this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
+            this.groupBox1 = new System.Windows.Forms.GroupBox();
+            this.groupBox2 = new System.Windows.Forms.GroupBox();
+            this.checkBox1 = new System.Windows.Forms.CheckBox();
+            this.groupBox3 = new System.Windows.Forms.GroupBox();
+            this.checkBox2 = new System.Windows.Forms.CheckBox();
+            this.checkBox3 = new System.Windows.Forms.CheckBox();
+            this.checkBox4 = new System.Windows.Forms.CheckBox();
+            this.checkBox5 = new System.Windows.Forms.CheckBox();
+            this.label7 = new System.Windows.Forms.Label();
+            this.textBox5 = new System.Windows.Forms.TextBox();
+            this.groupBox4 = new System.Windows.Forms.GroupBox();
+            this.checkBox6 = new System.Windows.Forms.CheckBox();
+            this.label8 = new System.Windows.Forms.Label();
+            this.textBox6 = new System.Windows.Forms.TextBox();
             ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
+            this.groupBox1.SuspendLayout();
+            this.groupBox2.SuspendLayout();
+            this.groupBox3.SuspendLayout();
+            this.groupBox4.SuspendLayout();
             this.SuspendLayout();
             // 
             // label1
             // 
             this.label1.AutoSize = true;
-            this.label1.Location = new System.Drawing.Point(40, 50);
+            this.label1.Location = new System.Drawing.Point(6, 40);
             this.label1.Name = "label1";
             this.label1.Size = new System.Drawing.Size(142, 25);
             this.label1.TabIndex = 0;
@@ -62,7 +80,7 @@
             // label2
             // 
             this.label2.AutoSize = true;
-            this.label2.Location = new System.Drawing.Point(40, 100);
+            this.label2.Location = new System.Drawing.Point(6, 139);
             this.label2.Name = "label2";
             this.label2.Size = new System.Drawing.Size(116, 25);
             this.label2.TabIndex = 1;
@@ -71,7 +89,7 @@
             // label3
             // 
             this.label3.AutoSize = true;
-            this.label3.Location = new System.Drawing.Point(40, 150);
+            this.label3.Location = new System.Drawing.Point(4, 41);
             this.label3.Name = "label3";
             this.label3.Size = new System.Drawing.Size(176, 25);
             this.label3.TabIndex = 2;
@@ -80,7 +98,7 @@
             // label4
             // 
             this.label4.AutoSize = true;
-            this.label4.Location = new System.Drawing.Point(40, 200);
+            this.label4.Location = new System.Drawing.Point(4, 91);
             this.label4.Name = "label4";
             this.label4.Size = new System.Drawing.Size(201, 25);
             this.label4.TabIndex = 3;
@@ -89,7 +107,7 @@
             // label5
             // 
             this.label5.AutoSize = true;
-            this.label5.Location = new System.Drawing.Point(40, 250);
+            this.label5.Location = new System.Drawing.Point(4, 141);
             this.label5.Name = "label5";
             this.label5.Size = new System.Drawing.Size(191, 25);
             this.label5.TabIndex = 4;
@@ -98,7 +116,7 @@
             // label6
             // 
             this.label6.AutoSize = true;
-            this.label6.Location = new System.Drawing.Point(40, 300);
+            this.label6.Location = new System.Drawing.Point(4, 191);
             this.label6.Name = "label6";
             this.label6.Size = new System.Drawing.Size(131, 25);
             this.label6.TabIndex = 5;
@@ -106,7 +124,7 @@
             // 
             // numericUpDown1
             // 
-            this.numericUpDown1.Location = new System.Drawing.Point(298, 48);
+            this.numericUpDown1.Location = new System.Drawing.Point(184, 38);
             this.numericUpDown1.Maximum = new decimal(new int[] {
             3,
             0,
@@ -128,28 +146,28 @@
             // 
             // textBox1
             // 
-            this.textBox1.Location = new System.Drawing.Point(298, 97);
+            this.textBox1.Location = new System.Drawing.Point(184, 133);
             this.textBox1.Name = "textBox1";
             this.textBox1.Size = new System.Drawing.Size(239, 31);
             this.textBox1.TabIndex = 7;
             // 
             // textBox2
             // 
-            this.textBox2.Location = new System.Drawing.Point(298, 147);
+            this.textBox2.Location = new System.Drawing.Point(207, 38);
             this.textBox2.Name = "textBox2";
             this.textBox2.Size = new System.Drawing.Size(200, 31);
             this.textBox2.TabIndex = 8;
             // 
             // textBox3
             // 
-            this.textBox3.Location = new System.Drawing.Point(298, 197);
+            this.textBox3.Location = new System.Drawing.Point(207, 88);
             this.textBox3.Name = "textBox3";
             this.textBox3.Size = new System.Drawing.Size(200, 31);
             this.textBox3.TabIndex = 9;
             // 
             // textBox4
             // 
-            this.textBox4.Location = new System.Drawing.Point(298, 247);
+            this.textBox4.Location = new System.Drawing.Point(207, 138);
             this.textBox4.Name = "textBox4";
             this.textBox4.Size = new System.Drawing.Size(200, 31);
             this.textBox4.TabIndex = 10;
@@ -160,14 +178,14 @@
             this.comboBox1.Items.AddRange(new object[] {
             "JSON",
             "CSV"});
-            this.comboBox1.Location = new System.Drawing.Point(298, 297);
+            this.comboBox1.Location = new System.Drawing.Point(207, 188);
             this.comboBox1.Name = "comboBox1";
             this.comboBox1.Size = new System.Drawing.Size(239, 33);
             this.comboBox1.TabIndex = 11;
             // 
             // button1
             // 
-            this.button1.Location = new System.Drawing.Point(502, 145);
+            this.button1.Location = new System.Drawing.Point(411, 36);
             this.button1.Name = "button1";
             this.button1.Size = new System.Drawing.Size(35, 34);
             this.button1.TabIndex = 12;
@@ -177,7 +195,7 @@
             // 
             // button2
             // 
-            this.button2.Location = new System.Drawing.Point(502, 195);
+            this.button2.Location = new System.Drawing.Point(411, 86);
             this.button2.Name = "button2";
             this.button2.Size = new System.Drawing.Size(35, 34);
             this.button2.TabIndex = 13;
@@ -187,7 +205,7 @@
             // 
             // button3
             // 
-            this.button3.Location = new System.Drawing.Point(502, 245);
+            this.button3.Location = new System.Drawing.Point(411, 136);
             this.button3.Name = "button3";
             this.button3.Size = new System.Drawing.Size(35, 34);
             this.button3.TabIndex = 14;
@@ -197,7 +215,7 @@
             // 
             // button4
             // 
-            this.button4.Location = new System.Drawing.Point(40, 355);
+            this.button4.Location = new System.Drawing.Point(12, 396);
             this.button4.Name = "button4";
             this.button4.Size = new System.Drawing.Size(160, 34);
             this.button4.TabIndex = 15;
@@ -207,7 +225,7 @@
             // 
             // button5
             // 
-            this.button5.Location = new System.Drawing.Point(377, 355);
+            this.button5.Location = new System.Drawing.Point(295, 396);
             this.button5.Name = "button5";
             this.button5.Size = new System.Drawing.Size(160, 34);
             this.button5.TabIndex = 16;
@@ -215,35 +233,190 @@
             this.button5.UseVisualStyleBackColor = true;
             this.button5.Click += new System.EventHandler(this.button5_Click);
             // 
+            // groupBox1
+            // 
+            this.groupBox1.Controls.Add(this.textBox5);
+            this.groupBox1.Controls.Add(this.label7);
+            this.groupBox1.Controls.Add(this.textBox2);
+            this.groupBox1.Controls.Add(this.label3);
+            this.groupBox1.Controls.Add(this.label4);
+            this.groupBox1.Controls.Add(this.button3);
+            this.groupBox1.Controls.Add(this.label5);
+            this.groupBox1.Controls.Add(this.button2);
+            this.groupBox1.Controls.Add(this.label6);
+            this.groupBox1.Controls.Add(this.button1);
+            this.groupBox1.Controls.Add(this.textBox3);
+            this.groupBox1.Controls.Add(this.comboBox1);
+            this.groupBox1.Controls.Add(this.textBox4);
+            this.groupBox1.Location = new System.Drawing.Point(461, 12);
+            this.groupBox1.Name = "groupBox1";
+            this.groupBox1.Size = new System.Drawing.Size(464, 282);
+            this.groupBox1.TabIndex = 17;
+            this.groupBox1.TabStop = false;
+            this.groupBox1.Text = "Ore Def";
+            // 
+            // groupBox2
+            // 
+            this.groupBox2.Controls.Add(this.checkBox1);
+            this.groupBox2.Controls.Add(this.label1);
+            this.groupBox2.Controls.Add(this.label2);
+            this.groupBox2.Controls.Add(this.numericUpDown1);
+            this.groupBox2.Controls.Add(this.textBox1);
+            this.groupBox2.Location = new System.Drawing.Point(12, 12);
+            this.groupBox2.Name = "groupBox2";
+            this.groupBox2.Size = new System.Drawing.Size(443, 191);
+            this.groupBox2.TabIndex = 18;
+            this.groupBox2.TabStop = false;
+            this.groupBox2.Text = "Machine";
+            // 
+            // checkBox1
+            // 
+            this.checkBox1.AutoSize = true;
+            this.checkBox1.Location = new System.Drawing.Point(6, 91);
+            this.checkBox1.Name = "checkBox1";
+            this.checkBox1.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
+            this.checkBox1.Size = new System.Drawing.Size(199, 29);
+            this.checkBox1.TabIndex = 8;
+            this.checkBox1.Text = "Enable Serial Output";
+            this.checkBox1.UseVisualStyleBackColor = true;
+            // 
+            // groupBox3
+            // 
+            this.groupBox3.Controls.Add(this.checkBox5);
+            this.groupBox3.Controls.Add(this.checkBox4);
+            this.groupBox3.Controls.Add(this.checkBox3);
+            this.groupBox3.Controls.Add(this.checkBox2);
+            this.groupBox3.Location = new System.Drawing.Point(12, 217);
+            this.groupBox3.Name = "groupBox3";
+            this.groupBox3.Size = new System.Drawing.Size(443, 173);
+            this.groupBox3.TabIndex = 19;
+            this.groupBox3.TabStop = false;
+            this.groupBox3.Text = "Logging";
+            // 
+            // checkBox2
+            // 
+            this.checkBox2.AutoSize = true;
+            this.checkBox2.Location = new System.Drawing.Point(129, 30);
+            this.checkBox2.Name = "checkBox2";
+            this.checkBox2.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
+            this.checkBox2.Size = new System.Drawing.Size(76, 29);
+            this.checkBox2.TabIndex = 0;
+            this.checkBox2.Text = "Error";
+            this.checkBox2.UseVisualStyleBackColor = true;
+            // 
+            // checkBox3
+            // 
+            this.checkBox3.AutoSize = true;
+            this.checkBox3.Location = new System.Drawing.Point(101, 65);
+            this.checkBox3.Name = "checkBox3";
+            this.checkBox3.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
+            this.checkBox3.Size = new System.Drawing.Size(104, 29);
+            this.checkBox3.TabIndex = 1;
+            this.checkBox3.Text = "Warning";
+            this.checkBox3.UseVisualStyleBackColor = true;
+            // 
+            // checkBox4
+            // 
+            this.checkBox4.AutoSize = true;
+            this.checkBox4.Location = new System.Drawing.Point(73, 100);
+            this.checkBox4.Name = "checkBox4";
+            this.checkBox4.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
+            this.checkBox4.Size = new System.Drawing.Size(132, 29);
+            this.checkBox4.TabIndex = 2;
+            this.checkBox4.Text = "Information";
+            this.checkBox4.UseVisualStyleBackColor = true;
+            // 
+            // checkBox5
+            // 
+            this.checkBox5.AutoSize = true;
+            this.checkBox5.Location = new System.Drawing.Point(77, 135);
+            this.checkBox5.Name = "checkBox5";
+            this.checkBox5.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
+            this.checkBox5.Size = new System.Drawing.Size(128, 29);
+            this.checkBox5.TabIndex = 3;
+            this.checkBox5.Text = "Debugging";
+            this.checkBox5.UseVisualStyleBackColor = true;
+            // 
+            // label7
+            // 
+            this.label7.AutoSize = true;
+            this.label7.Location = new System.Drawing.Point(4, 241);
+            this.label7.Name = "label7";
+            this.label7.Size = new System.Drawing.Size(184, 25);
+            this.label7.TabIndex = 15;
+            this.label7.Text = "Ore Def sample types";
+            // 
+            // textBox5
+            // 
+            this.textBox5.Location = new System.Drawing.Point(207, 238);
+            this.textBox5.Name = "textBox5";
+            this.textBox5.Size = new System.Drawing.Size(239, 31);
+            this.textBox5.TabIndex = 16;
+            // 
+            // groupBox4
+            // 
+            this.groupBox4.Controls.Add(this.textBox6);
+            this.groupBox4.Controls.Add(this.label8);
+            this.groupBox4.Controls.Add(this.checkBox6);
+            this.groupBox4.Location = new System.Drawing.Point(461, 300);
+            this.groupBox4.Name = "groupBox4";
+            this.groupBox4.Size = new System.Drawing.Size(464, 125);
+            this.groupBox4.TabIndex = 20;
+            this.groupBox4.TabStop = false;
+            this.groupBox4.Text = "LIMS";
+            // 
+            // checkBox6
+            // 
+            this.checkBox6.AutoSize = true;
+            this.checkBox6.Location = new System.Drawing.Point(6, 30);
+            this.checkBox6.Name = "checkBox6";
+            this.checkBox6.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
+            this.checkBox6.Size = new System.Drawing.Size(229, 29);
+            this.checkBox6.TabIndex = 0;
+            this.checkBox6.Text = "Enable LIMS Connection";
+            this.checkBox6.UseVisualStyleBackColor = true;
+            // 
+            // label8
+            // 
+            this.label8.AutoSize = true;
+            this.label8.Location = new System.Drawing.Point(11, 77);
+            this.label8.Name = "label8";
+            this.label8.Size = new System.Drawing.Size(146, 25);
+            this.label8.TabIndex = 17;
+            this.label8.Text = "LIMS Connection";
+            // 
+            // textBox6
+            // 
+            this.textBox6.Location = new System.Drawing.Point(207, 74);
+            this.textBox6.Name = "textBox6";
+            this.textBox6.Size = new System.Drawing.Size(239, 31);
+            this.textBox6.TabIndex = 18;
+            // 
             // SettingsDialog
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(559, 403);
+            this.ClientSize = new System.Drawing.Size(939, 443);
+            this.Controls.Add(this.groupBox4);
+            this.Controls.Add(this.groupBox3);
+            this.Controls.Add(this.groupBox2);
+            this.Controls.Add(this.groupBox1);
             this.Controls.Add(this.button5);
             this.Controls.Add(this.button4);
-            this.Controls.Add(this.button3);
-            this.Controls.Add(this.button2);
-            this.Controls.Add(this.button1);
-            this.Controls.Add(this.comboBox1);
-            this.Controls.Add(this.textBox4);
-            this.Controls.Add(this.textBox3);
-            this.Controls.Add(this.textBox2);
-            this.Controls.Add(this.textBox1);
-            this.Controls.Add(this.numericUpDown1);
-            this.Controls.Add(this.label6);
-            this.Controls.Add(this.label5);
-            this.Controls.Add(this.label4);
-            this.Controls.Add(this.label3);
-            this.Controls.Add(this.label2);
-            this.Controls.Add(this.label1);
             this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
             this.Name = "SettingsDialog";
             this.Text = "SettingsDialog";
             this.Load += new System.EventHandler(this.SettingsDialog_Load);
             ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
+            this.groupBox1.ResumeLayout(false);
+            this.groupBox1.PerformLayout();
+            this.groupBox2.ResumeLayout(false);
+            this.groupBox2.PerformLayout();
+            this.groupBox3.ResumeLayout(false);
+            this.groupBox3.PerformLayout();
+            this.groupBox4.ResumeLayout(false);
+            this.groupBox4.PerformLayout();
             this.ResumeLayout(false);
-            this.PerformLayout();
 
         }
 
@@ -267,5 +440,19 @@
         private Button button4;
         private Button button5;
         private FolderBrowserDialog folderBrowserDialog1;
+        private GroupBox groupBox1;
+        private TextBox textBox5;
+        private Label label7;
+        private GroupBox groupBox2;
+        private CheckBox checkBox1;
+        private GroupBox groupBox3;
+        private CheckBox checkBox5;
+        private CheckBox checkBox4;
+        private CheckBox checkBox3;
+        private CheckBox checkBox2;
+        private GroupBox groupBox4;
+        private TextBox textBox6;
+        private Label label8;
+        private CheckBox checkBox6;
     }
 }

+ 17 - 0
crusherScanner/SettingsDialog.cs

@@ -28,6 +28,14 @@ namespace crusherScanner
             Properties.Settings.Default.OreDefWorkFile = textBox3.Text;
             Properties.Settings.Default.OreDefOutFile = textBox4.Text;
             Properties.Settings.Default.OutputFormat = comboBox1.Text;
+            Properties.Settings.Default.OreDefTypes = textBox5.Text;
+            Properties.Settings.Default.LimsConnection = checkBox6.Checked;
+            Properties.Settings.Default.LimsConnString = textBox6.Text;
+            Properties.Settings.Default.PrepmasterConnection = checkBox1.Checked;
+            Properties.Settings.Default.LoggingDebug = checkBox5.Checked;
+            Properties.Settings.Default.LoggingInfo = checkBox4.Checked;
+            Properties.Settings.Default.LoggingWarning = checkBox3.Checked;
+            Properties.Settings.Default.LoggingError = checkBox2.Checked;
             Properties.Settings.Default.Save();
             Close();
         }
@@ -40,6 +48,14 @@ namespace crusherScanner
             textBox3.Text = Properties.Settings.Default.OreDefWorkFile;
             textBox4.Text = Properties.Settings.Default.OreDefOutFile;
             comboBox1.Text = Properties.Settings.Default.OutputFormat;
+            textBox5.Text = Properties.Settings.Default.OreDefTypes;
+            checkBox6.Checked = Properties.Settings.Default.LimsConnection;
+            textBox6.Text = Properties.Settings.Default.LimsConnString;
+            checkBox1.Checked = Properties.Settings.Default.PrepmasterConnection;
+            checkBox5.Checked = Properties.Settings.Default.LoggingDebug;
+            checkBox4.Checked = Properties.Settings.Default.LoggingInfo;
+            checkBox3.Checked = Properties.Settings.Default.LoggingWarning;
+            checkBox2.Checked = Properties.Settings.Default.LoggingError;
         }
 
         /// <summary>
@@ -107,5 +123,6 @@ namespace crusherScanner
                 return "";
             }
         }
+
     }
 }

+ 5 - 1
crusherScanner/WorkingDirControl.cs

@@ -11,7 +11,7 @@ namespace crusherScanner
         /// <summary>
         /// Update sample as scanned in the working directory.
         /// </summary>
-        /// <param name="scanData">Sample data containing Job and Barcode.</param>
+        /// <param name="e">Sample data containing Job and Barcode.</param>
         public static void UpdateWorkingDir(System.ComponentModel.DoWorkEventArgs e)
         {
             if (e.Argument == null)
@@ -51,6 +51,7 @@ namespace crusherScanner
         /// Is the currently scanned sample's job in the working directory.
         /// </summary>
         /// <param name="scanData">Sample data containing Job and Barcode.</param>
+        /// <param name="DataDirs"></param>
         private static string? GetJobFilePath(Scan scanData,string[] DataDirs)
         {
             try
@@ -100,10 +101,13 @@ namespace crusherScanner
                             {
                                 fileLines.Add(line);
                             }
+                            // Count if sample has been scanned already
                             if(CSV[8] != "")
                             {
                                 scanData.JobCount++;
                             }
+                            // set CSV to null to prevent data roll over
+                            CSV = null;
                         }
                         line = Reader.ReadLine();
                     }

+ 33 - 2
crusherScanner/crusherScanner.csproj

@@ -2,12 +2,19 @@
 
   <PropertyGroup>
     <OutputType>WinExe</OutputType>
-    <TargetFramework>net6.0-windows</TargetFramework>
+    <TargetFramework>net6.0-windows10.0.17763.0</TargetFramework>
     <Nullable>enable</Nullable>
     <UseWindowsForms>true</UseWindowsForms>
     <ImplicitUsings>enable</ImplicitUsings>
-    <SignAssembly>False</SignAssembly>
+    <SignAssembly>True</SignAssembly>
     <ApplicationIcon>0d28e7dc-5024-45b7-81f8-bb1c48fe484d.ico</ApplicationIcon>
+    <AssemblyOriginatorKeyFile>C:\Users\gregory\Documents\Visual Studio 2022\crusherScannerKeyPair.snk</AssemblyOriginatorKeyFile>
+    <GenerateDocumentationFile>True</GenerateDocumentationFile>
+    <GeneratePackageOnBuild>False</GeneratePackageOnBuild>
+    <PackageIcon>gray-standing-hippopotamus-vector-clipart.png</PackageIcon>
+    <PlatformTarget>x64</PlatformTarget>
+    <DelaySign>False</DelaySign>
+    <SupportedOSPlatformVersion>10.0.17763.0</SupportedOSPlatformVersion>
   </PropertyGroup>
 
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -20,16 +27,33 @@
     <NoWarn>1701;1702</NoWarn>
   </PropertyGroup>
 
+  <ItemGroup>
+    <AdditionalFiles Remove="app.manifest" />
+  </ItemGroup>
+
   <ItemGroup>
     <Content Include="0d28e7dc-5024-45b7-81f8-bb1c48fe484d.ico" />
   </ItemGroup>
 
   <ItemGroup>
+    <None Include="..\..\..\..\Downloads\gray-standing-hippopotamus-vector-clipart.png">
+      <Pack>True</Pack>
+      <PackagePath>\</PackagePath>
+    </None>
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="CsvHelper" Version="28.0.1" />
     <PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
     <PackageReference Include="System.IO.Ports" Version="6.0.0" />
   </ItemGroup>
 
   <ItemGroup>
+    <Compile Update="Properties\Resources.Designer.cs">
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
     <Compile Update="Properties\Settings.Designer.cs">
       <DesignTimeSharedInput>True</DesignTimeSharedInput>
       <AutoGen>True</AutoGen>
@@ -37,6 +61,13 @@
     </Compile>
   </ItemGroup>
 
+  <ItemGroup>
+    <EmbeddedResource Update="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+  </ItemGroup>
+
   <ItemGroup>
     <None Update="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>