2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.dsmr.internal.device.cosem;
15 import java.text.ParseException;
16 import java.util.Objects;
17 import java.util.regex.Matcher;
18 import java.util.regex.Pattern;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
24 * Class representing an OBISIdentifier
26 * @author M. Volaart - Initial contribution
27 * @author Hilbrand Bouwkamp - Simplified, groupF not relevant, and groupB renamed to channel.
30 public class OBISIdentifier {
32 * String representing a-channel:c.d.e.f OBIS ID
34 private static final String OBISID_REGEX = "((\\d+)\\-)?((\\d+):)?((\\d+)\\.)(\\d+)(\\.(\\d+))?(.(\\d+))?";
39 private static final Pattern OBIS_ID_PATTERN = Pattern.compile(OBISID_REGEX);
41 /* the six individual group values of the OBIS ID */
42 private final int groupA;
43 private final @Nullable Integer channel;
44 private final int groupC;
45 private final int groupD;
46 private final @Nullable Integer groupE;
47 private final @Nullable Integer groupF;
49 private boolean conflict;
52 * Constructs a new OBIS Identifier (A-x:C.D.E.x)
54 * @param groupA A value
55 * @param groupC C value
56 * @param groupD D value
57 * @param groupE E value
59 public OBISIdentifier(final int groupA, final int groupC, final int groupD, @Nullable final Integer groupE) {
60 this(groupA, groupC, groupD, groupE, false);
64 * Constructs a new OBIS Identifier (A-x:C.D.E.x)
66 * @param groupA A value
67 * @param groupC C value
68 * @param groupD D value
69 * @param groupE E value
70 * @param conflict if true indicates this OBIS Identifier is used for different types of data.
72 public OBISIdentifier(final int groupA, final int groupC, final int groupD, @Nullable final Integer groupE,
73 final boolean conflict) {
80 this.conflict = conflict;
84 * Creates a new {@link OBISIdentifier} of the specified String
86 * @param obisIDString the OBIS String ID
87 * @throws ParseException if obisIDString is not a valid OBIS Identifier
89 public OBISIdentifier(final String obisIDString) throws ParseException {
90 final Matcher m = OBIS_ID_PATTERN.matcher(obisIDString);
94 this.groupA = m.group(2) == null ? null : Integer.parseInt(m.group(2));
97 this.channel = m.group(4) == null ? null : Integer.valueOf(m.group(4));
99 // Required value C & D
100 this.groupC = Integer.parseInt(m.group(6));
101 this.groupD = Integer.parseInt(m.group(7));
104 this.groupE = m.group(9) == null ? null : Integer.valueOf(m.group(9));
107 this.groupF = m.group(11) == null ? null : Integer.valueOf(m.group(11));
109 throw new ParseException("Invalid OBIS identifier:" + obisIDString, 0);
113 public boolean isConflict() {
120 public int getGroupA() {
125 * @return the M-bus channel
127 public @Nullable Integer getChannel() {
134 public int getGroupC() {
141 public int getGroupD() {
148 public @Nullable Integer getGroupE() {
155 public @Nullable Integer getGroupF() {
160 public String toString() {
161 return groupA + "-" + (channel == null ? "" : (channel + ":")) + groupC + "." + groupD
162 + (groupE == null ? "" : ("." + groupE)) + (groupF == null ? "" : ("*" + groupF));
166 * Returns whether or not both {@link OBISIdentifier} are exact equal (all identifiers match).
168 * If wild card matching is needed (since some fields are null in case of a wildcard) use
169 * {@link #equalsWildCard(OBISIdentifier)} instead
171 * @return true if both OBISIdentifiers match, false otherwise
174 public boolean equals(@Nullable final Object other) {
176 if (other != null && other instanceof OBISIdentifier) {
177 o = (OBISIdentifier) other;
181 boolean result = true;
183 result &= groupA == o.groupA;
184 if (channel != null && o.channel != null) {
185 result &= (channel.equals(o.channel));
186 } else if (!(channel == null && o.channel == null)) {
189 result &= groupC == o.groupC;
190 result &= groupD == o.groupD;
191 if (groupE != null && o.groupE != null) {
192 result &= groupE.equals(o.groupE);
193 } else if (!(groupE == null && o.groupE == null)) {
196 if (groupF != null && o.groupF != null) {
197 result &= (groupF.equals(o.groupF));
198 } else if (!(groupF == null && o.groupF == null)) {
206 * Checks whether this OBIS Identifier and the other identifier equals taking the wildcards into account
208 * @param o OBISIdentifier to compare to
210 * @return true if identifiers match fully or against a wildcard, false otherwise
212 public boolean equalsWildCard(final OBISIdentifier o) {
213 boolean result = true;
215 result &= groupA == o.groupA;
216 if (channel != null && o.channel != null) {
217 result &= (channel.equals(o.channel));
219 result &= groupC == o.groupC;
220 result &= groupD == o.groupD;
221 if (groupE != null && o.groupE != null) {
222 result &= (groupE.equals(o.groupE));
224 if (groupF != null && o.groupF != null) {
225 result &= (groupF.equals(o.groupF));
232 public int hashCode() {
233 return Objects.hash(groupA, (channel != null ? channel : 0), groupC, groupD, (groupE != null ? groupE : 0),
234 (groupF != null ? groupF : 0));
238 * Returns a reduced OBIS Identifier.
240 * @return reduced OBIS Identifier
242 public OBISIdentifier getReducedOBISIdentifier() {
243 return new OBISIdentifier(groupA, groupC, groupD, groupE);
247 * Returns a reduced OBIS Identifier with group E set to null (.i.e. not applicable)
249 * @return reduced OBIS Identifier
251 public OBISIdentifier getReducedOBISIdentifierGroupE() {
252 return new OBISIdentifier(groupA, groupC, groupD, null);