77 lines
2.6 KiB
Java
77 lines
2.6 KiB
Java
package de.ph87.data.weather;
|
|
|
|
import com.fasterxml.jackson.databind.*;
|
|
import lombok.*;
|
|
import lombok.extern.slf4j.*;
|
|
import org.springframework.boot.context.event.*;
|
|
import org.springframework.context.event.EventListener;
|
|
import org.springframework.scheduling.annotation.*;
|
|
import org.springframework.stereotype.*;
|
|
|
|
import java.io.*;
|
|
import java.net.*;
|
|
import java.nio.charset.*;
|
|
import java.time.*;
|
|
import java.time.format.*;
|
|
import java.util.*;
|
|
|
|
@Slf4j
|
|
@Service
|
|
@EnableScheduling
|
|
@RequiredArgsConstructor
|
|
public class WeatherService {
|
|
|
|
private List<WeatherDay> days = new ArrayList<>();
|
|
|
|
private final WeatherConfig weatherConfig;
|
|
|
|
private final ObjectMapper objectMapper;
|
|
|
|
@NonNull
|
|
public List<WeatherDay> all() {
|
|
return new ArrayList<>(days);
|
|
}
|
|
|
|
@Scheduled(cron = "0 0 * * * *")
|
|
@EventListener(ApplicationStartedEvent.class)
|
|
public void update() {
|
|
try {
|
|
final LocalDate today = LocalDate.now();
|
|
final LocalDate first = today.minusDays(weatherConfig.getPastDays());
|
|
final LocalDate end = today.plusDays(weatherConfig.getFutureDays());
|
|
final List<WeatherDay> newDays = new ArrayList<>();
|
|
log.debug("Updating Weather...");
|
|
for (LocalDate day = first; !day.isAfter(end); day = day.plusDays(1)) {
|
|
final WeatherDay weatherDay = new WeatherDay(fetchDay(day));
|
|
newDays.add(weatherDay);
|
|
if (log.isDebugEnabled()) {
|
|
log.debug(" {}:", weatherDay);
|
|
for (WeatherDay.Hour hour : weatherDay.getHours()) {
|
|
log.debug(" %s: %4s clouds, %9s, %4s".formatted(hour.date.toLocalTime(), hour.getClouds(), hour.getIrradiation(), hour.getPrecipitation()));
|
|
}
|
|
}
|
|
}
|
|
days = newDays;
|
|
log.info("Weather update complete");
|
|
} catch (IOException e) {
|
|
log.error(e.toString());
|
|
}
|
|
}
|
|
|
|
@NonNull
|
|
public BrightSkyDto fetchDay(@NonNull final LocalDate day) throws IOException {
|
|
final String url = weatherConfig.getUrlPattern()
|
|
.replace("{date}", ZonedDateTime.of(day, LocalTime.MIDNIGHT, ZoneId.systemDefault()).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME))
|
|
.replace("{latitude}", weatherConfig.getLatitude() + "")
|
|
.replace("{longitude}", weatherConfig.getLongitude() + "");
|
|
final HttpURLConnection connection = (HttpURLConnection) URI.create(url).toURL().openConnection();
|
|
final int responseCode = connection.getResponseCode();
|
|
final byte[] bytes = connection.getInputStream().readAllBytes();
|
|
if (responseCode / 100 != 2) {
|
|
throw new IOException("responseCode=%d, message: %s".formatted(responseCode, new String(bytes, StandardCharsets.UTF_8)));
|
|
}
|
|
return objectMapper.readValue(bytes, BrightSkyDto.class);
|
|
}
|
|
|
|
}
|