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.ojelectronics.internal.services;
15 import java.util.concurrent.ScheduledExecutorService;
16 import java.util.concurrent.ScheduledFuture;
17 import java.util.concurrent.TimeUnit;
18 import java.util.function.BiConsumer;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.eclipse.jetty.client.HttpClient;
23 import org.eclipse.jetty.client.api.Request;
24 import org.eclipse.jetty.client.api.Result;
25 import org.eclipse.jetty.client.util.BufferingResponseListener;
26 import org.eclipse.jetty.http.HttpMethod;
27 import org.eclipse.jetty.http.HttpStatus;
28 import org.openhab.binding.ojelectronics.internal.common.OJGSonBuilder;
29 import org.openhab.binding.ojelectronics.internal.config.OJElectronicsBridgeConfiguration;
30 import org.openhab.binding.ojelectronics.internal.models.groups.GroupContentResponseModel;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
34 import com.google.gson.Gson;
35 import com.google.gson.JsonSyntaxException;
38 * Handles the refreshing of the devices of a session
40 * @author Christian Kittel - Initial Contribution
43 public final class RefreshService implements AutoCloseable {
45 private final OJElectronicsBridgeConfiguration config;
46 private final Logger logger = LoggerFactory.getLogger(RefreshService.class);
47 private final HttpClient httpClient;
48 private final Gson gson = OJGSonBuilder.getGSon();
50 private final ScheduledExecutorService schedulerService;
52 private @Nullable Runnable connectionLost;
53 private @Nullable BiConsumer<@Nullable GroupContentResponseModel, @Nullable String> refreshDone;
54 private @Nullable ScheduledFuture<?> scheduler;
55 private @Nullable Runnable unauthorized;
56 private @Nullable String sessionId;
57 private static boolean destroyed = false;
60 * Creates a new instance of {@link RefreshService}
62 * @param config Configuration of the bridge
63 * @param httpClient HTTP client
64 * @param updateService Service to update the thermostat in the cloud
66 public RefreshService(OJElectronicsBridgeConfiguration config, HttpClient httpClient,
67 ScheduledExecutorService schedulerService) {
69 this.httpClient = httpClient;
70 this.schedulerService = schedulerService;
74 * Starts refreshing all thing values
76 * @param sessionId Session-Id
77 * @param refreshDone This method is called if refreshing is done.
78 * @param connectionLosed This method is called if no connection could established.
79 * @param unauthorized This method is called if the result is unauthorized.
81 public void start(String sessionId, BiConsumer<@Nullable GroupContentResponseModel, @Nullable String> refreshDone,
82 Runnable connectionLost, Runnable unauthorized) {
83 logger.trace("RefreshService.startService({})", sessionId);
84 this.connectionLost = connectionLost;
85 this.refreshDone = refreshDone;
86 this.unauthorized = unauthorized;
87 this.sessionId = sessionId;
88 long refreshTime = config.refreshDelayInSeconds;
89 scheduler = schedulerService.scheduleWithFixedDelay(this::refresh, refreshTime, refreshTime, TimeUnit.SECONDS);
99 final ScheduledFuture<?> scheduler = this.scheduler;
100 if (scheduler != null) {
101 scheduler.cancel(false);
103 this.scheduler = null;
106 private void refresh() {
107 final String sessionId = this.sessionId;
108 if (sessionId == null) {
109 handleConnectionLost();
111 final Runnable unauthorized = this.unauthorized;
112 createRequest().send(new BufferingResponseListener() {
114 public void onComplete(@Nullable Result result) {
116 if (result == null || result.isFailed()) {
117 handleConnectionLost();
119 int status = result.getResponse().getStatus();
120 logger.trace("HTTP-Status {}", status);
121 if (status == HttpStatus.FORBIDDEN_403) {
122 if (unauthorized != null) {
125 handleConnectionLost();
127 } else if (status == HttpStatus.OK_200) {
128 handleRefreshDone(getContentAsString());
130 logger.warn("unsupported HTTP-Status {}", status);
131 handleConnectionLost();
139 private Request createRequest() {
140 Request request = httpClient.newRequest(config.apiUrl + "/Group/GroupContents").param("sessionid", sessionId)
141 .param("apiKey", config.apiKey).method(HttpMethod.GET);
145 private void handleRefreshDone(String responseBody) {
146 BiConsumer<@Nullable GroupContentResponseModel, @Nullable String> refreshDone = this.refreshDone;
147 if (refreshDone != null) {
148 logger.trace("refresh {}", responseBody);
150 GroupContentResponseModel content = gson.fromJson(responseBody, GroupContentResponseModel.class);
151 refreshDone.accept(content, null);
152 } catch (JsonSyntaxException exception) {
153 logger.debug("Error mapping Result to model", exception);
154 refreshDone.accept(null, exception.getMessage());
159 private void handleConnectionLost() {
160 final Runnable connectionLost = this.connectionLost;
161 if (connectionLost != null) {
162 connectionLost.run();
167 public void close() throws Exception {