]> git.basschouten.com Git - openhab-addons.git/blob
effe9674e8f4ecf0b7f69a0c7406e047abb4d1e7
[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.HashMap;
17 import java.util.Map;
18 import java.util.Map.Entry;
19 import java.util.regex.Matcher;
20 import java.util.regex.Pattern;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.openhab.core.types.State;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * Class for Cosem Object implementation
29  *
30  * @author M. Volaart - Initial contribution
31  */
32 @NonNullByDefault
33 public class CosemObject {
34
35     /**
36      * Regular expression for finding CosemValues
37      */
38     private static final Pattern COSEM_VALUES_PATTERN = Pattern.compile("(\\(([^\\(\\)]*)\\))");
39
40     private final Logger logger = LoggerFactory.getLogger(CosemObject.class);
41
42     /**
43      * CosemObject type
44      */
45     private final CosemObjectType type;
46
47     /**
48      * The actual OBISIdentifier for this CosemObject
49      */
50     private final OBISIdentifier obisIdentifier;
51
52     /**
53      * List of COSEM value in this message
54      */
55     private Map<String, State> cosemValues;
56
57     /**
58      * Construct a new CosemObject with the specified OBIS Message Type
59      *
60      * @param msgType
61      *            {@link CosemObjectType}
62      */
63     public CosemObject(CosemObjectType msgType, OBISIdentifier obisIdentifier) {
64         this.type = msgType;
65         this.obisIdentifier = obisIdentifier;
66
67         cosemValues = new HashMap<>();
68     }
69
70     /**
71      * Return the {@link CosemObjectType} for this Cosem Object
72      *
73      * @return the {@link CosemObjectType} for this Cosem Object
74      */
75     public CosemObjectType getType() {
76         return type;
77     }
78
79     /**
80      * @return the obisIdentifier
81      */
82     public OBISIdentifier getObisIdentifier() {
83         return obisIdentifier;
84     }
85
86     /**
87      * Returns string representation of this Cosem Object
88      *
89      * @return string representation of this Cosem Object
90      */
91     @Override
92     public String toString() {
93         return "Cosem Object(type:" + type + ", cosemValues:" + cosemValues + ")";
94     }
95
96     /**
97      * Returns the Cosem values that are part of this Cosem Object
98      *
99      * @return Map of channel keys with state values that are part of this Cosem Object
100      */
101     public Map<String, ? extends State> getCosemValues() {
102         return cosemValues;
103     }
104
105     /**
106      * Parses the List of COSEM String value to COSEM objects values.
107      * <p>
108      * When the parser has problems it throws a {@link ParseException}. The
109      * already parsed values will still be available. It is up to the caller how
110      * to handle a partially parsed message.
111      *
112      * @param cosemValueString the List of COSEM String values
113      * @throws ParseException if parsing fails
114      */
115     public void parseCosemValues(String cosemValueString) throws ParseException {
116         logger.trace("Parsing CosemValue string {}", cosemValueString);
117
118         Matcher cosemValueMatcher = COSEM_VALUES_PATTERN.matcher(cosemValueString);
119         int nrOfCosemValues = countCosemValues(cosemValueMatcher);
120
121         if (type.supportsNrOfValues(nrOfCosemValues)) {
122             logger.trace("Received items: {} is supported", nrOfCosemValues);
123
124             int cosemValueItr = 0;
125             while (cosemValueMatcher.find()) {
126                 final Entry<String, CosemValueDescriptor<?>> valueDescriptorEntry = type.getDescriptor(cosemValueItr);
127                 final State cosemValue = valueDescriptorEntry.getValue().getStateValue(cosemValueMatcher.group(2));
128
129                 if (!cosemValues.containsKey(valueDescriptorEntry.getKey())) {
130                     cosemValues.put(valueDescriptorEntry.getKey(), cosemValue);
131                 } else {
132                     logger.warn("Value for descriptor {} already exists, dropping value {}", valueDescriptorEntry,
133                             cosemValue);
134                 }
135                 cosemValueItr++;
136             }
137         } else {
138             throw new ParseException(type + " does not support " + nrOfCosemValues + " items", 0);
139         }
140     }
141
142     private int countCosemValues(Matcher cosemValueMatcher) {
143         int nrOfCosemValues = 0;
144
145         while (cosemValueMatcher.find()) {
146             nrOfCosemValues++;
147         }
148         // We need the matcher again, reset to initial state
149         cosemValueMatcher.reset();
150         return nrOfCosemValues;
151     }
152 }