]> git.basschouten.com Git - openhab-addons.git/blob
6fd883e428a16ecf9aafa882c777684cb1f3453b
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.neohub.internal;
14
15 import java.io.Closeable;
16 import java.io.IOException;
17 import java.time.Duration;
18 import java.time.Instant;
19 import java.util.Optional;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22
23 /**
24  * Base abstract class for text based communication between openHAB and NeoHub
25  *
26  * @author Andrew Fiddian-Green - Initial contribution
27  *
28  */
29 @NonNullByDefault
30 public abstract class NeoHubSocketBase implements Closeable {
31
32     protected final NeoHubConfiguration config;
33     protected final String hubId;
34
35     private static final int REQUEST_INTERVAL_MILLISECS = 1000;
36     private Optional<Instant> lastRequestTime = Optional.empty();
37
38     public NeoHubSocketBase(NeoHubConfiguration config, String hubId) {
39         this.config = config;
40         this.hubId = hubId;
41     }
42
43     /**
44      * Sends the message over the network to the NeoHub and returns its response
45      *
46      * @param requestJson the message to be sent to the NeoHub
47      * @return responseJson received from NeoHub
48      * @throws IOException if there was a communication error or the socket state would not permit communication
49      * @throws NeoHubException if the communication returned a response but the response was not valid JSON
50      */
51     public abstract String sendMessage(final String requestJson) throws IOException, NeoHubException;
52
53     /**
54      * Method for throttling requests to prevent overloading the hub.
55      * <p>
56      * The NeoHub can get confused if, while it is uploading data to the cloud, it also receives too many local
57      * requests, so this method throttles the requests to one per REQUEST_INTERVAL_MILLISECS maximum.
58      *
59      * @throws NeoHubException if the wait is interrupted
60      */
61     protected synchronized void throttle() throws NeoHubException {
62         try {
63             Instant now = Instant.now();
64             long delay = lastRequestTime
65                     .map(t -> Math.max(0, Duration.between(now, t).toMillis() + REQUEST_INTERVAL_MILLISECS)).orElse(0L);
66             lastRequestTime = Optional.of(now.plusMillis(delay));
67             Thread.sleep(delay);
68         } catch (InterruptedException e) {
69             throw new NeoHubException("Throttle sleep interrupted", e);
70         }
71     }
72 }