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
req.queue_item.data = 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
print(resp.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 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?
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 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.
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.