]> git.basschouten.com Git - openhab-addons.git/blob
bb62c4f37b933143635055d5b94f087f276f72f4
[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.freeboxos.internal.handler;
14
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.Optional;
18 import java.util.concurrent.Future;
19 import java.util.concurrent.TimeUnit;
20
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;
39
40 /**
41  * The {@link FreeboxOsHandler} handle common parts of Freebox bridges.
42  *
43  * @author GaĆ«l L'hopital - Initial contribution
44  */
45 @NonNullByDefault
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;
52
53     private Optional<Future<?>> openConnectionJob = Optional.empty();
54     private Optional<Future<?>> grantingJob = Optional.empty();
55
56     public FreeboxOsHandler(Bridge thing, FreeboxOsSession session, String callbackURL, BundleContext bundleContext,
57             AudioHTTPServer audioHTTPServer) {
58         super(thing);
59         this.session = session;
60         this.callbackURL = callbackURL;
61         this.bundleContext = bundleContext;
62         this.audioHTTPServer = audioHTTPServer;
63     }
64
65     @Override
66     public void initialize() {
67         freeConnectionJob();
68
69         FreeboxOsConfiguration config = getConfiguration();
70         openConnectionJob = Optional.of(scheduler.submit(() -> {
71             try {
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));
77                     return;
78                 } else {
79                     updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE);
80                     session.openSession(config.appToken);
81                 }
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());
87             }
88         }));
89     }
90
91     private void processGranting() {
92         try {
93             String appToken = session.grant();
94             if (appToken.isBlank()) {
95                 grantingJob = Optional.of(scheduler.schedule(this::processGranting, 2, TimeUnit.SECONDS));
96             } else {
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");
101                 initialize();
102             }
103         } catch (FreeboxException e) {
104             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
105         }
106     }
107
108     public <T extends RestManager> T getManager(Class<T> clazz) throws FreeboxException {
109         return session.getManager(clazz);
110     }
111
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();
117     }
118
119     @Override
120     public void dispose() {
121         freeConnectionJob();
122         session.closeSession();
123
124         super.dispose();
125     }
126
127     @Override
128     public Collection<Class<? extends ThingHandlerService>> getServices() {
129         return Collections.singleton(FreeboxOsDiscoveryService.class);
130     }
131
132     @Override
133     public void handleCommand(ChannelUID channelUID, Command command) {
134     }
135
136     public FreeboxOsConfiguration getConfiguration() {
137         return getConfigAs(FreeboxOsConfiguration.class);
138     }
139
140     public String getCallbackURL() {
141         return callbackURL;
142     }
143
144     public BundleContext getBundleContext() {
145         return bundleContext;
146     }
147
148     public AudioHTTPServer getAudioHTTPServer() {
149         return audioHTTPServer;
150     }
151 }