2 * Copyright (c) 2010-2021 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.lifx.internal;
15 import static org.openhab.binding.lifx.internal.LifxBindingConstants.DEFAULT_COLOR;
17 import java.time.Duration;
18 import java.time.LocalDateTime;
19 import java.util.Arrays;
20 import java.util.List;
21 import java.util.concurrent.CopyOnWriteArrayList;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.lifx.internal.fields.HSBK;
26 import org.openhab.binding.lifx.internal.listener.LifxLightStateListener;
27 import org.openhab.binding.lifx.internal.protocol.Effect;
28 import org.openhab.binding.lifx.internal.protocol.PowerState;
29 import org.openhab.binding.lifx.internal.protocol.SignalStrength;
30 import org.openhab.core.library.types.HSBType;
31 import org.openhab.core.library.types.OnOffType;
32 import org.openhab.core.library.types.PercentType;
35 * The {@link LifxLightState} stores the properties that represent the state of a light.
37 * @author Wouter Born - Extracted class from LifxLightHandler, added listener logic
40 public class LifxLightState {
42 private HSBK[] colors = new HSBK[] { new HSBK(DEFAULT_COLOR) };
43 private @Nullable PercentType infrared;
44 private @Nullable PowerState powerState;
45 private @Nullable SignalStrength signalStrength;
46 private @Nullable Effect tileEffect;
48 private LocalDateTime lastChange = LocalDateTime.MIN;
49 private List<LifxLightStateListener> listeners = new CopyOnWriteArrayList<>();
51 public void copy(LifxLightState other) {
52 this.powerState = other.getPowerState();
53 this.colors = other.getColors();
54 this.infrared = other.getInfrared();
55 this.signalStrength = other.getSignalStrength();
56 this.tileEffect = other.getTileEffect();
59 public @Nullable PowerState getPowerState() {
63 public HSBK getColor() {
64 return colors.length > 0 ? new HSBK(colors[0]) : new HSBK(DEFAULT_COLOR);
67 public HSBK getColor(int zoneIndex) {
68 return zoneIndex < colors.length ? new HSBK(colors[zoneIndex]) : new HSBK(DEFAULT_COLOR);
71 public HSBK[] getColors() {
72 HSBK[] colorsCopy = new HSBK[colors.length];
73 for (int i = 0; i < colors.length; i++) {
74 colorsCopy[i] = colors[i] != null ? new HSBK(colors[i]) : null;
79 public @Nullable PercentType getInfrared() {
83 public @Nullable SignalStrength getSignalStrength() {
84 return signalStrength;
87 public @Nullable Effect getTileEffect() {
91 public void setColor(HSBType newHSB) {
92 HSBK newColor = getColor();
93 newColor.setHSB(newHSB);
97 public void setColor(HSBType newHSB, int zoneIndex) {
98 HSBK newColor = getColor(zoneIndex);
99 newColor.setHSB(newHSB);
100 setColor(newColor, zoneIndex);
103 public void setBrightness(PercentType brightness) {
104 HSBK[] newColors = getColors();
105 for (HSBK newColor : newColors) {
106 newColor.setBrightness(brightness);
108 setColors(newColors);
111 public void setBrightness(PercentType brightness, int zoneIndex) {
112 HSBK newColor = getColor(zoneIndex);
113 newColor.setBrightness(brightness);
114 setColor(newColor, zoneIndex);
117 public void setColor(HSBK newColor) {
118 HSBK[] newColors = getColors();
119 Arrays.fill(newColors, newColor);
120 setColors(newColors);
123 public void setColor(HSBK newColor, int zoneIndex) {
124 HSBK[] newColors = getColors();
125 newColors[zoneIndex] = newColor;
126 setColors(newColors);
129 public void setColors(HSBK[] newColors) {
130 HSBK[] oldColors = this.colors;
131 this.colors = newColors;
133 listeners.forEach(listener -> listener.handleColorsChange(oldColors, newColors));
136 public void setPowerState(OnOffType newOnOff) {
137 setPowerState(PowerState.fromOnOffType(newOnOff));
140 public void setPowerState(PowerState newPowerState) {
141 PowerState oldPowerState = this.powerState;
142 this.powerState = newPowerState;
144 listeners.forEach(listener -> listener.handlePowerStateChange(oldPowerState, newPowerState));
147 public void setTemperature(int kelvin) {
148 HSBK[] newColors = getColors();
149 for (HSBK newColor : newColors) {
150 newColor.setKelvin(kelvin);
152 setColors(newColors);
155 public void setTemperature(int kelvin, int zoneIndex) {
156 HSBK newColor = getColor(zoneIndex);
157 newColor.setKelvin(kelvin);
158 setColor(newColor, zoneIndex);
161 public void setInfrared(PercentType newInfrared) {
162 PercentType oldInfrared = this.infrared;
163 this.infrared = newInfrared;
165 listeners.forEach(listener -> listener.handleInfraredChange(oldInfrared, newInfrared));
168 public void setSignalStrength(SignalStrength newSignalStrength) {
169 SignalStrength oldSignalStrength = this.signalStrength;
170 this.signalStrength = newSignalStrength;
172 listeners.forEach(listener -> listener.handleSignalStrengthChange(oldSignalStrength, newSignalStrength));
175 public void setTileEffect(Effect newEffect) {
176 // Caller has to take care that newEffect is another object
177 Effect oldEffect = tileEffect;
178 tileEffect = newEffect;
180 listeners.forEach(listener -> listener.handleTileEffectChange(oldEffect, newEffect));
183 private void updateLastChange() {
184 lastChange = LocalDateTime.now();
187 public Duration getDurationSinceLastChange() {
188 return Duration.between(lastChange, LocalDateTime.now());
191 public void addListener(LifxLightStateListener listener) {
192 listeners.add(listener);
195 public void removeListener(LifxLightStateListener listener) {
196 listeners.remove(listener);