Skip to content

Commit

Permalink
Fix mqtt reconnection issues due to missing client id (#150)
Browse files Browse the repository at this point in the history
Re-register device when services are updated

Test device update when group configuration is updated

agent should start even if existing configurations have errors

replace winston with default iot-agent-node-lib logger

insert transaction support
  • Loading branch information
chicco785 authored Jun 13, 2022
1 parent 321ba70 commit 957ee6a
Show file tree
Hide file tree
Showing 24 changed files with 584 additions and 208 deletions.
14 changes: 11 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
## [1.2.4](https://github.com/Atos-Research-and-Innovation/IoTagent-LoRaWAN/compare/v1.2.3...v1.2.4) (2021-01-22)
## [1.2.5-next](https://github.com/Atos-Research-and-Innovation/IoTagent-LoRaWAN/compare/v1.2.4...master) (2022-06-30)

### Features

- replace winston with default logging facility
([37aacdb](https://github.com/Atos-Research-and-Innovation/IoTagent-LoRaWAN/pull/150/commits/37aacdbfcd983b4f67b14e49d6d05e0cfb7badd1))
- reconnect lost mqtt connection
([37aacdb](https://github.com/Atos-Research-and-Innovation/IoTagent-LoRaWAN/pull/150/commits/37aacdbfcd983b4f67b14e49d6d05e0cfb7badd1))
- support ttn v3
([185fd9b](https://github.com/Atos-Research-and-Innovation/IoTagent-LoRaWAN/pull/147/commits/185fd9bf1aad26b3816d74a4d67b90e36530af83))
- refactor chirpstack support
Expand All @@ -20,22 +24,26 @@

### Bug Fixes

- update build badge
#152:([22d0a70](https://github.com/Atos-Research-and-Innovation/IoTagent-LoRaWAN/pull/153/commits/22d0a706e8da4a1a46754fd8a0a599b7ed2c5c32))
- propagate group configuration updates
([37aacdb](https://github.com/Atos-Research-and-Innovation/IoTagent-LoRaWAN/pull/150/commits/37aacdbfcd983b4f67b14e49d6d05e0cfb7badd1))
- fix failing test due to PR #120
([b0cb421](https://github.com/Atos-Research-and-Innovation/IoTagent-LoRaWAN/commit/b0cb421))

- loraserverioAppService.js : In the MQTT subscription, the text 'rx', which is obsolete for ChirpStack since version
3.11.0 (11/18/2020), has been replaced by '/event/up', which is what ChirpStack is currently publishing. As a
consequence, if (splittedMqttTopic.length !== 5) also had to be changed from 5 to 6, since otherwise it gives a 'Bad
format for a LoRaServer.io topic'. Reference: https://www.chirpstack.io/application-server/integrations/mqtt/

## [1.2.4](https://github.com/Atos-Research-and-Innovation/IoTagent-LoRaWAN/compare/v1.2.3...v1.2.4) (2021-01-22)

## [1.2.3](https://github.com/Atos-Research-and-Innovation/IoTagent-LoRaWAN/compare/v1.2.2...v1.2.3) (2019-06-13)

### Bug Fixes

- **loraserver.io #70:** MQTT topics updated to versions after v1
([6e40ec9](https://github.com/Atos-Research-and-Innovation/IoTagent-LoRaWAN/commit/6e40ec9)), closes
[#70](https://github.com/Atos-Research-and-Innovation/IoTagent-LoRaWAN/issues/70)
- **update build badge #152:**([22d0a70](https://github.com/Atos-Research-and-Innovation/IoTagent-LoRaWAN/pull/153/commits/22d0a706e8da4a1a46754fd8a0a599b7ed2c5c32))

## [1.2.2](https://github.com/Atos-Research-and-Innovation/IoTagent-LoRaWAN/compare/v1.2.1...v1.2.2) (2019-06-05)

Expand Down
21 changes: 14 additions & 7 deletions bin/iotagent-lora
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,31 @@

'use strict';

var iotAgentLora = require('../lib/iotagent-lora');
var winston = require('winston');
let iotAgent = require('../lib/iotagent-lora'),
iotAgentLib = require('iotagent-node-lib'),
info = require('../package.json'),
context = {
op: 'IoTAgentLoRaWAN.Executable'
},
logger = require('logops');

function start () {
var config;
function start() {
let config;

if (process.argv.length === 3) {
config = require('../' + process.argv[2]);
} else {
config = require('../config');
}

iotAgentLora.start(config, function (error) {
config.iota.iotaVersion = info.version;

iotAgentLib.startServer(config, iotAgent, function (error) {
if (error) {
winston.error('Error starting LoRaWAN IoT Agent: %s',
logger.error(context, 'Error starting LoRaWAN IoT Agent: [%s] Exiting process',
JSON.stringify(error));
} else {
winston.info('LoRaWAN IoT Agent started');
logger.info(context, 'LoRaWAN IoT Agent started');
}
});
}
Expand Down
53 changes: 46 additions & 7 deletions lib/applicationServers/abstractAppService.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@
/* eslint-disable no-unused-vars */
/* eslint-disable no-prototype-builtins */

const winston = require('winston');
const config = require('../configService');
const _ = require('lodash');
const context = {
op: 'IoTAgentLoRaWAN.AbstractAppService'
};

/**
*Class that represents a LoRaWAN app server
Expand Down Expand Up @@ -141,6 +145,35 @@ class AbstractAppService {
return this.appEui;
}

/**
* Gets the application server configuration.
*
* @return {Object} The application server configuration.
*/
getAppServerConf() {
return {
lorawan: {
app_eui: this.appEui,
application_server: this.applicationServer,
application_id: this.applicationId,
application_key: this.applicationKey,
data_model: this.dataModel
}
};
}

/**
* Gets the application server configuration.
*
* @return {Object} The application server configuration.
*/
setAppServerConf(applicationServer, applicationId, applicationKey, dataModel) {
this.applicationServer = applicationServer;
this.applicationId = applicationId;
this.applicationKey = applicationKey;
this.dataModel = dataModel;
}

/**
* Gets the iota configuration.
*
Expand All @@ -150,6 +183,15 @@ class AbstractAppService {
return this.iotaConfiguration;
}

/**
* Set the iota configuration.
*
* @param {Object} iotaConfiguration The IOTA configuration associated to this Application Server.
*/
setIotaConfiguration(iotaConfiguration) {
this.iotaConfiguration = iotaConfiguration;
}

/**
* Adds a device.
*
Expand All @@ -158,11 +200,8 @@ class AbstractAppService {
* @param {Object} deviceObject The device object
*/
addDevice(devId, devEUI, deviceObject) {
if (this.devices && this.devices[devId] && this.devices[devId] === deviceObject) {
winston.info('Device already provisioned');
} else if (this.devices && this.devices[devId]) {
winston.info('Device already provisioned. Updating object');
this.devices[devId] = deviceObject;
if (this.devices && this.devices[devId] && _.isEqual(this.devices[devId], deviceObject)) {
config.getLogger().info(context, 'Device already provisioned');
} else {
this.observeDevice(devId, devEUI, deviceObject);
this.devices[devId] = deviceObject;
Expand Down Expand Up @@ -203,7 +242,7 @@ class AbstractAppService {
let device = {};
let dataModel = {};
if (!devId && !devEui) {
winston.error('Device ID or device EUI must be provided');
config.getLogger().error(context, 'Device ID or device EUI must be provided');
throw new Error('Device ID or device EUI must be provided');
} else if (devId) {
device = this.getDevice(devId);
Expand Down
32 changes: 20 additions & 12 deletions lib/applicationServers/chirpstackAppService.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,16 @@

/* eslint-disable no-unused-vars */

const winston = require('winston');
const config = require('../configService');
const appService = require('./abstractAppService');
const mqttClient = require('../bindings/mqttClient');
const iotAgentLib = require('iotagent-node-lib');
const regenerateTransid = iotAgentLib.regenerateTransid;
const intoTrans = iotAgentLib.intoTrans;
const context = {
op: 'IoTAgentLoRaWAN.ChirpStackService'
};
const _ = require('lodash');

/**
*Class that represents a LoRaServer.io LoRaWAN app server
Expand Down Expand Up @@ -70,7 +77,8 @@ class ChirpStackService extends appService.AbstractAppService {
this.applicationServer.username,
this.applicationServer.password,
this.applicationServer.options,
this.preProcessMessage
this.preProcessMessage,
this.applicationId
);

this.mqttClient.start(callback);
Expand All @@ -93,39 +101,43 @@ class ChirpStackService extends appService.AbstractAppService {
* @param {<type>} message The message
*/
preProcessMessage(mqttTopic, message) {
winston.info('New message in topic', mqttTopic);
winston.debug('Message', JSON.stringify(message));
regenerateTransid(mqttTopic);
config.getLogger().info(context, 'New message in topic', mqttTopic);
config.getLogger().debug(context, 'Message', JSON.stringify(message));

const splittedMqttTopic = mqttTopic.split('/');
if (splittedMqttTopic.length !== 6) {
const errorMessage = 'Bad format for a LoRaServer.io topic';
winston.error(errorMessage);
config.getLogger().error(context, errorMessage);
} else {
// var appId = splittedMqttTopic[0];
const devEui = splittedMqttTopic[3];
const device = this.getDeviceByEui(devEui);
try {
message = JSON.parse(message);
} catch (e) {
winston.error('Error decoding message:' + e);
config.getLogger().error(context, 'Error decoding message:' + e);
message = null;
return;
}

const dataModel = this.getDataModel(null, message.devEUI);
const localContext = _.clone(context);

let deviceId;
if (device) {
deviceId = device.id;
localContext.srv = device.service;
localContext.subsrv = device.subservice;
} else if (message && message.deviceName) {
deviceId = message.deviceName;
}

if (message) {
if (dataModel === 'application_server' && message.object) {
this.messageHandler(this, deviceId, message.devEUI, message.object);
intoTrans(localContext, this.messageHandler)(this, deviceId, message.devEUI, message.object);
} else if (dataModel !== 'application_server' && message.data) {
this.messageHandler(this, deviceId, message.devEUI, message.data);
intoTrans(localContext, this.messageHandler)(this, deviceId, message.devEUI, message.data);
}
}
}
Expand All @@ -145,7 +157,6 @@ class ChirpStackService extends appService.AbstractAppService {

const mqttTopic = 'application/' + this.applicationId + '/device/' + devEUI.toLowerCase() + '/event/up';
this.mqttClient.subscribeTopic(mqttTopic);
winston.info('Mqtt topic subscribed:%s', mqttTopic);
}

/**
Expand All @@ -158,7 +169,6 @@ class ChirpStackService extends appService.AbstractAppService {
stopObservingDevice(devId, devEUI, deviceObject) {
const mqttTopic = 'application/' + this.applicationId + '/device/' + devEUI.toLowerCase() + '/event/up';
this.mqttClient.unSubscribeTopic(mqttTopic);
winston.info('Mqtt topic unsubscribed:%s', mqttTopic);
}

/**
Expand All @@ -167,7 +177,6 @@ class ChirpStackService extends appService.AbstractAppService {
observeAllDevices() {
const mqttTopic = 'application/' + this.applicationId + '/device/+/event/up';
this.mqttClient.subscribeTopic(mqttTopic);
winston.info('Mqtt topic subscribed:%s', mqttTopic);
}

/**
Expand All @@ -176,7 +185,6 @@ class ChirpStackService extends appService.AbstractAppService {
stopObserveAllDevices() {
const mqttTopic = 'application/' + this.applicationId + '/device/+/event/up';
this.mqttClient.unSubscribeTopic(mqttTopic);
winston.info('Mqtt topic unsubscribed:%s', mqttTopic);
}
}

Expand Down
Loading

0 comments on commit 957ee6a

Please sign in to comment.