]> git.basschouten.com Git - openhab-addons.git/blob
7c20d8b0a93d71511ec31f75e80c367fb1eab503
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.concurrent.*;
17
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;
32
33 import com.google.gson.Gson;
34
35 /**
36  * The {@link WlanThermoMiniHandler} is responsible for handling commands, which are
37  * sent to one of the channels.
38  *
39  * @author Christian Schlipp - Initial contribution
40  */
41 @NonNullByDefault
42 public class WlanThermoMiniHandler extends BaseThingHandler {
43
44     private final Logger logger = LoggerFactory.getLogger(WlanThermoMiniHandler.class);
45     private final WlanThermoMiniCommandHandler wlanThermoMiniCommandHandler = new WlanThermoMiniCommandHandler();
46
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();
54
55     public WlanThermoMiniHandler(Thing thing, HttpClient httpClient) {
56         super(thing);
57         this.httpClient = httpClient;
58     }
59
60     @Override
61     public void initialize() {
62         logger.debug("Start initializing WlanThermo Mini!");
63         config = getConfigAs(WlanThermoMiniConfiguration.class);
64
65         updateStatus(ThingStatus.UNKNOWN);
66         scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS);
67
68         logger.debug("Finished initializing WlanThermo Mini!");
69     }
70
71     private void checkConnection() {
72         try {
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);
78                 }
79                 pollingScheduler = scheduler.scheduleWithFixedDelay(this::update, 0, config.getPollingInterval(),
80                         TimeUnit.SECONDS);
81             } else {
82                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
83                         "WlanThermo not found under given address.");
84             }
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);
92             }
93             pollingScheduler = scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS);
94         }
95     }
96
97     @Override
98     public void handleCommand(ChannelUID channelUID, Command command) {
99         if (command instanceof RefreshType) {
100             State s = wlanThermoMiniCommandHandler.getState(channelUID, app);
101             if (s != null)
102                 updateState(channelUID, s);
103         }
104         // Mini is read only!
105     }
106
107     private void update() {
108         try {
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);
113
114             // Update channels
115             for (Channel channel : thing.getChannels()) {
116                 State state = wlanThermoMiniCommandHandler.getState(channel.getUID(), app);
117                 if (state != null) {
118                     updateState(channel.getUID(), state);
119                 } else {
120                     String trigger = wlanThermoMiniCommandHandler.getTrigger(channel.getUID(), app);
121                     if (trigger != null) {
122                         triggerChannel(channel.getUID(), trigger);
123                     }
124                 }
125
126             }
127
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);
134             }
135             for (Channel channel : thing.getChannels()) {
136                 updateState(channel.getUID(), UnDefType.UNDEF);
137             }
138             checkConnection();
139         }
140     }
141
142     @Override
143     public void dispose() {
144         ScheduledFuture<?> oldScheduler = pollingScheduler;
145         if (oldScheduler != null) {
146             boolean stopped = oldScheduler.cancel(true);
147             logger.debug("Stopped polling: {}", stopped);
148         }
149         pollingScheduler = null;
150     }
151 }