]> git.basschouten.com Git - openhab-addons.git/blob
3edb89995bea69b770e624fc9b98cd8ff74695da
[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.liquidcheck.internal;
14
15 import static org.openhab.binding.liquidcheck.internal.LiquidCheckBindingConstants.CONTENT_CHANNEL;
16 import static org.openhab.binding.liquidcheck.internal.LiquidCheckBindingConstants.FILL_INDICATOR_CHANNEL;
17 import static org.openhab.binding.liquidcheck.internal.LiquidCheckBindingConstants.LEVEL_CHANNEL;
18 import static org.openhab.binding.liquidcheck.internal.LiquidCheckBindingConstants.MEASURE_CHANNEL;
19 import static org.openhab.binding.liquidcheck.internal.LiquidCheckBindingConstants.PUMP_TOTAL_RUNS_CHANNEL;
20 import static org.openhab.binding.liquidcheck.internal.LiquidCheckBindingConstants.PUMP_TOTAL_RUNTIME_CHANNEL;
21 import static org.openhab.binding.liquidcheck.internal.LiquidCheckBindingConstants.RAW_CONTENT_CHANNEL;
22 import static org.openhab.binding.liquidcheck.internal.LiquidCheckBindingConstants.RAW_LEVEL_CHANNEL;
23
24 import java.util.HashMap;
25 import java.util.Map;
26 import java.util.concurrent.ExecutionException;
27 import java.util.concurrent.ScheduledFuture;
28 import java.util.concurrent.TimeUnit;
29 import java.util.concurrent.TimeoutException;
30
31 import org.eclipse.jdt.annotation.NonNullByDefault;
32 import org.eclipse.jdt.annotation.Nullable;
33 import org.eclipse.jetty.client.HttpClient;
34 import org.openhab.binding.liquidcheck.internal.httpclient.LiquidCheckHttpClient;
35 import org.openhab.binding.liquidcheck.internal.json.CommData;
36 import org.openhab.core.library.types.DecimalType;
37 import org.openhab.core.library.types.OnOffType;
38 import org.openhab.core.library.types.QuantityType;
39 import org.openhab.core.library.unit.SIUnits;
40 import org.openhab.core.library.unit.Units;
41 import org.openhab.core.thing.ChannelUID;
42 import org.openhab.core.thing.Thing;
43 import org.openhab.core.thing.ThingStatus;
44 import org.openhab.core.thing.ThingStatusDetail;
45 import org.openhab.core.thing.binding.BaseThingHandler;
46 import org.openhab.core.types.Command;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 import com.google.gson.Gson;
51 import com.google.gson.JsonSyntaxException;
52
53 /**
54  * The {@link LiquidCheckHandler} is responsible for handling commands, which are
55  * sent to one of the channels.
56  *
57  * @author Marcel Goerentz - Initial contribution
58  */
59 @NonNullByDefault
60 public class LiquidCheckHandler extends BaseThingHandler {
61
62     private final Logger logger = LoggerFactory.getLogger(LiquidCheckHandler.class);
63     private final HttpClient httpClient;
64
65     private Map<String, String> oldProps = new HashMap<>();
66
67     private LiquidCheckConfiguration config = new LiquidCheckConfiguration();
68     private @Nullable LiquidCheckHttpClient client;
69
70     private @Nullable ScheduledFuture<?> polling;
71
72     public LiquidCheckHandler(Thing thing, HttpClient httpClient) {
73         super(thing);
74         this.httpClient = httpClient;
75     }
76
77     @Override
78     @SuppressWarnings("null")
79     public void handleCommand(ChannelUID channelUID, Command command) {
80         if (channelUID.getId().equals(MEASURE_CHANNEL)) {
81             if (command instanceof OnOffType) {
82                 try {
83                     LiquidCheckHttpClient client = this.client;
84                     if (client != null && client.isConnected()) {
85                         String response = client.measureCommand();
86                         CommData commandResponse = new Gson().fromJson(response, CommData.class);
87                         if (commandResponse != null && !"".equals(commandResponse.header.name)) {
88                             if (!"success".equals(commandResponse.context.status)) {
89                                 logger.warn("Starting the measurement was not successful!");
90                             }
91                         } else {
92                             logger.debug("The object commandResponse is null!");
93                         }
94                     }
95                 } catch (TimeoutException | ExecutionException | JsonSyntaxException e) {
96                     logger.warn("This went wrong in handleCommand: {}", e.getMessage());
97                 } catch (InterruptedException e) {
98                     Thread.currentThread().interrupt();
99                 }
100                 updateState(channelUID, OnOffType.OFF);
101             }
102         }
103     }
104
105     @Override
106     public void initialize() {
107         config = getConfigAs(LiquidCheckConfiguration.class);
108         oldProps = thing.getProperties();
109
110         updateStatus(ThingStatus.UNKNOWN);
111         var client = new LiquidCheckHttpClient(config, httpClient);
112         this.client = client;
113         PollingForData pollingRunnable = new PollingForData(client);
114         polling = scheduler.scheduleWithFixedDelay(pollingRunnable, 0, config.refreshInterval, TimeUnit.SECONDS);
115     }
116
117     @Override
118     public void dispose() {
119         ScheduledFuture<?> polling = this.polling;
120         if (null != polling) {
121             polling.cancel(true);
122             this.polling = null;
123         }
124     }
125
126     private class PollingForData implements Runnable {
127
128         private final LiquidCheckHttpClient client;
129
130         public PollingForData(LiquidCheckHttpClient client) {
131             this.client = client;
132         }
133
134         @Override
135         public void run() {
136             try {
137                 String jsonString = client.pollData();
138                 CommData response = new Gson().fromJson(jsonString, CommData.class);
139                 if (response != null && !"".equals(response.header.messageId)) {
140                     Map<String, String> properties = response.createPropertyMap();
141                     if (!oldProps.equals(properties)) {
142                         oldProps = properties;
143                         updateProperties(properties);
144                     }
145                     updateState(CONTENT_CHANNEL, new QuantityType<>(response.payload.measure.content, Units.LITRE));
146                     updateState(LEVEL_CHANNEL, new QuantityType<>(response.payload.measure.level, SIUnits.METRE));
147                     updateState(RAW_CONTENT_CHANNEL,
148                             new QuantityType<>(response.payload.measure.raw.content, Units.LITRE));
149
150                     updateState(RAW_LEVEL_CHANNEL,
151                             new QuantityType<>(response.payload.measure.raw.level, SIUnits.METRE));
152
153                     updateState(PUMP_TOTAL_RUNS_CHANNEL, new DecimalType(response.payload.system.pump.totalRuns));
154                     updateState(PUMP_TOTAL_RUNTIME_CHANNEL,
155                             new QuantityType<>(response.payload.system.pump.totalRuntime, Units.SECOND));
156                     if (config.maxContent > 1) {
157                         double fillIndicator = response.payload.measure.content / config.maxContent * 100;
158                         updateState(FILL_INDICATOR_CHANNEL, new QuantityType<>(fillIndicator, Units.PERCENT));
159                     }
160                     if (!thing.getStatus().equals(ThingStatus.ONLINE)) {
161                         updateStatus(ThingStatus.ONLINE);
162                     }
163                 } else {
164                     logger.debug("Json is null");
165                 }
166             } catch (TimeoutException | ExecutionException | JsonSyntaxException e) {
167                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
168             } catch (InterruptedException e) {
169                 Thread.currentThread().interrupt();
170             }
171         }
172     }
173 }