Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lifx] Support HEV clean cycle #11262

Merged
merged 1 commit into from
Sep 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 78 additions & 53 deletions bundles/org.openhab.binding.lifx/README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
package org.openhab.binding.lifx.internal;

import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.lifx.internal.fields.HSBK;
Expand Down Expand Up @@ -55,6 +53,7 @@ public class LifxBindingConstants {
public static final String CHANNEL_COLOR = "color";
public static final String CHANNEL_COLOR_ZONE = "colorzone";
public static final String CHANNEL_EFFECT = "effect";
public static final String CHANNEL_HEV_CYCLE = "hevcycle";
public static final String CHANNEL_INFRARED = "infrared";
public static final String CHANNEL_SIGNAL_STRENGTH = "signalstrength";
public static final String CHANNEL_TEMPERATURE = "temperature";
Expand All @@ -80,11 +79,12 @@ public class LifxBindingConstants {
public static final String CONFIG_PROPERTY_FADETIME = "fadetime";

// Config property for channel configuration
public static final String CONFIG_PROPERTY_HEV_CYCLE_DURATION = "hevCycleDuration";
public static final String CONFIG_PROPERTY_EFFECT_FLAME_SPEED = "effectFlameSpeed";
public static final String CONFIG_PROPERTY_EFFECT_MORPH_SPEED = "effectMorphSpeed";
public static final String CONFIG_PROPERTY_POWER_ON_BRIGHTNESS = "powerOnBrightness";
public static final String CONFIG_PROPERTY_POWER_ON_COLOR = "powerOnColor";
public static final String CONFIG_PROPERTY_POWER_ON_TEMPERATURE = "powerOnTemperature";
public static final String CONFIG_PROPERTY_EFFECT_MORPH_SPEED = "effectMorphSpeed";
public static final String CONFIG_PROPERTY_EFFECT_FLAME_SPEED = "effectFlameSpeed";

// Property keys
public static final String PROPERTY_HOST = "host";
Expand All @@ -100,12 +100,13 @@ public class LifxBindingConstants {

// List of all Thing Type UIDs
public static final ThingTypeUID THING_TYPE_COLORLIGHT = new ThingTypeUID(BINDING_ID, "colorlight");
public static final ThingTypeUID THING_TYPE_COLORHEVLIGHT = new ThingTypeUID(BINDING_ID, "colorhevlight");
public static final ThingTypeUID THING_TYPE_COLORIRLIGHT = new ThingTypeUID(BINDING_ID, "colorirlight");
public static final ThingTypeUID THING_TYPE_COLORMZLIGHT = new ThingTypeUID(BINDING_ID, "colormzlight");
public static final ThingTypeUID THING_TYPE_WHITELIGHT = new ThingTypeUID(BINDING_ID, "whitelight");
public static final ThingTypeUID THING_TYPE_TILELIGHT = new ThingTypeUID(BINDING_ID, "tilelight");
public static final ThingTypeUID THING_TYPE_WHITELIGHT = new ThingTypeUID(BINDING_ID, "whitelight");

public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Stream.of(THING_TYPE_COLORLIGHT,
THING_TYPE_COLORIRLIGHT, THING_TYPE_COLORMZLIGHT, THING_TYPE_WHITELIGHT, THING_TYPE_TILELIGHT)
.collect(Collectors.toSet());
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_COLORLIGHT,
THING_TYPE_COLORHEVLIGHT, THING_TYPE_COLORIRLIGHT, THING_TYPE_COLORMZLIGHT, THING_TYPE_TILELIGHT,
THING_TYPE_WHITELIGHT);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.lifx.internal.LifxProduct.Features;
import org.openhab.binding.lifx.internal.dto.GetColorZonesRequest;
import org.openhab.binding.lifx.internal.dto.GetHevCycleRequest;
import org.openhab.binding.lifx.internal.dto.GetLightInfraredRequest;
import org.openhab.binding.lifx.internal.dto.GetRequest;
import org.openhab.binding.lifx.internal.dto.GetTileEffectRequest;
import org.openhab.binding.lifx.internal.dto.GetWifiInfoRequest;
import org.openhab.binding.lifx.internal.dto.HevCycleState;
import org.openhab.binding.lifx.internal.dto.Packet;
import org.openhab.binding.lifx.internal.dto.StateHevCycleResponse;
import org.openhab.binding.lifx.internal.dto.StateLightInfraredResponse;
import org.openhab.binding.lifx.internal.dto.StateLightPowerResponse;
import org.openhab.binding.lifx.internal.dto.StateMultiZoneResponse;
Expand Down Expand Up @@ -133,6 +136,9 @@ public void stop() {
private void sendLightStateRequests() {
communicationHandler.sendPacket(new GetRequest());

if (features.hasFeature(HEV)) {
communicationHandler.sendPacket(new GetHevCycleRequest());
}
if (features.hasFeature(INFRARED)) {
communicationHandler.sendPacket(new GetLightInfraredRequest());
}
Expand All @@ -157,14 +163,16 @@ public void handleResponsePacket(Packet packet) {
handlePowerStatus((StatePowerResponse) packet);
} else if (packet instanceof StateLightPowerResponse) {
handleLightPowerStatus((StateLightPowerResponse) packet);
} else if (packet instanceof StateHevCycleResponse) {
handleHevCycleStatus((StateHevCycleResponse) packet);
} else if (packet instanceof StateLightInfraredResponse) {
handleInfraredStatus((StateLightInfraredResponse) packet);
} else if (packet instanceof StateMultiZoneResponse) {
handleMultiZoneStatus((StateMultiZoneResponse) packet);
} else if (packet instanceof StateWifiInfoResponse) {
handleWifiInfoStatus((StateWifiInfoResponse) packet);
} else if (packet instanceof StateTileEffectResponse) {
handleTileEffectStatus((StateTileEffectResponse) packet);
} else if (packet instanceof StateWifiInfoResponse) {
handleWifiInfoStatus((StateWifiInfoResponse) packet);
}

currentLightState.setOnline();
Expand Down Expand Up @@ -192,6 +200,11 @@ private void handleLightPowerStatus(StateLightPowerResponse packet) {
currentLightState.setPowerState(packet.getState());
}

private void handleHevCycleStatus(StateHevCycleResponse packet) {
HevCycleState hevCycleState = new HevCycleState(!packet.getRemaining().isZero(), packet.getDuration());
currentLightState.setHevCycleState(hevCycleState);
}

private void handleInfraredStatus(StateLightInfraredResponse packet) {
PercentType infrared = infraredToPercentType(packet.getInfrared());
currentLightState.setInfrared(infrared);
Expand All @@ -209,11 +222,11 @@ private void handleMultiZoneStatus(StateMultiZoneResponse packet) {
currentLightState.setColors(colors);
}

private void handleWifiInfoStatus(StateWifiInfoResponse packet) {
currentLightState.setSignalStrength(packet.getSignalStrength());
}

private void handleTileEffectStatus(StateTileEffectResponse packet) {
currentLightState.setTileEffect(packet.getEffect());
}

private void handleWifiInfoStatus(StateWifiInfoResponse packet) {
currentLightState.setSignalStrength(packet.getSignalStrength());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.lifx.internal.dto.Effect;
import org.openhab.binding.lifx.internal.dto.HevCycleState;
import org.openhab.binding.lifx.internal.dto.PowerState;
import org.openhab.binding.lifx.internal.dto.SignalStrength;
import org.openhab.binding.lifx.internal.fields.HSBK;
Expand All @@ -40,6 +41,7 @@
public class LifxLightState {

private HSBK[] colors = new HSBK[] { new HSBK(DEFAULT_COLOR) };
private @Nullable HevCycleState hevCycleState;
private @Nullable PercentType infrared;
private @Nullable PowerState powerState;
private @Nullable SignalStrength signalStrength;
Expand All @@ -51,6 +53,7 @@ public class LifxLightState {
public void copy(LifxLightState other) {
this.powerState = other.getPowerState();
this.colors = other.getColors();
this.hevCycleState = other.getHevCycleState();
this.infrared = other.getInfrared();
this.signalStrength = other.getSignalStrength();
this.tileEffect = other.getTileEffect();
Expand All @@ -76,6 +79,10 @@ public HSBK[] getColors() {
return colorsCopy;
}

public @Nullable HevCycleState getHevCycleState() {
return hevCycleState;
}

public @Nullable PercentType getInfrared() {
return infrared;
}
Expand Down Expand Up @@ -158,6 +165,13 @@ public void setTemperature(int kelvin, int zoneIndex) {
setColor(newColor, zoneIndex);
}

public void setHevCycleState(HevCycleState newHevCycleState) {
HevCycleState oldHevCycleState = this.hevCycleState;
this.hevCycleState = newHevCycleState;
updateLastChange();
listeners.forEach(listener -> listener.handleHevCycleStateChange(oldHevCycleState, newHevCycleState));
}

public void setInfrared(PercentType newInfrared) {
PercentType oldInfrared = this.infrared;
this.infrared = newInfrared;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,16 @@
import org.openhab.binding.lifx.internal.dto.ApplicationRequest;
import org.openhab.binding.lifx.internal.dto.Effect;
import org.openhab.binding.lifx.internal.dto.GetColorZonesRequest;
import org.openhab.binding.lifx.internal.dto.GetHevCycleRequest;
import org.openhab.binding.lifx.internal.dto.GetLightInfraredRequest;
import org.openhab.binding.lifx.internal.dto.GetLightPowerRequest;
import org.openhab.binding.lifx.internal.dto.GetRequest;
import org.openhab.binding.lifx.internal.dto.HevCycleState;
import org.openhab.binding.lifx.internal.dto.Packet;
import org.openhab.binding.lifx.internal.dto.PowerState;
import org.openhab.binding.lifx.internal.dto.SetColorRequest;
import org.openhab.binding.lifx.internal.dto.SetColorZonesRequest;
import org.openhab.binding.lifx.internal.dto.SetHevCycleRequest;
import org.openhab.binding.lifx.internal.dto.SetLightInfraredRequest;
import org.openhab.binding.lifx.internal.dto.SetLightPowerRequest;
import org.openhab.binding.lifx.internal.dto.SetPowerRequest;
Expand Down Expand Up @@ -308,6 +311,17 @@ public void handlePowerStateChange(@Nullable PowerState oldPowerState, PowerStat
}
}

@Override
public void handleHevCycleStateChange(@Nullable HevCycleState oldHevCycleState, HevCycleState newHevCycleState) {
// The change should be ignored when both the old and new state are disabled regardless of the cycle duration
if (!newHevCycleState.equals(oldHevCycleState)
&& (oldHevCycleState == null || oldHevCycleState.isEnable() || newHevCycleState.isEnable())) {
SetHevCycleRequest packet = new SetHevCycleRequest(newHevCycleState.isEnable(),
newHevCycleState.getDuration());
replacePacketsInMap(packet);
}
}

@Override
public void handleInfraredChange(@Nullable PercentType oldInfrared, PercentType newInfrared) {
PercentType infrared = pendingLightState.getInfrared();
Expand All @@ -325,7 +339,7 @@ public void handleSignalStrengthChange(@Nullable SignalStrength oldSignalStrengt

@Override
public void handleTileEffectChange(@Nullable Effect oldEffect, Effect newEffect) {
if (oldEffect == null || !oldEffect.equals(newEffect)) {
if (!newEffect.equals(oldEffect)) {
SetTileEffectRequest packet = new SetTileEffectRequest(newEffect);
replacePacketsInMap(packet);
}
Expand Down Expand Up @@ -360,6 +374,13 @@ public void handleResponsePacket(Packet packet) {
getZonesIfZonesAreSet();
} else if (sentPacket instanceof SetColorZonesRequest) {
getZonesIfZonesAreSet();
} else if (sentPacket instanceof SetHevCycleRequest) {
scheduler.schedule(() -> {
GetHevCycleRequest hevCyclePacket = new GetHevCycleRequest();
communicationHandler.sendPacket(hevCyclePacket);
GetLightPowerRequest powerPacket = new GetLightPowerRequest();
communicationHandler.sendPacket(powerPacket);
}, 600, TimeUnit.MILLISECONDS);
} else if (sentPacket instanceof SetLightInfraredRequest) {
GetLightInfraredRequest infraredPacket = new GetLightInfraredRequest();
communicationHandler.sendPacket(infraredPacket);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,12 +371,14 @@ public Features getFeatures(String version) {

public ThingTypeUID getThingTypeUID() {
if (hasFeature(COLOR)) {
if (hasFeature(TILE_EFFECT)) {
return LifxBindingConstants.THING_TYPE_TILELIGHT;
if (hasFeature(HEV)) {
return LifxBindingConstants.THING_TYPE_COLORHEVLIGHT;
} else if (hasFeature(INFRARED)) {
return LifxBindingConstants.THING_TYPE_COLORIRLIGHT;
} else if (hasFeature(MULTIZONE)) {
return LifxBindingConstants.THING_TYPE_COLORMZLIGHT;
} else if (hasFeature(TILE_EFFECT)) {
return LifxBindingConstants.THING_TYPE_TILELIGHT;
} else {
return LifxBindingConstants.THING_TYPE_COLORLIGHT;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.lifx.internal.dto;

import java.nio.ByteBuffer;

/**
* @author Wouter Born - Initial contribution
*/
public class GetHevCycleConfigurationRequest extends Packet {

public static final int TYPE = 0x91;

public GetHevCycleConfigurationRequest() {
setTagged(false);
setAddressable(true);
setResponseRequired(true);
}

@Override
public int packetType() {
return TYPE;
}

@Override
protected int packetLength() {
return 0;
}

@Override
protected void parsePacket(ByteBuffer bytes) {
// do nothing
}

@Override
protected ByteBuffer packetBytes() {
return ByteBuffer.allocate(0);
}

@Override
public int[] expectedResponses() {
return new int[] { StateHevCycleConfigurationResponse.TYPE };
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.lifx.internal.dto;

import java.nio.ByteBuffer;

/**
* @author Wouter Born - Initial contribution
*/
public class GetHevCycleRequest extends Packet {

public static final int TYPE = 0x8E;

public GetHevCycleRequest() {
setTagged(false);
setAddressable(true);
setResponseRequired(true);
}

@Override
public int packetType() {
return TYPE;
}

@Override
protected int packetLength() {
return 0;
}

@Override
protected void parsePacket(ByteBuffer bytes) {
// do nothing
}

@Override
protected ByteBuffer packetBytes() {
return ByteBuffer.allocate(0);
}

@Override
public int[] expectedResponses() {
return new int[] { StateHevCycleResponse.TYPE };
}
}
Loading