]> git.basschouten.com Git - openhab-addons.git/blob
0275b73bc813376b22964011bd1155752da8a2cd
[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.benqprojector.internal.connector;
14
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.io.OutputStream;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.binding.benqprojector.internal.BenqProjectorException;
22 import org.openhab.core.io.transport.serial.PortInUseException;
23 import org.openhab.core.io.transport.serial.SerialPort;
24 import org.openhab.core.io.transport.serial.SerialPortEvent;
25 import org.openhab.core.io.transport.serial.SerialPortEventListener;
26 import org.openhab.core.io.transport.serial.SerialPortIdentifier;
27 import org.openhab.core.io.transport.serial.SerialPortManager;
28 import org.openhab.core.io.transport.serial.UnsupportedCommOperationException;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 /**
33  * Connector for serial port communication.
34  *
35  * @author Michael Lobstein - Initial contribution
36  */
37 @NonNullByDefault
38 public class BenqProjectorSerialConnector implements BenqProjectorConnector, SerialPortEventListener {
39
40     private final Logger logger = LoggerFactory.getLogger(BenqProjectorSerialConnector.class);
41     private final String serialPortName;
42     private final SerialPortManager serialPortManager;
43
44     private @Nullable InputStream in = null;
45     private @Nullable OutputStream out = null;
46     private @Nullable SerialPort serialPort = null;
47
48     public BenqProjectorSerialConnector(SerialPortManager serialPortManager, String serialPort) {
49         this.serialPortManager = serialPortManager;
50         this.serialPortName = serialPort;
51     }
52
53     @Override
54     public void connect() throws BenqProjectorException {
55         try {
56             logger.debug("Open connection to serial port '{}'", serialPortName);
57
58             SerialPortIdentifier serialPortIdentifier = serialPortManager.getIdentifier(serialPortName);
59
60             if (serialPortIdentifier == null) {
61                 throw new IOException("Unknown serial port");
62             }
63             SerialPort serialPort = serialPortIdentifier.open(this.getClass().getName(), 2000);
64             serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
65             serialPort.enableReceiveThreshold(1);
66             serialPort.disableReceiveTimeout();
67
68             InputStream in = serialPort.getInputStream();
69             OutputStream out = serialPort.getOutputStream();
70
71             if (in != null && out != null) {
72                 out.flush();
73                 if (in.markSupported()) {
74                     in.reset();
75                 }
76
77                 serialPort.notifyOnDataAvailable(true);
78
79                 this.serialPort = serialPort;
80                 this.in = in;
81                 this.out = out;
82             }
83         } catch (PortInUseException | UnsupportedCommOperationException | IOException e) {
84             throw new BenqProjectorException(e);
85         }
86     }
87
88     @Override
89     public void disconnect() throws BenqProjectorException {
90         InputStream in = this.in;
91         OutputStream out = this.out;
92         SerialPort serialPort = this.serialPort;
93
94         if (out != null) {
95             logger.debug("Close serial out stream");
96             try {
97                 out.close();
98             } catch (IOException e) {
99                 logger.debug("Error occurred when closing serial out stream: {}", e.getMessage());
100             }
101             this.out = null;
102         }
103         if (in != null) {
104             logger.debug("Close serial in stream");
105             try {
106                 in.close();
107             } catch (IOException e) {
108                 logger.debug("Error occurred when closing serial in stream: {}", e.getMessage());
109             }
110             this.in = null;
111         }
112         if (serialPort != null) {
113             logger.debug("Close serial port");
114             serialPort.close();
115             serialPort.removeEventListener();
116             this.serialPort = null;
117         }
118
119         logger.debug("Closed");
120     }
121
122     @Override
123     public String sendMessage(String data) throws BenqProjectorException {
124         InputStream in = this.in;
125         OutputStream out = this.out;
126
127         if (in == null || out == null) {
128             connect();
129             in = this.in;
130             out = this.out;
131         }
132
133         try {
134             if (in != null && out != null) {
135                 // flush input stream
136                 if (in.markSupported()) {
137                     in.reset();
138                 } else {
139                     while (in.available() > 0) {
140                         int availableBytes = in.available();
141
142                         if (availableBytes > 0) {
143                             byte[] tmpData = new byte[availableBytes];
144                             in.read(tmpData, 0, availableBytes);
145                         }
146                     }
147                 }
148                 return sendMsgReadResp(data, in, out);
149             } else {
150                 return BLANK;
151             }
152         } catch (IOException e) {
153             logger.debug("IO error occurred...reconnect and resend once: {}", e.getMessage());
154             disconnect();
155             connect();
156
157             try {
158                 return sendMsgReadResp(data, in, out);
159             } catch (IOException e1) {
160                 throw new BenqProjectorException(e);
161             }
162         }
163     }
164
165     @Override
166     public void serialEvent(SerialPortEvent arg0) {
167     }
168 }