]> git.basschouten.com Git - openhab-addons.git/blob
b510aadcb5aa5fb46b728d1ce2cee606f0222fd5
[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.electroluxair.internal.handler;
14
15 import static org.openhab.binding.electroluxair.internal.ElectroluxAirBindingConstants.*;
16
17 import java.util.Collection;
18 import java.util.Collections;
19 import java.util.Map;
20 import java.util.Set;
21 import java.util.concurrent.ConcurrentHashMap;
22 import java.util.concurrent.ScheduledFuture;
23 import java.util.concurrent.TimeUnit;
24
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.eclipse.jdt.annotation.Nullable;
27 import org.eclipse.jetty.client.HttpClient;
28 import org.openhab.binding.electroluxair.internal.ElectroluxAirBridgeConfiguration;
29 import org.openhab.binding.electroluxair.internal.api.ElectroluxDeltaAPI;
30 import org.openhab.binding.electroluxair.internal.discovery.ElectroluxAirDiscoveryService;
31 import org.openhab.binding.electroluxair.internal.dto.ElectroluxPureA9DTO;
32 import org.openhab.core.thing.Bridge;
33 import org.openhab.core.thing.ChannelUID;
34 import org.openhab.core.thing.ThingStatus;
35 import org.openhab.core.thing.ThingStatusDetail;
36 import org.openhab.core.thing.ThingTypeUID;
37 import org.openhab.core.thing.binding.BaseBridgeHandler;
38 import org.openhab.core.thing.binding.ThingHandlerService;
39 import org.openhab.core.types.Command;
40 import org.openhab.core.types.RefreshType;
41
42 import com.google.gson.Gson;
43
44 /**
45  * The {@link ElectroluxAirBridgeHandler} is responsible for handling commands, which are
46  * sent to one of the channels.
47  *
48  * @author Jan Gustafsson - Initial contribution
49  */
50 @NonNullByDefault
51 public class ElectroluxAirBridgeHandler extends BaseBridgeHandler {
52
53     public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_BRIDGE);
54
55     private int refreshTimeInSeconds = 300;
56
57     private final Gson gson;
58     private final HttpClient httpClient;
59     private final Map<String, ElectroluxPureA9DTO> electroluxAirThings = new ConcurrentHashMap<>();
60
61     private @Nullable ElectroluxDeltaAPI api;
62     private @Nullable ScheduledFuture<?> refreshJob;
63
64     public ElectroluxAirBridgeHandler(Bridge bridge, HttpClient httpClient, Gson gson) {
65         super(bridge);
66         this.httpClient = httpClient;
67         this.gson = gson;
68     }
69
70     @Override
71     public void initialize() {
72         ElectroluxAirBridgeConfiguration config = getConfigAs(ElectroluxAirBridgeConfiguration.class);
73
74         ElectroluxDeltaAPI electroluxDeltaAPI = new ElectroluxDeltaAPI(config, gson, httpClient);
75         refreshTimeInSeconds = config.refresh;
76
77         if (config.username == null || config.password == null) {
78             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
79                     "Configuration of username, password is mandatory");
80         } else if (refreshTimeInSeconds < 0) {
81             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
82                     "Refresh time cannot be negative!");
83         } else {
84             try {
85                 this.api = electroluxDeltaAPI;
86                 scheduler.execute(() -> {
87                     updateStatus(ThingStatus.UNKNOWN);
88                     startAutomaticRefresh();
89
90                 });
91             } catch (RuntimeException e) {
92                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
93             }
94         }
95     }
96
97     public Map<String, ElectroluxPureA9DTO> getElectroluxAirThings() {
98         return electroluxAirThings;
99     }
100
101     @Override
102     public Collection<Class<? extends ThingHandlerService>> getServices() {
103         return Collections.singleton(ElectroluxAirDiscoveryService.class);
104     }
105
106     @Override
107     public void dispose() {
108         stopAutomaticRefresh();
109     }
110
111     public @Nullable ElectroluxDeltaAPI getElectroluxDeltaAPI() {
112         return api;
113     }
114
115     private boolean refreshAndUpdateStatus() {
116         if (api != null) {
117             if (api.refresh(electroluxAirThings)) {
118                 getThing().getThings().stream().forEach(thing -> {
119                     ElectroluxAirHandler handler = (ElectroluxAirHandler) thing.getHandler();
120                     if (handler != null) {
121                         handler.update();
122                     }
123                 });
124                 updateStatus(ThingStatus.ONLINE);
125                 return true;
126             } else {
127                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
128             }
129         }
130         return false;
131     }
132
133     private void startAutomaticRefresh() {
134         ScheduledFuture<?> refreshJob = this.refreshJob;
135         if (refreshJob == null || refreshJob.isCancelled()) {
136             this.refreshJob = scheduler.scheduleWithFixedDelay(this::refreshAndUpdateStatus, 0, refreshTimeInSeconds,
137                     TimeUnit.SECONDS);
138         }
139     }
140
141     private void stopAutomaticRefresh() {
142         ScheduledFuture<?> refreshJob = this.refreshJob;
143         if (refreshJob != null) {
144             refreshJob.cancel(true);
145             this.refreshJob = null;
146         }
147     }
148
149     @Override
150     public void handleCommand(ChannelUID channelUID, Command command) {
151         if (CHANNEL_STATUS.equals(channelUID.getId()) && command instanceof RefreshType) {
152             scheduler.schedule(this::refreshAndUpdateStatus, 1, TimeUnit.SECONDS);
153         }
154     }
155 }