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