]> git.basschouten.com Git - openhab-addons.git/blob
3e0368c17f3fc3ff5fcc742582e3217d555becf3
[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.lirc.internal.handler;
14
15 import java.util.regex.Matcher;
16 import java.util.regex.Pattern;
17
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;
33
34 /**
35  * The {@link LIRCRemoteHandler} is responsible for handling commands, which are
36  * sent to one of the channels.
37  *
38  * @author Andrew Nagle - Initial contribution
39  */
40 public class LIRCRemoteHandler extends BaseThingHandler implements LIRCMessageListener {
41
42     private final Logger logger = LoggerFactory.getLogger(LIRCRemoteHandler.class);
43     private static final Pattern UNKNOWN_REMOTE_PATTERN = Pattern.compile("^unknown remote: \"(.+)\"$");
44
45     private LIRCBridgeHandler bridgeHandler;
46     private LIRCRemoteConfiguration config;
47     private String remoteName = null;
48
49     public LIRCRemoteHandler(Thing thing) {
50         super(thing);
51     }
52
53     @Override
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());
58             return;
59         }
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());
64             }
65         }
66     }
67
68     @Override
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");
76         } else {
77             bridgeHandler = (LIRCBridgeHandler) getBridge().getHandler();
78             bridgeHandler.registerMessageListener(this);
79             if (getBridge().getStatus() == ThingStatus.ONLINE) {
80                 updateStatus(ThingStatus.ONLINE);
81             } else {
82                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
83             }
84         }
85     }
86
87     @Override
88     public void dispose() {
89         logger.debug("Thing {} disposed.", getThing().getUID());
90         if (bridgeHandler != null) {
91             bridgeHandler.unregisterMessageListener(this);
92         }
93         bridgeHandler = null;
94         super.dispose();
95     }
96
97     @Override
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());
104         }
105     }
106
107     @Override
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)) {
114                     found = true;
115                 }
116             }
117             if (found) {
118                 updateStatus(ThingStatus.ONLINE);
119             } else {
120                 logger.error("Remote {}: Remote was removed from LIRC server.", remoteName);
121                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
122             }
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");
128             }
129         }
130     }
131 }