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.eclipse.jdt.annotation.NonNullByDefault;
16 import org.openhab.binding.dmx.internal.Util;
17 import org.openhab.binding.dmx.internal.multiverse.DmxChannel;
18 import org.openhab.core.library.types.PercentType;
21 * The {@link FadeAction} fades a given channel from its current state to the requested
22 * state in the given amount of time. After the fade, the new state is held for
23 * a given or indefinite time.
25 * @author Davy Vanherbergen - Initial contribution
26 * @author Jan N. Klug - Refactoring for ESH
29 public class FadeAction extends BaseAction {
30 /** Time in ms to hold the target value. -1 is indefinite */
31 private long holdTime;
33 /** Time in ms to fade from current value to new target value */
34 private long fadeTime;
36 /** Channel output value on action start. **/
37 private int startValue;
39 /** Desired channel output value. **/
40 private final int targetValue;
42 private float stepDuration;
44 private FadeDirection fadeDirection = FadeDirection.DOWN;
47 * Create new fading action.
49 * @param fadeTime time in ms to fade from the current value to the new value.
50 * @param targetValue new value 0-255 for this channel.
51 * @param holdTime time in ms to hold the color before moving to the next action. -1 is indefinite.
53 public FadeAction(int fadeTime, int targetValue, int holdTime) {
56 this.fadeTime = fadeTime;
57 this.targetValue = Util.toDmxValue(targetValue) << 8;
58 this.holdTime = holdTime;
68 public FadeAction(int fadeTime, PercentType targetValue, int holdTime) {
69 this(fadeTime, Util.toDmxValue(targetValue), holdTime);
72 public FadeAction(int fadeTime, int currentValue, int targetValue, int holdTime) {
73 this(Util.fadeTimeFraction(currentValue, targetValue, fadeTime), targetValue, holdTime);
77 public int getNewValue(DmxChannel channel, long currentTime) {
78 int newValue = channel.getHiResValue();
81 startTime = currentTime;
82 state = ActionState.RUNNING;
85 startValue = channel.getHiResValue();
87 // calculate fade details
88 if (startValue == targetValue) {
90 } else if (startValue > targetValue) {
91 fadeDirection = FadeDirection.DOWN;
92 stepDuration = (float) fadeTime / (startValue - targetValue);
94 fadeDirection = FadeDirection.UP;
95 stepDuration = (float) fadeTime / (targetValue - startValue);
98 newValue = targetValue;
102 long duration = currentTime - startTime;
104 if ((fadeTime != 0) && (newValue != targetValue)) {
105 // calculate new fade value
106 if (stepDuration == 0) {
109 int currentStep = (int) (duration / stepDuration);
111 if (fadeDirection == FadeDirection.UP) {
112 newValue = startValue + currentStep;
113 if (newValue > targetValue) {
114 newValue = targetValue;
117 newValue = startValue - currentStep;
118 if (newValue < targetValue) {
119 newValue = targetValue;
123 newValue = targetValue;
126 if (newValue == targetValue) {
128 // we reached the target already, check if we need to hold longer
129 if (((holdTime > 0 || fadeTime > 0) && (duration >= fadeTime + holdTime))
130 || (holdTime == 0 && fadeTime == 0)) {
131 // mark action as completed
132 state = ActionState.COMPLETED;
135 state = ActionState.COMPLETEDFINAL;
143 public String toString() {
144 return "FadeAction: " + targetValue + ", fade time " + fadeTime + "ms, hold time " + holdTime + "ms";