From 8a74b214f53ba87c734200a4a2bdb2bfa1792e12 Mon Sep 17 00:00:00 2001
From: Eilert Tunheim <emtunhei@stud.ntnu.no>
Date: Fri, 25 Mar 2022 13:35:22 +0100
Subject: [PATCH] Fully functional quick switching using constans class

---
 .../java/com/application/DB/Constants.java    |  43 +++++++-
 src/main/java/com/application/DB/DB.java      |  95 ++++++++++--------
 .../com/application/DB/Constants.class        | Bin 1028 -> 1340 bytes
 target/classes/com/application/DB/DB.class    | Bin 10348 -> 10444 bytes
 4 files changed, 94 insertions(+), 44 deletions(-)

diff --git a/src/main/java/com/application/DB/Constants.java b/src/main/java/com/application/DB/Constants.java
index 65b1741..9326672 100644
--- a/src/main/java/com/application/DB/Constants.java
+++ b/src/main/java/com/application/DB/Constants.java
@@ -23,16 +23,51 @@ public final class Constants {
     // Database ID/name
     public static final String PROJECT_ID = "sf-drying-optimization";
 
-    // Location Valasen
+
+    // Location Valasen(124)
+    // Project settings
     public static final int LOCATION_ID = 124;
     public static final String TABLE_NAME_VALMATICS = "int_dk_valmaticsdryingbatches_v2";
     public static final String TABLE_NAME_KWH = "int_sd_winccsensordata";
 
-    // Location Arjang
-    /*
+    // Parameters settings
+    // Valmatics
+    public static final String OTHER_PARAMETERS_NAME = "Name";
+    public static final String START_DRYING_NAME = "DryingStarted";
+    public static final String STOP_DRYING_NAME = "CalculatedStop";
+    public static final String KILIN_NAME = "KilnName";
+    public static final int KILIN_ID = 5;
+
+    // Winccsensordata
+    public static final String KWH_NAME = "VariantValue";
+    public static final int VALUE_ID = 51;
+
+
+
+
+
+
+
+/*
+    // Location Arjang(174)
+    // Project settings
     public static final int LOCATION_ID = 174;
     public static final String TABLE_NAME_VALMATICS = "int_dk_valmaticsdryingbatches";
     public static final String TABLE_NAME_KWH = "int_sd_swappconsensordata";
-     */
+
+    // Parameters settings
+    // Valmatics
+    public static final String OTHER_PARAMETERS_NAME = "Name";
+    public static final String START_DRYING_NAME = "DryingStarted";
+    public static final String STOP_DRYING_NAME = "DryingCompleted";
+    public static final String KILIN_NAME = "KilinId";
+    public static final int KILIN_ID = 16;
+
+    // Winccsensordata
+    public static final String KWH_NAME = "RealValue";
+    public static final int VALUE_ID = 19;
+
+ */
+
 
 }
diff --git a/src/main/java/com/application/DB/DB.java b/src/main/java/com/application/DB/DB.java
index eb340cd..a533625 100644
--- a/src/main/java/com/application/DB/DB.java
+++ b/src/main/java/com/application/DB/DB.java
@@ -12,6 +12,7 @@ import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
 
+
 import static com.application.DB.Constants.*;
 
 /**
@@ -167,14 +168,15 @@ public class DB {
 
             // Preparing a query statement
             // Query statement 124 Valåsen
-            final String sqlStatement = "SELECT `TimeStamp`, `VariantValue` " +
+            final String sqlStatement = "SELECT `TimeStamp`, `"+KWH_NAME+"` " +
                     "FROM `" + PROJECT_ID + "." + LOCATION_ID + "." + TABLE_NAME_KWH + "` " +
                     "WHERE TimeStamp BETWEEN " + '"'+ entry.getKey() + '"' +
                     " AND " + '"' + entry.getValue() + '"' +
-                    " AND ValueID = 51" +
+                    " AND ValueID = " + VALUE_ID + " " +
                     " ORDER BY TimeStamp ASC";
 
 
+
             /*
             // Query statement 174 Årjang
             final String sqlStatement =
@@ -199,12 +201,12 @@ public class DB {
 
                 // Sets the baseline in order to reset the kWh counter
                 if (baseline == 0){
-                    baseline = row.get("VariantValue").getNumericValue().intValue();
+                    baseline = row.get(""+KWH_NAME+"").getNumericValue().intValue();
                 }
                 //System.out.println("baseline: "+baseline);
 
                 // kWh value
-                int variantValue = row.get("VariantValue").getNumericValue().intValue()-baseline; //-baseline
+                int variantValue = row.get(""+KWH_NAME+"").getNumericValue().intValue()-baseline; //-baseline
 
                 // Retrieving the wanted data
                 long timeStamp = row.get("TimeStamp").getTimestampValue() / 1000;
@@ -258,10 +260,6 @@ public class DB {
      */
     private static Map<String, String> getZeroPointDate() throws Exception{
 
-        // Initializing a date format in the data type DateTimeFormatter
-        // Required for iterating through the dates.
-        DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
-
         // Initializing the dates map to store the results
         Map<String, String> dates = new HashMap<>();
 
@@ -274,19 +272,22 @@ public class DB {
          */
 
 
+        // Defining extra parameters if required
+        String extraInputParameter = "";
+        if(LOCATION_ID == 124){
+            extraInputParameter = "AND CalculatedStart BETWEEN \"1990-01-01 00:00:00\" AND \"" + TODAYS_DATE + "\" ";
+        }
+
         // Sqlstatement for Valåsen(124)
         final String sqlStatement =
-                        "SELECT MAX(Name) as DryingSchedule, MAX(KilnName) as Kiln_name, DryingStarted, Max(CalculatedStop) as CalculatedStop " +
+                        "SELECT MAX("+OTHER_PARAMETERS_NAME+") as DryingSchedule, MAX("+KILIN_NAME+") as Kiln_ID, " + START_DRYING_NAME + ", MAX("+STOP_DRYING_NAME+") as DryingCompleted " +
                         "FROM `" + PROJECT_ID + "." + LOCATION_ID + "." + TABLE_NAME_VALMATICS + "` " +
-                        "WHERE KilnName = 5 " +
-                        //"AND DATE(DryingStarted) BETWEEN \"1990-08-17\" AND \"2022-08-17\" " +
-                        //"AND DATE(CalculatedStop) BETWEEN \"1990-08-17\" AND \"2022-08-17\" " +
-                        //"AND DATE(CalculatedStart) BETWEEN \"1990-08-17\" AND \"2022-08-17\" " +
-                        "AND DryingStarted BETWEEN \"1990-01-01 00:00:00\" AND \"" + TODAYS_DATE + "\" " +
-                        "AND CalculatedStop BETWEEN \"1990-01-01 00:00:00\" AND \"" + TODAYS_DATE + "\" " +
-                        "AND CalculatedStart BETWEEN \"1990-01-01 00:00:00\" AND \"" + TODAYS_DATE + "\" " +
-                        "Group by DryingStarted " +
-                        "Order by DryingStarted ASC ";
+                        "WHERE " + KILIN_NAME + " = " + KILIN_ID + " " +
+                        "AND "+START_DRYING_NAME+" BETWEEN \"1990-01-01 00:00:00\" AND \"" + TODAYS_DATE + "\" " +
+                        "AND "+STOP_DRYING_NAME+" BETWEEN \"1990-01-01 00:00:00\" AND \"" + TODAYS_DATE + "\" " +
+                                extraInputParameter +
+                        "Group by "+ START_DRYING_NAME + " " +
+                        "Order by "+ START_DRYING_NAME + " ASC ";
 
         System.out.println(sqlStatement);
 
@@ -315,17 +316,26 @@ public class DB {
             String formatedInTidTork = "";
             String formatedUtTidTork = "";
 
+            //System.out.println("Start: "+row.get("DryingStarted").getTimestampValue());
+            //System.out.println("Stop: "+row.get("DryingCompleted").getTimestampValue());
+
+
             // Retrieving the data
             // DryingStarted:
             if(!row.get("DryingStarted").isNull()){
+
                 // Check if response is given in millis
-                if(row.get("DryingStarted").getValue() instanceof Integer) {
-                    long InTidTorkLong = row.get("DryingStarted").getTimestampValue()/1000;
+                try{
+                    long doubleValue = row.get("DryingStarted").getTimestampValue();
+                    long InTidTorkLong = doubleValue/1000;
                     // Formating the data from long to a string in the correct date format
                     formatedInTidTork = getDateFormat().format(InTidTorkLong);
-                }
-                // Checks if response is given in a string date format
-                else if(row.get("DryingStarted").getValue() instanceof String) {
+                    //System.out.println("LONG!!@@@@");
+                } catch(NumberFormatException e){
+                    //not long value, must be of type string
+
+                    //System.out.println("Must be a string!!@@@@");
+
                     // stores the value
                     String value = (String) row.get("DryingStarted").getValue();
                     // Splits the string based on 'T'
@@ -333,29 +343,34 @@ public class DB {
                     // Combines the values into a new format
                     formatedInTidTork = splitValue[0]+" "+splitValue[1];
                 }
+
+                // Checks if response is given in a string date format
+                //if(row.get("DryingStarted").getValue().equals(Long.parseLong(row.get("DryingStarted").getValue().toString()))) {
+
+
             }
 
             // CalculatedStop:
             // DryingCompleted:
-            if(!row.get("CalculatedStop").isNull()){
-                // Check if response is given in millis
-                if(row.get("CalculatedStop").getValue() instanceof Integer) {
-                    long utTidTorkLong = row.get("CalculatedStop").getTimestampValue()/1000;
-                    // Formating the data from long to a string in the correct date format
-                    formatedUtTidTork = getDateFormat().format(utTidTorkLong);
-                }
-                else if(row.get("CalculatedStop").getValue() instanceof String) {
-                    // stores the value
-                    String value = (String) row.get("CalculatedStop").getValue();
-                    // Splits the string based on 'T'
-                    String[] splitValue = value.split("T");
-                    // Combines the values into a new format
-                    formatedUtTidTork = splitValue[0]+" "+splitValue[1];
-                }
+            // Check if response is given in millis
+            try{
+                long doubleValue = row.get("DryingCompleted").getTimestampValue();
+                long utTidTorkLong = doubleValue/1000;
+                // Formating the data from long to a string in the correct date format
+                formatedUtTidTork = getDateFormat().format(utTidTorkLong);
+            } catch(NumberFormatException e) {
+                //not long value, must be of type string
+
+                // stores the value
+                String value = (String) row.get("DryingCompleted").getValue();
+                // Splits the string based on 'T'
+                String[] splitValue = value.split("T");
+                // Combines the values into a new format
+                formatedUtTidTork = splitValue[0] + " " + splitValue[1];
             }
 
-            System.out.println(formatedInTidTork);
-            System.out.println(formatedUtTidTork+"\n");
+            System.out.println("Inn formated: "+formatedInTidTork);
+            System.out.println("Ut formated: "+formatedUtTidTork+"\n");
 
             /*
             // CalculatedStop:
diff --git a/target/classes/com/application/DB/Constants.class b/target/classes/com/application/DB/Constants.class
index 36d1dfcf105d9904e54bdde59aeb74409a514b91..c682eb0f42ee8e24b82c8dc46fc7e8e06d2425f1 100644
GIT binary patch
delta 561
zcmZqS*u!Ob>ff$?3=9k=3|?FeoD2pW42E0`MhwQB3>*w5TnwfRW+1LPh-<;lV9Cy4
zHPNt$(R$(%gL)fA2EGtSCm+{%KSy8Jc<*oz4hCCB22uYI57(gh0LLIlU)K=VpkS~x
z2ZJ3WgJ5uoV^B!EOHibzpF338o{>QyIK)2yRn&ozfy>*|$I}n0%8`+Q1H$)oVP;@p
zU}a>G;qVUkfJ!?tGH`@B`h>d1L!^x-zMR0U#-KjAhEYPonTNrJ!Ig)Bi-DV+!HtK(
zoxuad@tnMdvCo;sFEKZjk%8Bxs4_DzJ-8&Xs3bLok%7-SF(<h+C$S_oCAcKN0Azb+
zP98)pPgr76W@27RSYl3TDkFo^<VGf?$+1kQ7<ngaFbCF4GDtA+GB7gmGcYhPF-S5<
zGDsour5Pj{WRUo>43Z3TNPKw)Nd^T5A-H};21y1bBza{9Nd^@pc~u4`1||kI26YBT
z1`P%V24h<WMg~Su2x)C+VB83HgC+w50~Z4m0|SEq0}F!?gBAk=0}n(IgEoT>0|NsG
cgD%8`$w!&hBoXTQ7&sV285kM#z~<-!0Jzgvs{jB1

delta 261
zcmdnP)xu$T>ff$?3=9k=4CY)6oD51F49Z*#Dh#Te3>*w<Tny?A8X&GFh^xiUpv}&p
zGtsb!QFr1J15rIj2EGtSCm+{%KSy8Jc<*oz4hH?n`HT~cB^V?b8H6h<D=T$<eRWe(
z6g)hva&xVUi`f|rco+;BjCdHh7`WLPjCmML7)(JNv&lwGeUq7(-!igI{=gjQ!^FVE
zAi*HXz{nuQz`$V4z{tSJz`($&wVi=+BLf2i6N5AZ0|OTW69WT-00Rqy5Q7W@0|O64
l5rZs)90LOb2ZKDsfXRPZ)Fct=`4~7DL>U+v6u{;v0swzRBiH}{

diff --git a/target/classes/com/application/DB/DB.class b/target/classes/com/application/DB/DB.class
index 386565ccedb8265adb368a8df6a4c7ae9917907c..d01f067c3c3db55edf5e5ab9b325a53bacff7aaa 100644
GIT binary patch
delta 4035
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
Q!*3AH$j8XT@P$DV0OB2lCjbBd

delta 3959
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
PPav9+m64g@HG?Do^3rXV

-- 
GitLab