kopia lustrzana https://github.com/bertrik/ttnhabbridge
Add possiblity to specify TTN stack version (V2 or V3)
rodzic
65a2cbf8b0
commit
ad26b51da6
|
@ -2,6 +2,8 @@ package nl.sikken.bertrik;
|
|||
|
||||
import java.time.Duration;
|
||||
|
||||
import nl.sikken.bertrik.hab.ttn.ETtnStackVersion;
|
||||
|
||||
/**
|
||||
* Configuration interface for the application.
|
||||
*/
|
||||
|
@ -22,6 +24,11 @@ public interface ITtnHabBridgeConfig {
|
|||
*/
|
||||
String getTtnMqttUrl();
|
||||
|
||||
/**
|
||||
* @return the version of the TTN stack, either v2 or v3
|
||||
*/
|
||||
ETtnStackVersion getTtnStackVersion();
|
||||
|
||||
/**
|
||||
* @return the application id of the TTN application
|
||||
*/
|
||||
|
|
|
@ -44,7 +44,7 @@ public final class TtnHabBridge {
|
|||
* Main application entry point.
|
||||
*
|
||||
* @param arguments application arguments (none taken)
|
||||
* @throws IOException in case of a problem reading a config file
|
||||
* @throws IOException in case of a problem reading a config file
|
||||
* @throws MqttException in case of a problem starting MQTT client
|
||||
*/
|
||||
public static void main(String[] arguments) throws IOException, MqttException {
|
||||
|
@ -65,10 +65,9 @@ public final class TtnHabBridge {
|
|||
* @param config the application configuration
|
||||
*/
|
||||
private TtnHabBridge(ITtnHabBridgeConfig config) {
|
||||
this.ttnListener = new TtnListener(this::handleTTNMessage,
|
||||
config.getTtnMqttUrl(), config.getTtnAppId(), config.getTtnAppKey());
|
||||
IHabitatRestApi restApi =
|
||||
HabitatUploader.newRestClient(config.getHabitatUrl(), config.getHabitatTimeout());
|
||||
this.ttnListener = new TtnListener(this::handleTTNMessage, config.getTtnMqttUrl(), config.getTtnStackVersion(),
|
||||
config.getTtnAppId(), config.getTtnAppKey());
|
||||
IHabitatRestApi restApi = HabitatUploader.newRestClient(config.getHabitatUrl(), config.getHabitatTimeout());
|
||||
this.habUploader = new HabitatUploader(restApi);
|
||||
this.decoder = new PayloadDecoder(EPayloadEncoding.parse(config.getTtnPayloadEncoding()));
|
||||
this.gwCache = new ExpiringCache(config.getTtnGwCacheExpiry());
|
||||
|
@ -91,15 +90,17 @@ public final class TtnHabBridge {
|
|||
|
||||
/**
|
||||
* Handles an incoming TTN message
|
||||
*
|
||||
* @param textMessage the message contents
|
||||
* @param now message arrival time
|
||||
* @param now message arrival time
|
||||
*/
|
||||
private void handleTTNMessage(TtnUplinkMessage message) {
|
||||
Instant now = Instant.now();
|
||||
try {
|
||||
// decode from JSON
|
||||
if (message.isRetry()) {
|
||||
// skip "retry" messages, they contain duplicate data with a misleading time stamp
|
||||
// skip "retry" messages, they contain duplicate data with a misleading time
|
||||
// stamp
|
||||
LOG.warn("Ignoring 'retry' message");
|
||||
return;
|
||||
}
|
||||
|
@ -114,7 +115,8 @@ public final class TtnHabBridge {
|
|||
HabReceiver receiver = new HabReceiver(gwName, gwLocation);
|
||||
receivers.add(receiver);
|
||||
|
||||
// send listener data only if it has a valid location and hasn't been sent recently
|
||||
// send listener data only if it has a valid location and hasn't been sent
|
||||
// recently
|
||||
if (gwLocation.isValid() && gwCache.add(gwName, now)) {
|
||||
habUploader.scheduleListenerDataUpload(receiver, now);
|
||||
}
|
||||
|
@ -125,8 +127,8 @@ public final class TtnHabBridge {
|
|||
} catch (DecodeException e) {
|
||||
LOG.warn("Payload decoding exception: {}", e.getMessage());
|
||||
} catch (Exception e) {
|
||||
LOG.trace("Caught unhandled exception", e);
|
||||
LOG.error("Caught unhandled exception:" + e.getMessage());
|
||||
LOG.trace("Caught unhandled exception", e);
|
||||
LOG.error("Caught unhandled exception:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@ package nl.sikken.bertrik;
|
|||
|
||||
import java.time.Duration;
|
||||
|
||||
import nl.sikken.bertrik.hab.ttn.ETtnStackVersion;
|
||||
|
||||
/**
|
||||
* Configuration class.
|
||||
*/
|
||||
|
@ -15,6 +17,7 @@ final class TtnHabBridgeConfig extends BaseConfig implements ITtnHabBridgeConfig
|
|||
HABITAT_TIMEOUT_MS("habitat.timeout", "5000", "Timeout in milliseconds"),
|
||||
|
||||
TTN_MQTT_URL("ttn.mqtt.url", "tcp://eu.thethings.network", "URL of the TTN MQTT server"),
|
||||
TTN_VERSION("ttn.version", "V2", "TTN stack version, V2 or V3"),
|
||||
TTN_APP_ID("ttn.app.id", "habhub", "TTN Application Id (e.g. habhub, ttnmapper, etc.)"),
|
||||
TTN_APP_KEY("ttn.app.key", "ttn-account-v2.Sh49WL90oQz-ZuxoDrS6yKuACL_jtAA0agdDfO_eVj4", "TTN Application key"),
|
||||
TTN_GW_CACHE_EXPIRY_SEC("ttn.gwcache.expiry", "600", "Gateway cache expiration time (seconds)"),
|
||||
|
@ -59,6 +62,11 @@ final class TtnHabBridgeConfig extends BaseConfig implements ITtnHabBridgeConfig
|
|||
return get(EConfigItem.TTN_MQTT_URL.key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ETtnStackVersion getTtnStackVersion() {
|
||||
return ETtnStackVersion.valueOf(get(EConfigItem.TTN_VERSION.key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTtnAppId() {
|
||||
return get(EConfigItem.TTN_APP_ID.key);
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package nl.sikken.bertrik.hab.ttn;
|
||||
|
||||
/**
|
||||
* The TTN stack version, used for example to differentiate between MQTT conventions.
|
||||
*/
|
||||
public enum ETtnStackVersion {
|
||||
V2(""),
|
||||
V3("v3/");
|
||||
|
||||
private final String prefix;
|
||||
|
||||
ETtnStackVersion(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
}
|
|
@ -36,7 +36,7 @@ public final class TtnListener {
|
|||
* @param appId the user name
|
||||
* @param appKey the password
|
||||
*/
|
||||
public TtnListener(IMessageReceived callback, String url, String appId, String appKey) {
|
||||
public TtnListener(IMessageReceived callback, String url, ETtnStackVersion version, String appId, String appKey) {
|
||||
LOG.info("Creating client for MQTT server '{}' for app '{}'", url, appId);
|
||||
try {
|
||||
this.mqttClient = new MqttClient(url, MqttClient.generateClientId(), new MemoryPersistence());
|
||||
|
@ -44,7 +44,8 @@ public final class TtnListener {
|
|||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
this.callback = callback;
|
||||
mqttClient.setCallback(new MqttCallbackHandler(mqttClient, "+/devices/+/up", this::handleMessage));
|
||||
mqttClient.setCallback(
|
||||
new MqttCallbackHandler(mqttClient, version.getPrefix() + "+/devices/+/up", this::handleMessage));
|
||||
|
||||
// create connect options
|
||||
options = new MqttConnectOptions();
|
||||
|
@ -145,7 +146,7 @@ public final class TtnListener {
|
|||
try {
|
||||
client.subscribe(topic);
|
||||
} catch (MqttException e) {
|
||||
LOG.error("Caught exception while subscribing!");
|
||||
LOG.error("Caught exception while subscribing!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue