]> git.basschouten.com Git - openhab-addons.git/blob
e314b74a61361724a894c1e3372ee3f0b45cba08
[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;
14
15 import java.util.List;
16 import java.util.stream.Collectors;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.openhab.binding.dsmr.internal.device.connector.DSMRConnectorErrorEvent;
20 import org.openhab.binding.dsmr.internal.device.connector.DSMRConnectorListener;
21 import org.openhab.binding.dsmr.internal.device.cosem.CosemObject;
22 import org.openhab.binding.dsmr.internal.device.p1telegram.P1Telegram;
23 import org.openhab.binding.dsmr.internal.device.p1telegram.P1Telegram.TelegramState;
24 import org.openhab.binding.dsmr.internal.device.p1telegram.P1TelegramListener;
25 import org.openhab.binding.dsmr.internal.device.p1telegram.P1TelegramParser;
26 import org.openhab.binding.dsmr.internal.device.p1telegram.TelegramParser;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 /**
31  * Helper listener to receive telegram data from the connector, send it to the parser and forward data or errors from
32  * the parser to the DSMR Device.
33  *
34  * @author M. Volaart - Initial contribution
35  * @author Hilbrand Bouwkamp - Moved this code out of the DSMRPort class, fixed some issues and reduced code
36  */
37 @NonNullByDefault
38 public class DSMRTelegramListener implements P1TelegramListener, DSMRConnectorListener {
39
40     private final Logger logger = LoggerFactory.getLogger(DSMRTelegramListener.class);
41     private final TelegramParser parser;
42
43     private @NonNullByDefault({}) DSMREventListener dsmrEventListener;
44
45     /**
46      * Constructor.
47      *
48      * @param eventListener listener to send received errors or messages to
49      */
50     public DSMRTelegramListener() {
51         parser = new P1TelegramParser(this);
52     }
53
54     /**
55      * Constructs {@link DSMRTelegramListener} with a Smarty decryptor to first decrypt incoming messages.
56      *
57      * @param decryptionKey Smarty decryption key
58      * @param additionalKey Additional optional descryption key
59      */
60     public DSMRTelegramListener(final String decryptionKey, final String additionalKey) {
61         parser = new SmartyDecrypter(new P1TelegramParser(this), this, decryptionKey, additionalKey);
62     }
63
64     /**
65      * Set the DSMR event listener.
66      *
67      * @param eventListener the listener to set
68      */
69     public void setDsmrEventListener(final DSMREventListener eventListener) {
70         this.dsmrEventListener = eventListener;
71     }
72
73     @Override
74     public void handleData(final byte[] data, final int length) {
75         parser.parse(data, length);
76     }
77
78     @Override
79     public void handleErrorEvent(final DSMRConnectorErrorEvent portEvent) {
80         dsmrEventListener.handleErrorEvent(portEvent);
81         parser.reset();
82     }
83
84     /**
85      * Handler for cosemObjects received in a P1 telegram
86      *
87      * @param telegram the received telegram.
88      */
89     @Override
90     public void telegramReceived(final P1Telegram telegram) {
91         final TelegramState telegramState = telegram.getTelegramState();
92         final List<CosemObject> cosemObjects = telegram.getCosemObjects();
93
94         if (logger.isTraceEnabled()) {
95             logger.trace("Received {} Cosem Objects with state: '{}'", cosemObjects.size(), telegramState);
96         }
97         if (telegramState == TelegramState.OK || telegramState == TelegramState.INVALID_ENCRYPTION_KEY) {
98             dsmrEventListener.handleTelegramReceived(telegram);
99         } else {
100             if (logger.isDebugEnabled()) {
101                 logger.debug("Telegram received with error state '{}': {}", telegramState,
102                         cosemObjects.stream().map(CosemObject::toString).collect(Collectors.joining(",")));
103             }
104         }
105     }
106
107     /**
108      * @param lenientMode the lenientMode to set
109      */
110     public void setLenientMode(final boolean lenientMode) {
111         parser.setLenientMode(lenientMode);
112     }
113 }