Take reflections into account

This commit is contained in:
woheller69 2023-05-02 12:14:34 +02:00
parent 6fcdccfa4f
commit 07fb5f0b9e
16 changed files with 79 additions and 19 deletions

View file

@ -9,6 +9,7 @@ import java.time.ZoneId;
import java.time.ZonedDateTime;
public class SolarPowerPlant {
double albedo;
double latitude;
double longitude;
double cellsMaxPower;
@ -23,7 +24,8 @@ public class SolarPowerPlant {
private final int[] shadingElevation;
private final int[] shadingOpacity;
public SolarPowerPlant(double latitude, double longitude, double cellsMaxPower, double cellsArea, double cellsEfficiency, double cellsTempCoeff, double diffuseEfficiency, double inverterPowerLimit, double inverterEfficiency, double azimuthAngle, double tiltAngle, int[] shadingElevation, int[] shadingOpacity ) {
public SolarPowerPlant(double latitude, double longitude, double cellsMaxPower, double cellsArea, double cellsEfficiency, double cellsTempCoeff, double diffuseEfficiency, double inverterPowerLimit, double inverterEfficiency, double azimuthAngle, double tiltAngle, int[] shadingElevation, int[] shadingOpacity, double albedo ) {
this.albedo = albedo;
this.latitude = latitude;
this.longitude = longitude;
this.cellsMaxPower = cellsMaxPower;
@ -40,7 +42,7 @@ public class SolarPowerPlant {
}
public float getPower(double solarPowerNormal, double solarPowerDiffuse, long epochTimeSeconds, double ambientTemperature) {
public float getPower(double solarPowerNormal, double solarPowerDiffuse, double shortwaveRadiation, long epochTimeSeconds, double ambientTemperature) {
Instant i = Instant.ofEpochSecond(epochTimeSeconds); //currentTimeMillis is in GMT
ZonedDateTime dateTime = ZonedDateTime.ofInstant(i, ZoneId.of("GMT"));
@ -73,7 +75,7 @@ public class SolarPowerPlant {
}
}
double totalRadiationOnCell = solarPowerNormal * efficiency + solarPowerDiffuse * diffuseEfficiency; //flat plate equivalent of the solar irradiance
double totalRadiationOnCell = solarPowerNormal * efficiency + solarPowerDiffuse * diffuseEfficiency + shortwaveRadiation * (0.5-0.5*Math.cos(tiltAngle/180*Math.PI)) * albedo; //flat plate equivalent of the solar irradiance
double cellTemperature = calcCellTemperature(ambientTemperature,totalRadiationOnCell);
double dcPower;
if (cellsEfficiency!=0 && cellsArea!=0){

View file

@ -189,6 +189,7 @@ public class ManageLocationsActivity extends NavigationActivity {
EditText editCellsEfficiency = (EditText) dialogView.findViewById(R.id.EditLocation_Cell_Efficiency);
EditText editCellsTempCoeff = (EditText) dialogView.findViewById(R.id.EditLocation_Cell_Temp_Coeff);
EditText editDiffuseEfficiency = (EditText) dialogView.findViewById(R.id.EditLocation_Diffuse_Efficiency);
EditText editAlbedo = (EditText) dialogView.findViewById(R.id.EditLocation_Albedo);
EditText editInverterPowerLimit = (EditText) dialogView.findViewById(R.id.EditLocation_Inverter_Power_Limit);
EditText editInverterEfficiency = (EditText) dialogView.findViewById(R.id.EditLocation_Inverter_Efficiency);
@ -209,6 +210,8 @@ public class ManageLocationsActivity extends NavigationActivity {
editCellsTempCoeff.setFilters(new InputFilter[]{ new InputFilterMinMax(-100, 100)});
editDiffuseEfficiency.setText(Float.toString(city.getDiffuseEfficiency()));
editDiffuseEfficiency.setFilters(new InputFilter[]{ new InputFilterMinMax(0, 100)});
editAlbedo.setText(Float.toString(city.getAlbedo()));
editAlbedo.setFilters(new InputFilter[]{ new InputFilterMinMax(0,1)});
editInverterPowerLimit.setText(Float.toString(city.getInverterPowerLimit()));
editInverterEfficiency.setText(Float.toString(city.getInverterEfficiency()));
editInverterEfficiency.setFilters(new InputFilter[]{ new InputFilterMinMax(0, 100)});
@ -221,7 +224,7 @@ public class ManageLocationsActivity extends NavigationActivity {
@Override
public void afterTextChanged(Editable editable) {
float tilt = Float.parseFloat(!editTilt.getText().toString().isEmpty() ? editTilt.getText().toString() : "0");
int diffuseEfficiency = (int) (100-50 * tilt/90);
int diffuseEfficiency = (int) ( 50 + 50* Math.cos(tilt/180*Math.PI));
editDiffuseEfficiency.setText(Float.toString((float) diffuseEfficiency));
}
});
@ -242,6 +245,7 @@ public class ManageLocationsActivity extends NavigationActivity {
Float.parseFloat(editCellsEfficiency.getText().toString().isEmpty() ? "0" : editCellsEfficiency.getText().toString()),
Float.parseFloat(editCellsTempCoeff.getText().toString().isEmpty() ? "0" : editCellsTempCoeff.getText().toString()),
Float.parseFloat(editDiffuseEfficiency.getText().toString().isEmpty() ? "0" : editDiffuseEfficiency.getText().toString()),
Float.parseFloat(editAlbedo.getText().toString().isEmpty() ? "0" : editAlbedo.getText().toString()),
Float.parseFloat(editInverterPowerLimit.getText().toString().isEmpty() ? "0" : editInverterPowerLimit.getText().toString()),
Float.parseFloat(editInverterEfficiency.getText().toString().isEmpty() ? "0" : editInverterEfficiency.getText().toString()),
shadingElevation,
@ -277,6 +281,7 @@ public class ManageLocationsActivity extends NavigationActivity {
Float.parseFloat(editCellsEfficiency.getText().toString().isEmpty() ? "0" : editCellsEfficiency.getText().toString()),
Float.parseFloat(editCellsTempCoeff.getText().toString().isEmpty() ? "0" : editCellsTempCoeff.getText().toString()),
Float.parseFloat(editDiffuseEfficiency.getText().toString().isEmpty() ? "0" : editDiffuseEfficiency.getText().toString()),
Float.parseFloat(editAlbedo.getText().toString().isEmpty() ? "0" : editAlbedo.getText().toString()),
Float.parseFloat(editInverterPowerLimit.getText().toString().isEmpty() ? "0" : editInverterPowerLimit.getText().toString()),
Float.parseFloat(editInverterEfficiency.getText().toString().isEmpty() ? "0" : editInverterEfficiency.getText().toString()),
shadingElevation,

View file

@ -23,6 +23,7 @@ public class CityToWatch {
private float inverterEfficiency;
private float azimuthAngle;
private float tiltAngle;
private float albedo;
private int rank;
private int[] shadingElevation = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
private int[] shadingOpacity = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
@ -46,6 +47,7 @@ public class CityToWatch {
this.inverterEfficiency = 95.0f;
this.azimuthAngle = 170.0f;
this.tiltAngle = 90.0f;
this.albedo = 0f;
}
@ -192,4 +194,8 @@ public class CityToWatch {
public void setCellsTempCoeff(float cellsTempCoeff) {
this.cellsTempCoeff = cellsTempCoeff;
}
public float getAlbedo() { return this.albedo; }
public void setAlbedo (float albedo) { this.albedo = albedo; }
}

View file

@ -15,6 +15,7 @@ public class HourlyForecast {
private int weatherID;
private float directRadiationNormal;
private float diffuseRadiation;
private float shortwaveRadiation;
private float power;
private String city_name;
@ -104,4 +105,8 @@ public class HourlyForecast {
public void setDiffuseRadiation(float diffuseRadiation) { this.diffuseRadiation = diffuseRadiation; }
public void setPower(float power) { this.power = power; }
public void setShortwaveRadiation(float shortwaveRadiation) { this.shortwaveRadiation = shortwaveRadiation; }
public float getShortwaveRadiation() { return this.shortwaveRadiation; }
}

View file

@ -20,7 +20,7 @@ import static androidx.core.app.JobIntentService.enqueueWork;
*/
public class SQLiteHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 2;
private static final int DATABASE_VERSION = 3;
private Context context;
private List<City> allCities = new ArrayList<>();
@ -54,6 +54,7 @@ public class SQLiteHelper extends SQLiteOpenHelper {
private static final String CITIES_TO_WATCH_SHADING_ELEVATION = "shading_elevation";
private static final String CITIES_TO_WATCH_SHADING_OPACITY = "shading_opacity";
private static final String CITIES_TO_WATCH_CELLS_TEMP_COEFF = "cells_temp_coeff";
private static final String CITIES_TO_WATCH_ALBEDO = "albedo";
//Names of columns in TABLE_FORECAST
private static final String FORECAST_ID = "forecast_id";
@ -137,7 +138,8 @@ public class SQLiteHelper extends SQLiteOpenHelper {
CITIES_TO_WATCH_TILT_ANGLE + " REAL NOT NULL," +
CITIES_TO_WATCH_SHADING_ELEVATION + " VARCHAR(255) NOT NULL," +
CITIES_TO_WATCH_SHADING_OPACITY + " VARCHAR(255) NOT NULL," +
CITIES_TO_WATCH_CELLS_TEMP_COEFF + " REAL NOT NULL)";
CITIES_TO_WATCH_CELLS_TEMP_COEFF + " REAL NOT NULL," +
CITIES_TO_WATCH_ALBEDO + " REAL NOT NULL)";
public static SQLiteHelper getInstance(Context context) {
if (instance == null && context != null) {
@ -166,6 +168,8 @@ public class SQLiteHelper extends SQLiteOpenHelper {
case 1:
db.execSQL("ALTER TABLE "+TABLE_CITIES_TO_WATCH+" ADD COLUMN "+CITIES_TO_WATCH_CELLS_TEMP_COEFF+" REAL DEFAULT 0");
// we want both updates, so no break statement here...
case 2:
db.execSQL("ALTER TABLE "+TABLE_CITIES_TO_WATCH+" ADD COLUMN "+CITIES_TO_WATCH_ALBEDO+" REAL DEFAULT 0");
}
}
@ -194,6 +198,7 @@ public class SQLiteHelper extends SQLiteOpenHelper {
values.put(CITIES_TO_WATCH_SHADING_ELEVATION,city.getShadingElevationString());
values.put(CITIES_TO_WATCH_SHADING_OPACITY,city.getShadingOpacityString());
values.put(CITIES_TO_WATCH_CELLS_TEMP_COEFF,city.getCellsTempCoeff());
values.put(CITIES_TO_WATCH_ALBEDO,city.getAlbedo());
long id=database.insert(TABLE_CITIES_TO_WATCH, null, values);
@ -228,6 +233,7 @@ public class SQLiteHelper extends SQLiteOpenHelper {
", " + CITIES_TO_WATCH_SHADING_ELEVATION +
", " + CITIES_TO_WATCH_SHADING_OPACITY +
", " + CITIES_TO_WATCH_CELLS_TEMP_COEFF +
", " + CITIES_TO_WATCH_ALBEDO +
", " + CITIES_TO_WATCH_COLUMN_RANK +
" FROM " + TABLE_CITIES_TO_WATCH +
" WHERE " + CITIES_TO_WATCH_CITY_ID + " = ?", arguments);
@ -251,7 +257,8 @@ public class SQLiteHelper extends SQLiteOpenHelper {
cityToWatch.setShadingElevation(cursor.getString(13));
cityToWatch.setShadingOpacity(cursor.getString(14));
cityToWatch.setCellsTempCoeff(Float.parseFloat(cursor.getString(15)));
cityToWatch.setRank(Integer.parseInt(cursor.getString(16)));
cityToWatch.setAlbedo(Float.parseFloat(cursor.getString(16)));
cityToWatch.setRank(Integer.parseInt(cursor.getString(17)));
cursor.close();
}
@ -283,6 +290,7 @@ public class SQLiteHelper extends SQLiteOpenHelper {
", " + CITIES_TO_WATCH_SHADING_ELEVATION +
", " + CITIES_TO_WATCH_SHADING_OPACITY +
", " + CITIES_TO_WATCH_CELLS_TEMP_COEFF +
", " + CITIES_TO_WATCH_ALBEDO +
", " + CITIES_TO_WATCH_COLUMN_RANK +
" FROM " + TABLE_CITIES_TO_WATCH
, new String[]{});
@ -308,7 +316,8 @@ public class SQLiteHelper extends SQLiteOpenHelper {
cityToWatch.setShadingElevation(cursor.getString(13));
cityToWatch.setShadingOpacity(cursor.getString(14));
cityToWatch.setCellsTempCoeff(Float.parseFloat(cursor.getString(15)));
cityToWatch.setRank(Integer.parseInt(cursor.getString(16)));
cityToWatch.setAlbedo(Float.parseFloat(cursor.getString(16)));
cityToWatch.setRank(Integer.parseInt(cursor.getString(17)));
cityToWatchList.add(cityToWatch);
} while (cursor.moveToNext());
@ -339,6 +348,7 @@ public class SQLiteHelper extends SQLiteOpenHelper {
values.put(CITIES_TO_WATCH_SHADING_ELEVATION,cityToWatch.getShadingElevationString());
values.put(CITIES_TO_WATCH_SHADING_OPACITY,cityToWatch.getShadingOpacityString());
values.put(CITIES_TO_WATCH_CELLS_TEMP_COEFF,cityToWatch.getCellsTempCoeff());
values.put(CITIES_TO_WATCH_ALBEDO,cityToWatch.getAlbedo());
database.update(TABLE_CITIES_TO_WATCH, values, CITIES_TO_WATCH_ID + " = ?",
new String[]{String.valueOf(cityToWatch.getId())});

View file

@ -130,7 +130,7 @@ public class RecyclerOverviewListAdapter extends RecyclerView.Adapter<ItemViewHo
public CityToWatch getCitytoWatch(int position){
return cities.get(position);
}
public void updateCity(CityToWatch cityToWatch, String cityName, float latitude, float longitude, float azimuth, float tilt, float cellsMaxPower, float cellsArea, float cellsEfficiency, float cellsTempCoeff, float diffuseEfficiency, float inverterPowerLimit, float inverterEfficiency, int[] shadingElevation, int[] shadingOpacity) {
public void updateCity(CityToWatch cityToWatch, String cityName, float latitude, float longitude, float azimuth, float tilt, float cellsMaxPower, float cellsArea, float cellsEfficiency, float cellsTempCoeff, float diffuseEfficiency, float albedo, float inverterPowerLimit, float inverterEfficiency, int[] shadingElevation, int[] shadingOpacity) {
cityToWatch.setCityName(cityName);
cityToWatch.setLatitude(latitude);
cityToWatch.setLongitude(longitude);
@ -141,6 +141,7 @@ public class RecyclerOverviewListAdapter extends RecyclerView.Adapter<ItemViewHo
cityToWatch.setCellsEfficiency(cellsEfficiency);
cityToWatch.setCellsTempCoeff(cellsTempCoeff);
cityToWatch.setDiffuseEfficiency(diffuseEfficiency);
cityToWatch.setAlbedo(albedo);
cityToWatch.setInverterPowerLimit(inverterPowerLimit);
cityToWatch.setInverterEfficiency(inverterEfficiency);
cityToWatch.setShadingElevation(shadingElevation);

View file

@ -69,12 +69,13 @@ public class OMDataExtractor implements IDataExtractor {
JSONArray tempArray = jsonData.has("temperature_2m") ? jsonData.getJSONArray("temperature_2m") : null;
JSONArray directRadiationArray = jsonData.has("direct_normal_irradiance") ? jsonData.getJSONArray("direct_normal_irradiance") : null;
JSONArray diffuseRadiationArray = jsonData.has("diffuse_radiation") ? jsonData.getJSONArray("diffuse_radiation") : null;
JSONArray shortwaveRadiationArray = jsonData.has("shortwave_radiation") ? jsonData.getJSONArray("shortwave_radiation") : null;
//TODO get Data for power plant from city to Watch
SQLiteHelper dbhelper = SQLiteHelper.getInstance(context);
CityToWatch city = dbhelper.getCityToWatch(cityID);
SolarPowerPlant spp = new SolarPowerPlant(city.getLatitude(), city.getLongitude(), city.getCellsMaxPower(), city.getCellsArea(), city.getCellsEfficiency(), city.getCellsTempCoeff(), city.getDiffuseEfficiency(), city.getInverterPowerLimit(), city.getInverterEfficiency(), city.getAzimuthAngle(), city.getTiltAngle(), city.getShadingElevation(), city.getShadingOpacity());
SolarPowerPlant spp = new SolarPowerPlant(city.getLatitude(), city.getLongitude(), city.getCellsMaxPower(), city.getCellsArea(), city.getCellsEfficiency(), city.getCellsTempCoeff(), city.getDiffuseEfficiency(), city.getInverterPowerLimit(), city.getInverterEfficiency(), city.getAzimuthAngle(), city.getTiltAngle(), city.getShadingElevation(), city.getShadingOpacity(), city.getAlbedo());
IApiToDatabaseConversion conversion = new OMToDatabaseConversion();
@ -87,7 +88,8 @@ public class OMDataExtractor implements IDataExtractor {
if (weathercodeArray!=null && !weathercodeArray.isNull(i)) hourlyForecast.setWeatherID(conversion.convertWeatherCategory(weathercodeArray.getString(i)));
if (directRadiationArray!=null && !directRadiationArray.isNull(i)) hourlyForecast.setDirectRadiationNormal((float) directRadiationArray.getDouble(i));
if (diffuseRadiationArray!=null && !diffuseRadiationArray.isNull(i)) hourlyForecast.setDiffuseRadiation((float) diffuseRadiationArray.getDouble(i));
hourlyForecast.setPower(spp.getPower(hourlyForecast.getDirectRadiationNormal(), hourlyForecast.getDiffuseRadiation(), timeArray.getLong(i)-1800, ambientTemperature)); //use solar position 1/2h earlier for calculation of average power in preceding hour
if (shortwaveRadiationArray!=null && !shortwaveRadiationArray.isNull(i)) hourlyForecast.setShortwaveRadiation((float) shortwaveRadiationArray.getDouble(i));
hourlyForecast.setPower(spp.getPower(hourlyForecast.getDirectRadiationNormal(), hourlyForecast.getDiffuseRadiation(), hourlyForecast.getShortwaveRadiation(), timeArray.getLong(i)-1800, ambientTemperature)); //use solar position 1/2h earlier for calculation of average power in preceding hour
hourlyForecasts.add(hourlyForecast);
}
return hourlyForecasts;

View file

@ -24,7 +24,7 @@ public class OMHttpRequest {
SharedPreferences sharedPreferences=PreferenceManager.getDefaultSharedPreferences(context);
return String.format(
"%sforecast?latitude=%s&longitude=%s&forecast_days=%s&hourly=temperature_2m,diffuse_radiation,direct_normal_irradiance,weathercode&daily=weathercode,sunrise,sunset,&timeformat=unixtime&timezone=auto",
"%sforecast?latitude=%s&longitude=%s&forecast_days=%s&hourly=temperature_2m,diffuse_radiation,direct_normal_irradiance,shortwave_radiation,weathercode&daily=weathercode,sunrise,sunset,&timeformat=unixtime&timezone=auto",
BuildConfig.BASE_URL,
lat,
lon,