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.easee.internal.handler;
15 import static org.openhab.binding.easee.internal.EaseeBindingConstants.*;
17 import java.util.Collection;
18 import java.util.HashMap;
21 import java.util.concurrent.Future;
22 import java.util.concurrent.TimeUnit;
23 import java.util.concurrent.atomic.AtomicReference;
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.easee.internal.AtomicReferenceTrait;
29 import org.openhab.binding.easee.internal.EaseeBindingConstants;
30 import org.openhab.binding.easee.internal.Utils;
31 import org.openhab.binding.easee.internal.command.EaseeCommand;
32 import org.openhab.binding.easee.internal.command.site.GetSite;
33 import org.openhab.binding.easee.internal.command.site.SiteState;
34 import org.openhab.binding.easee.internal.config.EaseeConfiguration;
35 import org.openhab.binding.easee.internal.connector.CommunicationStatus;
36 import org.openhab.binding.easee.internal.connector.WebInterface;
37 import org.openhab.binding.easee.internal.discovery.EaseeSiteDiscoveryService;
38 import org.openhab.core.config.discovery.DiscoveryService;
39 import org.openhab.core.thing.Bridge;
40 import org.openhab.core.thing.ThingStatus;
41 import org.openhab.core.thing.ThingStatusDetail;
42 import org.openhab.core.thing.binding.BaseBridgeHandler;
43 import org.openhab.core.thing.binding.ThingHandlerService;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
47 import com.google.gson.JsonObject;
50 * The {@link EaseeSiteHandler} is responsible for handling commands, which are
51 * sent to one of the channels.
53 * @author Alexander Friese - initial contribution
56 public class EaseeSiteHandler extends BaseBridgeHandler implements EaseeBridgeHandler, AtomicReferenceTrait {
57 private final Logger logger = LoggerFactory.getLogger(EaseeSiteHandler.class);
60 * Schedule for polling live data
62 private final AtomicReference<@Nullable Future<?>> dataPollingJobReference;
64 private @Nullable DiscoveryService discoveryService;
67 * Interface object for querying the Easee web interface
69 private WebInterface webInterface;
71 public EaseeSiteHandler(Bridge bridge, HttpClient httpClient) {
73 this.dataPollingJobReference = new AtomicReference<>(null);
74 this.webInterface = new WebInterface(scheduler, this, httpClient, super::updateStatus);
78 public void initialize() {
79 logger.debug("About to initialize Easee Site");
80 EaseeConfiguration config = getBridgeConfiguration();
81 logger.debug("Easee Site initialized with configuration: {}", config.toString());
83 updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE, STATUS_WAITING_FOR_LOGIN);
87 enqueueCommand(new GetSite(this, this::updateProperties));
90 private void updateProperties(CommunicationStatus status, JsonObject jsonObject) {
91 Map<String, String> properties = editProperties();
92 String name = Utils.getAsString(jsonObject, JSON_KEY_GENERIC_NAME);
94 properties.put(JSON_KEY_GENERIC_NAME, name);
96 String siteKey = Utils.getAsString(jsonObject, JSON_KEY_SITE_KEY);
97 if (siteKey != null) {
98 properties.put(JSON_KEY_SITE_KEY, siteKey);
100 updateProperties(properties);
106 private void startPolling() {
107 updateJobReference(dataPollingJobReference, scheduler.scheduleWithFixedDelay(this::pollingRun,
108 POLLING_INITIAL_DELAY, getBridgeConfiguration().getDataPollingInterval(), TimeUnit.SECONDS));
112 * Poll the Easee Cloud API one time.
115 String siteId = getConfig().get(EaseeBindingConstants.THING_CONFIG_SITE_ID).toString();
116 logger.debug("polling site data for {}", siteId);
118 SiteState state = new SiteState(this, siteId, getChildChargerHandlers(), this::updateOnlineStatus);
119 enqueueCommand(state);
121 // proceed if site is online
122 if (getThing().getStatus() == ThingStatus.ONLINE) {
123 // add further polling commands here
128 * creates a map containing all child chargers/masterchargers identified by their unique id.
130 * @return the map created
132 private Map<String, EaseeChargerHandler> getChildChargerHandlers() {
133 Map<String, EaseeChargerHandler> chargerHandlers = new HashMap<>();
135 getThing().getThings().stream().filter(x -> x.getThingTypeUID().equals(THING_TYPE_CHARGER)
136 || x.getThingTypeUID().equals(THING_TYPE_MASTER_CHARGER)).forEach(y -> {
137 EaseeChargerHandler handler = (EaseeChargerHandler) y.getHandler();
138 if (handler != null) {
139 chargerHandlers.put(handler.getId(), handler);
142 return chargerHandlers;
146 * result processor to handle online status updates
148 * @param status of command execution
149 * @param jsonObject json respone result
151 protected final void updateOnlineStatus(CommunicationStatus status, JsonObject jsonObject) {
152 String msg = Utils.getAsString(jsonObject, JSON_KEY_ERROR_TITLE);
153 if (msg == null || msg.isBlank()) {
154 msg = status.getMessage();
157 switch (status.getHttpCode()) {
160 super.updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE);
163 super.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
168 * Disposes the bridge.
171 public void dispose() {
172 logger.debug("Handler disposed.");
173 cancelJobReference(dataPollingJobReference);
174 webInterface.dispose();
178 public EaseeConfiguration getBridgeConfiguration() {
179 return this.getConfigAs(EaseeConfiguration.class);
183 public Collection<Class<? extends ThingHandlerService>> getServices() {
184 return Set.of(EaseeSiteDiscoveryService.class);
187 public void setDiscoveryService(EaseeSiteDiscoveryService discoveryService) {
188 this.discoveryService = discoveryService;
192 public void startDiscovery() {
193 DiscoveryService discoveryService = this.discoveryService;
194 if (discoveryService != null) {
195 discoveryService.startScan(null);
200 public void enqueueCommand(EaseeCommand command) {
201 webInterface.enqueueCommand(command);
205 public Logger getLogger() {