2 * Copyright (c) 2010-2023 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.etherrain.internal.handler;
15 import java.io.IOException;
16 import java.util.concurrent.ScheduledFuture;
17 import java.util.concurrent.TimeUnit;
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.etherrain.internal.EtherRainBindingConstants;
23 import org.openhab.binding.etherrain.internal.EtherRainException;
24 import org.openhab.binding.etherrain.internal.api.EtherRainCommunication;
25 import org.openhab.binding.etherrain.internal.api.EtherRainStatusResponse;
26 import org.openhab.binding.etherrain.internal.config.EtherRainConfiguration;
27 import org.openhab.core.library.types.DecimalType;
28 import org.openhab.core.library.types.OnOffType;
29 import org.openhab.core.library.types.StringType;
30 import org.openhab.core.thing.ChannelUID;
31 import org.openhab.core.thing.Thing;
32 import org.openhab.core.thing.ThingStatus;
33 import org.openhab.core.thing.ThingStatusDetail;
34 import org.openhab.core.thing.binding.BaseThingHandler;
35 import org.openhab.core.types.Command;
36 import org.openhab.core.types.RefreshType;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
41 * The {@link EtherRainHandler} is responsible for handling commands, which are
42 * sent to one of the channels.
44 * @author Joe Inkenbrandt - Initial contribution
47 public class EtherRainHandler extends BaseThingHandler {
49 private final Logger logger = LoggerFactory.getLogger(EtherRainHandler.class);
51 private @Nullable EtherRainCommunication device = null;
52 private boolean connected = false;
53 private @NonNullByDefault({}) EtherRainConfiguration config = null;
55 private @Nullable ScheduledFuture<?> updateJob = null;
57 private final HttpClient httpClient;
60 * Constructor class. Only call the parent constructor
62 public EtherRainHandler(Thing thing, HttpClient httpClient) {
64 this.httpClient = httpClient;
65 this.updateJob = null;
69 public void handleCommand(ChannelUID channelUID, Command command) {
70 if (command == RefreshType.REFRESH) {
71 scheduler.execute(this::updateBridge);
72 } else if (channelUID.getId().equals(EtherRainBindingConstants.CHANNEL_ID_EXECUTE)) {
74 updateState(EtherRainBindingConstants.CHANNEL_ID_EXECUTE, OnOffType.OFF);
75 } else if (channelUID.getId().equals(EtherRainBindingConstants.CHANNEL_ID_CLEAR)) {
77 updateState(EtherRainBindingConstants.CHANNEL_ID_CLEAR, OnOffType.OFF);
81 private boolean connectBridge() {
82 logger.debug("Attempting to connect to Etherrain with config = (Host: {}, Port: {}, Refresh: {}).", config.host,
83 config.port, config.refresh);
85 EtherRainCommunication device = new EtherRainCommunication(config.host, config.port, config.password,
89 device.commandStatus();
90 } catch (EtherRainException | IOException e) {
91 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
92 "Could not create a connection to the EtherRain");
93 logger.debug("Could not open API connection to the EtherRain device. Exception received: {}",
96 updateStatus(ThingStatus.OFFLINE);
101 updateStatus(ThingStatus.ONLINE);
106 private void startUpdateJob() {
107 logger.debug("Starting Etherrain Update Job");
108 this.updateJob = scheduler.scheduleWithFixedDelay(this::updateBridge, 0, config.refresh, TimeUnit.SECONDS);
110 logger.debug("EtherRain successfully initialized. Starting status poll at: {}", config.refresh);
113 private void stopUpdateJob() {
114 logger.debug("Stopping Etherrain Update Job");
116 final ScheduledFuture<?> updateJob = this.updateJob;
117 if (updateJob != null && !updateJob.isDone()) {
118 updateJob.cancel(false);
121 this.updateJob = null;
124 @SuppressWarnings("null")
125 private boolean updateBridge() {
126 if (!connected || device == null) {
127 connected = connectBridge();
128 if (!connected || device == null) {
131 logger.debug("Could not connect to Etherrain device.");
136 EtherRainStatusResponse response;
139 response = device.commandStatus();
140 } catch (EtherRainException | IOException e) {
141 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
142 "Could not create a connection to the EtherRain");
143 logger.debug("Could not open API connection to the EtherRain device. Exception received: {}",
149 updateState(EtherRainBindingConstants.CHANNEL_ID_OPERATING_STATUS,
150 new StringType(response.getOperatingStatus().name()));
152 updateState(EtherRainBindingConstants.CHANNEL_ID_COMMAND_STATUS,
153 new StringType(response.getLastCommandStatus().name()));
155 switch (response.getLastCommandResult()) {
157 updateState(EtherRainBindingConstants.CHANNEL_ID_OPERATING_RESULT, new StringType("OK"));
160 updateState(EtherRainBindingConstants.CHANNEL_ID_OPERATING_RESULT, new StringType("RAIN INTERRUPTED"));
163 updateState(EtherRainBindingConstants.CHANNEL_ID_OPERATING_RESULT,
164 new StringType("INTERRUPPTED SHORT"));
167 updateState(EtherRainBindingConstants.CHANNEL_ID_OPERATING_RESULT, new StringType("DID NOT COMPLETE"));
171 updateState(EtherRainBindingConstants.CHANNEL_ID_RELAY_INDEX, new DecimalType(response.getLastActiveValue()));
173 OnOffType rs = OnOffType.from(response.isRainSensor());
175 updateState(EtherRainBindingConstants.CHANNEL_ID_SENSOR_RAIN, rs);
177 logger.debug("Completed Etherrain Update");
182 private synchronized boolean execute() {
183 EtherRainCommunication device = this.device;
185 if (device != null) {
186 device.commandIrrigate(config.programDelay, config.zoneOnTime1, config.zoneOnTime2, config.zoneOnTime3,
187 config.zoneOnTime4, config.zoneOnTime5, config.zoneOnTime6, config.zoneOnTime7, config.zoneOnTime8);
194 private boolean clear() {
195 EtherRainCommunication device = this.device;
196 if (device != null) {
197 device.commandClear();
206 public void initialize() {
207 config = getConfigAs(EtherRainConfiguration.class);
212 public void dispose() {