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.powermax.internal.connector;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.io.OutputStream;
18 import java.util.ArrayList;
19 import java.util.List;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.powermax.internal.message.PowermaxBaseMessage;
24 import org.openhab.binding.powermax.internal.message.PowermaxMessageEvent;
25 import org.openhab.binding.powermax.internal.message.PowermaxMessageEventListener;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
30 * An abstract class for the communication with the Visonic alarm panel that
31 * handles stuff common to all communication types
33 * @author Laurent Garnier - Initial contribution
36 public abstract class PowermaxConnector implements PowermaxConnectorInterface {
38 private final Logger logger = LoggerFactory.getLogger(PowermaxConnector.class);
40 protected final String readerThreadName;
41 private final List<PowermaxMessageEventListener> listeners = new ArrayList<>();
43 private @Nullable InputStream input;
44 private @Nullable OutputStream output;
45 private boolean connected;
46 private @Nullable Thread readerThread;
47 private long waitingForResponse;
49 public PowermaxConnector(String readerThreadName) {
50 this.readerThreadName = readerThreadName;
54 public abstract void open() throws Exception;
57 public abstract void close();
60 * Cleanup everything; to be called when closing the communication
62 protected void cleanup(boolean closeStreams) {
63 logger.debug("cleanup(): cleaning up Connection");
65 Thread thread = readerThread;
70 } catch (InterruptedException e) {
75 OutputStream out = output;
79 } catch (IOException e) {
80 logger.debug("Error while closing the output stream: {}", e.getMessage());
84 InputStream in = input;
88 } catch (IOException e) {
89 logger.debug("Error while closing the input stream: {}", e.getMessage());
98 logger.debug("cleanup(): Connection Cleanup");
102 * Handles an incoming message
104 * @param incomingMessage the received message as a table of bytes
106 public void handleIncomingMessage(byte[] incomingMessage) {
107 PowermaxMessageEvent event = new PowermaxMessageEvent(this,
108 PowermaxBaseMessage.getMessageHandler(incomingMessage));
110 // send message to event listeners
111 listeners.forEach(listener -> listener.onNewMessageEvent(event));
115 * Handles a communication failure
117 public void handleCommunicationFailure(@Nullable String message) {
119 listeners.forEach(listener -> listener.onCommunicationFailure(message != null ? message : ""));
123 public void sendMessage(byte[] data) {
125 OutputStream out = output;
127 throw new IOException("output stream is undefined");
131 } catch (IOException e) {
132 logger.debug("sendMessage(): Writing error: {}", e.getMessage(), e);
133 handleCommunicationFailure(e.getMessage());
138 public int read(byte[] buffer) throws IOException {
139 InputStream in = input;
141 throw new IOException("input stream is undefined");
143 return in.read(buffer);
147 public void addEventListener(PowermaxMessageEventListener listener) {
148 listeners.add(listener);
152 public void removeEventListener(PowermaxMessageEventListener listener) {
153 listeners.remove(listener);
157 * @return the input stream
159 public @Nullable InputStream getInput() {
164 * Set the input stream
166 * @param input the input stream
168 public void setInput(@Nullable InputStream input) {
173 * @return the output stream
175 public @Nullable OutputStream getOutput() {
180 * Set the output stream
182 * @param output the output stream
184 public void setOutput(@Nullable OutputStream output) {
185 this.output = output;
189 * @return true if connected or false if not
192 public boolean isConnected() {
197 * Set the connection state
199 * @param connected true if connected or false if not
201 public void setConnected(boolean connected) {
202 this.connected = connected;
206 * @return the thread that handles the message reading
208 public @Nullable Thread getReaderThread() {
213 * Set the thread that handles the message reading
215 * @param readerThread the thread
217 public void setReaderThread(Thread readerThread) {
218 this.readerThread = readerThread;
222 * @return the start time of the time frame to receive a response
224 public synchronized long getWaitingForResponse() {
225 return waitingForResponse;
229 * Set the start time of the time frame to receive a response
231 * @param timeLastReceive the time in milliseconds
233 public synchronized void setWaitingForResponse(long waitingForResponse) {
234 this.waitingForResponse = waitingForResponse;