mcci-catena / arduino-lmic

LoraWAN-MAC-in-C library, adapted to run under the Arduino environment
https://forum.mcci.io/c/device-software/arduino-lmic/
MIT License
636 stars 207 forks source link

Get airtime estimate #754

Open bertrik opened 3 years ago

bertrik commented 3 years ago

TheThingsNetwork has a fair access policy that specifies 30 seconds of upload time per day. If possible, I'd like my application to adhere to that, but currently there is not really an easy way to ensure this.

What I'd like to have is receive an estimate of the time spent transmitting in the EV_TXCOMPLETE callback, like a number of milliseconds. Then I can use that to determine how long my application should hold off transmitting the next packet, based on some duty cycle (e.g. 30 sec / 86400 sec).

Currently, my makeshift solution is as follows: in the EV_TXSTART callback I read out the value of the LMIC.rps variable so I know at what spreading factor the LMIC library is currently operating. Assuming my payload is fixed length (which it isn't always the case) I have a hardcoded table telling me how long I should wait. This isn't very accurate.

terrillmoore commented 3 years ago

Hi @bertrik,

In EU868 and other regions (although not in US915), the LMIC already enforces duty cycle restrictions (for regulatory compliance). These are less stringent than the TTN restrictions, but they mean that the LMIC already has a very good idea of how long a message is on the air; it uses this to update the duty-cycle parameters. It would not be hard to have an API to fetch the number of milliseconds in the last message, so that higher level code could track this. For region portability we'd have to make sure that all regions can do the calculation, but this is straightforward.

I will put this on the list, but don't know when I'll get to it.

Best regards, --Terry

mrx23dot commented 2 years ago

Tracking the difference between EV_TXSTART and EV_TXCOMPLETE in app layer is far more simpler than having a function covering every possible cases. The difference could be calculated inside LMIC, but this is only TTN restriction.

bertrik commented 2 years ago

@mrx23dot The idea to track the time between EV_TXSTART and EV_TXCOMPLETE is elegant and simple. But I'm not completely sure what EV_TXCOMPLETE signifies. What I remember from looking at these events and what I find with a google search, is that EV_TXCOMPLETE occurs after the complete tx/rx cycle. This includes transmitting a message plus waiting for a response from the network, so the time between EV_TXSTART and EV_TXCOMPLETE is not representative for the actual time-on-air for uplink.

If there were such an event, that is sent from the stack to the application immediately after transmission finished, this could work.

bertrik commented 2 years ago

I looked a bit deeper into this. Apparently the code LacunaSpace basicmac stack has an event EV_TXDONE that looks like it does exactly the thing discussed above, see for example: https://github.com/LacunaSpace/basicmac/blob/master/lmic/lmic.c#L2414

This event is notified upon uplink done and upon join request tx done.

I think if this event would be available in the mcci lmic stack, it would allow the application to easily keep track of uplink transmission times in order to assist complying with the TTN FUP. This would not require any bookkeeping by the lmci stack.