mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[nikobus] added option to set rollershutter position (#11548)
Signed-off-by: Boris Krivonog boris.krivonog@inova.si Signed-off-by: Boris Krivonog <boris.krivonog@inova.si>
This commit is contained in:
parent
666214749b
commit
edafc1970b
@ -14,6 +14,7 @@ package org.openhab.binding.nikobus.internal.handler;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Future;
|
||||
@ -22,6 +23,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.nikobus.internal.utils.Utils;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.PercentType;
|
||||
import org.openhab.core.library.types.StopMoveType;
|
||||
@ -45,7 +47,6 @@ import org.slf4j.LoggerFactory;
|
||||
public class NikobusRollershutterModuleHandler extends NikobusModuleHandler {
|
||||
private final Logger logger = LoggerFactory.getLogger(NikobusRollershutterModuleHandler.class);
|
||||
private final List<PositionEstimator> positionEstimators = new CopyOnWriteArrayList<>();
|
||||
|
||||
private final Map<String, DirectionConfiguration> directionConfigurations = new ConcurrentHashMap<>();
|
||||
|
||||
public NikobusRollershutterModuleHandler(Thing thing) {
|
||||
@ -77,8 +78,65 @@ public class NikobusRollershutterModuleHandler extends NikobusModuleHandler {
|
||||
logger.debug("Position estimators for {} = {}", thing.getUID(), positionEstimators);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
positionEstimators.forEach(PositionEstimator::destroy);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int valueFromCommand(String channelId, Command command) {
|
||||
Optional<PositionEstimator> positionEstimator = getPositionEstimator(channelId);
|
||||
if (command instanceof DecimalType) {
|
||||
return positionEstimator.map(estimator -> {
|
||||
return estimator.processSetPosition(((DecimalType) command).intValue());
|
||||
}).orElseThrow(() -> {
|
||||
throw new IllegalArgumentException(
|
||||
"Received position request but no estimation configured for channel " + channelId);
|
||||
});
|
||||
}
|
||||
int result = convertCommandToValue(channelId, command);
|
||||
positionEstimator.ifPresent(PositionEstimator::cancelStopMovement);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected State stateFromValue(String channelId, int value) {
|
||||
if (value == 0x00) {
|
||||
return OnOffType.OFF;
|
||||
}
|
||||
DirectionConfiguration configuration = getDirectionConfiguration(channelId);
|
||||
if (value == configuration.up) {
|
||||
return UpDownType.UP;
|
||||
}
|
||||
if (value == configuration.down) {
|
||||
return UpDownType.DOWN;
|
||||
}
|
||||
throw new IllegalArgumentException("Unexpected value " + value + " received");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateState(ChannelUID channelUID, State state) {
|
||||
logger.debug("updateState {} {}", channelUID, state);
|
||||
|
||||
getPositionEstimator(channelUID.getId()).ifPresentOrElse(estimator -> {
|
||||
if (state == UpDownType.UP) {
|
||||
estimator.start(-1);
|
||||
} else if (state == UpDownType.DOWN) {
|
||||
estimator.start(1);
|
||||
} else if (state == OnOffType.OFF) {
|
||||
estimator.stop();
|
||||
} else {
|
||||
logger.debug("Unexpected state update '{}' for '{}'", state, channelUID);
|
||||
}
|
||||
}, () -> super.updateState(channelUID, state));
|
||||
}
|
||||
|
||||
private void updateState(ChannelUID channelUID, int percent) {
|
||||
super.updateState(channelUID, new PercentType(percent));
|
||||
}
|
||||
|
||||
protected int convertCommandToValue(String channelId, Command command) {
|
||||
if (command == StopMoveType.STOP) {
|
||||
return 0x00;
|
||||
}
|
||||
@ -91,43 +149,9 @@ public class NikobusRollershutterModuleHandler extends NikobusModuleHandler {
|
||||
throw new IllegalArgumentException("Command '" + command + "' not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected State stateFromValue(String channelId, int value) {
|
||||
if (value == 0x00) {
|
||||
return OnOffType.OFF;
|
||||
}
|
||||
|
||||
DirectionConfiguration configuration = getDirectionConfiguration(channelId);
|
||||
if (value == configuration.up) {
|
||||
return UpDownType.UP;
|
||||
}
|
||||
if (value == configuration.down) {
|
||||
return UpDownType.DOWN;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unexpected value " + value + " received");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateState(ChannelUID channelUID, State state) {
|
||||
logger.debug("updateState {} {}", channelUID, state);
|
||||
|
||||
positionEstimators.stream().filter(estimator -> channelUID.equals(estimator.getChannelUID())).findFirst()
|
||||
.ifPresentOrElse(estimator -> {
|
||||
if (state == UpDownType.UP) {
|
||||
estimator.start(-1);
|
||||
} else if (state == UpDownType.DOWN) {
|
||||
estimator.start(1);
|
||||
} else if (state == OnOffType.OFF) {
|
||||
estimator.stop();
|
||||
} else {
|
||||
logger.debug("Unexpected state update '{}' for '{}'", state, channelUID);
|
||||
}
|
||||
}, () -> super.updateState(channelUID, state));
|
||||
}
|
||||
|
||||
private void updateState(ChannelUID channelUID, int percent) {
|
||||
super.updateState(channelUID, new PercentType(percent));
|
||||
private Optional<PositionEstimator> getPositionEstimator(String channelId) {
|
||||
return positionEstimators.stream().filter(estimator -> channelId.equals(estimator.getChannelUID().getId()))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
private DirectionConfiguration getDirectionConfiguration(String channelId) {
|
||||
@ -154,6 +178,7 @@ public class NikobusRollershutterModuleHandler extends NikobusModuleHandler {
|
||||
private long startTimeMillis = 0;
|
||||
private int direction = 0;
|
||||
private @Nullable Future<?> updateEstimateFuture;
|
||||
private @Nullable Future<?> stopMovementFuture;
|
||||
|
||||
PositionEstimator(ChannelUID channelUID, PositionEstimatorConfig config) {
|
||||
this.channelUID = channelUID;
|
||||
@ -167,6 +192,12 @@ public class NikobusRollershutterModuleHandler extends NikobusModuleHandler {
|
||||
return channelUID;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
Utils.cancel(updateEstimateFuture);
|
||||
updateEstimateFuture = null;
|
||||
cancelStopMovement();
|
||||
}
|
||||
|
||||
public void start(int direction) {
|
||||
stop();
|
||||
synchronized (this) {
|
||||
@ -191,6 +222,41 @@ public class NikobusRollershutterModuleHandler extends NikobusModuleHandler {
|
||||
}
|
||||
}
|
||||
|
||||
public int processSetPosition(int percent) {
|
||||
if (percent < 0 || percent > 100) {
|
||||
throw new IllegalArgumentException("Position % out of range - expecting [0, 100] but got " + percent
|
||||
+ " for " + channelUID.getId());
|
||||
}
|
||||
|
||||
cancelStopMovement();
|
||||
|
||||
int newPosition = (int) ((double) percent * (double) durationInMillis / 100.0 + 0.5);
|
||||
int delta = position - newPosition;
|
||||
|
||||
logger.debug("Position set command {} for {}: delta = {}, current pos: {}, new position: {}", percent,
|
||||
channelUID, delta, position, newPosition);
|
||||
|
||||
if (delta == 0) {
|
||||
return convertCommandToValue(channelUID.getId(), StopMoveType.STOP);
|
||||
}
|
||||
|
||||
int time = Math.abs(delta);
|
||||
if (percent == 0 || percent == 100) {
|
||||
time += 5000; // Make sure we get to completely open/closed position.
|
||||
}
|
||||
|
||||
stopMovementFuture = scheduler.schedule(() -> {
|
||||
handleCommand(channelUID, StopMoveType.STOP);
|
||||
}, time, TimeUnit.MILLISECONDS);
|
||||
|
||||
return convertCommandToValue(channelUID.getId(), delta > 0 ? UpDownType.UP : UpDownType.DOWN);
|
||||
}
|
||||
|
||||
public void cancelStopMovement() {
|
||||
Utils.cancel(stopMovementFuture);
|
||||
stopMovementFuture = null;
|
||||
}
|
||||
|
||||
private void updateEstimate() {
|
||||
int direction;
|
||||
int ellapsedMillis;
|
||||
|
Loading…
Reference in New Issue
Block a user