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(); } }