]> git.basschouten.com Git - openhab-addons.git/blob
7c1cc802b69cc2d3bb66bdf5080a49238165862e
[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.List;
16 import java.util.function.Supplier;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.openhab.binding.smartmeter.connectors.IMeterReaderConnector;
21 import org.openhab.binding.smartmeter.internal.MeterDevice;
22 import org.openhab.binding.smartmeter.internal.MeterValue;
23 import org.openhab.binding.smartmeter.internal.helper.ProtocolMode;
24 import org.openhab.core.io.transport.serial.SerialPortManager;
25 import org.openmuc.jsml.structures.ASNObject;
26 import org.openmuc.jsml.structures.EMessageBody;
27 import org.openmuc.jsml.structures.SmlFile;
28 import org.openmuc.jsml.structures.SmlList;
29 import org.openmuc.jsml.structures.SmlListEntry;
30 import org.openmuc.jsml.structures.SmlMessage;
31 import org.openmuc.jsml.structures.SmlStatus;
32 import org.openmuc.jsml.structures.responses.SmlGetListRes;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 /**
37  * Represents a SML capable device.
38  *
39  * @author Matthias Steigenberger - Initial contribution
40  * @author Mathias Gilhuber - Also-By
41  */
42 @NonNullByDefault
43 public final class SmlMeterReader extends MeterDevice<SmlFile> {
44
45     protected final Logger logger = LoggerFactory.getLogger(SmlMeterReader.class);
46
47     /**
48      * Static factory method to create a SmlDevice object with a serial connector member.
49      *
50      * @param serialPortManagerSupplier
51      * @param deviceId the id of the device as defined in openHAB configuration.
52      * @param serialPort the port where the device is connected as defined in openHAB configuration.
53      * @param initMessage
54      * @param baudrate
55      * @param baudrateChangeDelay
56      */
57     public static SmlMeterReader createInstance(Supplier<SerialPortManager> serialPortManagerSupplier, String deviceId,
58             String serialPort, byte @Nullable [] initMessage, int baudrate, int baudrateChangeDelay) {
59         SmlMeterReader device = new SmlMeterReader(serialPortManagerSupplier, deviceId, serialPort, initMessage,
60                 baudrate, baudrateChangeDelay, ProtocolMode.SML);
61
62         return device;
63     }
64
65     /**
66      * Constructor to create a SmlDevice object with a serial connector member.
67      *
68      * @param deviceId the id of the device as defined in openHAB configuration.
69      * @param serialPort the port where the device is connected as defined in openHAB configuration.
70      * @param serialParameter
71      * @param initMessage
72      * @param baudrate
73      */
74     private SmlMeterReader(Supplier<SerialPortManager> serialPortManagerSupplier, String deviceId, String serialPort,
75             byte @Nullable [] initMessage, int baudrate, int baudrateChangeDelay, ProtocolMode protocolMode) {
76         super(serialPortManagerSupplier, deviceId, serialPort, initMessage, baudrate, baudrateChangeDelay,
77                 protocolMode);
78
79         logger.debug("Created SmlDevice instance {} with serial connector on port {}", deviceId, serialPort);
80     }
81
82     /**
83      * Decodes native SML informations from the device and stores them locally until the next read request.
84      *
85      * @param smlFile the native SML informations from the device
86      */
87     @Override
88     protected void populateValueCache(SmlFile smlFile) {
89         if (logger.isTraceEnabled()) {
90             logger.trace("Read out following SML file: {}", System.lineSeparator());
91             SmlFileDebugOutput.printFile(smlFile, (msg) -> logger.trace(msg));
92         }
93         List<SmlMessage> smlMessages = smlFile.getMessages();
94
95         if (smlMessages != null) {
96             int messageCount = smlMessages.size();
97
98             if (messageCount <= 0) {
99                 logger.warn("{}: no valid SML messages list retrieved.", this.toString());
100             }
101
102             for (int i = 0; i < messageCount; i++) {
103                 SmlMessage smlMessage = smlMessages.get(i);
104
105                 int tag = smlMessage.getMessageBody().getTag().id();
106
107                 if (tag != EMessageBody.GET_LIST_RESPONSE.id()) {
108                     continue;
109                 }
110
111                 SmlGetListRes listResponse = (SmlGetListRes) smlMessage.getMessageBody().getChoice();
112                 SmlList smlValueList = listResponse.getValList();
113                 SmlListEntry[] smlListEntries = smlValueList.getValListEntry();
114
115                 for (SmlListEntry entry : smlListEntries) {
116                     SmlValueExtractor valueExtractor = new SmlValueExtractor(entry);
117                     String obis = valueExtractor.getObisCode();
118
119                     MeterValue<?> smlValue = getMeterValue(obis);
120
121                     if (smlValue == null) {
122                         smlValue = valueExtractor.getSmlValue();
123                     }
124
125                     SmlStatus status = entry.getStatus();
126                     if (status != null) {
127                         String statusValue = readStatus(status, obis);
128                         if (statusValue != null) {
129                             smlValue.setStatus(statusValue);
130                         }
131                     }
132
133                     addObisCache(smlValue);
134                 }
135             }
136         } else {
137             logger.warn("{}: no valid SML messages list retrieved.", this.toString());
138         }
139     }
140
141     private @Nullable String readStatus(SmlStatus status, String obis) {
142         ASNObject choice = status.getChoice();
143         if (choice != null) {
144             String statusValue = choice.toString();
145             return statusValue;
146         }
147         return null;
148     }
149
150     @Override
151     protected IMeterReaderConnector<SmlFile> createConnector(Supplier<SerialPortManager> serialPortManagerSupplier,
152             String serialPort, int baudrate, int baudrateChangeDelay, ProtocolMode protocolMode) {
153         return new SmlSerialConnector(serialPortManagerSupplier, serialPort, baudrate, baudrateChangeDelay);
154     }
155
156     @Override
157     protected void printInfo() {
158         super.printInfo();
159     }
160 }