2 * Copyright (c) 2010-2020 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.wlanthermo.internal;
15 import java.net.URISyntaxException;
16 import java.util.concurrent.*;
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.eclipse.jetty.client.HttpClient;
21 import org.openhab.binding.wlanthermo.internal.api.mini.builtin.App;
22 import org.openhab.binding.wlanthermo.internal.api.mini.builtin.WlanThermoMiniCommandHandler;
23 import org.openhab.core.common.ThreadPoolManager;
24 import org.openhab.core.thing.*;
25 import org.openhab.core.thing.binding.BaseThingHandler;
26 import org.openhab.core.types.Command;
27 import org.openhab.core.types.RefreshType;
28 import org.openhab.core.types.State;
29 import org.openhab.core.types.UnDefType;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
33 import com.google.gson.Gson;
36 * The {@link WlanThermoMiniHandler} is responsible for handling commands, which are
37 * sent to one of the channels.
39 * @author Christian Schlipp - Initial contribution
42 public class WlanThermoMiniHandler extends BaseThingHandler {
44 private final Logger logger = LoggerFactory.getLogger(WlanThermoMiniHandler.class);
45 private final WlanThermoMiniCommandHandler wlanThermoMiniCommandHandler = new WlanThermoMiniCommandHandler();
47 private WlanThermoMiniConfiguration config = new WlanThermoMiniConfiguration();
48 private final HttpClient httpClient;
49 private @Nullable ScheduledFuture<?> pollingScheduler;
50 private final ScheduledExecutorService scheduler = ThreadPoolManager
51 .getScheduledPool(WlanThermoBindingConstants.WLANTHERMO_THREAD_POOL);
52 private final Gson gson = new Gson();
53 private App app = new App();
55 public WlanThermoMiniHandler(Thing thing, HttpClient httpClient) {
57 this.httpClient = httpClient;
61 public void initialize() {
62 logger.debug("Start initializing WlanThermo Mini!");
63 config = getConfigAs(WlanThermoMiniConfiguration.class);
65 updateStatus(ThingStatus.UNKNOWN);
66 scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS);
68 logger.debug("Finished initializing WlanThermo Mini!");
71 private void checkConnection() {
73 if (httpClient.GET(config.getUri("/app.php")).getStatus() == 200) {
74 updateStatus(ThingStatus.ONLINE);
75 ScheduledFuture<?> oldScheduler = pollingScheduler;
76 if (oldScheduler != null) {
77 oldScheduler.cancel(false);
79 pollingScheduler = scheduler.scheduleWithFixedDelay(this::update, 0, config.getPollingInterval(),
82 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
83 "WlanThermo not found under given address.");
85 } catch (URISyntaxException | InterruptedException | ExecutionException | TimeoutException e) {
86 logger.debug("Failed to connect.", e);
87 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
88 "Could not connect to WlanThermo at " + config.getIpAddress());
89 ScheduledFuture<?> oldScheduler = pollingScheduler;
90 if (oldScheduler != null) {
91 oldScheduler.cancel(false);
93 pollingScheduler = scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS);
98 public void handleCommand(ChannelUID channelUID, Command command) {
99 if (command instanceof RefreshType) {
100 State s = wlanThermoMiniCommandHandler.getState(channelUID, app);
102 updateState(channelUID, s);
104 // Mini is read only!
107 private void update() {
109 // Update objects with data from device
110 String json = httpClient.GET(config.getUri("/app.php")).getContentAsString();
111 app = gson.fromJson(json, App.class);
112 logger.debug("Received at /app.php: {}", json);
115 for (Channel channel : thing.getChannels()) {
116 State state = wlanThermoMiniCommandHandler.getState(channel.getUID(), app);
118 updateState(channel.getUID(), state);
120 String trigger = wlanThermoMiniCommandHandler.getTrigger(channel.getUID(), app);
121 if (trigger != null) {
122 triggerChannel(channel.getUID(), trigger);
128 } catch (URISyntaxException | InterruptedException | ExecutionException | TimeoutException e) {
129 logger.debug("Update failed, checking connection", e);
130 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Update failed, reconnecting...");
131 ScheduledFuture<?> oldScheduler = pollingScheduler;
132 if (oldScheduler != null) {
133 oldScheduler.cancel(false);
135 for (Channel channel : thing.getChannels()) {
136 updateState(channel.getUID(), UnDefType.UNDEF);
143 public void dispose() {
144 ScheduledFuture<?> oldScheduler = pollingScheduler;
145 if (oldScheduler != null) {
146 boolean stopped = oldScheduler.cancel(true);
147 logger.debug("Stopped polling: {}", stopped);
149 pollingScheduler = null;