]> git.basschouten.com Git - openhab-addons.git/blob
62a04de10faf17c99a021d5f13fb2c9a94070b4b
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.dmx.internal.action;
14
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;
19
20 /**
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.
24  *
25  * @author Davy Vanherbergen - Initial contribution
26  * @author Jan N. Klug - Refactoring for ESH
27  */
28 @NonNullByDefault
29 public class FadeAction extends BaseAction {
30     /** Time in ms to hold the target value. -1 is indefinite */
31     private long holdTime;
32
33     /** Time in ms to fade from current value to new target value */
34     private long fadeTime;
35
36     /** Channel output value on action start. **/
37     private int startValue;
38
39     /** Desired channel output value. **/
40     private final int targetValue;
41
42     private float stepDuration;
43
44     private FadeDirection fadeDirection = FadeDirection.DOWN;
45
46     /**
47      * Create new fading action.
48      *
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.
52      */
53     public FadeAction(int fadeTime, int targetValue, int holdTime) {
54         super();
55
56         this.fadeTime = fadeTime;
57         this.targetValue = Util.toDmxValue(targetValue) << 8;
58         this.holdTime = holdTime;
59
60         if (holdTime < -1) {
61             this.holdTime = -1;
62         }
63         if (fadeTime < 0) {
64             this.fadeTime = 0;
65         }
66     }
67
68     public FadeAction(int fadeTime, PercentType targetValue, int holdTime) {
69         this(fadeTime, Util.toDmxValue(targetValue), holdTime);
70     }
71
72     public FadeAction(int fadeTime, int currentValue, int targetValue, int holdTime) {
73         this(Util.fadeTimeFraction(currentValue, targetValue, fadeTime), targetValue, holdTime);
74     }
75
76     @Override
77     public int getNewValue(DmxChannel channel, long currentTime) {
78         int newValue = channel.getHiResValue();
79
80         if (startTime == 0) {
81             startTime = currentTime;
82             state = ActionState.RUNNING;
83
84             if (fadeTime != 0) {
85                 startValue = channel.getHiResValue();
86
87                 // calculate fade details
88                 if (startValue == targetValue) {
89                     stepDuration = 1;
90                 } else if (startValue > targetValue) {
91                     fadeDirection = FadeDirection.DOWN;
92                     stepDuration = (float) fadeTime / (startValue - targetValue);
93                 } else {
94                     fadeDirection = FadeDirection.UP;
95                     stepDuration = (float) fadeTime / (targetValue - startValue);
96                 }
97             } else {
98                 newValue = targetValue;
99             }
100         }
101
102         long duration = currentTime - startTime;
103
104         if ((fadeTime != 0) && (newValue != targetValue)) {
105             // calculate new fade value
106             if (stepDuration == 0) {
107                 stepDuration = 1;
108             }
109             int currentStep = (int) (duration / stepDuration);
110
111             if (fadeDirection == FadeDirection.UP) {
112                 newValue = startValue + currentStep;
113                 if (newValue > targetValue) {
114                     newValue = targetValue;
115                 }
116             } else {
117                 newValue = startValue - currentStep;
118                 if (newValue < targetValue) {
119                     newValue = targetValue;
120                 }
121             }
122         } else {
123             newValue = targetValue;
124         }
125
126         if (newValue == targetValue) {
127             if (holdTime > -1) {
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;
133                 }
134             } else {
135                 state = ActionState.COMPLETEDFINAL;
136             }
137         }
138
139         return newValue;
140     }
141
142     @Override
143     public String toString() {
144         return "FadeAction: " + targetValue + ", fade time " + fadeTime + "ms, hold time " + holdTime + "ms";
145     }
146 }