]> git.basschouten.com Git - openhab-addons.git/blob
415bd9e30681617ca8c1b753d203485a7794092a
[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.dsmr.internal.device.cosem;
14
15 import java.text.ParseException;
16 import java.util.Objects;
17 import java.util.regex.Matcher;
18 import java.util.regex.Pattern;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22
23 /**
24  * Class representing an OBISIdentifier
25  *
26  * @author M. Volaart - Initial contribution
27  * @author Hilbrand Bouwkamp - Simplified, groupF not relevant, and groupB renamed to channel.
28  */
29 @NonNullByDefault
30 public class OBISIdentifier {
31     /**
32      * String representing a-channel:c.d.e.f OBIS ID
33      */
34     private static final String OBISID_REGEX = "((\\d+)\\-)?((\\d+):)?((\\d+)\\.)(\\d+)(\\.(\\d+))?(.(\\d+))?";
35
36     /**
37      * OBIS ID pattern
38      */
39     private static final Pattern OBIS_ID_PATTERN = Pattern.compile(OBISID_REGEX);
40
41     /**
42      * Value to return when an invalid int was read.
43      */
44     private static final int INVALID_INT_READ = -1;
45
46     /* the six individual group values of the OBIS ID */
47     private final int groupA;
48     private final @Nullable Integer channel;
49     private final int groupC;
50     private final int groupD;
51     private final @Nullable Integer groupE;
52     private final @Nullable Integer groupF;
53
54     private boolean conflict;
55
56     /**
57      * Constructs a new OBIS Identifier (A-x:C.D.E.x)
58      *
59      * @param groupA A value
60      * @param groupC C value
61      * @param groupD D value
62      * @param groupE E value
63      */
64     public OBISIdentifier(final int groupA, final int groupC, final int groupD, @Nullable final Integer groupE) {
65         this(groupA, groupC, groupD, groupE, false);
66     }
67
68     /**
69      * Constructs a new OBIS Identifier (A-x:C.D.E.x)
70      *
71      * @param groupA A value
72      * @param groupC C value
73      * @param groupD D value
74      * @param groupE E value
75      * @param conflict if true indicates this OBIS Identifier is used for different types of data.
76      */
77     public OBISIdentifier(final int groupA, final int groupC, final int groupD, @Nullable final Integer groupE,
78             final boolean conflict) {
79         this.groupA = groupA;
80         this.channel = null;
81         this.groupC = groupC;
82         this.groupD = groupD;
83         this.groupE = groupE;
84         this.groupF = null;
85         this.conflict = conflict;
86     }
87
88     /**
89      * Creates a new {@link OBISIdentifier} of the specified String
90      *
91      * @param obisIDString the OBIS String ID
92      * @throws ParseException if obisIDString is not a valid OBIS Identifier
93      */
94     public OBISIdentifier(final String obisIDString) throws ParseException {
95         final Matcher m = OBIS_ID_PATTERN.matcher(obisIDString);
96
97         if (m.matches()) {
98             // Optional value A
99             this.groupA = safeInt(m.group(2));
100
101             // Optional value B
102             this.channel = safeInteger(m.group(4));
103
104             // Required value C & D
105             this.groupC = safeInt(m.group(6));
106             this.groupD = safeInt(m.group(7));
107
108             // Optional value E
109             this.groupE = safeInteger(m.group(9));
110
111             // Optional value F
112             this.groupF = safeInteger(m.group(11));
113         } else {
114             throw new ParseException("Invalid OBIS identifier:" + obisIDString, 0);
115         }
116     }
117
118     private static int safeInt(final @Nullable String value) {
119         try {
120             return value == null ? INVALID_INT_READ : Integer.parseInt(value);
121         } catch (final NumberFormatException e) {
122             return INVALID_INT_READ;
123         }
124     }
125
126     private static @Nullable Integer safeInteger(final @Nullable String value) {
127         try {
128             return value == null ? null : Integer.valueOf(value);
129         } catch (final NumberFormatException e) {
130             return null;
131         }
132     }
133
134     public boolean isConflict() {
135         return conflict;
136     }
137
138     /**
139      * @return the groupA
140      */
141     public int getGroupA() {
142         return groupA;
143     }
144
145     /**
146      * @return the M-bus channel
147      */
148     public @Nullable Integer getChannel() {
149         return channel;
150     }
151
152     /**
153      * @return the groupC
154      */
155     public int getGroupC() {
156         return groupC;
157     }
158
159     /**
160      * @return the groupD
161      */
162     public int getGroupD() {
163         return groupD;
164     }
165
166     /**
167      * @return the groupE
168      */
169     public @Nullable Integer getGroupE() {
170         return groupE;
171     }
172
173     /**
174      * @return the groupF
175      */
176     public @Nullable Integer getGroupF() {
177         return groupF;
178     }
179
180     @Override
181     public String toString() {
182         return groupA + "-" + (channel == null ? "" : (channel + ":")) + groupC + "." + groupD
183                 + (groupE == null ? "" : ("." + groupE)) + (groupF == null ? "" : ("*" + groupF));
184     }
185
186     /**
187      * Returns whether or not both {@link OBISIdentifier} are exact equal (all identifiers match).
188      *
189      * If wild card matching is needed (since some fields are null in case of a wildcard) use
190      * {@link #equalsWildCard(OBISIdentifier)} instead
191      *
192      * @return true if both OBISIdentifiers match, false otherwise
193      */
194     @Override
195     public boolean equals(@Nullable final Object other) {
196         OBISIdentifier o;
197         if (other != null && other instanceof OBISIdentifier identifier) {
198             o = identifier;
199         } else {
200             return false;
201         }
202         boolean result = true;
203
204         result &= groupA == o.groupA;
205         if (channel != null && o.channel != null) {
206             result &= (channel.equals(o.channel));
207         } else if (!(channel == null && o.channel == null)) {
208             result = false;
209         }
210         result &= groupC == o.groupC;
211         result &= groupD == o.groupD;
212         if (groupE != null && o.groupE != null) {
213             result &= groupE.equals(o.groupE);
214         } else if (!(groupE == null && o.groupE == null)) {
215             result = false;
216         }
217         if (groupF != null && o.groupF != null) {
218             result &= (groupF.equals(o.groupF));
219         } else if (!(groupF == null && o.groupF == null)) {
220             result = false;
221         }
222
223         return result;
224     }
225
226     /**
227      * Checks whether this OBIS Identifier and the other identifier equals taking the wildcards into account
228      *
229      * @param o OBISIdentifier to compare to
230      *
231      * @return true if identifiers match fully or against a wildcard, false otherwise
232      */
233     public boolean equalsWildCard(final OBISIdentifier o) {
234         boolean result = true;
235
236         result &= groupA == o.groupA;
237         if (channel != null && o.channel != null) {
238             result &= (channel.equals(o.channel));
239         }
240         result &= groupC == o.groupC;
241         result &= groupD == o.groupD;
242         if (groupE != null && o.groupE != null) {
243             result &= (groupE.equals(o.groupE));
244         }
245         if (groupF != null && o.groupF != null) {
246             result &= (groupF.equals(o.groupF));
247         }
248
249         return result;
250     }
251
252     @Override
253     public int hashCode() {
254         return Objects.hash(groupA, (channel != null ? channel : 0), groupC, groupD, (groupE != null ? groupE : 0),
255                 (groupF != null ? groupF : 0));
256     }
257
258     /**
259      * Returns a reduced OBIS Identifier.
260      *
261      * @return reduced OBIS Identifier
262      */
263     public OBISIdentifier getReducedOBISIdentifier() {
264         return new OBISIdentifier(groupA, groupC, groupD, groupE);
265     }
266
267     /**
268      * Returns a reduced OBIS Identifier with group E set to null (.i.e. not applicable)
269      *
270      * @return reduced OBIS Identifier
271      */
272     public OBISIdentifier getReducedOBISIdentifierGroupE() {
273         return new OBISIdentifier(groupA, groupC, groupD, null);
274     }
275 }