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.warmup.internal.handler;
15 import java.util.Collection;
17 import java.util.concurrent.ScheduledFuture;
18 import java.util.concurrent.TimeUnit;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.eclipse.jetty.client.HttpClient;
23 import org.openhab.binding.warmup.internal.api.MyWarmupApi;
24 import org.openhab.binding.warmup.internal.api.MyWarmupApiException;
25 import org.openhab.binding.warmup.internal.discovery.WarmupDiscoveryService;
26 import org.openhab.binding.warmup.internal.model.query.QueryResponseDTO;
27 import org.openhab.core.thing.Bridge;
28 import org.openhab.core.thing.ChannelUID;
29 import org.openhab.core.thing.Thing;
30 import org.openhab.core.thing.ThingStatus;
31 import org.openhab.core.thing.ThingStatusDetail;
32 import org.openhab.core.thing.binding.BaseBridgeHandler;
33 import org.openhab.core.thing.binding.ThingHandlerService;
34 import org.openhab.core.types.Command;
37 * @author James Melville - Initial contribution
40 public class MyWarmupAccountHandler extends BaseBridgeHandler {
42 private final MyWarmupApi api;
44 private @Nullable QueryResponseDTO queryResponse = null;
46 private @Nullable ScheduledFuture<?> refreshJob;
47 private @Nullable WarmupDiscoveryService discoveryService;
49 public MyWarmupAccountHandler(Bridge thing, final HttpClient httpClient) {
51 api = new MyWarmupApi(httpClient, getConfigAs(MyWarmupConfigurationDTO.class));
55 public void initialize() {
56 MyWarmupConfigurationDTO config = getConfigAs(MyWarmupConfigurationDTO.class);
57 if (config.username.length() == 0) {
58 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Username not configured");
59 } else if (config.password.length() == 0) {
60 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Password not configured");
61 } else if (config.refreshInterval >= 10) {
62 api.setConfiguration(config);
63 refreshJob = scheduler.scheduleWithFixedDelay(this::refreshFromServer, 0, config.refreshInterval,
66 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
67 "Refresh interval misconfigured (minimum 10s)");
72 public Collection<Class<? extends ThingHandlerService>> getServices() {
73 return Set.of(WarmupDiscoveryService.class);
77 public void handleCommand(ChannelUID channelUID, Command command) {
81 public void dispose() {
85 public void cancelRefresh() {
86 if (refreshJob != null) {
87 refreshJob.cancel(true);
92 public synchronized void refreshFromServer() {
94 queryResponse = api.getStatus();
95 updateStatus(ThingStatus.ONLINE);
96 } catch (MyWarmupApiException e) {
98 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
104 * Trigger updates to all devices
106 public synchronized void refreshFromCache() {
107 notifyListeners(queryResponse);
110 public void setDiscoveryService(final WarmupDiscoveryService discoveryService) {
111 this.discoveryService = discoveryService;
115 public void unsetDiscoveryService() {
116 discoveryService = null;
121 * @return reference to the bridge's API
123 public MyWarmupApi getApi() {
127 private void notifyListeners(@Nullable QueryResponseDTO domain) {
128 if (discoveryService != null && queryResponse != null) {
129 discoveryService.refresh(queryResponse);
131 getThing().getThings().stream().filter(thing -> thing.getHandler() instanceof WarmupRefreshListener)
132 .map(Thing::getHandler).map(WarmupRefreshListener.class::cast).forEach(thing -> thing.refresh(domain));