fix issue:refresh button not rotating

new feature: show sum
new feature: clone location
update Readme and help
This commit is contained in:
woheller69 2023-04-18 16:54:51 +02:00
parent 38295c65e1
commit 2ae9a055eb
16 changed files with 274 additions and 82 deletions

View file

@ -10,6 +10,10 @@ 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. It shows the estimated energy production for the next hours and up to 16 days.
The hourly values are calculated for the preceding hour. So if there are 150 Wh shown at 11:00 this means you can expect 150 Wh between 10:00 and 11:00. The hourly values are calculated for the preceding hour. So if there are 150 Wh shown at 11:00 this means you can expect 150 Wh between 10:00 and 11:00.
If you have several modules pointing in different directions you can define them as separate locations and switch on 'show sum' in preferences. Then
all locations with same latitude/longitude are summarized. In this case you should define your location names as 'myPV | part1', 'myPV | part2', etc.
In 'show sum' mode the location is then shown as 'myPV' and '|' is taken as delimiter in this case.
<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/01.png" width="150"/> <img src="fastlane/metadata/android/en-US/images/phoneScreenshots/02.png" width="150"/> <img src="fastlane/metadata/android/en-US/images/phoneScreenshots/03.png" width="150"/> <img src="fastlane/metadata/android/en-US/images/phoneScreenshots/04.png" width="150"/> <img src="fastlane/metadata/android/en-US/images/phoneScreenshots/01.png" width="150"/> <img src="fastlane/metadata/android/en-US/images/phoneScreenshots/02.png" width="150"/> <img src="fastlane/metadata/android/en-US/images/phoneScreenshots/03.png" width="150"/> <img src="fastlane/metadata/android/en-US/images/phoneScreenshots/04.png" width="150"/>
@ -74,6 +78,7 @@ The app uses:
- Map data from OpenStreetMap, licensed under the Open Data Commons Open Database License (ODbL) by the OpenStreetMap Foundation (OSMF) (https://www.openstreetmap.org/copyright) - Map data from OpenStreetMap, licensed under the Open Data Commons Open Database License (ODbL) by the OpenStreetMap Foundation (OSMF) (https://www.openstreetmap.org/copyright)
- Solar positioning library (https://github.com/klausbrunner/solarpositioning) which is licensed under <a href='https://github.com/klausbrunner/solarpositioning/blob/master/LICENSE.txt'>MIT License</a> - Solar positioning library (https://github.com/klausbrunner/solarpositioning) which is licensed under <a href='https://github.com/klausbrunner/solarpositioning/blob/master/LICENSE.txt'>MIT License</a>
- Zip4j (https://github.com/srikanth-lingala/zip4j) which is licensed under Apache License Version 2.0 - Zip4j (https://github.com/srikanth-lingala/zip4j) which is licensed under Apache License Version 2.0
## Contributing ## Contributing
If you find a bug, please open an issue in the Github repository, assuming one does not already exist. If you find a bug, please open an issue in the Github repository, assuming one does not already exist.

View file

@ -12,8 +12,8 @@ android {
applicationId "org.woheller69.solxpect" applicationId "org.woheller69.solxpect"
minSdkVersion 26 minSdkVersion 26
targetSdkVersion 31 targetSdkVersion 31
versionCode 13 versionCode 14
versionName "1.3" versionName "1.4"
buildConfigField "String", "BASE_URL", "\"https://api.open-meteo.com/v1/\"" buildConfigField "String", "BASE_URL", "\"https://api.open-meteo.com/v1/\""
buildConfigField "String", "GITHUB_URL","\"https://github.com/woheller69/solxpect/\"" buildConfigField "String", "GITHUB_URL","\"https://github.com/woheller69/solxpect/\""

View file

@ -8,6 +8,11 @@ Es zeigt die geschätzte Energieproduktion für die nächsten Stunden und bis zu
Die Stundenwerte werden für die vorangegangene Stunde berechnet. Die Stundenwerte werden für die vorangegangene Stunde berechnet.
Wenn also um 11:00 Uhr 150 Wh angezeigt werden, bedeutet dies, dass Sie zwischen 10:00 und 11:00 Uhr mit 150 Wh rechnen können. Wenn also um 11:00 Uhr 150 Wh angezeigt werden, bedeutet dies, dass Sie zwischen 10:00 und 11:00 Uhr mit 150 Wh rechnen können.
<h3>Mehrere Module am gleichen Ort</h3>
Wenn Sie mehrere Module haben, die in verschiedene Richtungen zeigen, können Sie sie als separate Standorte definieren und in den Einstellungen 'Summe anzeigen' einschalten.
Dann werden alle Orte mit gleichem Breiten-/Längengrad zusammengefasst. In diesem Fall sollten Sie Ihre Standortnamen als 'myPV | Teil1', 'meinPV | Teil2' usw. definieren.
Im Modus 'Summe anzeigen' wird der Standort dann als 'myPV' angezeigt und '|' wird in diesem Fall als Trennzeichen verwendet.
<h2>Parameter</h2> <h2>Parameter</h2>
<h3>Breitengrad [°]</h3> <h3>Breitengrad [°]</h3>

View file

@ -8,6 +8,11 @@ It shows the estimated energy production for the next hours and up to 16 days.
The hourly values are calculated for the preceding hour. The hourly values are calculated for the preceding hour.
So if there are 150 Wh shown at 11:00 this means you can expect 150 Wh between 10:00 and 11:00. So if there are 150 Wh shown at 11:00 this means you can expect 150 Wh between 10:00 and 11:00.
<h3>Several modules at same location</h3>
If you have several modules pointing in different directions you can define them as separate locations and switch on 'show sum' in preferences. Then
all locations with same latitude/longitude are summarized. In this case you should define your location names as 'myPV | part1', 'myPV | part2', etc.
In 'show sum' mode the location is then shown as 'myPV' and '|' is taken as delimiter in this case.
<h2>Parameters</h2> <h2>Parameters</h2>
<h3>Latitude [°]</h3> <h3>Latitude [°]</h3>

View file

@ -20,8 +20,8 @@ public class SolarPowerPlant {
double inverterEfficiency; double inverterEfficiency;
double azimuthAngle; double azimuthAngle;
double tiltAngle; double tiltAngle;
private int[] shadingElevation; private final int[] shadingElevation;
private int[] shadingOpacity; 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 ) {
this.latitude = latitude; this.latitude = latitude;

View file

@ -48,6 +48,7 @@ public class ForecastCityActivity extends NavigationActivity implements IUpdatea
private ViewPager2 viewPager2; private ViewPager2 viewPager2;
private TabLayout tabLayout; private TabLayout tabLayout;
private TextView noCityText; private TextView noCityText;
private static Boolean isRefreshing = false;
Context context; Context context;
@Override @Override
@ -136,10 +137,15 @@ public class ForecastCityActivity extends NavigationActivity implements IUpdatea
} }
private void initResources() { private void initResources() {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
viewPager2 = findViewById(R.id.viewPager2); viewPager2 = findViewById(R.id.viewPager2);
reduceViewpager2DragSensitivity(viewPager2,2); reduceViewpager2DragSensitivity(viewPager2,2);
tabLayout = findViewById(R.id.tab_layout); tabLayout = findViewById(R.id.tab_layout);
pagerAdapter = new WeatherPagerAdapter(this, getSupportFragmentManager(),getLifecycle()); if (sharedPreferences.getBoolean("pref_summarize",false)){
pagerAdapter = new WeatherPagerAdapter(this, getSupportFragmentManager(),getLifecycle(),true);
} else {
pagerAdapter = new WeatherPagerAdapter(this, getSupportFragmentManager(),getLifecycle(),false);
}
noCityText = findViewById(R.id.noCitySelectedText); noCityText = findViewById(R.id.noCitySelectedText);
} }
@ -158,6 +164,7 @@ public class ForecastCityActivity extends NavigationActivity implements IUpdatea
refreshActionButton = menu.findItem(R.id.menu_refresh); refreshActionButton = menu.findItem(R.id.menu_refresh);
refreshActionButton.setActionView(R.layout.menu_refresh_action_view); refreshActionButton.setActionView(R.layout.menu_refresh_action_view);
refreshActionButton.getActionView().setOnClickListener(v -> m.performIdentifierAction(refreshActionButton.getItemId(), 0)); refreshActionButton.getActionView().setOnClickListener(v -> m.performIdentifierAction(refreshActionButton.getItemId(), 0));
if (isRefreshing) startRefreshAnimation();
return true; return true;
} }
@ -208,28 +215,29 @@ public class ForecastCityActivity extends NavigationActivity implements IUpdatea
@Override @Override
public void processNewGeneralData(GeneralData data) { public void processNewGeneralData(GeneralData data) {
if (refreshActionButton != null && refreshActionButton.getActionView() != null) { stopRefreshAnimation();
refreshActionButton.getActionView().clearAnimation();
}
} }
@Override @Override
public void processNewWeekForecasts(List<WeekForecast> forecasts) { public void processNewWeekForecasts(List<WeekForecast> forecasts) {
if (refreshActionButton != null && refreshActionButton.getActionView() != null) { stopRefreshAnimation();
refreshActionButton.getActionView().clearAnimation();
}
} }
@Override @Override
public void processNewForecasts(List<HourlyForecast> hourlyForecasts) { public void processNewForecasts(List<HourlyForecast> hourlyForecasts) {
stopRefreshAnimation();
}
public static void stopRefreshAnimation(){
if (refreshActionButton != null && refreshActionButton.getActionView() != null) { if (refreshActionButton != null && refreshActionButton.getActionView() != null) {
refreshActionButton.getActionView().clearAnimation(); refreshActionButton.getActionView().clearAnimation();
} }
isRefreshing = false;
} }
public static void startRefreshAnimation(){ public static void startRefreshAnimation(){
{ isRefreshing = true;
if(refreshActionButton !=null && refreshActionButton.getActionView() != null) { if(refreshActionButton !=null && refreshActionButton.getActionView() != null) {
RotateAnimation rotate = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); RotateAnimation rotate = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(500); rotate.setDuration(500);
rotate.setRepeatCount(5); rotate.setRepeatCount(5);
@ -247,6 +255,7 @@ public class ForecastCityActivity extends NavigationActivity implements IUpdatea
refreshActionButton.getActionView().setActivated(true); refreshActionButton.getActionView().setActivated(true);
refreshActionButton.getActionView().setEnabled(true); refreshActionButton.getActionView().setEnabled(true);
refreshActionButton.getActionView().setClickable(true); refreshActionButton.getActionView().setClickable(true);
isRefreshing = false;
} }
@Override @Override
@ -254,8 +263,7 @@ public class ForecastCityActivity extends NavigationActivity implements IUpdatea
} }
}); });
refreshActionButton.getActionView().startAnimation(rotate); refreshActionButton.getActionView().startAnimation(rotate);
} }
}
} }
//https://devdreamz.com/question/348298-how-to-modify-sensitivity-of-viewpager //https://devdreamz.com/question/348298-how-to-modify-sensitivity-of-viewpager

View file

@ -251,6 +251,40 @@ public class ManageLocationsActivity extends NavigationActivity {
alert.setNegativeButton(getString(R.string.dialog_add_close_button), (dialog, whichButton) -> { alert.setNegativeButton(getString(R.string.dialog_add_close_button), (dialog, whichButton) -> {
}); });
alert.setNeutralButton(getString(R.string.dialog_add_clone_button), (dialog, whichButton) -> {
CityToWatch cloneCity = new CityToWatch(
database.getMaxRank() + 1,
-1,
0, city.getLongitude(),city.getLatitude(),
city.getCityName()
);
long id=database.addCityToWatch(cloneCity);
cloneCity.setId((int) id);
cloneCity.setCityId((int) id); //use id also instead of city id as unique identifier
cities.add(cloneCity);
adapter.notifyDataSetChanged();
for (int i = 0; i < shadingElevation.length ; i++) {
shadingElevation[i]= Integer.parseInt(elevationViews[i].getText().toString().isEmpty() ? "0" : elevationViews[i].getText().toString());
shadingOpacity[i]= Integer.parseInt(opacityViews[i].getText().toString().isEmpty() ? "0" : opacityViews[i].getText().toString());
}
adapter.updateCity(cloneCity, String.valueOf(editCity.getText()),
Float.parseFloat(editLatitude.getText().toString().isEmpty() ? "0" : editLatitude.getText().toString()),
Float.parseFloat(editLongitude.getText().toString().isEmpty() ? "0" : editLongitude.getText().toString()),
Float.parseFloat(editAzimuth.getText().toString().isEmpty() ? "0" : editAzimuth.getText().toString()),
Float.parseFloat(editTilt.getText().toString().isEmpty() ? "0" : editTilt.getText().toString()),
Float.parseFloat(editCellsMaxPower.getText().toString().isEmpty() ? "0" : editCellsMaxPower.getText().toString()),
Float.parseFloat(editCellsArea.getText().toString().isEmpty() ? "0" : editCellsArea.getText().toString()),
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(editInverterPowerLimit.getText().toString().isEmpty() ? "0" : editInverterPowerLimit.getText().toString()),
Float.parseFloat(editInverterEfficiency.getText().toString().isEmpty() ? "0" : editInverterEfficiency.getText().toString()),
shadingElevation,
shadingOpacity
);
});
alert.show(); alert.show();
} }
@ -283,7 +317,7 @@ public class ManageLocationsActivity extends NavigationActivity {
return new CityToWatch( return new CityToWatch(
database.getMaxRank() + 1, database.getMaxRank() + 1,
-1, -1,
selectedCity.getCityId(), selectedCity.getLongitude(),selectedCity.getLatitude(), 0, selectedCity.getLongitude(),selectedCity.getLatitude(),
selectedCity.getCityName() selectedCity.getCityName()
); );
} }

View file

@ -12,6 +12,7 @@ import androidx.preference.PreferenceManager;
import androidx.preference.SeekBarPreference; import androidx.preference.SeekBarPreference;
import org.woheller69.weather.R; import org.woheller69.weather.R;
import org.woheller69.weather.database.SQLiteHelper;
public class SettingsActivity extends NavigationActivity implements SharedPreferences.OnSharedPreferenceChangeListener{ public class SettingsActivity extends NavigationActivity implements SharedPreferences.OnSharedPreferenceChangeListener{
@ -80,6 +81,11 @@ public class SettingsActivity extends NavigationActivity implements SharedPrefer
if (key.equals("pref_number_days")){ if (key.equals("pref_number_days")){
SeekBarPreference numberDays = findPreference("pref_number_days"); SeekBarPreference numberDays = findPreference("pref_number_days");
if (numberDays.getValue()<3) numberDays.setValue(3); if (numberDays.getValue()<3) numberDays.setValue(3);
} else if (key.equals("pref_summarize")){
if (sharedPreferences.getBoolean("pref_summarize",false)) {
SQLiteHelper database = SQLiteHelper.getInstance(getActivity());
database.deleteAllForecasts();
}
} }
} }
} }

View file

@ -403,6 +403,17 @@ public class SQLiteHelper extends SQLiteOpenHelper {
} }
public synchronized void deleteAllForecasts(){
SQLiteDatabase database = this.getWritableDatabase();
database.delete(TABLE_GENERAL_DATA, COLUMN_CITY_ID + " <> ?",
new String[]{Integer.toString(-1)});
database.delete(TABLE_HOURLY_FORECAST, FORECAST_CITY_ID + " <> ?",
new String[]{Integer.toString(-1)});
database.delete(TABLE_WEEKFORECAST, WEEKFORECAST_CITY_ID + " <> ?",
new String[]{Integer.toString(-1)});
database.close();
}
public synchronized List<HourlyForecast> getForecastsByCityId(int cityId) { public synchronized List<HourlyForecast> getForecastsByCityId(int cityId) {
SQLiteDatabase database = this.getWritableDatabase(); SQLiteDatabase database = this.getWritableDatabase();

View file

@ -21,6 +21,7 @@ import com.db.chart.view.AxisController;
import com.db.chart.view.BarChartView; import com.db.chart.view.BarChartView;
import org.woheller69.weather.R; import org.woheller69.weather.R;
import org.woheller69.weather.database.CityToWatch;
import org.woheller69.weather.database.GeneralData; import org.woheller69.weather.database.GeneralData;
import org.woheller69.weather.database.HourlyForecast; import org.woheller69.weather.database.HourlyForecast;
import org.woheller69.weather.database.SQLiteHelper; import org.woheller69.weather.database.SQLiteHelper;
@ -69,7 +70,34 @@ public class CityWeatherAdapter extends RecyclerView.Adapter<CityWeatherAdapter.
// function update 3-hour or 1-hour forecast list // function update 3-hour or 1-hour forecast list
public void updateForecastData(List<HourlyForecast> hourlyForecasts) { public void updateForecastData(List<HourlyForecast> hourlyForecasts) {
if (hourlyForecasts.isEmpty()) return;
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
if (sp.getBoolean("pref_summarize",false)){
int cityId = hourlyForecasts.get(0).getCity_id();
ArrayList<Integer> CityIDList = new ArrayList<Integer>();
SQLiteHelper dbHelper = SQLiteHelper.getInstance(context.getApplicationContext());
hourlyForecasts = dbHelper.getForecastsByCityId(cityId); //get fresh values from database to make sure we do add new values to sum values from last update
List<CityToWatch> citiesToWatch = dbHelper.getAllCitiesToWatch();
CityToWatch requestedCity = dbHelper.getCityToWatch(cityId);
for (int i = 0; i < citiesToWatch.size(); i++) {
CityToWatch city = citiesToWatch.get(i);
if (city.getCityId()!=requestedCity.getCityId() && city.getLatitude() == requestedCity.getLatitude() && city.getLongitude() == requestedCity.getLongitude()) {
CityIDList.add(city.getCityId());
}
}
if (CityIDList.size()>0){
for (int c=0; c<CityIDList.size();c++) {
int iteratorCityId = CityIDList.get(c);
List<HourlyForecast> hfc = dbHelper.getForecastsByCityId(iteratorCityId);
if (hfc.size()!=hourlyForecasts.size()) break; //maybe something went wrong during update or city is not yet updated
for (int i=0;i<hfc.size();i++){
hourlyForecasts.get(i).setPower(hourlyForecasts.get(i).getPower()+hfc.get(i).getPower());
}
}
}
}
courseDayList = new ArrayList<>(); courseDayList = new ArrayList<>();
for (HourlyForecast f : hourlyForecasts) { for (HourlyForecast f : hourlyForecasts) {
@ -87,9 +115,33 @@ public class CityWeatherAdapter extends RecyclerView.Adapter<CityWeatherAdapter.
// function for week forecast list // function for week forecast list
public void updateWeekForecastData(List<WeekForecast> forecasts) { public void updateWeekForecastData(List<WeekForecast> forecasts) {
if (forecasts.isEmpty()) return; if (forecasts.isEmpty()) return;
int cityId = forecasts.get(0).getCity_id(); int cityId = forecasts.get(0).getCity_id();
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
if (sp.getBoolean("pref_summarize",false)){
ArrayList<Integer> CityIDList = new ArrayList<Integer>();
SQLiteHelper dbHelper = SQLiteHelper.getInstance(context.getApplicationContext());
forecasts = dbHelper.getWeekForecastsByCityId(cityId); //get fresh values from database to make sure we do add new values to sum values from last update
List<CityToWatch> citiesToWatch = dbHelper.getAllCitiesToWatch();
CityToWatch requestedCity = dbHelper.getCityToWatch(cityId);
for (int i = 0; i < citiesToWatch.size(); i++) {
CityToWatch city = citiesToWatch.get(i);
if (city.getCityId()!=requestedCity.getCityId() && city.getLatitude() == requestedCity.getLatitude() && city.getLongitude() == requestedCity.getLongitude()) {
CityIDList.add(city.getCityId());
}
}
if (CityIDList.size()>0){
for (int c=0; c<CityIDList.size();c++) {
int iteratorCityId = CityIDList.get(c);
List<WeekForecast> wfc = dbHelper.getWeekForecastsByCityId(iteratorCityId);
if (wfc.size() != forecasts.size()) break; //maybe something went wrong during update or city is not yet updated
for (int i=0;i<wfc.size();i++){
forecasts.get(i).setEnergyDay(forecasts.get(i).getEnergyDay()+wfc.get(i).getEnergyDay());
}
}
}
}
SQLiteHelper dbHelper = SQLiteHelper.getInstance(context.getApplicationContext()); SQLiteHelper dbHelper = SQLiteHelper.getInstance(context.getApplicationContext());
int zonemilliseconds = dbHelper.getGeneralDataByCityId(cityId).getTimeZoneSeconds() * 1000; int zonemilliseconds = dbHelper.getGeneralDataByCityId(cityId).getTimeZoneSeconds() * 1000;

View file

@ -17,6 +17,7 @@ import org.woheller69.weather.services.UpdateDataService;
import org.woheller69.weather.ui.WeatherCityFragment; import org.woheller69.weather.ui.WeatherCityFragment;
import org.woheller69.weather.ui.updater.IUpdateableCityUI; import org.woheller69.weather.ui.updater.IUpdateableCityUI;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -35,18 +36,41 @@ public class WeatherPagerAdapter extends FragmentStateAdapter implements IUpdate
private List<CityToWatch> cities; private List<CityToWatch> cities;
private boolean showSum;
public WeatherPagerAdapter(Context context, @NonNull FragmentManager supportFragmentManager, @NonNull Lifecycle lifecycle) { public WeatherPagerAdapter(Context context, @NonNull FragmentManager supportFragmentManager, @NonNull Lifecycle lifecycle, Boolean showSum) {
super(supportFragmentManager,lifecycle); super(supportFragmentManager,lifecycle);
this.mContext = context; this.mContext = context;
this.database = SQLiteHelper.getInstance(context); this.database = SQLiteHelper.getInstance(context);
this.showSum = showSum;
loadCities(); loadCities();
} }
public void loadCities() { public void loadCities() {
this.cities = database.getAllCitiesToWatch(); List<CityToWatch> allCities = database.getAllCitiesToWatch();
Collections.sort(cities, (o1, o2) -> o1.getRank() - o2.getRank()); Collections.sort(allCities, (o1, o2) -> o1.getRank() - o2.getRank());
if (showSum && !allCities.isEmpty()) {
List<CityToWatch> citiesFiltered = new ArrayList<>();
citiesFiltered.add(allCities.get(0)); //always add first element
if (allCities.size() > 0) { //if there is more than one element
for (int i = 1; i < allCities.size(); i++) {
boolean alreadyHasLatLon = false;
for (int j = 0; j < citiesFiltered.size(); j++) {
if (citiesFiltered.get(j).getLatitude() == allCities.get(i).getLatitude() && citiesFiltered.get(j).getLongitude() == allCities.get(i).getLongitude()) {
alreadyHasLatLon = true;
}
}
if (!alreadyHasLatLon) {
citiesFiltered.add(allCities.get(i));
}
}
}
this.cities = citiesFiltered;
} else {
this.cities = allCities;
}
} }
@NonNull @NonNull
@ -64,7 +88,19 @@ public class WeatherPagerAdapter extends FragmentStateAdapter implements IUpdate
} }
public CharSequence getPageTitle(int position) { public CharSequence getPageTitle(int position) {
return cities.get(position).getCityName(); String title;
if (showSum){
String name = cities.get(position).getCityName();
if (name.contains("|")){
String[] name2 = name.split("\\|");
title = name2[0];
} else {
title = cities.get(position).getCityName();
}
} else {
title = cities.get(position).getCityName();
}
return title;
} }
public static void refreshSingleData(Context context, Boolean asap, int cityId) { public static void refreshSingleData(Context context, Boolean asap, int cityId) {
@ -106,14 +142,4 @@ public class WeatherPagerAdapter extends FragmentStateAdapter implements IUpdate
return -1; //item not found return -1; //item not found
} }
public float getLatForPos(int pos) {
CityToWatch city = cities.get(pos);
return city.getLatitude();
}
public float getLonForPos(int pos) {
CityToWatch city = cities.get(pos);
return city.getLongitude();
}
} }

View file

@ -1,15 +1,18 @@
package org.woheller69.weather.weather_api.open_meteo; package org.woheller69.weather.weather_api.open_meteo;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.os.Handler; import android.os.Handler;
import android.widget.Toast; import android.widget.Toast;
import androidx.preference.PreferenceManager;
import com.android.volley.VolleyError; import com.android.volley.VolleyError;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.woheller69.weather.R; import org.woheller69.weather.R;
import org.woheller69.weather.activities.NavigationActivity; import org.woheller69.weather.activities.NavigationActivity;
import org.woheller69.weather.database.CityToWatch;
import org.woheller69.weather.database.GeneralData; import org.woheller69.weather.database.GeneralData;
import org.woheller69.weather.database.HourlyForecast; import org.woheller69.weather.database.HourlyForecast;
import org.woheller69.weather.database.WeekForecast; import org.woheller69.weather.database.WeekForecast;
@ -62,66 +65,88 @@ public class ProcessOMweatherAPIRequest implements IProcessHttpRequest {
public void processSuccessScenario(String response, int cityId) { public void processSuccessScenario(String response, int cityId) {
IDataExtractor extractor = new OMDataExtractor(context); IDataExtractor extractor = new OMDataExtractor(context);
try {
JSONObject json = new JSONObject(response);
//Extract daily weather
dbHelper.deleteWeekForecastsByCityId(cityId);
List<WeekForecast> weekforecasts = new ArrayList<>();
weekforecasts = extractor.extractWeekForecast(json.getString("daily"));
if (weekforecasts!=null && !weekforecasts.isEmpty()){ ArrayList<Integer> CityIDList = new ArrayList<Integer>();
for (WeekForecast weekForecast: weekforecasts){
weekForecast.setCity_id(cityId); SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedPreferences.getBoolean("pref_summarize",false)){
List<CityToWatch> citiesToWatch = dbHelper.getAllCitiesToWatch();
CityToWatch requestedCity = dbHelper.getCityToWatch(cityId);
for (int i = 0; i < citiesToWatch.size(); i++) {
CityToWatch city = citiesToWatch.get(i);
if (city.getCityId()!=requestedCity.getCityId() && city.getLatitude() == requestedCity.getLatitude() && city.getLongitude() == requestedCity.getLongitude()) {
CityIDList.add(city.getCityId());
} }
} else {
final String ERROR_MSG = context.getResources().getString(R.string.error_convert_to_json);
if (NavigationActivity.isVisible)
Toast.makeText(context, ERROR_MSG, Toast.LENGTH_LONG).show();
return;
} }
}
//Extract current weather CityIDList.add(cityId); //add requested city at end of list. Call Viewupdater if last (requested) city is updated
GeneralData generalData = new GeneralData();
generalData.setTimestamp(System.currentTimeMillis() / 1000);
generalData.setCity_id(cityId);
generalData.setTimeSunrise(weekforecasts.get(0).getTimeSunrise());
generalData.setTimeSunset(weekforecasts.get(0).getTimeSunset());
generalData.setTimeZoneSeconds(json.getInt("utc_offset_seconds"));
GeneralData current = dbHelper.getGeneralDataByCityId(cityId);
if (current != null && current.getCity_id() == cityId) {
dbHelper.updateGeneralData(generalData);
} else {
dbHelper.addGeneralData(generalData);
}
//Extract hourly weather for (int c=0; c<CityIDList.size();c++) {
dbHelper.deleteForecastsByCityId(cityId); cityId = CityIDList.get(c);
List<HourlyForecast> hourlyforecasts = new ArrayList<>();
hourlyforecasts = extractor.extractHourlyForecast(json.getString("hourly"), cityId);
if (hourlyforecasts!=null && !hourlyforecasts.isEmpty()){ try {
for (HourlyForecast hourlyForecast: hourlyforecasts){ JSONObject json = new JSONObject(response);
hourlyForecast.setCity_id(cityId);
//Extract daily weather
dbHelper.deleteWeekForecastsByCityId(cityId);
List<WeekForecast> weekforecasts = new ArrayList<>();
weekforecasts = extractor.extractWeekForecast(json.getString("daily"));
if (weekforecasts != null && !weekforecasts.isEmpty()) {
for (WeekForecast weekForecast : weekforecasts) {
weekForecast.setCity_id(cityId);
}
} else {
final String ERROR_MSG = context.getResources().getString(R.string.error_convert_to_json);
if (NavigationActivity.isVisible)
Toast.makeText(context, ERROR_MSG, Toast.LENGTH_LONG).show();
return;
} }
} else {
final String ERROR_MSG = context.getResources().getString(R.string.error_convert_to_json); //Extract current weather
if (NavigationActivity.isVisible) GeneralData generalData = new GeneralData();
Toast.makeText(context, ERROR_MSG, Toast.LENGTH_LONG).show(); generalData.setTimestamp(System.currentTimeMillis() / 1000);
return; generalData.setCity_id(cityId);
generalData.setTimeSunrise(weekforecasts.get(0).getTimeSunrise());
generalData.setTimeSunset(weekforecasts.get(0).getTimeSunset());
generalData.setTimeZoneSeconds(json.getInt("utc_offset_seconds"));
GeneralData current = dbHelper.getGeneralDataByCityId(cityId);
if (current != null && current.getCity_id() == cityId) {
dbHelper.updateGeneralData(generalData);
} else {
dbHelper.addGeneralData(generalData);
}
//Extract hourly weather
dbHelper.deleteForecastsByCityId(cityId);
List<HourlyForecast> hourlyforecasts = new ArrayList<>();
hourlyforecasts = extractor.extractHourlyForecast(json.getString("hourly"), cityId);
if (hourlyforecasts != null && !hourlyforecasts.isEmpty()) {
for (HourlyForecast hourlyForecast : hourlyforecasts) {
hourlyForecast.setCity_id(cityId);
}
} else {
final String ERROR_MSG = context.getResources().getString(R.string.error_convert_to_json);
if (NavigationActivity.isVisible)
Toast.makeText(context, ERROR_MSG, Toast.LENGTH_LONG).show();
return;
}
dbHelper.addForecasts(hourlyforecasts);
weekforecasts = reanalyzeWeekIDs(weekforecasts, hourlyforecasts);
dbHelper.addWeekForecasts(weekforecasts);
if (c == CityIDList.size()-1) ViewUpdater.updateGeneralDataData(generalData); // Call Viewupdater if last (requested) city is updated
if (c == CityIDList.size()-1) ViewUpdater.updateWeekForecasts(weekforecasts);
if (c == CityIDList.size()-1) ViewUpdater.updateForecasts(hourlyforecasts);
} catch (JSONException e) {
e.printStackTrace();
} }
dbHelper.addForecasts(hourlyforecasts);
weekforecasts = reanalyzeWeekIDs(weekforecasts, hourlyforecasts);
dbHelper.addWeekForecasts(weekforecasts);
ViewUpdater.updateGeneralDataData(generalData);
ViewUpdater.updateWeekForecasts(weekforecasts);
ViewUpdater.updateForecasts(hourlyforecasts);
} catch (JSONException e) {
e.printStackTrace();
} }
} }

View file

@ -102,6 +102,9 @@
<string name="permission_message">%s benötigt Zugriff auf den externen Speicher. Bitte die Berechtigung erteilen und erneut versuchen.</string> <string name="permission_message">%s benötigt Zugriff auf den externen Speicher. Bitte die Berechtigung erteilen und erneut versuchen.</string>
<string name="toast_delete">Bitte die Datei zuerst löschen und erneut versuchen.</string> <string name="toast_delete">Bitte die Datei zuerst löschen und erneut versuchen.</string>
<string name="restore_database_message">Daten aus dem Dokumentenordner wiederherstellen. Falls nötig, Ordner \'Documents\' öffnen und solXpect.zip auswählen!</string> <string name="restore_database_message">Daten aus dem Dokumentenordner wiederherstellen. Falls nötig, Ordner \'Documents\' öffnen und solXpect.zip auswählen!</string>
<string name="settings_summarize">Summe anzeigen</string>
<string name="summary_summarize">Summiere die Werte aller Module mit gleichem Längen- und Breitengrad.</string>
<string name="dialog_add_clone_button">Klonen</string>
</resources> </resources>

View file

@ -105,4 +105,7 @@
<string name="permission_message">%s needs access to external storage. Please accept permission and try again.</string> <string name="permission_message">%s needs access to external storage. Please accept permission and try again.</string>
<string name="toast_delete">Please delete file and try again</string> <string name="toast_delete">Please delete file and try again</string>
<string name="restore_database_message">Restore Data from Documents folder. Open folder \'Documents\' and select solXpect.zip if needed!</string> <string name="restore_database_message">Restore Data from Documents folder. Open folder \'Documents\' and select solXpect.zip if needed!</string>
<string name="settings_summarize">Show sum</string>
<string name="summary_summarize">Summarize values of modules at the same latitude and longitude.</string>
<string name="dialog_add_clone_button">Clone</string>
</resources> </resources>

View file

@ -11,6 +11,13 @@
app:showSeekBarValue="true" app:showSeekBarValue="true"
/> />
<SwitchPreference
android:key="pref_summarize"
android:title="@string/settings_summarize"
android:summary="@string/summary_summarize"
android:defaultValue="false"
/>
<SwitchPreference <SwitchPreference
android:key="pref_TimeFormat" android:key="pref_TimeFormat"
android:title="@string/settings_time24h" android:title="@string/settings_time24h"

View file

@ -0,0 +1,2 @@
Add option to show sum of all modules with same latitude/longitude
Add option to clone location