-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
9ece064
commit b25988a
Showing
6 changed files
with
49 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...bootstrap/src/main/java/net/sf/dz3r/runtime/config/model/DirectorConfigurationParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
dependencies { | ||
|
||
api(project(":dz3r-common")) | ||
api(project(":dz3r-model")) | ||
api(project(":dz3r-scheduler")) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,7 +30,7 @@ | |
/** | ||
* Assembles all the components related to one hardware HVAC unit, connects them, and manages their lifecycles. | ||
* | ||
* @author Copyright © <a href="mailto:[email protected]">Vadim Tkachenko</a> 2001-2021 | ||
* @author Copyright © <a href="mailto:[email protected]">Vadim Tkachenko</a> 2001-2023 | ||
*/ | ||
public class UnitDirector implements Addressable<String>, AutoCloseable { | ||
|
||
|
@@ -70,7 +70,20 @@ public UnitDirector( | |
|
||
var scheduleFlux = Optional.ofNullable(scheduleUpdater) | ||
.map(u -> connectScheduler(sensorFlux2zone.values(), u)) | ||
.orElse(Flux.empty()); | ||
.orElseGet(() -> { | ||
logger.warn("{}: no scheduler provided, running defaults", getAddress()); | ||
return Flux.empty(); | ||
}); | ||
|
||
// This is necessary because... <facepalm> the architecture is screwed up and applying the schedule to the zone | ||
// is a side effect of consuming this flux. No wonder the schedule was only applied when the console was up, | ||
// it was the only consumer until now. | ||
// See https://github.com/home-climate-control/dz/issues/281 | ||
|
||
scheduleFlux | ||
.publishOn(Schedulers.newSingle("schedule-watcher-" + name)) | ||
.doOnNext(s -> logger.debug("{}: zone={}, event={}", name, s.getKey(), s.getValue())) | ||
.subscribe(); | ||
|
||
feed = connectFeeds(sensorFlux2zone, unitController, hvacDevice, hvacMode, scheduleFlux); | ||
|
||
|
@@ -146,16 +159,15 @@ private Feed connectFeeds( | |
|
||
private Flux<Map.Entry<String, Map.Entry<SchedulePeriod, ZoneSettings>>> connectScheduler(Collection<Zone> zones, ScheduleUpdater scheduleUpdater) { | ||
|
||
if (scheduleUpdater == null) { | ||
logger.warn("no scheduler provided, running defaults"); | ||
return Flux.empty(); | ||
} | ||
net.sf.dz3r.common.HCCObjects.requireNonNull(scheduleUpdater, "programming error, this should've been resolved up the call stack"); | ||
|
||
var name2zone = Flux.fromIterable(zones) | ||
.map(z -> new AbstractMap.SimpleEntry<>(z.getAddress(), z)) | ||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)) | ||
.block(); | ||
|
||
logger.info("{}: connected schedules: {}", getAddress(), name2zone); | ||
|
||
var scheduler = new Scheduler(name2zone); | ||
|
||
return scheduler.connect(scheduleUpdater.update()); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,7 +22,7 @@ | |
* Listens to the schedule event feed coming from {@link ScheduleUpdater}, and | ||
* passes the commands down to {@link net.sf.dz3r.model.Zone}s. | ||
* | ||
* @author Copyright © <a href="mailto:[email protected]">Vadim Tkachenko</a> 2001-2021 | ||
* @author Copyright © <a href="mailto:[email protected]">Vadim Tkachenko</a> 2001-2023 | ||
*/ | ||
public class Scheduler { | ||
|
||
|
@@ -59,17 +59,17 @@ public Flux<Map.Entry<String, Map.Entry<SchedulePeriod, ZoneSettings>>> connect( | |
|
||
// Observe | ||
var observe = source | ||
.publishOn(Schedulers.newSingle("schedule-observe")) | ||
.flatMap(this::updateSchedule) | ||
.flatMap(this::applySchedule) | ||
.doOnNext(s -> logger.info("scheduleObserve: {}", s)) | ||
.subscribeOn(Schedulers.boundedElastic()); | ||
.doOnNext(s -> logger.info("scheduleObserve: {}", s)); | ||
|
||
// Execute | ||
var execute = Flux.interval(scheduleGranularity, Schedulers.boundedElastic()) | ||
.publishOn(Schedulers.newSingle("schedule-execute")) | ||
.flatMap(s -> Flux.fromIterable(zone2schedule.entrySet())) | ||
.flatMap(this::applySchedule) | ||
.doOnNext(s -> logger.info("scheduleExecute: {}", s)) | ||
.subscribeOn(Schedulers.boundedElastic()); | ||
.doOnNext(s -> logger.info("scheduleExecute: {}", s)); | ||
|
||
return Flux | ||
.merge(observe, execute) | ||
|
@@ -91,6 +91,22 @@ private Flux<Map.Entry<Zone, SortedMap<SchedulePeriod, ZoneSettings>>> updateSch | |
return Flux.just(new AbstractMap.SimpleEntry<>(zone, schedule)); | ||
} | ||
|
||
/** | ||
* Apply a period to a zone, possibly. | ||
* | ||
* @param source Mapping from a zone to a set of their periods. | ||
* | ||
* @return Status update. Values are as follows: | ||
* | ||
* <ul> | ||
* <li>Nothing if the zone is on hold;</li> | ||
* <li>Nothing if the zone is already at current period;</li> | ||
* <li>Mapping of the zone name to period and settings upon a change;</li> | ||
* <li>Mapping of the zone name to {@code null} if there is no active period.</li> | ||
* </ul> | ||
* | ||
* VT: FIXME: The above looks weird, need refactoring. | ||
*/ | ||
private synchronized Flux<Map.Entry<String, Map.Entry<SchedulePeriod, ZoneSettings>>> applySchedule(Map.Entry<Zone, SortedMap<SchedulePeriod, ZoneSettings>> source) { | ||
|
||
ThreadContext.push("applySchedule"); | ||
|