From 1c6ffdf61dbf524ea49f9903425f7db21ec1006f Mon Sep 17 00:00:00 2001
From: Eilert Tunheim <emtunhei@stud.ntnu.no>
Date: Mon, 2 May 2022 09:02:50 +0200
Subject: [PATCH] Added function to search for live data during drying process

---
 .../java/com/application/DB/Constants.java    |  11 ++--
 src/main/java/com/application/DB/DB.java      |  61 +++++++++++-------
 .../com/application/DB/HelpingFunctions.java  |  32 +++++++++
 .../com/application/GUI/InputPopUpWindow.java |  25 +++++++
 .../com/application/DB/Constants.class        | Bin 6168 -> 6466 bytes
 .../application/GUI/InputPopUpWindow.class    | Bin 7181 -> 7425 bytes
 6 files changed, 100 insertions(+), 29 deletions(-)

diff --git a/src/main/java/com/application/DB/Constants.java b/src/main/java/com/application/DB/Constants.java
index ce33886..2ea1fe0 100644
--- a/src/main/java/com/application/DB/Constants.java
+++ b/src/main/java/com/application/DB/Constants.java
@@ -18,10 +18,9 @@ public final class Constants {
     // Today's date
     public static final String TODAYS_DATE = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now());
 
-
     // Start- & end time
     public static String START_TIME = "";
-    public static String STOP_TIME = "";
+    public static String STOP_TIME = TODAYS_DATE;
 
     // User inputs
     public static String TREE_SPECIES = "";
@@ -35,11 +34,15 @@ public final class Constants {
     // Non linear regression
     public static final double ADJUST_REGRESSION = 5.5;
 
-    // Database ID/name
+    // Current sawmill settings;
     public static final String PROJECT_ID = "sf-drying-optimization";
-
     public static final int LOCATION_ID = 124;
     public static final String MAN_MOISTURE_TABLE = "int_dk_manMoisture";
+    public static final String KWH_TABLE_NAME = "int_sd_winccsensordata";
+    public static final String KWH_NAME_PARAMETER = "VariantValue";
+    public static final String KWH_TIMESTAMP_NAME_PARAMETER  = "Timestamp";
+    public static final String KWH_VALUE_ID_NAME_PARAMETER  = "ValueID";
+    public static final String KWH_VALUE_ID_VALUE_PARAMETER  = "51";          // Which chamber is used
 
 
     // Location Valasen(124)
diff --git a/src/main/java/com/application/DB/DB.java b/src/main/java/com/application/DB/DB.java
index 17cfb2c..cb88cf9 100644
--- a/src/main/java/com/application/DB/DB.java
+++ b/src/main/java/com/application/DB/DB.java
@@ -267,31 +267,7 @@ public class DB {
 
             //System.out.println("Timestamp \t kWh");
             int baseline = 0;
-            for (FieldValueList row : result.iterateAll()) {
-
-                // Sets the baseline in order to reset the kWh counter
-                if (baseline == 0) {
-                    baseline = row.get("" + KwhName + "").getNumericValue().intValue();
-                }
-                //System.out.println("baseline: "+baseline);
-
-                // kWh value
-                int variantValue = row.get("" + KwhName + "").getNumericValue().intValue() - baseline; //-baseline
-
-                // Retrieving the wanted data
-                long timeStamp = row.get("" + timestamp + "").getTimestampValue() / 1000;
-                // Riktig format, men i string
-                String formatedTimeStamp = HelpingFunctions.getDateFormat().format(timeStamp);
-
-                // Checks for negative values
-                if (variantValue > 0) {
-                    // Adding the data to a list in order to sort through later
-                    data.put(formatedTimeStamp, variantValue);
-                }
-
-                //System.out.printf("Timestamp: \t%s\t\t\tkWh: \t%s\t\t\tBaseline: %s\n",formatedTimeStamp,variantValue,baseline);
-                // Checks if the data is empty
-            }
+            HelpingFunctions.iterateKwhValues(data, baseline, result, KwhName, timestamp);
 
             System.out.println("Data size: " + data.size());
 
@@ -597,4 +573,39 @@ public class DB {
 
         HelpingFunctions.createQueryJob(sqlStatement);
     }
+
+    /**
+     *  Retrieves data from current drying process
+     *
+     * @return a map consisting of Timestamp(date&time) and Kwh value
+     * @throws Exception throws execution if anything is wrong
+     */
+    public static Map<String, Number> getCurrentDrying() throws Exception {
+
+        // Initializing the data map to store the results
+        Map<String, Number> data = new HashMap<>();
+        // Initializing baseline
+        int baseline = 0;
+
+        // Sqlstatement
+        final String sqlStatement = "SELECT `" + KWH_TIMESTAMP_NAME_PARAMETER + "`, `" + KWH_NAME_PARAMETER + "` " +
+                "FROM `" + PROJECT_ID + "." + LOCATION_ID + "." + KWH_TABLE_NAME + "` " +
+                "WHERE " + KWH_TIMESTAMP_NAME_PARAMETER + " BETWEEN " + '"' + START_TIME + '"' +
+                " AND " + '"' + STOP_TIME + '"' +
+                " AND " + KWH_VALUE_ID_NAME_PARAMETER + " = " + KWH_VALUE_ID_VALUE_PARAMETER + " " +
+                " AND " + KWH_NAME_PARAMETER + " <> 0 " +
+                " ORDER BY " + KWH_TIMESTAMP_NAME_PARAMETER + " ASC";
+
+        System.out.println(sqlStatement);
+
+        // Retrieves the results from the queryjob
+        TableResult result = HelpingFunctions.createQueryJob(sqlStatement);
+
+        //System.out.println("InTidTork\t\t\tUtTidTork");
+        // Iterating through the results
+        HelpingFunctions.iterateKwhValues(data, baseline, result, KWH_NAME_PARAMETER, KWH_TIMESTAMP_NAME_PARAMETER);
+        return new TreeMap<>(data);
+    }
+
+
 }
diff --git a/src/main/java/com/application/DB/HelpingFunctions.java b/src/main/java/com/application/DB/HelpingFunctions.java
index 5467ca7..a34f4f5 100644
--- a/src/main/java/com/application/DB/HelpingFunctions.java
+++ b/src/main/java/com/application/DB/HelpingFunctions.java
@@ -117,4 +117,36 @@ public class HelpingFunctions {
     public static Map<String, String> getManMoist() {
         return manMoist;
     }
+
+    /**
+     * Function to iterate through all the Kwh values and storing them in a map
+     *
+     * @param data a map to store all the data
+     * @param baseline a baseline to base all the next values of to get a zero point
+     * @param result TableResult to iterate through
+     * @param kwhNameParameter Name of the Kwh name parameter in the database
+     * @param kwhTimestampNameParameter Name of the timestamp parameter in the database
+     */
+    static void iterateKwhValues(Map<String, Number> data, int baseline, TableResult result, String kwhNameParameter, String kwhTimestampNameParameter) {
+        for (FieldValueList row : result.iterateAll()) {
+            // Sets the baseline in order to reset the kWh counter
+            if (baseline == 0) {
+                baseline = row.get("" + kwhNameParameter + "").getNumericValue().intValue();
+            }
+
+            // kWh value
+            int variantValue = row.get("" + kwhNameParameter + "").getNumericValue().intValue() - baseline; //-baseline
+
+            // Retrieving the wanted data
+            long timeStamp = row.get("" + kwhTimestampNameParameter + "").getTimestampValue() / 1000;
+            // Riktig format, men i string
+            String formatedTimeStamp = getDateFormat().format(timeStamp);
+
+            // Checks for negative values
+            if (variantValue > 0) {
+                // Adding the data to a list in order to sort through later
+                data.put(formatedTimeStamp, variantValue);
+            }
+        }
+    }
 }
diff --git a/src/main/java/com/application/GUI/InputPopUpWindow.java b/src/main/java/com/application/GUI/InputPopUpWindow.java
index 1d26d63..a4071ed 100644
--- a/src/main/java/com/application/GUI/InputPopUpWindow.java
+++ b/src/main/java/com/application/GUI/InputPopUpWindow.java
@@ -13,6 +13,7 @@ import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import static com.application.DB.Constants.*;
+import static com.application.DB.DB.getCurrentDrying;
 import static com.application.Main.*;
 import static com.application.DB.DB.setInputParameters;
 import static com.application.GUI.LineChartFunctionality.loadSingleSeries;
@@ -247,7 +248,31 @@ public class InputPopUpWindow {
                         ex.printStackTrace();
                     }
 
+                    // Retrieve data for current drying period
+                    try{
+                        Thread thread = new Thread(() -> {
+                            try {
+
+                                // Henter her data fra databasen
+                                Map<String, Number> data = getCurrentDrying();
+                                Platform.runLater(() -> {
+                                    try {
+                                        //loadSingleSeries(data);
+                                    } catch (Exception ex) {
+                                        ex.printStackTrace();
+                                    }
+                                });
+                            } catch (Exception ex) {
+                                ex.printStackTrace();
+                            }
+                        }
+                        );
+                        thread.setDaemon(true);
+                        thread.start();
 
+                    } catch (Exception ex) {
+                        ex.printStackTrace();
+                    }
 
                 }
 
diff --git a/target/classes/com/application/DB/Constants.class b/target/classes/com/application/DB/Constants.class
index 63ce6b6ba5f67a9529377d76c676478db897eb76..86a1941d22a795754d864cc38476bcc881177aec 100644
GIT binary patch
delta 2649
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
KSO6~d76Jh3sGvOn

delta 2387
zcmX?PG{d0&)W2Q(7#J8#7+!HPSTM|BXPC*wzyzXaaWR-O%;sWXVVDCFnG0gg0}=B%
z7#4s;7J@j7I2aa#=p`HsOF0;paWE|BU|7Myu#$se6$is=4u&;c3~L$IaWb$ltmk0Z
zz`?MQgJBZ~!)6YKEg-S2T=fhr4BJ2kYzGlLI2d+vFzn)B*v-MP2c%#x2g5!Py`O{O
z02jkShC^HohZ&B5SVuv^$2b^{gXj|=;v|ST1tLy^h%@XAXW1FfaWR}{xWL6=!f=tD
z;SwVQcZk1>V`Ol=i(`l@BZH97WDZ8*$tH~5jF%@LVANu~vblii1ry`d&5^8gS()=0
z3MT*LGPS<OaGi&tmZ6-7;ReG^9)=zetC69ck%2QTF()^*Br~~~hv62(Z61aekSMcv
zc?J(dCy1#q*^ftdavOIh_Z=RFYYcaJ7(yAsCja8L7m8sB<6-CnnbZ#=CNY#x_U4I7
zNMi_NWZ(=+P0R^P%qdOfVaNgr2v=5CR_glt>ZYV9cz9Ul=2{gOvoqY|VYtumfSutX
z55psd$2<&A7@qPlSTa~KGBEHkSTk7hFxY?yTM%IfBJ3F)CiC;^a6jW=c+T*GhasQg
z<zzQr=gob*Dophj3=9lv43Z!N7#J8hK?Z<n8wM*dZ40ICptL=M0|NttB!eS^69XfI
zGXnzy6N3wbB!e4+6`b$RAj#mt-~i`)GDtFbA<26)NHX|9<m<r(fE4&5Dd1<2Wbi}c
z3ouAB_#^QJ86+73koZCjk_>@Jd=Umoh9D%qD1#(JFvLQzeIX2zpcr9bWT+1Z3q&wT
zGDIS2kYbQzh(h8^Ge|N-Bk^S!BpG5D!WbAC5c*@0EQn)}WQa#nuf!n9kbuNjW{_k^
z1o7*kK?w3u5=a2b2l*%&iLb&S$&iA?S7nf7NJX*`<fAk+2c;vaS7(r9$Ux$QJe0{`
z#ZV86Ly(WM&<w~%(vZU-$&ia=VIBiN0~13&LjeOLLm>kLgE0dm10w?i1FP0{2F8ux
zKrLcmU;vdE3=Dh>EDQn+#SEYn3Rc8W!cYoMUhHKI<qS*=g_EZUnfZb=2r;lQFfgPs
za4@7Zh%#g_C^KZjHF7Y>GE^{BGB7YyL5+flR5LI@<DrIu3zTEQCW;GNBbk`bz`;<!
zAi+?`putdtWTFy79h!+C5m2&(#B2itCqpCDjfP?pleY_tBAHsoz`;<?AjnX`AjMFL
zWU2^;sUVRixI3E}xIl#l*qy7zv?e=?DAj{}FUP>nz`#(;z`;<*AjnY9AjQzYpv=(7
zpu^D2V9C&eWP>q7E1J7OBFHvyGPE(YgKS`6V2}aF4FdzqCI*QO3=9m63?SRsz@i<H
zu;XFqVBi83Umz`$KZuxt9VEuU%D}+T!@$AN%OJ?m#~{Vf&!EgO3CSU{3|(jr0g0eG
zq#K(<<j@^54dM{6J9-$(S-=iiDT*A6a~L=n<}yey%wy1Cn2+QLC5B!!M}S07W3dk&
zi@HcLxR`;1VF`mE!%_w*hGj@5g5nD`rGZ3{y~V}Q4>fVMm`@}qJRz~Sih+Y+HG?3-
z8U`tbwG7G(>lkzxHZWK+Y(z5Mm|+5%dqE<|rgJh(gaq2;0C7=Skm-=v+KLoNlc4s0
z5RsTXOI!{q!gexnFzjLwWZ2Ch#juA#nPDH2-Ledm(d-6^pxQkJVmE5a(Lj%|LvXin
zFid4AsD~B>&luPkKwy=S<_-p}9Sqvr7<4u>=nCm=X3z%_1|Y%^L>RGbW-#8(U=qo?
zm%%iWnPUe7Yj7ls02_$j!C<zX!F)4=1VUcG7$gzNB47ccVG8763MwO+1q4Adkt_m2
zAR4AZ4W=TJSwI*h5y=9fVG1-r1r{VvXfbdxFfa%+@G*!n2s4N?NH9n+fXYTC1{nr5
a26F~C2788dhERqMh8PA$hH2n}ZaM&CKw%dE

diff --git a/target/classes/com/application/GUI/InputPopUpWindow.class b/target/classes/com/application/GUI/InputPopUpWindow.class
index 6f8be194dd66499c7a4cda284470d56527148834..04830397692eb383cf896d85766005d3041e3420 100644
GIT binary patch
delta 3194
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
H9HRgLpKXY`

delta 2948
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

-- 
GitLab