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.dsmr.internal.device;
15 import java.util.List;
16 import java.util.stream.Collectors;
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;
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.
34 * @author M. Volaart - Initial contribution
35 * @author Hilbrand Bouwkamp - Moved this code out of the DSMRPort class, fixed some issues and reduced code
38 public class DSMRTelegramListener implements P1TelegramListener, DSMRConnectorListener {
40 private final Logger logger = LoggerFactory.getLogger(DSMRTelegramListener.class);
41 private final TelegramParser parser;
43 private @NonNullByDefault({}) DSMREventListener dsmrEventListener;
48 * @param eventListener listener to send received errors or messages to
50 public DSMRTelegramListener() {
51 parser = new P1TelegramParser(this);
55 * Constructs {@link DSMRTelegramListener} with a Smarty decryptor to first decrypt incoming messages.
57 * @param decryptionKey Smarty decryption key
58 * @param additionalKey Additional optional descryption key
60 public DSMRTelegramListener(final String decryptionKey, final String additionalKey) {
61 parser = new SmartyDecrypter(new P1TelegramParser(this), this, decryptionKey, additionalKey);
65 * Set the DSMR event listener.
67 * @param eventListener the listener to set
69 public void setDsmrEventListener(final DSMREventListener eventListener) {
70 this.dsmrEventListener = eventListener;
74 public void handleData(final byte[] data, final int length) {
75 parser.parse(data, length);
79 public void handleErrorEvent(final DSMRConnectorErrorEvent portEvent) {
80 dsmrEventListener.handleErrorEvent(portEvent);
85 * Handler for cosemObjects received in a P1 telegram
87 * @param telegram the received telegram.
90 public void telegramReceived(final P1Telegram telegram) {
91 final TelegramState telegramState = telegram.getTelegramState();
92 final List<CosemObject> cosemObjects = telegram.getCosemObjects();
94 if (logger.isTraceEnabled()) {
95 logger.trace("Received {} Cosem Objects with state: '{}'", cosemObjects.size(), telegramState);
97 if (telegramState == TelegramState.OK || telegramState == TelegramState.INVALID_ENCRYPTION_KEY) {
98 dsmrEventListener.handleTelegramReceived(telegram);
100 if (logger.isDebugEnabled()) {
101 logger.debug("Telegram received with error state '{}': {}", telegramState,
102 cosemObjects.stream().map(CosemObject::toString).collect(Collectors.joining(",")));
108 * @param lenientMode the lenientMode to set
110 public void setLenientMode(final boolean lenientMode) {
111 parser.setLenientMode(lenientMode);