diff --git a/src/main/java/ch/hevs/isi/MinecraftController.java b/src/main/java/ch/hevs/isi/MinecraftController.java index 1e6b4ac..66da3ec 100644 --- a/src/main/java/ch/hevs/isi/MinecraftController.java +++ b/src/main/java/ch/hevs/isi/MinecraftController.java @@ -34,7 +34,7 @@ public class MinecraftController { } @SuppressWarnings("all") - public static void main(String[] args) { + public static void main(String[] args) throws InterruptedException { // ------------------------------------- DO NOT CHANGE THE FOLLOWING LINES ------------------------------------- String dbProtocol = "http"; @@ -99,17 +99,37 @@ public class MinecraftController { Utility.pDebug("Database URL: " + DatabaseConnector.url); Utility.pDebug("Config: " + properties.getProperty("DB.URL")); DatabaseConnector.getMySelf().initialize(DatabaseConnector.url); + System.out.println("Database is running on " + DatabaseConnector.url); } // Initialize the Modbus TCP connector FieldConnector.getMySelf().initialize(modbusTcpHost, modbusTcpPort,"src/main/resources/ModbusMap.csv"); - - + System.out.println("Field is running on " + modbusTcpHost + ":" + modbusTcpPort); // Initialize the web server String host = properties.getProperty("WEB.URL"); int port = Integer.parseInt(properties.getProperty("WEB.PORT")); WebConnector.getMySelf().initialize(host, port); + System.out.println("Web server is running on " + host + ":" + port); + + + SmartControl smartControl = new SmartControl(); + System.out.println("SmartControl is running"); + while (true) { + boolean stateGrid = true; + try { + stateGrid = smartControl.run(); + } catch (Exception e) { + e.printStackTrace(); + } + if(!stateGrid) { + System.out.println("Grid is not fine"); + System.exit(0); + } else { + System.out.println("Grid is fine"); + } + Thread.sleep(SmartControl.TIME_BETWEEN_UPDATES); + } } diff --git a/src/main/java/ch/hevs/isi/SmartControl.java b/src/main/java/ch/hevs/isi/SmartControl.java new file mode 100644 index 0000000..5b39be3 --- /dev/null +++ b/src/main/java/ch/hevs/isi/SmartControl.java @@ -0,0 +1,241 @@ +package ch.hevs.isi; + +import ch.hevs.isi.core.BooleanDataPoint; +import ch.hevs.isi.core.DataPoint; +import ch.hevs.isi.core.FloatDataPoint; + +public class SmartControl { + + private static final float BATTERY_LEVEL_LOW = 0.1f; + private static final float BATTERY_LEVEL_HIGH = 0.9f; + private static final float BATTERY_POWER_MAX = 2500f; + private static final float COAL_AMOUNT_DAY = (1f-0.2f)/3f; + private static final float GRID_VOLTAGE_MIN = 750f; + private static final float GRID_VOLTAGE_MAX = 900f; + private static final float GRID_VOLTAGE_NOMINAL = 800f; + private static final float GRID_VOLTAGE_TOLERANCE = 25f; + private static final float PV_PANEL_NOMINAL = 1000f; + private static final float PV_PANEL_NOMINAL_RAINING = 500f; + + public static final long TIME_BETWEEN_UPDATES = 10; + + + + // Useful data points + private FloatDataPoint clock; + private FloatDataPoint battChrg; + private FloatDataPoint battPwrIn; + private FloatDataPoint remoteCoalSp; + private FloatDataPoint remoteFactorySp; + private FloatDataPoint coalAmount; + + + private void defineDataPoints(){ + clock = (FloatDataPoint) DataPoint.getDataPointOnListFromLabel("CLOCK_FLOAT"); + battChrg = (FloatDataPoint) DataPoint.getDataPointOnListFromLabel("BATT_CHRG_FLOAT"); + battPwrIn = (FloatDataPoint) DataPoint.getDataPointOnListFromLabel("BATT_P_FLOAT"); + remoteCoalSp = (FloatDataPoint) DataPoint.getDataPointOnListFromLabel("REMOTE_COAL_SP"); + remoteFactorySp = (FloatDataPoint) DataPoint.getDataPointOnListFromLabel("REMOTE_FACTORY_SP"); + coalAmount = (FloatDataPoint) DataPoint.getDataPointOnListFromLabel("COAL_AMOUNT"); + gridVoltage = (FloatDataPoint) DataPoint.getDataPointOnListFromLabel("GRID_U_FLOAT"); + } + + float getValue(FloatDataPoint fdp){ + if(fdp == null) return 0f; + return fdp.getValue(); + } + + // Emergency data points + private FloatDataPoint gridVoltage; + + // Ideal goal points variables + private float igpBatteryLevel = 0f; + private float igpCoalAmount = 0f; + + // Time variables + private int day = 0; + private float previousTime; + final float kpiFactory = 1f; + final float kpiCoal = 1f; + + + + + private float getTimeOfTheDay(){ + float timeOfTheDay = getValue(clock); + timeOfTheDay %= 1; + timeOfTheDay *= 24; + return timeOfTheDay; + } + + private float getProducerPower(){ + float producerPower = 0f; + FloatDataPoint solar = (FloatDataPoint) DataPoint.getDataPointOnListFromLabel("SOLAR_P_FLOAT"); + FloatDataPoint wind = (FloatDataPoint) DataPoint.getDataPointOnListFromLabel("WIND_P_FLOAT"); + FloatDataPoint coal = (FloatDataPoint) DataPoint.getDataPointOnListFromLabel("COAL_P_FLOAT"); + + producerPower += getValue(solar); + producerPower += getValue(wind); + producerPower += getValue(coal); + + return producerPower; + } + + private float getConsumerPower(){ + float consumerPower = 0f; + FloatDataPoint home = (FloatDataPoint) DataPoint.getDataPointOnListFromLabel("HOME_P_FLOAT"); + FloatDataPoint factory = (FloatDataPoint) DataPoint.getDataPointOnListFromLabel("FACTORY_P_FLOAT"); + FloatDataPoint bunker = (FloatDataPoint) DataPoint.getDataPointOnListFromLabel("BUNKER_P_FLOAT"); + + consumerPower += getValue(home); + consumerPower += getValue(factory); + consumerPower += getValue(bunker); + return consumerPower; + } + + private boolean checkIfGridIsFine(){ + boolean gridIsFine = true; + + // Grid voltage is too high + if(getValue(gridVoltage) > (GRID_VOLTAGE_MAX-GRID_VOLTAGE_TOLERANCE)) { + gridIsFine = false; + new BooleanDataPoint("SOLAR_CONNECT_ST", true).setValue(false); + new BooleanDataPoint("WIND_CONNECT_ST", true).setValue(false); + remoteCoalSp.setValue(0f); + if(getValue(gridVoltage) > GRID_VOLTAGE_MAX) { + remoteFactorySp.setValue(1f); + } + } + + // Grid voltage is too low + if(getValue(gridVoltage) < (GRID_VOLTAGE_MIN+GRID_VOLTAGE_TOLERANCE)) { + gridIsFine = false; + new BooleanDataPoint("SOLAR_CONNECT_ST", true).setValue(true); + new BooleanDataPoint("WIND_CONNECT_ST", true).setValue(true); + remoteCoalSp.setValue(1f); + if(getValue(gridVoltage) < GRID_VOLTAGE_MIN) { + remoteFactorySp.setValue(0f); + } + } + + return gridIsFine; + } + + private int getPeriodOfDay(){ + float timeOfTheDay = getTimeOfTheDay(); + + // 0 = Night, 1 = Morning, 2 = Afternoon + int periodOfDay = 0; + if(timeOfTheDay >= 0 && timeOfTheDay < 6) periodOfDay = 1; // Night + if(timeOfTheDay >= 6 && timeOfTheDay < 12) periodOfDay = 2; // Morning + if(timeOfTheDay >= 12 && timeOfTheDay < 18) periodOfDay = 3; // Afternoon + if(timeOfTheDay >= 18 && timeOfTheDay < 24) periodOfDay = 4; // Evening + + return periodOfDay; + } + + private void defineIGPbatteryLevel(){ + + switch (getPeriodOfDay()){ + case 1: // Night + if(getTimeOfTheDay() < 5f) igpBatteryLevel = BATTERY_LEVEL_HIGH-0.5f; + else igpBatteryLevel = BATTERY_LEVEL_LOW+0.2f; + break; + case 2: // Morning + igpBatteryLevel = BATTERY_LEVEL_LOW; + break; + case 3: // Afternoon + igpBatteryLevel = BATTERY_LEVEL_HIGH; + break; + case 4: // Evening + if(getTimeOfTheDay() < 21f) igpBatteryLevel = BATTERY_LEVEL_HIGH-0.2f; + else igpBatteryLevel = BATTERY_LEVEL_HIGH-0.4f; + break; + default: + break; + } + } + + private void defineIGPcoalAmount(int day){ + float igpCoalAmountForTheDay = 1f; + switch (getPeriodOfDay()){ + case 1: // Night + if(getTimeOfTheDay() < 5f) igpCoalAmountForTheDay = 0.93f; + else igpCoalAmountForTheDay = 0.8f; + break; + case 2: // Morning + igpCoalAmountForTheDay = 0.7f; + break; + case 3: // Afternoon + igpCoalAmountForTheDay = 0.6f; + break; + case 4: // Evening + if(getTimeOfTheDay() < 21f) igpCoalAmountForTheDay = 0.5f; + else igpCoalAmountForTheDay = 0.3f; + break; + default: + break; + } + igpCoalAmountForTheDay += day; + igpCoalAmountForTheDay /= 3f; + + + } + + + public SmartControl() { + defineDataPoints(); + + previousTime = getTimeOfTheDay(); + + // start the solar and wind power plants + new BooleanDataPoint("REMOTE_SOLAR_SW", true).setValue(true); + new BooleanDataPoint("REMOTE_WIND_SW", true).setValue(true); + + + } + + public boolean run() { + defineDataPoints(); + float spCoal = getValue(remoteCoalSp); + float spFactory = getValue(remoteFactorySp); + + if (getTimeOfTheDay() < previousTime) { + previousTime = getTimeOfTheDay(); + day++; + day %= 3; + } + defineIGPbatteryLevel(); + defineIGPcoalAmount(day); + + if (getValue(battChrg) < igpBatteryLevel) { + spFactory -= (igpBatteryLevel - getValue(battChrg)) * kpiFactory; + spCoal += (igpBatteryLevel - getValue(battChrg)) * kpiCoal; + } + + if (getValue(battChrg) > igpBatteryLevel) { + spFactory += (getValue(battChrg) - igpBatteryLevel) * kpiFactory; + spCoal -= (getValue(battChrg) - igpBatteryLevel) * kpiCoal; + } + + if (getValue(coalAmount) < igpCoalAmount) { + spFactory -= (igpCoalAmount - getValue(coalAmount)) * kpiFactory; + spCoal += (igpCoalAmount - getValue(coalAmount)) * kpiCoal; + } + + if (getValue(coalAmount) > igpCoalAmount) { + spFactory += (getValue(coalAmount) - igpCoalAmount) * kpiFactory; + spCoal -= (getValue(coalAmount) - igpCoalAmount) * kpiCoal; + } + + if (spFactory > 1f) spFactory = 1f; + if (spFactory < 0f) spFactory = 0f; + if (spCoal > 1f) spCoal = 1f; + if (spCoal < 0f) spCoal = 0f; + + remoteFactorySp.setValue(spFactory); + remoteCoalSp.setValue(spCoal); + + return checkIfGridIsFine(); + } +} diff --git a/src/main/java/ch/hevs/isi/field/SmartControl.java b/src/main/java/ch/hevs/isi/field/SmartControl.java deleted file mode 100644 index 72ac3c7..0000000 --- a/src/main/java/ch/hevs/isi/field/SmartControl.java +++ /dev/null @@ -1,64 +0,0 @@ -package ch.hevs.isi.field; - -import ch.hevs.isi.core.DataPoint; -import ch.hevs.isi.core.FloatDataPoint; - -public class SmartControl { - - public SmartControl(){ - - //time - FloatDataPoint clockFloat = (FloatDataPoint) DataPoint.getDataPointFromLabel("CLOCK_FLOAT"); - int timeOfTheDay = 0; //0=default 1=beginning 2=day 3=end 4=night - if (clockFloat.getValue() > 0.2f && clockFloat.getValue() <= 0.3f) { //beginning of the day - timeOfTheDay =1; - } - if (clockFloat.getValue() > 0.3f && clockFloat.getValue() <= 0.7f){ //day - timeOfTheDay = 2; - } - if (clockFloat.getValue() > 0.7f && clockFloat.getValue() <= 0.8f){ //end of the day - timeOfTheDay = 3; - } - if (clockFloat.getValue() <= 0.2f && clockFloat.getValue() > 0.8f){ //night - timeOfTheDay = 4; - } - - - //Factory and coal - FloatDataPoint battChrgFloat = (FloatDataPoint) DataPoint.getDataPointFromLabel("BATT_CHRG_FLOAT"); - FloatDataPoint remoteCoalSp = (FloatDataPoint) DataPoint.getDataPointFromLabel("REMOTE_COAL_SP"); - FloatDataPoint remoteFactorySp = (FloatDataPoint) DataPoint.getDataPointFromLabel("REMOTE_FACTORY_SP"); - FloatDataPoint coalAmount = (FloatDataPoint) DataPoint.getDataPointFromLabel("COAL_AMOUNT"); - - if (battChrgFloat.getValue() <= 0.4f){ //if battery level is under 40 % - if(coalAmount.getValue() <= 0.5f){ - remoteCoalSp.setValue(0.5f); //start the coal power plant with 50% - }else{ - remoteCoalSp.setValue(1f); //start the coal power plant with 100% - } - remoteFactorySp.setValue(0f); //stop the consumption of the factory - } - if (battChrgFloat.getValue() > 0.4f && battChrgFloat.getValue() < 0.6f){ //if battery lever is between 40% and 60% - remoteCoalSp.setValue(0f); //stop the coal power plant - remoteFactorySp.setValue(0f); //stop the consumption of the factory - } - if(battChrgFloat.getValue() >= 0.6f){ //if battery level is over 60 % - remoteCoalSp.setValue(0f); //stop the coal power plant - remoteFactorySp.setValue(1f); //start the consumption of the factory - } - - //Solar - FloatDataPoint weatherFloat = (FloatDataPoint) DataPoint.getDataPointFromLabel("WEATHER_FLOAT"); - FloatDataPoint weatherCountdownFloat = (FloatDataPoint) DataPoint.getDataPointFromLabel("WEATHER_COUNTDOWN_FLOAT"); - FloatDataPoint weatherForecastFloat = (FloatDataPoint) DataPoint.getDataPointFromLabel("WEATHER_FORECAST_FLOAT"); - - /** TODO Solar Smartcontrol - * check the value of weatherForecastFloat and weatherFloat - */ - - //Wind - /** TODO Wind Smartcontrol - * - */ - } -}