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.freeboxos.internal.handler;
15 import java.util.Collection;
16 import java.util.Optional;
18 import java.util.concurrent.Future;
19 import java.util.concurrent.TimeUnit;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.openhab.binding.freeboxos.internal.api.FreeboxException;
23 import org.openhab.binding.freeboxos.internal.api.rest.FreeboxOsSession;
24 import org.openhab.binding.freeboxos.internal.api.rest.RestManager;
25 import org.openhab.binding.freeboxos.internal.config.FreeboxOsConfiguration;
26 import org.openhab.binding.freeboxos.internal.discovery.FreeboxOsDiscoveryService;
27 import org.openhab.core.audio.AudioHTTPServer;
28 import org.openhab.core.config.core.Configuration;
29 import org.openhab.core.thing.Bridge;
30 import org.openhab.core.thing.ChannelUID;
31 import org.openhab.core.thing.ThingStatus;
32 import org.openhab.core.thing.ThingStatusDetail;
33 import org.openhab.core.thing.binding.BaseBridgeHandler;
34 import org.openhab.core.thing.binding.ThingHandlerService;
35 import org.openhab.core.types.Command;
36 import org.osgi.framework.BundleContext;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
41 * The {@link FreeboxOsHandler} handle common parts of Freebox bridges.
43 * @author Gaƫl L'hopital - Initial contribution
46 public class FreeboxOsHandler extends BaseBridgeHandler {
47 private final Logger logger = LoggerFactory.getLogger(FreeboxOsHandler.class);
48 private final FreeboxOsSession session;
49 private final String callbackURL;
50 private final BundleContext bundleContext;
51 private final AudioHTTPServer audioHTTPServer;
53 private Optional<Future<?>> openConnectionJob = Optional.empty();
54 private Optional<Future<?>> grantingJob = Optional.empty();
56 public FreeboxOsHandler(Bridge thing, FreeboxOsSession session, String callbackURL, BundleContext bundleContext,
57 AudioHTTPServer audioHTTPServer) {
59 this.session = session;
60 this.callbackURL = callbackURL;
61 this.bundleContext = bundleContext;
62 this.audioHTTPServer = audioHTTPServer;
66 public void initialize() {
69 FreeboxOsConfiguration config = getConfiguration();
70 openConnectionJob = Optional.of(scheduler.submit(() -> {
72 session.initialize(config);
73 if (config.appToken.isBlank()) {
74 updateStatus(ThingStatus.ONLINE, ThingStatusDetail.CONFIGURATION_PENDING,
75 "@text/info-conf-pending");
76 grantingJob = Optional.of(scheduler.schedule(this::processGranting, 2, TimeUnit.SECONDS));
79 updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE);
80 session.openSession(config.appToken);
82 updateStatus(ThingStatus.ONLINE);
83 } catch (FreeboxException e) {
84 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
85 } catch (InterruptedException e) {
86 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
91 private void processGranting() {
93 String appToken = session.grant();
94 if (appToken.isBlank()) {
95 grantingJob = Optional.of(scheduler.schedule(this::processGranting, 2, TimeUnit.SECONDS));
97 Configuration thingConfig = editConfiguration();
98 thingConfig.put(FreeboxOsConfiguration.APP_TOKEN, appToken);
99 updateConfiguration(thingConfig);
100 logger.info("AppToken updated, ensure giving permissions in the Freebox management console");
103 } catch (FreeboxException e) {
104 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
108 public <T extends RestManager> T getManager(Class<T> clazz) throws FreeboxException {
109 return session.getManager(clazz);
112 private void freeConnectionJob() {
113 openConnectionJob.ifPresent(job -> job.cancel(true));
114 openConnectionJob = Optional.empty();
115 grantingJob.ifPresent(job -> job.cancel(true));
116 grantingJob = Optional.empty();
120 public void dispose() {
122 session.closeSession();
128 public Collection<Class<? extends ThingHandlerService>> getServices() {
129 return Set.of(FreeboxOsDiscoveryService.class);
133 public void handleCommand(ChannelUID channelUID, Command command) {
136 public FreeboxOsConfiguration getConfiguration() {
137 return getConfigAs(FreeboxOsConfiguration.class);
140 public String getCallbackURL() {
144 public BundleContext getBundleContext() {
145 return bundleContext;
148 public AudioHTTPServer getAudioHTTPServer() {
149 return audioHTTPServer;