I have multiple Observable<Boolean>
delivering data from "alert sensors". They are delivering only value changes. How to wait until all of them switch to false
which would indicate there is no alert anymore?
Asked
Active
Viewed 131 times
2 Answers
2
Use Observable.combineLatest()
in conjunction with Observable.filter()
for that scenario:
Observale<Boolean> source1 = TODO();
Observale<Boolean> source2 = TODO();
Observale<Boolean> source3 = TODO();
Observable
.combineLatest(source1, source2, source3, (value1. value2, value3) -> {
return value1 || value2 || value3;
})
.filter(combinedValue -> combinedValue == false)
.subscribe(TODO())

ConstOrVar
- 2,025
- 1
- 11
- 14
-
Your response helped me greatly to find the solution, however there is one problem with it. It would work if the stream of boolean "alerts" was continuous. But it is only happening on changes in sensor state, as I stated in the question. Therefore I had to make sure that all the sources have some initial `true` state which is also propagated. – morisil May 22 '20 at 09:52
-
I posted my solution. Maybe there is an easier way to do it? Please feel free to update your answer and I will accept it. – morisil May 22 '20 at 10:03
0
@ConstOrVar's answer helped me a lot, but actually I had to add one element to it. Because my Observables
are delivering new state only on actual value changes I had to make sure that there is some reference initial state to operate on in combineLatest
():
val oneTruth = Observable.just(true)
Observables
.combineLatest(
oneTruth.concatWith(events.cliffLeft),
oneTruth.concatWith(events.cliffFrontLeft),
oneTruth.concatWith(events.cliffFrontRight),
oneTruth.concatWith(events.cliffRight),
oneTruth.concatWith(events.wheelDropLeft),
oneTruth.concatWith(events.wheelDropRight)
) { v0, v1, v2, v3, v4, v5 ->
(v0 || v1 || v2 || v3 || v4 || v5)
}
.filter { danger -> !danger }
.filter { state.oiMode == OiMode.PASSIVE }
.subscribe {
logger.debug { "Bringing Roomba back to safe mode" }
roomba.safeMode()
}
Note: it's Kotlin code using rxkotlin
syntactic sugar for combineLatest

morisil
- 1,345
- 8
- 19
-
1You should use `events.cliffLeft.startWith(true)` instead or each of those Observables upon subscription should return `true` straight away. Have you thought of using a `BehaviorSubject.createDefault` for them perhaps? – ExpensiveBelly May 23 '20 at 21:17
-
Good point, but actually there is only one subscription for this one anyway. And thanks for the `BehaviorSubject.createDefault` tip. In this app it's rather not an option as all the event streams, and there is more of them, are created in generic way. – morisil May 24 '20 at 11:41