]> git.basschouten.com Git - openhab-addons.git/blob
8d4d4d16367b71f091fadcf89db5af2bd044727e
[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.automation.pwm.internal.handler.state;
14
15 import java.time.Instant;
16 import java.time.temporal.ChronoUnit;
17 import java.util.concurrent.ScheduledFuture;
18 import java.util.concurrent.TimeUnit;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21
22 /**
23  * Active when, the output is currently ON and the duty cycle is between 0% and 100% (exclusively).
24  *
25  * @author Fabian Wolter - Initial Contribution
26  */
27 @NonNullByDefault
28 public class OnState extends State {
29     private @NonNullByDefault({}) ScheduledFuture<?> offTimer;
30     private Instant enabledAt = Instant.now();
31
32     public OnState(StateMachine context) {
33         super(context);
34
35         context.controlOutput(true);
36
37         startOnTimer(calculateOnTimeMs(context.getDutycycle()));
38     }
39
40     private void startOnTimer(long timeMs) {
41         offTimer = scheduler.schedule(() -> {
42             if (Math.round(context.getDutycycle()) >= 100) {
43                 nextState(DutycycleHundredState::new);
44             } else {
45                 nextState(OffState::new);
46             }
47         }, timeMs, TimeUnit.MILLISECONDS);
48     }
49
50     @Override
51     public void dutyCycleChanged() {
52         // end current ON phase prematurely or extend it if the new duty cycle demands it
53         offTimer.cancel(false);
54
55         long newOnTimeMs = calculateOnTimeMs(context.getDutycycle());
56         long elapsedMs = enabledAt.until(Instant.now(), ChronoUnit.MILLIS);
57
58         if (elapsedMs - newOnTimeMs > 0) {
59             nextState(OffState::new);
60         } else {
61             startOnTimer(newOnTimeMs - elapsedMs);
62         }
63     }
64
65     @Override
66     protected void dutyCycleUpdated() {
67         // nothing
68     }
69
70     @Override
71     public void dispose() {
72         offTimer.cancel(false);
73     }
74 }