2 * Copyright (c) 2010-2023 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.dmx.internal.action;
15 import org.openhab.binding.dmx.internal.Util;
16 import org.openhab.binding.dmx.internal.multiverse.DmxChannel;
17 import org.openhab.core.library.types.PercentType;
20 * The {@link FadeAction} fades a given channel from its current state to the requested
21 * state in the given amount of time. After the fade, the new state is held for
22 * a given or indefinite time.
24 * @author Davy Vanherbergen - Initial contribution
25 * @author Jan N. Klug - Refactoring for ESH
27 public class FadeAction extends BaseAction {
28 /** Time in ms to hold the target value. -1 is indefinite */
29 private long holdTime;
31 /** Time in ms to fade from current value to new target value */
32 private long fadeTime;
34 /** Channel output value on action start. **/
35 private int startValue;
37 /** Desired channel output value. **/
38 private final int targetValue;
40 private float stepDuration;
42 private FadeDirection fadeDirection;
45 * Create new fading action.
47 * @param fadeTime time in ms to fade from the current value to the new value.
48 * @param targetValue new value 0-255 for this channel.
49 * @param holdTime time in ms to hold the color before moving to the next action. -1 is indefinite.
51 public FadeAction(int fadeTime, int targetValue, int holdTime) {
54 this.fadeTime = fadeTime;
55 this.targetValue = Util.toDmxValue(targetValue) << 8;
56 this.holdTime = holdTime;
66 public FadeAction(int fadeTime, PercentType targetValue, int holdTime) {
67 this(fadeTime, Util.toDmxValue(targetValue), holdTime);
70 public FadeAction(int fadeTime, int currentValue, int targetValue, int holdTime) {
71 this(Util.fadeTimeFraction(currentValue, targetValue, fadeTime), targetValue, holdTime);
75 public int getNewValue(DmxChannel channel, long currentTime) {
76 int newValue = channel.getHiResValue();
79 startTime = currentTime;
80 state = ActionState.RUNNING;
83 startValue = channel.getHiResValue();
85 // calculate fade details
86 if (startValue == targetValue) {
88 } else if (startValue > targetValue) {
89 fadeDirection = FadeDirection.DOWN;
90 stepDuration = (float) fadeTime / (startValue - targetValue);
92 fadeDirection = FadeDirection.UP;
93 stepDuration = (float) fadeTime / (targetValue - startValue);
96 newValue = targetValue;
100 long duration = currentTime - startTime;
102 if ((fadeTime != 0) && (newValue != targetValue)) {
103 // calculate new fade value
104 if (stepDuration == 0) {
107 int currentStep = (int) (duration / stepDuration);
109 if (fadeDirection == FadeDirection.UP) {
110 newValue = startValue + currentStep;
111 if (newValue > targetValue) {
112 newValue = targetValue;
115 newValue = startValue - currentStep;
116 if (newValue < targetValue) {
117 newValue = targetValue;
121 newValue = targetValue;
124 if (newValue == targetValue) {
126 // we reached the target already, check if we need to hold longer
127 if (((holdTime > 0 || fadeTime > 0) && (duration >= fadeTime + holdTime))
128 || (holdTime == 0 && fadeTime == 0)) {
129 // mark action as completed
130 state = ActionState.COMPLETED;
133 state = ActionState.COMPLETEDFINAL;
141 public String toString() {
142 return "FadeAction: " + String.valueOf(targetValue) + ", fade time " + String.valueOf(fadeTime)
143 + "ms, hold time " + String.valueOf(holdTime) + "ms";