diff --git a/README.md b/README.md index 2522fe9..2a6450c 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,12 @@ Enter the dependence of the cell power on temperature, usually in the range of - Enter the size of your solar panel. #### Diffuse radiation efficiency [%] -Specify the efficiency of your solar power plant for diffuse radiation. When pointing up, it should be around 100%, but when pointing towards the horizon, it may be around 50%, depending on reflections and other factors. +Specify the efficiency of your solar power plant for diffuse radiation. When pointing up, it should be around 100%, but when pointing towards the horizon, it may be 50% or less, depending on the environment. +You probably need to optimize this parameter. + +#### Albedo [0..1] +Specify the average albedo for your environment to take reflections into account. The value ranges from 0 (all radiation is absorbed) to 1 (all radiation is reflected). +Examples: Fresh snow: 0.8, green gras: 0.25, asphalt: 0.1 You probably need to optimize this parameter. #### Inverter power [W] diff --git a/app/src/main/assets/help/help-de.html b/app/src/main/assets/help/help-de.html index 9881cab..ced5f7d 100644 --- a/app/src/main/assets/help/help-de.html +++ b/app/src/main/assets/help/help-de.html @@ -41,7 +41,12 @@ Geben Sie die Abhängigkeit der Zellleistung von der Temperatur an, normalerweis Geben Sie die Größe Ihres Solarmoduls an.

Effizienz diffuse Strahlung [%]

-Geben Sie die Effizienz Ihrer Solaranlage für diffuse Strahlung an. Wenn sie nach oben gerichtet ist, sollte sie etwa 100% betragen, aber wenn sie in Richtung Horizont gerichtet ist, kann sie je nach Reflexionen und anderen Faktoren etwa 50% betragen. +Geben Sie die Effizienz Ihrer Solaranlage für diffuse Strahlung an. Wenn sie nach oben gerichtet ist, sollte sie etwa 100% betragen, aber wenn sie in Richtung Horizont gerichtet ist, beträgt Sie 50% oder weniger - abhängig von der Umgebung. +Sie müssen diesen Parameter wahrscheinlich optimieren. + +

Albedo [0..1]

+Geben Sie die durchschnittliche Albedo für Ihre Umgebung an, um Reflexionen zu berücksichtigen. Der Wertebereich geht von 0 (alle Strahlung wird absorbiert) bis 1 (alle Strahlung wird reflektiert). +Beispiele: Frischer Schnee: 0.8, grünes Gras: 0.25, Asphalt: 0.1 Sie müssen diesen Parameter wahrscheinlich optimieren.

Wechselrichterleistung [W]

diff --git a/app/src/main/assets/help/help-en.html b/app/src/main/assets/help/help-en.html index e9c47e0..371f18e 100644 --- a/app/src/main/assets/help/help-en.html +++ b/app/src/main/assets/help/help-en.html @@ -41,7 +41,12 @@ Enter the dependence of the cell power on temperature, usually in the range of - Enter the size of your solar panel.

Diffuse radiation efficiency [%]

-Specify the efficiency of your solar power plant for diffuse radiation. When pointing up, it should be around 100%, but when pointing towards the horizon, it may be around 50%, depending on reflections and other factors. +Specify the efficiency of your solar power plant for diffuse radiation. When pointing up, it should be around 100%, but when pointing towards the horizon, it may be 50% or less, depending on the environment. +You probably need to optimize this parameter. + +

Albedo [0..1]

+Specify the average albedo for your environment to take reflections into account. The value ranges from 0 (all radiation is absorbed) to 1 (all radiation is reflected). +Examples: Fresh snow: 0.8, green gras: 0.25, asphalt: 0.1 You probably need to optimize this parameter.

Inverter power [W]

diff --git a/app/src/main/java/org/woheller69/weather/SolarPowerPlant.java b/app/src/main/java/org/woheller69/weather/SolarPowerPlant.java index f59c390..9111da0 100644 --- a/app/src/main/java/org/woheller69/weather/SolarPowerPlant.java +++ b/app/src/main/java/org/woheller69/weather/SolarPowerPlant.java @@ -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){ diff --git a/app/src/main/java/org/woheller69/weather/activities/ManageLocationsActivity.java b/app/src/main/java/org/woheller69/weather/activities/ManageLocationsActivity.java index 289192b..7aed91a 100644 --- a/app/src/main/java/org/woheller69/weather/activities/ManageLocationsActivity.java +++ b/app/src/main/java/org/woheller69/weather/activities/ManageLocationsActivity.java @@ -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, diff --git a/app/src/main/java/org/woheller69/weather/database/CityToWatch.java b/app/src/main/java/org/woheller69/weather/database/CityToWatch.java index aef9b23..b66d91a 100644 --- a/app/src/main/java/org/woheller69/weather/database/CityToWatch.java +++ b/app/src/main/java/org/woheller69/weather/database/CityToWatch.java @@ -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; } } \ No newline at end of file diff --git a/app/src/main/java/org/woheller69/weather/database/HourlyForecast.java b/app/src/main/java/org/woheller69/weather/database/HourlyForecast.java index 2a6cdfe..737f131 100644 --- a/app/src/main/java/org/woheller69/weather/database/HourlyForecast.java +++ b/app/src/main/java/org/woheller69/weather/database/HourlyForecast.java @@ -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; } } diff --git a/app/src/main/java/org/woheller69/weather/database/SQLiteHelper.java b/app/src/main/java/org/woheller69/weather/database/SQLiteHelper.java index 80699f8..83cb220 100644 --- a/app/src/main/java/org/woheller69/weather/database/SQLiteHelper.java +++ b/app/src/main/java/org/woheller69/weather/database/SQLiteHelper.java @@ -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 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())}); diff --git a/app/src/main/java/org/woheller69/weather/ui/RecycleList/RecyclerOverviewListAdapter.java b/app/src/main/java/org/woheller69/weather/ui/RecycleList/RecyclerOverviewListAdapter.java index 3f09b47..d89d0d6 100644 --- a/app/src/main/java/org/woheller69/weather/ui/RecycleList/RecyclerOverviewListAdapter.java +++ b/app/src/main/java/org/woheller69/weather/ui/RecycleList/RecyclerOverviewListAdapter.java @@ -130,7 +130,7 @@ public class RecyclerOverviewListAdapter extends RecyclerView.Adapter + + + + + + Klonen ENTFERNT:\u0020\u0020%s WIEDERHERSTELLEN + Albedo [0..1] diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 571e466..1b9aa92 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -110,4 +110,5 @@ Clone REMOVED:\u0020\u0020%s UNDO + Albedo [0..1] diff --git a/fastlane/metadata/android/de-DE/full_description.txt b/fastlane/metadata/android/de-DE/full_description.txt index 924f785..5782c9e 100644 --- a/fastlane/metadata/android/de-DE/full_description.txt +++ b/fastlane/metadata/android/de-DE/full_description.txt @@ -1,7 +1,6 @@ solXpect prognostiziert den Ertrag Ihrer PV Anlage -Diese App nimmt direkte und diffuse Strahlungsdaten von Open-Meteo.com, berechnet die Position -der Sonne und projiziert die Strahlung auf Ihr Solarpanel. +Diese App nimmt direkte und diffuse Strahlungsdaten von Open-Meteo.com, berechnet die Position der Sonne und projiziert die Strahlung auf Ihr Solarpanel. Es zeigt die geschätzte Energieproduktion für die nächsten Stunden und bis zu 16 Tage an. Features: diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index eb01496..a00d55f 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -1,7 +1,6 @@ solXpect forecasts the output of your solar power plant -This app takes direct and diffuse radiation data from Open-Meteo.com, calculates the position -of the sun and projects the radiation on your solar panel. +This app takes direct and diffuse radiation data from Open-Meteo.com, calculates the position of the sun and projects the radiation on your solar panel. It shows the estimated energy production for the next hours and up to 16 days. Features: