From 25d78dc32a4d4304afd65a37db606cb230130d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Ha=C3=9Fel?= Date: Sun, 3 Oct 2021 21:39:47 +0200 Subject: [PATCH] using spring-boot:repackage + some minor fixes + clean up --- deploy.sh | 6 ++ pom.xml | 98 +++---------------- .../ph87/homeautomation/DemoDataService.java | 35 ++++--- .../homeautomation/knx/KnxThreadService.java | 4 +- .../knx/group/KnxGroupLinkService.java | 2 +- .../knx/group/KnxGroupRepository.java | 2 + .../knx/group/KnxGroupWriteService.java | 49 ++++------ .../schedule/ScheduleThreadService.java | 4 +- .../schedule/ScheduleWriteService.java | 28 ++++-- .../shared/AbstractThreadService.java | 7 +- 10 files changed, 94 insertions(+), 141 deletions(-) create mode 100755 deploy.sh diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..5bd5f90 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +cd "$(dirname "$0")" || exit 1 + +mvn clean package spring-boot:repackage && \ +scp target/Homeautomation.jar media@10.0.0.50:/home/media/Homeautomation/Homeautomation.jar diff --git a/pom.xml b/pom.xml index 5a2f93b..4520155 100644 --- a/pom.xml +++ b/pom.xml @@ -7,18 +7,16 @@ de.ph87 Homeautomation 1.0-SNAPSHOT - war - 11 - 11 + 15 + 15 org.springframework.boot spring-boot-starter-parent 2.3.6.RELEASE - @@ -50,11 +48,13 @@ org.projectlombok lombok + 1.18.20 + com.github.calimero calimero-core - 2.5-M1 + 2.5-rc1 com.luckycatlabs @@ -71,95 +71,27 @@ + ${project.artifactId} - + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 11 + + org.springframework.boot spring-boot-maven-plugin - - repackage - - spring-boot - - de.ph87.de.ph87.homeautomation.BackendApplication - + de.ph87.homeautomation.BackendApplication - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/de/ph87/homeautomation/DemoDataService.java b/src/main/java/de/ph87/homeautomation/DemoDataService.java index 37535a1..5a8f95d 100644 --- a/src/main/java/de/ph87/homeautomation/DemoDataService.java +++ b/src/main/java/de/ph87/homeautomation/DemoDataService.java @@ -1,6 +1,7 @@ package de.ph87.homeautomation; import com.luckycatlabs.sunrisesunset.Zenith; +import de.ph87.homeautomation.knx.group.KnxGroupRepository; import de.ph87.homeautomation.knx.group.KnxGroupWriteService; import de.ph87.homeautomation.schedule.PropertyEntry; import de.ph87.homeautomation.schedule.Schedule; @@ -36,13 +37,15 @@ public class DemoDataService { private final ScheduleRepository scheduleRepository; + private final KnxGroupRepository knxGroupRepository; + @PostConstruct public void postConstruct() { - knxGroupWriteService.create("Wohnzimmer Rollladen Position Anfahren", WOHNZIMMER_ROLLLADEN_POSITION_ANFAHREN_ADDRESS, "5.001", false); - knxGroupWriteService.create("Schlafzimmer Rollladen Position Anfahren", SCHLAFZIMMER_ROLLLADEN_POSITION_ANFAHREN_ADDRESS, "5.001", false); - knxGroupWriteService.create("Flur Rollladen Position Anfahren", FLUR_ROLLLADEN_POSITION_ANFAHREN_ADDRESS, "5.001", false); - knxGroupWriteService.create("Badewanne Schalten", BADEWANNE_SCHALTEN, "1.001", false); - knxGroupWriteService.create("Badewanne Status", BADEWANNE_STATUS, "1.001", true); + createKnxGroupIfNotExists("Wohnzimmer Rollladen Position Anfahren", WOHNZIMMER_ROLLLADEN_POSITION_ANFAHREN_ADDRESS, "5.001", false); + createKnxGroupIfNotExists("Schlafzimmer Rollladen Position Anfahren", SCHLAFZIMMER_ROLLLADEN_POSITION_ANFAHREN_ADDRESS, "5.001", false); + createKnxGroupIfNotExists("Flur Rollladen Position Anfahren", FLUR_ROLLLADEN_POSITION_ANFAHREN_ADDRESS, "5.001", false); + createKnxGroupIfNotExists("Badewanne Schalten", BADEWANNE_SCHALTEN, "1.001", false); + createKnxGroupIfNotExists("Badewanne Status", BADEWANNE_STATUS, "1.001", true); final Schedule wohnzimmer = new Schedule(); wohnzimmer.setName("Rollläden Wohnzimmer"); @@ -62,14 +65,20 @@ public class DemoDataService { createSunset(flur, Zenith.NAUTICAL, new PropertyEntry(FLUR_ROLLLADEN_POSITION_ANFAHREN_ADDRESS, "100")); scheduleRepository.save(flur); -// final Schedule badewanne = new Schedule(); -// badewanne.setName("Badewanne"); -// int seconds = 2; -// createRelative(badewanne, seconds += 2, new PropertyEntry(BADEWANNE_SCHALTEN, "true")); -// createRelative(badewanne, seconds += 2, new PropertyEntry(BADEWANNE_SCHALTEN, "false")); -// createRelative(badewanne, seconds += 2, new PropertyEntry(BADEWANNE_SCHALTEN, "true")); -// createRelative(badewanne, seconds += 2, new PropertyEntry(BADEWANNE_SCHALTEN, "false")); -// scheduleRepository.save(badewanne); + final Schedule badewanne = new Schedule(); + badewanne.setName("Badewanne"); + int seconds = 2; + createRelative(badewanne, seconds += 2, new PropertyEntry(BADEWANNE_SCHALTEN, "true")); + createRelative(badewanne, seconds += 2, new PropertyEntry(BADEWANNE_SCHALTEN, "false")); + createRelative(badewanne, seconds += 2, new PropertyEntry(BADEWANNE_SCHALTEN, "true")); + createRelative(badewanne, seconds += 2, new PropertyEntry(BADEWANNE_SCHALTEN, "false")); + scheduleRepository.save(badewanne); + } + + private void createKnxGroupIfNotExists(final String name, final GroupAddress address, final String dpt, final boolean readable) { + if (!knxGroupRepository.existsByAddressRaw(address.getRawAddress())) { + knxGroupWriteService.create(name, address, dpt, readable); + } } private ScheduleEntry createRelative(final Schedule schedule, final int inSeconds, final Map.Entry... entries) { diff --git a/src/main/java/de/ph87/homeautomation/knx/KnxThreadService.java b/src/main/java/de/ph87/homeautomation/knx/KnxThreadService.java index f76c055..75bf2b4 100644 --- a/src/main/java/de/ph87/homeautomation/knx/KnxThreadService.java +++ b/src/main/java/de/ph87/homeautomation/knx/KnxThreadService.java @@ -129,14 +129,14 @@ public class KnxThreadService extends AbstractThreadService implements NetworkLi @Override public void groupReadResponse(final ProcessEvent processEvent) { synchronized (databaseAccessLock) { - knxGroupWriteService.updateOrCreate(processEvent.getDestination().getRawAddress(), processEvent.getASDU()); + knxGroupWriteService.updateIfExists(processEvent.getDestination().getRawAddress(), processEvent.getASDU()); } } @Override public void groupWrite(final ProcessEvent processEvent) { synchronized (databaseAccessLock) { - knxGroupWriteService.updateOrCreate(processEvent.getDestination().getRawAddress(), processEvent.getASDU()); + knxGroupWriteService.updateIfExists(processEvent.getDestination().getRawAddress(), processEvent.getASDU()); } } diff --git a/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupLinkService.java b/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupLinkService.java index 83d824c..0c57337 100644 --- a/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupLinkService.java +++ b/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupLinkService.java @@ -47,7 +47,7 @@ public class KnxGroupLinkService { knxGroup.getSend().setErrorCount(0); knxGroup.getSend().setErrorMessage(null); knxGroup.getSend().setNextTimestamp(null); - log.debug("Successfully sent KnxGroup: {}", knxGroup); + log.info("Successfully sent KnxGroup: {}", knxGroup); return true; } catch (KNXFormatException e) { log.error(e.toString()); diff --git a/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupRepository.java b/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupRepository.java index b0c3c8e..8d1eaf1 100644 --- a/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupRepository.java +++ b/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupRepository.java @@ -20,4 +20,6 @@ public interface KnxGroupRepository extends CrudRepository { Optional findFirstByRead_NextTimestampNotNullOrderByRead_NextTimestampAsc(); + boolean existsByAddressRaw(int rawAddress); + } diff --git a/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupWriteService.java b/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupWriteService.java index af0e240..40fe28a 100644 --- a/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupWriteService.java +++ b/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupWriteService.java @@ -25,32 +25,27 @@ public class KnxGroupWriteService { private final KnxGroupRepository knxGroupRepository; - public void updateOrCreate(final int rawAddress, final byte[] data) { - final KnxGroup knxGroup = getOrCreate(rawAddress); - knxGroup.setValue(data); - knxGroup.setValueTimestamp(ZonedDateTime.now()); - knxGroup.setBooleanValue(null); - knxGroup.setNumberValue(null); - try { - final DPTXlator translator = findTranslator(knxGroup); - translator.setData(data); - if (translator instanceof DPTXlatorBoolean) { - knxGroup.setBooleanValue(((DPTXlatorBoolean) translator).getValueBoolean()); - } - // TODO implement all DPTXlator... - } catch (NoTranslatorException e) { - log.error(e.getMessage()); + public void updateIfExists(final int rawAddress, final byte[] data) { + final Optional knxGroupOptional = knxGroupRepository.findByAddressRaw(rawAddress); + if (knxGroupOptional.isEmpty()) { + log.debug("No KnxGroup with address={}", new GroupAddress(rawAddress)); } - log.debug("KnxGroup updated: {}", knxGroup); - } - - private KnxGroup getOrCreate(final int rawAddress) { - return knxGroupRepository.findByAddressRaw(rawAddress).orElseGet(() -> { - final KnxGroup trans = new KnxGroup(); - trans.setAddress(rawAddress); - final KnxGroup saved = knxGroupRepository.save(trans); - log.info("KnxGroup created: {}", saved); - return saved; + knxGroupOptional.ifPresent(knxGroup -> { + knxGroup.setValue(data); + knxGroup.setValueTimestamp(ZonedDateTime.now()); + knxGroup.setBooleanValue(null); + knxGroup.setNumberValue(null); + try { + final DPTXlator translator = findTranslator(knxGroup); + translator.setData(data); + if (translator instanceof DPTXlatorBoolean) { + knxGroup.setBooleanValue(((DPTXlatorBoolean) translator).getValueBoolean()); + } + // TODO implement all DPTXlator... + } catch (NoTranslatorException e) { + log.error(e.getMessage()); + } + log.debug("KnxGroup updated: {}", knxGroup); }); } @@ -58,10 +53,6 @@ public class KnxGroupWriteService { knxGroupRepository.findAllByRead_AbleTrue().forEach(knxGroup -> knxGroup.getRead().setNextTimestamp(ZonedDateTime.now())); } - public void create(final String name, final int main, final int middle, final int sub, final String dpt, final boolean readable) { - create(name, new GroupAddress(main, middle, sub), dpt, readable); - } - public void create(final String name, final GroupAddress address, final String dpt, final boolean readable) { final KnxGroup trans = new KnxGroup(); trans.setAddress(address); diff --git a/src/main/java/de/ph87/homeautomation/schedule/ScheduleThreadService.java b/src/main/java/de/ph87/homeautomation/schedule/ScheduleThreadService.java index f75513e..b46d6ad 100644 --- a/src/main/java/de/ph87/homeautomation/schedule/ScheduleThreadService.java +++ b/src/main/java/de/ph87/homeautomation/schedule/ScheduleThreadService.java @@ -27,8 +27,8 @@ public class ScheduleThreadService extends AbstractThreadService { @Override protected long doStep() throws InterruptedException { - scheduleWriteService.executeAllDue(); - return scheduleWriteService.getOverallNextTimestamp().map(nextTimestamp -> Duration.between(ZonedDateTime.now(), nextTimestamp).toMillis()).orElse(0L); + scheduleWriteService.executeAllLastDue(); + return scheduleWriteService.getNextTimestamp().map(nextTimestamp -> Duration.between(ZonedDateTime.now(), nextTimestamp).toMillis()).orElse(0L); } @Override diff --git a/src/main/java/de/ph87/homeautomation/schedule/ScheduleWriteService.java b/src/main/java/de/ph87/homeautomation/schedule/ScheduleWriteService.java index c23d8a8..05a27f5 100644 --- a/src/main/java/de/ph87/homeautomation/schedule/ScheduleWriteService.java +++ b/src/main/java/de/ph87/homeautomation/schedule/ScheduleWriteService.java @@ -39,22 +39,22 @@ public class ScheduleWriteService { public void calculateAllNext() { final ZonedDateTime now = ZonedDateTime.now(); - scheduleRepository.findAll().forEach(schedule -> schedule.getEntries().forEach(entry -> calculateNext(schedule, entry, now))); + scheduleRepository.findAll().forEach(schedule -> calculateSchedule(schedule, now)); } - public void executeAllDue() { + public void executeAllLastDue() { final ZonedDateTime now = ZonedDateTime.now(); - scheduleRepository.findAll().forEach(schedule -> executeIfDue(schedule, now)); + scheduleRepository.findAll().forEach(schedule -> executeLastDue(schedule, now)); } - private void executeIfDue(final Schedule schedule, final ZonedDateTime now) { + private void executeLastDue(final Schedule schedule, final ZonedDateTime now) { schedule.getEntries().stream() .filter(entry -> entry.getNextDateTime() != null && !entry.getNextDateTime().isAfter(now)) .max(Comparator.comparing(ScheduleEntry::getNextDateTime)) .ifPresent(entry -> { log.info("Executing ScheduleEntry {}", entry); - calculateNext(schedule, entry, now); entry.getProperties().forEach(this::applyPropertyMapEntry); + calculateSchedule(schedule, now); }); } @@ -66,24 +66,32 @@ public class ScheduleWriteService { } } - private void calculateNext(final Schedule schedule, final ScheduleEntry entry, final ZonedDateTime now) { + private void calculateSchedule(final Schedule schedule, final ZonedDateTime now) { + schedule.getEntries().forEach(scheduleEntry -> calculateEntry(schedule, scheduleEntry, now)); + schedule.getEntries().stream() + .filter(entry -> entry.getNextDateTime() != null && entry.getNextDateTime().isAfter(now)) + .min(Comparator.comparing(ScheduleEntry::getNextDateTime)) + .ifPresent(scheduleEntry -> log.info("Next schedule for \"{}\": {}", schedule.getName(), scheduleEntry.getNextDateTime())); + } + + private void calculateEntry(final Schedule schedule, final ScheduleEntry entry, final ZonedDateTime now) { log.debug("calculateNext \"{}\", {}:", schedule.getName(), entry); if (!entry.isEnabled() || !isAnyWeekdayEnabled(entry)) { entry.setNextDateTime(null); return; } ZonedDateTime midnight = now.withHour(0).withMinute(0).withSecond(0).withNano(0); - ZonedDateTime next = nextForDay(entry, midnight); + ZonedDateTime next = calculateEntryForDay(entry, midnight); while (next != null && (!next.isAfter(now) || !isWeekdayValid(entry, next))) { log.debug(" -- skipping: {}", next); midnight = midnight.plusDays(1); - next = nextForDay(entry, midnight); + next = calculateEntryForDay(entry, midnight); } log.debug(" => {}", next); entry.setNextDateTime(next); } - private ZonedDateTime nextForDay(final ScheduleEntry entry, final ZonedDateTime midnight) { + private ZonedDateTime calculateEntryForDay(final ScheduleEntry entry, final ZonedDateTime midnight) { switch (entry.getType()) { case TIME: return midnight.withHour(entry.getHour()).withMinute(entry.getMinute()).withSecond(entry.getSecond()); @@ -142,7 +150,7 @@ public class ScheduleWriteService { return false; } - public Optional getOverallNextTimestamp() { + public Optional getNextTimestamp() { return scheduleEntryRepository.findFirstNextDateTimeByNextDateTimeNotNullOrderByNextDateTimeAsc().map(ScheduleEntry::getNextDateTime); } diff --git a/src/main/java/de/ph87/homeautomation/shared/AbstractThreadService.java b/src/main/java/de/ph87/homeautomation/shared/AbstractThreadService.java index 17883aa..c8b564a 100644 --- a/src/main/java/de/ph87/homeautomation/shared/AbstractThreadService.java +++ b/src/main/java/de/ph87/homeautomation/shared/AbstractThreadService.java @@ -21,6 +21,8 @@ public abstract class AbstractThreadService { private final Object lock = new Object(); + private boolean started = false; + private boolean stopped = false; protected abstract String getThreadName(); @@ -35,6 +37,9 @@ public abstract class AbstractThreadService { @EventListener(ApplicationStartedEvent.class) public void afterStartup() { + synchronized (lock) { + started = true; + } thread.start(); } @@ -46,7 +51,7 @@ public abstract class AbstractThreadService { synchronized (lock) { lock.notifyAll(); try { - while (!stopped) { + while (started && !stopped) { lock.wait(); } } catch (InterruptedException e) {