]> git.basschouten.com Git - openhab-addons.git/blob
c06ad866f431a66924b5887f384f19a294e21524
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.tradfri.internal;
14
15 import java.util.concurrent.CompletableFuture;
16
17 import org.eclipse.californium.core.CoapHandler;
18 import org.eclipse.californium.core.CoapResponse;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.core.thing.ThingStatus;
22 import org.openhab.core.thing.ThingStatusDetail;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 import com.google.gson.JsonParseException;
27 import com.google.gson.JsonParser;
28
29 /**
30  * The {@link TradfriCoapHandler} is used to handle the asynchronous coap reponses.
31  * It can either be used with a callback class or with a future.
32  *
33  * @author Kai Kreuzer - Initial contribution
34  */
35 @NonNullByDefault
36 public class TradfriCoapHandler implements CoapHandler {
37
38     private final Logger logger = LoggerFactory.getLogger(TradfriCoapHandler.class);
39     private final JsonParser parser = new JsonParser();
40
41     private @Nullable CoapCallback callback;
42     private @Nullable CompletableFuture<String> future;
43
44     /**
45      * Constructor for using a callback
46      *
47      * @param callback the callback to use for responses
48      */
49     public TradfriCoapHandler(CoapCallback callback) {
50         this.callback = callback;
51     }
52
53     /**
54      * Constructor for using a future
55      *
56      * @param future the future to use for responses
57      */
58     public TradfriCoapHandler(CompletableFuture<String> future) {
59         this.future = future;
60     }
61
62     @Override
63     public void onLoad(@Nullable CoapResponse response) {
64         if (response == null) {
65             logger.trace("received empty CoAP response");
66             return;
67         }
68         logger.debug("CoAP response\noptions: {}\npayload: {}", response.getOptions(), response.getResponseText());
69         if (response.isSuccess()) {
70             final CoapCallback callback = this.callback;
71             if (callback != null) {
72                 try {
73                     callback.onUpdate(parser.parse(response.getResponseText()));
74                     callback.setStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE);
75                 } catch (JsonParseException e) {
76                     logger.warn("Observed value is no valid json: {}, {}", response.getResponseText(), e.getMessage());
77                 }
78             }
79             final CompletableFuture<String> future = this.future;
80             if (future != null) {
81                 String data = response.getResponseText();
82                 future.complete(data);
83             }
84         } else {
85             logger.debug("CoAP error {}", response.getCode());
86             if (callback != null) {
87                 callback.setStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
88             }
89             if (future != null) {
90                 future.completeExceptionally(new RuntimeException("Response " + response.getCode().toString()));
91             }
92         }
93     }
94
95     @Override
96     public void onError() {
97         logger.debug("CoAP onError");
98         if (callback != null) {
99             callback.setStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
100         }
101         if (future != null) {
102             future.completeExceptionally(new RuntimeException("CoAP GET resulted in an error."));
103         }
104     }
105 }