]> git.basschouten.com Git - openhab-addons.git/blob
c2b755cf7223ae28e0edb668996efee93f6a8798
[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.velux.internal.bridge.slip;
14
15 import java.util.Arrays;
16
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.openhab.binding.velux.internal.bridge.slip.utils.Packet;
20 import org.openhab.binding.velux.internal.things.VeluxProductPosition;
21
22 /**
23  * Implementation of API Functional Parameters.
24  * Supports an array of of four Functional Parameter values { FP1 .. FP4 }
25  *
26  * @author Andrew Fiddian-Green - Initial contribution.
27  */
28
29 @NonNullByDefault
30 public class FunctionalParameters {
31     private static final int FUNCTIONAL_PARAMETER_COUNT = 4;
32
33     private final int[] values;
34
35     /**
36      * Private constructor to create a FunctionalParameters instance with all empty values.
37      */
38     private FunctionalParameters() {
39         values = new int[FUNCTIONAL_PARAMETER_COUNT];
40         Arrays.fill(values, VeluxProductPosition.VPP_VELUX_UNKNOWN);
41     }
42
43     /**
44      * Public constructor to create a FunctionalParameters instance from one specific value at one specific index.
45      */
46     public FunctionalParameters(int index, int newValue) {
47         this();
48         values[index] = newValue;
49     }
50
51     @Override
52     public FunctionalParameters clone() {
53         FunctionalParameters result = new FunctionalParameters();
54         System.arraycopy(values, 0, result.values, 0, FUNCTIONAL_PARAMETER_COUNT);
55         return result;
56     }
57
58     @Override
59     public String toString() {
60         return String.format("{0x%04X, 0x%04X, 0x%04X, 0x%04X}", values[0], values[1], values[2], values[3]);
61     }
62
63     /**
64      * Return the functional parameter value at index.
65      *
66      * @return the value at the index.
67      */
68     public int getValue(int index) {
69         return values[index];
70     }
71
72     /**
73      * Create a Functional Parameters instance from the merger of the data in 'foundationFunctionalParameters' and
74      * 'substituteFunctionalParameters'. Invalid parameter values are not merged. If either
75      * 'foundationFunctionalParameters' or 'substituteFunctionalParameters' is null, the merge includes only the data
76      * from the non null parameter set. And if both sets of parameters are null then the result is also null.
77      *
78      * @param foundationFunctionalParameters the Functional Parameters to be used as the foundation for the merge.
79      * @param substituteFunctionalParameters the Functional Parameters to substituted on top (if they can be).
80      * @return a new Functional Parameters class instance containing the merged data.
81      */
82     public static @Nullable FunctionalParameters createMergeSubstitute(
83             @Nullable FunctionalParameters foundationFunctionalParameters,
84             @Nullable FunctionalParameters substituteFunctionalParameters) {
85         if (foundationFunctionalParameters == null && substituteFunctionalParameters == null) {
86             return null;
87         }
88         FunctionalParameters result = new FunctionalParameters();
89         if (foundationFunctionalParameters != null) {
90             for (int i = 0; i < FUNCTIONAL_PARAMETER_COUNT; i++) {
91                 if (isNormalPosition(foundationFunctionalParameters.values[i])) {
92                     result.values[i] = foundationFunctionalParameters.values[i];
93                 }
94             }
95         }
96         if (substituteFunctionalParameters != null) {
97             for (int i = 0; i < FUNCTIONAL_PARAMETER_COUNT; i++) {
98                 if (isNormalPosition(substituteFunctionalParameters.values[i])) {
99                     result.values[i] = substituteFunctionalParameters.values[i];
100                 }
101             }
102         }
103         return result;
104     }
105
106     /**
107      * Check if a given parameter value is a normal actuator position value (i.e. 0x0000 .. 0xC800).
108      *
109      * @param paramValue the value to be checked.
110      * @return true if it is a normal actuator position value.
111      */
112     public static boolean isNormalPosition(int paramValue) {
113         return (paramValue >= VeluxProductPosition.VPP_VELUX_MIN) && (paramValue <= VeluxProductPosition.VPP_VELUX_MAX);
114     }
115
116     /**
117      * Create a FunctionalParameters instance from the given Packet. Where the parameters are packed into an array of
118      * two byte integer values.
119      *
120      * @param responseData the Packet to read from.
121      * @param startPosition the read starting position.
122      * @return this object.
123      */
124     public static @Nullable FunctionalParameters readArray(Packet responseData, int startPosition) {
125         int pos = startPosition;
126         boolean isValid = false;
127         FunctionalParameters result = new FunctionalParameters();
128         for (int i = 0; i < FUNCTIONAL_PARAMETER_COUNT; i++) {
129             int value = responseData.getTwoByteValue(pos);
130             if (isNormalPosition(value)) {
131                 result.values[i] = value;
132                 isValid = true;
133             }
134             pos = pos + 2;
135         }
136         return isValid ? result : null;
137     }
138
139     /**
140      * Create a FunctionalParameters instance from the given Packet. Where the parameters are packed into an array of
141      * three byte records each comprising a one byte index followed by a two byte integer value.
142      *
143      * @param responseData the Packet to read from.
144      * @param startPosition the read starting position.
145      * @return this object.
146      */
147     public static @Nullable FunctionalParameters readArrayIndexed(Packet responseData, int startPosition) {
148         int pos = startPosition;
149         boolean isValid = false;
150         FunctionalParameters result = new FunctionalParameters();
151         for (int i = 0; i < FUNCTIONAL_PARAMETER_COUNT; i++) {
152             int index = responseData.getOneByteValue(pos) - 1;
153             pos++;
154             if ((index >= 0) && (index < FUNCTIONAL_PARAMETER_COUNT)) {
155                 int value = responseData.getTwoByteValue(pos);
156                 if (isNormalPosition(value)) {
157                     result.values[index] = value;
158                     isValid = true;
159                 }
160             }
161             pos = pos + 2;
162         }
163         return isValid ? result : null;
164     }
165
166     /**
167      * Write the Functional Parameters to the given packet. Only writes normal valid position values.
168      *
169      * @param requestData the Packet to write to.
170      * @param startPosition the write starting position.
171      * @return fpIndex a bit map that indicates which of the written Functional Parameters contains a normal valid
172      *         position value.
173      */
174     public int writeArray(Packet requestData, int startPosition) {
175         int bitMask = 0b10000000;
176         int pos = startPosition;
177         int fpIndex = 0;
178         for (int i = 0; i < FUNCTIONAL_PARAMETER_COUNT; i++) {
179             if (isNormalPosition(values[i])) {
180                 fpIndex |= bitMask;
181                 requestData.setTwoByteValue(pos, values[i]);
182             }
183             pos = pos + 2;
184             bitMask = bitMask >>> 1;
185         }
186         return fpIndex;
187     }
188
189     @Override
190     public boolean equals(@Nullable Object obj) {
191         if (!(obj instanceof FunctionalParameters)) {
192             return false;
193         }
194         FunctionalParameters other = (FunctionalParameters) obj;
195         for (int i = 0; i < FUNCTIONAL_PARAMETER_COUNT; i++) {
196             if (values[i] != other.values[i]) {
197                 return false;
198             }
199         }
200         return true;
201     }
202
203     @Override
204     public int hashCode() {
205         return Arrays.hashCode(values);
206     };
207 }