]> git.basschouten.com Git - openhab-addons.git/blob
69ffed8fd54218a0b59c07de6d56c1aeb7ae48f1
[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.boschindego.internal.handler;
14
15 import static org.openhab.binding.boschindego.internal.BoschIndegoBindingConstants.*;
16
17 import java.io.IOException;
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.List;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jetty.client.HttpClient;
24 import org.openhab.binding.boschindego.internal.IndegoController;
25 import org.openhab.binding.boschindego.internal.discovery.IndegoDiscoveryService;
26 import org.openhab.binding.boschindego.internal.dto.response.DevicePropertiesResponse;
27 import org.openhab.binding.boschindego.internal.exceptions.IndegoAuthenticationException;
28 import org.openhab.binding.boschindego.internal.exceptions.IndegoException;
29 import org.openhab.core.auth.client.oauth2.AccessTokenResponse;
30 import org.openhab.core.auth.client.oauth2.OAuthClientService;
31 import org.openhab.core.auth.client.oauth2.OAuthException;
32 import org.openhab.core.auth.client.oauth2.OAuthFactory;
33 import org.openhab.core.auth.client.oauth2.OAuthResponseException;
34 import org.openhab.core.thing.Bridge;
35 import org.openhab.core.thing.ChannelUID;
36 import org.openhab.core.thing.ThingStatus;
37 import org.openhab.core.thing.ThingStatusDetail;
38 import org.openhab.core.thing.binding.BaseBridgeHandler;
39 import org.openhab.core.thing.binding.ThingHandlerService;
40 import org.openhab.core.types.Command;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 /**
45  * The {@link BoschAccountHandler} is responsible for handling commands, which are
46  * sent to one of the channels.
47  *
48  * @author Jacob Laursen - Initial contribution
49  */
50 @NonNullByDefault
51 public class BoschAccountHandler extends BaseBridgeHandler {
52
53     private final Logger logger = LoggerFactory.getLogger(BoschAccountHandler.class);
54     private final OAuthFactory oAuthFactory;
55
56     private OAuthClientService oAuthClientService;
57     private IndegoController controller;
58
59     public BoschAccountHandler(Bridge bridge, HttpClient httpClient, OAuthFactory oAuthFactory) {
60         super(bridge);
61
62         this.oAuthFactory = oAuthFactory;
63
64         oAuthClientService = oAuthFactory.createOAuthClientService(getThing().getUID().getAsString(), BSK_TOKEN_URI,
65                 BSK_AUTH_URI, BSK_CLIENT_ID, null, BSK_SCOPE, false);
66         controller = new IndegoController(httpClient, oAuthClientService);
67     }
68
69     @Override
70     public void initialize() {
71         updateStatus(ThingStatus.UNKNOWN);
72
73         scheduler.execute(() -> {
74             try {
75                 AccessTokenResponse accessTokenResponse = this.oAuthClientService.getAccessTokenResponse();
76                 if (accessTokenResponse == null) {
77                     updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
78                             "@text/offline.conf-error.oauth2-unauthorized");
79                 } else {
80                     updateStatus(ThingStatus.ONLINE);
81                 }
82             } catch (OAuthException | OAuthResponseException e) {
83                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
84                         "@text/offline.conf-error.oauth2-unauthorized");
85             } catch (IOException e) {
86                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
87                         "@text/offline.comm-error.oauth2-authorization-failed");
88             }
89         });
90     }
91
92     @Override
93     public void dispose() {
94         oAuthFactory.ungetOAuthService(this.getThing().getUID().getAsString());
95     }
96
97     @Override
98     public void handleCommand(ChannelUID channelUID, Command command) {
99     }
100
101     @Override
102     public Collection<Class<? extends ThingHandlerService>> getServices() {
103         return List.of(IndegoDiscoveryService.class);
104     }
105
106     public void authorize(String authCode) throws IndegoAuthenticationException {
107         logger.info("Attempting to authorize using authorization code");
108
109         try {
110             oAuthClientService.getAccessTokenResponseByAuthorizationCode(authCode, BSK_REDIRECT_URI);
111         } catch (OAuthException | OAuthResponseException | IOException e) {
112             throw new IndegoAuthenticationException("Failed to authorize by authorization code " + authCode, e);
113         }
114
115         logger.info("Authorization completed successfully");
116
117         updateStatus(ThingStatus.ONLINE);
118     }
119
120     public OAuthClientService getOAuthClientService() {
121         return oAuthClientService;
122     }
123
124     public Collection<DevicePropertiesResponse> getDevices() throws IndegoException {
125         Collection<String> serialNumbers = controller.getSerialNumbers();
126         List<DevicePropertiesResponse> devices = new ArrayList<DevicePropertiesResponse>(serialNumbers.size());
127
128         for (String serialNumber : serialNumbers) {
129             DevicePropertiesResponse properties = controller.getDeviceProperties(serialNumber);
130             if (properties.serialNumber == null) {
131                 properties.serialNumber = serialNumber;
132             }
133             devices.add(properties);
134         }
135
136         return devices;
137     }
138 }