1
0
This repository has been archived on 2024-01-25. You can view files and clone it, but cannot push or open issues or pull requests.

242 lines
8.3 KiB
Java

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