]> git.basschouten.com Git - openhab-addons.git/blob
066ec22e5ee9b6a03757528dbf40aecdb3e83cfa
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.insteon.internal.driver;
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.core.io.transport.serial.PortInUseException;
22 import org.openhab.core.io.transport.serial.SerialPort;
23 import org.openhab.core.io.transport.serial.SerialPortIdentifier;
24 import org.openhab.core.io.transport.serial.SerialPortManager;
25 import org.openhab.core.io.transport.serial.UnsupportedCommOperationException;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  * Implements IOStream for serial devices.
31  *
32  * @author Bernd Pfrommer - Initial contribution
33  * @author Daniel Pfrommer - openHAB 1 insteonplm binding
34  * @author Rob Nielsen - Port to openHAB 2 insteon binding
35  */
36 @NonNullByDefault
37 public class SerialIOStream extends IOStream {
38     private final Logger logger = LoggerFactory.getLogger(SerialIOStream.class);
39     private @Nullable SerialPort port = null;
40     private final String appName = "PLM";
41     private int baudRate = 19200;
42     private String devName;
43     private boolean validConfig = true;
44     private @Nullable SerialPortManager serialPortManager;
45
46     public SerialIOStream(@Nullable SerialPortManager serialPortManager, String config) {
47         this.serialPortManager = serialPortManager;
48
49         String[] parts = config.split(",");
50         devName = parts[0];
51         for (int i = 1; i < parts.length; i++) {
52             String parameter = parts[i];
53             String[] paramParts = parameter.split("=");
54             if (paramParts.length != 2) {
55                 logger.warn("{} invalid parameter format '{}', must be 'key=value'.", config, parameter);
56
57                 validConfig = false;
58             } else {
59                 String key = paramParts[0];
60                 String value = paramParts[1];
61                 if ("baudRate".equals(key)) {
62                     try {
63                         baudRate = Integer.parseInt(value);
64                     } catch (NumberFormatException e) {
65                         logger.warn("{} baudRate {} must be an integer.", config, value);
66
67                         validConfig = false;
68                     }
69                 } else {
70                     logger.warn("{} invalid parameter '{}'.", config, parameter);
71
72                     validConfig = false;
73                 }
74             }
75         }
76     }
77
78     @Override
79     public boolean open() {
80         if (!validConfig) {
81             logger.warn("{} has an invalid configuration.", devName);
82             return false;
83         }
84
85         try {
86             SerialPortManager serialPortManager = this.serialPortManager;
87             if (serialPortManager == null) {
88                 logger.warn("serial port manager is null.");
89                 return false;
90             }
91             SerialPortIdentifier spi = serialPortManager.getIdentifier(devName);
92             if (spi == null) {
93                 logger.warn("{} is not a valid serial port.", devName);
94                 return false;
95             }
96
97             port = spi.open(appName, 1000);
98             open(port);
99             logger.debug("successfully opened port {}", devName);
100             return true;
101         } catch (IOException e) {
102             logger.warn("cannot open port: {}, got IOException {}", devName, e.getMessage());
103         } catch (PortInUseException e) {
104             logger.warn("cannot open port: {}, it is in use!", devName);
105         } catch (UnsupportedCommOperationException e) {
106             logger.warn("got unsupported operation {} on port {}", e.getMessage(), devName);
107         }
108
109         return false;
110     }
111
112     private void open(@Nullable SerialPort port) throws UnsupportedCommOperationException, IOException {
113         if (port != null) {
114             port.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
115             port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
116             logger.debug("setting {} baud rate to {}", devName, baudRate);
117             port.enableReceiveThreshold(1);
118             port.enableReceiveTimeout(1000);
119             in = port.getInputStream();
120             out = port.getOutputStream();
121         } else {
122             logger.warn("port is null");
123         }
124     }
125
126     @Override
127     public void close() {
128         InputStream in = this.in;
129         if (in != null) {
130             try {
131                 in.close();
132             } catch (IOException e) {
133                 logger.warn("failed to close input stream", e);
134             }
135             this.in = null;
136         }
137
138         OutputStream out = this.out;
139         if (out != null) {
140             try {
141                 out.close();
142             } catch (IOException e) {
143                 logger.warn("failed to close output stream", e);
144             }
145             this.out = null;
146         }
147
148         SerialPort port = this.port;
149         if (port != null) {
150             port.close();
151             this.port = null;
152         }
153     }
154 }