Add possiblity to specify TTN stack version (V2 or V3)

master
Bertrik Sikken 2021-03-07 14:59:14 +01:00
rodzic 65a2cbf8b0
commit ad26b51da6
5 zmienionych plików z 54 dodań i 17 usunięć

Wyświetl plik

@ -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
*/

Wyświetl plik

@ -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,22 +90,24 @@ 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;
}
Sentence sentence = decoder.decode(message);
String line = sentence.format();
// collect list of listeners
// collect list of listeners
List<HabReceiver> receivers = new ArrayList<>();
for (GatewayInfo gw : message.getGateways()) {
String gwName = gw.getId();
@ -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());
}
}
@ -141,7 +143,7 @@ public final class TtnHabBridge {
habUploader.stop();
LOG.info("Stopped TTN HAB bridge application");
}
/**
* Handles uncaught exceptions: log it and stop the application.
*
@ -152,7 +154,7 @@ public final class TtnHabBridge {
LOG.error("Caught unhandled exception, application will be stopped ...", e);
stop();
}
private static ITtnHabBridgeConfig readConfig(File file) throws IOException {
TtnHabBridgeConfig config = new TtnHabBridgeConfig();
try (FileInputStream fis = new FileInputStream(file)) {

Wyświetl plik

@ -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);

Wyświetl plik

@ -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;
}
}

Wyświetl plik

@ -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);
}
}
}