]> git.basschouten.com Git - openhab-addons.git/blob
cf6417c40dfa40e411885634fedc04d423268e9d
[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.iammeter.internal;
14
15 import java.io.IOException;
16 import java.time.Duration;
17 import java.util.concurrent.ScheduledFuture;
18 import java.util.concurrent.TimeUnit;
19
20 import javax.measure.Unit;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.openhab.core.cache.ExpiringCache;
25 import org.openhab.core.io.net.http.HttpUtil;
26 import org.openhab.core.library.types.QuantityType;
27 import org.openhab.core.thing.ChannelUID;
28 import org.openhab.core.thing.Thing;
29 import org.openhab.core.thing.ThingStatus;
30 import org.openhab.core.thing.ThingStatusDetail;
31 import org.openhab.core.thing.binding.BaseThingHandler;
32 import org.openhab.core.types.Command;
33 import org.openhab.core.types.RefreshType;
34 import org.openhab.core.types.State;
35 import org.openhab.core.types.UnDefType;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 import com.google.gson.JsonSyntaxException;
40
41 /**
42  * The {@link IammeterHandler} is responsible for handling commands, which are
43  * sent to one of the channels.
44  *
45  * @author Yang Bo - Initial contribution
46  */
47
48 @NonNullByDefault
49 public abstract class IammeterBaseHandler extends BaseThingHandler {
50
51     private final Logger logger = LoggerFactory.getLogger(IammeterBaseHandler.class);
52     private @Nullable ScheduledFuture<?> refreshJob;
53     private IammeterConfiguration config;
54     private static final int TIMEOUT_MS = 5000;
55     private final ExpiringCache<Boolean> refreshCache = new ExpiringCache<>(Duration.ofSeconds(5), this::refresh);
56
57     public IammeterBaseHandler(Thing thing) {
58         super(thing);
59         config = getConfiguration();
60     }
61
62     @Override
63     public void handleCommand(ChannelUID channelUID, Command command) {
64         if (command instanceof RefreshType) {
65             refreshCache.getValue();
66         }
67     }
68
69     @Override
70     public void initialize() {
71         ScheduledFuture<?> refreshJob = this.refreshJob;
72         config = getConfiguration();
73         if (refreshJob == null) {
74             refreshJob = scheduler.scheduleWithFixedDelay(this::refresh, 0, config.refreshInterval, TimeUnit.SECONDS);
75             this.refreshJob = refreshJob;
76             updateStatus(ThingStatus.UNKNOWN);
77         }
78     }
79
80     protected abstract void resolveData(String response);
81
82     @SuppressWarnings("null")
83     private boolean refresh() {
84         refreshCache.invalidateValue();
85         IammeterConfiguration config = this.config;
86         try {
87             String httpMethod = "GET";
88             String url = "http://" + config.username + ":" + config.password + "@" + config.host + ":" + config.port
89                     + "/monitorjson";
90             String response = HttpUtil.executeUrl(httpMethod, url, TIMEOUT_MS);
91             resolveData(response);
92             updateStatus(ThingStatus.ONLINE);
93             return true;
94             // Very rudimentary Exception differentiation
95         } catch (IOException e) {
96             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
97                     "Communication error with the device: " + e.getMessage());
98         } catch (JsonSyntaxException je) {
99             logger.warn("Invalid JSON when refreshing source {}: {}", getThing().getUID(), je.getMessage());
100             updateStatus(ThingStatus.OFFLINE);
101         }
102         return false;
103     }
104
105     protected State getQuantityState(String value, Unit<?> unit) {
106         try {
107             return QuantityType.valueOf(Float.parseFloat(value), unit);
108         } catch (NumberFormatException e) {
109             return UnDefType.UNDEF;
110         }
111     }
112
113     @Override
114     public void dispose() {
115         ScheduledFuture<?> refreshJob = this.refreshJob;
116         if (refreshJob != null && !refreshJob.isCancelled()) {
117             refreshJob.cancel(true);
118             this.refreshJob = null;
119         }
120         super.dispose();
121     }
122
123     public IammeterConfiguration getConfiguration() {
124         return this.getConfigAs(IammeterConfiguration.class);
125     }
126 }