]> git.basschouten.com Git - openhab-addons.git/blob
1a3e5fed1241f830af81c1000e8902ffbc67f5c8
[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.lutron.internal.radiora;
14
15 import java.io.BufferedReader;
16 import java.io.IOException;
17 import java.io.InputStreamReader;
18 import java.io.OutputStream;
19 import java.util.TooManyListenersException;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.lutron.internal.radiora.protocol.RadioRAFeedback;
24 import org.openhab.core.io.transport.serial.PortInUseException;
25 import org.openhab.core.io.transport.serial.SerialPort;
26 import org.openhab.core.io.transport.serial.SerialPortEvent;
27 import org.openhab.core.io.transport.serial.SerialPortEventListener;
28 import org.openhab.core.io.transport.serial.SerialPortIdentifier;
29 import org.openhab.core.io.transport.serial.SerialPortManager;
30 import org.openhab.core.io.transport.serial.UnsupportedCommOperationException;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 /**
35  * RS232 connection to the RadioRA Classic system.
36  *
37  * @author Jeff Lauterbach - Initial Contribution
38  *
39  */
40 @NonNullByDefault
41 public class RS232Connection implements RadioRAConnection, SerialPortEventListener {
42
43     private final Logger logger = LoggerFactory.getLogger(RS232Connection.class);
44
45     protected SerialPortManager serialPortManager;
46     protected @Nullable SerialPort serialPort;
47
48     protected @Nullable BufferedReader inputReader;
49
50     protected @Nullable RadioRAFeedbackListener listener;
51     protected RS232MessageParser parser = new RS232MessageParser();
52
53     public RS232Connection(SerialPortManager serialPortManager) {
54         super();
55         this.serialPortManager = serialPortManager;
56     }
57
58     @Override
59     public void open(String portName, int baud) throws RadioRAConnectionException {
60         SerialPortIdentifier portIdentifier = serialPortManager.getIdentifier(portName);
61         if (portIdentifier == null) {
62             throw new RadioRAConnectionException(String.format("Port not found", portName));
63         }
64
65         try {
66             SerialPort serialPort = portIdentifier.open("openhab", 5000);
67             this.serialPort = serialPort;
68             serialPort.notifyOnDataAvailable(true);
69             serialPort.setSerialPortParams(baud, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
70             serialPort.addEventListener(this);
71             inputReader = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
72         } catch (PortInUseException e) {
73             throw new RadioRAConnectionException(String.format("Port %s already in use", portIdentifier.getName()));
74         } catch (UnsupportedCommOperationException e) {
75             throw new RadioRAConnectionException("Error initializing - Failed to set serial port params");
76         } catch (TooManyListenersException e) {
77             throw new RadioRAConnectionException("Error initializing - Failed to add event listener");
78         } catch (IOException e) {
79             throw new RadioRAConnectionException("Error initializing - Failed to get input stream");
80         }
81     }
82
83     @Override
84     public void write(String command) {
85         logger.debug("Writing to serial port: {}", command);
86         SerialPort serialPort = this.serialPort;
87
88         try {
89             if (serialPort != null) {
90                 OutputStream outputStream = serialPort.getOutputStream();
91                 if (outputStream != null) {
92                     outputStream.write(command.getBytes());
93                 } else {
94                     logger.debug("Cannot write to serial port. outputStream is null.");
95                 }
96             } else {
97                 logger.debug("Cannot write to serial port. serialPort is null.");
98             }
99         } catch (IOException e) {
100             logger.debug("An error occurred writing to serial port", e);
101         }
102     }
103
104     @Override
105     public void disconnect() {
106         SerialPort serialPort = this.serialPort;
107         if (serialPort != null) {
108             serialPort.close();
109         }
110     }
111
112     @Override
113     public void serialEvent(SerialPortEvent ev) {
114         switch (ev.getEventType()) {
115             case SerialPortEvent.DATA_AVAILABLE:
116                 BufferedReader inputReader = this.inputReader;
117                 try {
118                     if (inputReader == null || !inputReader.ready()) {
119                         logger.debug("Serial Data Available but input reader not ready");
120                         return;
121                     }
122
123                     String message = inputReader.readLine();
124                     logger.debug("Msg Received: {}", message);
125                     RadioRAFeedback feedback = parser.parse(message);
126
127                     if (feedback != null) {
128                         logger.debug("Msg Parsed as {}", feedback.getClass().getName());
129                         RadioRAFeedbackListener listener = this.listener;
130                         if (listener != null) {
131                             listener.handleRadioRAFeedback(feedback);
132                         } else {
133                             logger.debug("Cannot handle feedback message. Listener is null.");
134                         }
135                     }
136                     logger.debug("Finished handling feedback");
137                 } catch (IOException e) {
138                     logger.debug("IOException occurred", e);
139                 }
140                 break;
141             default:
142                 logger.debug("Unhandled SerialPortEvent raised [{}]", ev.getEventType());
143                 break;
144         }
145     }
146
147     @Override
148     public void setListener(RadioRAFeedbackListener listener) {
149         this.listener = listener;
150     }
151 }