No message posted in TTN MQTT broker through AWS lambda

I am experiencing problems displaying the downlink message generated by the AWS lambda. However, I can see that TTN has subscribed to the post made through lambda. Below I show the code from the lambda using the node.js mqtt package:

import { connect } from 'mqtt';

export async function handler(event) {
    let options = {
        port:1883,
        clientId: 'mqttjs_'+ Math.random().toString(16).substr(2,8),
        username:'my-user-name',
        password: 'my-app-key',
        keepalive:60,
        reconnectPeriod:1000,
        protocolId:'MQIsdp',
        protocolVersion:3,
        //clean:true,
        encoding: 'utf8'
    };
    
    const mqttHost = 'eu1.cloud.thethings.network'; // La direcciĂłn del broker MQTT de TTN
    //const mqttPort = 1883; // El puerto MQTT (generalmente 1883 para MQTT y 8883 para MQTT sobre TLS)
    const appId = 'my-app-id'; // El ID de la aplicaciĂłn en TTN
    const deviceId = 'my device id'; 
    
    const payload = `{
          "color": "green"
          }`;
    const topic = "v3/my-application@ttn/devices/my-device-id/down/push";
    const client = connect(`https://${mqttHost}`, options);
    
    return new Promise((resolve, reject) => {
  client.on('connect', () => {
  client.subscribe([topic], () => {
    console.log(`Subscribe to topic '${topic}'`);
    client.publish(topic, payload, { qos: 0, retain: true }, (error) => {
      if (error) {
        console.error(error);
      }else {
        console.log('Mensaje de downlink enviado correctamente');
        resolve('Mensaje de downlink enviado correctamente');
        //console.log(client)
        return resolve;
        }
    });
    });
    });

    client.on('message', (topic, payload) => {
      console.log('Received Message:', topic, payload.toString());
    });
    //LAMBDA MQTT.txt
    });
}

with this code I get the following message from TTN

but nothing more than this. I would like to know how to get the payload. Thanks for your contributions.

The subscribe message means the mqtt session is established.

The topic you are using is for messages to the device. Is that the one you are looking for?

Please use the message formatting tools at the top of the entry box when posting code for better readability.

What are you trying to do? What triggers the lambda to run in the first place?

It looks like you are subscribing to the topic that you publish a downlink to and on that basis send a downlink when you get a message.

So you are unlikely to see anything happen as the topic will never send you a message - it only receives messages.

If you are looking to process something for every uplink that sends a downlink, please ensure you are familiar with the Fair Use Policy which limits you to 10 downlinks a day per device. Due to the impact on gateways, the community aspires to very occasional downlinks - one a fortnight being a fair balance for changing settings and/or doing a link check.

Sorry kersing,
I was not aware of that functionality. My idea is that after the node sends a message, it receives a downlink with the current hour and minutes. This will only be done 3 times a day, and is required to synchronize other connected devices.

I would like to test the function and know that TTN is receiving the message from the topic to which it has subscribed. But I don’t know if this is possible, because so far I have only seen the information I have posted.

Thank you Descartes,
I am aware of the fair policy limiting the number of downlinks to 10 per day.
So far I have linked through TTN’s MQTT broker the AWS client, but I am not aware if the posting in the topic is correct. I have removed the subscription part, because as you say the topic only receives messages.

My problem is, I don’t know how I can subscribe the topic to TTN, specifically, my device to receive the downlink message I am trying to send.

In my logic that requires you to subscribe to the uplink events from a device so you get a trigger when an uplink (message from the device) is received. Then you need to post a message to the appropriate topic for that device to schedule the downlink.

The lambda function is triggered by the uplink event. When I try to generate a message through the serial port on the arduino MKRWAN 1310, the event is triggered and the lambda function posts to the topic.

In the TTN MQTT documentation it appears that to publish a downlink message it is necessary to publish to v3/{application id}@{tenant id}/devices/{device id}/down/push. As it appears in the console of TTN there is a subscription to the topic, however, I don’t see the publications of the lambda function reflected.

You’ve not told us what you are trying to achieve with the Lambda.

Typically you subscribe to the “up” topic, process the contents and then use the publish topic to queue a downlink if appropriate.

The implication of using a Lambda is that it is triggered by an external stimulus. Using MQTT is rather random and requires you set a timeout that fits the device interval which is actually rather anti-Lambda. Sure, it launches in a few ms using Firecracker but using a web hook Lambda is far far far better as keeping an incoming http(s) request suspended in the TCP stack whilst the process becomes available has been around for a very long time (like I was doing it this way back in 1996, 3 years before MQTT was created) and it uses far less resources and you can move the code base to a boring VPS with a web server on it without changes - particularly if you go old school and use Personal Home Page …

You can queue a downlink by publishing at any time if it’s not dependent on the uplink.

synchronizing your devices? are you trying to send data at a precise time, say at exactly 10h00?

synchronizing messages are not the best practice

1 Like

As above, not good practice at all - take the reading at the right time but then send the uplink with some random delay - called jitter - this gets you the reading when you want it without messing up the local network.

But any device that can’t keep the time for a few days is going to have many other issues - like temperature sensitive of its ADC. So sending the time 3 times a day seems a bit excessive.

And when you reach 8 devices, your gateway will be at capacity but any other local devices &/or general broadcasts on the ISM band will probably end up with some packet loss.

Additionally, there is the perfectly good LoRaWAN spec time request that will be much more accurate than the processing delays incorporated in AppServer → MQTT → Lamda → MQTT → AppServer → NetworkServer → scheduled to a Gateway on Rx1 or maybe Rx2 which you will have to account for → device → RTC.

I am trying to receive a message when the device button is pressed. I apologize for using the word synchronization, because it is not in the strict sense of the word.

I have seven MKRWAN 1310 devices that are low-energy (500µA), and therefore the only active element with which it counts its cycles is the watchdog. This board has connected a number of sensors that must take measurements every 12 hours. This hasn’t been a problem until yet, because the watchdog cycle counting is quite accurate, and all the MKRWANs took the measures approximately at the same time, which is what I was looking for.

Now a functionality has been added to the devices, that by pressing the button, they do the measurements and after that return to the mode under consumption. There is no internal variable within the MKRWAN that stores the time passed, then before returning to low-consumption mode, again put 12 hours (“Really equivalent cycles”) and again enter low consumption. This is a problem, because in this way, if the devices are pulsed at different times they will end up with a large dispersion in the number of hours, and they will no longer all give the measurement at the same time approximately.

If every time the device, takes a measure, receives in its listening time the current hour and minute, putting the reference that at 9 a.m. they always have to give the measurement, I no longer have any problem. Because before the return to low consumption I make the difference of current time and the expected time and put the internal count adapted to the rest of both, so that approximately I take the data again at 9 o’clock, and not that I make a 12-hour account. As I have commented before, in an extreme case, this button will not be pressed more than 3 times in a day, since the site where it is located is a remote place, without any urban nucleus in 10 km round, and the worker himself who goes to do the measurement goes sporadically.

I’m looking for a solution for that, I had decided for AWS because I have an account. But I’m open to other easier or more effective suggestions. If you share the documentation or indicate me reference sites to find the solution I would be very grateful

The Arduino docs - very literally since it is an Arduino board - with reference to the Real Time Clock. There are many libraries around to get the time and set a wake up time but you probably already have this so I’m confused on how you are doing it at present.

For LoRaWAN, look at the specification with particular regard to the DeviceTimeReq. The LNS will give you all you need without resorting to MQTT on a Lambda.

On TTN we’re not bothered about 3 uplinks a day, it’s 3 downlinks that you would effectively be queuing within the same few seconds that will get messy, particularly for you but also for anyone else in the immediate area. And I’ve not yet seen a SAMD21 RTC drift much over a few days unless the temperature changes a lot.

oh you want to synchronize to 09h00?