]> git.basschouten.com Git - openhab-addons.git/blob
eda9b69cc059152c5d7948ec54caf63b023c3b33
[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.lgwebos.internal;
14
15 import java.util.concurrent.ScheduledExecutorService;
16 import java.util.concurrent.TimeUnit;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.openhab.binding.lgwebos.internal.handler.LGWebOSHandler;
20 import org.openhab.binding.lgwebos.internal.handler.LGWebOSTVSocket.State;
21 import org.openhab.binding.lgwebos.internal.handler.core.CommandConfirmation;
22 import org.openhab.core.library.types.OnOffType;
23 import org.openhab.core.types.Command;
24 import org.openhab.core.types.RefreshType;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 /**
29  * Handles Power Control Command.
30  * Note: Connect SDK only supports powering OFF for most devices.
31  *
32  * @author Sebastian Prehn - Initial contribution
33  */
34 @NonNullByDefault
35 public class PowerControlPower extends BaseChannelHandler<CommandConfirmation> {
36     private static final int WOL_PACKET_RETRY_COUNT = 10;
37     private static final int WOL_PACKET_RETRY_DELAY_MILLIS = 100;
38
39     private final Logger logger = LoggerFactory.getLogger(PowerControlPower.class);
40     private final ConfigProvider configProvider;
41     private final ScheduledExecutorService scheduler;
42
43     public PowerControlPower(ConfigProvider configProvider, ScheduledExecutorService scheduler) {
44         this.configProvider = configProvider;
45         this.scheduler = scheduler;
46     }
47
48     @Override
49     public void onReceiveCommand(String channelId, LGWebOSHandler handler, Command command) {
50         final State state = handler.getSocket().getState();
51         if (RefreshType.REFRESH == command) {
52             handler.postUpdate(channelId, state == State.REGISTERED ? OnOffType.ON : OnOffType.OFF);
53         } else if (OnOffType.ON == command) {
54             switch (state) {
55                 case CONNECTING:
56                 case REGISTERING:
57                     logger.debug("Received ON - TV is currently connecting.");
58                     handler.postUpdate(channelId, OnOffType.OFF);
59                     break;
60                 case REGISTERED:
61                     logger.debug("Received ON - TV is already on.");
62                     break;
63                 case DISCONNECTING: // WOL will not stop the shutdown process, but we must not update the state to ON
64                 case DISCONNECTED:
65                     String macAddress = configProvider.getMacAddress();
66                     if (macAddress.isEmpty()) {
67                         logger.debug("""
68                                 Received ON - Turning TV on via API is not supported by LG WebOS TVs. \
69                                 You may succeed using wake on lan (WOL). \
70                                 Please set the macAddress config value in Thing configuration to enable this.\
71                                 """);
72                         handler.postUpdate(channelId, OnOffType.OFF);
73                     } else {
74                         for (int i = 0; i < WOL_PACKET_RETRY_COUNT; i++) {
75                             scheduler.schedule(() -> {
76                                 try {
77                                     WakeOnLanUtility.sendWOLPacket(macAddress);
78                                 } catch (IllegalArgumentException e) {
79                                     logger.debug("Failed to send WOL packet: {}", e.getMessage());
80                                 }
81                             }, i * WOL_PACKET_RETRY_DELAY_MILLIS, TimeUnit.MILLISECONDS);
82                         }
83                     }
84                     break;
85             }
86         } else if (OnOffType.OFF == command) {
87             switch (state) {
88                 case CONNECTING:
89                 case REGISTERING:
90                     // in both states no message will sent to TV, thus the operation won't have an effect
91                     logger.debug("Received OFF - TV is currently connecting.");
92                     break;
93                 case REGISTERED:
94                     handler.getSocket().powerOff(getDefaultResponseListener());
95                     break;
96                 case DISCONNECTING:
97                 case DISCONNECTED:
98                     logger.debug("Received OFF - TV is already off.");
99                     break;
100             }
101         } else {
102             logger.info("Only accept OnOffType, RefreshType. Type was {}.", command.getClass());
103         }
104     }
105
106     @Override
107     public void onDeviceReady(String channelId, LGWebOSHandler handler) {
108         handler.postUpdate(channelId, OnOffType.ON);
109     }
110
111     @Override
112     public void onDeviceRemoved(String channelId, LGWebOSHandler handler) {
113         handler.postUpdate(channelId, OnOffType.OFF);
114     }
115
116     public interface ConfigProvider {
117         String getMacAddress();
118     }
119 }