]> git.basschouten.com Git - openhab-addons.git/blob
6c5f4de9e1eabc99403ef9238d84a6ade07afdf6
[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.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 import org.eclipse.jdt.annotation.Nullable;
22
23 /**
24  * Active when, the PWM period ended with a duty cycle set to 100%.
25  *
26  * @author Fabian Wolter - Initial Contribution
27  */
28 @NonNullByDefault
29 public class DutycycleHundredState extends State {
30     private ScheduledFuture<?> periodTimer;
31     private @Nullable ScheduledFuture<?> offTimer;
32     private Instant enabledAt = Instant.now();
33     private boolean dutyCycleChanged;
34
35     public DutycycleHundredState(StateMachine context) {
36         super(context);
37
38         controlOutput(true);
39
40         periodTimer = scheduler.schedule(this::periodEnded, context.getPeriodMs(), TimeUnit.MILLISECONDS);
41     }
42
43     private void periodEnded() {
44         long dutycycleRounded = Math.round(context.getDutycycle());
45
46         if (!dutyCycleChanged && dutycycleRounded <= 0) {
47             nextState(AlwaysOffState::new);
48         } else if (!dutyCycleChanged && dutycycleRounded >= 100) {
49             nextState(AlwaysOnState::new);
50         } else {
51             nextState(OnState::new);
52         }
53     }
54
55     @Override
56     public void dutyCycleChanged() {
57         dutyCycleChanged = true;
58
59         long newOnTimeMs = calculateOnTimeMs(context.getDutycycle());
60         long elapsedMs = enabledAt.until(Instant.now(), ChronoUnit.MILLIS);
61
62         if (elapsedMs - newOnTimeMs > 0) {
63             controlOutput(false);
64         } else {
65             ScheduledFuture<?> timer = offTimer;
66             if (timer != null) {
67                 timer.cancel(false);
68             }
69             offTimer = scheduler.schedule(() -> controlOutput(false), newOnTimeMs - elapsedMs, TimeUnit.MILLISECONDS);
70         }
71     }
72
73     @Override
74     protected void dutyCycleUpdated() {
75         // nothing
76     }
77
78     @Override
79     public void dispose() {
80         periodTimer.cancel(false);
81
82         ScheduledFuture<?> timer = offTimer;
83         if (timer != null) {
84             timer.cancel(false);
85         }
86     }
87 }