2 * Copyright (c) 2010-2024 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.neohub.internal;
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;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
24 * Base abstract class for text based communication between openHAB and NeoHub
26 * @author Andrew Fiddian-Green - Initial contribution
30 public abstract class NeoHubSocketBase implements Closeable {
32 protected final NeoHubConfiguration config;
33 protected final String hubId;
35 private static final int REQUEST_INTERVAL_MILLISECS = 1000;
36 private Optional<Instant> lastRequestTime = Optional.empty();
38 public NeoHubSocketBase(NeoHubConfiguration config, String hubId) {
44 * Sends the message over the network to the NeoHub and returns its response
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
51 public abstract String sendMessage(final String requestJson) throws IOException, NeoHubException;
54 * Method for throttling requests to prevent overloading the hub.
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.
59 * @throws NeoHubException if the wait is interrupted
61 protected synchronized void throttle() throws NeoHubException {
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));
68 } catch (InterruptedException e) {
69 throw new NeoHubException("Throttle sleep interrupted", e);