]> git.basschouten.com Git - openhab-addons.git/blob
5a675c89f2a102663c47d6d141004c7d4aee8d5b
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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      */
59     public DSMRTelegramListener(String decryptionKey) {
60         parser = new SmartyDecrypter(new P1TelegramParser(this), this, decryptionKey);
61     }
62
63     /**
64      * Set the DSMR event listener.
65      *
66      * @param eventListener the listener to set
67      */
68     public void setDsmrEventListener(DSMREventListener eventListener) {
69         this.dsmrEventListener = eventListener;
70     }
71
72     @Override
73     public void handleData(byte[] data, int length) {
74         parser.parse(data, length);
75     }
76
77     @Override
78     public void handleErrorEvent(DSMRConnectorErrorEvent portEvent) {
79         dsmrEventListener.handleErrorEvent(portEvent);
80         parser.reset();
81     }
82
83     /**
84      * Handler for cosemObjects received in a P1 telegram
85      *
86      * @param telegram the received telegram.
87      */
88     @Override
89     public void telegramReceived(P1Telegram telegram) {
90         final TelegramState telegramState = telegram.getTelegramState();
91         final List<CosemObject> cosemObjects = telegram.getCosemObjects();
92
93         if (logger.isTraceEnabled()) {
94             logger.trace("Received {} Cosem Objects with state: '{}'", cosemObjects.size(), telegramState);
95         }
96         if (telegramState == TelegramState.OK || telegramState == TelegramState.INVALID_ENCRYPTION_KEY) {
97             dsmrEventListener.handleTelegramReceived(telegram);
98         } else {
99             if (logger.isDebugEnabled()) {
100                 logger.debug("Telegram received with error state '{}': {}", telegramState,
101                         cosemObjects.stream().map(CosemObject::toString).collect(Collectors.joining(",")));
102             }
103         }
104     }
105
106     /**
107      * @param lenientMode the lenientMode to set
108      */
109     public void setLenientMode(boolean lenientMode) {
110         parser.setLenientMode(lenientMode);
111     }
112 }