CS v4. Can't set up downlink

Hi There!
I have a Chirpstack v4 running on R-PI and Thingsboard C.E on a ubuntu server.
I have several devices working, but for the first time I need to set up a downlink to enable/disable the relay output in a Dragino LT-22222-L device.
I’ve followed many many guides and a long chat with ChatGPT…and Im completly stuck as the HTTP API command that should work to send downlinks to devices, doesn’t work at all.
I’ve been able to send commands with the QUEUE option with some hexa bytes, so downlink itself works on the device, but the API call does not

This what Im trying in CURL:

curl -v -X POST http://*serveraddress*:8081/api/devices/a84041XXXXXXXXXXX/down -H "Authorization: Bearer XXXXXXXXXXXXXJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJjaGlycHN0YWNrIiwiaXNzIjoiY2hpcnBzdGFjayIsInN1YiIXXXXXXXXXzMtNGRkNi1iN2JmLThlMDhjNGFlODRhZCIsInR5cCI6ImtleSJ9.JrxQgNqGce4JXXXXXXXXXXXXXXXXXXXXXXXXX -H "Content-Type: application/json" -d '{"confirmed": true,"fPort": 2,"data": "AQ=="}'

Ok I hid some data iwth XXX but other than that, it’s all the same
The Authorization was taken from the section:API KEYS, inside TENANT, although I tried another key created outside the tenant, same result
The port is correct, 8081 is where my Chirpstack “lives”, what I use to enter the web application and manage all.
a84041XXXXXXXXXXX is the actual DevEUI from the Dragino LT-22222-L

And the reply from this POST is:

* Host XXXXXXX.org:8081 was resolved.
* IPv6: (none)
* IPv4: XX.XX.XX.91
*   Trying XX.XX.XX.91:8081...
* Connected to XXXXXXX.org (XX,XX,XX.91) port 8081
> POST /api/devices/a84041ccXXXXXX/down HTTP/1.1
> Host: XXXXXXXXXXXX:8081
> User-Agent: curl/8.7.1
> Accept: */*
> Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYZZZZZZZZZZZZZZZZZZZZZZZ -H Content-Type:
>
* Request completely sent off
< HTTP/1.1 400 Bad Request
< content-length: 0
< date: Tue, 03 Sep 2024 21:36:52 GMT
<
* Connection #0 to host XXXXXXX.org left intact
* URL rejected: Malformed input to a URL function
* Closing connection
curl: (3) URL rejected: Malformed input to a URL function
* URL rejected: Malformed input to a URL function
* Closing connection
curl: (3) URL rejected: Malformed input to a URL function
* URL rejected: Malformed input to a URL function
* Closing connection
curl: (3) URL rejected: Malformed input to a URL function

Is there anything I need to install on Chirpstack to allow downlinks?
Is there anythign else I could be missing?
Am I misunderstanding any of the parameters?

Thanks in advance!

Not sure if its your only issue but it looks like you’re missing the devEUI in the MQTT message. Check out the example payload at the bottom of this page:

https://www.chirpstack.io/docs/chirpstack/integrations/mqtt.html

Ok but the link you provide is about MQTT downlink, Im trying to use an HTTP API REST (post) method, which is a different syntax. The DevEUI is already in the URL:
http://serveraddress:8081/api/devices/a84041XXXXXXXXXXX/down

BTW I tried http://serveraddress:8081/api/devices/a84041XXXXXXXXXXX/down
and also
http://serveraddress:8081/api/devices/a84041XXXXXXXXXXX/queue
with same result

** In my knowledge ** All the API is doing is triggering Chirpstack to publish the JSON message you pass it to the correct MQTT topic that your Gateway Bridge subscribes to. That JSON message published to the broker should be the same regardless of how it was generated (gRPC, REST, MQTT integration), so the syntax used for the actual JSON message should be the same for REST as it is in MQTT. I do not believe the REST API would inject the devEUI into the JSON message itself.

I grabbed this from the REST API documentation, the struct for a DeviceQueueItem still requires a devEUI:

type DeviceQueueItem struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// ID (UUID).
	// This is automatically generated on enqueue.
	Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
	// Device EUI (EUI64).
	DevEui string `protobuf:"bytes,2,opt,name=dev_eui,json=devEui,proto3" json:"dev_eui,omitempty"`
	// Confirmed.
	Confirmed bool `protobuf:"varint,3,opt,name=confirmed,proto3" json:"confirmed,omitempty"`
	// FPort (must be > 0).
	FPort uint32 `protobuf:"varint,4,opt,name=f_port,json=fPort,proto3" json:"f_port,omitempty"`
	// Data.
	// Or use the json_object field when a codec has been configured.
	Data []byte `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"`
	// Only use this when a codec has been configured that can encode this
	// object to bytes.
	Object *structpb.Struct `protobuf:"bytes,6,opt,name=object,proto3" json:"object,omitempty"`
	// Is pending.
	// This is set by ChirpStack to true when the downlink is pending (e.g. it
	// has been sent, but a confirmation is still pending).
	IsPending bool `protobuf:"varint,7,opt,name=is_pending,json=isPending,proto3" json:"is_pending,omitempty"`
	// Downlink frame-counter.
	// Do not set this for plain-text data payloads. It will be automatically set
	// by ChirpStack when the payload has been sent as downlink.
	FCntDown uint32 `protobuf:"varint,8,opt,name=f_cnt_down,json=fCntDown,proto3" json:"f_cnt_down,omitempty"`
	// Is encrypted.
	// This must be set to true if the end-application has already encrypted
	// the data payload. In this case, the f_cnt_down field must be set to
	// the corresponding frame-counter which has been used during the encryption.
	IsEncrypted bool `protobuf:"varint,9,opt,name=is_encrypted,json=isEncrypted,proto3" json:"is_encrypted,omitempty"`
}

A quick google of a couple other people’s REST downlink examples can quickly confirm all this for you.

Thanks a lot. Still, I tried this:
curl -v -X POST http://XXXXXX.org:8081/api/devices/YYYYYYYYYYY/queue -H “Grpc-Metadata-Authorization: Bearer ***longstring” -H “Content-Type: application/json” -d ‘{“downlink”:{“devEui”:“YYYYYYYYYYYYYYYYYY”,“confirmed”:false,“fPort”:2,“data”:“EA==”}}’
And I still get 400 BAD REQUEST
I tried …/queue and /down, from different documentation.
L also tried “Grpc-Metadata-Authorization: Bearer xxxxxx” and “Authorization: Bearer xxxxx” with no change
Am I still missing a needed parameter?
Thanks

Looks like your URL might be off too, check what this guy uses: Enqueueing a downlink via v4 REST API .

I’ve never used REST before so I can’t offer much help besides that, just noticed that devEUI was missing from the packet.

Last attempt:
curl -v -X POST http://XXXXXX:8081/DeviceService/DeviceService_Enqueue -H “Authorization: Bearer yyyyyyyyyyyyyyyy*****” -H “Content-Type: application/json” -d '{“queueItem”:{“devEui”:“xxxxxxxxxxxxxxxxx”,“confirmed”:true,“data”:“AwER”,“fPort”:2}}
No luck…:frowning:

Do you get an error in the Chirpstack logs when you try?

From what I’m reading, since CS v4 the API REST functions are disabled and replaced by gRPC. Further reading states that sending an gRPC command from Thingsboard is not possible an implies generating a script outside that processes gRPC data, which is not what I want in my case
Other option is to install the gRPC-API REST proxy addon for Chirpstack, which looks like a simple 3 or 4 commands set
Does this make sense?
Thanks

Is there a way to retrieve CS logs from inside the web app? Cause from where I am right now, I don’t have SSH access to the R-PI server where I have CS installed…
Thanks

Chirpstack moved away from REST in V4 but I believe it is still natively supported, at the very least I know that in the docker install they have a service by default for the Rest API:

  chirpstack-rest-api:
    image: chirpstack/chirpstack-rest-api:4
    restart: unless-stopped
    command: --server chirpstack:8080 --bind 0.0.0.0:8090 --insecure
    ports:
      - 8090:8090
    depends_on:
      - chirpstack

I wouldn’t be surprised if you needed to do a separate install if you did Ubuntu.

Unfortunately I don’t think so

EDIT:

This line from the REST API documentation seems to imply that it is not natively supported:

With the introduction of ChirpStack v4, the REST API interface is no longer included

So I would give the proxy a shot if I were you.

Ok I will install this as soon as I have physical access to this server, I don’t have port 22 NAT’ed in this router.
Thanks!

Ok I installed the api-rest-proxy, binded it to a new port 8090, NAT’ed the router to listen to this port and point to the Chirpstack IP, and tried most of the strings I had already tried before…
Same result, 400 BAD REQUEST on them all
Some specific details sometimes like:

{“code”:3, “message”:“invalid character ‘\’’ looking for beginning of value”, “details”:}* Connection #0 to host XXXXXXX left intact

BTW my message wan not even close to that, it was:

-d ‘{“queueItem”: {“confirmed”:true,“data”:“AwER”,“fPort”:2,“devEui”:“XYXYXYXYXYXYX”}}’

Thanks

Sorry, I don’t know how to help you. Maybe if you know more GO than I do you could get some insight from the actual API definition: chirpstack-rest-api/openapiv2/api/device.swagger.json at master · chirpstack/chirpstack-rest-api · GitHub

I’ve seen @datnus solve a few REST issues before so maybe he’d be willing to help?

Ok, issue solved!!!
You link and finding others’ posts with same errors led to finding out what was wrong.
This is the FINAL WORKING CURL COMMAND:
curl -X POST -H “Content-Type: application/json” -H “Grpc-Metadata-Authorization: Bearer mytoken” -H “Accept: application/json” -d “{"queueItem": { "confirmed" :false, "fPort" : 2, "data" : "AwAA" }}” http://SSSSSSSSSSSSSSSS:8091/api/devices/XXXXXXXXXXXXXX/queue
So there was an issue with single and double quotes, single ones had to be removed and used doubles, and doubles had to be escaped with
Also command was queueItem and not DeviceQueueItem as some sites mentioned
GRPC-Metadata-Authorization used instead of only Authorization…
And probably some other changes along the way, I had tested like 150 commands already…
Thanks!!

1 Like

Love to hear you got it figured out :slightly_smiling_face:

1 Like