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.handler;
15 import java.util.regex.Matcher;
16 import java.util.regex.Pattern;
18 import org.openhab.binding.lirc.internal.LIRCBindingConstants;
19 import org.openhab.binding.lirc.internal.LIRCMessageListener;
20 import org.openhab.binding.lirc.internal.config.LIRCRemoteConfiguration;
21 import org.openhab.binding.lirc.internal.messages.LIRCButtonEvent;
22 import org.openhab.binding.lirc.internal.messages.LIRCResponse;
23 import org.openhab.core.library.types.StringType;
24 import org.openhab.core.thing.ChannelUID;
25 import org.openhab.core.thing.Thing;
26 import org.openhab.core.thing.ThingStatus;
27 import org.openhab.core.thing.ThingStatusDetail;
28 import org.openhab.core.thing.ThingUID;
29 import org.openhab.core.thing.binding.BaseThingHandler;
30 import org.openhab.core.types.Command;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
35 * The {@link LIRCRemoteHandler} is responsible for handling commands, which are
36 * sent to one of the channels.
38 * @author Andrew Nagle - Initial contribution
40 public class LIRCRemoteHandler extends BaseThingHandler implements LIRCMessageListener {
42 private final Logger logger = LoggerFactory.getLogger(LIRCRemoteHandler.class);
43 private static final Pattern UNKNOWN_REMOTE_PATTERN = Pattern.compile("^unknown remote: \"(.+)\"$");
45 private LIRCBridgeHandler bridgeHandler;
46 private LIRCRemoteConfiguration config;
47 private String remoteName = null;
49 public LIRCRemoteHandler(Thing thing) {
54 public void handleCommand(ChannelUID channelUID, Command command) {
55 logger.debug("Received channel: {}, command: {}", channelUID, command);
56 if (remoteName == null) {
57 logger.error("Remote name is not set in {}", getThing().getUID());
60 if (channelUID.getId().equals(LIRCBindingConstants.CHANNEL_TRANSMIT)) {
61 // command instanceof RefreshType is not supported
62 if (command instanceof StringType) {
63 bridgeHandler.transmit(remoteName, command.toString());
69 public void initialize() {
70 logger.debug("Initializing thing {}", getThing().getUID());
71 config = getConfigAs(LIRCRemoteConfiguration.class);
72 remoteName = config.getRemote();
73 if (remoteName == null) {
74 logger.error("Remote name is not set in {}", getThing().getUID());
75 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Remote name is not set");
77 bridgeHandler = (LIRCBridgeHandler) getBridge().getHandler();
78 bridgeHandler.registerMessageListener(this);
79 if (getBridge().getStatus() == ThingStatus.ONLINE) {
80 updateStatus(ThingStatus.ONLINE);
82 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
88 public void dispose() {
89 logger.debug("Thing {} disposed.", getThing().getUID());
90 if (bridgeHandler != null) {
91 bridgeHandler.unregisterMessageListener(this);
98 public void onButtonPressed(ThingUID bridge, LIRCButtonEvent buttonEvent) {
99 if (remoteName.equals(buttonEvent.getRemote())) {
100 logger.debug("Remote {}: Button {} pressed {} times.", remoteName, buttonEvent.getButton(),
101 buttonEvent.getRepeats() + 1);
102 updateStatus(ThingStatus.ONLINE);
103 triggerChannel(LIRCBindingConstants.CHANNEL_EVENT, buttonEvent.getButton());
108 public void onMessageReceived(ThingUID bridge, LIRCResponse response) {
109 String command = response.getCommand();
110 if ("LIST".equals(command) && response.isSuccess()) {
111 boolean found = false;
112 for (String remote : response.getData()) {
113 if (remoteName.equals(remote)) {
118 updateStatus(ThingStatus.ONLINE);
120 logger.error("Remote {}: Remote was removed from LIRC server.", remoteName);
121 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
123 } else if (!response.isSuccess()) {
124 String error = response.getData()[0];
125 Matcher m = UNKNOWN_REMOTE_PATTERN.matcher(error);
126 if (m.matches() && remoteName.equals(m.group(1))) {
127 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Unknown remote");