Problem sending MAC-Commands with gRPC


I am currently trying to experiment with my LoRa Sensor by sending different MAC-Commands to change parameters for various purposes. However, I have not been able to send a single MAC-Command due to my limited knowledge on how this works. It is my first time doing this and I’m slighty overwhelmed. This is the code so far:

import os
import sys

import grpc
from chirpstack_api import api

# Configuration.

# This must point to the API interface.
server = "..."

# The DevEUI for which you want to enqueue the downlink.
dev_eui = "..."

# The API token (retrieved using the web-interface).
api_token = "..."

if __name__ == "__main__":
  # Connect without using TLS.
  channel = grpc.insecure_channel(server)

  # Device-queue API client.
  client = api.DeviceServiceStub(channel)

  # Define the API key meta-data.
  auth_token = [("authorization", "Bearer %s" % api_token)]

  # Construct request.
  req = api.EnqueueDeviceQueueItemRequest()
  req.queue_item.confirmed = False = bytes([0x06])
  req.queue_item.dev_eui = dev_eui
  req.queue_item.f_port = 255

  resp = client.Enqueue(req, metadata=auth_token)

  # Print the downlink id

This will send a downlink to my device, but instead of it being an actual MAC-Command, it’s just “06” inside the payload, not DevStatusReq as intended. I understand that I need to work with the CID, but I was not able to get it done. I also don’t understand how I would input the data needed to change, for example, the duty cycle per MAC-Command.

I have been on this problem for a while and I just can’t seem to get it right. Thanks in advance for anyone trying to help.

I think you want to send downlinks to configure your nodes. Not MAC commands.

MAC commands are seldom used by end-users. They are for LoRaWAN internal use


I specifically need to test MAC-Commands such as DevStatusReq, DutyCycleReq or NewChannelReq for internal testing. Unfortunately I have not found a way to do so yet. Maybe this is the wrong approach, but there surely must be a way to do this, right?

If mac command, the fport should be 0.

I believe the ChirpStack API you are using does not accept fport 0.

You can try btw.

This is not possible and I’m not planning to support this for the following reason:

The mac-layer is handled by ChirpStack. ChirpStack keeps an internal state of each device (e.g. the channel-mask and the channels that the device knows about). If it detects a configuration change between the device and ChirpStack it will send mac-commands to synchronize the device settings.

If you want to test the NewChannelReq for example, one way to trigger this is to change the extra-channels configuration. E.g.:

This would trigger a NewChannelReq mac-command.

1 Like

Thank for you for your reply,

in September 2018, you wrote that it would be possible to do this through the API:

Is this not possible anymore? If it’s still possible, what exactly do I need to put in for it to work?

This used to be possible a long time ago, but I removed this as I realized it would never work as expected and it is not something I would like to support.

E.g. you would send a manual request to change the RX1 delay from 1 to 3 seconds, but ChirpStack would still send the downlink using RX1 delay 1 second so your device would never work again until a new rejoin.

Mac-commands are driven by the configuration you feed into ChirpStack. Certain mac-commands can be triggered by changing configuration and in such case ChirpStack will handle these mac-commands as it should be.

Thanks for the quick answer,

this is quite unfortunate, but I will just have to trigger them via configuration then. Still, thanks for helping me out.


sorry to bother again, but I am currently struggling with the config file. While I am able to change the parameters, I can only do so after rebooting the gateway, thus I have to reactivate the device every time. This makes it impossible for me to catch the MAC-command. Is it possible to update the gateway without having to restart it, so that the device is still in a session?

There is no need to reboot your gateway or re-activate your device. After changing the parameters in the chirpstack.toml / region_xxxx.toml configuration files and restart ChirpStack, ChirpStack will automatically send the mac-command(s) needed to synchronize the device settings at the next Class-A downlink opportunity.

If you want to send mac commands manually, use the interop tool from actility, on the free ThingPark Community platform. It has a test mode tool and a manual command sending mode.

1 Like