Compare commits

...

6 Commits

Author SHA1 Message Date
Orne Brocaar
e56530a620 Implement Blynk integration. 2025-08-22 16:01:27 +01:00
Orne Brocaar
4b068ea1c3 Add Blynk integration web-interface components. 2025-08-21 14:36:42 +01:00
Orne Brocaar
78e426963e Add Blynk integration API. 2025-08-21 14:36:42 +01:00
Orne Brocaar
050c2b37f3 Fix tokio_reactor_trait version mismatch in amqp integration.
Fixes #730 #733.
2025-08-21 14:26:06 +01:00
Orne Brocaar
1783a2b97e Fix missing field in mqtt struct. 2025-08-21 14:24:44 +01:00
Orne Brocaar
97af1a456f Implement using fPort returned by js codec.
This adds support for using the fPort returned by the encodeDownlink
codec function. In case this function does not return the fPort, the
fPort value of the downlink command will be used.
2025-08-18 12:06:56 +01:00
27 changed files with 1777 additions and 216 deletions

11
Cargo.lock generated
View File

@@ -866,6 +866,7 @@ dependencies = [
"tower-http",
"tracing",
"tracing-subscriber",
"url",
"urlencoding",
"uuid",
"validator",
@@ -3810,11 +3811,13 @@ dependencies = [
[[package]]
name = "reactor-trait"
version = "2.0.0"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b2eb4ff39ed91c79034b2856a73b07bc8afd752c981bc4433bcbeff531e275a"
checksum = "51d05d2072db44c9e2769ee9e700ec5e56330500b1753ab114d4eeeecacf81db"
dependencies = [
"async-trait",
"executor-trait",
"flume",
"futures-core",
"futures-io",
]
@@ -5069,9 +5072,9 @@ dependencies = [
[[package]]
name = "tokio-reactor-trait"
version = "2.0.0"
version = "3.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "890b2de29a909d511eaaabb0405f72d5c4df3ce35a24aeaf94974037699b5a81"
checksum = "a342ef9732e1c59a80093a47dc8a9831ca66fab2b3d2f1fb17498dde72a4c731"
dependencies = [
"async-trait",
"futures-core",

View File

@@ -83,6 +83,7 @@ const (
IntegrationKind_PILOT_THINGS IntegrationKind = 8
IntegrationKind_MQTT_GLOBAL IntegrationKind = 9
IntegrationKind_IFTTT IntegrationKind = 10
IntegrationKind_BLYNK IntegrationKind = 11
)
// Enum value maps for IntegrationKind.
@@ -98,6 +99,7 @@ var (
8: "PILOT_THINGS",
9: "MQTT_GLOBAL",
10: "IFTTT",
11: "BLYNK",
}
IntegrationKind_value = map[string]int32{
"HTTP": 0,
@@ -110,6 +112,7 @@ var (
"PILOT_THINGS": 8,
"MQTT_GLOBAL": 9,
"IFTTT": 10,
"BLYNK": 11,
}
)
@@ -3735,6 +3738,285 @@ func (x *DeleteIftttIntegrationRequest) GetApplicationId() string {
return ""
}
type BlynkIntegration struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Application ID (UUID).
ApplicationId string `protobuf:"bytes,1,opt,name=application_id,json=applicationId,proto3" json:"application_id,omitempty"`
// Blynk integration token.
Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *BlynkIntegration) Reset() {
*x = BlynkIntegration{}
mi := &file_api_application_proto_msgTypes[67]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *BlynkIntegration) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BlynkIntegration) ProtoMessage() {}
func (x *BlynkIntegration) ProtoReflect() protoreflect.Message {
mi := &file_api_application_proto_msgTypes[67]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BlynkIntegration.ProtoReflect.Descriptor instead.
func (*BlynkIntegration) Descriptor() ([]byte, []int) {
return file_api_application_proto_rawDescGZIP(), []int{67}
}
func (x *BlynkIntegration) GetApplicationId() string {
if x != nil {
return x.ApplicationId
}
return ""
}
func (x *BlynkIntegration) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
type CreateBlynkIntegrationRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Integration object to create.
Integration *BlynkIntegration `protobuf:"bytes,1,opt,name=integration,proto3" json:"integration,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CreateBlynkIntegrationRequest) Reset() {
*x = CreateBlynkIntegrationRequest{}
mi := &file_api_application_proto_msgTypes[68]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CreateBlynkIntegrationRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateBlynkIntegrationRequest) ProtoMessage() {}
func (x *CreateBlynkIntegrationRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_application_proto_msgTypes[68]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateBlynkIntegrationRequest.ProtoReflect.Descriptor instead.
func (*CreateBlynkIntegrationRequest) Descriptor() ([]byte, []int) {
return file_api_application_proto_rawDescGZIP(), []int{68}
}
func (x *CreateBlynkIntegrationRequest) GetIntegration() *BlynkIntegration {
if x != nil {
return x.Integration
}
return nil
}
type GetBlynkIntegrationRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Application ID (UUID).
ApplicationId string `protobuf:"bytes,1,opt,name=application_id,json=applicationId,proto3" json:"application_id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetBlynkIntegrationRequest) Reset() {
*x = GetBlynkIntegrationRequest{}
mi := &file_api_application_proto_msgTypes[69]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetBlynkIntegrationRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetBlynkIntegrationRequest) ProtoMessage() {}
func (x *GetBlynkIntegrationRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_application_proto_msgTypes[69]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetBlynkIntegrationRequest.ProtoReflect.Descriptor instead.
func (*GetBlynkIntegrationRequest) Descriptor() ([]byte, []int) {
return file_api_application_proto_rawDescGZIP(), []int{69}
}
func (x *GetBlynkIntegrationRequest) GetApplicationId() string {
if x != nil {
return x.ApplicationId
}
return ""
}
type GetBlynkIntegrationResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Integration object.
Integration *BlynkIntegration `protobuf:"bytes,1,opt,name=integration,proto3" json:"integration,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetBlynkIntegrationResponse) Reset() {
*x = GetBlynkIntegrationResponse{}
mi := &file_api_application_proto_msgTypes[70]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetBlynkIntegrationResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetBlynkIntegrationResponse) ProtoMessage() {}
func (x *GetBlynkIntegrationResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_application_proto_msgTypes[70]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetBlynkIntegrationResponse.ProtoReflect.Descriptor instead.
func (*GetBlynkIntegrationResponse) Descriptor() ([]byte, []int) {
return file_api_application_proto_rawDescGZIP(), []int{70}
}
func (x *GetBlynkIntegrationResponse) GetIntegration() *BlynkIntegration {
if x != nil {
return x.Integration
}
return nil
}
type UpdateBlynkIntegrationRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Integration object to update.
Integration *BlynkIntegration `protobuf:"bytes,1,opt,name=integration,proto3" json:"integration,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *UpdateBlynkIntegrationRequest) Reset() {
*x = UpdateBlynkIntegrationRequest{}
mi := &file_api_application_proto_msgTypes[71]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *UpdateBlynkIntegrationRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateBlynkIntegrationRequest) ProtoMessage() {}
func (x *UpdateBlynkIntegrationRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_application_proto_msgTypes[71]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateBlynkIntegrationRequest.ProtoReflect.Descriptor instead.
func (*UpdateBlynkIntegrationRequest) Descriptor() ([]byte, []int) {
return file_api_application_proto_rawDescGZIP(), []int{71}
}
func (x *UpdateBlynkIntegrationRequest) GetIntegration() *BlynkIntegration {
if x != nil {
return x.Integration
}
return nil
}
type DeleteBlynkIntegrationRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Application ID (UUID).
ApplicationId string `protobuf:"bytes,1,opt,name=application_id,json=applicationId,proto3" json:"application_id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *DeleteBlynkIntegrationRequest) Reset() {
*x = DeleteBlynkIntegrationRequest{}
mi := &file_api_application_proto_msgTypes[72]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *DeleteBlynkIntegrationRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeleteBlynkIntegrationRequest) ProtoMessage() {}
func (x *DeleteBlynkIntegrationRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_application_proto_msgTypes[72]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DeleteBlynkIntegrationRequest.ProtoReflect.Descriptor instead.
func (*DeleteBlynkIntegrationRequest) Descriptor() ([]byte, []int) {
return file_api_application_proto_rawDescGZIP(), []int{72}
}
func (x *DeleteBlynkIntegrationRequest) GetApplicationId() string {
if x != nil {
return x.ApplicationId
}
return ""
}
type GenerateMqttIntegrationClientCertificateRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Application ID (UUID).
@@ -3745,7 +4027,7 @@ type GenerateMqttIntegrationClientCertificateRequest struct {
func (x *GenerateMqttIntegrationClientCertificateRequest) Reset() {
*x = GenerateMqttIntegrationClientCertificateRequest{}
mi := &file_api_application_proto_msgTypes[67]
mi := &file_api_application_proto_msgTypes[73]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3757,7 +4039,7 @@ func (x *GenerateMqttIntegrationClientCertificateRequest) String() string {
func (*GenerateMqttIntegrationClientCertificateRequest) ProtoMessage() {}
func (x *GenerateMqttIntegrationClientCertificateRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_application_proto_msgTypes[67]
mi := &file_api_application_proto_msgTypes[73]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3770,7 +4052,7 @@ func (x *GenerateMqttIntegrationClientCertificateRequest) ProtoReflect() protore
// Deprecated: Use GenerateMqttIntegrationClientCertificateRequest.ProtoReflect.Descriptor instead.
func (*GenerateMqttIntegrationClientCertificateRequest) Descriptor() ([]byte, []int) {
return file_api_application_proto_rawDescGZIP(), []int{67}
return file_api_application_proto_rawDescGZIP(), []int{73}
}
func (x *GenerateMqttIntegrationClientCertificateRequest) GetApplicationId() string {
@@ -3796,7 +4078,7 @@ type GenerateMqttIntegrationClientCertificateResponse struct {
func (x *GenerateMqttIntegrationClientCertificateResponse) Reset() {
*x = GenerateMqttIntegrationClientCertificateResponse{}
mi := &file_api_application_proto_msgTypes[68]
mi := &file_api_application_proto_msgTypes[74]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3808,7 +4090,7 @@ func (x *GenerateMqttIntegrationClientCertificateResponse) String() string {
func (*GenerateMqttIntegrationClientCertificateResponse) ProtoMessage() {}
func (x *GenerateMqttIntegrationClientCertificateResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_application_proto_msgTypes[68]
mi := &file_api_application_proto_msgTypes[74]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3821,7 +4103,7 @@ func (x *GenerateMqttIntegrationClientCertificateResponse) ProtoReflect() protor
// Deprecated: Use GenerateMqttIntegrationClientCertificateResponse.ProtoReflect.Descriptor instead.
func (*GenerateMqttIntegrationClientCertificateResponse) Descriptor() ([]byte, []int) {
return file_api_application_proto_rawDescGZIP(), []int{68}
return file_api_application_proto_rawDescGZIP(), []int{74}
}
func (x *GenerateMqttIntegrationClientCertificateResponse) GetTlsCert() string {
@@ -3864,7 +4146,7 @@ type ApplicationDeviceProfileListItem struct {
func (x *ApplicationDeviceProfileListItem) Reset() {
*x = ApplicationDeviceProfileListItem{}
mi := &file_api_application_proto_msgTypes[69]
mi := &file_api_application_proto_msgTypes[75]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3876,7 +4158,7 @@ func (x *ApplicationDeviceProfileListItem) String() string {
func (*ApplicationDeviceProfileListItem) ProtoMessage() {}
func (x *ApplicationDeviceProfileListItem) ProtoReflect() protoreflect.Message {
mi := &file_api_application_proto_msgTypes[69]
mi := &file_api_application_proto_msgTypes[75]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3889,7 +4171,7 @@ func (x *ApplicationDeviceProfileListItem) ProtoReflect() protoreflect.Message {
// Deprecated: Use ApplicationDeviceProfileListItem.ProtoReflect.Descriptor instead.
func (*ApplicationDeviceProfileListItem) Descriptor() ([]byte, []int) {
return file_api_application_proto_rawDescGZIP(), []int{69}
return file_api_application_proto_rawDescGZIP(), []int{75}
}
func (x *ApplicationDeviceProfileListItem) GetId() string {
@@ -3916,7 +4198,7 @@ type ListApplicationDeviceProfilesRequest struct {
func (x *ListApplicationDeviceProfilesRequest) Reset() {
*x = ListApplicationDeviceProfilesRequest{}
mi := &file_api_application_proto_msgTypes[70]
mi := &file_api_application_proto_msgTypes[76]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3928,7 +4210,7 @@ func (x *ListApplicationDeviceProfilesRequest) String() string {
func (*ListApplicationDeviceProfilesRequest) ProtoMessage() {}
func (x *ListApplicationDeviceProfilesRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_application_proto_msgTypes[70]
mi := &file_api_application_proto_msgTypes[76]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3941,7 +4223,7 @@ func (x *ListApplicationDeviceProfilesRequest) ProtoReflect() protoreflect.Messa
// Deprecated: Use ListApplicationDeviceProfilesRequest.ProtoReflect.Descriptor instead.
func (*ListApplicationDeviceProfilesRequest) Descriptor() ([]byte, []int) {
return file_api_application_proto_rawDescGZIP(), []int{70}
return file_api_application_proto_rawDescGZIP(), []int{76}
}
func (x *ListApplicationDeviceProfilesRequest) GetApplicationId() string {
@@ -3961,7 +4243,7 @@ type ListApplicationDeviceProfilesResponse struct {
func (x *ListApplicationDeviceProfilesResponse) Reset() {
*x = ListApplicationDeviceProfilesResponse{}
mi := &file_api_application_proto_msgTypes[71]
mi := &file_api_application_proto_msgTypes[77]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3973,7 +4255,7 @@ func (x *ListApplicationDeviceProfilesResponse) String() string {
func (*ListApplicationDeviceProfilesResponse) ProtoMessage() {}
func (x *ListApplicationDeviceProfilesResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_application_proto_msgTypes[71]
mi := &file_api_application_proto_msgTypes[77]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3986,7 +4268,7 @@ func (x *ListApplicationDeviceProfilesResponse) ProtoReflect() protoreflect.Mess
// Deprecated: Use ListApplicationDeviceProfilesResponse.ProtoReflect.Descriptor instead.
func (*ListApplicationDeviceProfilesResponse) Descriptor() ([]byte, []int) {
return file_api_application_proto_rawDescGZIP(), []int{71}
return file_api_application_proto_rawDescGZIP(), []int{77}
}
func (x *ListApplicationDeviceProfilesResponse) GetResult() []*ApplicationDeviceProfileListItem {
@@ -4008,7 +4290,7 @@ type ApplicationDeviceTagListItem struct {
func (x *ApplicationDeviceTagListItem) Reset() {
*x = ApplicationDeviceTagListItem{}
mi := &file_api_application_proto_msgTypes[72]
mi := &file_api_application_proto_msgTypes[78]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4020,7 +4302,7 @@ func (x *ApplicationDeviceTagListItem) String() string {
func (*ApplicationDeviceTagListItem) ProtoMessage() {}
func (x *ApplicationDeviceTagListItem) ProtoReflect() protoreflect.Message {
mi := &file_api_application_proto_msgTypes[72]
mi := &file_api_application_proto_msgTypes[78]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4033,7 +4315,7 @@ func (x *ApplicationDeviceTagListItem) ProtoReflect() protoreflect.Message {
// Deprecated: Use ApplicationDeviceTagListItem.ProtoReflect.Descriptor instead.
func (*ApplicationDeviceTagListItem) Descriptor() ([]byte, []int) {
return file_api_application_proto_rawDescGZIP(), []int{72}
return file_api_application_proto_rawDescGZIP(), []int{78}
}
func (x *ApplicationDeviceTagListItem) GetKey() string {
@@ -4060,7 +4342,7 @@ type ListApplicationDeviceTagsRequest struct {
func (x *ListApplicationDeviceTagsRequest) Reset() {
*x = ListApplicationDeviceTagsRequest{}
mi := &file_api_application_proto_msgTypes[73]
mi := &file_api_application_proto_msgTypes[79]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4072,7 +4354,7 @@ func (x *ListApplicationDeviceTagsRequest) String() string {
func (*ListApplicationDeviceTagsRequest) ProtoMessage() {}
func (x *ListApplicationDeviceTagsRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_application_proto_msgTypes[73]
mi := &file_api_application_proto_msgTypes[79]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4085,7 +4367,7 @@ func (x *ListApplicationDeviceTagsRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ListApplicationDeviceTagsRequest.ProtoReflect.Descriptor instead.
func (*ListApplicationDeviceTagsRequest) Descriptor() ([]byte, []int) {
return file_api_application_proto_rawDescGZIP(), []int{73}
return file_api_application_proto_rawDescGZIP(), []int{79}
}
func (x *ListApplicationDeviceTagsRequest) GetApplicationId() string {
@@ -4105,7 +4387,7 @@ type ListApplicationDeviceTagsResponse struct {
func (x *ListApplicationDeviceTagsResponse) Reset() {
*x = ListApplicationDeviceTagsResponse{}
mi := &file_api_application_proto_msgTypes[74]
mi := &file_api_application_proto_msgTypes[80]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4117,7 +4399,7 @@ func (x *ListApplicationDeviceTagsResponse) String() string {
func (*ListApplicationDeviceTagsResponse) ProtoMessage() {}
func (x *ListApplicationDeviceTagsResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_application_proto_msgTypes[74]
mi := &file_api_application_proto_msgTypes[80]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4130,7 +4412,7 @@ func (x *ListApplicationDeviceTagsResponse) ProtoReflect() protoreflect.Message
// Deprecated: Use ListApplicationDeviceTagsResponse.ProtoReflect.Descriptor instead.
func (*ListApplicationDeviceTagsResponse) Descriptor() ([]byte, []int) {
return file_api_application_proto_rawDescGZIP(), []int{74}
return file_api_application_proto_rawDescGZIP(), []int{80}
}
func (x *ListApplicationDeviceTagsResponse) GetResult() []*ApplicationDeviceTagListItem {
@@ -4342,6 +4624,19 @@ const file_api_application_proto_rawDesc = "" +
"\x1dUpdateIftttIntegrationRequest\x127\n" +
"\vintegration\x18\x01 \x01(\v2\x15.api.IftttIntegrationR\vintegration\"F\n" +
"\x1dDeleteIftttIntegrationRequest\x12%\n" +
"\x0eapplication_id\x18\x01 \x01(\tR\rapplicationId\"O\n" +
"\x10BlynkIntegration\x12%\n" +
"\x0eapplication_id\x18\x01 \x01(\tR\rapplicationId\x12\x14\n" +
"\x05token\x18\x02 \x01(\tR\x05token\"X\n" +
"\x1dCreateBlynkIntegrationRequest\x127\n" +
"\vintegration\x18\x01 \x01(\v2\x15.api.BlynkIntegrationR\vintegration\"C\n" +
"\x1aGetBlynkIntegrationRequest\x12%\n" +
"\x0eapplication_id\x18\x01 \x01(\tR\rapplicationId\"V\n" +
"\x1bGetBlynkIntegrationResponse\x127\n" +
"\vintegration\x18\x01 \x01(\v2\x15.api.BlynkIntegrationR\vintegration\"X\n" +
"\x1dUpdateBlynkIntegrationRequest\x127\n" +
"\vintegration\x18\x01 \x01(\v2\x15.api.BlynkIntegrationR\vintegration\"F\n" +
"\x1dDeleteBlynkIntegrationRequest\x12%\n" +
"\x0eapplication_id\x18\x01 \x01(\tR\rapplicationId\"X\n" +
"/GenerateMqttIntegrationClientCertificateRequest\x12%\n" +
"\x0eapplication_id\x18\x01 \x01(\tR\rapplicationId\"\xba\x01\n" +
@@ -4367,7 +4662,7 @@ const file_api_application_proto_rawDesc = "" +
"\x06result\x18\x01 \x03(\v2!.api.ApplicationDeviceTagListItemR\x06result*\"\n" +
"\bEncoding\x12\b\n" +
"\x04JSON\x10\x00\x12\f\n" +
"\bPROTOBUF\x10\x01*\xaf\x01\n" +
"\bPROTOBUF\x10\x01*\xba\x01\n" +
"\x0fIntegrationKind\x12\b\n" +
"\x04HTTP\x10\x00\x12\r\n" +
"\tINFLUX_DB\x10\x01\x12\x10\n" +
@@ -4380,7 +4675,8 @@ const file_api_application_proto_rawDesc = "" +
"\fPILOT_THINGS\x10\b\x12\x0f\n" +
"\vMQTT_GLOBAL\x10\t\x12\t\n" +
"\x05IFTTT\x10\n" +
"*?\n" +
"\x12\t\n" +
"\x05BLYNK\x10\v*?\n" +
"\x11InfluxDbPrecision\x12\x06\n" +
"\x02NS\x10\x00\x12\x05\n" +
"\x01U\x10\x01\x12\x06\n" +
@@ -4392,7 +4688,7 @@ const file_api_application_proto_rawDesc = "" +
"\n" +
"INFLUXDB_1\x10\x00\x12\x0e\n" +
"\n" +
"INFLUXDB_2\x10\x012\xce9\n" +
"INFLUXDB_2\x10\x012\xc8>\n" +
"\x12ApplicationService\x12e\n" +
"\x06Create\x12\x1d.api.CreateApplicationRequest\x1a\x1e.api.CreateApplicationResponse\"\x1c\x82\xd3\xe4\x93\x02\x16:\x01*\"\x11/api/applications\x12^\n" +
"\x03Get\x12\x1a.api.GetApplicationRequest\x1a\x1b.api.GetApplicationResponse\"\x1e\x82\xd3\xe4\x93\x02\x18\x12\x16/api/applications/{id}\x12n\n" +
@@ -4435,7 +4731,11 @@ const file_api_application_proto_rawDesc = "" +
"\x16CreateIftttIntegration\x12\".api.CreateIftttIntegrationRequest\x1a\x16.google.protobuf.Empty\"L\x82\xd3\xe4\x93\x02F:\x01*\"A/api/applications/{integration.application_id}/integrations/ifttt\x12\x97\x01\n" +
"\x13GetIftttIntegration\x12\x1f.api.GetIftttIntegrationRequest\x1a .api.GetIftttIntegrationResponse\"=\x82\xd3\xe4\x93\x027\x125/api/applications/{application_id}/integrations/ifttt\x12\xa2\x01\n" +
"\x16UpdateIftttIntegration\x12\".api.UpdateIftttIntegrationRequest\x1a\x16.google.protobuf.Empty\"L\x82\xd3\xe4\x93\x02F:\x01*\x1aA/api/applications/{integration.application_id}/integrations/ifttt\x12\x93\x01\n" +
"\x16DeleteIftttIntegration\x12\".api.DeleteIftttIntegrationRequest\x1a\x16.google.protobuf.Empty\"=\x82\xd3\xe4\x93\x027*5/api/applications/{application_id}/integrations/ifttt\x12\xe1\x01\n" +
"\x16DeleteIftttIntegration\x12\".api.DeleteIftttIntegrationRequest\x1a\x16.google.protobuf.Empty\"=\x82\xd3\xe4\x93\x027*5/api/applications/{application_id}/integrations/ifttt\x12\xa2\x01\n" +
"\x16CreateBlynkIntegration\x12\".api.CreateBlynkIntegrationRequest\x1a\x16.google.protobuf.Empty\"L\x82\xd3\xe4\x93\x02F:\x01*\"A/api/applications/{integration.application_id}/integrations/blynk\x12\x97\x01\n" +
"\x13GetBlynkIntegration\x12\x1f.api.GetBlynkIntegrationRequest\x1a .api.GetBlynkIntegrationResponse\"=\x82\xd3\xe4\x93\x027\x125/api/applications/{application_id}/integrations/blynk\x12\xa2\x01\n" +
"\x16UpdateBlynkIntegration\x12\".api.UpdateBlynkIntegrationRequest\x1a\x16.google.protobuf.Empty\"L\x82\xd3\xe4\x93\x02F:\x01*\x1aA/api/applications/{integration.application_id}/integrations/blynk\x12\x93\x01\n" +
"\x16DeleteBlynkIntegration\x12\".api.DeleteBlynkIntegrationRequest\x1a\x16.google.protobuf.Empty\"=\x82\xd3\xe4\x93\x027*5/api/applications/{application_id}/integrations/blynk\x12\xe1\x01\n" +
"(GenerateMqttIntegrationClientCertificate\x124.api.GenerateMqttIntegrationClientCertificateRequest\x1a5.api.GenerateMqttIntegrationClientCertificateResponse\"H\x82\xd3\xe4\x93\x02B\"@/api/applications/{application_id}/integrations/mqtt/certificate\x12\xa7\x01\n" +
"\x12ListDeviceProfiles\x12).api.ListApplicationDeviceProfilesRequest\x1a*.api.ListApplicationDeviceProfilesResponse\":\x82\xd3\xe4\x93\x024\x122/api/applications/{application_id}/device-profiles\x12\x97\x01\n" +
"\x0eListDeviceTags\x12%.api.ListApplicationDeviceTagsRequest\x1a&.api.ListApplicationDeviceTagsResponse\"6\x82\xd3\xe4\x93\x020\x12./api/applications/{application_id}/device-tagsB\x96\x01\n" +
@@ -4454,7 +4754,7 @@ func file_api_application_proto_rawDescGZIP() []byte {
}
var file_api_application_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
var file_api_application_proto_msgTypes = make([]protoimpl.MessageInfo, 77)
var file_api_application_proto_msgTypes = make([]protoimpl.MessageInfo, 83)
var file_api_application_proto_goTypes = []any{
(Encoding)(0), // 0: api.Encoding
(IntegrationKind)(0), // 1: api.IntegrationKind
@@ -4527,163 +4827,180 @@ var file_api_application_proto_goTypes = []any{
(*GetIftttIntegrationResponse)(nil), // 68: api.GetIftttIntegrationResponse
(*UpdateIftttIntegrationRequest)(nil), // 69: api.UpdateIftttIntegrationRequest
(*DeleteIftttIntegrationRequest)(nil), // 70: api.DeleteIftttIntegrationRequest
(*GenerateMqttIntegrationClientCertificateRequest)(nil), // 71: api.GenerateMqttIntegrationClientCertificateRequest
(*GenerateMqttIntegrationClientCertificateResponse)(nil), // 72: api.GenerateMqttIntegrationClientCertificateResponse
(*ApplicationDeviceProfileListItem)(nil), // 73: api.ApplicationDeviceProfileListItem
(*ListApplicationDeviceProfilesRequest)(nil), // 74: api.ListApplicationDeviceProfilesRequest
(*ListApplicationDeviceProfilesResponse)(nil), // 75: api.ListApplicationDeviceProfilesResponse
(*ApplicationDeviceTagListItem)(nil), // 76: api.ApplicationDeviceTagListItem
(*ListApplicationDeviceTagsRequest)(nil), // 77: api.ListApplicationDeviceTagsRequest
(*ListApplicationDeviceTagsResponse)(nil), // 78: api.ListApplicationDeviceTagsResponse
nil, // 79: api.Application.TagsEntry
nil, // 80: api.HttpIntegration.HeadersEntry
(*timestamppb.Timestamp)(nil), // 81: google.protobuf.Timestamp
(*emptypb.Empty)(nil), // 82: google.protobuf.Empty
(*BlynkIntegration)(nil), // 71: api.BlynkIntegration
(*CreateBlynkIntegrationRequest)(nil), // 72: api.CreateBlynkIntegrationRequest
(*GetBlynkIntegrationRequest)(nil), // 73: api.GetBlynkIntegrationRequest
(*GetBlynkIntegrationResponse)(nil), // 74: api.GetBlynkIntegrationResponse
(*UpdateBlynkIntegrationRequest)(nil), // 75: api.UpdateBlynkIntegrationRequest
(*DeleteBlynkIntegrationRequest)(nil), // 76: api.DeleteBlynkIntegrationRequest
(*GenerateMqttIntegrationClientCertificateRequest)(nil), // 77: api.GenerateMqttIntegrationClientCertificateRequest
(*GenerateMqttIntegrationClientCertificateResponse)(nil), // 78: api.GenerateMqttIntegrationClientCertificateResponse
(*ApplicationDeviceProfileListItem)(nil), // 79: api.ApplicationDeviceProfileListItem
(*ListApplicationDeviceProfilesRequest)(nil), // 80: api.ListApplicationDeviceProfilesRequest
(*ListApplicationDeviceProfilesResponse)(nil), // 81: api.ListApplicationDeviceProfilesResponse
(*ApplicationDeviceTagListItem)(nil), // 82: api.ApplicationDeviceTagListItem
(*ListApplicationDeviceTagsRequest)(nil), // 83: api.ListApplicationDeviceTagsRequest
(*ListApplicationDeviceTagsResponse)(nil), // 84: api.ListApplicationDeviceTagsResponse
nil, // 85: api.Application.TagsEntry
nil, // 86: api.HttpIntegration.HeadersEntry
(*timestamppb.Timestamp)(nil), // 87: google.protobuf.Timestamp
(*emptypb.Empty)(nil), // 88: google.protobuf.Empty
}
var file_api_application_proto_depIdxs = []int32{
79, // 0: api.Application.tags:type_name -> api.Application.TagsEntry
81, // 1: api.ApplicationListItem.created_at:type_name -> google.protobuf.Timestamp
81, // 2: api.ApplicationListItem.updated_at:type_name -> google.protobuf.Timestamp
4, // 3: api.CreateApplicationRequest.application:type_name -> api.Application
4, // 4: api.GetApplicationResponse.application:type_name -> api.Application
81, // 5: api.GetApplicationResponse.created_at:type_name -> google.protobuf.Timestamp
81, // 6: api.GetApplicationResponse.updated_at:type_name -> google.protobuf.Timestamp
4, // 7: api.UpdateApplicationRequest.application:type_name -> api.Application
5, // 8: api.ListApplicationsResponse.result:type_name -> api.ApplicationListItem
1, // 9: api.IntegrationListItem.kind:type_name -> api.IntegrationKind
15, // 10: api.ListIntegrationsResponse.result:type_name -> api.IntegrationListItem
80, // 11: api.HttpIntegration.headers:type_name -> api.HttpIntegration.HeadersEntry
0, // 12: api.HttpIntegration.encoding:type_name -> api.Encoding
17, // 13: api.CreateHttpIntegrationRequest.integration:type_name -> api.HttpIntegration
17, // 14: api.GetHttpIntegrationResponse.integration:type_name -> api.HttpIntegration
17, // 15: api.UpdateHttpIntegrationRequest.integration:type_name -> api.HttpIntegration
2, // 16: api.InfluxDbIntegration.precision:type_name -> api.InfluxDbPrecision
3, // 17: api.InfluxDbIntegration.version:type_name -> api.InfluxDbVersion
23, // 18: api.CreateInfluxDbIntegrationRequest.integration:type_name -> api.InfluxDbIntegration
23, // 19: api.GetInfluxDbIntegrationResponse.integration:type_name -> api.InfluxDbIntegration
23, // 20: api.UpdateInfluxDbIntegrationRequest.integration:type_name -> api.InfluxDbIntegration
29, // 21: api.CreateThingsBoardIntegrationRequest.integration:type_name -> api.ThingsBoardIntegration
29, // 22: api.GetThingsBoardIntegrationResponse.integration:type_name -> api.ThingsBoardIntegration
29, // 23: api.UpdateThingsBoardIntegrationRequest.integration:type_name -> api.ThingsBoardIntegration
35, // 24: api.CreateMyDevicesIntegrationRequest.integration:type_name -> api.MyDevicesIntegration
35, // 25: api.GetMyDevicesIntegrationResponse.integration:type_name -> api.MyDevicesIntegration
35, // 26: api.UpdateMyDevicesIntegrationRequest.integration:type_name -> api.MyDevicesIntegration
0, // 27: api.GcpPubSubIntegration.encoding:type_name -> api.Encoding
41, // 28: api.CreateGcpPubSubIntegrationRequest.integration:type_name -> api.GcpPubSubIntegration
41, // 29: api.GetGcpPubSubIntegrationResponse.integration:type_name -> api.GcpPubSubIntegration
41, // 30: api.UpdateGcpPubSubIntegrationRequest.integration:type_name -> api.GcpPubSubIntegration
0, // 31: api.AwsSnsIntegration.encoding:type_name -> api.Encoding
47, // 32: api.CreateAwsSnsIntegrationRequest.integration:type_name -> api.AwsSnsIntegration
47, // 33: api.GetAwsSnsIntegrationResponse.integration:type_name -> api.AwsSnsIntegration
47, // 34: api.UpdateAwsSnsIntegrationRequest.integration:type_name -> api.AwsSnsIntegration
0, // 35: api.AzureServiceBusIntegration.encoding:type_name -> api.Encoding
53, // 36: api.CreateAzureServiceBusIntegrationRequest.integration:type_name -> api.AzureServiceBusIntegration
53, // 37: api.GetAzureServiceBusIntegrationResponse.integration:type_name -> api.AzureServiceBusIntegration
53, // 38: api.UpdateAzureServiceBusIntegrationRequest.integration:type_name -> api.AzureServiceBusIntegration
59, // 39: api.CreatePilotThingsIntegrationRequest.integration:type_name -> api.PilotThingsIntegration
59, // 40: api.GetPilotThingsIntegrationResponse.integration:type_name -> api.PilotThingsIntegration
59, // 41: api.UpdatePilotThingsIntegrationRequest.integration:type_name -> api.PilotThingsIntegration
65, // 42: api.CreateIftttIntegrationRequest.integration:type_name -> api.IftttIntegration
65, // 43: api.GetIftttIntegrationResponse.integration:type_name -> api.IftttIntegration
65, // 44: api.UpdateIftttIntegrationRequest.integration:type_name -> api.IftttIntegration
81, // 45: api.GenerateMqttIntegrationClientCertificateResponse.expires_at:type_name -> google.protobuf.Timestamp
73, // 46: api.ListApplicationDeviceProfilesResponse.result:type_name -> api.ApplicationDeviceProfileListItem
76, // 47: api.ListApplicationDeviceTagsResponse.result:type_name -> api.ApplicationDeviceTagListItem
6, // 48: api.ApplicationService.Create:input_type -> api.CreateApplicationRequest
8, // 49: api.ApplicationService.Get:input_type -> api.GetApplicationRequest
10, // 50: api.ApplicationService.Update:input_type -> api.UpdateApplicationRequest
11, // 51: api.ApplicationService.Delete:input_type -> api.DeleteApplicationRequest
12, // 52: api.ApplicationService.List:input_type -> api.ListApplicationsRequest
14, // 53: api.ApplicationService.ListIntegrations:input_type -> api.ListIntegrationsRequest
18, // 54: api.ApplicationService.CreateHttpIntegration:input_type -> api.CreateHttpIntegrationRequest
19, // 55: api.ApplicationService.GetHttpIntegration:input_type -> api.GetHttpIntegrationRequest
21, // 56: api.ApplicationService.UpdateHttpIntegration:input_type -> api.UpdateHttpIntegrationRequest
22, // 57: api.ApplicationService.DeleteHttpIntegration:input_type -> api.DeleteHttpIntegrationRequest
24, // 58: api.ApplicationService.CreateInfluxDbIntegration:input_type -> api.CreateInfluxDbIntegrationRequest
25, // 59: api.ApplicationService.GetInfluxDbIntegration:input_type -> api.GetInfluxDbIntegrationRequest
27, // 60: api.ApplicationService.UpdateInfluxDbIntegration:input_type -> api.UpdateInfluxDbIntegrationRequest
28, // 61: api.ApplicationService.DeleteInfluxDbIntegration:input_type -> api.DeleteInfluxDbIntegrationRequest
30, // 62: api.ApplicationService.CreateThingsBoardIntegration:input_type -> api.CreateThingsBoardIntegrationRequest
31, // 63: api.ApplicationService.GetThingsBoardIntegration:input_type -> api.GetThingsBoardIntegrationRequest
33, // 64: api.ApplicationService.UpdateThingsBoardIntegration:input_type -> api.UpdateThingsBoardIntegrationRequest
34, // 65: api.ApplicationService.DeleteThingsBoardIntegration:input_type -> api.DeleteThingsBoardIntegrationRequest
36, // 66: api.ApplicationService.CreateMyDevicesIntegration:input_type -> api.CreateMyDevicesIntegrationRequest
37, // 67: api.ApplicationService.GetMyDevicesIntegration:input_type -> api.GetMyDevicesIntegrationRequest
39, // 68: api.ApplicationService.UpdateMyDevicesIntegration:input_type -> api.UpdateMyDevicesIntegrationRequest
40, // 69: api.ApplicationService.DeleteMyDevicesIntegration:input_type -> api.DeleteMyDevicesIntegrationRequest
42, // 70: api.ApplicationService.CreateGcpPubSubIntegration:input_type -> api.CreateGcpPubSubIntegrationRequest
43, // 71: api.ApplicationService.GetGcpPubSubIntegration:input_type -> api.GetGcpPubSubIntegrationRequest
45, // 72: api.ApplicationService.UpdateGcpPubSubIntegration:input_type -> api.UpdateGcpPubSubIntegrationRequest
46, // 73: api.ApplicationService.DeleteGcpPubSubIntegration:input_type -> api.DeleteGcpPubSubIntegrationRequest
48, // 74: api.ApplicationService.CreateAwsSnsIntegration:input_type -> api.CreateAwsSnsIntegrationRequest
49, // 75: api.ApplicationService.GetAwsSnsIntegration:input_type -> api.GetAwsSnsIntegrationRequest
51, // 76: api.ApplicationService.UpdateAwsSnsIntegration:input_type -> api.UpdateAwsSnsIntegrationRequest
52, // 77: api.ApplicationService.DeleteAwsSnsIntegration:input_type -> api.DeleteAwsSnsIntegrationRequest
54, // 78: api.ApplicationService.CreateAzureServiceBusIntegration:input_type -> api.CreateAzureServiceBusIntegrationRequest
55, // 79: api.ApplicationService.GetAzureServiceBusIntegration:input_type -> api.GetAzureServiceBusIntegrationRequest
57, // 80: api.ApplicationService.UpdateAzureServiceBusIntegration:input_type -> api.UpdateAzureServiceBusIntegrationRequest
58, // 81: api.ApplicationService.DeleteAzureServiceBusIntegration:input_type -> api.DeleteAzureServiceBusIntegrationRequest
60, // 82: api.ApplicationService.CreatePilotThingsIntegration:input_type -> api.CreatePilotThingsIntegrationRequest
61, // 83: api.ApplicationService.GetPilotThingsIntegration:input_type -> api.GetPilotThingsIntegrationRequest
63, // 84: api.ApplicationService.UpdatePilotThingsIntegration:input_type -> api.UpdatePilotThingsIntegrationRequest
64, // 85: api.ApplicationService.DeletePilotThingsIntegration:input_type -> api.DeletePilotThingsIntegrationRequest
66, // 86: api.ApplicationService.CreateIftttIntegration:input_type -> api.CreateIftttIntegrationRequest
67, // 87: api.ApplicationService.GetIftttIntegration:input_type -> api.GetIftttIntegrationRequest
69, // 88: api.ApplicationService.UpdateIftttIntegration:input_type -> api.UpdateIftttIntegrationRequest
70, // 89: api.ApplicationService.DeleteIftttIntegration:input_type -> api.DeleteIftttIntegrationRequest
71, // 90: api.ApplicationService.GenerateMqttIntegrationClientCertificate:input_type -> api.GenerateMqttIntegrationClientCertificateRequest
74, // 91: api.ApplicationService.ListDeviceProfiles:input_type -> api.ListApplicationDeviceProfilesRequest
77, // 92: api.ApplicationService.ListDeviceTags:input_type -> api.ListApplicationDeviceTagsRequest
7, // 93: api.ApplicationService.Create:output_type -> api.CreateApplicationResponse
9, // 94: api.ApplicationService.Get:output_type -> api.GetApplicationResponse
82, // 95: api.ApplicationService.Update:output_type -> google.protobuf.Empty
82, // 96: api.ApplicationService.Delete:output_type -> google.protobuf.Empty
13, // 97: api.ApplicationService.List:output_type -> api.ListApplicationsResponse
16, // 98: api.ApplicationService.ListIntegrations:output_type -> api.ListIntegrationsResponse
82, // 99: api.ApplicationService.CreateHttpIntegration:output_type -> google.protobuf.Empty
20, // 100: api.ApplicationService.GetHttpIntegration:output_type -> api.GetHttpIntegrationResponse
82, // 101: api.ApplicationService.UpdateHttpIntegration:output_type -> google.protobuf.Empty
82, // 102: api.ApplicationService.DeleteHttpIntegration:output_type -> google.protobuf.Empty
82, // 103: api.ApplicationService.CreateInfluxDbIntegration:output_type -> google.protobuf.Empty
26, // 104: api.ApplicationService.GetInfluxDbIntegration:output_type -> api.GetInfluxDbIntegrationResponse
82, // 105: api.ApplicationService.UpdateInfluxDbIntegration:output_type -> google.protobuf.Empty
82, // 106: api.ApplicationService.DeleteInfluxDbIntegration:output_type -> google.protobuf.Empty
82, // 107: api.ApplicationService.CreateThingsBoardIntegration:output_type -> google.protobuf.Empty
32, // 108: api.ApplicationService.GetThingsBoardIntegration:output_type -> api.GetThingsBoardIntegrationResponse
82, // 109: api.ApplicationService.UpdateThingsBoardIntegration:output_type -> google.protobuf.Empty
82, // 110: api.ApplicationService.DeleteThingsBoardIntegration:output_type -> google.protobuf.Empty
82, // 111: api.ApplicationService.CreateMyDevicesIntegration:output_type -> google.protobuf.Empty
38, // 112: api.ApplicationService.GetMyDevicesIntegration:output_type -> api.GetMyDevicesIntegrationResponse
82, // 113: api.ApplicationService.UpdateMyDevicesIntegration:output_type -> google.protobuf.Empty
82, // 114: api.ApplicationService.DeleteMyDevicesIntegration:output_type -> google.protobuf.Empty
82, // 115: api.ApplicationService.CreateGcpPubSubIntegration:output_type -> google.protobuf.Empty
44, // 116: api.ApplicationService.GetGcpPubSubIntegration:output_type -> api.GetGcpPubSubIntegrationResponse
82, // 117: api.ApplicationService.UpdateGcpPubSubIntegration:output_type -> google.protobuf.Empty
82, // 118: api.ApplicationService.DeleteGcpPubSubIntegration:output_type -> google.protobuf.Empty
82, // 119: api.ApplicationService.CreateAwsSnsIntegration:output_type -> google.protobuf.Empty
50, // 120: api.ApplicationService.GetAwsSnsIntegration:output_type -> api.GetAwsSnsIntegrationResponse
82, // 121: api.ApplicationService.UpdateAwsSnsIntegration:output_type -> google.protobuf.Empty
82, // 122: api.ApplicationService.DeleteAwsSnsIntegration:output_type -> google.protobuf.Empty
82, // 123: api.ApplicationService.CreateAzureServiceBusIntegration:output_type -> google.protobuf.Empty
56, // 124: api.ApplicationService.GetAzureServiceBusIntegration:output_type -> api.GetAzureServiceBusIntegrationResponse
82, // 125: api.ApplicationService.UpdateAzureServiceBusIntegration:output_type -> google.protobuf.Empty
82, // 126: api.ApplicationService.DeleteAzureServiceBusIntegration:output_type -> google.protobuf.Empty
82, // 127: api.ApplicationService.CreatePilotThingsIntegration:output_type -> google.protobuf.Empty
62, // 128: api.ApplicationService.GetPilotThingsIntegration:output_type -> api.GetPilotThingsIntegrationResponse
82, // 129: api.ApplicationService.UpdatePilotThingsIntegration:output_type -> google.protobuf.Empty
82, // 130: api.ApplicationService.DeletePilotThingsIntegration:output_type -> google.protobuf.Empty
82, // 131: api.ApplicationService.CreateIftttIntegration:output_type -> google.protobuf.Empty
68, // 132: api.ApplicationService.GetIftttIntegration:output_type -> api.GetIftttIntegrationResponse
82, // 133: api.ApplicationService.UpdateIftttIntegration:output_type -> google.protobuf.Empty
82, // 134: api.ApplicationService.DeleteIftttIntegration:output_type -> google.protobuf.Empty
72, // 135: api.ApplicationService.GenerateMqttIntegrationClientCertificate:output_type -> api.GenerateMqttIntegrationClientCertificateResponse
75, // 136: api.ApplicationService.ListDeviceProfiles:output_type -> api.ListApplicationDeviceProfilesResponse
78, // 137: api.ApplicationService.ListDeviceTags:output_type -> api.ListApplicationDeviceTagsResponse
93, // [93:138] is the sub-list for method output_type
48, // [48:93] is the sub-list for method input_type
48, // [48:48] is the sub-list for extension type_name
48, // [48:48] is the sub-list for extension extendee
0, // [0:48] is the sub-list for field type_name
85, // 0: api.Application.tags:type_name -> api.Application.TagsEntry
87, // 1: api.ApplicationListItem.created_at:type_name -> google.protobuf.Timestamp
87, // 2: api.ApplicationListItem.updated_at:type_name -> google.protobuf.Timestamp
4, // 3: api.CreateApplicationRequest.application:type_name -> api.Application
4, // 4: api.GetApplicationResponse.application:type_name -> api.Application
87, // 5: api.GetApplicationResponse.created_at:type_name -> google.protobuf.Timestamp
87, // 6: api.GetApplicationResponse.updated_at:type_name -> google.protobuf.Timestamp
4, // 7: api.UpdateApplicationRequest.application:type_name -> api.Application
5, // 8: api.ListApplicationsResponse.result:type_name -> api.ApplicationListItem
1, // 9: api.IntegrationListItem.kind:type_name -> api.IntegrationKind
15, // 10: api.ListIntegrationsResponse.result:type_name -> api.IntegrationListItem
86, // 11: api.HttpIntegration.headers:type_name -> api.HttpIntegration.HeadersEntry
0, // 12: api.HttpIntegration.encoding:type_name -> api.Encoding
17, // 13: api.CreateHttpIntegrationRequest.integration:type_name -> api.HttpIntegration
17, // 14: api.GetHttpIntegrationResponse.integration:type_name -> api.HttpIntegration
17, // 15: api.UpdateHttpIntegrationRequest.integration:type_name -> api.HttpIntegration
2, // 16: api.InfluxDbIntegration.precision:type_name -> api.InfluxDbPrecision
3, // 17: api.InfluxDbIntegration.version:type_name -> api.InfluxDbVersion
23, // 18: api.CreateInfluxDbIntegrationRequest.integration:type_name -> api.InfluxDbIntegration
23, // 19: api.GetInfluxDbIntegrationResponse.integration:type_name -> api.InfluxDbIntegration
23, // 20: api.UpdateInfluxDbIntegrationRequest.integration:type_name -> api.InfluxDbIntegration
29, // 21: api.CreateThingsBoardIntegrationRequest.integration:type_name -> api.ThingsBoardIntegration
29, // 22: api.GetThingsBoardIntegrationResponse.integration:type_name -> api.ThingsBoardIntegration
29, // 23: api.UpdateThingsBoardIntegrationRequest.integration:type_name -> api.ThingsBoardIntegration
35, // 24: api.CreateMyDevicesIntegrationRequest.integration:type_name -> api.MyDevicesIntegration
35, // 25: api.GetMyDevicesIntegrationResponse.integration:type_name -> api.MyDevicesIntegration
35, // 26: api.UpdateMyDevicesIntegrationRequest.integration:type_name -> api.MyDevicesIntegration
0, // 27: api.GcpPubSubIntegration.encoding:type_name -> api.Encoding
41, // 28: api.CreateGcpPubSubIntegrationRequest.integration:type_name -> api.GcpPubSubIntegration
41, // 29: api.GetGcpPubSubIntegrationResponse.integration:type_name -> api.GcpPubSubIntegration
41, // 30: api.UpdateGcpPubSubIntegrationRequest.integration:type_name -> api.GcpPubSubIntegration
0, // 31: api.AwsSnsIntegration.encoding:type_name -> api.Encoding
47, // 32: api.CreateAwsSnsIntegrationRequest.integration:type_name -> api.AwsSnsIntegration
47, // 33: api.GetAwsSnsIntegrationResponse.integration:type_name -> api.AwsSnsIntegration
47, // 34: api.UpdateAwsSnsIntegrationRequest.integration:type_name -> api.AwsSnsIntegration
0, // 35: api.AzureServiceBusIntegration.encoding:type_name -> api.Encoding
53, // 36: api.CreateAzureServiceBusIntegrationRequest.integration:type_name -> api.AzureServiceBusIntegration
53, // 37: api.GetAzureServiceBusIntegrationResponse.integration:type_name -> api.AzureServiceBusIntegration
53, // 38: api.UpdateAzureServiceBusIntegrationRequest.integration:type_name -> api.AzureServiceBusIntegration
59, // 39: api.CreatePilotThingsIntegrationRequest.integration:type_name -> api.PilotThingsIntegration
59, // 40: api.GetPilotThingsIntegrationResponse.integration:type_name -> api.PilotThingsIntegration
59, // 41: api.UpdatePilotThingsIntegrationRequest.integration:type_name -> api.PilotThingsIntegration
65, // 42: api.CreateIftttIntegrationRequest.integration:type_name -> api.IftttIntegration
65, // 43: api.GetIftttIntegrationResponse.integration:type_name -> api.IftttIntegration
65, // 44: api.UpdateIftttIntegrationRequest.integration:type_name -> api.IftttIntegration
71, // 45: api.CreateBlynkIntegrationRequest.integration:type_name -> api.BlynkIntegration
71, // 46: api.GetBlynkIntegrationResponse.integration:type_name -> api.BlynkIntegration
71, // 47: api.UpdateBlynkIntegrationRequest.integration:type_name -> api.BlynkIntegration
87, // 48: api.GenerateMqttIntegrationClientCertificateResponse.expires_at:type_name -> google.protobuf.Timestamp
79, // 49: api.ListApplicationDeviceProfilesResponse.result:type_name -> api.ApplicationDeviceProfileListItem
82, // 50: api.ListApplicationDeviceTagsResponse.result:type_name -> api.ApplicationDeviceTagListItem
6, // 51: api.ApplicationService.Create:input_type -> api.CreateApplicationRequest
8, // 52: api.ApplicationService.Get:input_type -> api.GetApplicationRequest
10, // 53: api.ApplicationService.Update:input_type -> api.UpdateApplicationRequest
11, // 54: api.ApplicationService.Delete:input_type -> api.DeleteApplicationRequest
12, // 55: api.ApplicationService.List:input_type -> api.ListApplicationsRequest
14, // 56: api.ApplicationService.ListIntegrations:input_type -> api.ListIntegrationsRequest
18, // 57: api.ApplicationService.CreateHttpIntegration:input_type -> api.CreateHttpIntegrationRequest
19, // 58: api.ApplicationService.GetHttpIntegration:input_type -> api.GetHttpIntegrationRequest
21, // 59: api.ApplicationService.UpdateHttpIntegration:input_type -> api.UpdateHttpIntegrationRequest
22, // 60: api.ApplicationService.DeleteHttpIntegration:input_type -> api.DeleteHttpIntegrationRequest
24, // 61: api.ApplicationService.CreateInfluxDbIntegration:input_type -> api.CreateInfluxDbIntegrationRequest
25, // 62: api.ApplicationService.GetInfluxDbIntegration:input_type -> api.GetInfluxDbIntegrationRequest
27, // 63: api.ApplicationService.UpdateInfluxDbIntegration:input_type -> api.UpdateInfluxDbIntegrationRequest
28, // 64: api.ApplicationService.DeleteInfluxDbIntegration:input_type -> api.DeleteInfluxDbIntegrationRequest
30, // 65: api.ApplicationService.CreateThingsBoardIntegration:input_type -> api.CreateThingsBoardIntegrationRequest
31, // 66: api.ApplicationService.GetThingsBoardIntegration:input_type -> api.GetThingsBoardIntegrationRequest
33, // 67: api.ApplicationService.UpdateThingsBoardIntegration:input_type -> api.UpdateThingsBoardIntegrationRequest
34, // 68: api.ApplicationService.DeleteThingsBoardIntegration:input_type -> api.DeleteThingsBoardIntegrationRequest
36, // 69: api.ApplicationService.CreateMyDevicesIntegration:input_type -> api.CreateMyDevicesIntegrationRequest
37, // 70: api.ApplicationService.GetMyDevicesIntegration:input_type -> api.GetMyDevicesIntegrationRequest
39, // 71: api.ApplicationService.UpdateMyDevicesIntegration:input_type -> api.UpdateMyDevicesIntegrationRequest
40, // 72: api.ApplicationService.DeleteMyDevicesIntegration:input_type -> api.DeleteMyDevicesIntegrationRequest
42, // 73: api.ApplicationService.CreateGcpPubSubIntegration:input_type -> api.CreateGcpPubSubIntegrationRequest
43, // 74: api.ApplicationService.GetGcpPubSubIntegration:input_type -> api.GetGcpPubSubIntegrationRequest
45, // 75: api.ApplicationService.UpdateGcpPubSubIntegration:input_type -> api.UpdateGcpPubSubIntegrationRequest
46, // 76: api.ApplicationService.DeleteGcpPubSubIntegration:input_type -> api.DeleteGcpPubSubIntegrationRequest
48, // 77: api.ApplicationService.CreateAwsSnsIntegration:input_type -> api.CreateAwsSnsIntegrationRequest
49, // 78: api.ApplicationService.GetAwsSnsIntegration:input_type -> api.GetAwsSnsIntegrationRequest
51, // 79: api.ApplicationService.UpdateAwsSnsIntegration:input_type -> api.UpdateAwsSnsIntegrationRequest
52, // 80: api.ApplicationService.DeleteAwsSnsIntegration:input_type -> api.DeleteAwsSnsIntegrationRequest
54, // 81: api.ApplicationService.CreateAzureServiceBusIntegration:input_type -> api.CreateAzureServiceBusIntegrationRequest
55, // 82: api.ApplicationService.GetAzureServiceBusIntegration:input_type -> api.GetAzureServiceBusIntegrationRequest
57, // 83: api.ApplicationService.UpdateAzureServiceBusIntegration:input_type -> api.UpdateAzureServiceBusIntegrationRequest
58, // 84: api.ApplicationService.DeleteAzureServiceBusIntegration:input_type -> api.DeleteAzureServiceBusIntegrationRequest
60, // 85: api.ApplicationService.CreatePilotThingsIntegration:input_type -> api.CreatePilotThingsIntegrationRequest
61, // 86: api.ApplicationService.GetPilotThingsIntegration:input_type -> api.GetPilotThingsIntegrationRequest
63, // 87: api.ApplicationService.UpdatePilotThingsIntegration:input_type -> api.UpdatePilotThingsIntegrationRequest
64, // 88: api.ApplicationService.DeletePilotThingsIntegration:input_type -> api.DeletePilotThingsIntegrationRequest
66, // 89: api.ApplicationService.CreateIftttIntegration:input_type -> api.CreateIftttIntegrationRequest
67, // 90: api.ApplicationService.GetIftttIntegration:input_type -> api.GetIftttIntegrationRequest
69, // 91: api.ApplicationService.UpdateIftttIntegration:input_type -> api.UpdateIftttIntegrationRequest
70, // 92: api.ApplicationService.DeleteIftttIntegration:input_type -> api.DeleteIftttIntegrationRequest
72, // 93: api.ApplicationService.CreateBlynkIntegration:input_type -> api.CreateBlynkIntegrationRequest
73, // 94: api.ApplicationService.GetBlynkIntegration:input_type -> api.GetBlynkIntegrationRequest
75, // 95: api.ApplicationService.UpdateBlynkIntegration:input_type -> api.UpdateBlynkIntegrationRequest
76, // 96: api.ApplicationService.DeleteBlynkIntegration:input_type -> api.DeleteBlynkIntegrationRequest
77, // 97: api.ApplicationService.GenerateMqttIntegrationClientCertificate:input_type -> api.GenerateMqttIntegrationClientCertificateRequest
80, // 98: api.ApplicationService.ListDeviceProfiles:input_type -> api.ListApplicationDeviceProfilesRequest
83, // 99: api.ApplicationService.ListDeviceTags:input_type -> api.ListApplicationDeviceTagsRequest
7, // 100: api.ApplicationService.Create:output_type -> api.CreateApplicationResponse
9, // 101: api.ApplicationService.Get:output_type -> api.GetApplicationResponse
88, // 102: api.ApplicationService.Update:output_type -> google.protobuf.Empty
88, // 103: api.ApplicationService.Delete:output_type -> google.protobuf.Empty
13, // 104: api.ApplicationService.List:output_type -> api.ListApplicationsResponse
16, // 105: api.ApplicationService.ListIntegrations:output_type -> api.ListIntegrationsResponse
88, // 106: api.ApplicationService.CreateHttpIntegration:output_type -> google.protobuf.Empty
20, // 107: api.ApplicationService.GetHttpIntegration:output_type -> api.GetHttpIntegrationResponse
88, // 108: api.ApplicationService.UpdateHttpIntegration:output_type -> google.protobuf.Empty
88, // 109: api.ApplicationService.DeleteHttpIntegration:output_type -> google.protobuf.Empty
88, // 110: api.ApplicationService.CreateInfluxDbIntegration:output_type -> google.protobuf.Empty
26, // 111: api.ApplicationService.GetInfluxDbIntegration:output_type -> api.GetInfluxDbIntegrationResponse
88, // 112: api.ApplicationService.UpdateInfluxDbIntegration:output_type -> google.protobuf.Empty
88, // 113: api.ApplicationService.DeleteInfluxDbIntegration:output_type -> google.protobuf.Empty
88, // 114: api.ApplicationService.CreateThingsBoardIntegration:output_type -> google.protobuf.Empty
32, // 115: api.ApplicationService.GetThingsBoardIntegration:output_type -> api.GetThingsBoardIntegrationResponse
88, // 116: api.ApplicationService.UpdateThingsBoardIntegration:output_type -> google.protobuf.Empty
88, // 117: api.ApplicationService.DeleteThingsBoardIntegration:output_type -> google.protobuf.Empty
88, // 118: api.ApplicationService.CreateMyDevicesIntegration:output_type -> google.protobuf.Empty
38, // 119: api.ApplicationService.GetMyDevicesIntegration:output_type -> api.GetMyDevicesIntegrationResponse
88, // 120: api.ApplicationService.UpdateMyDevicesIntegration:output_type -> google.protobuf.Empty
88, // 121: api.ApplicationService.DeleteMyDevicesIntegration:output_type -> google.protobuf.Empty
88, // 122: api.ApplicationService.CreateGcpPubSubIntegration:output_type -> google.protobuf.Empty
44, // 123: api.ApplicationService.GetGcpPubSubIntegration:output_type -> api.GetGcpPubSubIntegrationResponse
88, // 124: api.ApplicationService.UpdateGcpPubSubIntegration:output_type -> google.protobuf.Empty
88, // 125: api.ApplicationService.DeleteGcpPubSubIntegration:output_type -> google.protobuf.Empty
88, // 126: api.ApplicationService.CreateAwsSnsIntegration:output_type -> google.protobuf.Empty
50, // 127: api.ApplicationService.GetAwsSnsIntegration:output_type -> api.GetAwsSnsIntegrationResponse
88, // 128: api.ApplicationService.UpdateAwsSnsIntegration:output_type -> google.protobuf.Empty
88, // 129: api.ApplicationService.DeleteAwsSnsIntegration:output_type -> google.protobuf.Empty
88, // 130: api.ApplicationService.CreateAzureServiceBusIntegration:output_type -> google.protobuf.Empty
56, // 131: api.ApplicationService.GetAzureServiceBusIntegration:output_type -> api.GetAzureServiceBusIntegrationResponse
88, // 132: api.ApplicationService.UpdateAzureServiceBusIntegration:output_type -> google.protobuf.Empty
88, // 133: api.ApplicationService.DeleteAzureServiceBusIntegration:output_type -> google.protobuf.Empty
88, // 134: api.ApplicationService.CreatePilotThingsIntegration:output_type -> google.protobuf.Empty
62, // 135: api.ApplicationService.GetPilotThingsIntegration:output_type -> api.GetPilotThingsIntegrationResponse
88, // 136: api.ApplicationService.UpdatePilotThingsIntegration:output_type -> google.protobuf.Empty
88, // 137: api.ApplicationService.DeletePilotThingsIntegration:output_type -> google.protobuf.Empty
88, // 138: api.ApplicationService.CreateIftttIntegration:output_type -> google.protobuf.Empty
68, // 139: api.ApplicationService.GetIftttIntegration:output_type -> api.GetIftttIntegrationResponse
88, // 140: api.ApplicationService.UpdateIftttIntegration:output_type -> google.protobuf.Empty
88, // 141: api.ApplicationService.DeleteIftttIntegration:output_type -> google.protobuf.Empty
88, // 142: api.ApplicationService.CreateBlynkIntegration:output_type -> google.protobuf.Empty
74, // 143: api.ApplicationService.GetBlynkIntegration:output_type -> api.GetBlynkIntegrationResponse
88, // 144: api.ApplicationService.UpdateBlynkIntegration:output_type -> google.protobuf.Empty
88, // 145: api.ApplicationService.DeleteBlynkIntegration:output_type -> google.protobuf.Empty
78, // 146: api.ApplicationService.GenerateMqttIntegrationClientCertificate:output_type -> api.GenerateMqttIntegrationClientCertificateResponse
81, // 147: api.ApplicationService.ListDeviceProfiles:output_type -> api.ListApplicationDeviceProfilesResponse
84, // 148: api.ApplicationService.ListDeviceTags:output_type -> api.ListApplicationDeviceTagsResponse
100, // [100:149] is the sub-list for method output_type
51, // [51:100] is the sub-list for method input_type
51, // [51:51] is the sub-list for extension type_name
51, // [51:51] is the sub-list for extension extendee
0, // [0:51] is the sub-list for field type_name
}
func init() { file_api_application_proto_init() }
@@ -4697,7 +5014,7 @@ func file_api_application_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_application_proto_rawDesc), len(file_api_application_proto_rawDesc)),
NumEnums: 4,
NumMessages: 77,
NumMessages: 83,
NumExtensions: 0,
NumServices: 1,
},

View File

@@ -62,6 +62,10 @@ const (
ApplicationService_GetIftttIntegration_FullMethodName = "/api.ApplicationService/GetIftttIntegration"
ApplicationService_UpdateIftttIntegration_FullMethodName = "/api.ApplicationService/UpdateIftttIntegration"
ApplicationService_DeleteIftttIntegration_FullMethodName = "/api.ApplicationService/DeleteIftttIntegration"
ApplicationService_CreateBlynkIntegration_FullMethodName = "/api.ApplicationService/CreateBlynkIntegration"
ApplicationService_GetBlynkIntegration_FullMethodName = "/api.ApplicationService/GetBlynkIntegration"
ApplicationService_UpdateBlynkIntegration_FullMethodName = "/api.ApplicationService/UpdateBlynkIntegration"
ApplicationService_DeleteBlynkIntegration_FullMethodName = "/api.ApplicationService/DeleteBlynkIntegration"
ApplicationService_GenerateMqttIntegrationClientCertificate_FullMethodName = "/api.ApplicationService/GenerateMqttIntegrationClientCertificate"
ApplicationService_ListDeviceProfiles_FullMethodName = "/api.ApplicationService/ListDeviceProfiles"
ApplicationService_ListDeviceTags_FullMethodName = "/api.ApplicationService/ListDeviceTags"
@@ -158,6 +162,14 @@ type ApplicationServiceClient interface {
UpdateIftttIntegration(ctx context.Context, in *UpdateIftttIntegrationRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// Delete IFTTT integration.
DeleteIftttIntegration(ctx context.Context, in *DeleteIftttIntegrationRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// Create Blynk integration.
CreateBlynkIntegration(ctx context.Context, in *CreateBlynkIntegrationRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// Get Blynk integration.
GetBlynkIntegration(ctx context.Context, in *GetBlynkIntegrationRequest, opts ...grpc.CallOption) (*GetBlynkIntegrationResponse, error)
// Update Blynk integration.
UpdateBlynkIntegration(ctx context.Context, in *UpdateBlynkIntegrationRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// Delete Blynk integration.
DeleteBlynkIntegration(ctx context.Context, in *DeleteBlynkIntegrationRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// Generates application ID specific client-certificate.
GenerateMqttIntegrationClientCertificate(ctx context.Context, in *GenerateMqttIntegrationClientCertificateRequest, opts ...grpc.CallOption) (*GenerateMqttIntegrationClientCertificateResponse, error)
// List device-profiles used within the given application.
@@ -594,6 +606,46 @@ func (c *applicationServiceClient) DeleteIftttIntegration(ctx context.Context, i
return out, nil
}
func (c *applicationServiceClient) CreateBlynkIntegration(ctx context.Context, in *CreateBlynkIntegrationRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, ApplicationService_CreateBlynkIntegration_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *applicationServiceClient) GetBlynkIntegration(ctx context.Context, in *GetBlynkIntegrationRequest, opts ...grpc.CallOption) (*GetBlynkIntegrationResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetBlynkIntegrationResponse)
err := c.cc.Invoke(ctx, ApplicationService_GetBlynkIntegration_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *applicationServiceClient) UpdateBlynkIntegration(ctx context.Context, in *UpdateBlynkIntegrationRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, ApplicationService_UpdateBlynkIntegration_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *applicationServiceClient) DeleteBlynkIntegration(ctx context.Context, in *DeleteBlynkIntegrationRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, ApplicationService_DeleteBlynkIntegration_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *applicationServiceClient) GenerateMqttIntegrationClientCertificate(ctx context.Context, in *GenerateMqttIntegrationClientCertificateRequest, opts ...grpc.CallOption) (*GenerateMqttIntegrationClientCertificateResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GenerateMqttIntegrationClientCertificateResponse)
@@ -715,6 +767,14 @@ type ApplicationServiceServer interface {
UpdateIftttIntegration(context.Context, *UpdateIftttIntegrationRequest) (*emptypb.Empty, error)
// Delete IFTTT integration.
DeleteIftttIntegration(context.Context, *DeleteIftttIntegrationRequest) (*emptypb.Empty, error)
// Create Blynk integration.
CreateBlynkIntegration(context.Context, *CreateBlynkIntegrationRequest) (*emptypb.Empty, error)
// Get Blynk integration.
GetBlynkIntegration(context.Context, *GetBlynkIntegrationRequest) (*GetBlynkIntegrationResponse, error)
// Update Blynk integration.
UpdateBlynkIntegration(context.Context, *UpdateBlynkIntegrationRequest) (*emptypb.Empty, error)
// Delete Blynk integration.
DeleteBlynkIntegration(context.Context, *DeleteBlynkIntegrationRequest) (*emptypb.Empty, error)
// Generates application ID specific client-certificate.
GenerateMqttIntegrationClientCertificate(context.Context, *GenerateMqttIntegrationClientCertificateRequest) (*GenerateMqttIntegrationClientCertificateResponse, error)
// List device-profiles used within the given application.
@@ -857,6 +917,18 @@ func (UnimplementedApplicationServiceServer) UpdateIftttIntegration(context.Cont
func (UnimplementedApplicationServiceServer) DeleteIftttIntegration(context.Context, *DeleteIftttIntegrationRequest) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteIftttIntegration not implemented")
}
func (UnimplementedApplicationServiceServer) CreateBlynkIntegration(context.Context, *CreateBlynkIntegrationRequest) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateBlynkIntegration not implemented")
}
func (UnimplementedApplicationServiceServer) GetBlynkIntegration(context.Context, *GetBlynkIntegrationRequest) (*GetBlynkIntegrationResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetBlynkIntegration not implemented")
}
func (UnimplementedApplicationServiceServer) UpdateBlynkIntegration(context.Context, *UpdateBlynkIntegrationRequest) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateBlynkIntegration not implemented")
}
func (UnimplementedApplicationServiceServer) DeleteBlynkIntegration(context.Context, *DeleteBlynkIntegrationRequest) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteBlynkIntegration not implemented")
}
func (UnimplementedApplicationServiceServer) GenerateMqttIntegrationClientCertificate(context.Context, *GenerateMqttIntegrationClientCertificateRequest) (*GenerateMqttIntegrationClientCertificateResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GenerateMqttIntegrationClientCertificate not implemented")
}
@@ -1643,6 +1715,78 @@ func _ApplicationService_DeleteIftttIntegration_Handler(srv interface{}, ctx con
return interceptor(ctx, in, info, handler)
}
func _ApplicationService_CreateBlynkIntegration_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateBlynkIntegrationRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ApplicationServiceServer).CreateBlynkIntegration(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ApplicationService_CreateBlynkIntegration_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ApplicationServiceServer).CreateBlynkIntegration(ctx, req.(*CreateBlynkIntegrationRequest))
}
return interceptor(ctx, in, info, handler)
}
func _ApplicationService_GetBlynkIntegration_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetBlynkIntegrationRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ApplicationServiceServer).GetBlynkIntegration(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ApplicationService_GetBlynkIntegration_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ApplicationServiceServer).GetBlynkIntegration(ctx, req.(*GetBlynkIntegrationRequest))
}
return interceptor(ctx, in, info, handler)
}
func _ApplicationService_UpdateBlynkIntegration_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateBlynkIntegrationRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ApplicationServiceServer).UpdateBlynkIntegration(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ApplicationService_UpdateBlynkIntegration_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ApplicationServiceServer).UpdateBlynkIntegration(ctx, req.(*UpdateBlynkIntegrationRequest))
}
return interceptor(ctx, in, info, handler)
}
func _ApplicationService_DeleteBlynkIntegration_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteBlynkIntegrationRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ApplicationServiceServer).DeleteBlynkIntegration(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ApplicationService_DeleteBlynkIntegration_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ApplicationServiceServer).DeleteBlynkIntegration(ctx, req.(*DeleteBlynkIntegrationRequest))
}
return interceptor(ctx, in, info, handler)
}
func _ApplicationService_GenerateMqttIntegrationClientCertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GenerateMqttIntegrationClientCertificateRequest)
if err := dec(in); err != nil {
@@ -1872,6 +2016,22 @@ var ApplicationService_ServiceDesc = grpc.ServiceDesc{
MethodName: "DeleteIftttIntegration",
Handler: _ApplicationService_DeleteIftttIntegration_Handler,
},
{
MethodName: "CreateBlynkIntegration",
Handler: _ApplicationService_CreateBlynkIntegration_Handler,
},
{
MethodName: "GetBlynkIntegration",
Handler: _ApplicationService_GetBlynkIntegration_Handler,
},
{
MethodName: "UpdateBlynkIntegration",
Handler: _ApplicationService_UpdateBlynkIntegration_Handler,
},
{
MethodName: "DeleteBlynkIntegration",
Handler: _ApplicationService_DeleteBlynkIntegration_Handler,
},
{
MethodName: "GenerateMqttIntegrationClientCertificate",
Handler: _ApplicationService_GenerateMqttIntegrationClientCertificate_Handler,

View File

@@ -1918,6 +1918,8 @@ type DeviceQueueItem struct {
// Confirmed.
Confirmed bool `protobuf:"varint,3,opt,name=confirmed,proto3" json:"confirmed,omitempty"`
// FPort (must be > 0).
// On enqueue and if using a JavaScript codec, this value might be
// automatically set by the codec function.
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.

View File

@@ -383,6 +383,40 @@ service ApplicationService {
};
}
// Create Blynk integration.
rpc CreateBlynkIntegration(CreateBlynkIntegrationRequest)
returns (google.protobuf.Empty) {
option (google.api.http) = {
post : "/api/applications/{integration.application_id}/integrations/blynk"
body : "*"
};
}
// Get Blynk integration.
rpc GetBlynkIntegration(GetBlynkIntegrationRequest)
returns (GetBlynkIntegrationResponse) {
option (google.api.http) = {
get : "/api/applications/{application_id}/integrations/blynk"
};
}
// Update Blynk integration.
rpc UpdateBlynkIntegration(UpdateBlynkIntegrationRequest)
returns (google.protobuf.Empty) {
option (google.api.http) = {
put : "/api/applications/{integration.application_id}/integrations/blynk"
body : "*"
};
}
// Delete Blynk integration.
rpc DeleteBlynkIntegration(DeleteBlynkIntegrationRequest)
returns (google.protobuf.Empty) {
option (google.api.http) = {
delete : "/api/applications/{application_id}/integrations/blynk"
};
}
// Generates application ID specific client-certificate.
rpc GenerateMqttIntegrationClientCertificate(
GenerateMqttIntegrationClientCertificateRequest)
@@ -423,6 +457,7 @@ enum IntegrationKind {
PILOT_THINGS = 8;
MQTT_GLOBAL = 9;
IFTTT = 10;
BLYNK = 11;
}
message Application {
@@ -954,6 +989,39 @@ message DeleteIftttIntegrationRequest {
string application_id = 1;
}
message BlynkIntegration {
// Application ID (UUID).
string application_id = 1;
// Blynk integration token.
string token = 2;
}
message CreateBlynkIntegrationRequest {
// Integration object to create.
BlynkIntegration integration = 1;
}
message GetBlynkIntegrationRequest {
// Application ID (UUID).
string application_id = 1;
}
message GetBlynkIntegrationResponse {
// Integration object.
BlynkIntegration integration = 1;
}
message UpdateBlynkIntegrationRequest {
// Integration object to update.
BlynkIntegration integration = 1;
}
message DeleteBlynkIntegrationRequest {
// Application ID (UUID).
string application_id = 1;
}
message GenerateMqttIntegrationClientCertificateRequest {
// Application ID (UUID).
string application_id = 1;

View File

@@ -543,6 +543,8 @@ message DeviceQueueItem {
bool confirmed = 3;
// FPort (must be > 0).
// On enqueue and if using a JavaScript codec, this value might be
// automatically set by the codec function.
uint32 f_port = 4;
// Data.

View File

@@ -383,6 +383,40 @@ service ApplicationService {
};
}
// Create Blynk integration.
rpc CreateBlynkIntegration(CreateBlynkIntegrationRequest)
returns (google.protobuf.Empty) {
option (google.api.http) = {
post : "/api/applications/{integration.application_id}/integrations/blynk"
body : "*"
};
}
// Get Blynk integration.
rpc GetBlynkIntegration(GetBlynkIntegrationRequest)
returns (GetBlynkIntegrationResponse) {
option (google.api.http) = {
get : "/api/applications/{application_id}/integrations/blynk"
};
}
// Update Blynk integration.
rpc UpdateBlynkIntegration(UpdateBlynkIntegrationRequest)
returns (google.protobuf.Empty) {
option (google.api.http) = {
put : "/api/applications/{integration.application_id}/integrations/blynk"
body : "*"
};
}
// Delete Blynk integration.
rpc DeleteBlynkIntegration(DeleteBlynkIntegrationRequest)
returns (google.protobuf.Empty) {
option (google.api.http) = {
delete : "/api/applications/{application_id}/integrations/blynk"
};
}
// Generates application ID specific client-certificate.
rpc GenerateMqttIntegrationClientCertificate(
GenerateMqttIntegrationClientCertificateRequest)
@@ -423,6 +457,7 @@ enum IntegrationKind {
PILOT_THINGS = 8;
MQTT_GLOBAL = 9;
IFTTT = 10;
BLYNK = 11;
}
message Application {
@@ -954,6 +989,39 @@ message DeleteIftttIntegrationRequest {
string application_id = 1;
}
message BlynkIntegration {
// Application ID (UUID).
string application_id = 1;
// Blynk integration token.
string token = 2;
}
message CreateBlynkIntegrationRequest {
// Integration object to create.
BlynkIntegration integration = 1;
}
message GetBlynkIntegrationRequest {
// Application ID (UUID).
string application_id = 1;
}
message GetBlynkIntegrationResponse {
// Integration object.
BlynkIntegration integration = 1;
}
message UpdateBlynkIntegrationRequest {
// Integration object to update.
BlynkIntegration integration = 1;
}
message DeleteBlynkIntegrationRequest {
// Application ID (UUID).
string application_id = 1;
}
message GenerateMqttIntegrationClientCertificateRequest {
// Application ID (UUID).
string application_id = 1;

View File

@@ -543,6 +543,8 @@ message DeviceQueueItem {
bool confirmed = 3;
// FPort (must be > 0).
// On enqueue and if using a JavaScript codec, this value might be
// automatically set by the codec function.
uint32 f_port = 4;
// Data.

View File

@@ -74,7 +74,7 @@
"rustls-native-certs",
] }
tokio-executor-trait = "2.1"
tokio-reactor-trait = "2.0"
tokio-reactor-trait = "3.8"
rdkafka = { version = "0.38", default-features = false, features = [
"tokio",
"cmake-build",
@@ -100,6 +100,7 @@
http-body = "1.0"
rust-embed = "8.7"
mime_guess = "2.0"
url = "2.5"
tower-http = { version = "0.6", features = ["trace", "auth"] }
# Error handling

View File

@@ -240,6 +240,7 @@ impl ApplicationService for Application {
}
application::IntegrationKind::PilotThings => api::IntegrationKind::PilotThings,
application::IntegrationKind::Ifttt => api::IntegrationKind::Ifttt,
application::IntegrationKind::Blynk => api::IntegrationKind::Blynk,
}
.into(),
})
@@ -1644,6 +1645,147 @@ impl ApplicationService for Application {
Ok(resp)
}
async fn create_blynk_integration(
&self,
request: Request<api::CreateBlynkIntegrationRequest>,
) -> Result<Response<()>, Status> {
let req_int = match &request.get_ref().integration {
Some(v) => v,
None => {
return Err(Status::invalid_argument("integration is missing"));
}
};
let app_id = Uuid::from_str(&req_int.application_id).map_err(|e| e.status())?;
self.validator
.validate(
request.extensions(),
validator::ValidateApplicationAccess::new(validator::Flag::Update, app_id),
)
.await?;
let _ = application::create_integration(application::Integration {
application_id: app_id.into(),
kind: application::IntegrationKind::Blynk,
configuration: application::IntegrationConfiguration::Blynk(
application::BlynkConfiguration {
token: req_int.token.clone(),
},
),
..Default::default()
})
.await
.map_err(|e| e.status())?;
let mut resp = Response::new(());
resp.metadata_mut().insert(
"x-log-application_id",
req_int.application_id.parse().unwrap(),
);
Ok(resp)
}
async fn get_blynk_integration(
&self,
request: Request<api::GetBlynkIntegrationRequest>,
) -> Result<Response<api::GetBlynkIntegrationResponse>, Status> {
let req = request.get_ref();
let app_id = Uuid::from_str(&req.application_id).map_err(|e| e.status())?;
self.validator
.validate(
request.extensions(),
validator::ValidateApplicationAccess::new(validator::Flag::Read, app_id),
)
.await?;
let i = application::get_integration(&app_id, application::IntegrationKind::Blynk)
.await
.map_err(|e| e.status())?;
if let application::IntegrationConfiguration::Blynk(conf) = &i.configuration {
let mut resp = Response::new(api::GetBlynkIntegrationResponse {
integration: Some(api::BlynkIntegration {
application_id: app_id.to_string(),
token: conf.token.clone(),
}),
});
resp.metadata_mut()
.insert("x-log-application_id", req.application_id.parse().unwrap());
Ok(resp)
} else {
Err(Status::internal("Integration has no Blynk configuration"))
}
}
async fn update_blynk_integration(
&self,
request: Request<api::UpdateBlynkIntegrationRequest>,
) -> Result<Response<()>, Status> {
let req_int = match &request.get_ref().integration {
Some(v) => v,
None => {
return Err(Status::invalid_argument("integration is missing"));
}
};
let app_id = Uuid::from_str(&req_int.application_id).map_err(|e| e.status())?;
self.validator
.validate(
request.extensions(),
validator::ValidateApplicationAccess::new(validator::Flag::Update, app_id),
)
.await?;
let _ = application::update_integration(application::Integration {
application_id: app_id.into(),
kind: application::IntegrationKind::Blynk,
configuration: application::IntegrationConfiguration::Blynk(
application::BlynkConfiguration {
token: req_int.token.clone(),
},
),
..Default::default()
})
.await
.map_err(|e| e.status())?;
let mut resp = Response::new(());
resp.metadata_mut().insert(
"x-log-application_id",
req_int.application_id.parse().unwrap(),
);
Ok(resp)
}
async fn delete_blynk_integration(
&self,
request: Request<api::DeleteBlynkIntegrationRequest>,
) -> Result<Response<()>, Status> {
let req = request.get_ref();
let app_id = Uuid::from_str(&req.application_id).map_err(|e| e.status())?;
self.validator
.validate(
request.extensions(),
validator::ValidateApplicationAccess::new(validator::Flag::Update, app_id),
)
.await?;
application::delete_integration(&app_id, application::IntegrationKind::Blynk)
.await
.map_err(|e| e.status())?;
let mut resp = Response::new(());
resp.metadata_mut()
.insert("x-log-application_id", req.application_id.parse().unwrap());
Ok(resp)
}
async fn generate_mqtt_integration_client_certificate(
&self,
request: Request<api::GenerateMqttIntegrationClientCertificateRequest>,
@@ -3148,4 +3290,122 @@ pub mod test {
list_resp
);
}
#[tokio::test]
async fn test_blynk_integration() {
let _guard = test::prepare().await;
let app = get_application().await;
let u = get_user().await;
let service = Application::new(RequestValidator::new());
// create
let create_req = get_request(
&u.id,
api::CreateBlynkIntegrationRequest {
integration: Some(api::BlynkIntegration {
application_id: app.id.to_string(),
token: "foobartoken".into(),
}),
},
);
let _ = service.create_blynk_integration(create_req).await.unwrap();
// get
let get_req = get_request(
&u.id,
api::GetBlynkIntegrationRequest {
application_id: app.id.to_string(),
},
);
let get_resp = service.get_blynk_integration(get_req).await.unwrap();
let get_resp = get_resp.get_ref();
assert_eq!(
Some(api::BlynkIntegration {
application_id: app.id.to_string(),
token: "foobartoken".into(),
}),
get_resp.integration
);
// update
let update_req = get_request(
&u.id,
api::UpdateBlynkIntegrationRequest {
integration: Some(api::BlynkIntegration {
application_id: app.id.to_string(),
token: "someothertoken".into(),
}),
},
);
let _ = service.update_blynk_integration(update_req).await.unwrap();
// get
let get_req = get_request(
&u.id,
api::GetBlynkIntegrationRequest {
application_id: app.id.to_string(),
},
);
let get_resp = service.get_blynk_integration(get_req).await.unwrap();
let get_resp = get_resp.get_ref();
assert_eq!(
Some(api::BlynkIntegration {
application_id: app.id.to_string(),
token: "someothertoken".into(),
}),
get_resp.integration
);
// list
let list_req = get_request(
&u.id,
api::ListIntegrationsRequest {
application_id: app.id.to_string(),
},
);
let list_resp = service.list_integrations(list_req).await.unwrap();
let list_resp = list_resp.get_ref();
assert_eq!(
&api::ListIntegrationsResponse {
total_count: 2,
result: vec![
api::IntegrationListItem {
kind: api::IntegrationKind::Blynk.into(),
},
api::IntegrationListItem {
kind: api::IntegrationKind::MqttGlobal.into(),
}
],
},
list_resp
);
// delete
let del_req = get_request(
&u.id,
api::DeleteBlynkIntegrationRequest {
application_id: app.id.to_string(),
},
);
let _ = service.delete_blynk_integration(del_req).await.unwrap();
// list
let list_req = get_request(
&u.id,
api::ListIntegrationsRequest {
application_id: app.id.to_string(),
},
);
let list_resp = service.list_integrations(list_req).await.unwrap();
let list_resp = list_resp.get_ref();
assert_eq!(
&api::ListIntegrationsResponse {
total_count: 1,
result: vec![api::IntegrationListItem {
kind: api::IntegrationKind::MqttGlobal.into(),
},],
},
list_resp
);
}
}

View File

@@ -1075,6 +1075,7 @@ impl DeviceService for Device {
.await?;
let mut data = req_qi.data.clone();
let mut f_port = req_qi.f_port as u8;
if let Some(obj) = &req_qi.object {
let dev = device::get(&dev_eui).await.map_err(|e| e.status())?;
@@ -1082,7 +1083,7 @@ impl DeviceService for Device {
.await
.map_err(|e| e.status())?;
data = codec::struct_to_binary(
(f_port, data) = codec::struct_to_binary(
dp.payload_codec_runtime,
req_qi.f_port as u8,
&dev.variables,
@@ -1096,7 +1097,7 @@ impl DeviceService for Device {
let qi = device_queue::DeviceQueueItem {
id: Uuid::new_v4().into(),
dev_eui,
f_port: req_qi.f_port as i16,
f_port: f_port as i16,
confirmed: req_qi.confirmed,
is_encrypted: req_qi.is_encrypted,
f_cnt_down: if req_qi.is_encrypted {

View File

@@ -110,7 +110,7 @@ pub async fn encode(
variables: &HashMap<String, String>,
encode_config: &str,
s: &prost_types::Struct,
) -> Result<Vec<u8>> {
) -> Result<(u8, Vec<u8>)> {
let conf = config::get();
let max_run_ts = SystemTime::now() + conf.codec.js.max_execution_time;
@@ -158,7 +158,6 @@ pub async fn encode(
let buff: rquickjs::Function = buff.get("Buffer")?;
let input = rquickjs::Object::new(ctx.clone())?;
input.set("fPort", f_port.into_js(&ctx)?)?;
input.set("variables", variables.into_js(&ctx)?)?;
input.set("data", convert::struct_to_rquickjs(&ctx, s))?;
@@ -186,10 +185,14 @@ pub async fn encode(
// Directly into u8 can result into the following error:
// Error converting from js 'float' into type 'i32'
let v: Vec<f64> = res.get("bytes")?;
let v: Vec<u8> = v.iter().map(|v| *v as u8).collect();
let b: Vec<f64> = res.get("bytes")?;
let b: Vec<u8> = b.iter().map(|v| *v as u8).collect();
Ok(v)
// Get fPort, or else fallback on provided fPort.
let f_port: f64 = res.get("fPort").unwrap_or_else(|_| f_port as f64);
let f_port = f_port as u8;
Ok((f_port, b))
})
}
@@ -388,8 +391,7 @@ pub mod test {
"#
.to_string();
let mut vars: HashMap<String, String> = HashMap::new();
vars.insert("foo".into(), "bar".into());
let vars: HashMap<String, String> = HashMap::new();
let mut input = prost_types::Struct::default();
input.fields.insert(
@@ -400,6 +402,26 @@ pub mod test {
);
let out = encode(10, &vars, &encoder, &input).await.unwrap();
assert_eq!(vec![1], out);
assert_eq!((10, vec![1]), out);
}
#[tokio::test]
pub async fn test_encode_fport() {
let encoder = r#"
function encodeDownlink(input) {
return {
fPort: 20,
bytes: [],
};
}
"#
.to_string();
let vars: HashMap<String, String> = HashMap::new();
let input = prost_types::Struct::default();
let out = encode(10, &vars, &encoder, &input).await.unwrap();
assert_eq!((20, vec![]), out);
}
}

View File

@@ -97,10 +97,13 @@ pub async fn struct_to_binary(
variables: &HashMap<String, String>,
encoder_config: &str,
obj: &prost_types::Struct,
) -> Result<Vec<u8>> {
) -> Result<(u8, Vec<u8>)> {
Ok(match codec {
Codec::NONE => Vec::new(),
Codec::CAYENNE_LPP => cayenne_lpp::encode(obj).context("CayenneLpp encode")?,
Codec::NONE => (f_port, Vec::new()),
Codec::CAYENNE_LPP => (
f_port,
cayenne_lpp::encode(obj).context("CayenneLpp encode")?,
),
Codec::JS => js::encode(f_port, variables, encoder_config, obj).await?,
})
}

View File

@@ -67,7 +67,7 @@ impl<'a> Integration<'a> {
// Use tokio executor and reactor.
// At the moment the reactor is only available for unix.
.with_executor(tokio_executor_trait::Tokio::current())
.with_reactor(tokio_reactor_trait::Tokio);
.with_reactor(tokio_reactor_trait::Tokio::current());
let conn = Connection::connect(&self.url, options).await?;
let chan = conn.create_channel().await?;
@@ -264,17 +264,17 @@ pub mod test {
let conf = Config {
url: env::var("TEST_AMQP_URL").unwrap(),
json: true,
event_routing_key: "application.{{application_id}}.device.{{dev_eui}}.event.{{event}}"
.to_string(),
..Default::default()
};
let i = Integration::new(&conf).await.unwrap();
let conn = loop {
match Connection::connect(
&conf.url,
ConnectionProperties::default()
.with_executor(tokio_executor_trait::Tokio::current())
.with_reactor(tokio_reactor_trait::Tokio),
.with_reactor(tokio_reactor_trait::Tokio::current()),
)
.await
{
@@ -318,8 +318,6 @@ pub mod test {
.await
.unwrap();
let i = Integration::new(&conf).await.unwrap();
let pl = integration::UplinkEvent {
device_info: Some(integration::DeviceInfo {
application_id: Uuid::nil().to_string(),

View File

@@ -0,0 +1,348 @@
use std::collections::HashMap;
use std::sync::OnceLock;
use std::time::Duration;
use anyhow::{Context, Result};
use async_trait::async_trait;
use base64::prelude::*;
use reqwest::header::{HeaderMap, AUTHORIZATION, CONTENT_TYPE};
use reqwest::Client;
use serde::Serialize;
use tracing::{info, trace};
use url::Url;
use super::Integration as IntegrationTrait;
use crate::storage::application::BlynkConfiguration;
use chirpstack_api::integration;
static CLIENT: OnceLock<Client> = OnceLock::new();
fn get_client() -> Client {
CLIENT
.get_or_init(|| {
Client::builder()
.timeout(Duration::from_secs(5))
.use_rustls_tls()
.build()
.unwrap()
})
.clone()
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
struct DeviceInfo {
pub tenant_id: String,
pub tenant_name: String,
pub application_id: String,
pub application_name: String,
pub device_profile_id: String,
pub device_profile_name: String,
pub device_name: String,
pub dev_eui: String,
pub device_class_enabled: String,
pub tags: HashMap<String, String>,
}
impl From<integration::DeviceInfo> for DeviceInfo {
fn from(value: integration::DeviceInfo) -> Self {
DeviceInfo {
tenant_id: value.tenant_id.clone(),
tenant_name: value.tenant_name.clone(),
application_id: value.application_id.clone(),
application_name: value.application_name.clone(),
device_profile_id: value.device_profile_id.clone(),
device_profile_name: value.device_profile_name.clone(),
device_name: value.device_name.clone(),
dev_eui: value.dev_eui.clone(),
device_class_enabled: value.device_class_enabled().as_str_name().into(),
tags: value.tags.clone(),
}
}
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
struct UplinkEvent {
pub device_info: Option<DeviceInfo>,
pub time: Option<pbjson_types::Timestamp>,
pub object: Option<pbjson_types::Struct>,
}
impl From<integration::UplinkEvent> for UplinkEvent {
fn from(value: integration::UplinkEvent) -> Self {
UplinkEvent {
device_info: value.device_info.map(|v| v.into()),
time: value.time.clone(),
object: value.object.clone(),
}
}
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
struct JoinEvent {
pub device_info: Option<DeviceInfo>,
pub time: Option<pbjson_types::Timestamp>,
}
impl From<integration::JoinEvent> for JoinEvent {
fn from(value: integration::JoinEvent) -> Self {
JoinEvent {
device_info: value.device_info.map(|v| v.into()),
time: value.time.clone(),
}
}
}
pub struct Integration {
token: String,
}
impl Integration {
pub fn new(conf: &BlynkConfiguration) -> Integration {
trace!("Initializing Blynk integration");
Integration {
token: conf.token.clone(),
}
}
fn parse_token(&self) -> Result<(String, String)> {
let token_b = BASE64_STANDARD.decode(&self.token).context("Parse token")?;
let token_str = String::from_utf8(token_b).context("Parse token")?;
let token_url = Url::parse(&token_str).context("Parse token")?;
let integration_url = format!(
"{}://{}{}{}",
token_url.scheme(),
token_url.host_str().unwrap_or_default(),
token_url
.port()
.map(|v| format!(":{}", v))
.unwrap_or_default(),
token_url.path()
);
let params: HashMap<String, String> = token_url.query_pairs().into_owned().collect();
Ok((
integration_url,
params.get("token").cloned().unwrap_or_default(),
))
}
async fn post_event<T>(&self, event: &str, pl: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
let (integration_url, integration_token) = self.parse_token()?;
let b = serde_json::to_vec(pl)?;
info!(event = %event, url = %integration_url, "Posting event");
let mut headers = HeaderMap::new();
headers.insert(CONTENT_TYPE, "application/json".parse().unwrap());
headers.insert(
AUTHORIZATION,
format!("Bearer {}", integration_token).parse().unwrap(),
);
get_client()
.post(&integration_url)
.body(b.to_vec())
.query(&[("event", event)])
.headers(headers)
.send()
.await?
.error_for_status()?;
Ok(())
}
}
#[async_trait]
impl IntegrationTrait for Integration {
async fn uplink_event(
&self,
_vars: &HashMap<String, String>,
pl: &integration::UplinkEvent,
) -> Result<()> {
self.post_event("up", &UplinkEvent::from(pl.clone())).await
}
async fn join_event(
&self,
_vars: &HashMap<String, String>,
pl: &integration::JoinEvent,
) -> Result<()> {
self.post_event("join", &JoinEvent::from(pl.clone())).await
}
async fn ack_event(
&self,
_vars: &HashMap<String, String>,
_pl: &integration::AckEvent,
) -> Result<()> {
Ok(())
}
async fn txack_event(
&self,
_vars: &HashMap<String, String>,
_pl: &integration::TxAckEvent,
) -> Result<()> {
Ok(())
}
async fn log_event(
&self,
_vars: &HashMap<String, String>,
_pl: &integration::LogEvent,
) -> Result<()> {
Ok(())
}
async fn status_event(
&self,
_vars: &HashMap<String, String>,
_pl: &integration::StatusEvent,
) -> Result<()> {
Ok(())
}
async fn location_event(
&self,
_vars: &HashMap<String, String>,
_pl: &integration::LocationEvent,
) -> Result<()> {
Ok(())
}
async fn integration_event(
&self,
_vars: &HashMap<String, String>,
_pl: &integration::IntegrationEvent,
) -> Result<()> {
Ok(())
}
}
#[cfg(test)]
mod test {
use super::*;
use httpmock::prelude::*;
#[tokio::test]
async fn test_blynk() {
let server = MockServer::start();
let mut token = String::new();
BASE64_STANDARD.encode_string(
format!("{}?token=my-secret-token", server.url("/")),
&mut token,
);
let i = Integration { token };
// uplink event
let pl: integration::UplinkEvent = integration::UplinkEvent {
device_info: Some(integration::DeviceInfo {
application_id: "app_id".into(),
application_name: "app_name".into(),
dev_eui: "0102030405060708".into(),
device_name: "dev_name".into(),
device_profile_id: "dp_id".into(),
device_profile_name: "dp_name".into(),
tenant_id: "t_id".into(),
tenant_name: "t_name".into(),
device_class_enabled: 0,
tags: HashMap::new(),
}),
object: Some(pbjson_types::Struct::default()),
time: Some(pbjson_types::Timestamp::default()),
..Default::default()
};
let pl_expected = UplinkEvent {
device_info: Some(DeviceInfo {
application_id: "app_id".into(),
application_name: "app_name".into(),
dev_eui: "0102030405060708".into(),
device_name: "dev_name".into(),
device_profile_id: "dp_id".into(),
device_profile_name: "dp_name".into(),
tenant_id: "t_id".into(),
tenant_name: "t_name".into(),
device_class_enabled: "CLASS_A".into(),
tags: HashMap::new(),
}),
object: Some(pbjson_types::Struct::default()),
time: Some(pbjson_types::Timestamp::default()),
};
let pl_test: UplinkEvent = pl.clone().into();
assert_eq!(pl_expected, pl_test);
let mut mock = server.mock(|when, then| {
when.method(POST)
.path("/")
.query_param("event", "up")
.header("Authorization", "Bearer my-secret-token")
.body(serde_json::to_string(&pl_expected).unwrap());
then.status(200);
});
i.uplink_event(&HashMap::new(), &pl).await.unwrap();
mock.assert();
mock.delete();
// join event
let pl: integration::JoinEvent = integration::JoinEvent {
device_info: Some(integration::DeviceInfo {
application_id: "app_id".into(),
application_name: "app_name".into(),
dev_eui: "0102030405060708".into(),
device_name: "dev_name".into(),
device_profile_id: "dp_id".into(),
device_profile_name: "dp_name".into(),
tenant_id: "t_id".into(),
tenant_name: "t_name".into(),
device_class_enabled: 0,
tags: HashMap::new(),
}),
time: Some(pbjson_types::Timestamp::default()),
..Default::default()
};
let pl_expected = JoinEvent {
device_info: Some(DeviceInfo {
application_id: "app_id".into(),
application_name: "app_name".into(),
dev_eui: "0102030405060708".into(),
device_name: "dev_name".into(),
device_profile_id: "dp_id".into(),
device_profile_name: "dp_name".into(),
tenant_id: "t_id".into(),
tenant_name: "t_name".into(),
device_class_enabled: "CLASS_A".into(),
tags: HashMap::new(),
}),
time: Some(pbjson_types::Timestamp::default()),
};
let pl_test: JoinEvent = pl.clone().into();
assert_eq!(pl_expected, pl_test);
let mut mock = server.mock(|when, then| {
when.method(POST)
.path("/")
.query_param("event", "join")
.header("Authorization", "Bearer my-secret-token")
.body(serde_json::to_string(&pl_expected).unwrap());
then.status(200);
});
i.join_event(&HashMap::new(), &pl).await.unwrap();
mock.assert();
mock.delete();
}
}

View File

@@ -18,6 +18,7 @@ use lrwn::EUI64;
mod amqp;
mod aws_sns;
mod azure_service_bus;
mod blynk;
mod gcp_pub_sub;
mod http;
mod ifttt;
@@ -178,6 +179,9 @@ async fn for_application_id(id: Uuid) -> Result<Vec<Box<dyn Integration + Sync +
application::IntegrationConfiguration::Ifttt(conf) => {
Box::new(ifttt::Integration::new(conf))
}
application::IntegrationConfiguration::Blynk(conf) => {
Box::new(blynk::Integration::new(conf))
}
_ => {
continue;
}
@@ -539,10 +543,12 @@ async fn handle_down_command(application_id: String, pl: integration::DownlinkCo
}
let mut data = pl.data.clone();
let mut f_port = pl.f_port as u8;
if let Some(obj) = &pl.object {
let dp = device_profile::get(&dev.device_profile_id).await?;
data = codec::struct_to_binary(
(f_port, data) = codec::struct_to_binary(
dp.payload_codec_runtime,
pl.f_port as u8,
&dev.variables,
@@ -557,7 +563,7 @@ async fn handle_down_command(application_id: String, pl: integration::DownlinkCo
true => Uuid::new_v4().into(),
false => Uuid::from_str(&pl.id)?.into(),
},
f_port: pl.f_port as i16,
f_port: f_port as i16,
confirmed: pl.confirmed,
data,
dev_eui,

View File

@@ -702,6 +702,7 @@ pub mod test {
f_port: 10,
data: vec![1, 2, 3],
object: None,
expires_at: None,
};
let down_cmd_json = serde_json::to_string(&down_cmd).unwrap();
client

View File

@@ -84,6 +84,7 @@ pub enum IntegrationKind {
AzureServiceBus,
PilotThings,
Ifttt,
Blynk,
}
impl fmt::Display for IntegrationKind {
@@ -106,6 +107,7 @@ impl FromStr for IntegrationKind {
"AzureServiceBus" => IntegrationKind::AzureServiceBus,
"PilotThings" => IntegrationKind::PilotThings,
"Ifttt" => IntegrationKind::Ifttt,
"Blynk" => IntegrationKind::Blynk,
_ => {
return Err(anyhow!("Unexpected IntegrationKind: {}", s));
}
@@ -155,6 +157,7 @@ pub enum IntegrationConfiguration {
AzureServiceBus(AzureServiceBusConfiguration),
PilotThings(PilotThingsConfiguration),
Ifttt(IftttConfiguration),
Blynk(BlynkConfiguration),
}
#[cfg(feature = "postgres")]
@@ -260,6 +263,12 @@ pub struct IftttConfiguration {
pub event_prefix: String,
}
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(default)]
pub struct BlynkConfiguration {
pub token: String,
}
#[derive(Clone, Queryable, Insertable, PartialEq, Eq, Debug)]
#[diesel(table_name = application_integration)]
pub struct Integration {

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -57,6 +57,11 @@ import type {
GetIftttIntegrationResponse,
UpdateIftttIntegrationRequest,
DeleteIftttIntegrationRequest,
CreateBlynkIntegrationRequest,
GetBlynkIntegrationRequest,
GetBlynkIntegrationResponse,
UpdateBlynkIntegrationRequest,
DeleteBlynkIntegrationRequest,
GenerateMqttIntegrationClientCertificateRequest,
GenerateMqttIntegrationClientCertificateResponse,
ListApplicationDeviceProfilesRequest,
@@ -67,6 +72,7 @@ import type {
import SessionStore from "./SessionStore";
import { HandleError } from "./helpers";
import { callback } from "chart.js/helpers";
class ApplicationStore extends EventEmitter {
client: ApplicationServiceClient;
@@ -723,6 +729,69 @@ class ApplicationStore extends EventEmitter {
});
};
createBlynkIntegration = (req: CreateBlynkIntegrationRequest, callbackFunc: () => void) => {
this.client.createBlynkIntegration(req, SessionStore.getMetadata(), err => {
if (err !== null) {
HandleError(err);
return;
}
notification.success({
message: "Blynk integration created",
duration: 3,
});
callbackFunc();
});
};
getBlynkIntegration = (
req: GetBlynkIntegrationRequest,
callbackFunc: (resp: GetBlynkIntegrationResponse) => void,
) => {
this.client.getBlynkIntegration(req, SessionStore.getMetadata(), (err, resp) => {
if (err !== null) {
HandleError(err);
return;
}
callbackFunc(resp);
});
};
updateBlynkIntegration = (req: UpdateBlynkIntegrationRequest, callbackFunc: () => void) => {
this.client.updateBlynkIntegration(req, SessionStore.getMetadata(), err => {
if (err !== null) {
HandleError(err);
return;
}
notification.success({
message: "Blynk integration updated",
duration: 3,
});
callbackFunc();
});
};
deleteBlynkIntegration = (req: DeleteBlynkIntegrationRequest, callbackFunc: () => void) => {
this.client.deleteBlynkIntegration(req, SessionStore.getMetadata(), err => {
if (err !== null) {
HandleError(err);
return;
}
notification.success({
message: "Blynk integration deleted",
duration: 3,
});
this.emit("integration.delete");
callbackFunc();
});
};
generateMqttIntegrationClientCertificate = (
req: GenerateMqttIntegrationClientCertificateRequest,
callbackFunc: (resp: GenerateMqttIntegrationClientCertificateResponse) => void,

View File

@@ -37,6 +37,8 @@ import EditThingsBoardIntegration from "./integrations/EditThingsBoardIntegratio
import GenerateMqttCertificate from "./integrations/GenerateMqttCertificate";
import CreateIftttIntegration from "./integrations/CreateIftttIntegration";
import EditIftttIntegration from "./integrations/EditIftttIntegration";
import CreateBlynkIntegration from "./integrations/CreateBlynkIntegration";
import EditBlynkIntegration from "./integrations/EditBlynkIntegration";
import { useTitle } from "../helpers";
interface IProps {
@@ -193,6 +195,8 @@ function ApplicationLayout(props: IProps) {
path="/integrations/ifttt/edit"
element={<EditIftttIntegration application={app} measurementKeys={props.measurementKeys} />}
/>
<Route path="/integrations/blynk/create" element={<CreateBlynkIntegration application={app} />} />
<Route path="/integrations/blynk/edit" element={<EditBlynkIntegration application={app} />} />
</Routes>
</Card>
</Space>

View File

@@ -20,6 +20,7 @@ import InfluxdbCard from "./integrations/InfluxdbCard";
import PilotThingsCard from "./integrations/PilotThingsCard";
import ThingsBoardCard from "./integrations/ThingsBoardCard";
import IftttCard from "./integrations/IftttCard";
import BlynkCard from "./integrations/BlynkCard";
interface IProps {
application: Application;
@@ -62,6 +63,13 @@ function ListIntegrations(props: IProps) {
available.push(<AzureServiceBusCard application={props.application} add />);
}
// Blynk
if (includes(resp.getResultList(), IntegrationKind.BLYNK)) {
configured.push(<BlynkCard application={props.application} />);
} else {
available.push(<BlynkCard application={props.application} add />);
}
// GCP Pub/Sub
if (includes(resp.getResultList(), IntegrationKind.GCP_PUB_SUB)) {
configured.push(<GcpPubSubCard application={props.application} />);

View File

@@ -0,0 +1,56 @@
import { Link } from "react-router-dom";
import { Col, Card, Popconfirm } from "antd";
import { PlusOutlined, EditOutlined, DeleteOutlined } from "@ant-design/icons";
import type { Application } from "@chirpstack/chirpstack-api-grpc-web/api/application_pb";
import { DeleteBlynkIntegrationRequest } from "@chirpstack/chirpstack-api-grpc-web/api/application_pb";
import ApplicationStore from "../../../stores/ApplicationStore";
interface IProps {
application: Application;
add?: boolean;
}
function BlynkCard(props: IProps) {
const onDelete = () => {
const req = new DeleteBlynkIntegrationRequest();
req.setApplicationId(props.application.getId());
ApplicationStore.deleteBlynkIntegration(req, () => {});
};
let actions: JSX.Element[] = [];
if (props.add) {
actions = [
<Link to="blynk/create">
<PlusOutlined />
</Link>,
];
} else {
actions = [
<Link to="blynk/edit">
<EditOutlined />
</Link>,
<Popconfirm title="Are you sure you want to delete this integration?" onConfirm={onDelete}>
<DeleteOutlined />
</Popconfirm>,
];
}
return (
<Col span={8}>
<Card
title="Blynk"
className="integration-card"
cover={<img alt="Blynk" src="/integrations/blynk.png" style={{ padding: 1 }} />}
actions={actions}
>
<Card.Meta description="The Blynk integration forwards events to the Blynk platform." />
</Card>
</Col>
);
}
export default BlynkCard;

View File

@@ -0,0 +1,46 @@
import { Form, Input, Button } from "antd";
import { BlynkIntegration } from "@chirpstack/chirpstack-api-grpc-web/api/application_pb";
import { onFinishFailed } from "../../helpers";
interface IProps {
initialValues: BlynkIntegration;
onFinish: (obj: BlynkIntegration) => void;
}
function BlynkIntegrationForm(props: IProps) {
const onFinish = (values: BlynkIntegration.AsObject) => {
const v = Object.assign(props.initialValues.toObject(), values);
const i = new BlynkIntegration();
i.setApplicationId(v.applicationId);
i.setToken(v.token);
props.onFinish(i);
};
return (
<Form
layout="vertical"
initialValues={props.initialValues.toObject()}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
>
<Form.Item
label="Blynk API token"
name="token"
rules={[{ required: true, message: "Please enter a Blynk API token!" }]}
>
<Input.Password />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
);
}
export default BlynkIntegrationForm;

View File

@@ -0,0 +1,41 @@
import { useNavigate } from "react-router-dom";
import { Card } from "antd";
import type { Application } from "@chirpstack/chirpstack-api-grpc-web/api/application_pb";
import {
BlynkIntegration,
CreateBlynkIntegrationRequest,
} from "@chirpstack/chirpstack-api-grpc-web/api/application_pb";
import BlynkIngrationForm from "./BlynkIntegrationForm";
import ApplicationStore from "../../../stores/ApplicationStore";
interface IProps {
application: Application;
}
function CreateBlynkIntegration(props: IProps) {
const navigate = useNavigate();
const onFinish = (obj: BlynkIntegration) => {
obj.setApplicationId(props.application.getId());
const req = new CreateBlynkIntegrationRequest();
req.setIntegration(obj);
ApplicationStore.createBlynkIntegration(req, () => {
navigate(`/tenants/${props.application.getTenantId()}/applications/${props.application.getId()}/integrations`);
});
};
const i = new BlynkIntegration();
return (
<Card title="Add Blynk integration">
<BlynkIngrationForm initialValues={i} onFinish={onFinish} />
</Card>
);
}
export default CreateBlynkIntegration;

View File

@@ -0,0 +1,56 @@
import { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { Card } from "antd";
import type {
Application,
BlynkIntegration,
GetBlynkIntegrationResponse,
} from "@chirpstack/chirpstack-api-grpc-web/api/application_pb";
import {
GetBlynkIntegrationRequest,
UpdateBlynkIntegrationRequest,
} from "@chirpstack/chirpstack-api-grpc-web/api/application_pb";
import BlynkIntegrationForm from "./BlynkIntegrationForm";
import ApplicationStore from "../../../stores/ApplicationStore";
interface IProps {
application: Application;
}
function EditBlynkIntegration(props: IProps) {
const navigate = useNavigate();
const [integration, setIntegration] = useState<BlynkIntegration | undefined>(undefined);
useEffect(() => {
const req = new GetBlynkIntegrationRequest();
req.setApplicationId(props.application.getId());
ApplicationStore.getBlynkIntegration(req, (resp: GetBlynkIntegrationResponse) => {
setIntegration(resp.getIntegration());
});
}, [props]);
const onFinish = (obj: BlynkIntegration) => {
const req = new UpdateBlynkIntegrationRequest();
req.setIntegration(obj);
ApplicationStore.updateBlynkIntegration(req, () => {
navigate(`/tenants/${props.application.getTenantId()}/applications/${props.application.getId()}/integrations`);
});
};
if (integration === undefined) {
return null;
}
return (
<Card title="Update Blynk integration">
<BlynkIntegrationForm initialValues={integration} onFinish={onFinish} />
</Card>
);
}
export default EditBlynkIntegration;

View File

@@ -44,12 +44,16 @@ function CreateDeviceProfile(props: IProps) {
* @param {number} input.fPort Uplink fPort.
* @param {Record<string, string>} input.variables Object containing the configured device variables.
*
* @returns {{data: object}} Object representing the decoded payload.
* @returns {{data: object, errors: string[], warnings: string[]}}
* An object containing:
* - data: Object representing the decoded payload.
* - errors: An array of errors (optional).
* - warnings: An array of warnings (optional).
*/
function decodeUplink(input) {
return {
data: {
// temp: 22.5
temp: 22.5,
}
};
}
@@ -61,11 +65,17 @@ function decodeUplink(input) {
* @param {object} input.data Object representing the payload that must be encoded.
* @param {Record<string, string>} input.variables Object containing the configured device variables.
*
* @returns {{bytes: number[]}} Byte array containing the downlink payload.
* @returns {{bytes: number[], fPort: number, errors: string[], warnings: string[]}}
* An object containing:
* - bytes: Byte array containing the downlink payload.
* - fPort: The downlink LoRaWAN fPort.
* - errors: An array of errors (optional).
* - warnings: An array of warnings (optional).
*/
function encodeDownlink(input) {
return {
// bytes: [225, 230, 255, 0]
fPort: 10,
bytes: [225, 230, 255, 0],
};
}
`;