mirror of
https://github.com/chirpstack/chirpstack.git
synced 2025-06-17 06:48:24 +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:
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
|
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 protoreflect.FileDescriptor
|
||||||
|
|
||||||
var file_api_gateway_proto_rawDesc = []byte{
|
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, 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,
|
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,
|
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,
|
0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x50, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22,
|
||||||
0x37, 0x0a, 0x0c, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12,
|
0xa2, 0x01, 0x0a, 0x21, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x44, 0x75,
|
||||||
0x0e, 0x0a, 0x0a, 0x4e, 0x45, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x45, 0x4e, 0x10, 0x00, 0x12,
|
0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65,
|
||||||
0x0a, 0x0a, 0x06, 0x4f, 0x4e, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4f,
|
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
|
||||||
0x46, 0x46, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x02, 0x32, 0x91, 0x06, 0x0a, 0x0e, 0x47, 0x61, 0x74,
|
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77,
|
||||||
0x65, 0x77, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x06, 0x43,
|
0x61, 0x79, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20,
|
||||||
0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61,
|
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||||
0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
|
||||||
0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20,
|
||||||
0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12,
|
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||||
0x3a, 0x01, 0x2a, 0x22, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
|
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
|
||||||
0x79, 0x73, 0x12, 0x5a, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
0x03, 0x65, 0x6e, 0x64, 0x22, 0xa1, 0x01, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65,
|
||||||
0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
0x77, 0x61, 0x79, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72,
|
||||||
0x74, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77,
|
0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x13, 0x6d,
|
||||||
0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93,
|
0x61, 0x78, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61,
|
||||||
0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
|
0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
|
||||||
0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x6a,
|
0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x11, 0x6d, 0x61, 0x78, 0x4c, 0x6f, 0x61,
|
||||||
0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55,
|
0x64, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x11, 0x77,
|
||||||
0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75,
|
0x69, 0x6e, 0x64, 0x6f, 0x77, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65,
|
||||||
0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
|
||||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x2d, 0x82, 0xd3, 0xe4,
|
0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x10, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x50, 0x65,
|
||||||
0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a, 0x1a, 0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74,
|
0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x2a, 0x37, 0x0a, 0x0c, 0x47, 0x61, 0x74, 0x65,
|
||||||
0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x67,
|
0x77, 0x61, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x45, 0x56, 0x45,
|
||||||
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x5f, 0x0a, 0x06, 0x44, 0x65,
|
0x52, 0x5f, 0x53, 0x45, 0x45, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x4e, 0x4c, 0x49,
|
||||||
0x6c, 0x65, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
|
0x4e, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x46, 0x46, 0x4c, 0x49, 0x4e, 0x45, 0x10,
|
||||||
0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
0x02, 0x32, 0xb1, 0x07, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x65, 0x72,
|
||||||
0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x19,
|
||||||
0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x2a,
|
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77,
|
||||||
0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b,
|
0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||||
0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x52, 0x0a, 0x04, 0x4c,
|
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
|
||||||
0x69, 0x73, 0x74, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x61,
|
0x79, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x3a, 0x01, 0x2a, 0x22, 0x0d, 0x2f, 0x61,
|
||||||
0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e,
|
0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0x5a, 0x0a, 0x03, 0x47,
|
||||||
0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73,
|
0x65, 0x74, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65,
|
||||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f,
|
0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69,
|
||||||
0x12, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x12,
|
0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||||
0xb1, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65,
|
0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x61, 0x70,
|
||||||
0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x2e,
|
0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65,
|
||||||
0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65,
|
0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x6a, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74,
|
||||||
0x77, 0x61, 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
|
0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x61,
|
||||||
0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x61, 0x70,
|
0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67,
|
||||||
0x69, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61,
|
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
|
||||||
0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
|
0x6d, 0x70, 0x74, 0x79, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a, 0x1a,
|
||||||
0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93,
|
0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b,
|
||||||
0x02, 0x31, 0x22, 0x2f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
|
0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f,
|
||||||
0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67,
|
0x69, 0x64, 0x7d, 0x12, 0x5f, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x19, 0x2e,
|
||||||
0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
|
0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61,
|
||||||
0x61, 0x74, 0x65, 0x12, 0x77, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
|
0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||||
0x73, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77,
|
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
|
||||||
0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x2a, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67,
|
||||||
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,
|
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,
|
0x5f, 0x69, 0x64, 0x7d, 0x12, 0x52, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x18, 0x2e, 0x61,
|
||||||
0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70,
|
0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52,
|
||||||
0x69, 0x42, 0x0c, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50,
|
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73,
|
||||||
0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68,
|
0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||||
0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74,
|
0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f,
|
||||||
0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70,
|
0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0xb1, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x6e,
|
||||||
0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41,
|
0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69,
|
||||||
0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
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 (
|
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_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{}{
|
var file_api_gateway_proto_goTypes = []interface{}{
|
||||||
(GatewayState)(0), // 0: api.GatewayState
|
(GatewayState)(0), // 0: api.GatewayState
|
||||||
(*Gateway)(nil), // 1: api.Gateway
|
(*Gateway)(nil), // 1: api.Gateway
|
||||||
@ -1295,62 +1449,70 @@ var file_api_gateway_proto_goTypes = []interface{}{
|
|||||||
(*GenerateGatewayClientCertificateResponse)(nil), // 11: api.GenerateGatewayClientCertificateResponse
|
(*GenerateGatewayClientCertificateResponse)(nil), // 11: api.GenerateGatewayClientCertificateResponse
|
||||||
(*GetGatewayMetricsRequest)(nil), // 12: api.GetGatewayMetricsRequest
|
(*GetGatewayMetricsRequest)(nil), // 12: api.GetGatewayMetricsRequest
|
||||||
(*GetGatewayMetricsResponse)(nil), // 13: api.GetGatewayMetricsResponse
|
(*GetGatewayMetricsResponse)(nil), // 13: api.GetGatewayMetricsResponse
|
||||||
nil, // 14: api.Gateway.TagsEntry
|
(*GetGatewayDutyCycleMetricsRequest)(nil), // 14: api.GetGatewayDutyCycleMetricsRequest
|
||||||
nil, // 15: api.Gateway.MetadataEntry
|
(*GetGatewayDutyCycleMetricsResponse)(nil), // 15: api.GetGatewayDutyCycleMetricsResponse
|
||||||
nil, // 16: api.GatewayListItem.PropertiesEntry
|
nil, // 16: api.Gateway.TagsEntry
|
||||||
(*common.Location)(nil), // 17: common.Location
|
nil, // 17: api.Gateway.MetadataEntry
|
||||||
(*timestamppb.Timestamp)(nil), // 18: google.protobuf.Timestamp
|
nil, // 18: api.GatewayListItem.PropertiesEntry
|
||||||
(common.Aggregation)(0), // 19: common.Aggregation
|
(*common.Location)(nil), // 19: common.Location
|
||||||
(*common.Metric)(nil), // 20: common.Metric
|
(*timestamppb.Timestamp)(nil), // 20: google.protobuf.Timestamp
|
||||||
(*emptypb.Empty)(nil), // 21: google.protobuf.Empty
|
(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{
|
var file_api_gateway_proto_depIdxs = []int32{
|
||||||
17, // 0: api.Gateway.location:type_name -> common.Location
|
19, // 0: api.Gateway.location:type_name -> common.Location
|
||||||
14, // 1: api.Gateway.tags:type_name -> api.Gateway.TagsEntry
|
16, // 1: api.Gateway.tags:type_name -> api.Gateway.TagsEntry
|
||||||
15, // 2: api.Gateway.metadata:type_name -> api.Gateway.MetadataEntry
|
17, // 2: api.Gateway.metadata:type_name -> api.Gateway.MetadataEntry
|
||||||
17, // 3: api.GatewayListItem.location:type_name -> common.Location
|
19, // 3: api.GatewayListItem.location:type_name -> common.Location
|
||||||
16, // 4: api.GatewayListItem.properties:type_name -> api.GatewayListItem.PropertiesEntry
|
18, // 4: api.GatewayListItem.properties:type_name -> api.GatewayListItem.PropertiesEntry
|
||||||
18, // 5: api.GatewayListItem.created_at:type_name -> google.protobuf.Timestamp
|
20, // 5: api.GatewayListItem.created_at:type_name -> google.protobuf.Timestamp
|
||||||
18, // 6: api.GatewayListItem.updated_at:type_name -> google.protobuf.Timestamp
|
20, // 6: api.GatewayListItem.updated_at:type_name -> google.protobuf.Timestamp
|
||||||
18, // 7: api.GatewayListItem.last_seen_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
|
0, // 8: api.GatewayListItem.state:type_name -> api.GatewayState
|
||||||
1, // 9: api.CreateGatewayRequest.gateway:type_name -> api.Gateway
|
1, // 9: api.CreateGatewayRequest.gateway:type_name -> api.Gateway
|
||||||
1, // 10: api.GetGatewayResponse.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
|
20, // 11: api.GetGatewayResponse.created_at:type_name -> google.protobuf.Timestamp
|
||||||
18, // 12: api.GetGatewayResponse.updated_at:type_name -> google.protobuf.Timestamp
|
20, // 12: api.GetGatewayResponse.updated_at:type_name -> google.protobuf.Timestamp
|
||||||
18, // 13: api.GetGatewayResponse.last_seen_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
|
1, // 14: api.UpdateGatewayRequest.gateway:type_name -> api.Gateway
|
||||||
2, // 15: api.ListGatewaysResponse.result:type_name -> api.GatewayListItem
|
2, // 15: api.ListGatewaysResponse.result:type_name -> api.GatewayListItem
|
||||||
18, // 16: api.GenerateGatewayClientCertificateResponse.expires_at:type_name -> google.protobuf.Timestamp
|
20, // 16: api.GenerateGatewayClientCertificateResponse.expires_at:type_name -> google.protobuf.Timestamp
|
||||||
18, // 17: api.GetGatewayMetricsRequest.start:type_name -> google.protobuf.Timestamp
|
20, // 17: api.GetGatewayMetricsRequest.start:type_name -> google.protobuf.Timestamp
|
||||||
18, // 18: api.GetGatewayMetricsRequest.end:type_name -> google.protobuf.Timestamp
|
20, // 18: api.GetGatewayMetricsRequest.end:type_name -> google.protobuf.Timestamp
|
||||||
19, // 19: api.GetGatewayMetricsRequest.aggregation:type_name -> common.Aggregation
|
21, // 19: api.GetGatewayMetricsRequest.aggregation:type_name -> common.Aggregation
|
||||||
20, // 20: api.GetGatewayMetricsResponse.rx_packets:type_name -> common.Metric
|
22, // 20: api.GetGatewayMetricsResponse.rx_packets:type_name -> common.Metric
|
||||||
20, // 21: api.GetGatewayMetricsResponse.tx_packets:type_name -> common.Metric
|
22, // 21: api.GetGatewayMetricsResponse.tx_packets:type_name -> common.Metric
|
||||||
20, // 22: api.GetGatewayMetricsResponse.tx_packets_per_freq:type_name -> common.Metric
|
22, // 22: api.GetGatewayMetricsResponse.tx_packets_per_freq:type_name -> common.Metric
|
||||||
20, // 23: api.GetGatewayMetricsResponse.rx_packets_per_freq:type_name -> common.Metric
|
22, // 23: api.GetGatewayMetricsResponse.rx_packets_per_freq:type_name -> common.Metric
|
||||||
20, // 24: api.GetGatewayMetricsResponse.tx_packets_per_dr:type_name -> common.Metric
|
22, // 24: api.GetGatewayMetricsResponse.tx_packets_per_dr:type_name -> common.Metric
|
||||||
20, // 25: api.GetGatewayMetricsResponse.rx_packets_per_dr:type_name -> common.Metric
|
22, // 25: api.GetGatewayMetricsResponse.rx_packets_per_dr:type_name -> common.Metric
|
||||||
20, // 26: api.GetGatewayMetricsResponse.tx_packets_per_status:type_name -> common.Metric
|
22, // 26: api.GetGatewayMetricsResponse.tx_packets_per_status:type_name -> common.Metric
|
||||||
3, // 27: api.GatewayService.Create:input_type -> api.CreateGatewayRequest
|
20, // 27: api.GetGatewayDutyCycleMetricsRequest.start:type_name -> google.protobuf.Timestamp
|
||||||
4, // 28: api.GatewayService.Get:input_type -> api.GetGatewayRequest
|
20, // 28: api.GetGatewayDutyCycleMetricsRequest.end:type_name -> google.protobuf.Timestamp
|
||||||
6, // 29: api.GatewayService.Update:input_type -> api.UpdateGatewayRequest
|
22, // 29: api.GetGatewayDutyCycleMetricsResponse.max_load_percentage:type_name -> common.Metric
|
||||||
7, // 30: api.GatewayService.Delete:input_type -> api.DeleteGatewayRequest
|
22, // 30: api.GetGatewayDutyCycleMetricsResponse.window_percentage:type_name -> common.Metric
|
||||||
8, // 31: api.GatewayService.List:input_type -> api.ListGatewaysRequest
|
3, // 31: api.GatewayService.Create:input_type -> api.CreateGatewayRequest
|
||||||
10, // 32: api.GatewayService.GenerateClientCertificate:input_type -> api.GenerateGatewayClientCertificateRequest
|
4, // 32: api.GatewayService.Get:input_type -> api.GetGatewayRequest
|
||||||
12, // 33: api.GatewayService.GetMetrics:input_type -> api.GetGatewayMetricsRequest
|
6, // 33: api.GatewayService.Update:input_type -> api.UpdateGatewayRequest
|
||||||
21, // 34: api.GatewayService.Create:output_type -> google.protobuf.Empty
|
7, // 34: api.GatewayService.Delete:input_type -> api.DeleteGatewayRequest
|
||||||
5, // 35: api.GatewayService.Get:output_type -> api.GetGatewayResponse
|
8, // 35: api.GatewayService.List:input_type -> api.ListGatewaysRequest
|
||||||
21, // 36: api.GatewayService.Update:output_type -> google.protobuf.Empty
|
10, // 36: api.GatewayService.GenerateClientCertificate:input_type -> api.GenerateGatewayClientCertificateRequest
|
||||||
21, // 37: api.GatewayService.Delete:output_type -> google.protobuf.Empty
|
12, // 37: api.GatewayService.GetMetrics:input_type -> api.GetGatewayMetricsRequest
|
||||||
9, // 38: api.GatewayService.List:output_type -> api.ListGatewaysResponse
|
14, // 38: api.GatewayService.GetDutyCycleMetrics:input_type -> api.GetGatewayDutyCycleMetricsRequest
|
||||||
11, // 39: api.GatewayService.GenerateClientCertificate:output_type -> api.GenerateGatewayClientCertificateResponse
|
23, // 39: api.GatewayService.Create:output_type -> google.protobuf.Empty
|
||||||
13, // 40: api.GatewayService.GetMetrics:output_type -> api.GetGatewayMetricsResponse
|
5, // 40: api.GatewayService.Get:output_type -> api.GetGatewayResponse
|
||||||
34, // [34:41] is the sub-list for method output_type
|
23, // 41: api.GatewayService.Update:output_type -> google.protobuf.Empty
|
||||||
27, // [27:34] is the sub-list for method input_type
|
23, // 42: api.GatewayService.Delete:output_type -> google.protobuf.Empty
|
||||||
27, // [27:27] is the sub-list for extension type_name
|
9, // 43: api.GatewayService.List:output_type -> api.ListGatewaysResponse
|
||||||
27, // [27:27] is the sub-list for extension extendee
|
11, // 44: api.GatewayService.GenerateClientCertificate:output_type -> api.GenerateGatewayClientCertificateResponse
|
||||||
0, // [0:27] is the sub-list for field type_name
|
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() }
|
func init() { file_api_gateway_proto_init() }
|
||||||
@ -1515,6 +1677,30 @@ func file_api_gateway_proto_init() {
|
|||||||
return nil
|
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{}
|
type x struct{}
|
||||||
out := protoimpl.TypeBuilder{
|
out := protoimpl.TypeBuilder{
|
||||||
@ -1522,7 +1708,7 @@ func file_api_gateway_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_api_gateway_proto_rawDesc,
|
RawDescriptor: file_api_gateway_proto_rawDesc,
|
||||||
NumEnums: 1,
|
NumEnums: 1,
|
||||||
NumMessages: 16,
|
NumMessages: 18,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
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_List_FullMethodName = "/api.GatewayService/List"
|
||||||
GatewayService_GenerateClientCertificate_FullMethodName = "/api.GatewayService/GenerateClientCertificate"
|
GatewayService_GenerateClientCertificate_FullMethodName = "/api.GatewayService/GenerateClientCertificate"
|
||||||
GatewayService_GetMetrics_FullMethodName = "/api.GatewayService/GetMetrics"
|
GatewayService_GetMetrics_FullMethodName = "/api.GatewayService/GetMetrics"
|
||||||
|
GatewayService_GetDutyCycleMetrics_FullMethodName = "/api.GatewayService/GetDutyCycleMetrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GatewayServiceClient is the client API for GatewayService service.
|
// 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)
|
GenerateClientCertificate(ctx context.Context, in *GenerateGatewayClientCertificateRequest, opts ...grpc.CallOption) (*GenerateGatewayClientCertificateResponse, error)
|
||||||
// GetMetrics returns the gateway metrics.
|
// GetMetrics returns the gateway metrics.
|
||||||
GetMetrics(ctx context.Context, in *GetGatewayMetricsRequest, opts ...grpc.CallOption) (*GetGatewayMetricsResponse, error)
|
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 {
|
type gatewayServiceClient struct {
|
||||||
@ -120,6 +124,15 @@ func (c *gatewayServiceClient) GetMetrics(ctx context.Context, in *GetGatewayMet
|
|||||||
return out, nil
|
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.
|
// GatewayServiceServer is the server API for GatewayService service.
|
||||||
// All implementations must embed UnimplementedGatewayServiceServer
|
// All implementations must embed UnimplementedGatewayServiceServer
|
||||||
// for forward compatibility
|
// for forward compatibility
|
||||||
@ -138,6 +151,9 @@ type GatewayServiceServer interface {
|
|||||||
GenerateClientCertificate(context.Context, *GenerateGatewayClientCertificateRequest) (*GenerateGatewayClientCertificateResponse, error)
|
GenerateClientCertificate(context.Context, *GenerateGatewayClientCertificateRequest) (*GenerateGatewayClientCertificateResponse, error)
|
||||||
// GetMetrics returns the gateway metrics.
|
// GetMetrics returns the gateway metrics.
|
||||||
GetMetrics(context.Context, *GetGatewayMetricsRequest) (*GetGatewayMetricsResponse, error)
|
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()
|
mustEmbedUnimplementedGatewayServiceServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,6 +182,9 @@ func (UnimplementedGatewayServiceServer) GenerateClientCertificate(context.Conte
|
|||||||
func (UnimplementedGatewayServiceServer) GetMetrics(context.Context, *GetGatewayMetricsRequest) (*GetGatewayMetricsResponse, error) {
|
func (UnimplementedGatewayServiceServer) GetMetrics(context.Context, *GetGatewayMetricsRequest) (*GetGatewayMetricsResponse, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetMetrics not implemented")
|
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() {}
|
func (UnimplementedGatewayServiceServer) mustEmbedUnimplementedGatewayServiceServer() {}
|
||||||
|
|
||||||
// UnsafeGatewayServiceServer may be embedded to opt out of forward compatibility for this service.
|
// 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)
|
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.
|
// GatewayService_ServiceDesc is the grpc.ServiceDesc for GatewayService service.
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
// It's only intended for direct use with grpc.RegisterService,
|
||||||
// and not to be introspected or modified (even as a copy)
|
// and not to be introspected or modified (even as a copy)
|
||||||
@ -340,6 +377,10 @@ var GatewayService_ServiceDesc = grpc.ServiceDesc{
|
|||||||
MethodName: "GetMetrics",
|
MethodName: "GetMetrics",
|
||||||
Handler: _GatewayService_GetMetrics_Handler,
|
Handler: _GatewayService_GetMetrics_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "GetDutyCycleMetrics",
|
||||||
|
Handler: _GatewayService_GetDutyCycleMetrics_Handler,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Streams: []grpc.StreamDesc{},
|
Streams: []grpc.StreamDesc{},
|
||||||
Metadata: "api/gateway.proto",
|
Metadata: "api/gateway.proto",
|
||||||
|
43
api/go/common/common.pb.go
vendored
43
api/go/common/common.pb.go
vendored
@ -434,6 +434,8 @@ const (
|
|||||||
Aggregation_DAY Aggregation = 1
|
Aggregation_DAY Aggregation = 1
|
||||||
// Month.
|
// Month.
|
||||||
Aggregation_MONTH Aggregation = 2
|
Aggregation_MONTH Aggregation = 2
|
||||||
|
// Minute.
|
||||||
|
Aggregation_MINUTE Aggregation = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
// Enum value maps for Aggregation.
|
// Enum value maps for Aggregation.
|
||||||
@ -442,11 +444,13 @@ var (
|
|||||||
0: "HOUR",
|
0: "HOUR",
|
||||||
1: "DAY",
|
1: "DAY",
|
||||||
2: "MONTH",
|
2: "MONTH",
|
||||||
|
3: "MINUTE",
|
||||||
}
|
}
|
||||||
Aggregation_value = map[string]int32{
|
Aggregation_value = map[string]int32{
|
||||||
"HOUR": 0,
|
"HOUR": 0,
|
||||||
"DAY": 1,
|
"DAY": 1,
|
||||||
"MONTH": 2,
|
"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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
0x4e, 0x54, 0x48, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x49, 0x4e, 0x55, 0x54, 0x45, 0x10,
|
||||||
0x69, 0x6e, 0x64, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x00,
|
0x03, 0x2a, 0x32, 0x0a, 0x0a, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4b, 0x69, 0x6e, 0x64, 0x12,
|
||||||
0x12, 0x0c, 0x0a, 0x08, 0x41, 0x42, 0x53, 0x4f, 0x4c, 0x55, 0x54, 0x45, 0x10, 0x01, 0x12, 0x09,
|
0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08,
|
||||||
0x0a, 0x05, 0x47, 0x41, 0x55, 0x47, 0x45, 0x10, 0x02, 0x2a, 0x39, 0x0a, 0x0a, 0x52, 0x65, 0x67,
|
0x41, 0x42, 0x53, 0x4f, 0x4c, 0x55, 0x54, 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x41,
|
||||||
0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x47, 0x55, 0x4c,
|
0x55, 0x47, 0x45, 0x10, 0x02, 0x2a, 0x39, 0x0a, 0x0a, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x74,
|
||||||
0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12,
|
0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x47, 0x55, 0x4c, 0x41, 0x54, 0x49, 0x4f,
|
||||||
0x13, 0x0a, 0x0f, 0x45, 0x54, 0x53, 0x49, 0x5f, 0x45, 0x4e, 0x5f, 0x33, 0x30, 0x30, 0x5f, 0x32,
|
0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x45,
|
||||||
0x32, 0x30, 0x10, 0x01, 0x2a, 0x34, 0x0a, 0x0b, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6c,
|
0x54, 0x53, 0x49, 0x5f, 0x45, 0x4e, 0x5f, 0x33, 0x30, 0x30, 0x5f, 0x32, 0x32, 0x30, 0x10, 0x01,
|
||||||
0x61, 0x73, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x41, 0x10, 0x00,
|
0x2a, 0x34, 0x0a, 0x0b, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12,
|
||||||
0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x42, 0x10, 0x01, 0x12, 0x0b, 0x0a,
|
0x0b, 0x0a, 0x07, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x41, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07,
|
||||||
0x07, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x43, 0x10, 0x02, 0x42, 0x69, 0x0a, 0x11, 0x69, 0x6f,
|
0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x42, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4c, 0x41,
|
||||||
0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42,
|
0x53, 0x53, 0x5f, 0x43, 0x10, 0x02, 0x42, 0x69, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69,
|
||||||
0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31,
|
0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0b, 0x43, 0x6f, 0x6d,
|
||||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70,
|
0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68,
|
||||||
0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b,
|
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63,
|
||||||
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
|
0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69,
|
||||||
0x6e, 0xaa, 0x02, 0x11, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x43,
|
0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0xaa, 0x02, 0x11,
|
||||||
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
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 (
|
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"
|
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 {
|
enum GatewayState {
|
||||||
@ -255,3 +263,22 @@ message GetGatewayMetricsResponse {
|
|||||||
// TX packets per status.
|
// TX packets per status.
|
||||||
common.Metric tx_packets_per_status = 7;
|
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.
|
||||||
MONTH = 2;
|
MONTH = 2;
|
||||||
|
|
||||||
|
// Minute.
|
||||||
|
MINUTE = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MetricKind {
|
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"
|
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 {
|
enum GatewayState {
|
||||||
@ -255,3 +263,22 @@ message GetGatewayMetricsResponse {
|
|||||||
// TX packets per status.
|
// TX packets per status.
|
||||||
common.Metric tx_packets_per_status = 7;
|
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.
|
||||||
MONTH = 2;
|
MONTH = 2;
|
||||||
|
|
||||||
|
// Minute.
|
||||||
|
MINUTE = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MetricKind {
|
enum MetricKind {
|
||||||
|
@ -614,11 +614,180 @@ impl GatewayService for Gateway {
|
|||||||
|
|
||||||
Ok(resp)
|
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)]
|
#[cfg(test)]
|
||||||
pub mod test {
|
pub mod test {
|
||||||
use chrono::{Datelike, Local, TimeZone};
|
use chrono::{Datelike, Local, TimeZone, Timelike};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -823,7 +992,13 @@ pub mod test {
|
|||||||
m.metrics.insert("tx_freq_868200000".into(), 5.0);
|
m.metrics.insert("tx_freq_868200000".into(), 5.0);
|
||||||
m.metrics.insert("tx_dr_4".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
|
// setup api
|
||||||
let service = Gateway::new(RequestValidator::new());
|
let service = Gateway::new(RequestValidator::new());
|
||||||
@ -862,4 +1037,130 @@ pub mod test {
|
|||||||
stats_resp.rx_packets
|
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 {
|
impl ToProto<common::Aggregation> for Aggregation {
|
||||||
fn to_proto(self) -> common::Aggregation {
|
fn to_proto(self) -> common::Aggregation {
|
||||||
match self {
|
match self {
|
||||||
|
Aggregation::MINUTE => common::Aggregation::Minute,
|
||||||
Aggregation::HOUR => common::Aggregation::Hour,
|
Aggregation::HOUR => common::Aggregation::Hour,
|
||||||
Aggregation::DAY => common::Aggregation::Day,
|
Aggregation::DAY => common::Aggregation::Day,
|
||||||
Aggregation::MONTH => common::Aggregation::Month,
|
Aggregation::MONTH => common::Aggregation::Month,
|
||||||
@ -179,6 +180,7 @@ impl ToProto<common::Aggregation> for Aggregation {
|
|||||||
impl FromProto<Aggregation> for common::Aggregation {
|
impl FromProto<Aggregation> for common::Aggregation {
|
||||||
fn from_proto(self) -> Aggregation {
|
fn from_proto(self) -> Aggregation {
|
||||||
match self {
|
match self {
|
||||||
|
common::Aggregation::Minute => Aggregation::MINUTE,
|
||||||
common::Aggregation::Hour => Aggregation::HOUR,
|
common::Aggregation::Hour => Aggregation::HOUR,
|
||||||
common::Aggregation::Day => Aggregation::DAY,
|
common::Aggregation::Day => Aggregation::DAY,
|
||||||
common::Aggregation::Month => Aggregation::MONTH,
|
common::Aggregation::Month => Aggregation::MONTH,
|
||||||
|
@ -13,11 +13,18 @@ use crate::storage::{get_async_redis_conn, redis_key};
|
|||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum Aggregation {
|
pub enum Aggregation {
|
||||||
|
MINUTE,
|
||||||
HOUR,
|
HOUR,
|
||||||
DAY,
|
DAY,
|
||||||
MONTH,
|
MONTH,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Aggregation {
|
||||||
|
pub fn default_aggregations() -> Vec<Aggregation> {
|
||||||
|
vec![Aggregation::HOUR, Aggregation::DAY, Aggregation::MONTH]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Aggregation {
|
impl fmt::Display for Aggregation {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{:?}", self)
|
write!(f, "{:?}", self)
|
||||||
@ -48,16 +55,13 @@ pub struct Record {
|
|||||||
|
|
||||||
fn get_ttl(a: Aggregation) -> Duration {
|
fn get_ttl(a: Aggregation) -> Duration {
|
||||||
match a {
|
match a {
|
||||||
|
Aggregation::MINUTE => Duration::from_secs(60 * 60 * 2), // two hours
|
||||||
Aggregation::HOUR => Duration::from_secs(60 * 60 * 24 * 2), // two days
|
Aggregation::HOUR => Duration::from_secs(60 * 60 * 24 * 2), // two days
|
||||||
Aggregation::DAY => Duration::from_secs(60 * 60 * 24 * 31 * 2), // two months
|
Aggregation::DAY => Duration::from_secs(60 * 60 * 24 * 31 * 2), // two months
|
||||||
Aggregation::MONTH => Duration::from_secs(60 * 60 * 24 * 365 * 2), // two years
|
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 {
|
fn get_key(name: &str, a: Aggregation, dt: DateTime<Local>) -> String {
|
||||||
redis_key(format!(
|
redis_key(format!(
|
||||||
"metrics:{{{}}}:{}:{}",
|
"metrics:{{{}}}:{}:{}",
|
||||||
@ -82,7 +86,7 @@ pub async fn save_state(name: &str, state: &str) -> Result<()> {
|
|||||||
Ok(())
|
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() {
|
if record.metrics.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -90,10 +94,20 @@ pub async fn save(name: &str, record: &Record) -> Result<()> {
|
|||||||
let mut pipe = redis::pipe();
|
let mut pipe = redis::pipe();
|
||||||
pipe.atomic();
|
pipe.atomic();
|
||||||
|
|
||||||
for a in get_aggregations() {
|
for a in aggregations {
|
||||||
let ttl = get_ttl(a);
|
let ttl = get_ttl(*a);
|
||||||
|
|
||||||
let ts: DateTime<Local> = match 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
|
Aggregation::HOUR => Local
|
||||||
.with_ymd_and_hms(
|
.with_ymd_and_hms(
|
||||||
record.time.year(),
|
record.time.year(),
|
||||||
@ -119,7 +133,7 @@ pub async fn save(name: &str, record: &Record) -> Result<()> {
|
|||||||
.unwrap(),
|
.unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let key = get_key(name, a, ts);
|
let key = get_key(name, *a, ts);
|
||||||
|
|
||||||
for (k, v) in &record.metrics {
|
for (k, v) in &record.metrics {
|
||||||
// Passing a reference to hincr will return a runtime error.
|
// 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();
|
let mut timestamps: Vec<DateTime<Local>> = Vec::new();
|
||||||
|
|
||||||
match a {
|
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 => {
|
Aggregation::HOUR => {
|
||||||
let mut ts = Local
|
let mut ts = Local
|
||||||
.with_ymd_and_hms(start.year(), start.month(), start.day(), start.hour(), 0, 0)
|
.with_ymd_and_hms(start.year(), start.month(), start.day(), start.hour(), 0, 0)
|
||||||
@ -304,6 +346,41 @@ pub mod test {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::test;
|
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]
|
#[tokio::test]
|
||||||
async fn test_hour() {
|
async fn test_hour() {
|
||||||
let _guard = test::prepare().await;
|
let _guard = test::prepare().await;
|
||||||
@ -335,7 +412,7 @@ pub mod test {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
for r in &records {
|
for r in &records {
|
||||||
save("test", r).await.unwrap();
|
save("test", r, &[Aggregation::HOUR]).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let resp = get(
|
let resp = get(
|
||||||
@ -402,7 +479,7 @@ pub mod test {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
for r in &records {
|
for r in &records {
|
||||||
save("test", r).await.unwrap();
|
save("test", r, &[Aggregation::DAY]).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let resp = get(
|
let resp = get(
|
||||||
@ -469,7 +546,7 @@ pub mod test {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
for r in &records {
|
for r in &records {
|
||||||
save("test", r).await.unwrap();
|
save("test", r, &[Aggregation::DAY]).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let resp = get(
|
let resp = get(
|
||||||
@ -536,7 +613,7 @@ pub mod test {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
for r in &records {
|
for r in &records {
|
||||||
save("test", r).await.unwrap();
|
save("test", r, &[Aggregation::MONTH]).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let resp = get(
|
let resp = get(
|
||||||
@ -595,7 +672,7 @@ pub mod test {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
for r in &records {
|
for r in &records {
|
||||||
save("test", r).await.unwrap();
|
save("test", r, &[Aggregation::HOUR]).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let resp = get(
|
let resp = get(
|
||||||
@ -644,7 +721,7 @@ pub mod test {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
for r in &records {
|
for r in &records {
|
||||||
save("test", r).await.unwrap();
|
save("test", r, &[Aggregation::HOUR]).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let resp = get(
|
let resp = get(
|
||||||
@ -693,7 +770,7 @@ pub mod test {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
for r in &records {
|
for r in &records {
|
||||||
save("test", r).await.unwrap();
|
save("test", r, &[Aggregation::HOUR]).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let resp = get(
|
let resp = get(
|
||||||
|
@ -1045,7 +1045,12 @@ impl Data {
|
|||||||
metrics: [("value".to_string(), v)].iter().cloned().collect(),
|
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) => {
|
pbjson_types::value::Kind::StringValue(v) => {
|
||||||
metrics::save_state(
|
metrics::save_state(
|
||||||
@ -1215,7 +1220,12 @@ impl Data {
|
|||||||
|
|
||||||
let dev = self.device.as_ref().unwrap();
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1246,7 +1256,12 @@ impl Data {
|
|||||||
|
|
||||||
let dev = self.device.as_ref().unwrap();
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -441,6 +441,7 @@ impl JoinRequest {
|
|||||||
.cloned()
|
.cloned()
|
||||||
.collect(),
|
.collect(),
|
||||||
},
|
},
|
||||||
|
&metrics::Aggregation::default_aggregations(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@ -490,6 +491,7 @@ impl JoinRequest {
|
|||||||
kind: metrics::Kind::ABSOLUTE,
|
kind: metrics::Kind::ABSOLUTE,
|
||||||
metrics: [("error_OTAA".into(), 1f64)].iter().cloned().collect(),
|
metrics: [("error_OTAA".into(), 1f64)].iter().cloned().collect(),
|
||||||
},
|
},
|
||||||
|
&metrics::Aggregation::default_aggregations(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -338,6 +338,7 @@ impl JoinRequest {
|
|||||||
.cloned()
|
.cloned()
|
||||||
.collect(),
|
.collect(),
|
||||||
},
|
},
|
||||||
|
&metrics::Aggregation::default_aggregations(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@ -387,6 +388,7 @@ impl JoinRequest {
|
|||||||
kind: metrics::Kind::ABSOLUTE,
|
kind: metrics::Kind::ABSOLUTE,
|
||||||
metrics: [("error_OTAA".into(), 1f64)].iter().cloned().collect(),
|
metrics: [("error_OTAA".into(), 1f64)].iter().cloned().collect(),
|
||||||
},
|
},
|
||||||
|
&metrics::Aggregation::default_aggregations(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ use std::collections::hash_map::DefaultHasher;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use chrono::{DateTime, Local, Utc};
|
use chrono::{DateTime, Local, Utc};
|
||||||
@ -63,6 +64,7 @@ impl Stats {
|
|||||||
|
|
||||||
ctx.update_gateway_state().await?;
|
ctx.update_gateway_state().await?;
|
||||||
ctx.save_stats().await?;
|
ctx.save_stats().await?;
|
||||||
|
ctx.save_duty_cycle_stats().await?;
|
||||||
ctx.update_gateway_configuration().await?;
|
ctx.update_gateway_configuration().await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -156,6 +158,7 @@ impl Stats {
|
|||||||
metrics::save(
|
metrics::save(
|
||||||
&format!("gw:{}", self.gateway.as_ref().unwrap().gateway_id),
|
&format!("gw:{}", self.gateway.as_ref().unwrap().gateway_id),
|
||||||
&m,
|
&m,
|
||||||
|
&metrics::Aggregation::default_aggregations(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.context("Save gateway stats")?;
|
.context("Save gateway stats")?;
|
||||||
@ -163,6 +166,73 @@ impl Stats {
|
|||||||
Ok(())
|
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<()> {
|
async fn update_gateway_configuration(&self) -> Result<()> {
|
||||||
trace!("Updating gateway configuration");
|
trace!("Updating gateway configuration");
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
"chartjs-adapter-moment": "^1.0.1",
|
"chartjs-adapter-moment": "^1.0.1",
|
||||||
"chartjs-chart-matrix": "^2.0.1",
|
"chartjs-chart-matrix": "^2.0.1",
|
||||||
"codemirror": "5.65.3",
|
"codemirror": "5.65.3",
|
||||||
|
"google-palette": "^1.1.1",
|
||||||
"history": "^5.3.0",
|
"history": "^5.3.0",
|
||||||
"js-file-download": "^0.4.12",
|
"js-file-download": "^0.4.12",
|
||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
|
@ -3,6 +3,7 @@ import { Card } from "antd";
|
|||||||
import { TimeUnit } from "chart.js";
|
import { TimeUnit } from "chart.js";
|
||||||
import { Bar } from "react-chartjs-2";
|
import { Bar } from "react-chartjs-2";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
import palette from "google-palette";
|
||||||
|
|
||||||
import { Metric, Aggregation } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
|
import { Metric, Aggregation } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
|
||||||
|
|
||||||
@ -19,24 +20,6 @@ function MetricBar(props: IProps) {
|
|||||||
unit = "month";
|
unit = "month";
|
||||||
}
|
}
|
||||||
|
|
||||||
let backgroundColors = [
|
|
||||||
"#8bc34a",
|
|
||||||
"#ff5722",
|
|
||||||
"#ff9800",
|
|
||||||
"#ffc107",
|
|
||||||
"#ffeb3b",
|
|
||||||
"#cddc39",
|
|
||||||
"#4caf50",
|
|
||||||
"#009688",
|
|
||||||
"#00bcd4",
|
|
||||||
"#03a9f4",
|
|
||||||
"#2196f3",
|
|
||||||
"#3f51b5",
|
|
||||||
"#673ab7",
|
|
||||||
"#9c27b0",
|
|
||||||
"#e91e63",
|
|
||||||
];
|
|
||||||
|
|
||||||
const animation: false = false;
|
const animation: false = false;
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
@ -72,13 +55,13 @@ function MetricBar(props: IProps) {
|
|||||||
datasets: [],
|
datasets: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
for (let ds of props.metric.getDatasetsList()) {
|
props.metric.getDatasetsList().forEach((ds, i) => {
|
||||||
data.datasets.push({
|
data.datasets.push({
|
||||||
label: ds.getLabel(),
|
label: ds.getLabel(),
|
||||||
data: ds.getDataList(),
|
data: ds.getDataList(),
|
||||||
backgroundColor: backgroundColors.shift()!,
|
backgroundColor: palette("cb-Paired", props.metric.getDatasetsList().length).map((hex: string) => "#" + hex)[i],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card title={props.metric.getName()} className="dashboard-chart">
|
<Card title={props.metric.getName()} className="dashboard-chart">
|
||||||
|
@ -3,6 +3,7 @@ import { Card } from "antd";
|
|||||||
import { TimeUnit } from "chart.js";
|
import { TimeUnit } from "chart.js";
|
||||||
import { Line } from "react-chartjs-2";
|
import { Line } from "react-chartjs-2";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
import palette from "google-palette";
|
||||||
|
|
||||||
import { Metric, Aggregation, MetricKind } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
|
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) {
|
} else if (props.aggregation === Aggregation.MONTH) {
|
||||||
unit = "month";
|
unit = "month";
|
||||||
tooltipFormat = "MMM YYYY";
|
tooltipFormat = "MMM YYYY";
|
||||||
|
} else if (props.aggregation === Aggregation.MINUTE) {
|
||||||
|
unit = "minute";
|
||||||
|
tooltipFormat = "LT";
|
||||||
}
|
}
|
||||||
|
|
||||||
const animation: false = false;
|
const animation: false = false;
|
||||||
@ -50,13 +54,19 @@ function MetricChart(props: IProps) {
|
|||||||
let prevValue = 0;
|
let prevValue = 0;
|
||||||
let data = {
|
let data = {
|
||||||
labels: props.metric.getTimestampsList().map(v => moment(v.toDate()).valueOf()),
|
labels: props.metric.getTimestampsList().map(v => moment(v.toDate()).valueOf()),
|
||||||
datasets: props.metric.getDatasetsList().map(v => {
|
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 {
|
return {
|
||||||
label: v.getLabel(),
|
label: v.getLabel(),
|
||||||
borderColor: "rgba(33, 150, 243, 1)",
|
borderColor: colors[i],
|
||||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
pointBackgroundColor: colors[i],
|
||||||
lineTension: 0,
|
lineTension: 0,
|
||||||
pointBackgroundColor: "rgba(33, 150, 243, 1)",
|
|
||||||
data: v.getDataList().map(v => {
|
data: v.getDataList().map(v => {
|
||||||
if (v === 0 && props.zeroToNull) {
|
if (v === 0 && props.zeroToNull) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -11,6 +11,8 @@ import {
|
|||||||
ListGatewaysResponse,
|
ListGatewaysResponse,
|
||||||
GetGatewayMetricsRequest,
|
GetGatewayMetricsRequest,
|
||||||
GetGatewayMetricsResponse,
|
GetGatewayMetricsResponse,
|
||||||
|
GetGatewayDutyCycleMetricsRequest,
|
||||||
|
GetGatewayDutyCycleMetricsResponse,
|
||||||
GenerateGatewayClientCertificateRequest,
|
GenerateGatewayClientCertificateRequest,
|
||||||
GenerateGatewayClientCertificateResponse,
|
GenerateGatewayClientCertificateResponse,
|
||||||
} from "@chirpstack/chirpstack-api-grpc-web/api/gateway_pb";
|
} 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 = (
|
generateClientCertificate = (
|
||||||
req: GenerateGatewayClientCertificateRequest,
|
req: GenerateGatewayClientCertificateRequest,
|
||||||
callbackFunc: (resp: GenerateGatewayClientCertificateResponse) => void,
|
callbackFunc: (resp: GenerateGatewayClientCertificateResponse) => void,
|
||||||
|
@ -8,6 +8,8 @@ import {
|
|||||||
Gateway,
|
Gateway,
|
||||||
GetGatewayMetricsRequest,
|
GetGatewayMetricsRequest,
|
||||||
GetGatewayMetricsResponse,
|
GetGatewayMetricsResponse,
|
||||||
|
GetGatewayDutyCycleMetricsRequest,
|
||||||
|
GetGatewayDutyCycleMetricsResponse,
|
||||||
} from "@chirpstack/chirpstack-api-grpc-web/api/gateway_pb";
|
} from "@chirpstack/chirpstack-api-grpc-web/api/gateway_pb";
|
||||||
import { Aggregation } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
|
import { Aggregation } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
|
||||||
|
|
||||||
@ -25,6 +27,9 @@ interface IProps {
|
|||||||
function GatewayDashboard(props: IProps) {
|
function GatewayDashboard(props: IProps) {
|
||||||
const [metricsAggregation] = useState<Aggregation>(Aggregation.DAY);
|
const [metricsAggregation] = useState<Aggregation>(Aggregation.DAY);
|
||||||
const [gatewayMetrics, setGatewayMetrics] = useState<GetGatewayMetricsResponse | undefined>(undefined);
|
const [gatewayMetrics, setGatewayMetrics] = useState<GetGatewayMetricsResponse | undefined>(undefined);
|
||||||
|
const [gatewayDutyCycleMetrics, setGatewayDutyCycleMetrics] = useState<
|
||||||
|
GetGatewayDutyCycleMetricsResponse | undefined
|
||||||
|
>(undefined);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const agg = metricsAggregation;
|
const agg = metricsAggregation;
|
||||||
@ -54,12 +59,29 @@ function GatewayDashboard(props: IProps) {
|
|||||||
GatewayStore.getMetrics(req, (resp: GetGatewayMetricsResponse) => {
|
GatewayStore.getMetrics(req, (resp: GetGatewayMetricsResponse) => {
|
||||||
setGatewayMetrics(resp);
|
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]);
|
}, [props, metricsAggregation]);
|
||||||
|
|
||||||
const loc = props.gateway.getLocation()!;
|
const loc = props.gateway.getLocation()!;
|
||||||
const location: [number, number] = [loc.getLatitude(), loc.getLongitude()];
|
const location: [number, number] = [loc.getLatitude(), loc.getLongitude()];
|
||||||
|
|
||||||
if (gatewayMetrics === undefined) {
|
if (gatewayMetrics === undefined || gatewayDutyCycleMetrics === undefined) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,6 +111,17 @@ function GatewayDashboard(props: IProps) {
|
|||||||
</Map>
|
</Map>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</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}>
|
<Row gutter={24}>
|
||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
<MetricChart metric={gatewayMetrics.getRxPackets()!} aggregation={metricsAggregation} />
|
<MetricChart metric={gatewayMetrics.getRxPackets()!} aggregation={metricsAggregation} />
|
||||||
|
@ -14,7 +14,8 @@
|
|||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "react-jsx"
|
"jsx": "react-jsx",
|
||||||
|
"typeRoots": ["./types", "./node_modules/@types"]
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"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==
|
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||||
|
|
||||||
"@chirpstack/chirpstack-api-grpc-web@file:../api/grpc-web":
|
"@chirpstack/chirpstack-api-grpc-web@file:../api/grpc-web":
|
||||||
version "4.7.0"
|
version "4.8.0-test.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/google-protobuf" "^3.15.12"
|
"@types/google-protobuf" "^3.15.12"
|
||||||
google-protobuf "^3.21.2"
|
google-protobuf "^3.21.2"
|
||||||
@ -5433,6 +5433,11 @@ globby@^11.0.4, globby@^11.1.0:
|
|||||||
merge2 "^1.4.1"
|
merge2 "^1.4.1"
|
||||||
slash "^3.0.0"
|
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:
|
google-protobuf@^3.21.2:
|
||||||
version "3.21.2"
|
version "3.21.2"
|
||||||
resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.21.2.tgz#4580a2bea8bbb291ee579d1fefb14d6fa3070ea4"
|
resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.21.2.tgz#4580a2bea8bbb291ee579d1fefb14d6fa3070ea4"
|
||||||
|
Reference in New Issue
Block a user