mirror of
https://github.com/chirpstack/chirpstack.git
synced 2025-04-08 20:04:19 +00:00
Implement storing + display duty-cycle stats.
Note that these stats are only available for Concentratord based gateways as these metrics must be aggregated by the gateway.
This commit is contained in:
parent
2889da37c2
commit
a5ff416fa2
408
api/go/api/gateway.pb.go
vendored
408
api/go/api/gateway.pb.go
vendored
@ -1029,6 +1029,129 @@ func (x *GetGatewayMetricsResponse) GetTxPacketsPerStatus() *common.Metric {
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetGatewayDutyCycleMetricsRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Gateway ID (EUI64).
|
||||
GatewayId string `protobuf:"bytes,1,opt,name=gateway_id,json=gatewayId,proto3" json:"gateway_id,omitempty"`
|
||||
// Interval start timestamp.
|
||||
Start *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=start,proto3" json:"start,omitempty"`
|
||||
// Interval end timestamp.
|
||||
End *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=end,proto3" json:"end,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetGatewayDutyCycleMetricsRequest) Reset() {
|
||||
*x = GetGatewayDutyCycleMetricsRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_gateway_proto_msgTypes[13]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetGatewayDutyCycleMetricsRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetGatewayDutyCycleMetricsRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetGatewayDutyCycleMetricsRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_gateway_proto_msgTypes[13]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetGatewayDutyCycleMetricsRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetGatewayDutyCycleMetricsRequest) Descriptor() ([]byte, []int) {
|
||||
return file_api_gateway_proto_rawDescGZIP(), []int{13}
|
||||
}
|
||||
|
||||
func (x *GetGatewayDutyCycleMetricsRequest) GetGatewayId() string {
|
||||
if x != nil {
|
||||
return x.GatewayId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GetGatewayDutyCycleMetricsRequest) GetStart() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.Start
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *GetGatewayDutyCycleMetricsRequest) GetEnd() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.End
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetGatewayDutyCycleMetricsResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Percentage relative to max load.
|
||||
MaxLoadPercentage *common.Metric `protobuf:"bytes,1,opt,name=max_load_percentage,json=maxLoadPercentage,proto3" json:"max_load_percentage,omitempty"`
|
||||
// Percentage relative to tracking window.
|
||||
WindowPercentage *common.Metric `protobuf:"bytes,2,opt,name=window_percentage,json=windowPercentage,proto3" json:"window_percentage,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetGatewayDutyCycleMetricsResponse) Reset() {
|
||||
*x = GetGatewayDutyCycleMetricsResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_gateway_proto_msgTypes[14]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetGatewayDutyCycleMetricsResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetGatewayDutyCycleMetricsResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetGatewayDutyCycleMetricsResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_gateway_proto_msgTypes[14]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetGatewayDutyCycleMetricsResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetGatewayDutyCycleMetricsResponse) Descriptor() ([]byte, []int) {
|
||||
return file_api_gateway_proto_rawDescGZIP(), []int{14}
|
||||
}
|
||||
|
||||
func (x *GetGatewayDutyCycleMetricsResponse) GetMaxLoadPercentage() *common.Metric {
|
||||
if x != nil {
|
||||
return x.MaxLoadPercentage
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *GetGatewayDutyCycleMetricsResponse) GetWindowPercentage() *common.Metric {
|
||||
if x != nil {
|
||||
return x.WindowPercentage
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_api_gateway_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_api_gateway_proto_rawDesc = []byte{
|
||||
@ -1203,67 +1326,98 @@ var file_api_gateway_proto_rawDesc = []byte{
|
||||
0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73,
|
||||
0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x12, 0x74, 0x78, 0x50,
|
||||
0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x50, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2a,
|
||||
0x37, 0x0a, 0x0c, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12,
|
||||
0x0e, 0x0a, 0x0a, 0x4e, 0x45, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x45, 0x4e, 0x10, 0x00, 0x12,
|
||||
0x0a, 0x0a, 0x06, 0x4f, 0x4e, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4f,
|
||||
0x46, 0x46, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x02, 0x32, 0x91, 0x06, 0x0a, 0x0e, 0x47, 0x61, 0x74,
|
||||
0x65, 0x77, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x06, 0x43,
|
||||
0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12,
|
||||
0x3a, 0x01, 0x2a, 0x22, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
|
||||
0x79, 0x73, 0x12, 0x5a, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77,
|
||||
0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
|
||||
0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x6a,
|
||||
0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55,
|
||||
0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x2d, 0x82, 0xd3, 0xe4,
|
||||
0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a, 0x1a, 0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74,
|
||||
0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x67,
|
||||
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x5f, 0x0a, 0x06, 0x44, 0x65,
|
||||
0x6c, 0x65, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
|
||||
0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||
0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x2a,
|
||||
0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b,
|
||||
0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x52, 0x0a, 0x04, 0x4c,
|
||||
0x69, 0x73, 0x74, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x61,
|
||||
0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f,
|
||||
0x12, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x12,
|
||||
0xb1, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65,
|
||||
0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65,
|
||||
0x77, 0x61, 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
|
||||
0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61,
|
||||
0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
|
||||
0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x31, 0x22, 0x2f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
|
||||
0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67,
|
||||
0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
|
||||
0x61, 0x74, 0x65, 0x12, 0x77, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
|
||||
0x73, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77,
|
||||
0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61,
|
||||
0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67,
|
||||
0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x50, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22,
|
||||
0xa2, 0x01, 0x0a, 0x21, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x44, 0x75,
|
||||
0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
|
||||
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77,
|
||||
0x61, 0x79, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
|
||||
0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
|
||||
0x03, 0x65, 0x6e, 0x64, 0x22, 0xa1, 0x01, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65,
|
||||
0x77, 0x61, 0x79, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72,
|
||||
0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x13, 0x6d,
|
||||
0x61, 0x78, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61,
|
||||
0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
|
||||
0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x11, 0x6d, 0x61, 0x78, 0x4c, 0x6f, 0x61,
|
||||
0x64, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x11, 0x77,
|
||||
0x69, 0x6e, 0x64, 0x6f, 0x77, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
|
||||
0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x10, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x50, 0x65,
|
||||
0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x2a, 0x37, 0x0a, 0x0c, 0x47, 0x61, 0x74, 0x65,
|
||||
0x77, 0x61, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x45, 0x56, 0x45,
|
||||
0x52, 0x5f, 0x53, 0x45, 0x45, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x4e, 0x4c, 0x49,
|
||||
0x4e, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x46, 0x46, 0x4c, 0x49, 0x4e, 0x45, 0x10,
|
||||
0x02, 0x32, 0xb1, 0x07, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x19,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77,
|
||||
0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
|
||||
0x79, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x3a, 0x01, 0x2a, 0x22, 0x0d, 0x2f, 0x61,
|
||||
0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0x5a, 0x0a, 0x03, 0x47,
|
||||
0x65, 0x74, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65,
|
||||
0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x61, 0x70,
|
||||
0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65,
|
||||
0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x6a, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74,
|
||||
0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x61,
|
||||
0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
|
||||
0x6d, 0x70, 0x74, 0x79, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a, 0x1a,
|
||||
0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b,
|
||||
0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f,
|
||||
0x69, 0x64, 0x7d, 0x12, 0x5f, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x19, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61,
|
||||
0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
|
||||
0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x2a, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67,
|
||||
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
|
||||
0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x42, 0x64, 0x0a, 0x11,
|
||||
0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x42, 0x0c, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50,
|
||||
0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68,
|
||||
0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74,
|
||||
0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70,
|
||||
0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41,
|
||||
0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x5f, 0x69, 0x64, 0x7d, 0x12, 0x52, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x18, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f,
|
||||
0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0xb1, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x6e,
|
||||
0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69,
|
||||
0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x6e,
|
||||
0x65, 0x72, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6c, 0x69, 0x65,
|
||||
0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72,
|
||||
0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
|
||||
0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x22, 0x2f, 0x2f, 0x61, 0x70,
|
||||
0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65,
|
||||
0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65,
|
||||
0x2d, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x77, 0x0a, 0x0a,
|
||||
0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69,
|
||||
0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
|
||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
||||
0x24, 0x12, 0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73,
|
||||
0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x6d, 0x65,
|
||||
0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x44, 0x75, 0x74,
|
||||
0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x26, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x44, 0x75,
|
||||
0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47,
|
||||
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d,
|
||||
0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35,
|
||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74,
|
||||
0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69,
|
||||
0x64, 0x7d, 0x2f, 0x64, 0x75, 0x74, 0x79, 0x2d, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x2d, 0x6d, 0x65,
|
||||
0x74, 0x72, 0x69, 0x63, 0x73, 0x42, 0x64, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72,
|
||||
0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0c, 0x47, 0x61, 0x74, 0x65,
|
||||
0x77, 0x61, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68,
|
||||
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63,
|
||||
0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69,
|
||||
0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69,
|
||||
0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -1279,7 +1433,7 @@ func file_api_gateway_proto_rawDescGZIP() []byte {
|
||||
}
|
||||
|
||||
var file_api_gateway_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_api_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
|
||||
var file_api_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 18)
|
||||
var file_api_gateway_proto_goTypes = []interface{}{
|
||||
(GatewayState)(0), // 0: api.GatewayState
|
||||
(*Gateway)(nil), // 1: api.Gateway
|
||||
@ -1295,62 +1449,70 @@ var file_api_gateway_proto_goTypes = []interface{}{
|
||||
(*GenerateGatewayClientCertificateResponse)(nil), // 11: api.GenerateGatewayClientCertificateResponse
|
||||
(*GetGatewayMetricsRequest)(nil), // 12: api.GetGatewayMetricsRequest
|
||||
(*GetGatewayMetricsResponse)(nil), // 13: api.GetGatewayMetricsResponse
|
||||
nil, // 14: api.Gateway.TagsEntry
|
||||
nil, // 15: api.Gateway.MetadataEntry
|
||||
nil, // 16: api.GatewayListItem.PropertiesEntry
|
||||
(*common.Location)(nil), // 17: common.Location
|
||||
(*timestamppb.Timestamp)(nil), // 18: google.protobuf.Timestamp
|
||||
(common.Aggregation)(0), // 19: common.Aggregation
|
||||
(*common.Metric)(nil), // 20: common.Metric
|
||||
(*emptypb.Empty)(nil), // 21: google.protobuf.Empty
|
||||
(*GetGatewayDutyCycleMetricsRequest)(nil), // 14: api.GetGatewayDutyCycleMetricsRequest
|
||||
(*GetGatewayDutyCycleMetricsResponse)(nil), // 15: api.GetGatewayDutyCycleMetricsResponse
|
||||
nil, // 16: api.Gateway.TagsEntry
|
||||
nil, // 17: api.Gateway.MetadataEntry
|
||||
nil, // 18: api.GatewayListItem.PropertiesEntry
|
||||
(*common.Location)(nil), // 19: common.Location
|
||||
(*timestamppb.Timestamp)(nil), // 20: google.protobuf.Timestamp
|
||||
(common.Aggregation)(0), // 21: common.Aggregation
|
||||
(*common.Metric)(nil), // 22: common.Metric
|
||||
(*emptypb.Empty)(nil), // 23: google.protobuf.Empty
|
||||
}
|
||||
var file_api_gateway_proto_depIdxs = []int32{
|
||||
17, // 0: api.Gateway.location:type_name -> common.Location
|
||||
14, // 1: api.Gateway.tags:type_name -> api.Gateway.TagsEntry
|
||||
15, // 2: api.Gateway.metadata:type_name -> api.Gateway.MetadataEntry
|
||||
17, // 3: api.GatewayListItem.location:type_name -> common.Location
|
||||
16, // 4: api.GatewayListItem.properties:type_name -> api.GatewayListItem.PropertiesEntry
|
||||
18, // 5: api.GatewayListItem.created_at:type_name -> google.protobuf.Timestamp
|
||||
18, // 6: api.GatewayListItem.updated_at:type_name -> google.protobuf.Timestamp
|
||||
18, // 7: api.GatewayListItem.last_seen_at:type_name -> google.protobuf.Timestamp
|
||||
19, // 0: api.Gateway.location:type_name -> common.Location
|
||||
16, // 1: api.Gateway.tags:type_name -> api.Gateway.TagsEntry
|
||||
17, // 2: api.Gateway.metadata:type_name -> api.Gateway.MetadataEntry
|
||||
19, // 3: api.GatewayListItem.location:type_name -> common.Location
|
||||
18, // 4: api.GatewayListItem.properties:type_name -> api.GatewayListItem.PropertiesEntry
|
||||
20, // 5: api.GatewayListItem.created_at:type_name -> google.protobuf.Timestamp
|
||||
20, // 6: api.GatewayListItem.updated_at:type_name -> google.protobuf.Timestamp
|
||||
20, // 7: api.GatewayListItem.last_seen_at:type_name -> google.protobuf.Timestamp
|
||||
0, // 8: api.GatewayListItem.state:type_name -> api.GatewayState
|
||||
1, // 9: api.CreateGatewayRequest.gateway:type_name -> api.Gateway
|
||||
1, // 10: api.GetGatewayResponse.gateway:type_name -> api.Gateway
|
||||
18, // 11: api.GetGatewayResponse.created_at:type_name -> google.protobuf.Timestamp
|
||||
18, // 12: api.GetGatewayResponse.updated_at:type_name -> google.protobuf.Timestamp
|
||||
18, // 13: api.GetGatewayResponse.last_seen_at:type_name -> google.protobuf.Timestamp
|
||||
20, // 11: api.GetGatewayResponse.created_at:type_name -> google.protobuf.Timestamp
|
||||
20, // 12: api.GetGatewayResponse.updated_at:type_name -> google.protobuf.Timestamp
|
||||
20, // 13: api.GetGatewayResponse.last_seen_at:type_name -> google.protobuf.Timestamp
|
||||
1, // 14: api.UpdateGatewayRequest.gateway:type_name -> api.Gateway
|
||||
2, // 15: api.ListGatewaysResponse.result:type_name -> api.GatewayListItem
|
||||
18, // 16: api.GenerateGatewayClientCertificateResponse.expires_at:type_name -> google.protobuf.Timestamp
|
||||
18, // 17: api.GetGatewayMetricsRequest.start:type_name -> google.protobuf.Timestamp
|
||||
18, // 18: api.GetGatewayMetricsRequest.end:type_name -> google.protobuf.Timestamp
|
||||
19, // 19: api.GetGatewayMetricsRequest.aggregation:type_name -> common.Aggregation
|
||||
20, // 20: api.GetGatewayMetricsResponse.rx_packets:type_name -> common.Metric
|
||||
20, // 21: api.GetGatewayMetricsResponse.tx_packets:type_name -> common.Metric
|
||||
20, // 22: api.GetGatewayMetricsResponse.tx_packets_per_freq:type_name -> common.Metric
|
||||
20, // 23: api.GetGatewayMetricsResponse.rx_packets_per_freq:type_name -> common.Metric
|
||||
20, // 24: api.GetGatewayMetricsResponse.tx_packets_per_dr:type_name -> common.Metric
|
||||
20, // 25: api.GetGatewayMetricsResponse.rx_packets_per_dr:type_name -> common.Metric
|
||||
20, // 26: api.GetGatewayMetricsResponse.tx_packets_per_status:type_name -> common.Metric
|
||||
3, // 27: api.GatewayService.Create:input_type -> api.CreateGatewayRequest
|
||||
4, // 28: api.GatewayService.Get:input_type -> api.GetGatewayRequest
|
||||
6, // 29: api.GatewayService.Update:input_type -> api.UpdateGatewayRequest
|
||||
7, // 30: api.GatewayService.Delete:input_type -> api.DeleteGatewayRequest
|
||||
8, // 31: api.GatewayService.List:input_type -> api.ListGatewaysRequest
|
||||
10, // 32: api.GatewayService.GenerateClientCertificate:input_type -> api.GenerateGatewayClientCertificateRequest
|
||||
12, // 33: api.GatewayService.GetMetrics:input_type -> api.GetGatewayMetricsRequest
|
||||
21, // 34: api.GatewayService.Create:output_type -> google.protobuf.Empty
|
||||
5, // 35: api.GatewayService.Get:output_type -> api.GetGatewayResponse
|
||||
21, // 36: api.GatewayService.Update:output_type -> google.protobuf.Empty
|
||||
21, // 37: api.GatewayService.Delete:output_type -> google.protobuf.Empty
|
||||
9, // 38: api.GatewayService.List:output_type -> api.ListGatewaysResponse
|
||||
11, // 39: api.GatewayService.GenerateClientCertificate:output_type -> api.GenerateGatewayClientCertificateResponse
|
||||
13, // 40: api.GatewayService.GetMetrics:output_type -> api.GetGatewayMetricsResponse
|
||||
34, // [34:41] is the sub-list for method output_type
|
||||
27, // [27:34] is the sub-list for method input_type
|
||||
27, // [27:27] is the sub-list for extension type_name
|
||||
27, // [27:27] is the sub-list for extension extendee
|
||||
0, // [0:27] is the sub-list for field type_name
|
||||
20, // 16: api.GenerateGatewayClientCertificateResponse.expires_at:type_name -> google.protobuf.Timestamp
|
||||
20, // 17: api.GetGatewayMetricsRequest.start:type_name -> google.protobuf.Timestamp
|
||||
20, // 18: api.GetGatewayMetricsRequest.end:type_name -> google.protobuf.Timestamp
|
||||
21, // 19: api.GetGatewayMetricsRequest.aggregation:type_name -> common.Aggregation
|
||||
22, // 20: api.GetGatewayMetricsResponse.rx_packets:type_name -> common.Metric
|
||||
22, // 21: api.GetGatewayMetricsResponse.tx_packets:type_name -> common.Metric
|
||||
22, // 22: api.GetGatewayMetricsResponse.tx_packets_per_freq:type_name -> common.Metric
|
||||
22, // 23: api.GetGatewayMetricsResponse.rx_packets_per_freq:type_name -> common.Metric
|
||||
22, // 24: api.GetGatewayMetricsResponse.tx_packets_per_dr:type_name -> common.Metric
|
||||
22, // 25: api.GetGatewayMetricsResponse.rx_packets_per_dr:type_name -> common.Metric
|
||||
22, // 26: api.GetGatewayMetricsResponse.tx_packets_per_status:type_name -> common.Metric
|
||||
20, // 27: api.GetGatewayDutyCycleMetricsRequest.start:type_name -> google.protobuf.Timestamp
|
||||
20, // 28: api.GetGatewayDutyCycleMetricsRequest.end:type_name -> google.protobuf.Timestamp
|
||||
22, // 29: api.GetGatewayDutyCycleMetricsResponse.max_load_percentage:type_name -> common.Metric
|
||||
22, // 30: api.GetGatewayDutyCycleMetricsResponse.window_percentage:type_name -> common.Metric
|
||||
3, // 31: api.GatewayService.Create:input_type -> api.CreateGatewayRequest
|
||||
4, // 32: api.GatewayService.Get:input_type -> api.GetGatewayRequest
|
||||
6, // 33: api.GatewayService.Update:input_type -> api.UpdateGatewayRequest
|
||||
7, // 34: api.GatewayService.Delete:input_type -> api.DeleteGatewayRequest
|
||||
8, // 35: api.GatewayService.List:input_type -> api.ListGatewaysRequest
|
||||
10, // 36: api.GatewayService.GenerateClientCertificate:input_type -> api.GenerateGatewayClientCertificateRequest
|
||||
12, // 37: api.GatewayService.GetMetrics:input_type -> api.GetGatewayMetricsRequest
|
||||
14, // 38: api.GatewayService.GetDutyCycleMetrics:input_type -> api.GetGatewayDutyCycleMetricsRequest
|
||||
23, // 39: api.GatewayService.Create:output_type -> google.protobuf.Empty
|
||||
5, // 40: api.GatewayService.Get:output_type -> api.GetGatewayResponse
|
||||
23, // 41: api.GatewayService.Update:output_type -> google.protobuf.Empty
|
||||
23, // 42: api.GatewayService.Delete:output_type -> google.protobuf.Empty
|
||||
9, // 43: api.GatewayService.List:output_type -> api.ListGatewaysResponse
|
||||
11, // 44: api.GatewayService.GenerateClientCertificate:output_type -> api.GenerateGatewayClientCertificateResponse
|
||||
13, // 45: api.GatewayService.GetMetrics:output_type -> api.GetGatewayMetricsResponse
|
||||
15, // 46: api.GatewayService.GetDutyCycleMetrics:output_type -> api.GetGatewayDutyCycleMetricsResponse
|
||||
39, // [39:47] is the sub-list for method output_type
|
||||
31, // [31:39] is the sub-list for method input_type
|
||||
31, // [31:31] is the sub-list for extension type_name
|
||||
31, // [31:31] is the sub-list for extension extendee
|
||||
0, // [0:31] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_api_gateway_proto_init() }
|
||||
@ -1515,6 +1677,30 @@ func file_api_gateway_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_api_gateway_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetGatewayDutyCycleMetricsRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_api_gateway_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetGatewayDutyCycleMetricsResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
@ -1522,7 +1708,7 @@ func file_api_gateway_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_api_gateway_proto_rawDesc,
|
||||
NumEnums: 1,
|
||||
NumMessages: 16,
|
||||
NumMessages: 18,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
41
api/go/api/gateway_grpc.pb.go
vendored
41
api/go/api/gateway_grpc.pb.go
vendored
@ -27,6 +27,7 @@ const (
|
||||
GatewayService_List_FullMethodName = "/api.GatewayService/List"
|
||||
GatewayService_GenerateClientCertificate_FullMethodName = "/api.GatewayService/GenerateClientCertificate"
|
||||
GatewayService_GetMetrics_FullMethodName = "/api.GatewayService/GetMetrics"
|
||||
GatewayService_GetDutyCycleMetrics_FullMethodName = "/api.GatewayService/GetDutyCycleMetrics"
|
||||
)
|
||||
|
||||
// GatewayServiceClient is the client API for GatewayService service.
|
||||
@ -47,6 +48,9 @@ type GatewayServiceClient interface {
|
||||
GenerateClientCertificate(ctx context.Context, in *GenerateGatewayClientCertificateRequest, opts ...grpc.CallOption) (*GenerateGatewayClientCertificateResponse, error)
|
||||
// GetMetrics returns the gateway metrics.
|
||||
GetMetrics(ctx context.Context, in *GetGatewayMetricsRequest, opts ...grpc.CallOption) (*GetGatewayMetricsResponse, error)
|
||||
// GetDutyCycleMetrics returns the duty-cycle metrics.
|
||||
// Note that only the last 2 hours of data are stored. Currently only per minute aggregation is available.
|
||||
GetDutyCycleMetrics(ctx context.Context, in *GetGatewayDutyCycleMetricsRequest, opts ...grpc.CallOption) (*GetGatewayDutyCycleMetricsResponse, error)
|
||||
}
|
||||
|
||||
type gatewayServiceClient struct {
|
||||
@ -120,6 +124,15 @@ func (c *gatewayServiceClient) GetMetrics(ctx context.Context, in *GetGatewayMet
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *gatewayServiceClient) GetDutyCycleMetrics(ctx context.Context, in *GetGatewayDutyCycleMetricsRequest, opts ...grpc.CallOption) (*GetGatewayDutyCycleMetricsResponse, error) {
|
||||
out := new(GetGatewayDutyCycleMetricsResponse)
|
||||
err := c.cc.Invoke(ctx, GatewayService_GetDutyCycleMetrics_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GatewayServiceServer is the server API for GatewayService service.
|
||||
// All implementations must embed UnimplementedGatewayServiceServer
|
||||
// for forward compatibility
|
||||
@ -138,6 +151,9 @@ type GatewayServiceServer interface {
|
||||
GenerateClientCertificate(context.Context, *GenerateGatewayClientCertificateRequest) (*GenerateGatewayClientCertificateResponse, error)
|
||||
// GetMetrics returns the gateway metrics.
|
||||
GetMetrics(context.Context, *GetGatewayMetricsRequest) (*GetGatewayMetricsResponse, error)
|
||||
// GetDutyCycleMetrics returns the duty-cycle metrics.
|
||||
// Note that only the last 2 hours of data are stored. Currently only per minute aggregation is available.
|
||||
GetDutyCycleMetrics(context.Context, *GetGatewayDutyCycleMetricsRequest) (*GetGatewayDutyCycleMetricsResponse, error)
|
||||
mustEmbedUnimplementedGatewayServiceServer()
|
||||
}
|
||||
|
||||
@ -166,6 +182,9 @@ func (UnimplementedGatewayServiceServer) GenerateClientCertificate(context.Conte
|
||||
func (UnimplementedGatewayServiceServer) GetMetrics(context.Context, *GetGatewayMetricsRequest) (*GetGatewayMetricsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetMetrics not implemented")
|
||||
}
|
||||
func (UnimplementedGatewayServiceServer) GetDutyCycleMetrics(context.Context, *GetGatewayDutyCycleMetricsRequest) (*GetGatewayDutyCycleMetricsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetDutyCycleMetrics not implemented")
|
||||
}
|
||||
func (UnimplementedGatewayServiceServer) mustEmbedUnimplementedGatewayServiceServer() {}
|
||||
|
||||
// UnsafeGatewayServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
@ -305,6 +324,24 @@ func _GatewayService_GetMetrics_Handler(srv interface{}, ctx context.Context, de
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _GatewayService_GetDutyCycleMetrics_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetGatewayDutyCycleMetricsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(GatewayServiceServer).GetDutyCycleMetrics(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: GatewayService_GetDutyCycleMetrics_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(GatewayServiceServer).GetDutyCycleMetrics(ctx, req.(*GetGatewayDutyCycleMetricsRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// GatewayService_ServiceDesc is the grpc.ServiceDesc for GatewayService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@ -340,6 +377,10 @@ var GatewayService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "GetMetrics",
|
||||
Handler: _GatewayService_GetMetrics_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetDutyCycleMetrics",
|
||||
Handler: _GatewayService_GetDutyCycleMetrics_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "api/gateway.proto",
|
||||
|
49
api/go/common/common.pb.go
vendored
49
api/go/common/common.pb.go
vendored
@ -434,6 +434,8 @@ const (
|
||||
Aggregation_DAY Aggregation = 1
|
||||
// Month.
|
||||
Aggregation_MONTH Aggregation = 2
|
||||
// Minute.
|
||||
Aggregation_MINUTE Aggregation = 3
|
||||
)
|
||||
|
||||
// Enum value maps for Aggregation.
|
||||
@ -442,11 +444,13 @@ var (
|
||||
0: "HOUR",
|
||||
1: "DAY",
|
||||
2: "MONTH",
|
||||
3: "MINUTE",
|
||||
}
|
||||
Aggregation_value = map[string]int32{
|
||||
"HOUR": 0,
|
||||
"DAY": 1,
|
||||
"MONTH": 2,
|
||||
"HOUR": 0,
|
||||
"DAY": 1,
|
||||
"MONTH": 2,
|
||||
"MINUTE": 3,
|
||||
}
|
||||
)
|
||||
|
||||
@ -1054,27 +1058,28 @@ var file_common_common_proto_rawDesc = []byte{
|
||||
0x56, 0x45, 0x52, 0x5f, 0x52, 0x53, 0x53, 0x49, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x47, 0x45,
|
||||
0x4f, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x4c, 0x56, 0x45, 0x52, 0x5f, 0x47, 0x4e, 0x53, 0x53, 0x10,
|
||||
0x05, 0x12, 0x15, 0x0a, 0x11, 0x47, 0x45, 0x4f, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x4c, 0x56, 0x45,
|
||||
0x52, 0x5f, 0x57, 0x49, 0x46, 0x49, 0x10, 0x06, 0x2a, 0x2b, 0x0a, 0x0b, 0x41, 0x67, 0x67, 0x72,
|
||||
0x52, 0x5f, 0x57, 0x49, 0x46, 0x49, 0x10, 0x06, 0x2a, 0x37, 0x0a, 0x0b, 0x41, 0x67, 0x67, 0x72,
|
||||
0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x4f, 0x55, 0x52, 0x10,
|
||||
0x00, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x41, 0x59, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x4d, 0x4f,
|
||||
0x4e, 0x54, 0x48, 0x10, 0x02, 0x2a, 0x32, 0x0a, 0x0a, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4b,
|
||||
0x69, 0x6e, 0x64, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x00,
|
||||
0x12, 0x0c, 0x0a, 0x08, 0x41, 0x42, 0x53, 0x4f, 0x4c, 0x55, 0x54, 0x45, 0x10, 0x01, 0x12, 0x09,
|
||||
0x0a, 0x05, 0x47, 0x41, 0x55, 0x47, 0x45, 0x10, 0x02, 0x2a, 0x39, 0x0a, 0x0a, 0x52, 0x65, 0x67,
|
||||
0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x47, 0x55, 0x4c,
|
||||
0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12,
|
||||
0x13, 0x0a, 0x0f, 0x45, 0x54, 0x53, 0x49, 0x5f, 0x45, 0x4e, 0x5f, 0x33, 0x30, 0x30, 0x5f, 0x32,
|
||||
0x32, 0x30, 0x10, 0x01, 0x2a, 0x34, 0x0a, 0x0b, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6c,
|
||||
0x61, 0x73, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x41, 0x10, 0x00,
|
||||
0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x42, 0x10, 0x01, 0x12, 0x0b, 0x0a,
|
||||
0x07, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x43, 0x10, 0x02, 0x42, 0x69, 0x0a, 0x11, 0x69, 0x6f,
|
||||
0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42,
|
||||
0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31,
|
||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70,
|
||||
0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b,
|
||||
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
|
||||
0x6e, 0xaa, 0x02, 0x11, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x43,
|
||||
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x4e, 0x54, 0x48, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x49, 0x4e, 0x55, 0x54, 0x45, 0x10,
|
||||
0x03, 0x2a, 0x32, 0x0a, 0x0a, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4b, 0x69, 0x6e, 0x64, 0x12,
|
||||
0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08,
|
||||
0x41, 0x42, 0x53, 0x4f, 0x4c, 0x55, 0x54, 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x41,
|
||||
0x55, 0x47, 0x45, 0x10, 0x02, 0x2a, 0x39, 0x0a, 0x0a, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x47, 0x55, 0x4c, 0x41, 0x54, 0x49, 0x4f,
|
||||
0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x45,
|
||||
0x54, 0x53, 0x49, 0x5f, 0x45, 0x4e, 0x5f, 0x33, 0x30, 0x30, 0x5f, 0x32, 0x32, 0x30, 0x10, 0x01,
|
||||
0x2a, 0x34, 0x0a, 0x0b, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12,
|
||||
0x0b, 0x0a, 0x07, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x41, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07,
|
||||
0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x42, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4c, 0x41,
|
||||
0x53, 0x53, 0x5f, 0x43, 0x10, 0x02, 0x42, 0x69, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69,
|
||||
0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0b, 0x43, 0x6f, 0x6d,
|
||||
0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68,
|
||||
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63,
|
||||
0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69,
|
||||
0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0xaa, 0x02, 0x11,
|
||||
0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f,
|
||||
0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
27
api/proto/api/gateway.proto
vendored
27
api/proto/api/gateway.proto
vendored
@ -65,6 +65,14 @@ service GatewayService {
|
||||
get: "/api/gateways/{gateway_id}/metrics"
|
||||
};
|
||||
}
|
||||
|
||||
// GetDutyCycleMetrics returns the duty-cycle metrics.
|
||||
// Note that only the last 2 hours of data are stored. Currently only per minute aggregation is available.
|
||||
rpc GetDutyCycleMetrics(GetGatewayDutyCycleMetricsRequest) returns (GetGatewayDutyCycleMetricsResponse) {
|
||||
option(google.api.http) = {
|
||||
get: "/api/gateways/{gateway_id}/duty-cycle-metrics"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
enum GatewayState {
|
||||
@ -255,3 +263,22 @@ message GetGatewayMetricsResponse {
|
||||
// TX packets per status.
|
||||
common.Metric tx_packets_per_status = 7;
|
||||
}
|
||||
|
||||
message GetGatewayDutyCycleMetricsRequest {
|
||||
// Gateway ID (EUI64).
|
||||
string gateway_id = 1;
|
||||
|
||||
// Interval start timestamp.
|
||||
google.protobuf.Timestamp start = 2;
|
||||
|
||||
// Interval end timestamp.
|
||||
google.protobuf.Timestamp end = 3;
|
||||
}
|
||||
|
||||
message GetGatewayDutyCycleMetricsResponse {
|
||||
// Percentage relative to max load.
|
||||
common.Metric max_load_percentage = 1;
|
||||
|
||||
// Percentage relative to tracking window.
|
||||
common.Metric window_percentage = 2;
|
||||
}
|
||||
|
3
api/proto/common/common.proto
vendored
3
api/proto/common/common.proto
vendored
@ -141,6 +141,9 @@ enum Aggregation {
|
||||
|
||||
// Month.
|
||||
MONTH = 2;
|
||||
|
||||
// Minute.
|
||||
MINUTE = 3;
|
||||
}
|
||||
|
||||
enum MetricKind {
|
||||
|
27
api/rust/proto/chirpstack/api/gateway.proto
vendored
27
api/rust/proto/chirpstack/api/gateway.proto
vendored
@ -65,6 +65,14 @@ service GatewayService {
|
||||
get: "/api/gateways/{gateway_id}/metrics"
|
||||
};
|
||||
}
|
||||
|
||||
// GetDutyCycleMetrics returns the duty-cycle metrics.
|
||||
// Note that only the last 2 hours of data are stored. Currently only per minute aggregation is available.
|
||||
rpc GetDutyCycleMetrics(GetGatewayDutyCycleMetricsRequest) returns (GetGatewayDutyCycleMetricsResponse) {
|
||||
option(google.api.http) = {
|
||||
get: "/api/gateways/{gateway_id}/duty-cycle-metrics"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
enum GatewayState {
|
||||
@ -255,3 +263,22 @@ message GetGatewayMetricsResponse {
|
||||
// TX packets per status.
|
||||
common.Metric tx_packets_per_status = 7;
|
||||
}
|
||||
|
||||
message GetGatewayDutyCycleMetricsRequest {
|
||||
// Gateway ID (EUI64).
|
||||
string gateway_id = 1;
|
||||
|
||||
// Interval start timestamp.
|
||||
google.protobuf.Timestamp start = 2;
|
||||
|
||||
// Interval end timestamp.
|
||||
google.protobuf.Timestamp end = 3;
|
||||
}
|
||||
|
||||
message GetGatewayDutyCycleMetricsResponse {
|
||||
// Percentage relative to max load.
|
||||
common.Metric max_load_percentage = 1;
|
||||
|
||||
// Percentage relative to tracking window.
|
||||
common.Metric window_percentage = 2;
|
||||
}
|
||||
|
@ -141,6 +141,9 @@ enum Aggregation {
|
||||
|
||||
// Month.
|
||||
MONTH = 2;
|
||||
|
||||
// Minute.
|
||||
MINUTE = 3;
|
||||
}
|
||||
|
||||
enum MetricKind {
|
||||
|
@ -614,11 +614,180 @@ impl GatewayService for Gateway {
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_duty_cycle_metrics(
|
||||
&self,
|
||||
request: Request<api::GetGatewayDutyCycleMetricsRequest>,
|
||||
) -> Result<Response<api::GetGatewayDutyCycleMetricsResponse>, Status> {
|
||||
let req = request.get_ref();
|
||||
let gateway_id = EUI64::from_str(&req.gateway_id).map_err(|e| e.status())?;
|
||||
|
||||
self.validator
|
||||
.validate(
|
||||
request.extensions(),
|
||||
validator::ValidateGatewayAccess::new(validator::Flag::Read, gateway_id),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let start = SystemTime::try_from(
|
||||
req.start
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("start is None"))
|
||||
.map_err(|e| e.status())?
|
||||
.clone(),
|
||||
)
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
let end = SystemTime::try_from(
|
||||
req.end
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("end is None"))
|
||||
.map_err(|e| e.status())?
|
||||
.clone(),
|
||||
)
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
let start: DateTime<Local> = start.into();
|
||||
let end: DateTime<Local> = end.into();
|
||||
|
||||
let dc_metrics = metrics::get(
|
||||
&format!("gw:dc:{}", gateway_id),
|
||||
metrics::Kind::COUNTER,
|
||||
metrics::Aggregation::MINUTE,
|
||||
start,
|
||||
end,
|
||||
)
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
let out = api::GetGatewayDutyCycleMetricsResponse {
|
||||
max_load_percentage: Some({
|
||||
// discover all data-sets
|
||||
let mut datasets: HashSet<String> = HashSet::new();
|
||||
for m in &dc_metrics {
|
||||
for k in m.metrics.keys() {
|
||||
if k.starts_with("max_load_perc_") {
|
||||
datasets.insert(k.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
common::Metric {
|
||||
name: "Percentage of max tx duty-cycle".into(),
|
||||
timestamps: dc_metrics
|
||||
.iter()
|
||||
.map(|row| {
|
||||
let ts: DateTime<Utc> = row.time.into();
|
||||
let ts: pbjson_types::Timestamp = ts.into();
|
||||
ts
|
||||
})
|
||||
.collect(),
|
||||
datasets: datasets
|
||||
.iter()
|
||||
.map(|key| common::MetricDataset {
|
||||
label: {
|
||||
let s = key.strip_prefix("max_load_perc_").unwrap_or_default();
|
||||
let s: Vec<&str> = s.split('_').collect();
|
||||
|
||||
format!(
|
||||
"{} ({:.2}MHz - {:.2}MHz: {:.2}%)",
|
||||
s.first().unwrap_or(&""),
|
||||
s.get(1)
|
||||
.unwrap_or(&"")
|
||||
.parse::<f64>()
|
||||
.map(|v| v / 1_000_000.0)
|
||||
.unwrap_or(0.0),
|
||||
s.get(2)
|
||||
.unwrap_or(&"")
|
||||
.parse::<f64>()
|
||||
.map(|v| v / 1_000_000.0)
|
||||
.unwrap_or(0.0),
|
||||
s.get(3)
|
||||
.unwrap_or(&"")
|
||||
.parse::<f64>()
|
||||
.map(|v| v / 10.0)
|
||||
.unwrap_or(0.0),
|
||||
)
|
||||
},
|
||||
data: dc_metrics
|
||||
.iter()
|
||||
.map(|row| row.metrics.get(key).cloned().unwrap_or(0.0) as f32)
|
||||
.collect(),
|
||||
})
|
||||
.collect(),
|
||||
kind: common::MetricKind::Absolute.into(),
|
||||
}
|
||||
}),
|
||||
window_percentage: Some({
|
||||
// discover all data-sets
|
||||
let mut datasets: HashSet<String> = HashSet::new();
|
||||
for m in &dc_metrics {
|
||||
for k in m.metrics.keys() {
|
||||
if k.starts_with("window_perc_") {
|
||||
datasets.insert(k.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
common::Metric {
|
||||
name: "Tx duty-cycle".into(),
|
||||
timestamps: dc_metrics
|
||||
.iter()
|
||||
.map(|row| {
|
||||
let ts: DateTime<Utc> = row.time.into();
|
||||
let ts: pbjson_types::Timestamp = ts.into();
|
||||
ts
|
||||
})
|
||||
.collect(),
|
||||
datasets: datasets
|
||||
.iter()
|
||||
.map(|key| common::MetricDataset {
|
||||
label: {
|
||||
let s = key.strip_prefix("window_perc_").unwrap_or_default();
|
||||
let s: Vec<&str> = s.split('_').collect();
|
||||
|
||||
format!(
|
||||
"{} ({:.2}MHz - {:.2}MHz: {:.2}%)",
|
||||
s.first().unwrap_or(&""),
|
||||
s.get(1)
|
||||
.unwrap_or(&"")
|
||||
.parse::<f64>()
|
||||
.map(|v| v / 1_000_000.0)
|
||||
.unwrap_or(0.0),
|
||||
s.get(2)
|
||||
.unwrap_or(&"")
|
||||
.parse::<f64>()
|
||||
.map(|v| v / 1_000_000.0)
|
||||
.unwrap_or(0.0),
|
||||
s.get(3)
|
||||
.unwrap_or(&"")
|
||||
.parse::<f64>()
|
||||
.map(|v| v / 10.0)
|
||||
.unwrap_or(0.0),
|
||||
)
|
||||
},
|
||||
data: dc_metrics
|
||||
.iter()
|
||||
.map(|row| row.metrics.get(key).cloned().unwrap_or(0.0) as f32)
|
||||
.collect(),
|
||||
})
|
||||
.collect(),
|
||||
kind: common::MetricKind::Absolute.into(),
|
||||
}
|
||||
}),
|
||||
};
|
||||
|
||||
let mut resp = Response::new(out);
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-gateway_id", req.gateway_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod test {
|
||||
use chrono::{Datelike, Local, TimeZone};
|
||||
use chrono::{Datelike, Local, TimeZone, Timelike};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use super::*;
|
||||
@ -823,7 +992,13 @@ pub mod test {
|
||||
m.metrics.insert("tx_freq_868200000".into(), 5.0);
|
||||
m.metrics.insert("tx_dr_4".into(), 5.0);
|
||||
|
||||
metrics::save("gw:0102030405060708", &m).await.unwrap();
|
||||
metrics::save(
|
||||
"gw:0102030405060708",
|
||||
&m,
|
||||
&metrics::Aggregation::default_aggregations(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// setup api
|
||||
let service = Gateway::new(RequestValidator::new());
|
||||
@ -862,4 +1037,130 @@ pub mod test {
|
||||
stats_resp.rx_packets
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_gateway_duty_cycle_stats() {
|
||||
let _guard = test::prepare().await;
|
||||
|
||||
// setup admin user
|
||||
let u = user::User {
|
||||
is_admin: true,
|
||||
is_active: true,
|
||||
email: "admin@admin".into(),
|
||||
email_verified: true,
|
||||
..Default::default()
|
||||
};
|
||||
let u = user::create(u).await.unwrap();
|
||||
|
||||
// create tenant
|
||||
let t = tenant::create(tenant::Tenant {
|
||||
name: "test-tenant".into(),
|
||||
can_have_gateways: true,
|
||||
max_gateway_count: 10,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// create gateway
|
||||
let _ = gateway::create(gateway::Gateway {
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
tenant_id: t.id.clone(),
|
||||
name: "test-gw".into(),
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let now = Local::now();
|
||||
|
||||
// insert stats
|
||||
let mut m = metrics::Record {
|
||||
kind: metrics::Kind::COUNTER,
|
||||
time: now.into(),
|
||||
metrics: HashMap::new(),
|
||||
};
|
||||
|
||||
m.metrics
|
||||
.insert("window_perc_M_868000000_868600000_10".into(), 0.5);
|
||||
m.metrics
|
||||
.insert("max_load_perc_L_865000000_868000000_10".into(), 5.0);
|
||||
|
||||
metrics::save(
|
||||
"gw:dc:0102030405060708",
|
||||
&m,
|
||||
&[metrics::Aggregation::MINUTE],
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// setup api
|
||||
let service = Gateway::new(RequestValidator::new());
|
||||
|
||||
// request stats
|
||||
let now_st: SystemTime = now.into();
|
||||
let stats_req = api::GetGatewayDutyCycleMetricsRequest {
|
||||
gateway_id: "0102030405060708".into(),
|
||||
start: Some(now_st.into()),
|
||||
end: Some(now_st.into()),
|
||||
};
|
||||
let mut stats_req = Request::new(stats_req);
|
||||
stats_req
|
||||
.extensions_mut()
|
||||
.insert(AuthID::User(u.id.clone()));
|
||||
let stats_resp = service.get_duty_cycle_metrics(stats_req).await.unwrap();
|
||||
let stats_resp = stats_resp.get_ref();
|
||||
assert_eq!(
|
||||
Some(common::Metric {
|
||||
name: "Percentage of max tx duty-cycle".into(),
|
||||
timestamps: vec![{
|
||||
let ts = Local
|
||||
.with_ymd_and_hms(
|
||||
now.year(),
|
||||
now.month(),
|
||||
now.day(),
|
||||
now.hour(),
|
||||
now.minute(),
|
||||
0,
|
||||
)
|
||||
.unwrap();
|
||||
//let ts: SystemTime = ts.into();
|
||||
let ts: DateTime<Utc> = ts.into();
|
||||
ts.into()
|
||||
}],
|
||||
datasets: vec![common::MetricDataset {
|
||||
label: "L (865.00MHz - 868.00MHz: 1.00%)".into(),
|
||||
data: vec![5.0],
|
||||
}],
|
||||
kind: common::MetricKind::Absolute.into(),
|
||||
}),
|
||||
stats_resp.max_load_percentage
|
||||
);
|
||||
assert_eq!(
|
||||
Some(common::Metric {
|
||||
name: "Tx duty-cycle".into(),
|
||||
timestamps: vec![{
|
||||
let ts = Local
|
||||
.with_ymd_and_hms(
|
||||
now.year(),
|
||||
now.month(),
|
||||
now.day(),
|
||||
now.hour(),
|
||||
now.minute(),
|
||||
0,
|
||||
)
|
||||
.unwrap();
|
||||
//let ts: SystemTime = ts.into();
|
||||
let ts: DateTime<Utc> = ts.into();
|
||||
ts.into()
|
||||
}],
|
||||
datasets: vec![common::MetricDataset {
|
||||
label: "M (868.00MHz - 868.60MHz: 1.00%)".into(),
|
||||
data: vec![0.5],
|
||||
}],
|
||||
kind: common::MetricKind::Absolute.into(),
|
||||
}),
|
||||
stats_resp.window_percentage
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -169,6 +169,7 @@ impl FromProto<MeasurementKind> for api::MeasurementKind {
|
||||
impl ToProto<common::Aggregation> for Aggregation {
|
||||
fn to_proto(self) -> common::Aggregation {
|
||||
match self {
|
||||
Aggregation::MINUTE => common::Aggregation::Minute,
|
||||
Aggregation::HOUR => common::Aggregation::Hour,
|
||||
Aggregation::DAY => common::Aggregation::Day,
|
||||
Aggregation::MONTH => common::Aggregation::Month,
|
||||
@ -179,6 +180,7 @@ impl ToProto<common::Aggregation> for Aggregation {
|
||||
impl FromProto<Aggregation> for common::Aggregation {
|
||||
fn from_proto(self) -> Aggregation {
|
||||
match self {
|
||||
common::Aggregation::Minute => Aggregation::MINUTE,
|
||||
common::Aggregation::Hour => Aggregation::HOUR,
|
||||
common::Aggregation::Day => Aggregation::DAY,
|
||||
common::Aggregation::Month => Aggregation::MONTH,
|
||||
|
@ -13,11 +13,18 @@ use crate::storage::{get_async_redis_conn, redis_key};
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum Aggregation {
|
||||
MINUTE,
|
||||
HOUR,
|
||||
DAY,
|
||||
MONTH,
|
||||
}
|
||||
|
||||
impl Aggregation {
|
||||
pub fn default_aggregations() -> Vec<Aggregation> {
|
||||
vec![Aggregation::HOUR, Aggregation::DAY, Aggregation::MONTH]
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Aggregation {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:?}", self)
|
||||
@ -48,16 +55,13 @@ pub struct Record {
|
||||
|
||||
fn get_ttl(a: Aggregation) -> Duration {
|
||||
match a {
|
||||
Aggregation::MINUTE => Duration::from_secs(60 * 60 * 2), // two hours
|
||||
Aggregation::HOUR => Duration::from_secs(60 * 60 * 24 * 2), // two days
|
||||
Aggregation::DAY => Duration::from_secs(60 * 60 * 24 * 31 * 2), // two months
|
||||
Aggregation::MONTH => Duration::from_secs(60 * 60 * 24 * 365 * 2), // two years
|
||||
}
|
||||
}
|
||||
|
||||
fn get_aggregations() -> Vec<Aggregation> {
|
||||
vec![Aggregation::HOUR, Aggregation::DAY, Aggregation::MONTH]
|
||||
}
|
||||
|
||||
fn get_key(name: &str, a: Aggregation, dt: DateTime<Local>) -> String {
|
||||
redis_key(format!(
|
||||
"metrics:{{{}}}:{}:{}",
|
||||
@ -82,7 +86,7 @@ pub async fn save_state(name: &str, state: &str) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn save(name: &str, record: &Record) -> Result<()> {
|
||||
pub async fn save(name: &str, record: &Record, aggregations: &[Aggregation]) -> Result<()> {
|
||||
if record.metrics.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
@ -90,10 +94,20 @@ pub async fn save(name: &str, record: &Record) -> Result<()> {
|
||||
let mut pipe = redis::pipe();
|
||||
pipe.atomic();
|
||||
|
||||
for a in get_aggregations() {
|
||||
let ttl = get_ttl(a);
|
||||
for a in aggregations {
|
||||
let ttl = get_ttl(*a);
|
||||
|
||||
let ts: DateTime<Local> = match a {
|
||||
Aggregation::MINUTE => Local
|
||||
.with_ymd_and_hms(
|
||||
record.time.year(),
|
||||
record.time.month(),
|
||||
record.time.day(),
|
||||
record.time.hour(),
|
||||
record.time.minute(),
|
||||
0,
|
||||
)
|
||||
.unwrap(),
|
||||
Aggregation::HOUR => Local
|
||||
.with_ymd_and_hms(
|
||||
record.time.year(),
|
||||
@ -119,7 +133,7 @@ pub async fn save(name: &str, record: &Record) -> Result<()> {
|
||||
.unwrap(),
|
||||
};
|
||||
|
||||
let key = get_key(name, a, ts);
|
||||
let key = get_key(name, *a, ts);
|
||||
|
||||
for (k, v) in &record.metrics {
|
||||
// Passing a reference to hincr will return a runtime error.
|
||||
@ -178,6 +192,34 @@ pub async fn get(
|
||||
let mut timestamps: Vec<DateTime<Local>> = Vec::new();
|
||||
|
||||
match a {
|
||||
Aggregation::MINUTE => {
|
||||
let mut ts = Local
|
||||
.with_ymd_and_hms(
|
||||
start.year(),
|
||||
start.month(),
|
||||
start.day(),
|
||||
start.hour(),
|
||||
start.minute(),
|
||||
0,
|
||||
)
|
||||
.unwrap();
|
||||
let end = Local
|
||||
.with_ymd_and_hms(
|
||||
end.year(),
|
||||
end.month(),
|
||||
end.day(),
|
||||
end.hour(),
|
||||
end.minute(),
|
||||
0,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
while ts.le(&end) {
|
||||
timestamps.push(ts);
|
||||
keys.push(get_key(name, a, ts));
|
||||
ts += ChronoDuration::minutes(1);
|
||||
}
|
||||
}
|
||||
Aggregation::HOUR => {
|
||||
let mut ts = Local
|
||||
.with_ymd_and_hms(start.year(), start.month(), start.day(), start.hour(), 0, 0)
|
||||
@ -304,6 +346,41 @@ pub mod test {
|
||||
use super::*;
|
||||
use crate::test;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_minute() {
|
||||
let _guard = test::prepare().await;
|
||||
|
||||
let records = vec![
|
||||
Record {
|
||||
time: Local.with_ymd_and_hms(2018, 1, 1, 1, 1, 0).unwrap(),
|
||||
kind: Kind::ABSOLUTE,
|
||||
metrics: [("foo".into(), 1f64), ("bar".into(), 2f64)]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect(),
|
||||
},
|
||||
Record {
|
||||
time: Local.with_ymd_and_hms(2018, 1, 1, 1, 1, 10).unwrap(),
|
||||
kind: Kind::ABSOLUTE,
|
||||
metrics: [("foo".into(), 4f64), ("bar".into(), 4f64)]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect(),
|
||||
},
|
||||
Record {
|
||||
time: Local.with_ymd_and_hms(2018, 1, 1, 1, 2, 0).unwrap(),
|
||||
kind: Kind::ABSOLUTE,
|
||||
metrics: [("foo".into(), 5f64), ("bar".into(), 6f64)]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect(),
|
||||
},
|
||||
];
|
||||
for r in &records {
|
||||
save("test", r, &[Aggregation::MINUTE]).await.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_hour() {
|
||||
let _guard = test::prepare().await;
|
||||
@ -335,7 +412,7 @@ pub mod test {
|
||||
},
|
||||
];
|
||||
for r in &records {
|
||||
save("test", r).await.unwrap();
|
||||
save("test", r, &[Aggregation::HOUR]).await.unwrap();
|
||||
}
|
||||
|
||||
let resp = get(
|
||||
@ -402,7 +479,7 @@ pub mod test {
|
||||
},
|
||||
];
|
||||
for r in &records {
|
||||
save("test", r).await.unwrap();
|
||||
save("test", r, &[Aggregation::DAY]).await.unwrap();
|
||||
}
|
||||
|
||||
let resp = get(
|
||||
@ -469,7 +546,7 @@ pub mod test {
|
||||
},
|
||||
];
|
||||
for r in &records {
|
||||
save("test", r).await.unwrap();
|
||||
save("test", r, &[Aggregation::DAY]).await.unwrap();
|
||||
}
|
||||
|
||||
let resp = get(
|
||||
@ -536,7 +613,7 @@ pub mod test {
|
||||
},
|
||||
];
|
||||
for r in &records {
|
||||
save("test", r).await.unwrap();
|
||||
save("test", r, &[Aggregation::MONTH]).await.unwrap();
|
||||
}
|
||||
|
||||
let resp = get(
|
||||
@ -595,7 +672,7 @@ pub mod test {
|
||||
},
|
||||
];
|
||||
for r in &records {
|
||||
save("test", r).await.unwrap();
|
||||
save("test", r, &[Aggregation::HOUR]).await.unwrap();
|
||||
}
|
||||
|
||||
let resp = get(
|
||||
@ -644,7 +721,7 @@ pub mod test {
|
||||
},
|
||||
];
|
||||
for r in &records {
|
||||
save("test", r).await.unwrap();
|
||||
save("test", r, &[Aggregation::HOUR]).await.unwrap();
|
||||
}
|
||||
|
||||
let resp = get(
|
||||
@ -693,7 +770,7 @@ pub mod test {
|
||||
},
|
||||
];
|
||||
for r in &records {
|
||||
save("test", r).await.unwrap();
|
||||
save("test", r, &[Aggregation::HOUR]).await.unwrap();
|
||||
}
|
||||
|
||||
let resp = get(
|
||||
|
@ -1045,7 +1045,12 @@ impl Data {
|
||||
metrics: [("value".to_string(), v)].iter().cloned().collect(),
|
||||
};
|
||||
|
||||
metrics::save(&format!("device:{}:{}", dev.dev_eui, k), &record).await?;
|
||||
metrics::save(
|
||||
&format!("device:{}:{}", dev.dev_eui, k),
|
||||
&record,
|
||||
&metrics::Aggregation::default_aggregations(),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
pbjson_types::value::Kind::StringValue(v) => {
|
||||
metrics::save_state(
|
||||
@ -1215,7 +1220,12 @@ impl Data {
|
||||
|
||||
let dev = self.device.as_ref().unwrap();
|
||||
|
||||
metrics::save(&format!("device:{}", dev.dev_eui), &record).await?;
|
||||
metrics::save(
|
||||
&format!("device:{}", dev.dev_eui),
|
||||
&record,
|
||||
&metrics::Aggregation::default_aggregations(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1246,7 +1256,12 @@ impl Data {
|
||||
|
||||
let dev = self.device.as_ref().unwrap();
|
||||
|
||||
metrics::save(&format!("device:{}", dev.dev_eui), &record).await?;
|
||||
metrics::save(
|
||||
&format!("device:{}", dev.dev_eui),
|
||||
&record,
|
||||
&metrics::Aggregation::default_aggregations(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -441,6 +441,7 @@ impl JoinRequest {
|
||||
.cloned()
|
||||
.collect(),
|
||||
},
|
||||
&metrics::Aggregation::default_aggregations(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@ -490,6 +491,7 @@ impl JoinRequest {
|
||||
kind: metrics::Kind::ABSOLUTE,
|
||||
metrics: [("error_OTAA".into(), 1f64)].iter().cloned().collect(),
|
||||
},
|
||||
&metrics::Aggregation::default_aggregations(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
@ -338,6 +338,7 @@ impl JoinRequest {
|
||||
.cloned()
|
||||
.collect(),
|
||||
},
|
||||
&metrics::Aggregation::default_aggregations(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@ -387,6 +388,7 @@ impl JoinRequest {
|
||||
kind: metrics::Kind::ABSOLUTE,
|
||||
metrics: [("error_OTAA".into(), 1f64)].iter().cloned().collect(),
|
||||
},
|
||||
&metrics::Aggregation::default_aggregations(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
@ -2,6 +2,7 @@ use std::collections::hash_map::DefaultHasher;
|
||||
use std::collections::HashMap;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use chrono::{DateTime, Local, Utc};
|
||||
@ -63,6 +64,7 @@ impl Stats {
|
||||
|
||||
ctx.update_gateway_state().await?;
|
||||
ctx.save_stats().await?;
|
||||
ctx.save_duty_cycle_stats().await?;
|
||||
ctx.update_gateway_configuration().await?;
|
||||
|
||||
Ok(())
|
||||
@ -156,6 +158,7 @@ impl Stats {
|
||||
metrics::save(
|
||||
&format!("gw:{}", self.gateway.as_ref().unwrap().gateway_id),
|
||||
&m,
|
||||
&metrics::Aggregation::default_aggregations(),
|
||||
)
|
||||
.await
|
||||
.context("Save gateway stats")?;
|
||||
@ -163,6 +166,73 @@ impl Stats {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn save_duty_cycle_stats(&self) -> Result<()> {
|
||||
trace!("Saving duty-cycle stats");
|
||||
|
||||
let duty_cycle_stats = match self.stats.duty_cycle_stats.as_ref() {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
// No stats, nothing to do.
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
let window: Duration = duty_cycle_stats
|
||||
.window
|
||||
.clone()
|
||||
.map(|v| v.try_into().unwrap_or_default())
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut m = metrics::Record {
|
||||
time: match &self.stats.time {
|
||||
Some(v) => DateTime::try_from(v.clone())
|
||||
.map_err(anyhow::Error::msg)?
|
||||
.into(),
|
||||
None => Local::now(),
|
||||
},
|
||||
kind: metrics::Kind::COUNTER,
|
||||
metrics: HashMap::new(),
|
||||
};
|
||||
|
||||
for b in &duty_cycle_stats.bands {
|
||||
let load_max: Duration = b
|
||||
.load_max
|
||||
.clone()
|
||||
.map(|d| d.try_into().unwrap_or_default())
|
||||
.unwrap_or_default();
|
||||
let load_tracked: Duration = b
|
||||
.load_tracked
|
||||
.clone()
|
||||
.map(|d| d.try_into().unwrap_or_default())
|
||||
.unwrap_or_default();
|
||||
|
||||
let permille = load_max.as_nanos() / (window.as_nanos() / 1000);
|
||||
let key = format!(
|
||||
"{}_{}_{}_{}",
|
||||
b.name, b.frequency_min, b.frequency_max, permille
|
||||
);
|
||||
let dc_max_load_perc_key = format!("max_load_perc_{}", key);
|
||||
let dc_window_perc_key = format!("window_perc_{}", key);
|
||||
|
||||
let dc_max_load_perc =
|
||||
load_tracked.as_nanos() as f64 / load_max.as_nanos() as f64 * 100.0;
|
||||
let dc_window_perc = load_tracked.as_nanos() as f64 / window.as_nanos() as f64 * 100.0;
|
||||
|
||||
m.metrics.insert(dc_max_load_perc_key, dc_max_load_perc);
|
||||
m.metrics.insert(dc_window_perc_key, dc_window_perc);
|
||||
}
|
||||
|
||||
metrics::save(
|
||||
&format!("gw:dc:{}", self.gateway.as_ref().unwrap().gateway_id),
|
||||
&m,
|
||||
&[metrics::Aggregation::MINUTE],
|
||||
)
|
||||
.await
|
||||
.context("Save gateway duty-cycle stats")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_gateway_configuration(&self) -> Result<()> {
|
||||
trace!("Updating gateway configuration");
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
"chartjs-adapter-moment": "^1.0.1",
|
||||
"chartjs-chart-matrix": "^2.0.1",
|
||||
"codemirror": "5.65.3",
|
||||
"google-palette": "^1.1.1",
|
||||
"history": "^5.3.0",
|
||||
"js-file-download": "^0.4.12",
|
||||
"leaflet": "^1.9.4",
|
||||
|
@ -3,6 +3,7 @@ import { Card } from "antd";
|
||||
import { TimeUnit } from "chart.js";
|
||||
import { Bar } from "react-chartjs-2";
|
||||
import moment from "moment";
|
||||
import palette from "google-palette";
|
||||
|
||||
import { Metric, Aggregation } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
|
||||
|
||||
@ -19,24 +20,6 @@ function MetricBar(props: IProps) {
|
||||
unit = "month";
|
||||
}
|
||||
|
||||
let backgroundColors = [
|
||||
"#8bc34a",
|
||||
"#ff5722",
|
||||
"#ff9800",
|
||||
"#ffc107",
|
||||
"#ffeb3b",
|
||||
"#cddc39",
|
||||
"#4caf50",
|
||||
"#009688",
|
||||
"#00bcd4",
|
||||
"#03a9f4",
|
||||
"#2196f3",
|
||||
"#3f51b5",
|
||||
"#673ab7",
|
||||
"#9c27b0",
|
||||
"#e91e63",
|
||||
];
|
||||
|
||||
const animation: false = false;
|
||||
|
||||
const options = {
|
||||
@ -72,13 +55,13 @@ function MetricBar(props: IProps) {
|
||||
datasets: [],
|
||||
};
|
||||
|
||||
for (let ds of props.metric.getDatasetsList()) {
|
||||
props.metric.getDatasetsList().forEach((ds, i) => {
|
||||
data.datasets.push({
|
||||
label: ds.getLabel(),
|
||||
data: ds.getDataList(),
|
||||
backgroundColor: backgroundColors.shift()!,
|
||||
backgroundColor: palette("cb-Paired", props.metric.getDatasetsList().length).map((hex: string) => "#" + hex)[i],
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<Card title={props.metric.getName()} className="dashboard-chart">
|
||||
|
@ -3,6 +3,7 @@ import { Card } from "antd";
|
||||
import { TimeUnit } from "chart.js";
|
||||
import { Line } from "react-chartjs-2";
|
||||
import moment from "moment";
|
||||
import palette from "google-palette";
|
||||
|
||||
import { Metric, Aggregation, MetricKind } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
|
||||
|
||||
@ -21,6 +22,9 @@ function MetricChart(props: IProps) {
|
||||
} else if (props.aggregation === Aggregation.MONTH) {
|
||||
unit = "month";
|
||||
tooltipFormat = "MMM YYYY";
|
||||
} else if (props.aggregation === Aggregation.MINUTE) {
|
||||
unit = "minute";
|
||||
tooltipFormat = "LT";
|
||||
}
|
||||
|
||||
const animation: false = false;
|
||||
@ -50,31 +54,37 @@ function MetricChart(props: IProps) {
|
||||
let prevValue = 0;
|
||||
let data = {
|
||||
labels: props.metric.getTimestampsList().map(v => moment(v.toDate()).valueOf()),
|
||||
datasets: props.metric.getDatasetsList().map(v => {
|
||||
return {
|
||||
label: v.getLabel(),
|
||||
borderColor: "rgba(33, 150, 243, 1)",
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
lineTension: 0,
|
||||
pointBackgroundColor: "rgba(33, 150, 243, 1)",
|
||||
data: v.getDataList().map(v => {
|
||||
if (v === 0 && props.zeroToNull) {
|
||||
return null;
|
||||
} else {
|
||||
if (props.metric.getKind() === MetricKind.COUNTER) {
|
||||
let val = v - prevValue;
|
||||
prevValue = v;
|
||||
if (val < 0) {
|
||||
return 0;
|
||||
}
|
||||
return val;
|
||||
datasets: props.metric
|
||||
.getDatasetsList()
|
||||
.sort((a, b) => a.getLabel().localeCompare(b.getLabel()))
|
||||
.map((v, i) => {
|
||||
const colors = palette("cb-Paired", props.metric.getDatasetsList().length).map((hex: string) => "#" + hex);
|
||||
console.log(v.getLabel());
|
||||
console.log(colors[i]);
|
||||
|
||||
return {
|
||||
label: v.getLabel(),
|
||||
borderColor: colors[i],
|
||||
pointBackgroundColor: colors[i],
|
||||
lineTension: 0,
|
||||
data: v.getDataList().map(v => {
|
||||
if (v === 0 && props.zeroToNull) {
|
||||
return null;
|
||||
} else {
|
||||
return v;
|
||||
if (props.metric.getKind() === MetricKind.COUNTER) {
|
||||
let val = v - prevValue;
|
||||
prevValue = v;
|
||||
if (val < 0) {
|
||||
return 0;
|
||||
}
|
||||
return val;
|
||||
} else {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
};
|
||||
}),
|
||||
}),
|
||||
};
|
||||
}),
|
||||
};
|
||||
|
||||
let name = props.metric.getName();
|
||||
|
@ -124,7 +124,7 @@ pre {
|
||||
|
||||
.ant-drawer {
|
||||
padding-top: 64px;
|
||||
z-index:1002;
|
||||
z-index: 1002;
|
||||
}
|
||||
|
||||
.ant-drawer-body {
|
||||
|
@ -11,6 +11,8 @@ import {
|
||||
ListGatewaysResponse,
|
||||
GetGatewayMetricsRequest,
|
||||
GetGatewayMetricsResponse,
|
||||
GetGatewayDutyCycleMetricsRequest,
|
||||
GetGatewayDutyCycleMetricsResponse,
|
||||
GenerateGatewayClientCertificateRequest,
|
||||
GenerateGatewayClientCertificateResponse,
|
||||
} from "@chirpstack/chirpstack-api-grpc-web/api/gateway_pb";
|
||||
@ -107,6 +109,20 @@ class GatewayStore extends EventEmitter {
|
||||
});
|
||||
};
|
||||
|
||||
getDutyCycleMetrics = (
|
||||
req: GetGatewayDutyCycleMetricsRequest,
|
||||
callbackFunc: (resp: GetGatewayDutyCycleMetricsResponse) => void,
|
||||
) => {
|
||||
this.client.getDutyCycleMetrics(req, SessionStore.getMetadata(), (err, resp) => {
|
||||
if (err !== null) {
|
||||
HandleError(err);
|
||||
return;
|
||||
}
|
||||
|
||||
callbackFunc(resp);
|
||||
});
|
||||
};
|
||||
|
||||
generateClientCertificate = (
|
||||
req: GenerateGatewayClientCertificateRequest,
|
||||
callbackFunc: (resp: GenerateGatewayClientCertificateResponse) => void,
|
||||
|
@ -8,6 +8,8 @@ import {
|
||||
Gateway,
|
||||
GetGatewayMetricsRequest,
|
||||
GetGatewayMetricsResponse,
|
||||
GetGatewayDutyCycleMetricsRequest,
|
||||
GetGatewayDutyCycleMetricsResponse,
|
||||
} from "@chirpstack/chirpstack-api-grpc-web/api/gateway_pb";
|
||||
import { Aggregation } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
|
||||
|
||||
@ -25,6 +27,9 @@ interface IProps {
|
||||
function GatewayDashboard(props: IProps) {
|
||||
const [metricsAggregation] = useState<Aggregation>(Aggregation.DAY);
|
||||
const [gatewayMetrics, setGatewayMetrics] = useState<GetGatewayMetricsResponse | undefined>(undefined);
|
||||
const [gatewayDutyCycleMetrics, setGatewayDutyCycleMetrics] = useState<
|
||||
GetGatewayDutyCycleMetricsResponse | undefined
|
||||
>(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
const agg = metricsAggregation;
|
||||
@ -54,12 +59,29 @@ function GatewayDashboard(props: IProps) {
|
||||
GatewayStore.getMetrics(req, (resp: GetGatewayMetricsResponse) => {
|
||||
setGatewayMetrics(resp);
|
||||
});
|
||||
|
||||
const dcEnd = moment().subtract(1, "minute");
|
||||
let dcEndPb = new Timestamp();
|
||||
dcEndPb.fromDate(dcEnd.toDate());
|
||||
|
||||
const dcStart = dcEnd.subtract(1, "hours");
|
||||
let dcStartPb = new Timestamp();
|
||||
dcStartPb.fromDate(dcStart.toDate());
|
||||
|
||||
let dcReq = new GetGatewayDutyCycleMetricsRequest();
|
||||
dcReq.setGatewayId(props.gateway.getGatewayId());
|
||||
dcReq.setStart(dcStartPb);
|
||||
dcReq.setEnd(dcEndPb);
|
||||
|
||||
GatewayStore.getDutyCycleMetrics(dcReq, (resp: GetGatewayDutyCycleMetricsResponse) => {
|
||||
setGatewayDutyCycleMetrics(resp);
|
||||
});
|
||||
}, [props, metricsAggregation]);
|
||||
|
||||
const loc = props.gateway.getLocation()!;
|
||||
const location: [number, number] = [loc.getLatitude(), loc.getLongitude()];
|
||||
|
||||
if (gatewayMetrics === undefined) {
|
||||
if (gatewayMetrics === undefined || gatewayDutyCycleMetrics === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -89,6 +111,17 @@ function GatewayDashboard(props: IProps) {
|
||||
</Map>
|
||||
</Col>
|
||||
</Row>
|
||||
{gatewayDutyCycleMetrics.getMaxLoadPercentage()!.getDatasetsList().length !== 0 &&
|
||||
gatewayDutyCycleMetrics.getWindowPercentage()!.getDatasetsList().length !== 0 && (
|
||||
<Row gutter={24}>
|
||||
<Col span={12}>
|
||||
<MetricChart metric={gatewayDutyCycleMetrics.getWindowPercentage()!} aggregation={Aggregation.MINUTE} />
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<MetricChart metric={gatewayDutyCycleMetrics.getMaxLoadPercentage()!} aggregation={Aggregation.MINUTE} />
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
<Row gutter={24}>
|
||||
<Col span={8}>
|
||||
<MetricChart metric={gatewayMetrics.getRxPackets()!} aggregation={metricsAggregation} />
|
||||
|
@ -14,7 +14,8 @@
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx"
|
||||
"jsx": "react-jsx",
|
||||
"typeRoots": ["./types", "./node_modules/@types"]
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
1
ui/types/google-palette/index.d.ts
vendored
Normal file
1
ui/types/google-palette/index.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
declare module "google-palette";
|
@ -1256,7 +1256,7 @@
|
||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||
|
||||
"@chirpstack/chirpstack-api-grpc-web@file:../api/grpc-web":
|
||||
version "4.7.0"
|
||||
version "4.8.0-test.2"
|
||||
dependencies:
|
||||
"@types/google-protobuf" "^3.15.12"
|
||||
google-protobuf "^3.21.2"
|
||||
@ -5433,6 +5433,11 @@ globby@^11.0.4, globby@^11.1.0:
|
||||
merge2 "^1.4.1"
|
||||
slash "^3.0.0"
|
||||
|
||||
google-palette@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/google-palette/-/google-palette-1.1.1.tgz#671b3b932c8393271b67da908ccd7f2c48e84cc7"
|
||||
integrity sha512-yZiM5oLl8lCZzf06IMOGdDkxqvCMd9HNFcCiOMqWgGGiGzC22vWBVhKJNvykXXbeC0NAElNH97jA/y0bq6TCrA==
|
||||
|
||||
google-protobuf@^3.21.2:
|
||||
version "3.21.2"
|
||||
resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.21.2.tgz#4580a2bea8bbb291ee579d1fefb14d6fa3070ea4"
|
||||
|
Loading…
x
Reference in New Issue
Block a user