]> git.basschouten.com Git - openhab-addons.git/blob
eb0c3893e3acb4ba09ea2b20ac7f93031bcd065f
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.wlanthermo.internal;
14
15 import java.net.URISyntaxException;
16 import java.util.Objects;
17 import java.util.concurrent.*;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.eclipse.jetty.client.HttpClient;
22 import org.openhab.binding.wlanthermo.internal.api.mini.builtin.App;
23 import org.openhab.binding.wlanthermo.internal.api.mini.builtin.WlanThermoMiniCommandHandler;
24 import org.openhab.core.common.ThreadPoolManager;
25 import org.openhab.core.thing.*;
26 import org.openhab.core.thing.binding.BaseThingHandler;
27 import org.openhab.core.types.Command;
28 import org.openhab.core.types.RefreshType;
29 import org.openhab.core.types.State;
30 import org.openhab.core.types.UnDefType;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import com.google.gson.Gson;
35
36 /**
37  * The {@link WlanThermoMiniHandler} is responsible for handling commands, which are
38  * sent to one of the channels.
39  *
40  * @author Christian Schlipp - Initial contribution
41  */
42 @NonNullByDefault
43 public class WlanThermoMiniHandler extends BaseThingHandler {
44
45     private final Logger logger = LoggerFactory.getLogger(WlanThermoMiniHandler.class);
46     private final WlanThermoMiniCommandHandler wlanThermoMiniCommandHandler = new WlanThermoMiniCommandHandler();
47
48     private WlanThermoMiniConfiguration config = new WlanThermoMiniConfiguration();
49     private final HttpClient httpClient;
50     private @Nullable ScheduledFuture<?> pollingScheduler;
51     private final ScheduledExecutorService scheduler = ThreadPoolManager
52             .getScheduledPool(WlanThermoBindingConstants.WLANTHERMO_THREAD_POOL);
53     private final Gson gson = new Gson();
54     private App app = new App();
55
56     public WlanThermoMiniHandler(Thing thing, HttpClient httpClient) {
57         super(thing);
58         this.httpClient = httpClient;
59     }
60
61     @Override
62     public void initialize() {
63         logger.debug("Start initializing WlanThermo Mini!");
64         config = getConfigAs(WlanThermoMiniConfiguration.class);
65
66         updateStatus(ThingStatus.UNKNOWN);
67         scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS);
68
69         logger.debug("Finished initializing WlanThermo Mini!");
70     }
71
72     private void checkConnection() {
73         try {
74             if (httpClient.GET(config.getUri("/app.php")).getStatus() == 200) {
75                 updateStatus(ThingStatus.ONLINE);
76                 ScheduledFuture<?> oldScheduler = pollingScheduler;
77                 if (oldScheduler != null) {
78                     oldScheduler.cancel(false);
79                 }
80                 pollingScheduler = scheduler.scheduleWithFixedDelay(this::update, 0, config.getPollingInterval(),
81                         TimeUnit.SECONDS);
82             } else {
83                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
84                         "WlanThermo not found under given address.");
85             }
86         } catch (URISyntaxException | InterruptedException | ExecutionException | TimeoutException e) {
87             logger.debug("Failed to connect.", e);
88             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
89                     "Could not connect to WlanThermo at " + config.getIpAddress());
90             ScheduledFuture<?> oldScheduler = pollingScheduler;
91             if (oldScheduler != null) {
92                 oldScheduler.cancel(false);
93             }
94             pollingScheduler = scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS);
95         }
96     }
97
98     @Override
99     public void handleCommand(ChannelUID channelUID, Command command) {
100         if (command instanceof RefreshType) {
101             State s = wlanThermoMiniCommandHandler.getState(channelUID, app);
102             if (s != null)
103                 updateState(channelUID, s);
104         }
105         // Mini is read only!
106     }
107
108     private void update() {
109         try {
110             // Update objects with data from device
111             String json = httpClient.GET(config.getUri("/app.php")).getContentAsString();
112             app = Objects.requireNonNull(gson.fromJson(json, App.class));
113             logger.debug("Received at /app.php: {}", json);
114
115             // Update channels
116             for (Channel channel : thing.getChannels()) {
117                 State state = wlanThermoMiniCommandHandler.getState(channel.getUID(), app);
118                 if (state != null) {
119                     updateState(channel.getUID(), state);
120                 } else {
121                     String trigger = wlanThermoMiniCommandHandler.getTrigger(channel.getUID(), app);
122                     if (trigger != null) {
123                         triggerChannel(channel.getUID(), trigger);
124                     }
125                 }
126
127             }
128
129         } catch (URISyntaxException | InterruptedException | ExecutionException | TimeoutException e) {
130             logger.debug("Update failed, checking connection", e);
131             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Update failed, reconnecting...");
132             ScheduledFuture<?> oldScheduler = pollingScheduler;
133             if (oldScheduler != null) {
134                 oldScheduler.cancel(false);
135             }
136             for (Channel channel : thing.getChannels()) {
137                 updateState(channel.getUID(), UnDefType.UNDEF);
138             }
139             checkConnection();
140         }
141     }
142
143     @Override
144     public void dispose() {
145         ScheduledFuture<?> oldScheduler = pollingScheduler;
146         if (oldScheduler != null) {
147             boolean stopped = oldScheduler.cancel(true);
148             logger.debug("Stopped polling: {}", stopped);
149         }
150         pollingScheduler = null;
151     }
152 }