Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 3.5.2: Introduce DAO interfaces to clarify interface with data layer #1

Merged
merged 1 commit into from
Nov 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<groupId>org.keen</groupId>
<artifactId>solar</artifactId>
<version>3.5.1</version>
<version>3.5.2</version>

<name>solar</name>
<description>Retrieves solar data from a Fronius inverter and persists it to a data store.</description>
Expand Down Expand Up @@ -112,7 +112,7 @@
<!-- Excluding tests which call the Fronius API and hence will only run locally -->
<exclude>**/CurrentPowerRetrieverIT.java</exclude>
<exclude>**/StringPowerRetrieverIT.java</exclude>
<exclude>**/InverterInfoLoggerIT.java</exclude>
<exclude>**/SystemInfoLoggerIT.java</exclude>
</excludes>
</configuration>
<executions>
Expand Down
16 changes: 8 additions & 8 deletions src/main/java/org/keen/solar/financial/PowerCostCalculator.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.keen.solar.financial;

import org.keen.solar.financial.dal.TariffRepository;
import org.keen.solar.financial.dal.PowerCostRepository;
import org.keen.solar.financial.dal.TariffDao;
import org.keen.solar.financial.dal.PowerCostDao;
import org.keen.solar.financial.domain.PowerCost;
import org.keen.solar.financial.domain.Tariff;
import org.keen.solar.system.domain.CurrentPower;
Expand Down Expand Up @@ -39,13 +39,13 @@ public class PowerCostCalculator {
* up to 3600 (the number of seconds in one hour).
*/
private final int collectionFrequencySeconds;
private final TariffRepository tariffRepository;
private final PowerCostRepository powerCostRepository;
private final TariffDao tariffRepository;
private final PowerCostDao powerCostRepository;
private final Deque<CurrentPower> uncostedPowers = new ConcurrentLinkedDeque<>();

public PowerCostCalculator(@Value("${app.power.collection-frequency-sec}") int collectionFrequencySeconds,
TariffRepository tariffRepository,
PowerCostRepository powerCostRepository) {
TariffDao tariffRepository,
PowerCostDao powerCostRepository) {
validateCollectionFrequency(collectionFrequencySeconds);

this.collectionFrequencySeconds = collectionFrequencySeconds;
Expand Down Expand Up @@ -89,15 +89,15 @@ private void calculateCostAndPersist(CurrentPower currentPower) {
LocalTime localTime = measurementZonedDateTime.toLocalTime();
// Get feed-in tariff
Tariff effectiveFeedInTariff = tariffRepository
.findEffectiveFeedInTariff(dayOfWeek, localTime, currentPower.getEpochTimestamp());
.getEffectiveFeedInTariff(dayOfWeek, localTime, currentPower.getEpochTimestamp());
if (effectiveFeedInTariff == null) {
logger.warn("No effective feed-in tariff found; unable to calculate power cost.");
return;
}
BigDecimal feedInTariffWattSecond = convertTariffToWattSeconds(effectiveFeedInTariff);
// Get usage tariff
Tariff effectiveUsageTariff = tariffRepository
.findEffectiveUsageTariff(dayOfWeek, localTime, currentPower.getEpochTimestamp());
.getEffectiveUsageTariff(dayOfWeek, localTime, currentPower.getEpochTimestamp());
if (effectiveUsageTariff == null) {
logger.warn("No effective usage tariff found; unable to calculate power cost.");
return;
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/org/keen/solar/financial/dal/PowerCostDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.keen.solar.financial.dal;

import org.keen.solar.financial.domain.PowerCost;

public interface PowerCostDao {

/**
* Persists the given PowerCost to the repository.
*/
void save(PowerCost powerCost);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.keen.solar.financial.dal;

import org.keen.solar.financial.domain.PowerCost;
import org.springframework.stereotype.Component;

@Component
public class PowerCostDaoSpringDataImpl implements PowerCostDao {

private final PowerCostRepository repository;

public PowerCostDaoSpringDataImpl(PowerCostRepository repository) {
this.repository = repository;
}


@Override
public void save(PowerCost powerCost) {
repository.save(powerCost);
}
}
31 changes: 31 additions & 0 deletions src/main/java/org/keen/solar/financial/dal/TariffDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.keen.solar.financial.dal;

import org.keen.solar.financial.domain.Tariff;

import java.time.DayOfWeek;
import java.time.LocalTime;

public interface TariffDao {

/**
* Retrieves the feed-in tariff for the given day and time, effective
* as at {@code epochTime}.
*
* @param dayOfWeek the day of the week to retrieve the tariff for
* @param localTime the time of day to retrieve the tariff for
* @param epochTime the epoch time that the tariff is effective for
* @return the feed-in tariff
*/
Tariff getEffectiveFeedInTariff(DayOfWeek dayOfWeek, LocalTime localTime, long epochTime);

/**
* Retrieves the usage tariff for the given day and time, effective
* as at {@code epochTime}.
*
* @param dayOfWeek the day of the week to retrieve the tariff for
* @param localTime the time of day to retrieve the tariff for
* @param epochTime the epoch time that the tariff is effective for
* @return the usage tariff
*/
Tariff getEffectiveUsageTariff(DayOfWeek dayOfWeek, LocalTime localTime, long epochTime);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.keen.solar.financial.dal;

import org.keen.solar.financial.domain.Tariff;
import org.springframework.stereotype.Component;

import java.time.DayOfWeek;
import java.time.LocalTime;

@Component
public class TariffDaoSpringDataImpl implements TariffDao {

private final TariffRepository repository;

public TariffDaoSpringDataImpl(TariffRepository repository) {
this.repository = repository;
}

@Override
public Tariff getEffectiveFeedInTariff(DayOfWeek dayOfWeek, LocalTime localTime, long epochTime) {
return repository.findEffectiveFeedInTariff(dayOfWeek, localTime, epochTime);
}

@Override
public Tariff getEffectiveUsageTariff(DayOfWeek dayOfWeek, LocalTime localTime, long epochTime) {
return repository.findEffectiveUsageTariff(dayOfWeek, localTime, epochTime);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.keen.solar.solcast.forecast;

import org.keen.solar.solcast.forecast.dal.ForecastRepository;
import org.keen.solar.solcast.forecast.dal.ForecastDao;
import org.keen.solar.solcast.forecast.domain.GenerationForecast;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
Expand All @@ -21,7 +21,7 @@ public class ForecastPersister {
private ForecastRetriever retriever;

@Autowired
private ForecastRepository repository;
private ForecastDao repository;

@Async
@Scheduled(cron = "${app.solcast.forecast-retrieval-cron}")
Expand All @@ -31,17 +31,7 @@ public void retrieveAndPersistAsync() {

public void retrieveAndPersist() {
List<GenerationForecast> forecasts = retriever.retrieve();
// Retrieve the id for any existing forecast for the same period so that it gets updated in the database,
// rather than inserted.
// Not particularly efficient, given that each forecast is retrieved individually from the database.
// Spring Data JDBC doesn't provide a mechanism to write queries that take collections as parameters.
forecasts.forEach(forecast -> {
GenerationForecast existingForecast = repository.findByPeriodEnd(forecast.getPeriod_end_epoch());
if (existingForecast != null) {
forecast.setId(existingForecast.getId());
}
});
repository.saveAll(forecasts);
repository.save(forecasts);
}

}
13 changes: 13 additions & 0 deletions src/main/java/org/keen/solar/solcast/forecast/dal/ForecastDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.keen.solar.solcast.forecast.dal;

import org.keen.solar.solcast.forecast.domain.GenerationForecast;

import java.util.Collection;

public interface ForecastDao {

/**
* Persists the given forecasts to the repository, updating them if they exist.
*/
void save(Collection<GenerationForecast> forecasts);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.keen.solar.solcast.forecast.dal;

import org.keen.solar.solcast.forecast.domain.GenerationForecast;
import org.springframework.stereotype.Component;

import java.util.Collection;

@Component
public class ForecastDaoSpringDataImpl implements ForecastDao {

private final ForecastRepository repository;

public ForecastDaoSpringDataImpl(ForecastRepository repository) {
this.repository = repository;
}

@Override
public void save(Collection<GenerationForecast> forecasts) {
// Retrieve the id for any existing forecast for the same period so that it gets updated in the database,
// rather than inserted.
// Not particularly efficient, given that each forecast is retrieved individually from the database.
// Spring Data JDBC doesn't provide a mechanism to write queries that take collections as parameters.
forecasts.forEach(forecast -> {
GenerationForecast existingForecast = repository.findByPeriodEnd(forecast.getPeriod_end_epoch());
if (existingForecast != null) {
forecast.setId(existingForecast.getId());
}
});
repository.saveAll(forecasts);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.keen.solar.solcast.measurement;

import org.keen.solar.system.dal.CurrentPowerRepository;
import org.keen.solar.system.dal.CurrentPowerDao;
import org.keen.solar.system.domain.CurrentPower;
import org.keen.solar.solcast.measurement.domain.Measurement;
import org.keen.solar.solcast.measurement.domain.MeasurementResponse;
Expand Down Expand Up @@ -28,7 +28,7 @@ public class MeasurementUploader {
private final Logger logger = LoggerFactory.getLogger(MeasurementUploader.class);

private final RestTemplate restTemplate;
private final CurrentPowerRepository repository;
private final CurrentPowerDao repository;

@Value("${app.solcast.base-url}")
private String solcastApiBaseUrl;
Expand All @@ -39,7 +39,7 @@ public class MeasurementUploader {
@Value("${app.solcast.api-key}")
private String solcastApiKey;

public MeasurementUploader(RestTemplateBuilder restTemplateBuilder, CurrentPowerRepository repository) {
public MeasurementUploader(RestTemplateBuilder restTemplateBuilder, CurrentPowerDao repository) {
this.restTemplate = restTemplateBuilder.build();
this.repository = repository;
}
Expand All @@ -48,7 +48,7 @@ public MeasurementUploader(RestTemplateBuilder restTemplateBuilder, CurrentPower
* Uploads all measurements not yet uploaded to Solcast
*/
public void uploadAll() {
List<CurrentPower> currentPowerNotUploaded = repository.findByUploaded(false);
List<CurrentPower> currentPowerNotUploaded = repository.getNotUploaded();
doUpload(currentPowerNotUploaded);
}

Expand Down Expand Up @@ -103,7 +103,7 @@ private void updateRepository(List<Measurement> measurementsToUpload, List<Measu
logger.debug("Updating repository");
measurementsUploaded.forEach(measurement -> {
measurement.getSource().parallelStream().forEach(currentPower -> currentPower.setUploaded(true));
repository.saveAll(measurement.getSource());
repository.save(measurement.getSource());
});
// Log which measurements were in error
measurementsToUpload.removeAll(returnedMeasurements);
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/org/keen/solar/string/dal/StringPowerDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.keen.solar.string.dal;

import org.keen.solar.string.domain.StringPower;

public interface StringPowerDao {

/**
* Persists the given StringPower to the repository.
*/
void save(StringPower stringPower);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.keen.solar.string.dal;

import org.keen.solar.string.domain.StringPower;
import org.springframework.stereotype.Component;

@Component
public class StringPowerDaoSpringDataImpl implements StringPowerDao {

private final StringPowerRepository repository;

public StringPowerDaoSpringDataImpl(StringPowerRepository repository) {
this.repository = repository;
}

@Override
public void save(StringPower stringPower) {
repository.save(stringPower);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.keen.solar.string.fronius;

import org.keen.solar.string.dal.StringPowerRepository;
import org.keen.solar.string.dal.StringPowerDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
Expand All @@ -11,7 +11,7 @@ public class StringPowerPersister {
private StringPowerRetriever retriever;

@Autowired
private StringPowerRepository repository;
private StringPowerDao repository;

@Async
@Scheduled(cron = "15 0/5 * * * *")
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/org/keen/solar/system/dal/CurrentPowerDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.keen.solar.system.dal;

import org.keen.solar.system.domain.CurrentPower;

import java.util.Collection;
import java.util.List;

public interface CurrentPowerDao {

/**
* Returns all CurrentPowers not yet uploaded to Solcast.
*/
List<CurrentPower> getNotUploaded();

/**
* Persists the given CurrentPower to the repository.
*/
void save(CurrentPower currentPower);

/**
* Persists the given CurrentPowers to the repository.
*/
void save(Collection<CurrentPower> currentPowers);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.keen.solar.system.dal;

import org.keen.solar.system.domain.CurrentPower;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;

@Component
public class CurrentPowerDaoSpringDataImpl implements CurrentPowerDao {

private final CurrentPowerRepository repository;

public CurrentPowerDaoSpringDataImpl(CurrentPowerRepository repository) {
this.repository = repository;
}

@Override
public List<CurrentPower> getNotUploaded() {
return repository.findByUploaded(false);
}

@Override
public void save(CurrentPower currentPower) {
repository.save(currentPower);
}

@Override
public void save(Collection<CurrentPower> currentPowers) {
repository.saveAll(currentPowers);
}
}
Loading
Loading