]> git.basschouten.com Git - openhab-addons.git/blob
acaf18e83030d82ea22d5f26aae9507a8575a11a
[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      *
52      * @param deviceId the id of the device as defined in openHAB configuration.
53      * @param pullRequestRequired identicates if SML values have to be actively requested.
54      * @param serialPort the port where the device is connected as defined in openHAB configuration.
55      * @param serialParameter
56      * @param initMessage
57      */
58     public static SmlMeterReader createInstance(Supplier<SerialPortManager> serialPortManagerSupplier, String deviceId,
59             String serialPort, byte @Nullable [] initMessage, int baudrate, int baudrateChangeDelay) {
60         SmlMeterReader device = new SmlMeterReader(serialPortManagerSupplier, deviceId, serialPort, initMessage,
61                 baudrate, baudrateChangeDelay, ProtocolMode.SML);
62
63         return device;
64     }
65
66     /**
67      * Constructor to create a SmlDevice object with a serial connector member.
68      *
69      * @param deviceId the id of the device as defined in openHAB configuration.
70      * @param serialPort the port where the device is connected as defined in openHAB configuration.
71      * @param serialParameter
72      * @param initMessage
73      * @param baudrate
74      */
75     private SmlMeterReader(Supplier<SerialPortManager> serialPortManagerSupplier, String deviceId, String serialPort,
76             byte @Nullable [] initMessage, int baudrate, int baudrateChangeDelay, ProtocolMode protocolMode) {
77         super(serialPortManagerSupplier, deviceId, serialPort, initMessage, baudrate, baudrateChangeDelay,
78                 protocolMode);
79
80         logger.debug("Created SmlDevice instance {} with serial connector on port {}", deviceId, serialPort);
81     }
82
83     /**
84      * Decodes native SML informations from the device and stores them locally until the next read request.
85      *
86      * @param smlFile the native SML informations from the device
87      */
88     @Override
89     protected void populateValueCache(SmlFile smlFile) {
90         if (logger.isTraceEnabled()) {
91             logger.trace("Read out following SML file: {}", System.lineSeparator());
92             SmlFileDebugOutput.printFile(smlFile, (msg) -> logger.trace(msg));
93         }
94         List<SmlMessage> smlMessages = smlFile.getMessages();
95
96         if (smlMessages != null) {
97             int messageCount = smlMessages.size();
98
99             if (messageCount <= 0) {
100                 logger.warn("{}: no valid SML messages list retrieved.", this.toString());
101             }
102
103             for (int i = 0; i < messageCount; i++) {
104                 SmlMessage smlMessage = smlMessages.get(i);
105
106                 int tag = smlMessage.getMessageBody().getTag().id();
107
108                 if (tag != EMessageBody.GET_LIST_RESPONSE.id()) {
109                     continue;
110                 }
111
112                 SmlGetListRes listResponse = (SmlGetListRes) smlMessage.getMessageBody().getChoice();
113                 SmlList smlValueList = listResponse.getValList();
114                 SmlListEntry[] smlListEntries = smlValueList.getValListEntry();
115
116                 for (SmlListEntry entry : smlListEntries) {
117                     SmlValueExtractor valueExtractor = new SmlValueExtractor(entry);
118                     String obis = valueExtractor.getObisCode();
119
120                     MeterValue<?> smlValue = getMeterValue(obis);
121
122                     if (smlValue == null) {
123                         smlValue = valueExtractor.getSmlValue();
124                     }
125
126                     SmlStatus status = entry.getStatus();
127                     if (status != null) {
128                         String statusValue = readStatus(status, obis);
129                         if (statusValue != null) {
130                             smlValue.setStatus(statusValue);
131                         }
132                     }
133
134                     addObisCache(smlValue);
135                 }
136             }
137         } else {
138             logger.warn("{}: no valid SML messages list retrieved.", this.toString());
139         }
140     }
141
142     private @Nullable String readStatus(SmlStatus status, String obis) {
143         ASNObject choice = status.getChoice();
144         if (choice != null) {
145             String statusValue = choice.toString();
146             return statusValue;
147         }
148         return null;
149     }
150
151     @Override
152     protected IMeterReaderConnector<SmlFile> createConnector(Supplier<SerialPortManager> serialPortManagerSupplier,
153             String serialPort, int baudrate, int baudrateChangeDelay, ProtocolMode protocolMode) {
154         return new SmlSerialConnector(serialPortManagerSupplier, serialPort, baudrate, baudrateChangeDelay);
155     }
156
157     @Override
158     protected void printInfo() {
159         super.printInfo();
160     }
161 }