brocaar / chirpstack-api Goto Github PK
View Code? Open in Web Editor NEWChirpStack API (Protobuf & gRPC)
License: MIT License
ChirpStack API (Protobuf & gRPC)
License: MIT License
hei man,I really want to use it "io.chirpstack", When can it be used normally ? thks!!!
On a Docker Chirpstack ver. 4.3 , python 3.9.2, the example "nqueue_downlink.py" (https://www.chirpstack.io/docs/chirpstack/api/python-examples.html#enqueue_downlinkpy) works fine.
When we try to execute the following python code for multicast downlink :
server = "localhost:8080"
dev_eui = "0080e1150546f8eb"
api_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJjaGlycHN0YWNrIiwiaXNzIjoiY2hpcnBzdGFjayIsInN1YiI6ImMyOGM5M2I4LTdlNWMtNGYzOS1hZTA2LWFlNDU3ZjYxNzcwNiIsInR5cCI6ImtleSJ9.7cbczN8WJ5ZNGoQwjZwFLaHiBThGDMJ-1T_uaUTT2F4"
data = [ 0x84, 0x9b, 0x00, 0x08, 0x00, 0x02, 0x01 ]
mcast_group_id = "4b2b9d7c-776f-4e54-b81d-d17178d6d558"
channel = grpc.insecure_channel(server)
client = api.DeviceServiceStub(channel)
auth_token = [("authorization", "Bearer %s" % api_token)]
req = api.EnqueueMulticastGroupQueueItemRequest()
req.queue_item.data = bytes(data)
req.queue_item.f_port = 2
req.queue_item.multicast_group_id = mcast_group_id
resp = client.Enqueue(req, metadata=auth_token)
We are getting the folowing error message :
Traceback (most recent call last):
File "/root/spyros/lora/sandbox/lora_send.py", line 69, in <module>
multicast(server, dev_eui, 2, api_token, mcast_group_id, data)
File "/root/spyros/lora/sandbox/lora_send.py", line 49, in multicast
resp = client.Enqueue(req, metadata=auth_token)
File "/root/.pyenv/versions/test1/lib/python3.9/site-packages/grpc/_channel.py", line 1030, in __call__
return _end_unary_response_blocking(state, call, False, None)
File "/root/.pyenv/versions/test1/lib/python3.9/site-packages/grpc/_channel.py", line 910, in _end_unary_response_blocking
raise _InactiveRpcError(state) # pytype: disable=not-instantiable
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.INTERNAL
**details = "failed to decode Protobuf message: DeviceQueueItem.f_port: EnqueueDeviceQueueItemRequest.queue_item: invalid wire type: LengthDelimited (expected Varint)"
debug_error_string = "UNKNOWN:Error received from peer {grpc_message:"failed to decode Protobuf message: DeviceQueueItem.f_port: EnqueueDeviceQueueItemRequest.queue_item: invalid wire type: LengthDelimited (expected Varint)", grpc_status:13, created_time:"2023-07-05T12:30:54.699263412+03:00"}"**
When we try the "EnqueueMulticastGroupQueueItemRequest()" with Node_Red it works fine.
Does anybody knows about this error message ?
The only point where the Application server reports the DevAddr is in the JoinEvent, and afterwards its completely unreported. This is a shame, because its very valueable information. The Gateway API basically only communicates the DevAddr and no DevEUI.
chirpstack-api/protobuf/as/integration/integration.proto
Lines 103 to 104 in 4b2fccc
https://github.com/brocaar/chirpstack-api/blob/master/protobuf/nc/nc.proto
I would like to see either the DevAddr on the Gateway part, or the DevEUI on the appserver Integration API.
The added benefit of having the DevAddr on the gateway, is that if a join request is accepted, the address is already known. Now I have to wait for the first data to arrive at the station in order to pick it up from the Join event of the appserver.
As i wanted to build ChirpStack gRPC API message from client to server (with javascript), the error pops up:
TypeError: Cannot read property 'createInsecure' of undefined
at file:///.
The code is copied from https://www.npmjs.com/package/@chirpstack/chirpstack-api
I think the issue is the 'credentials', that is 'undefined'. Can someone help me to solve this problem?
To run the ChirpStack gRPC API message
The code line:
// Create the client for the 'internal' service
const internalServiceClient = new internalService.InternalServiceClient(
'localhost:8080',
grpc.credentials.createInsecure()
);
And the Output with the error:
TypeError: Cannot read property 'createInsecure' of undefined
at file:///.
import * as grpc from 'grpc';
import * as internalService from '@chirpstack/chirpstack-api/as/external/api/internal_grpc_pb';
import * as internalMessages from '@chirpstack/chirpstack-api/as/external/api/internal_pb';
// Create the client for the 'internal' service
const internalServiceClient = new internalService.InternalServiceClient(
'localhost:8080',
grpc.credentials.createInsecure()
);
// Create and build the login request message
const loginRequest = new internalMessages.LoginRequest();
loginRequest.setUsername('username');
loginRequest.setPassword('password');
// Send the login request
internalServiceClient.login(loginRequest, (error, response) => {
// Build a gRPC metadata object, setting the authorization key to the JWT we
// got back from logging in.
const metadata = new grpc.Metadata();
metadata.set('authorization', response.getJwt());
// This metadata can now be passed for requests to APIs that require authorization
// e.g.
// deviceServiceClient.create(createDeviceRequest, metadata, callback);
});
Component | Version |
---|---|
ChirpStack API | v?.?.? |
I am using @chirpstack/api
inside of a Sveltekit project and Rollup.js complains about the use of eval
in the Google Protobuf JS library:
node_modules/google-protobuf/google-protobuf.js (27:206): Use of eval in "node_modules/google-protobuf/google-protobuf.js" is strongly discouraged as it poses security risks and may cause issues with minification.
node_modules/google-protobuf/google-protobuf.js (29:315): Use of eval in "node_modules/google-protobuf/google-protobuf.js" is strongly discouraged as it poses security risks and may cause issues with minification.
node_modules/google-protobuf/google-protobuf.js (48:475): Use of eval in "node_modules/google-protobuf/google-protobuf.js" is strongly discouraged as it poses security risks and may cause issues with minification.
I would love to not have these warnings and maybe even trim my bundle size down a bit.
I looked into using protobuf.js but they do not implement the Timestamp field.
Steps:
vite build
)node_modules/google-protobuf/google-protobuf.js (27:206): Use of eval in "node_modules/google-protobuf/google-protobuf.js" is strongly discouraged as it poses security risks and may cause issues with minification.
node_modules/google-protobuf/google-protobuf.js (29:315): Use of eval in "node_modules/google-protobuf/google-protobuf.js" is strongly discouraged as it poses security risks and may cause issues with minification.
node_modules/google-protobuf/google-protobuf.js (48:475): Use of eval in "node_modules/google-protobuf/google-protobuf.js" is strongly discouraged as it poses security risks and may cause issues with minification.
Component | Version |
---|---|
ChirpStack API | v4.70 |
import device_pb from '@chirpstack/chirpstack-api/api/device_pb';
import timestamp_pb from 'google-protobuf/google/protobuf/timestamp_pb';
import device_grpc_pb from '@chirpstack/chirpstack-api/api/device_grpc_pb';
import device_profile_grpc_pb from '@chirpstack/chirpstack-api/api/device_profile_grpc_pb';
import device_profile_pb from '@chirpstack/chirpstack-api/api/device_profile_pb';
const {
CreateDeviceRequest,
Device,
ListDevicesRequest,
GetDeviceRequest,
DeleteDeviceRequest,
DeviceKeys,
CreateDeviceKeysRequest,
UpdateDeviceKeysRequest,
GetDeviceKeysRequest,
GetDeviceMetricsRequest,
UpdateDeviceRequest
} = device_pb;
const { DeviceServiceClient } = device_grpc_pb;
const { DeviceProfileServiceClient } = device_profile_grpc_pb;
const { ListDeviceProfilesRequest } = device_profile_pb;
In our project we are using chirpstack-api as an external dependency, but we cannot upgrade the com.google.protobuf package, because chirpstack-api is transitively forces an older version containing now deprecated calls in the generated sources.
Not at the moment.
Go protobuf V2 (https://pkg.go.dev/google.golang.org/protobuf) was released a while ago. It would be nice to have the API updated to V2 to better unify code bases that are integrated with ChirpStack and permanently get rid of those deprecated linter warnings.
To make life easier for projects that integrate using chirpstack-api
. The current integration messages, for example, do not implement the proto reflect methods necessary to use the V2 protobuf API.
Presumably this would require a significant search-and-replace of this repo and all associated projects. I imagine there would be limited changes to logic, if any.
Maybe, kinda busy. ;)
At the moment the version string is defined multiple times in docker-compose.yml. This could be changed so that it is only defined once.
Fewer changes required to update version string.
I see two ways to do this:
Yes.
Since I'm currently building one for myself. I like to check if there already is some REST client for the Chirpstack API in Go?
I guess you focused more on the JS side. At least I'm now using the entities from https://godoc.org/github.com/brocaar/chirpstack-api/go/as/external/api
for implementation.
Once it is a little bit more major I would also consider sharing the code.
Include variables and tags in the Get /api/devices request
Basically this avoids making individual requests when we want to get variables / tags associated to handled devices.
The current js/README.md
refers to the usage of login based JWT tokens. This has been deprecated in favor of API keys that can be created using the ChirpStack Application Server web-interface. The README.md
should be updated.
As the last commit removes the username from the user.proto
file the login method is quite irritating as it reqiueres still a "username". I understand that we should use the identifier to identify the user and that in future builds we should only use the e-mail to login, but I would like to show the username in my C# application which I derive from this very github repository.
I would suggest to rename username to email
and I would love to see if we could keep the username in future releases so we can show it in external applications.
When trying to stream frames from /api/gateways/{gateway_id}/frames we don't get any data.
Getting join request via the stream. I'm faily confident things are setup correctly as I get an error if I use the wrong api key.
Steps:
Component | Version |
---|---|
ChirpStack API | v1.0.0 |
The chirpstack application api defines that the model of an organization is a string. However in this package it is defined as number. This is an inconcistency. It looks like it is a number, so maybe this is an issue for the application server.
Using the javascript version.
PS. working on a node-red integration based on this package
https://github.com/adminfriso/node-red-contrib-chirpstack
Component | Version |
---|---|
ChirpStack API | v3.8.1 |
Error in Python example:
loginRequest = api.LoginRequest()
loginRequest.password = 'admin'
loginRequest.username = 'admin'
loginRequest = api.LoginRequest()
loginRequest.password = 'admin'
loginRequest.email= 'admin'
Component | Version |
---|---|
ChirpStack API | v?.?.? |
Recent changes to UplinkEvent, #47, are not reflected in https://www.chirpstack.io/application-server/integrations/events/. I was looking for examples and couldn't find them.
Hi,
I'm actually struggling to create the client with dotnet-grpc. Is there a way you publish one ? I'm getting a lot of errors because of the folder architecture and the bad import.
c:\Python\Python310>python --version
Python 3.10.8
c:\Python\Python310>pip --version
pip 23.1.2 from c:\Python\Python310\lib\site-packages\pip (python 3.10)
pip install chirpstack-api
Run "enqueue_downlink.py" sample:
https://www.chirpstack.io/application-server/api/python-examples/
import os
import sys
import grpc
from chirpstack_api.as_pb.external import api
...
Output:
python enqueue_downlink.py
Traceback (most recent call last):
File "c:\lor\enqueue_downlink.py", line 5, in <module>
from chirpstack_api.as_pb.external import api
ModuleNotFoundError: No module named 'chirpstack_api.as_pb'
Steps:
Component | Version |
---|---|
ChirpStack API | v?.?.? |
My lorawan server host is https://192.168.1.200:13402.
It is ok.
My Code:
=====================================================
`
log.Println("111111111111111")
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()
apiClient, err := grpc.DialContext(ctx, "192.168.1.200:13402", grpc.WithInsecure(), grpc.WithBlock())
if err != nil {
panic(err)
}
log.Println("222222222222")
api := pb.NewDeviceServiceClient(apiClient)
devices, err := api.List(context.Background(), &pb.ListDeviceRequest{
Limit: 10,
Offset: 0,
})
if err != nil {
panic(err)
}
jd, _ := json.Marshal(devices)
log.Println("grpc list:", string(jd))
The error logs:
****************************************************************************
2019/12/10 18:05:00 111111111111111
panic: context deadline exceeded
goroutine 1 [running]:
main.main()
E:/go_workplace/src/GoYunNanPoverty/main.go:47 +0x3f9
How do I use 'grpc'?
I need use jwt?
How can i use the parameter(jwt)?
I generated the java api, everything seems to work, authentication is ok, after some extra efforts how to inject the bearer token to the calls even this works and I'm able to create an application via the api
//create application
ApplicationServiceBlockingStub applicationservicestub=io.chirpstack.api.as.external.api.ApplicationServiceGrpc
.newBlockingStub(channel)
.withCallCredentials(btoken);
Application application=io.chirpstack.api.as.external.api.Application.newBuilder()
.setName("wasserstandsmesser2")
.setDescription("mydescrioption")
.setOrganizationId(2)
.setServiceProfileId("91ca668f-64c1-484f-aeff-9a05098c6389")
.build();
CreateApplicationRequest apprequest=CreateApplicationRequest.newBuilder()
.setApplication(application)
.build();
CreateApplicationResponse applicationresponse=applicationservicestub.create(apprequest);
with applicationresponse.getId() I get the created id. when I try to create a device with the similar code
//create device
DeviceServiceBlockingStub deviceservicestub=io.chirpstack.api.as.external.api.DeviceServiceGrpc.newBlockingStub(channel).withCallCredentials(btoken);;
io.chirpstack.api.as.external.api.Device device=io.chirpstack.api.as.external.api.Device.newBuilder()
.setApplicationId(applicationresponse.getId())
.setName("devicename")
.setDescription("description")
.setDevEui("0018b20000023065")
.setDeviceProfileId("94b0900e-9124-4ba4-89a6-33ee4eebc5f0")
.build();
io.chirpstack.api.as.external.api.CreateDeviceRequest createdevicerequest=io.chirpstack.api.as.external.api.CreateDeviceRequest
.newBuilder()
.setDevice(device)
.build();
deviceservicestub.create(createdevicerequest);
I found out that the create function only returns an Empty Datatype
I expected to get the id of the created device. The function create should return a type of sth like createdeviceresponse.
I think there is an error in the protobuf
Component | Version |
---|---|
ChirpStack API | v3.12.4 |
I want to suggest to the community the generation of python packages in the betterproto format. This format is more robust for python development, and up to date regarding the norm.
Provide to the developpers a new way to interact with the chirpstack api
A new docker/Makefile could be created to generate in the python directory new module named chirpstack_api_betterproto
Yes ! Of course !
Hi,
This existing chirpstack-api
contains support to build the api's using Docker, and the makefile
also contains support for docker compose; but not Ubuntu.
Previous versions of chirpstack-api
contained support for Ubuntu in Makefile
-->
Our network servers and application server are deployed on ubuntu servers only, that is why we are dependent on Ubuntu. It would be really great if you could continue the support on Ubuntu.
When I try to connect with MQTT on my C# program and then want to read on the topic "application/123/device/+/event/up
and parse the received bytes as UTF-8 string and then parse it with the google protobuf parser, then I get the following exception:
Google.Protobuf.InvalidProtocolBufferException: Invalid base64 data
---> System.FormatException: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
It happens on this field: gw.UplinkRXInfo.uplink_id
with this data: d902040a-4859-41e3-aacc-a3f79de22e12
C# example:
string json = @"{""applicationID"":""4"",""applicationName"":""WetterStation"",""deviceName"":""0XXXXXXXXXXXX"",""devEUI"":""0101010101010101"",""rxInfo"":[{""gatewayID"":""1234567889141422"",""uplinkID"":""d902040a-4859-41e3-aacc-a3f79de22e12"",""name"":""XXXXXXXXXXXXX"",""time"":""2021-07-27T18:19:23.776381Z"",""rssi"":-106,""loRaSNR"":4,""location"":{""latitude"":54.31039,""longitude"":9.66927,""altitude"":228}},{""gatewayID"":""0000000000000000"",""uplinkID"":""11740492-1111-2222-3333-44444444444"",""name"":""xxxxxxxxxxx"",""time"":""2021-07-27T18:19:23.778124Z"",""rssi"":-114,""loRaSNR"":2,""location"":{""latitude"":0.00000,""longitude"":0.00000,""altitude"":43}}],""txInfo"":{""frequency"":868100000,""dr"":5},""adr"":false,""fCnt"":8706,""fPort"":1,""data"":""dGVzdA=="",""object"":{""Counter"":[299],""Voltage"":[3.406]}}";
UplinkEvent.Parser.ParseJson(json);
When serializing the UplinkEvent in the application server it should parse it as base64 OR make gw.UplinkRXInfo.uplink_id a string:
In gw.proto:
string uplink_id = 16 [json_name = "uplinkID"];
Hi!
I have a question about the tagsMap on a Gateway object in the chirpstack-api for JS.
While there is getters and setters for gatewayId, name, etc., there is no setter for tagsMap. Is this intended, or has it been missed out? :-)?
It's the same case with Metadata.
Kind regards.
Hi,
i use access to API by adding authorization with value Bearer
to GET request. generate for organization (not root).
Feature Request
Have Python stubs where programmers can communicate with chirpstack api. I would like to make this contribution and I am in the middle of generating the stubs. However, I do have some questions regarding how to generate and structure files.
How would you manage the as as a keyword in Python?
When I try to import the files, I got an invalid syntax error due the use of "as" that in this case it's a reserved keyword in Pyhton, when generating the client code.
How would be the tree structure folder you expect to have for python folder?
Currently, this is the output that I got, this is something that you would like to sort in a way that can fit with the current js and rust folders?
src
└── gen
├── as_pb
│ ├── as
│ │ ├── as_pb2_grpc.py
│ │ └── as_pb2.py
│ ├── external
│ │ └── api
│ │ └── as
│ │ └── external
│ │ └── api
│ │ ├── application_pb2_grpc.py
│ │ ├── application_pb2.py
│ │ ├── device_pb2_grpc.py
│ │ ├── device_pb2.py
│ │ ├── deviceProfile_pb2_grpc.py
│ │ ├── deviceProfile_pb2.py
│ │ ├── deviceQueue_pb2_grpc.py
│ │ ├── deviceQueue_pb2.py
│ │ ├── frameLog_pb2_grpc.py
│ │ ├── frameLog_pb2.py
│ │ ├── fuotaDeployment_pb2_grpc.py
│ │ ├── fuotaDeployment_pb2.py
│ │ ├── gateway_pb2_grpc.py
│ │ ├── gateway_pb2.py
│ │ ├── gatewayProfile_pb2_grpc.py
│ │ ├── gatewayProfile_pb2.py
│ │ ├── internal_pb2_grpc.py
│ │ ├── internal_pb2.py
│ │ ├── multicastGroup_pb2_grpc.py
│ │ ├── multicastGroup_pb2.py
│ │ ├── networkServer_pb2_grpc.py
│ │ ├── networkServer_pb2.py
│ │ ├── organization_pb2_grpc.py
│ │ ├── organization_pb2.py
│ │ ├── profiles_pb2_grpc.py
│ │ ├── profiles_pb2.py
│ │ ├── serviceProfile_pb2_grpc.py
│ │ ├── serviceProfile_pb2.py
│ │ ├── user_pb2_grpc.py
│ │ └── user_pb2.py
│ └── integration
│ └── as
│ └── integration
│ └── integration_pb2.py
├── common
│ └── common
│ └── common_pb2.py
├── geo
│ └── geo
│ ├── geo_pb2_grpc.py
│ └── geo_pb2.py
├── gw
│ └── gw
│ └── gw_pb2.py
├── nc
│ └── nc
│ ├── nc_pb2_grpc.py
│ └── nc_pb2.py
├── ns
│ └── ns
│ ├── ns_pb2_grpc.py
│ ├── ns_pb2.py
│ └── profiles_pb2.py
└── protobuf
└── google
└── protobuf
└── empty_pb2.py
Not Required
Not Required
Not Required
Could you share your log output?
Not Required
I wanted to use the proto fuota api at https://github.com/brocaar/chirpstack-api/blob/master/protobuf/fuota/fuota.proto, but it was missing from the python package here. Then I compiled the python files myself but the option --grpc_python_out=src
was missing in the makefile so no FUOTAServerServiceStub is generated. I don't know if this was intentional.
Use the fuota API for the chirpstack-fuota-server in Python the same way as in the application-server and network-server.
Steps:
Component | Version |
---|---|
ChirpStack API | v3.9.4 |
Compare:
https://github.com/brocaar/chirpstack-api/blob/master/go/as/external/internal.pb.go#L695
to
https://github.com/brocaar/chirpstack-application-server/blob/master/api/internal.pb.go#L690
This results in errors like the following:
"rpc error: code = Unimplemented desc = unknown service external.InternalService"
I would like to see the option for a C# namespace, so underneath the java option something this:
option csharp_namespace = "Chirpstack.Api.As";
Unfortunately, we are not able to define a base namespace in C# and Api.DeviceService
is not a really good, distinguishable name for it, I think. Every time there is a new version of your API I add it with a tool, but it would be quite nice if I could keep the files as they are, and I am certain that people using C# will benefit from it.
I can do it on my own and make a PR if it's wanted.
Also, I could create a sample C# client if wanted
gRPC supports PHP, so this should just be a case of generating client code for PHP.
I'm currently building a Laravel app that integrates with Chirpstack to communicate with IoT sensors out in the field. Having a gRPC client for Chirpstack would simplify things since I'm effectively writing a client from scratch using the REST API:
<?php
namespace App\Services;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
class Chirpstack
{
public function listDevices(): array
{
return $this->http()
->get('devices')
->throw()
->json();
}
public function getDevice(string $deviceEui): array
{
return $this->http()
->get("devices/{$deviceEui}")
->throw()
->json();
}
public function enqueueOnDeviceQueue(string $deviceEui, string $data, int $lorawanPort): array
{
return $this->http()
->post("devices/{$deviceEui}/queue", [
'deviceQueueItem' => [
'data' => $data,
'fPort' => $lorawanPort,
],
])
->throw()
->json();
}
protected function http(): PendingRequest
{
return Http::baseUrl(Str::finish(config('services.chirpstack.base_uri'), '/') . 'api')
->withHeaders([
'Grpc-Metadata-Authorization' => 'Bearer ' . config('services.chirpstack.auth_token'),
]);
}
}
Basically the same as the clients for the other supported languages?
I'm happy to give it a go, but I've never worked with gRPC before
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.