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.Objects;
17 import java.util.concurrent.*;
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;
34 import com.google.gson.Gson;
37 * The {@link WlanThermoMiniHandler} is responsible for handling commands, which are
38 * sent to one of the channels.
40 * @author Christian Schlipp - Initial contribution
43 public class WlanThermoMiniHandler extends BaseThingHandler {
45 private final Logger logger = LoggerFactory.getLogger(WlanThermoMiniHandler.class);
46 private final WlanThermoMiniCommandHandler wlanThermoMiniCommandHandler = new WlanThermoMiniCommandHandler();
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();
56 public WlanThermoMiniHandler(Thing thing, HttpClient httpClient) {
58 this.httpClient = httpClient;
62 public void initialize() {
63 logger.debug("Start initializing WlanThermo Mini!");
64 config = getConfigAs(WlanThermoMiniConfiguration.class);
66 updateStatus(ThingStatus.UNKNOWN);
67 scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS);
69 logger.debug("Finished initializing WlanThermo Mini!");
72 private void checkConnection() {
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);
80 pollingScheduler = scheduler.scheduleWithFixedDelay(this::update, 0, config.getPollingInterval(),
83 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
84 "WlanThermo not found under given address.");
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);
94 pollingScheduler = scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS);
99 public void handleCommand(ChannelUID channelUID, Command command) {
100 if (command instanceof RefreshType) {
101 State s = wlanThermoMiniCommandHandler.getState(channelUID, app);
103 updateState(channelUID, s);
105 // Mini is read only!
108 private void update() {
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);
116 for (Channel channel : thing.getChannels()) {
117 State state = wlanThermoMiniCommandHandler.getState(channel.getUID(), app);
119 updateState(channel.getUID(), state);
121 String trigger = wlanThermoMiniCommandHandler.getTrigger(channel.getUID(), app);
122 if (trigger != null) {
123 triggerChannel(channel.getUID(), trigger);
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);
136 for (Channel channel : thing.getChannels()) {
137 updateState(channel.getUID(), UnDefType.UNDEF);
144 public void dispose() {
145 ScheduledFuture<?> oldScheduler = pollingScheduler;
146 if (oldScheduler != null) {
147 boolean stopped = oldScheduler.cancel(true);
148 logger.debug("Stopped polling: {}", stopped);
150 pollingScheduler = null;