2 * Copyright (c) 2010-2024 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.homewizard.internal;
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.openhab.core.io.net.http.HttpUtil;
22 import org.openhab.core.thing.Thing;
23 import org.openhab.core.thing.ThingStatus;
24 import org.openhab.core.thing.ThingStatusDetail;
25 import org.openhab.core.thing.binding.BaseThingHandler;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
29 import com.google.gson.FieldNamingPolicy;
30 import com.google.gson.Gson;
31 import com.google.gson.GsonBuilder;
34 * The {@link HomeWizardDeviceHandler} is a base class for all
35 * HomeWizard devices. It provides configuration and polling of
36 * data from a device. It also processes common data.
38 * @author Daniƫl van Os - Initial contribution
41 public abstract class HomeWizardDeviceHandler extends BaseThingHandler {
43 protected final Logger logger = LoggerFactory.getLogger(HomeWizardDeviceHandler.class);
44 protected final Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
47 private HomeWizardConfiguration config = new HomeWizardConfiguration();
48 private @Nullable ScheduledFuture<?> pollingJob;
50 protected String apiURL = "";
55 * @param thing The thing to handle
57 public HomeWizardDeviceHandler(Thing thing) {
62 * If a host has been specified start polling it
65 public void initialize() {
66 config = getConfigAs(HomeWizardConfiguration.class);
68 pollingJob = scheduler.scheduleWithFixedDelay(this::pollingCode, 0, config.refreshDelay, TimeUnit.SECONDS);
73 * Check the current configuration
75 * @return true if the configuration is ok to start polling, false otherwise
77 private boolean configure() {
78 if (config.ipAddress.trim().isEmpty()) {
79 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
80 "Missing ipAddress/host configuration");
83 updateStatus(ThingStatus.UNKNOWN);
84 apiURL = String.format("http://%s/api/v1/", config.ipAddress.trim());
90 * dispose: stop the poller
93 public void dispose() {
102 * Device specific handling of the returned data payload.
104 * @param payload The data parsed from the data Json file
106 protected abstract void handleDataPayload(DataPayload payload);
111 protected void pollData() {
112 final String dataResult;
115 dataResult = HttpUtil.executeUrl("GET", apiURL + "data", 30000);
116 } catch (IOException e) {
117 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
118 String.format("Unable to query device data: %s", e.getMessage()));
122 if (dataResult.trim().isEmpty()) {
123 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Device returned empty data");
127 DataPayload dataPayload = gson.fromJson(dataResult, DataPayload.class);
128 if (dataPayload == null) {
129 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
130 "Unable to parse data response from device");
134 if ("".equals(dataPayload.getWifiSsid())) {
135 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Results from API are empty");
139 updateStatus(ThingStatus.ONLINE);
140 handleDataPayload(dataPayload);
144 * The actual polling loop
146 protected void pollingCode() {