![JAR search and dependency download from the Maven repository](/logo.png)
de.hasait.sprinkler.service.schedule.ScheduleTaskService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sprinkler Show documentation
Show all versions of sprinkler Show documentation
Sprinkler - Spring Boot application for controlling sprinklers using Raspberry Pi
The newest version!
package de.hasait.sprinkler.service.schedule;
import de.hasait.sprinkler.domain.schedule.ScheduleLogPO;
import de.hasait.sprinkler.domain.schedule.ScheduleLogRepository;
import de.hasait.sprinkler.domain.schedule.SchedulePO;
import de.hasait.sprinkler.domain.schedule.ScheduleRepository;
import de.hasait.sprinkler.service.relay.RelayService;
import de.hasait.sprinkler.util.Util;
import de.hasait.sprinkler.util.ValueWithExplanation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
@Service
public class ScheduleTaskService {
private static final Logger LOG = LoggerFactory.getLogger(ScheduleTaskService.class);
private final ScheduleRepository repository;
private final ScheduleLogRepository scheduleLogRepository;
private final ScheduleService scheduleService;
private final TaskScheduler taskScheduler;
private final RelayService relayService;
private final ConcurrentHashMap>> scheduledFutures = new ConcurrentHashMap<>();
public ScheduleTaskService(ScheduleRepository repository, ScheduleLogRepository scheduleLogRepository, ScheduleService scheduleService, TaskScheduler taskScheduler, RelayService relayService) {
super();
this.repository = repository;
this.scheduleLogRepository = scheduleLogRepository;
this.scheduleService = scheduleService;
this.taskScheduler = taskScheduler;
this.relayService = relayService;
SchedulePOListener.scheduleTaskService = this;
repository.findAll().forEach(this::createOrUpdateScheduledTask);
}
public void postPersistSchedulePO(SchedulePO po) {
LOG.debug("postPersistSchedulePO: {}", po);
createOrUpdateScheduledTask(po);
}
public void postUpdateSchedulePO(SchedulePO po) {
LOG.debug("postUpdateSchedulePO: {}", po);
createOrUpdateScheduledTask(po);
}
public void preRemoveSchedulePO(SchedulePO po) {
LOG.debug("preRemoveSchedulePO: {}", po);
cancelScheduledTask(po.getId());
}
private void cancelScheduledTask(long scheduleId) {
LOG.debug("cancelScheduledTask {}...", scheduleId);
List> oldSchedules = scheduledFutures.remove(scheduleId);
if (oldSchedules != null) {
oldSchedules.forEach(it -> it.cancel(true));
}
}
private void createOrUpdateScheduledTask(SchedulePO po) {
long scheduleId = po.getId();
cancelScheduledTask(scheduleId);
boolean enabled = po.isEnabled();
String cronExpression = po.getCronExpression();
if (enabled && cronExpression != null) {
long durationMillis = po.determineDurationMillis();
CronTrigger cronTrigger = new CronTrigger(cronExpression);
SprinklerWithSensorTask task = new SprinklerWithSensorTask(scheduleId);
registerScheduledFuture(scheduleId, taskScheduler.schedule(task, cronTrigger));
LocalDateTime now = LocalDateTime.now();
LocalDateTime previousSeed = now.minus(durationMillis, ChronoUnit.MILLIS);
LocalDateTime previousStart = Util.determineNext(cronExpression, previousSeed);
if (previousStart.isBefore(now)) {
long remainingMillis = durationMillis - Duration.between(previousStart, now).toMillis();
if (remainingMillis > 10000) {
LOG.info("Resuming {}...", po.getRelay().getName());
registerScheduledFuture(scheduleId, relayService.scheduleNow(po.getRelay().getId(), remainingMillis, "Resuming after restart"));
}
}
}
}
private void registerScheduledFuture(long scheduleId, ScheduledFuture> scheduledFuture) {
LOG.debug("registerScheduledFuture {}...", scheduleId);
Util.registerScheduledFuture(scheduleId, scheduledFuture, scheduledFutures);
}
public void executeSchedule(long scheduleId) {
SchedulePO schedulePO = repository.findById(scheduleId).orElseThrow();
ValueWithExplanation durationMillisSensor = scheduleService.determineDurationMillisSensor(schedulePO);
if (durationMillisSensor.getValue() <= 0) {
if (LOG.isInfoEnabled()) {
LOG.info("{} skipped: {}", schedulePO.getRelay().getName(), durationMillisSensor.getExplanation());
}
return;
}
ScheduleLogPO scheduleLog = new ScheduleLogPO();
LocalDateTime now = LocalDateTime.now();
scheduleLog.setStart(now);
scheduleLog.setSchedule(schedulePO);
scheduleLog.setRelayName(schedulePO.getRelay().getName());
scheduleLog.setDurationMillis(durationMillisSensor.getValue());
scheduleLogRepository.save(scheduleLog);
scheduleLogRepository.deleteAllBefore(now.minusMonths(2));
registerScheduledFuture(scheduleId, relayService.scheduleNow(schedulePO.getRelay().getId(), durationMillisSensor.getValue(), durationMillisSensor.getExplanation()));
}
private class SprinklerWithSensorTask implements Runnable {
private final long scheduleId;
public SprinklerWithSensorTask(long scheduleId) {
this.scheduleId = scheduleId;
}
@Override
public void run() {
executeSchedule(scheduleId);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy