Skip to content
This repository has been archived by the owner on May 7, 2020. It is now read-only.

Commit

Permalink
[LIFX] Update ThingStatus at most once a second (#3816)
Browse files Browse the repository at this point in the history
* Update LIFX ThingStatus only when changed
* Use 1 second interval for unchanged ThingStatusInfo updates and rework code to use Java 8 Durations

Signed-off-by: Wouter Born <eclipse@maindrain.net>
  • Loading branch information
wborn authored and sjsf committed Jul 10, 2017
1 parent 5c5c7ba commit 6b91d19
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 27 deletions.
Expand Up @@ -10,6 +10,9 @@
import static org.eclipse.smarthome.binding.lifx.LifxBindingConstants.*;
import static org.eclipse.smarthome.binding.lifx.internal.LifxUtils.increaseDecreasePercentType;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
Expand Down Expand Up @@ -47,6 +50,7 @@
import org.eclipse.smarthome.core.thing.Thing;
import org.eclipse.smarthome.core.thing.ThingStatus;
import org.eclipse.smarthome.core.thing.ThingStatusDetail;
import org.eclipse.smarthome.core.thing.ThingStatusInfo;
import org.eclipse.smarthome.core.thing.binding.BaseThingHandler;
import org.eclipse.smarthome.core.types.Command;
import org.eclipse.smarthome.core.types.RefreshType;
Expand All @@ -68,24 +72,28 @@ public class LifxLightHandler extends BaseThingHandler implements LifxProperties

private final Logger logger = LoggerFactory.getLogger(LifxLightHandler.class);

private static final long FADE_TIME_DEFAULT = 300;
private static final int MAX_STATE_CHANGE_DURATION = 4000;
private static final Duration FADE_TIME_DEFAULT = Duration.ofMillis(300);
private static final Duration MIN_STATUS_INFO_UPDATE_INTERVAL = Duration.ofSeconds(1);
private static final Duration MAX_STATE_CHANGE_DURATION = Duration.ofSeconds(4);

private final LifxChannelFactory channelFactory;
private Products product;

private long fadeTime = FADE_TIME_DEFAULT;
private Duration fadeTime = FADE_TIME_DEFAULT;
private PercentType powerOnBrightness;

private MACAddress macAddress;
private String macAsHex;

private final ReentrantLock lock = new ReentrantLock();

private Map<String, State> channelStates;
private CurrentLightState currentLightState;
private LifxLightState pendingLightState;

private Map<String, State> channelStates;
private ThingStatusInfo statusInfo;
private LocalDateTime lastStatusInfoUpdate = LocalDateTime.MIN;

private LifxLightCommunicationHandler communicationHandler;
private LifxLightCurrentStateUpdater currentStateUpdater;
private LifxLightStateChanger lightStateChanger;
Expand All @@ -103,15 +111,15 @@ public boolean isOffline() {
}

public void setOnline() {
updateStatus(ThingStatus.ONLINE);
updateStatusIfChanged(ThingStatus.ONLINE);
}

public void setOffline() {
updateStatus(ThingStatus.OFFLINE);
updateStatusIfChanged(ThingStatus.OFFLINE);
}

public void setOfflineByCommunicationError() {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
updateStatusIfChanged(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
}

@Override
Expand Down Expand Up @@ -280,17 +288,9 @@ public void dispose() {
}
}

private long getFadeTime() {
Object fadeCfg = getConfig().get(LifxBindingConstants.CONFIG_PROPERTY_FADETIME);
if (fadeCfg == null) {
return FADE_TIME_DEFAULT;
}
try {
return Long.parseLong(fadeCfg.toString());
} catch (NumberFormatException e) {
logger.warn("Invalid value '{}' for transition time, using default instead.", fadeCfg.toString());
return FADE_TIME_DEFAULT;
}
private Duration getFadeTime() {
BigDecimal fadeCfg = (BigDecimal) getConfig().get(LifxBindingConstants.CONFIG_PROPERTY_FADETIME);
return fadeCfg == null ? FADE_TIME_DEFAULT : Duration.ofMillis(fadeCfg.longValue());
}

private PercentType getPowerOnBrightness() {
Expand Down Expand Up @@ -483,7 +483,7 @@ private LifxLightState getLightStateForCommand() {
}

private boolean isStateChangePending() {
return pendingLightState.getMillisSinceLastChange() < MAX_STATE_CHANGE_DURATION;
return pendingLightState.getDurationSinceLastChange().minus(MAX_STATE_CHANGE_DURATION).isNegative();
}

private void handleTemperatureCommand(PercentType temperature) {
Expand Down Expand Up @@ -573,4 +573,20 @@ private void updateStateIfChanged(String channel, State newState) {
}
}

private void updateStatusIfChanged(ThingStatus status) {
updateStatusIfChanged(status, ThingStatusDetail.NONE);
}

private void updateStatusIfChanged(ThingStatus status, ThingStatusDetail statusDetail) {
ThingStatusInfo newStatusInfo = new ThingStatusInfo(status, statusDetail, null);
Duration durationSinceLastUpdate = Duration.between(lastStatusInfoUpdate, LocalDateTime.now());
boolean intervalElapsed = MIN_STATUS_INFO_UPDATE_INTERVAL.minus(durationSinceLastUpdate).isNegative();

if (statusInfo == null || !statusInfo.equals(newStatusInfo) || intervalElapsed) {
statusInfo = newStatusInfo;
lastStatusInfoUpdate = LocalDateTime.now();
updateStatus(status, statusDetail);
}
}

}
Expand Up @@ -9,6 +9,8 @@

import static org.eclipse.smarthome.binding.lifx.LifxBindingConstants.DEFAULT_COLOR;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
Expand All @@ -33,7 +35,7 @@ public class LifxLightState {
private PercentType infrared;
private SignalStrength signalStrength;

private long lastChange;
private LocalDateTime lastChange = LocalDateTime.MIN;

private List<LifxLightStateListener> listeners = new CopyOnWriteArrayList<>();

Expand Down Expand Up @@ -184,11 +186,11 @@ public void setSignalStrength(SignalStrength newSignalStrength) {
}

private void updateLastChange() {
lastChange = System.currentTimeMillis();
lastChange = LocalDateTime.now();
}

public long getMillisSinceLastChange() {
return System.currentTimeMillis() - lastChange;
public Duration getDurationSinceLastChange() {
return Duration.between(lastChange, LocalDateTime.now());
}

public void addListener(LifxLightStateListener listener) {
Expand Down
Expand Up @@ -10,6 +10,7 @@
import static org.eclipse.smarthome.binding.lifx.LifxBindingConstants.PACKET_INTERVAL;
import static org.eclipse.smarthome.binding.lifx.internal.LifxUtils.*;

import java.time.Duration;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
Expand Down Expand Up @@ -68,7 +69,7 @@ public class LifxLightStateChanger implements LifxLightStateListener, LifxRespon
private final ScheduledExecutorService scheduler;
private final LifxLightState pendingLightState;
private final LifxLightCommunicationHandler communicationHandler;
private final long fadeTime;
private final Duration fadeTime;
private final Products product;

private final ReentrantLock lock = new ReentrantLock();
Expand Down Expand Up @@ -129,7 +130,7 @@ public void run() {

public LifxLightStateChanger(MACAddress macAddress, ScheduledExecutorService scheduler,
LifxLightState pendingLightState, LifxLightCommunicationHandler communicationHandler, Products product,
long fadeTime) {
Duration fadeTime) {
this.macAsHex = macAddress.getHex();
this.scheduler = scheduler;
this.pendingLightState = pendingLightState;
Expand Down Expand Up @@ -277,14 +278,15 @@ private PendingPacket removeAcknowledgedPacket(int sequenceNumber) {
@Override
public void handleColorsChange(HSBK[] oldColors, HSBK[] newColors) {
if (sameColors(newColors)) {
SetColorRequest packet = new SetColorRequest(pendingLightState.getColors()[0], fadeTime);
SetColorRequest packet = new SetColorRequest(pendingLightState.getColors()[0], fadeTime.toMillis());
removePacketsByType(SetColorZonesRequest.TYPE);
replacePacketsInMap(packet);
} else {
List<SetColorZonesRequest> packets = new ArrayList<>();
for (int i = 0; i < newColors.length; i++) {
if (newColors[i] != null && !newColors[i].equals(oldColors[i])) {
packets.add(new SetColorZonesRequest(i, newColors[i], fadeTime, ApplicationRequest.APPLY));
packets.add(
new SetColorZonesRequest(i, newColors[i], fadeTime.toMillis(), ApplicationRequest.APPLY));
}
}
if (!packets.isEmpty()) {
Expand Down

0 comments on commit 6b91d19

Please sign in to comment.