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.electroluxair.internal.handler;
15 import static org.openhab.binding.electroluxair.internal.ElectroluxAirBindingConstants.*;
17 import java.util.Collection;
18 import java.util.Collections;
21 import java.util.concurrent.ConcurrentHashMap;
22 import java.util.concurrent.ScheduledFuture;
23 import java.util.concurrent.TimeUnit;
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;
42 import com.google.gson.Gson;
45 * The {@link ElectroluxAirBridgeHandler} is responsible for handling commands, which are
46 * sent to one of the channels.
48 * @author Jan Gustafsson - Initial contribution
51 public class ElectroluxAirBridgeHandler extends BaseBridgeHandler {
53 public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_BRIDGE);
55 private int refreshTimeInSeconds = 300;
57 private final Gson gson;
58 private final HttpClient httpClient;
59 private final Map<String, ElectroluxPureA9DTO> electroluxAirThings = new ConcurrentHashMap<>();
61 private @Nullable ElectroluxDeltaAPI api;
62 private @Nullable ScheduledFuture<?> refreshJob;
64 public ElectroluxAirBridgeHandler(Bridge bridge, HttpClient httpClient, Gson gson) {
66 this.httpClient = httpClient;
71 public void initialize() {
72 ElectroluxAirBridgeConfiguration config = getConfigAs(ElectroluxAirBridgeConfiguration.class);
74 ElectroluxDeltaAPI electroluxDeltaAPI = new ElectroluxDeltaAPI(config, gson, httpClient);
75 refreshTimeInSeconds = config.refresh;
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!");
85 this.api = electroluxDeltaAPI;
86 scheduler.execute(() -> {
87 updateStatus(ThingStatus.UNKNOWN);
88 startAutomaticRefresh();
91 } catch (RuntimeException e) {
92 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
97 public Map<String, ElectroluxPureA9DTO> getElectroluxAirThings() {
98 return electroluxAirThings;
102 public Collection<Class<? extends ThingHandlerService>> getServices() {
103 return Collections.singleton(ElectroluxAirDiscoveryService.class);
107 public void dispose() {
108 stopAutomaticRefresh();
111 public @Nullable ElectroluxDeltaAPI getElectroluxDeltaAPI() {
115 private boolean refreshAndUpdateStatus() {
117 if (api.refresh(electroluxAirThings)) {
118 getThing().getThings().stream().forEach(thing -> {
119 ElectroluxAirHandler handler = (ElectroluxAirHandler) thing.getHandler();
120 if (handler != null) {
124 updateStatus(ThingStatus.ONLINE);
127 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
133 private void startAutomaticRefresh() {
134 ScheduledFuture<?> refreshJob = this.refreshJob;
135 if (refreshJob == null || refreshJob.isCancelled()) {
136 this.refreshJob = scheduler.scheduleWithFixedDelay(this::refreshAndUpdateStatus, 0, refreshTimeInSeconds,
141 private void stopAutomaticRefresh() {
142 ScheduledFuture<?> refreshJob = this.refreshJob;
143 if (refreshJob != null) {
144 refreshJob.cancel(true);
145 this.refreshJob = null;
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);