Merge remote-tracking branch 'origin/features' into field
This commit is contained in:
		
							
								
								
									
										3
									
								
								src/config.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/config.properties
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | URL    = https://influx.sdi.hevs.ch | ||||||
|  | ORG    = SIn15 | ||||||
|  | BUCKET = SIn15 | ||||||
| @@ -1,5 +1,8 @@ | |||||||
| package ch.hevs.isi; | package ch.hevs.isi; | ||||||
|  |  | ||||||
|  | import ch.hevs.isi.core.BooleanDataPoint; | ||||||
|  | import ch.hevs.isi.core.FloatDataPoint; | ||||||
|  | import ch.hevs.isi.db.DatabaseConnector; | ||||||
| import ch.hevs.isi.utils.Utility; | import ch.hevs.isi.utils.Utility; | ||||||
|  |  | ||||||
| public class MinecraftController { | public class MinecraftController { | ||||||
| @@ -74,5 +77,20 @@ public class MinecraftController { | |||||||
|  |  | ||||||
|         // Start coding here ... |         // Start coding here ... | ||||||
|  |  | ||||||
|  |         // Initialize the database connector | ||||||
|  |         if((dbProtocol != null) && (dbHostName != null)){ | ||||||
|  |             DatabaseConnector.url = dbProtocol+ "://" + dbHostName; | ||||||
|  |             DatabaseConnector.getMySelf().initialize(dbProtocol+ "://" + dbHostName); | ||||||
|  |         } | ||||||
|  |         if(dbName != null){ | ||||||
|  |             DatabaseConnector.org = dbName; | ||||||
|  |         } | ||||||
|  |         if(dbUserName != null){ | ||||||
|  |             DatabaseConnector.bucket = dbUserName; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Initialize the Modbus TCP connector | ||||||
|  |  | ||||||
|  |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -25,8 +25,8 @@ public class BooleanDataPoint extends DataPoint{ | |||||||
|     public String toString(){ |     public String toString(){ | ||||||
|         String s; |         String s; | ||||||
|         s = this.getLabel(); |         s = this.getLabel(); | ||||||
|         s += ": "; |         s += "="; | ||||||
|         s += this.getValue(); |         s += this.getValue() ? "1" : "0"; | ||||||
|         return s; |         return s; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ public class FloatDataPoint extends DataPoint{ | |||||||
|     public String toString(){ |     public String toString(){ | ||||||
|         String s; |         String s; | ||||||
|         s = this.getLabel(); |         s = this.getLabel(); | ||||||
|         s += ": "; |         s += "="; | ||||||
|         s += this.getValue(); |         s += this.getValue(); | ||||||
|         return s; |         return s; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,32 +1,190 @@ | |||||||
| package ch.hevs.isi.db; | package ch.hevs.isi.db; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | import ch.hevs.isi.MinecraftController; | ||||||
| import ch.hevs.isi.core.DataPoint; | import ch.hevs.isi.core.DataPoint; | ||||||
| import ch.hevs.isi.core.DataPointListener; | import ch.hevs.isi.core.DataPointListener; | ||||||
|  | import ch.hevs.isi.core.FloatDataPoint; | ||||||
|  | import ch.hevs.isi.utils.Utility; | ||||||
|  |  | ||||||
|  | import java.io.FileInputStream; | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.io.InputStream; | ||||||
|  | import java.io.OutputStreamWriter; | ||||||
|  | import java.net.HttpURLConnection; | ||||||
|  | import java.net.MalformedURLException; | ||||||
|  | import java.net.ProtocolException; | ||||||
|  | import java.net.URL; | ||||||
|  | import java.util.Properties; | ||||||
|  |  | ||||||
|  |  | ||||||
| public class DatabaseConnector implements DataPointListener { | public class DatabaseConnector implements DataPointListener { | ||||||
|  |     private Properties properties = new Properties();           // Properties of the config.properties file | ||||||
|  |     private String fullURL = null;                              // Full URL of the InfluxDB server | ||||||
|  |     private URL urlForWrite = null;                             // URL of the InfluxDB server | ||||||
|  |     private HttpURLConnection con = null;                       // Connection to the InfluxDB server | ||||||
|  |     private boolean initialized = false;                        // Boolean to know if the database connector is initialized | ||||||
|  |     private TimeManager _timeManager = new TimeManager(3); // Time manager to manage the time of the data points | ||||||
|  |     private long _timestamp = 0;                                // Timestamp of the data points | ||||||
|  |     String default_token = System.getenv("SECRET_TOKEN"); // Token to access the InfluxDB server | ||||||
|  |     public static String url = null;                            // URL of the InfluxDB server | ||||||
|  |     public static String org = null;                            // Organization of the InfluxDB server | ||||||
|  |     public static String bucket = null;                         // Bucket of the InfluxDB server | ||||||
|  |  | ||||||
|  |  | ||||||
|     private static DatabaseConnector  mySelf = null; |     private static DatabaseConnector  mySelf = null; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Private constructor of the database connector | ||||||
|  |      * Read the config.properties file and initialize the database connector | ||||||
|  |      */ | ||||||
|     private DatabaseConnector (){ |     private DatabaseConnector (){ | ||||||
|  |         // Read the config.properties file | ||||||
|  |         try (InputStream input = new FileInputStream("src/config.properties")) { | ||||||
|  |             properties.load(input); | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             e.printStackTrace(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         // Get the URL, the organization and the bucket from the config.properties file if their are null | ||||||
|  |         if (url == null){ | ||||||
|  |             url = properties.getProperty("URL"); | ||||||
|  |         } | ||||||
|  |         if (org == null){ | ||||||
|  |             org = properties.getProperty("ORG"); | ||||||
|  |         } | ||||||
|  |         if (bucket == null){ | ||||||
|  |             bucket = properties.getProperty("BUCKET"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the instance of the database connector | ||||||
|  |      * @return The instance of the database connector | ||||||
|  |      */ | ||||||
|     public static DatabaseConnector  getMySelf(){ |     public static DatabaseConnector  getMySelf(){ | ||||||
|         if (mySelf == null){ |         if (mySelf == null){ | ||||||
|             mySelf = new DatabaseConnector(); |             mySelf = new DatabaseConnector(); | ||||||
|         } |         } | ||||||
|         return mySelf; |         return mySelf; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Initialize the database connector | ||||||
|  |      * @param url URL of the database. If null take the URL from the config.properties file | ||||||
|  |      */ | ||||||
|     public void initialize(String url){ |     public void initialize(String url){ | ||||||
|  |         try{ | ||||||
|  |             if(urlForWrite == null){ | ||||||
|  |                 if(url == null){ | ||||||
|  |                     url = properties.getProperty("URL"); | ||||||
|  |                 } | ||||||
|  |                 fullURL = url + "/api/v2/write?org=" + org + "&bucket=" + bucket; | ||||||
|  |                 Utility.pDebug("URL: " + fullURL); | ||||||
|  |                 urlForWrite = new URL(fullURL); | ||||||
|  |             } | ||||||
|  |             initialized = true; | ||||||
|  |         } catch (MalformedURLException e) { | ||||||
|  |             throw new RuntimeException(e); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     private void pushToDatabase(DataPoint dp){ |         // If the user want to erase the previous data in the database | ||||||
|         System.out.println(dp.toString() + " -> Database"); |         // Delete the previous data | ||||||
|  |         if(MinecraftController.ERASE_PREVIOUS_DATA_INB_DB){ | ||||||
|  |             try { | ||||||
|  |                 // Create the URL to delete the data | ||||||
|  |                 fullURL = url + "/api/v2/delete?org=" + org + "&bucket=" + bucket; | ||||||
|  |                 Utility.pDebug("URL: " + fullURL); | ||||||
|  |                 URL urlForDelete = new URL(fullURL); | ||||||
|  |                 // Create the connection to the database | ||||||
|  |                 con = (HttpURLConnection) urlForDelete.openConnection(); | ||||||
|  |                 con.setRequestMethod("POST"); | ||||||
|  |                 con.setRequestProperty("Authorization", "Token " + default_token); | ||||||
|  |                 con.setRequestProperty("Content-Type", "text/plain"); | ||||||
|  |                 con.setRequestProperty("Accept", "application/json"); | ||||||
|  |                 con.setDoOutput(true); | ||||||
|  |             } catch (MalformedURLException e) { | ||||||
|  |                 throw new RuntimeException(e); | ||||||
|  |             } catch (ProtocolException e) { | ||||||
|  |                 throw new RuntimeException(e); | ||||||
|  |             } catch (IOException e) { | ||||||
|  |                 throw new RuntimeException(e); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             // Create the data to send to delete the data in the database and send it | ||||||
|  |             String data = "{\n"; | ||||||
|  |             data += "\"start\": \"2000-01-01T00:00:00Z\",\n"; | ||||||
|  |             data += "\"stop\": \"2024-04-25T10:45:00Z\",\n"; | ||||||
|  |             data += "\"predicate\": \"_measurement=\\\"Minecraft\\\"\"\n"; | ||||||
|  |             data += "}"; | ||||||
|  |             Utility.pDebug(data); | ||||||
|  |             sendDataToDatabase(data); | ||||||
|  |             fullURL=null;   // Reset the full URL | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Push the data point to the database | ||||||
|  |      * @param dp Data point to push | ||||||
|  |      */ | ||||||
|  |     private void pushToDatabase(DataPoint dp) { | ||||||
|  |         // Initialize the database connector if not already done | ||||||
|  |         if(initialized == false){ | ||||||
|  |             initialize(null); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Create the data to send | ||||||
|  |         String data = "Minecraft "; | ||||||
|  |         data += dp.toString(); | ||||||
|  |         data += " " + _timestamp; | ||||||
|  |  | ||||||
|  |         // Send the data to the database | ||||||
|  |         sendDataToDatabase(data); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void sendDataToDatabase(String data){ | ||||||
|  |         try { | ||||||
|  |             // Create connection and set headers | ||||||
|  |             if(con == null){ | ||||||
|  |                 con = (HttpURLConnection) urlForWrite.openConnection(); | ||||||
|  |                 con.setRequestMethod("POST"); | ||||||
|  |                 con.setRequestProperty("Authorization", "Token " + default_token); | ||||||
|  |                 con.setRequestProperty("Content-Type", "application/json"); | ||||||
|  |                 con.setDoOutput(true); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // Send data | ||||||
|  |             OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream()); | ||||||
|  |             writer.write(data); | ||||||
|  |             writer.flush(); | ||||||
|  |  | ||||||
|  |             // Get response code | ||||||
|  |             int respondCode = con.getResponseCode(); | ||||||
|  |             if(respondCode != 204){ | ||||||
|  |                 System.out.println("Error: " + respondCode + ", Data: " + data); | ||||||
|  |             } else { | ||||||
|  |                 System.out.println(data + " -> Database"); | ||||||
|  |             } | ||||||
|  |             con.disconnect(); | ||||||
|  |             con = null; | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             e.printStackTrace(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Push the data point to the database | ||||||
|  |      * @param dp Data point to push | ||||||
|  |      */ | ||||||
|     @Override |     @Override | ||||||
|     public void onNewValue(DataPoint dp) { |     public void onNewValue(DataPoint dp) { | ||||||
|  |         if(dp.getLabel().equals("CLOAK_FLOAT")) { | ||||||
|  |             FloatDataPoint fdp = (FloatDataPoint) dp; | ||||||
|  |             _timeManager.setTimestamp(fdp.getValue()); | ||||||
|  |             _timestamp = _timeManager.getNanosForDB(); | ||||||
|  |         } | ||||||
|  |         if(_timestamp != 0){ | ||||||
|             pushToDatabase(dp); |             pushToDatabase(dp); | ||||||
|         } |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ import java.util.*; | |||||||
| public class Utility { | public class Utility { | ||||||
|     /** Default size for the TCP input stream */ |     /** Default size for the TCP input stream */ | ||||||
|     public static final int	TCP_BUFFER_SIZE 	= 4096; |     public static final int	TCP_BUFFER_SIZE 	= 4096; | ||||||
|  |     public static final boolean DEBUG_MODE = false; | ||||||
|  |  | ||||||
|     /** Object to get some random values... */ |     /** Object to get some random values... */ | ||||||
|     public static Random rnd = new Random(1); |     public static Random rnd = new Random(1); | ||||||
| @@ -419,4 +420,8 @@ public class Utility { | |||||||
|             System.out.println(logMsg); |             System.out.println(logMsg); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public static void pDebug(String msg) { | ||||||
|  |         if(DEBUG_MODE) System.out.println(msg); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										29
									
								
								src/test/java/Database.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/test/java/Database.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | import ch.hevs.isi.MinecraftController; | ||||||
|  | import ch.hevs.isi.core.BooleanDataPoint; | ||||||
|  | import ch.hevs.isi.core.DataPoint; | ||||||
|  | import ch.hevs.isi.core.FloatDataPoint; | ||||||
|  | import ch.hevs.isi.db.DatabaseConnector; | ||||||
|  |  | ||||||
|  | import java.io.FileInputStream; | ||||||
|  | import java.io.InputStream; | ||||||
|  | import java.util.Properties; | ||||||
|  |  | ||||||
|  | public class Database { | ||||||
|  |     public static void main(String[] args) { | ||||||
|  |         MinecraftController.ERASE_PREVIOUS_DATA_INB_DB = true; | ||||||
|  |         FloatDataPoint clock = new FloatDataPoint("CLOAK_FLOAT", false); | ||||||
|  |         FloatDataPoint gridVoltage = new FloatDataPoint("GRID_U_FLOAT", true); | ||||||
|  |         BooleanDataPoint solarPanel = new BooleanDataPoint("REMOTE_SOLAR_SW", true); | ||||||
|  |  | ||||||
|  |         DatabaseConnector.getMySelf().initialize(null); | ||||||
|  |  | ||||||
|  |         clock.setValue(0f); | ||||||
|  |  | ||||||
|  |         for (float i = 0; i < 3; i += 0.1f) { | ||||||
|  |             System.out.println(""); | ||||||
|  |             clock.setValue(i); | ||||||
|  |             gridVoltage.setValue(750 + (100*i)%100); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user