]> git.basschouten.com Git - openhab-addons.git/blob
8b555637e908cb65767a9391404d2c81942a80dc
[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.smartmeter.internal.sml;
14
15 import java.util.Arrays;
16
17 import javax.measure.Quantity;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.openhab.binding.smartmeter.SmartMeterBindingConstants;
21 import org.openhab.binding.smartmeter.internal.MeterValue;
22 import org.openmuc.jsml.EObis;
23 import org.openmuc.jsml.EUnit;
24 import org.openmuc.jsml.structures.ASNObject;
25 import org.openmuc.jsml.structures.SmlListEntry;
26
27 /**
28  * Proxy class to encapsulate an openMUC SML_ListEntry-Object to read informations.
29  *
30  * @author Matthias Steigenberger - Initial contribution
31  * @author Mathias Gilhuber - Also-By
32  */
33 @NonNullByDefault
34 public final class SmlValueExtractor {
35
36     /**
37      * Stores the original value object from jSML
38      */
39     SmlListEntry smlListEntry;
40
41     /**
42      * Constructor
43      *
44      * @param obis
45      */
46     public SmlValueExtractor(SmlListEntry listEntry) {
47         smlListEntry = listEntry;
48     }
49
50     public <Q extends Quantity<Q>> MeterValue<Q> getSmlValue() {
51         return new MeterValue<Q>(getObisCode(), getValue(), SmlUnitConversion.getUnit(getUnit()));
52     }
53
54     /**
55      * Gets the values unit.
56      *
57      * @return the values unit if available - Integer.MIN_VALUE.
58      */
59     public EUnit getUnit() {
60         return EUnit.from(smlListEntry.getUnit().getVal());
61     }
62
63     /**
64      * Gets the values unit.
65      *
66      * @return the string representation of the values unit - otherwise null.
67      */
68     public String getUnitName() {
69         EUnit unitEnum = getUnit();
70         return unitEnum.name();
71     }
72
73     /**
74      * Gets a human readable name of the OBIS code.
75      *
76      * @return The name of the obis code or {@link EObis#UNKNOWN} if not known
77      */
78     public String getObisName() {
79         String obisName = null;
80         EObis smlUnit = Arrays.asList(EObis.values()).stream()
81                 .filter((a) -> a.obisCode().equals(smlListEntry.getObjName())).findAny().orElseGet(() -> EObis.UNKNOWN);
82         obisName = smlUnit.name();
83
84         return obisName;
85     }
86
87     @Override
88     public String toString() {
89         return "Value: '" + this.getValue() + "' Unit: '" + this.getUnitName() + "' Scaler:'" + this.getScaler() + "'";
90     }
91
92     /**
93      * Gets the value
94      *
95      * @return the value as String if available - otherwise null.
96      */
97     public String getValue() {
98         org.openmuc.jsml.structures.SmlValue smlValue = smlListEntry.getValue();
99         ASNObject choice = smlValue.getChoice();
100         String value = choice.toString();
101         try {
102             value = scaleValue(Double.parseDouble(value)) + "";
103         } catch (Exception e) {
104             // value is no numeric value
105         }
106         return value;
107     }
108
109     /**
110      * Gets the scaler which has to be applied to the value.
111      *
112      * @return scaler which has to be applied to the value.
113      */
114     double getScaler() {
115         int scaler = 0;
116
117         if (smlListEntry.getScaler().isSelected()) {
118             byte scalerByte = smlListEntry.getScaler().getVal();
119
120             scaler = Integer.parseInt(String.format("%02x", scalerByte), 16);
121
122             if (scaler > 127) {
123                 scaler -= 256;
124             }
125         }
126
127         return Math.pow(10, scaler);
128     }
129
130     /**
131      * Scales the value if necessary
132      *
133      * @return a string representation of the scaled value.
134      */
135     Double scaleValue(Double originalValue) {
136         return originalValue * getScaler();
137     }
138
139     /**
140      * Byte to Integer conversion.
141      *
142      * @param byte to convert to Integer.
143      */
144     private static int byteToInt(byte b) {
145         return Integer.parseInt(String.format("%02x", b), 16);
146     }
147
148     /**
149      * Converts hex encoded OBIS to formatted string.
150      *
151      * @return the hex encoded OBIS code as readable string.
152      */
153     protected static String getObisAsString(byte[] octetBytes) {
154         String formattedObis = String.format(SmartMeterBindingConstants.OBIS_FORMAT_MINIMAL, byteToInt(octetBytes[0]),
155                 byteToInt(octetBytes[1]), byteToInt(octetBytes[2]), byteToInt(octetBytes[3]), byteToInt(octetBytes[4]));
156
157         return formattedObis;
158     }
159
160     public String getObisCode() {
161         return getObisAsString(smlListEntry.getObjName().getValue());
162     }
163 }