]> git.basschouten.com Git - openhab-addons.git/blob
ed2e2a60fbb39122e414ec4870efb07b143ac25b
[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("Received ON - Turning TV on via API is not supported by LG WebOS TVs. "
68                                 + "You may succeed using wake on lan (WOL). "
69                                 + "Please set the macAddress config value in Thing configuration to enable this.");
70                         handler.postUpdate(channelId, OnOffType.OFF);
71                     } else {
72                         for (int i = 0; i < WOL_PACKET_RETRY_COUNT; i++) {
73                             scheduler.schedule(() -> {
74                                 try {
75                                     WakeOnLanUtility.sendWOLPacket(macAddress);
76                                 } catch (IllegalArgumentException e) {
77                                     logger.debug("Failed to send WOL packet: {}", e.getMessage());
78                                 }
79                             }, i * WOL_PACKET_RETRY_DELAY_MILLIS, TimeUnit.MILLISECONDS);
80                         }
81                     }
82                     break;
83             }
84         } else if (OnOffType.OFF == command) {
85             switch (state) {
86                 case CONNECTING:
87                 case REGISTERING:
88                     // in both states no message will sent to TV, thus the operation won't have an effect
89                     logger.debug("Received OFF - TV is currently connecting.");
90                     break;
91                 case REGISTERED:
92                     handler.getSocket().powerOff(getDefaultResponseListener());
93                     break;
94                 case DISCONNECTING:
95                 case DISCONNECTED:
96                     logger.debug("Received OFF - TV is already off.");
97                     break;
98             }
99         } else {
100             logger.info("Only accept OnOffType, RefreshType. Type was {}.", command.getClass());
101         }
102     }
103
104     @Override
105     public void onDeviceReady(String channelId, LGWebOSHandler handler) {
106         handler.postUpdate(channelId, OnOffType.ON);
107     }
108
109     @Override
110     public void onDeviceRemoved(String channelId, LGWebOSHandler handler) {
111         handler.postUpdate(channelId, OnOffType.OFF);
112     }
113
114     public interface ConfigProvider {
115         String getMacAddress();
116     }
117 }