]> git.basschouten.com Git - openhab-addons.git/blob
5adc0b0a33ef79496bbcfe50facee2f08f837050
[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.broadlinkthermostat.internal.handler;
14
15 import static org.openhab.core.library.types.OnOffType.OFF;
16 import static org.openhab.core.library.types.OnOffType.ON;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.nio.file.Files;
21 import java.nio.file.StandardOpenOption;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.broadlinkthermostat.internal.BroadlinkBindingConstants;
26 import org.openhab.binding.broadlinkthermostat.internal.BroadlinkHandlerFactory;
27 import org.openhab.core.library.types.OnOffType;
28 import org.openhab.core.thing.ChannelUID;
29 import org.openhab.core.thing.Thing;
30 import org.openhab.core.thing.ThingStatus;
31 import org.openhab.core.thing.ThingStatusDetail;
32 import org.openhab.core.types.Command;
33 import org.openhab.core.types.RefreshType;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 import com.github.mob41.blapi.RM2Device;
38 import com.github.mob41.blapi.mac.Mac;
39 import com.github.mob41.blapi.pkt.cmd.rm2.SendDataCmdPayload;
40
41 /**
42  * The {@link RMUniversalRemoteHandler} is responsible for handling RM Mini Universal Remotes.
43  *
44  * @author Miguel Álvarez - Initial contribution
45  */
46 @NonNullByDefault
47 public class RMUniversalRemoteHandler extends BroadlinkBaseHandler {
48     private final Logger logger = LoggerFactory.getLogger(RMUniversalRemoteHandler.class);
49     private @Nullable RM2Device rm2Device;
50
51     /**
52      * Creates a new instance of this class for the {@link RMUniversalRemoteHandler}.
53      *
54      * @param thing the thing that should be handled, not null
55      */
56     public RMUniversalRemoteHandler(Thing thing) {
57         super(thing);
58     }
59
60     /**
61      * Initializes a new instance of a {@link RMUniversalRemoteHandler}.
62      */
63     @Override
64     public void initialize() {
65         super.initialize();
66         if (!host.isBlank() && !macAddress.isBlank()) {
67             try {
68                 blDevice = new RM2Device(host, new Mac(macAddress));
69                 this.rm2Device = (RM2Device) blDevice;
70                 updateStatus(ThingStatus.ONLINE);
71             } catch (IOException e) {
72                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
73                         "Could not find broadlink universal remote device at host " + host + " with MAC " + macAddress
74                                 + ": " + e.getMessage());
75             }
76         } else {
77             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Missing device configuration");
78         }
79     }
80
81     @Override
82     public void handleCommand(ChannelUID channelUID, Command command) {
83         logger.debug("Command: {}", command.toFullString());
84
85         if (command == RefreshType.REFRESH) {
86             logger.debug("Nothing to refresh on thing {}", thing.getUID());
87             return;
88         }
89         authenticate(false);
90         String channelId = channelUID.getIdWithoutGroup();
91         try {
92             switch (channelId) {
93                 case BroadlinkBindingConstants.LEARNING_MODE:
94                     if (OnOffType.from(command.toFullString()).equals(ON)) {
95                         handleLearningCommand();
96                     }
97                     break;
98                 case BroadlinkBindingConstants.SAVE_LEARNED:
99                     handleSaveLearned(command);
100                     break;
101                 case BroadlinkBindingConstants.SEND_LEARNED:
102                     handleSendLearned(command);
103                     break;
104                 default:
105                     logger.debug("Command {} not supported by channel {}", command.toFullString(), channelId);
106             }
107         } catch (Exception e) {
108             logger.warn("Exception while running channel {}", channelUID);
109         }
110     }
111
112     private void handleLearningCommand() throws IOException {
113         RM2Device rm2Device = this.rm2Device;
114         if (rm2Device != null) {
115             try {
116                 rm2Device.enterLearning();
117                 updateState(BroadlinkBindingConstants.LEARNING_MODE, ON);
118                 logger.debug("Thing {} entered learning mode", thing.getUID());
119             } catch (IOException e) {
120                 updateState(BroadlinkBindingConstants.LEARNING_MODE, OFF);
121                 throw e;
122             }
123         } else {
124             logger.warn("Device not initialized");
125         }
126     }
127
128     private void handleSaveLearned(Command command) throws Exception {
129         RM2Device rm2Device = this.rm2Device;
130         if (rm2Device != null) {
131             byte @Nullable [] learned = rm2Device.checkData();
132             updateState(BroadlinkBindingConstants.LEARNING_MODE, OFF);
133             if (learned == null) {
134                 logger.warn("Thing {}: nothing learned", thing.getUID());
135                 return;
136             }
137             var packetName = command.toFullString();
138             File destinationFile = new File(BroadlinkHandlerFactory.INFRARED_FOLDER, packetName);
139             if (destinationFile.exists()) {
140                 logger.info("Key '{}' is already learned, overwriting...", packetName);
141             }
142             Files.write(destinationFile.toPath(), learned, new StandardOpenOption[] { StandardOpenOption.WRITE,
143                     StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING });
144         }
145     }
146
147     private void handleSendLearned(Command command) throws IOException {
148         RM2Device rm2Device = this.rm2Device;
149         if (rm2Device != null) {
150             File packetFile = new File(BroadlinkHandlerFactory.INFRARED_FOLDER, command.toFullString());
151             if (!packetFile.exists()) {
152                 logger.warn("{}: Nothing learned as '{}'", thing.getUID(), command.toFullString());
153                 return;
154             }
155             var packet = Files.readAllBytes(packetFile.toPath());
156             rm2Device.sendCmdPkt(new SendDataCmdPayload(packet));
157         }
158     }
159 }