]> git.basschouten.com Git - openhab-addons.git/blob
189294e4c2224a3bb71e9fc1d293ea658f2de362
[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.lutron.internal.protocol;
14
15 import java.math.BigDecimal;
16 import java.math.RoundingMode;
17 import java.util.regex.Matcher;
18 import java.util.regex.Pattern;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21
22 /**
23  * Holds time durations used by the Lutron protocols
24  *
25  * @author Bob Adair - Initial contribution
26  *
27  */
28 @NonNullByDefault
29 public class LutronDuration {
30     public static final int MAX_SECONDS = 360000 - 1;
31     public static final int MAX_HUNDREDTHS = 99;
32
33     private static final Pattern PATTERN_SS = Pattern.compile("^(\\d{1,2})$");
34     private static final Pattern PATTERN_SSDEC = Pattern.compile("^(\\d{1,2})\\.(\\d{2})$");
35     private static final Pattern PATTERN_MMSS = Pattern.compile("^(\\d{1,2}):(\\d{2})$");
36     private static final Pattern PATTERN_HHMMSS = Pattern.compile("^(\\d{1,2}):(\\d{2}):(\\d{2})$");
37
38     public final Integer seconds;
39     public final Integer hundredths;
40
41     /**
42      * Constructor accepting duration in seconds
43      */
44     public LutronDuration(Integer seconds) {
45         if (seconds < 0 || seconds > MAX_SECONDS) {
46             throw new IllegalArgumentException("Invalid duration");
47         }
48         this.seconds = seconds;
49         this.hundredths = 0;
50     }
51
52     /**
53      * Constructor accepting duration in seconds and hundredths of seconds
54      */
55     public LutronDuration(Integer seconds, Integer hundredths) {
56         if (seconds < 0 || seconds > MAX_SECONDS || hundredths < 0 || hundredths > MAX_HUNDREDTHS) {
57             throw new IllegalArgumentException("Invalid duration");
58         }
59         this.seconds = seconds;
60         this.hundredths = hundredths;
61     }
62
63     /**
64      * Constructor accepting duration in seconds as a BigDecimal
65      */
66     public LutronDuration(BigDecimal seconds) {
67         if (seconds.compareTo(BigDecimal.ZERO) == -1 || seconds.compareTo(new BigDecimal(MAX_SECONDS)) == 1) {
68             new IllegalArgumentException("Invalid duration");
69         }
70         this.seconds = seconds.intValue();
71         BigDecimal fractional = seconds.subtract(new BigDecimal(seconds.intValue()));
72         this.hundredths = fractional.movePointRight(2).intValue();
73     }
74
75     /**
76      * Constructor accepting duration in seconds as a Double
77      */
78     public LutronDuration(Double seconds) {
79         this(new BigDecimal(seconds).setScale(2, RoundingMode.HALF_UP));
80     }
81
82     /**
83      * Constructor accepting duration string of the format: SS.ss, SS, MM:SS, or HH:MM:SS
84      */
85     public LutronDuration(String duration) {
86         Matcher matcherSS = PATTERN_SS.matcher(duration);
87         if (matcherSS.find()) {
88             Integer seconds = Integer.valueOf(matcherSS.group(1));
89             this.seconds = seconds;
90             this.hundredths = 0;
91             return;
92         }
93         Matcher matcherSSDec = PATTERN_SSDEC.matcher(duration);
94         if (matcherSSDec.find()) {
95             this.seconds = Integer.valueOf(matcherSSDec.group(1));
96             this.hundredths = Integer.valueOf(matcherSSDec.group(2));
97             return;
98         }
99         Matcher matcherMMSS = PATTERN_MMSS.matcher(duration);
100         if (matcherMMSS.find()) {
101             Integer minutes = Integer.valueOf(matcherMMSS.group(1));
102             Integer seconds = Integer.valueOf(matcherMMSS.group(2));
103             this.seconds = minutes * 60 + seconds;
104             this.hundredths = 0;
105             return;
106         }
107         Matcher matcherHHMMSS = PATTERN_HHMMSS.matcher(duration);
108         if (matcherHHMMSS.find()) {
109             Integer hours = Integer.valueOf(matcherHHMMSS.group(1));
110             Integer minutes = Integer.valueOf(matcherHHMMSS.group(2));
111             Integer seconds = Integer.valueOf(matcherHHMMSS.group(3));
112             this.seconds = hours * 60 * 60 + minutes * 60 + seconds;
113             this.hundredths = 0;
114             return;
115         }
116         throw new IllegalArgumentException("Invalid duration");
117     }
118
119     public String asLipString() {
120         if (seconds < 100) {
121             if (hundredths == 0) {
122                 return String.valueOf(seconds);
123             } else {
124                 return String.format("%d.%02d", seconds, hundredths);
125             }
126         } else if (seconds < 3600) {
127             return String.format("%d:%02d", seconds / 60, seconds % 60);
128         } else {
129             return String.format("%d:%02d:%02d", seconds / 3600, (seconds % 3600) / 60, (seconds % 60));
130         }
131     }
132
133     public String asLeapString() {
134         Integer seconds = this.seconds;
135         if (seconds.equals(0) && hundredths > 0) {
136             // use 1 second if interval is > 0 and < 1
137             seconds = 1;
138         } else if (hundredths >= 50) {
139             // else apply normal rounding of hundredths
140             seconds++;
141         }
142         return String.format("%02d:%02d:%02d", seconds / 3600, (seconds % 3600) / 60, (seconds % 60));
143     }
144
145     @Override
146     public String toString() {
147         return asLipString();
148     }
149 }