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.smartmeter.internal.sml;
15 import java.util.Arrays;
17 import javax.measure.Quantity;
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;
28 * Proxy class to encapsulate an openMUC SML_ListEntry-Object to read informations.
30 * @author Matthias Steigenberger - Initial contribution
31 * @author Mathias Gilhuber - Also-By
34 public final class SmlValueExtractor {
37 * Stores the original value object from jSML
39 SmlListEntry smlListEntry;
46 public SmlValueExtractor(SmlListEntry listEntry) {
47 smlListEntry = listEntry;
50 public <Q extends Quantity<Q>> MeterValue<Q> getSmlValue() {
51 return new MeterValue<Q>(getObisCode(), getValue(), SmlUnitConversion.getUnit(getUnit()));
55 * Gets the values unit.
57 * @return the values unit if available - Integer.MIN_VALUE.
59 public EUnit getUnit() {
60 return EUnit.from(smlListEntry.getUnit().getVal());
64 * Gets the values unit.
66 * @return the string representation of the values unit - otherwise null.
68 public String getUnitName() {
69 EUnit unitEnum = getUnit();
70 return unitEnum.name();
74 * Gets a human readable name of the OBIS code.
76 * @return The name of the obis code or {@link EObis#UNKNOWN} if not known
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();
88 public String toString() {
89 return "Value: '" + this.getValue() + "' Unit: '" + this.getUnitName() + "' Scaler:'" + this.getScaler() + "'";
95 * @return the value as String if available - otherwise null.
97 public String getValue() {
98 org.openmuc.jsml.structures.SmlValue smlValue = smlListEntry.getValue();
99 ASNObject choice = smlValue.getChoice();
100 String value = choice.toString();
102 value = scaleValue(Double.parseDouble(value)) + "";
103 } catch (Exception e) {
104 // value is no numeric value
110 * Gets the scaler which has to be applied to the value.
112 * @return scaler which has to be applied to the value.
117 if (smlListEntry.getScaler().isSelected()) {
118 byte scalerByte = smlListEntry.getScaler().getVal();
120 scaler = Integer.parseInt(String.format("%02x", scalerByte), 16);
127 return Math.pow(10, scaler);
131 * Scales the value if necessary
133 * @return a string representation of the scaled value.
135 Double scaleValue(Double originalValue) {
136 return originalValue * getScaler();
140 * Byte to Integer conversion.
142 * @param byte to convert to Integer.
144 private static int byteToInt(byte b) {
145 return Integer.parseInt(String.format("%02x", b), 16);
149 * Converts hex encoded OBIS to formatted string.
151 * @return the hex encoded OBIS code as readable string.
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]));
157 return formattedObis;
160 public String getObisCode() {
161 return getObisAsString(smlListEntry.getObjName().getValue());