Dynamically set clientID for MQTT output

Hello,

I'm trying to work with a LoRaWAN gateway running Node-RED, however am running into a bit of an issue.

What I need to do is for each payload received by the gateway, strip out the serial number from the data it sends, and use this serial number to send a 1-off MQTT message, using the serial number as a clientID for the MQTT connection, then close the connection. This process would then be repeated programmatically for each LoRaWAN node that calls in.

Currently, I can't find a good way to set clientIDs on the fly. Anyone know of a way to do this?

There is a PR for dynamic mqtt control waiting review. It can do this (and more).

If you are desperate, I could tell you how to modify your installation SRC to make it work otherwise hang tight and keep fingers crossed for node-red 2.1.

Approaching desperation, definitely. If you have a workaround that would be fantastic!

Ok. But first. How is your node-red installed, what version, what hardware and what OS? Do you have access to filesystem?

Can you explain why you want to do this? It seems very unusual.

1 Like

@Colin I need to do this because this is how my company's IoT architecture is setup on the backend, it's out of my control I'm afraid.

@Steve-Mcl Working with v0.15.3, it came pre-installed on the gateway (MultiTech Conduit AP MTCAP-LNA3), OS appears to be arm-mlinux, and I have ssh and file system access.

Unfortunately I think that is too old. The underlying MQTT library has had several full major updates since then.

Does that box have an updated firmware with a newer node js & node-red or is it possible to upgrade it?

Failing that, you could install node-red on a server or raspberry pi?

Out of interest, do you understand why? At the moment I have difficulty seeing a use case. Unless it is for some security related issue I suppose.

@Steve-Mcl Unsure if I can upgrade it, I'll look into it, but would like to at least attempt with the current version before opening that can of worms

@Colin Security is definitely one reason, in any case, it's outside of my hands to change it, just have to roll with the punches for now.

Ok, in that case don't tell them that you are connecting using the Id of a different device.

While waiting for the new version, a simple work-around would be to use a python script. Call it from NR using the exec node with necessary params where one is the serial number that you then use in the script as clientID

Unfortunately, the node version on that box is 0.x (I looked at the firmware info) so it is doubtful it will ever work.

Assuming python is installed on that box & the OP can install an MQTT lib.


An alternative (also assuming box already has mosquitto_pub or OP can install mosquitto client tools) is to exec the mosquitto_pub command specifying the client id

Demo...
JWJjKe5Yok

Check on broker ...

Very interesting, thank you both for the recommendations and workarounds, they're much appreciated!

I'll see about working this way soon as the project is starting up tomorrow, I'll let you guys know how it goes. Thanks again!

This is a simple script I think should work (you have to change the ip to the broker) as a starting point. Maybe you also have to change the sensor value to a string before you send it

Create a file named "lorawan_send.py" or similar and call it with the params as described below

#!/usr/bin/python
# USAGE
# python lorawan_send.py -cid mqtt_client_id -v value
# or
# python3 lorawan_send.py -cid mqtt_client_id -v value

import argparse
import paho.mqtt.client as mqtt

def on_publish(mosq, userdata, mid):
    mosq.disconnect()
    del mosq
    exit(0)

ap = argparse.ArgumentParser()
ap.add_argument(
    "-cid",
    "--cid", 
    required=True, 
    help="mqtt client id"
)
ap.add_argument(
    "-v",
    "--value", 
    required=True, 
    help="value from sensor"
)
args = vars(ap.parse_args())


client = mqtt.Mosquitto(client_id=args['cid'])
client.connect("127.0.0.1", 1883, 60)
client.on_publish = on_publish
client.publish("lorawan", args['value'], 1, False)
client.loop_forever()

If on Linux - then as @Steve-Mcl suggested - calling the command line program mosquitto_pub may be simpler.