78 lines
2.7 KiB
Java
78 lines
2.7 KiB
Java
package de.ph87.data.weather;
|
|
|
|
import lombok.NonNull;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
|
import org.springframework.context.event.EventListener;
|
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
|
import org.springframework.scheduling.annotation.Scheduled;
|
|
import org.springframework.stereotype.Service;
|
|
import tools.jackson.databind.ObjectMapper;
|
|
|
|
import java.io.IOException;
|
|
import java.net.HttpURLConnection;
|
|
import java.net.URI;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.time.LocalDate;
|
|
import java.time.LocalTime;
|
|
import java.time.ZoneId;
|
|
import java.time.ZonedDateTime;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
@Slf4j
|
|
@Service
|
|
@EnableScheduling
|
|
@RequiredArgsConstructor
|
|
public class WeatherService {
|
|
|
|
private List<WeatherHour> hours = new ArrayList<>();
|
|
|
|
private final WeatherConfig weatherConfig;
|
|
|
|
private final ObjectMapper objectMapper;
|
|
|
|
@NonNull
|
|
public List<WeatherHour> all() {
|
|
return new ArrayList<>(hours);
|
|
}
|
|
|
|
@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<WeatherHour> hours = new ArrayList<>();
|
|
log.debug("Updating Weather...");
|
|
for (LocalDate day = first; !day.isAfter(end); day = day.plusDays(1)) {
|
|
fetchDay(day).getWeather().stream().map(WeatherHour::new).forEach(hours::add);
|
|
}
|
|
this.hours = hours;
|
|
log.info("Weather update complete");
|
|
} catch (Exception e) {
|
|
log.error("Failed fetching Weather data: {}", 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);
|
|
}
|
|
|
|
}
|