I have a motionSensor, which offers me a Subject
with a boolean
value. true
, when movement was detected and false
when the sensor doesn't detect anything after a fixed, non-changeable timerange.
I want to turn lights on movement, but the lights should stay on for a given period. false
should be delayed.
If a true
-value was emitted, while the delay is "delaying", then nothing should happen (aka the lights should stay on).
Consider this table
time t | emitted value | action |
---|---|---|
1 | true | turn lights on |
2 | false | do nothing |
3 | none emitted | turn lights off |
4 | true | turn lights on |
5 | false | do nothing |
6 | true | do nothing |
Here is some pseudo-code:
motionSensor.isMoving$()
// delayWhen-method does not exsit
.delayWhen(Duration.of(5, MINUTES), isMoving -> !isMoving)
.distinctUntilChanged()
.subscribe(isMoving -> {
if (isMoving) {
turnLightsOn();
} else {
turnLightsOff();
});
I need it in this Github Project
I found no operator, so I wrote it as a manual style.
Subject<Boolean> isMoving$ = getSubject();
isMoving$
.switchMap(value -> isMoving
? Observable.just(isMoving)
: Observable.just(isMoving).delay(5, TimeUnit.MINUTES))
.distinctUntilChanged()
.subscribe(isMoving -> isMoving ? turnLightsOn() : turnLightsOff());
Special note: IntelliJ is confused by this code. If it warns you, you can ignore it.