Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions bundles/org.openhab.binding.linktap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,15 @@ If the gateway cannot publish to openHAB, then the gateway is checked every 2 mi

### Gateway Configuration

| Name | Type | Description | Recommended Values | Required | Advanced |
|-----------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|----------|----------|
| host | String | The hostname / IP address of the gateway device | | Yes | No |
| username | String | The username if set for the gateway device | | No | No |
| password | String | The password if set for the gateway device | | No | No |
| enableMDNS | Switch | On connection whether the mDNS responder should be enabled on the gateway device | true | No | Yes |
| enforceProtocolLimits | Switch | If true data outside of the allowed ranges against the protocol will be logged and not sent | true | No | Yes |
| enableJSONComms | Switch | false by default for backwards compatibility, if using up to date firmware with no other local network applications set this to true, for more efficient communications | true | No | Yes |
| Name | Type | Description | Recommended Values | Required | Advanced |
|------------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|----------|----------|
| host | text | The hostname / IP address of the gateway device | | Yes | No |
| username | text | The username if set for the gateway device | | No | No |
| password | text | The password if set for the gateway device | | No | No |
| enableMDNS | boolean | On connection whether the mDNS responder should be enabled on the gateway device | true | No | Yes |
| enforceProtocolLimits | boolean | If true data outside of the allowed ranges against the protocol will be logged and not sent | true | No | Yes |
| enableJSONComms | boolean | false by default for backwards compatibility, if using up to date firmware with no other local network applications set this to true, for more efficient communications | true | No | Yes |
| gatewayResponseTimeout | integer | For slow or heavily loaded systems this may need increasing, if communication errors are seen (seconds allowed for responses from the gateway) | 3 | No | Yes |

**NOTE** When enableMDNS is enabled, upon connection to the gateway option "Enable mDNS responder" is switched on.

Expand Down Expand Up @@ -153,7 +154,7 @@ There are 4 different areas of channels:
- **Device Model**: Q1

```java
Bridge linktap:gateway:home "LinkTap GW02" [ host="192.168.0.21", enableMDNS=true, enableJSONComms=false, enforceProtocolLimits=true ] {
Bridge linktap:gateway:home "LinkTap GW02" [ host="192.168.0.21", enableMDNS=true, enableJSONComms=false, enforceProtocolLimits=true, gatewayRequestTimeout=3 ] {
Thing device TapValve1 "Outdoor Tap 1" [ id="D71BC52E985B1200_1", name="ValveLinker_1", enableAlerts=true ]
Thing device TapValve2 "Outdoor Tap 2" [ id="D71BC52E985B1200_2", name="ValveLinker_2", enableAlerts=true ]
Thing device TapValve3 "Outdoor Tap 3" [ id="D71BC52E985B1200_3", name="ValveLinker_3", enableAlerts=true ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ public class LinkTapBridgeConfiguration {
public boolean enableMDNS = true;
public boolean enableJSONComms = false;
public boolean enforceProtocolLimits = true;
public int gatewayResponseTimeout = 3;
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public class LinkTapBindingConstants {
public static final String BRIDGE_CONFIG_MDNS_ENABLE = "enableMDNS";
public static final String BRIDGE_CONFIG_NON_HTML_COMM_ENABLE = "enableJSONComms";
public static final String BRIDGE_CONFIG_ENFORCE_COMM_LIMITS = "enforceProtocolLimits";
public static final String BRIDGE_CONFIG_GATEWAY_RESPONSE_TIMEOUT = "gatewayResponseTimeout";

public static final String DEVICE_PROP_DEV_ID = "deviceId";
public static final String DEVICE_PROP_DEV_NAME = "deviceName";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ public String getLocalizedText(String key, @Nullable Object @Nullable... argumen
return Objects.nonNull(result) ? result : key;
}

public int getResponseTimeout() {
return config.gatewayResponseTimeout;
}

private void startGwPolling() {
synchronized (schedulerLock) {
cancelGwPolling();
Expand Down Expand Up @@ -379,7 +383,7 @@ public String sendSingleApiRequest(final TLGatewayFrame req) throws TransientCom
}
final String reqData = LinkTapBindingConstants.GSON.toJson(req);
logger.debug("{} = APP BRIDGE -> GW -> Request {}", uid, reqData);
final String respData = api.sendRequest(host, reqData);
final String respData = api.sendRequest(host, getResponseTimeout(), reqData);
logger.debug("{} = APP BRIDGE -> GW -> Response {}", uid, respData);
final GatewayDeviceResponse gwResponseFrame = LinkTapBindingConstants.GSON.fromJson(respData,
GatewayDeviceResponse.class);
Expand Down Expand Up @@ -429,7 +433,7 @@ private void connect() {
final WebServerApi api = WebServerApi.getInstance();
api.setHttpClient(httpClientProvider.getHttpClient());
try {
final Map<String, String> bridgeProps = api.getBridgeProperities(bridgeKey);
final Map<String, String> bridgeProps = api.getBridgeProperities(bridgeKey, getResponseTimeout());
if (!bridgeProps.isEmpty()) {
final String readGwId = bridgeProps.get(BRIDGE_PROP_GW_ID);
if (readGwId != null) {
Expand All @@ -439,7 +443,7 @@ private void connect() {
currentProps.putAll(bridgeProps);
updateProperties(currentProps);
} else {
if (!api.unlockWebInterface(bridgeKey, config.username, config.password)) {
if (!api.unlockWebInterface(bridgeKey, getResponseTimeout(), config.username, config.password)) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
getLocalizedText("bridge.error.check-credentials"));
return;
Expand Down Expand Up @@ -481,13 +485,13 @@ private void connect() {
final String servletEp = BindingServlet.getServletAddress(localServerAddr,
getLocalizedText("warning.no-http-server-port"));
final Optional<String> servletEpOpt = (!servletEp.isEmpty()) ? Optional.of(servletEp) : Optional.empty();
api.configureBridge(hostname, Optional.of(config.enableMDNS), Optional.of(config.enableJSONComms),
servletEpOpt);
api.configureBridge(hostname, getResponseTimeout(), Optional.of(config.enableMDNS),
Optional.of(config.enableJSONComms), servletEpOpt);
if (Thread.currentThread().isInterrupted()) {
return;
}

// Ensure we have a response with data in if not schedule a reconnect in 15 seconds, theres no reason
// Ensure we have a response with data in if not schedule a reconnect in 15 seconds, there's no reason
// for a gateway with no devices.
if (!getGatewayConfigurationFreshCheck()) {
logger.debug("{}", getLocalizedText("bridge.info.awaiting-init"));
Expand Down Expand Up @@ -532,7 +536,8 @@ private void connect() {
}

private void scheduleReconnect() {
scheduleReconnect(15);
scheduleReconnect(getResponseTimeout() * 5); // 5 is due to the number of req/resp required for
// connection
}

public void attemptReconnectIfNeeded() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ public void handleCommand(final ChannelUID channelUID, final Command command) {
strStore.put(DEVICE_CHANNEL_OH_VOLUME_LIMIT, String.valueOf(targetValue));
break;
}
} else if (command instanceof StringType stringCmd) {
} else if (command instanceof StringType) {
switch (channelUID.getId()) {
case DEVICE_CHANNEL_CHILD_LOCK: {
sendRequest(new LockReq(Integer.valueOf(command.toString())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ public String sendSingleRequest(final LinkTapBridgeHandler handler, final TLGate
final String payloadJson = GSON.toJson(request);
logger.debug("{} = APP -> GW Request {} -> Payload {}", uid, targetHost, payloadJson);

String response = API.sendRequest(targetHost, GSON.toJson(request));
String response = API.sendRequest(targetHost, handler.getResponseTimeout(), GSON.toJson(request));
logger.debug("{} = APP -> GW Response {} -> Payload {}", uid, targetHost, response.trim());
GatewayDeviceResponse gatewayFrame = GSON.fromJson(response, GatewayDeviceResponse.class);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2010-2025 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.linktap.protocol.http;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.api.Request;
import org.slf4j.Logger;

/**
* The {@link JettyTraceListener} defines a basic listener that can be utilised for logging jetty client states.
*
* @author David Goodyear - Initial contribution
*/
@NonNullByDefault
public final class JettyTraceListener implements Request.Listener {

private final Logger logger;

public JettyTraceListener(final Logger logger) {
this.logger = logger;
}

@Override
public void onQueued(@Nullable Request request) {
if (request != null) {
logger.trace("HTTP Comms request is queued to be processed to {}", request.getURI());
} else {
logger.trace("HTTP Comms request is queued to be processed");
}
Request.Listener.super.onQueued(request);
}

@Override
public void onBegin(@Nullable Request request) {
if (request != null) {
logger.trace("HTTP Comms request is beginning to be processed to {}", request.getURI());
} else {
logger.trace("HTTP Comms request is beginning to be processed");
}
Request.Listener.super.onBegin(request);
}

@Override
public void onSuccess(@Nullable Request request) {
if (request != null) {
logger.trace("HTTP Comms request has been reported as successful to {}", request.getURI());
} else {
logger.trace("HTTP Comms request has been reported as successful");
}
Request.Listener.super.onSuccess(request);
}

@Override
public void onFailure(@Nullable Request request, @Nullable Throwable failure) {
if (request != null) {
logger.trace("HTTP Comms request has failed {}", request.getHost());
} else {
logger.trace("HTTP Comms request has failed with error");
}
if (failure != null) {
logger.trace("HTTP Comms request has failed due to cause {}", failure.toString());
}
Request.Listener.super.onFailure(request, failure);
}
}
Loading