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.lirc.internal.connector;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.io.OutputStream;
18 import java.io.PrintWriter;
19 import java.net.Socket;
20 import java.net.UnknownHostException;
22 import java.util.concurrent.CopyOnWriteArraySet;
24 import org.openhab.binding.lirc.internal.config.LIRCBridgeConfiguration;
25 import org.openhab.binding.lirc.internal.messages.LIRCButtonEvent;
26 import org.openhab.binding.lirc.internal.messages.LIRCResponse;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
31 * Connector for communication with the LIRC server
33 * @author Andrew Nagle - Initial contributor
35 public class LIRCConnector {
37 private final Logger logger = LoggerFactory.getLogger(LIRCConnector.class);
39 private Set<LIRCEventListener> listeners = new CopyOnWriteArraySet<>();
40 private Socket socket;
41 private InputStream in;
42 private OutputStream out;
43 private PrintWriter outWriter;
44 private Thread readerThread;
46 public void addEventListener(LIRCEventListener listener) {
47 listeners.add(listener);
50 public void removeEventListener(LIRCEventListener listener) {
51 listeners.remove(listener);
54 public void connect(LIRCBridgeConfiguration config) throws UnknownHostException, IOException {
55 logger.debug("Connecting");
57 // Consider adding support for Unix Domain sockets as well.
58 // This would allow us to autodiscover the local LIRC server.
59 // The junixsocket library should work nicely
60 socket = new Socket(config.getHost(), config.getPortNumber());
61 out = socket.getOutputStream();
62 in = socket.getInputStream();
63 outWriter = new PrintWriter(out, true);
64 readerThread = new LIRCStreamReader(this, in);
68 public void disconnect() {
69 logger.debug("Disconnecting");
70 if (readerThread != null) {
71 logger.debug("Interrupt stream listener");
72 readerThread.interrupt();
75 if (outWriter != null) {
76 logger.debug("Close print writer stream");
81 logger.debug("Close socket");
84 } catch (IOException e) {
85 logger.debug("Error while closing the socket: {}", e.getMessage());
91 logger.debug("Disconnected");
95 * Begins discovery of all remotes the LIRC server knows about.
97 public void startRemoteDiscovery() {
102 * Transmits the button press for the specified remote.
109 public void transmit(String remote, String button) {
112 String[] parts = button.split(" ");
113 if (parts.length > 1) {
114 buttonName = parts[0];
115 timesToSend = Integer.parseInt(parts[1]);
119 transmit(remote, buttonName, timesToSend);
123 * Transmits the button press for the specified remote
130 * Number of times to transmit the button
132 public void transmit(String remote, String button, int timesToSend) {
133 // The last parameter is the number of times the command should be repeated.
134 // For example, the command "SEND_ONCE TV KEY_VOLUMEUP 4" will transmit
135 // the volume up code 5 times.
136 sendCommand(String.format("SEND_ONCE %s %s %s", remote, button, timesToSend - 1));
139 private synchronized void sendCommand(String command) {
140 outWriter.println(command);
145 * Sends a button pressed event to all listeners
150 public synchronized void sendButtonToListeners(LIRCButtonEvent buttonEvent) {
152 for (LIRCEventListener listener : listeners) {
153 listener.buttonPressed(buttonEvent);
155 } catch (Exception e) {
156 logger.error("Error invoking event listener", e);
161 * Sends an error message to all listeners
164 * error message to send
166 public synchronized void sendErrorToListeners(String error) {
168 for (LIRCEventListener listener : listeners) {
169 listener.errorOccured(error);
171 } catch (Exception e) {
172 logger.error("Error invoking event listener", e);
177 * Sends a LIRC message to all listeners
182 public synchronized void sendMessageToListeners(LIRCResponse message) {
184 for (LIRCEventListener listener : listeners) {
185 listener.messageReceived(message);
187 } catch (Exception e) {
188 logger.error("Error invoking event listener", e);